From dc7862db33eea87b4d91727a459fc40b6886d7a3 Mon Sep 17 00:00:00 2001 From: Unai Zalba Date: Wed, 13 Mar 2024 17:41:44 +0100 Subject: [PATCH 1/2] feat/AB#88032_ABC-disable-cross-page-filtering-in-the-app-builder-as-well feat: add Map to set any filter values for each one of the dashboards of the application in the app builder, filters are set only for each dashboard now feat: clean Map once the user exits application remove: filterValues$ observable as is not used --- .../app/application/application.component.ts | 9 ++++- .../dashboard-filter.component.ts | 4 +- .../lib/services/context/context.service.ts | 40 ++++++++++--------- 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/apps/back-office/src/app/application/application.component.ts b/apps/back-office/src/app/application/application.component.ts index ac62b70018..4304bfc59c 100644 --- a/apps/back-office/src/app/application/application.component.ts +++ b/apps/back-office/src/app/application/application.component.ts @@ -7,6 +7,7 @@ import { ApplicationService, ConfirmService, UnsubscribeComponent, + ContextService, } from '@oort-front/shared'; import get from 'lodash/get'; import { takeUntil, map } from 'rxjs/operators'; @@ -49,13 +50,15 @@ export class ApplicationComponent * @param router Angular router * @param translate Angular translate service * @param confirmService Shared confirmation service + * @param contextService ContextService */ constructor( private applicationService: ApplicationService, public route: ActivatedRoute, private router: Router, private translate: TranslateService, - private confirmService: ConfirmService + private confirmService: ConfirmService, + private contextService: ContextService ) { super(); this.largeDevice = window.innerWidth > 1024; @@ -270,12 +273,16 @@ export class ApplicationComponent return dialogRef.closed.pipe( map((confirm) => { if (confirm) { + // Clear any context filter history from current application + this.contextService.filterHistory.clear(); return true; } return false; }) ); } + // Clear any context filter history from current application + this.contextService.filterHistory.clear(); return true; } diff --git a/libs/shared/src/lib/components/dashboard-filter/dashboard-filter.component.ts b/libs/shared/src/lib/components/dashboard-filter/dashboard-filter.component.ts index c467314b1b..b8d5e01c74 100644 --- a/libs/shared/src/lib/components/dashboard-filter/dashboard-filter.component.ts +++ b/libs/shared/src/lib/components/dashboard-filter/dashboard-filter.component.ts @@ -326,9 +326,7 @@ export class DashboardFilterComponent const currentSurveyQuestions = this.survey.getAllQuestions(); const nextFilterValue: any = surveyData; // Don't merge current context filter values to the filter if survey has init and it's used in web component - if ( - !(this.surveyInit && this.contextService.shadowDomService.isShadowRoot) - ) { + if (!this.surveyInit) { const currentFilterValue = this.contextService.filter.value; const filterKeys = Object.keys(currentFilterValue); filterKeys diff --git a/libs/shared/src/lib/services/context/context.service.ts b/libs/shared/src/lib/services/context/context.service.ts index 049eb7f395..56a2b8e53f 100644 --- a/libs/shared/src/lib/services/context/context.service.ts +++ b/libs/shared/src/lib/services/context/context.service.ts @@ -12,8 +12,6 @@ import { get, isEqual, isObject, - forEach, - set, has, isArray, every, @@ -55,7 +53,7 @@ export class ContextService { dashboardId: string; } | null>(null); /** To keep the history of previous dashboard filter values */ - public filterValues = new BehaviorSubject(null); + public filterHistory = new Map(); /** Is filter opened */ public filterOpened = new BehaviorSubject(false); /** Web component filter surveys */ @@ -108,11 +106,6 @@ export class ContextService { return this.filterPosition.asObservable(); } - /** @returns filterValues value as observable */ - get filterValues$() { - return this.filterValues.asObservable(); - } - /** @returns filterOpened value as observable */ get filterOpened$() { return this.filterOpened.asObservable(); @@ -422,20 +415,31 @@ export class ContextService { */ public initSurvey(structure: any): SurveyModel { const survey = this.formBuilderService.createSurvey(structure); - // set each question value manually otherwise the defaultValueExpression is not loaded + // Create unique identifier key using current question names + const surveyModelQuestions = JSON.stringify( + survey.getAllQuestions().map((qu) => qu.name) ?? {} + ); if (!this.shadowDomService.isShadowRoot) { - forEach(this.filterValues.getValue(), (value, key) => { - if (survey.getQuestionByName(key)) { - survey.getQuestionByName(key).value = value; - } - }); + if (this.filterHistory.has(surveyModelQuestions)) { + const previousSurveyValue = + this.filterHistory.get(surveyModelQuestions); + survey.data = previousSurveyValue; + } else { + this.filterHistory.set(surveyModelQuestions, { + ...survey.data, + }); + } } - // prevent the default value from being applied when a question has been intentionally cleared const handleValueChanged = (sender: any, options: any) => { - const history = this.filterValues.getValue() ?? {}; - set(history, options.name, options.value); - this.filterValues.next(history); + if (this.filterHistory.has(surveyModelQuestions)) { + const previousSurveyValue = + this.filterHistory.get(surveyModelQuestions); + this.filterHistory.set(surveyModelQuestions, { + ...previousSurveyValue, + [options.name]: options.value, + }); + } }; survey.onValueChanged.add(handleValueChanged); From 18eeb4610da7cf5af0eec5c8e3f2a271a1efbc28 Mon Sep 17 00:00:00 2001 From: Unai Zalba Date: Thu, 14 Mar 2024 12:17:04 +0100 Subject: [PATCH 2/2] feat/AB#88032_ABC-disable-cross-page-filtering-in-the-app-builder-as-well fix: use current unique dashboard id to save filter values instead survey questions as keys, as could be that same questions be set in different dashboards --- .../pages/dashboard/dashboard.component.ts | 1 + .../pages/dashboard/dashboard.component.ts | 1 + .../lib/services/context/context.service.ts | 28 ++++++++++--------- .../services/dashboard/dashboard.service.ts | 2 ++ 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/apps/back-office/src/app/app-preview/pages/dashboard/dashboard.component.ts b/apps/back-office/src/app/app-preview/pages/dashboard/dashboard.component.ts index 2fadac1366..5cb70f122d 100644 --- a/apps/back-office/src/app/app-preview/pages/dashboard/dashboard.component.ts +++ b/apps/back-office/src/app/app-preview/pages/dashboard/dashboard.component.ts @@ -70,6 +70,7 @@ export class DashboardComponent this.route.params.pipe(takeUntil(this.destroy$)).subscribe((params) => { this.loading = true; this.id = params.id; + this.dashboardService.currentDashboardId = this.id; this.apollo .query({ query: GET_DASHBOARD_BY_ID, diff --git a/apps/back-office/src/app/dashboard/pages/dashboard/dashboard.component.ts b/apps/back-office/src/app/dashboard/pages/dashboard/dashboard.component.ts index a6db74fa84..3cdd7f9342 100644 --- a/apps/back-office/src/app/dashboard/pages/dashboard/dashboard.component.ts +++ b/apps/back-office/src/app/dashboard/pages/dashboard/dashboard.component.ts @@ -249,6 +249,7 @@ export class DashboardComponent .then(({ data }) => { if (data.dashboard) { this.id = data.dashboard.id || id; + this.dashboardService.currentDashboardId = this.id; this.dashboard = data.dashboard; this.gridOptions = { ...omit(this.gridOptions, ['gridType', 'minimumHeight']), // Prevent issue when gridType or minimumHeight was not set diff --git a/libs/shared/src/lib/services/context/context.service.ts b/libs/shared/src/lib/services/context/context.service.ts index ff7685c657..198cbd721c 100644 --- a/libs/shared/src/lib/services/context/context.service.ts +++ b/libs/shared/src/lib/services/context/context.service.ts @@ -36,6 +36,7 @@ import { ApplicationService } from '../application/application.service'; import { ActivatedRoute, Router } from '@angular/router'; import { RecordQueryResponse } from '../../models/record.model'; import { GET_RECORD_BY_ID } from './graphql/queries'; +import { DashboardService } from '../dashboard/dashboard.service'; /** * Dashboard context service @@ -139,6 +140,7 @@ export class ContextService { * @param applicationService Shared application service * @param router Angular router * @param {ShadowDomService} shadowDomService Shadow dom service containing the current DOM host + * @param dashboardService Shared dashboard service */ constructor( private dialog: Dialog, @@ -148,7 +150,8 @@ export class ContextService { private formBuilderService: FormBuilderService, private applicationService: ApplicationService, private router: Router, - public shadowDomService: ShadowDomService + public shadowDomService: ShadowDomService, + private dashboardService: DashboardService ) { this.filterPosition$.subscribe( (value: { position: FilterPosition; dashboardId: string } | null) => { @@ -419,27 +422,26 @@ export class ContextService { */ public initSurvey(structure: any): SurveyModel { const survey = this.formBuilderService.createSurvey(structure); - // Create unique identifier key using current question names - const surveyModelQuestions = JSON.stringify( - survey.getAllQuestions().map((qu) => qu.name) ?? {} - ); + if (!this.shadowDomService.isShadowRoot) { - if (this.filterHistory.has(surveyModelQuestions)) { - const previousSurveyValue = - this.filterHistory.get(surveyModelQuestions); + if (this.filterHistory.has(this.dashboardService.currentDashboardId)) { + const previousSurveyValue = this.filterHistory.get( + this.dashboardService.currentDashboardId + ); survey.data = previousSurveyValue; } else { - this.filterHistory.set(surveyModelQuestions, { + this.filterHistory.set(this.dashboardService.currentDashboardId, { ...survey.data, }); } } // prevent the default value from being applied when a question has been intentionally cleared const handleValueChanged = (sender: any, options: any) => { - if (this.filterHistory.has(surveyModelQuestions)) { - const previousSurveyValue = - this.filterHistory.get(surveyModelQuestions); - this.filterHistory.set(surveyModelQuestions, { + if (this.filterHistory.has(this.dashboardService.currentDashboardId)) { + const previousSurveyValue = this.filterHistory.get( + this.dashboardService.currentDashboardId + ); + this.filterHistory.set(this.dashboardService.currentDashboardId, { ...previousSurveyValue, [options.name]: options.value, }); diff --git a/libs/shared/src/lib/services/dashboard/dashboard.service.ts b/libs/shared/src/lib/services/dashboard/dashboard.service.ts index 9f015a9e1d..55abeee5b4 100644 --- a/libs/shared/src/lib/services/dashboard/dashboard.service.ts +++ b/libs/shared/src/lib/services/dashboard/dashboard.service.ts @@ -31,6 +31,8 @@ export class DashboardService { public widgets: BehaviorSubject = new BehaviorSubject([]); /** Observable of current loaded dashboard widgets */ public widgets$ = this.widgets.asObservable(); + /** Current dashboard id in the view */ + public currentDashboardId = ''; /** @returns To listen when dashboard widgets that can be hidden refreshes its contents */ get widgetContentRefreshed$(): Observable {