From b17cdf58480f7929fed4f13499b97fe631d53a72 Mon Sep 17 00:00:00 2001 From: Greg Schueler Date: Fri, 1 Dec 2023 17:11:06 -0800 Subject: [PATCH 1/6] local storage job filters --- .../src/library/stores/JobListFilterStore.ts | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 rundeckapp/grails-spa/packages/ui-trellis/src/library/stores/JobListFilterStore.ts diff --git a/rundeckapp/grails-spa/packages/ui-trellis/src/library/stores/JobListFilterStore.ts b/rundeckapp/grails-spa/packages/ui-trellis/src/library/stores/JobListFilterStore.ts new file mode 100644 index 00000000000..420c767987b --- /dev/null +++ b/rundeckapp/grails-spa/packages/ui-trellis/src/library/stores/JobListFilterStore.ts @@ -0,0 +1,102 @@ +import { InjectionKey } from "vue"; + +export const STORAGE_JOB_FILTER_KEY = "job-filters"; + +export type JobListFilter = { + name: string; + query: { [key: string]: string }; +}; +export type StoredJobFilters = { + [project: string]: JobListFilter[]; +}; + +export interface JobListFilterLoader { + load(): Promise; + + store(filters: StoredJobFilters): Promise; +} + +export class JobListFilterLocalStorage implements JobListFilterLoader { + async load(): Promise { + const settings = localStorage.getItem(STORAGE_JOB_FILTER_KEY); + + if (settings) { + try { + return JSON.parse(settings); + } catch (e) { + localStorage.removeItem(STORAGE_JOB_FILTER_KEY); + } + } + return {}; + } + + async store(jobFilters: StoredJobFilters): Promise { + localStorage.setItem( + STORAGE_JOB_FILTER_KEY, + JSON.stringify(jobFilters) + ); + } +} + +export class JobListFilterStore { + private readonly project: string; + private readonly jobStorageLoader: JobListFilterLoader; + loaded: boolean = false; + filters: StoredJobFilters = {}; + + constructor(project: string, jobStorageLoader: JobListFilterLoader) { + this.project = project; + this.jobStorageLoader = jobStorageLoader; + } + + async load(): Promise { + if (!this.loaded) { + this.filters = await this.jobStorageLoader.load(); + this.loaded = true; + } + return this.filters; + } + + async modified() { + await this.jobStorageLoader.store(this.filters); + } + + getFilters(): JobListFilter[] { + return this.filters[this.project] || []; + } + + hasFilter(name: string): boolean { + return ( + this.filters[this.project]?.some((f) => f.name === name) || false + ); + } + + getFilter(name: string): JobListFilter|null { + return this.filters[this.project]?.find((f) => f.name === name) || null; + } + + saveFilter(filter: JobListFilter) { + if (!this.filters[this.project]) { + this.filters[this.project] = [filter]; + } else { + this.filters[this.project].push(filter); + } + + this.modified(); + } + + deleteFilter(name: string) { + if (!this.filters[this.project]) { + return; + } else { + this.filters[this.project] = this.filters[this.project].filter( + (f) => f.name !== name + ); + } + + this.modified(); + } +} + +export const JobListFilterStoreInjectionKey: InjectionKey = + Symbol("jobListFilterStore"); From 3b3e96dbe4056546cc005f6927758b4c18359a7a Mon Sep 17 00:00:00 2001 From: Greg Schueler Date: Fri, 1 Dec 2023 17:12:20 -0800 Subject: [PATCH 2/6] Add job filters to next-ui for job list page --- .../pages/job/browse/JobFilterSaveModal.vue | 77 ++++++++++++ .../pages/job/browse/JobPageFiltersPopup.vue | 88 +++++++++++++ .../app/pages/job/browse/JobSearchModal.vue | 14 ++- .../app/pages/job/browse/JobsPageHeader.vue | 118 ++++++++++++++---- .../src/app/pages/job/browse/main.ts | 11 +- .../src/app/utilities/locales/en_US.js | 4 + .../src/library/stores/JobPageStore.ts | 1 + 7 files changed, 287 insertions(+), 26 deletions(-) create mode 100644 rundeckapp/grails-spa/packages/ui-trellis/src/app/pages/job/browse/JobFilterSaveModal.vue create mode 100644 rundeckapp/grails-spa/packages/ui-trellis/src/app/pages/job/browse/JobPageFiltersPopup.vue diff --git a/rundeckapp/grails-spa/packages/ui-trellis/src/app/pages/job/browse/JobFilterSaveModal.vue b/rundeckapp/grails-spa/packages/ui-trellis/src/app/pages/job/browse/JobFilterSaveModal.vue new file mode 100644 index 00000000000..1094aedc5d7 --- /dev/null +++ b/rundeckapp/grails-spa/packages/ui-trellis/src/app/pages/job/browse/JobFilterSaveModal.vue @@ -0,0 +1,77 @@ + + + + + diff --git a/rundeckapp/grails-spa/packages/ui-trellis/src/app/pages/job/browse/JobPageFiltersPopup.vue b/rundeckapp/grails-spa/packages/ui-trellis/src/app/pages/job/browse/JobPageFiltersPopup.vue new file mode 100644 index 00000000000..84e3a32e5eb --- /dev/null +++ b/rundeckapp/grails-spa/packages/ui-trellis/src/app/pages/job/browse/JobPageFiltersPopup.vue @@ -0,0 +1,88 @@ + + + + + diff --git a/rundeckapp/grails-spa/packages/ui-trellis/src/app/pages/job/browse/JobSearchModal.vue b/rundeckapp/grails-spa/packages/ui-trellis/src/app/pages/job/browse/JobSearchModal.vue index 34794fb22f3..55bf9b6c4a3 100644 --- a/rundeckapp/grails-spa/packages/ui-trellis/src/app/pages/job/browse/JobSearchModal.vue +++ b/rundeckapp/grails-spa/packages/ui-trellis/src/app/pages/job/browse/JobSearchModal.vue @@ -170,12 +170,17 @@ {{ $t("job.filter.apply.button.title") }} + + + {{ $t("job.filter.save.button.title") }} + diff --git a/rundeckapp/grails-spa/packages/ui-trellis/src/app/pages/job/browse/JobsPageHeader.vue b/rundeckapp/grails-spa/packages/ui-trellis/src/app/pages/job/browse/JobsPageHeader.vue index 3d026bc899d..1563d7e6c2d 100644 --- a/rundeckapp/grails-spa/packages/ui-trellis/src/app/pages/job/browse/JobsPageHeader.vue +++ b/rundeckapp/grails-spa/packages/ui-trellis/src/app/pages/job/browse/JobsPageHeader.vue @@ -3,7 +3,7 @@
-
+
- +