diff --git a/src/components/GroupSortDropdown.vue b/src/components/GroupSortDropdown.vue
new file mode 100644
index 000000000..9e32b1794
--- /dev/null
+++ b/src/components/GroupSortDropdown.vue
@@ -0,0 +1,488 @@
+
+
+
+
+
+
+
diff --git a/src/components/PublicGroupList.vue b/src/components/PublicGroupList.vue
index cb97ecdcd..3e68c93e3 100644
--- a/src/components/PublicGroupList.vue
+++ b/src/components/PublicGroupList.vue
@@ -10,9 +10,18 @@
-
-
-
+
+
+
+
+
+
+
@@ -21,7 +30,6 @@
-
= 2);
}
},
+ watch: {
+ // No watchers needed - sorting is handled by GroupSortDropdown component
+ },
created() {
-
+ // Sorting is now handled by GroupSortDropdown component
},
methods: {
/**
@@ -141,8 +153,7 @@ export default {
/**
* Remove a monitor from a group
- * @param {number} groupIndex Index of group to remove monitor
- * from
+ * @param {number} groupIndex Index of group to remove monitor from
* @param {number} index Index of monitor to remove
* @returns {void}
*/
@@ -163,7 +174,9 @@ export default {
// We must check if there are any elements in monitorList to
// prevent undefined errors if it hasn't been loaded yet
if (this.$parent.editMode && ignoreSendUrl && Object.keys(this.$root.monitorList).length) {
- return this.$root.monitorList[monitor.element.id].type === "http" || this.$root.monitorList[monitor.element.id].type === "keyword" || this.$root.monitorList[monitor.element.id].type === "json-query";
+ return this.$root.monitorList[monitor.element.id].type === "http" ||
+ this.$root.monitorList[monitor.element.id].type === "keyword" ||
+ this.$root.monitorList[monitor.element.id].type === "json-query";
}
return monitor.element.sendUrl && monitor.element.url && monitor.element.url !== "https://";
},
@@ -194,6 +207,32 @@ export default {
}
return "#DC2626";
},
+
+ /**
+ * Update group properties
+ * @param {number} groupIndex Index of group to update
+ * @param {object} updates Object with properties to update
+ * @returns {void}
+ */
+ updateGroup(groupIndex, updates) {
+ Object.assign(this.$root.publicGroupList[groupIndex], updates);
+ },
+
+ /**
+ * Get unique identifier for a group
+ * @param {object} group object
+ * @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;
+ }
+ // Fallback to ID or index
+ return group.id ? `group${group.id}` : `group${this.$root.publicGroupList.indexOf(group)}`;
+ }
}
};
@@ -255,6 +294,15 @@ export default {
}
.group-title {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+
+ .title-section {
+ display: flex;
+ align-items: center;
+ }
+
span {
display: inline-block;
min-width: 15px;
@@ -265,10 +313,14 @@ export default {
.item {
padding: 13px 0 10px;
}
+
+ .group-title {
+ flex-direction: column;
+ align-items: flex-start;
+ }
}
.bg-maintenance {
background-color: $maintenance;
}
-
diff --git a/src/icon.js b/src/icon.js
index 7bdfe1ca0..d81023df1 100644
--- a/src/icon.js
+++ b/src/icon.js
@@ -8,6 +8,8 @@ import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
// 2) add the icon name to the library.add() statement below.
import {
faArrowAltCircleUp,
+ faArrowDown,
+ faArrowUp,
faCog,
faEdit,
faEye,
@@ -54,6 +56,8 @@ import {
library.add(
faArrowAltCircleUp,
+ faArrowDown,
+ faArrowUp,
faCog,
faEdit,
faEye,