Skip to content

Commit db687ed

Browse files
committed
feat: persistent dashboard collapse setting
Signed-off-by: Olivier Vernin <olivier@vernin.me>
1 parent 7335804 commit db687ed

File tree

1 file changed

+61
-5
lines changed

1 file changed

+61
-5
lines changed

src/components/scm/_summary.vue

Lines changed: 61 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@
116116
</v-icon>
117117
</div>
118118
</v-col>
119+
</v-row>
120+
<v-row>
119121
<v-col>
120122
<div class="status-summary">
121123
<v-chip
@@ -272,6 +274,7 @@ import { getApiBaseURL } from '@/composables/api';
272274
ChartJS.register(RadialLinearScale, ArcElement, Tooltip, Legend)
273275
274276
const EMPTY_DONUT_DATA = Object.freeze({ labels: [], datasets: [] });
277+
const COLLAPSE_STORAGE_KEY = 'udash:scm-summary-collapse-state';
275278
276279
export default {
277280
components: {
@@ -322,6 +325,7 @@ export default {
322325
loadedPages: new Set(),
323326
isFetching: false,
324327
hasSearched: false,
328+
collapseAllByDefault: true,
325329
collapsedRepositories: {},
326330
visibleBranchesByRepo: {},
327331
initialBranchPageSize: 10,
@@ -372,10 +376,46 @@ export default {
372376
this.data = {};
373377
this.doughnutData = {};
374378
this.hasSearched = true;
375-
this.collapsedRepositories = {};
376379
this.visibleBranchesByRepo = {};
377380
},
378381
382+
loadPersistedCollapseState() {
383+
try {
384+
const rawValue = localStorage.getItem(COLLAPSE_STORAGE_KEY);
385+
if (!rawValue) {
386+
return;
387+
}
388+
389+
const savedState = JSON.parse(rawValue);
390+
391+
if (typeof savedState.collapseAllByDefault === 'boolean') {
392+
this.collapseAllByDefault = savedState.collapseAllByDefault;
393+
}
394+
395+
if (savedState.collapsedRepositories && typeof savedState.collapsedRepositories === 'object' && !Array.isArray(savedState.collapsedRepositories)) {
396+
this.collapsedRepositories = Object.fromEntries(
397+
Object.entries(savedState.collapsedRepositories).filter(([url, isCollapsed]) => typeof url === 'string' && typeof isCollapsed === 'boolean')
398+
);
399+
}
400+
} catch (error) {
401+
console.warn('Unable to restore persisted SCM collapse state', error);
402+
}
403+
},
404+
405+
persistCollapseState() {
406+
try {
407+
const stateToPersist = {
408+
collapseAllByDefault: this.collapseAllByDefault,
409+
collapsedRepositories: this.collapsedRepositories,
410+
updatedAt: new Date().toISOString(),
411+
};
412+
413+
localStorage.setItem(COLLAPSE_STORAGE_KEY, JSON.stringify(stateToPersist));
414+
} catch (error) {
415+
console.warn('Unable to persist SCM collapse state', error);
416+
}
417+
},
418+
379419
countLoadedScmBranches(allScmData) {
380420
return Object.values(allScmData || {}).reduce((total, scmData) => {
381421
if (!scmData || typeof scmData !== 'object') {
@@ -403,15 +443,24 @@ export default {
403443
return false;
404444
}
405445
406-
return this.collapsedRepositories[url] !== false;
446+
if (Object.prototype.hasOwnProperty.call(this.collapsedRepositories, url)) {
447+
return this.collapsedRepositories[url];
448+
}
449+
450+
return this.collapseAllByDefault;
407451
},
408452
409453
toggleRepo(url) {
410-
this.collapsedRepositories[url] = !this.isRepoCollapsed(url);
454+
this.collapsedRepositories = {
455+
...this.collapsedRepositories,
456+
[url]: !this.isRepoCollapsed(url),
457+
};
411458
412459
if (!this.visibleBranchesByRepo[url]) {
413460
this.visibleBranchesByRepo[url] = this.initialBranchPageSize;
414461
}
462+
463+
this.persistCollapseState();
415464
},
416465
417466
areAllReposCollapsed() {
@@ -425,14 +474,20 @@ export default {
425474
426475
toggleAllRepos() {
427476
const collapseAll = !this.areAllReposCollapsed();
477+
const collapsedRepositories = { ...this.collapsedRepositories };
478+
479+
this.collapseAllByDefault = collapseAll;
428480
429481
Object.keys(this.data || {}).forEach((url) => {
430-
this.collapsedRepositories[url] = collapseAll;
482+
collapsedRepositories[url] = collapseAll;
431483
432484
if (!this.visibleBranchesByRepo[url]) {
433485
this.visibleBranchesByRepo[url] = this.initialBranchPageSize;
434486
}
435487
});
488+
489+
this.collapsedRepositories = collapsedRepositories;
490+
this.persistCollapseState();
436491
},
437492
438493
visibleBranchCount(url) {
@@ -744,6 +799,7 @@ export default {
744799
},
745800
},
746801
async created() {
802+
this.loadPersistedCollapseState();
747803
this.resetPagination();
748804
await this.loadNextPage();
749805
},
@@ -801,7 +857,7 @@ export default {
801857
802858
.status-summary {
803859
max-width: 220px;
804-
margin-left: auto;
860+
margin-right: auto;
805861
display: flex;
806862
flex-direction: column;
807863
align-items: flex-end;

0 commit comments

Comments
 (0)