Replace localStorage with query parameters for state management

This commit is contained in:
Marshu 2025-06-05 00:00:05 +08:00
parent 2558f0cb61
commit 69f304b101

View file

@ -18,11 +18,11 @@
<div v-if="group.element && group.element.monitorList && group.element.monitorList.length > 1" class="sort-dropdown"> <div v-if="group.element && group.element.monitorList && group.element.monitorList.length > 1" class="sort-dropdown">
<div class="dropdown"> <div class="dropdown">
<button :id="'sortDropdown' + group.index" type="button" class="btn btn-sm btn-outline-secondary dropdown-toggle sort-button" <button :id="'sortDropdown' + group.index" type="button" class="btn btn-sm btn-outline-secondary dropdown-toggle sort-button"
data-bs-toggle="dropdown" data-bs-toggle="dropdown"
aria-expanded="false" aria-expanded="false"
:aria-label="$t('Sort options')" :aria-label="$t('Sort options')"
:title="$t('Sort options')"> :title="$t('Sort options')">
<div class="sort-arrows"> <div class="sort-arrows">
<font-awesome-icon <font-awesome-icon
icon="arrow-down" icon="arrow-down"
@ -42,9 +42,9 @@
</button> </button>
<ul class="dropdown-menu dropdown-menu-end sort-menu" :aria-labelledby="'sortDropdown' + group.index"> <ul class="dropdown-menu dropdown-menu-end sort-menu" :aria-labelledby="'sortDropdown' + group.index">
<li> <li>
<button class="dropdown-item sort-item" type="button" @click="setSort(group.element, 'status')" <button class="dropdown-item sort-item" type="button" @click="setSort(group.element, 'status')"
:aria-label="$t('Sort by status')" :aria-label="$t('Sort by status')"
:title="$t('Sort by status')"> :title="$t('Sort by status')">
<div class="sort-item-content"> <div class="sort-item-content">
<span>{{ $t("Status") }}</span> <span>{{ $t("Status") }}</span>
<span v-if="getSortKey(group.element) === 'status'" class="sort-indicators"> <span v-if="getSortKey(group.element) === 'status'" class="sort-indicators">
@ -57,9 +57,9 @@
</button> </button>
</li> </li>
<li> <li>
<button class="dropdown-item sort-item" type="button" @click="setSort(group.element, 'name')" <button class="dropdown-item sort-item" type="button" @click="setSort(group.element, 'name')"
:aria-label="$t('Sort by name')" :aria-label="$t('Sort by name')"
:title="$t('Sort by name')"> :title="$t('Sort by name')">
<div class="sort-item-content"> <div class="sort-item-content">
<span>{{ $t("Name") }}</span> <span>{{ $t("Name") }}</span>
<span v-if="getSortKey(group.element) === 'name'" class="sort-indicators"> <span v-if="getSortKey(group.element) === 'name'" class="sort-indicators">
@ -72,9 +72,9 @@
</button> </button>
</li> </li>
<li> <li>
<button class="dropdown-item sort-item" type="button" @click="setSort(group.element, 'uptime')" <button class="dropdown-item sort-item" type="button" @click="setSort(group.element, 'uptime')"
:aria-label="$t('Sort by uptime')" :aria-label="$t('Sort by uptime')"
:title="$t('Sort by uptime')"> :title="$t('Sort by uptime')">
<div class="sort-item-content"> <div class="sort-item-content">
<span>{{ $t("Uptime") }}</span> <span>{{ $t("Uptime") }}</span>
<span v-if="getSortKey(group.element) === 'uptime'" class="sort-indicators"> <span v-if="getSortKey(group.element) === 'uptime'" class="sort-indicators">
@ -87,9 +87,9 @@
</button> </button>
</li> </li>
<li v-if="showCertificateExpiry"> <li v-if="showCertificateExpiry">
<button class="dropdown-item sort-item" type="button" @click="setSort(group.element, 'cert')" <button class="dropdown-item sort-item" type="button" @click="setSort(group.element, 'cert')"
:aria-label="$t('Sort by certificate expiry')" :aria-label="$t('Sort by certificate expiry')"
:title="$t('Sort by certificate expiry')"> :title="$t('Sort by certificate expiry')">
<div class="sort-item-content"> <div class="sort-item-content">
<span>{{ $t("Cert Exp.") }}</span> <span>{{ $t("Cert Exp.") }}</span>
<span v-if="getSortKey(group.element) === 'cert'" class="sort-indicators"> <span v-if="getSortKey(group.element) === 'cert'" class="sort-indicators">
@ -248,8 +248,6 @@ export default {
this.initializeSortSettings(); this.initializeSortSettings();
}, },
mounted() { mounted() {
// Load sort settings from URL
this.loadSortSettingsFromURL();
// Listen for URL changes // Listen for URL changes
window.addEventListener("popstate", this.handlePopState); window.addEventListener("popstate", this.handlePopState);
}, },
@ -263,46 +261,35 @@ export default {
* @returns {void} * @returns {void}
*/ */
initializeSortSettings() { initializeSortSettings() {
// Load sort settings from URL
this.loadSortSettingsFromURL();
// Set default sort values for groups not configured in URL
if (this.$root.publicGroupList) { if (this.$root.publicGroupList) {
this.$root.publicGroupList.forEach(group => { this.$root.publicGroupList.forEach(group => {
if (group) { if (group) {
// Try to read saved sort settings from localStorage // If sort settings are not defined from URL, use default settings
const savedSettings = this.getSavedSortSettings(group); if (group.sortKey === undefined) {
group.sortKey = "status";
if (savedSettings) {
// Apply saved settings
group.sortKey = savedSettings.key;
group.sortDirection = savedSettings.direction;
} else {
// Use default settings
if (group.sortKey === undefined) {
group.sortKey = "status";
}
if (group.sortDirection === undefined) {
group.sortDirection = "asc";
}
} }
if (group.sortDirection === undefined) {
group.sortDirection = "asc";
}
// Apply initial sorting // Apply initial sorting
this.applySort(group); this.applySort(group);
} }
}); });
} }
// Watch for new groups being added and initialize their sort state // Watch for new groups being added and initialize their sort state
if (this.$root) { if (this.$root) {
this.$root.$watch("publicGroupList", (newGroups) => { this.$root.$watch("publicGroupList", (newGroups) => {
if (newGroups) { if (newGroups) {
newGroups.forEach(group => { newGroups.forEach(group => {
if (group && group.sortKey === undefined) { if (group && group.sortKey === undefined) {
const savedSettings = this.getSavedSortSettings(group); group.sortKey = "status";
group.sortDirection = "asc";
if (savedSettings) {
group.sortKey = savedSettings.key;
group.sortDirection = savedSettings.direction;
} else {
group.sortKey = "status";
group.sortDirection = "asc";
}
this.applySort(group); this.applySort(group);
} }
}); });
@ -311,27 +298,6 @@ export default {
} }
}, },
/**
* Get saved sort settings from localStorage
* @param {object} group object
* @returns {object|null} saved sorting settings
*/
getSavedSortSettings(group) {
try {
const groupId = this.getGroupIdentifier(group);
const slug = this.$root.statusPage ? this.$root.statusPage.slug : "default";
const storageKey = `uptime-kuma-sort-${slug}-${groupId}`;
const savedSettings = localStorage.getItem(storageKey);
if (savedSettings) {
return JSON.parse(savedSettings);
}
} catch (error) {
console.error("Cannot read sort settings", error);
}
return null;
},
/** /**
* Get sort key for a group * Get sort key for a group
* @param {object} group object * @param {object} group object
@ -363,22 +329,8 @@ export default {
group.sortKey = key; group.sortKey = key;
group.sortDirection = "asc"; group.sortDirection = "asc";
} }
try {
const groupId = this.getGroupIdentifier(group);
const slug = this.$root.statusPage ? this.$root.statusPage.slug : "default";
const storageKey = `uptime-kuma-sort-${slug}-${groupId}`;
const sortSettings = {
key: group.sortKey,
direction: group.sortDirection
};
localStorage.setItem(storageKey, JSON.stringify(sortSettings));
} catch (error) {
console.error("Cannot save sort settings", error);
}
this.applySort(group); this.applySort(group);
this.updateURLSortParams(); this.updateURLSortParams();
}, },
@ -724,16 +676,16 @@ export default {
border: none; border: none;
outline: none; outline: none;
} }
.dark & { .dark & {
background-color: $dark-bg; background-color: $dark-bg;
color: $dark-font-color; color: $dark-font-color;
box-shadow: 0 15px 70px rgba(0, 0, 0, 0.3); box-shadow: 0 15px 70px rgba(0, 0, 0, 0.3);
&:hover { &:hover {
background-color: $dark-bg2; background-color: $dark-bg2;
} }
&:focus, &:active { &:focus, &:active {
box-shadow: 0 15px 70px rgba(0, 0, 0, 0.3); box-shadow: 0 15px 70px rgba(0, 0, 0, 0.3);
} }
@ -753,7 +705,7 @@ export default {
color: #aaa; color: #aaa;
font-size: 0.7rem; font-size: 0.7rem;
opacity: 0.5; opacity: 0.5;
.dark & { .dark & {
color: #6c757d; color: #6c757d;
} }
@ -762,7 +714,7 @@ export default {
.arrow-active { .arrow-active {
color: #4caf50; color: #4caf50;
font-size: 0.8rem; font-size: 0.8rem;
.dark & { .dark & {
color: $primary; color: $primary;
} }
@ -776,7 +728,7 @@ export default {
border: none; border: none;
box-shadow: 0 15px 70px rgba(0, 0, 0, 0.1); box-shadow: 0 15px 70px rgba(0, 0, 0, 0.1);
overflow: hidden; overflow: hidden;
.dark & { .dark & {
background-color: $dark-bg; background-color: $dark-bg;
color: $dark-font-color; color: $dark-font-color;
@ -796,10 +748,10 @@ export default {
&:hover { &:hover {
background-color: #f8f9fa; background-color: #f8f9fa;
} }
.dark & { .dark & {
color: $dark-font-color; color: $dark-font-color;
&:hover { &:hover {
background-color: $dark-bg2; background-color: $dark-bg2;
} }