-
@@ -183,6 +196,59 @@ export default {
// Sorting is now handled by GroupSortDropdown component
},
methods: {
+ /**
+ * Toggle collapsed state for a group
+ * @param {object} group Group to toggle
+ * @returns {void}
+ */
+ toggleGroup(group) {
+ if (!this.$router) {
+ return;
+ }
+
+ const groupId = this.getGroupIdentifier(group);
+ const collapsed = this.getCollapsedList();
+ const index = collapsed.indexOf(groupId);
+
+ if (index >= 0) {
+ collapsed.splice(index, 1);
+ } else {
+ collapsed.push(groupId);
+ }
+
+ const query = { ...this.$route.query };
+ if (collapsed.length > 0) {
+ query.collapse = collapsed;
+ } else {
+ delete query.collapse;
+ }
+
+ this.$router.push({ query }).catch(() => {});
+ },
+
+ /**
+ * Check if a group is collapsed
+ * @param {object} group Group to check
+ * @returns {boolean} Whether the group is collapsed
+ */
+ isGroupCollapsed(group) {
+ return this.getCollapsedList().includes(this.getGroupIdentifier(group));
+ },
+
+ /**
+ * Get list of collapsed group identifiers from the query param.
+ * Vue Router normalises repeated params (?collapse=1&collapse=2) into an array.
+ * @returns {string[]} Collapsed group identifiers
+ */
+ getCollapsedList() {
+ const raw = this.$route.query.collapse;
+ if (!raw) {
+ return [];
+ }
+ // Normalise to array: a single query param is a string, repeated params are already an array
+ return [].concat(raw);
+ },
+
/**
* Remove the specified group
* @param {number} index Index of group to remove
@@ -278,14 +344,10 @@ export default {
* @returns {string} group identifier
*/
getGroupIdentifier(group) {
- // Use the name directly if available
- if (group.name) {
- // Only remove spaces and use encodeURIComponent for URL safety
- const cleanName = group.name.replace(/\s+/g, "");
- return cleanName;
+ if (group.id !== undefined && group.id !== null) {
+ return group.id.toString();
}
- // Fallback to ID or index
- return group.id ? `group${group.id}` : `group${this.$root.publicGroupList.indexOf(group)}`;
+ return `group${this.$root.publicGroupList.indexOf(group)}`;
},
},
};
@@ -363,6 +425,21 @@ export default {
}
}
+.collapse-toggle {
+ cursor: pointer;
+ padding: 2px;
+}
+
+.chevron {
+ font-size: 0.8em;
+ color: #bbb;
+ transition: all 0.2s $easing-in;
+
+ &.collapsed {
+ transform: rotate(-90deg);
+ }
+}
+
.mobile {
.item {
padding: 13px 0 10px;