From 08c8e04c825c7832f6e5ba42731bb8b34fa2123b Mon Sep 17 00:00:00 2001 From: RidhamShah Date: Wed, 30 Oct 2024 10:19:40 +0530 Subject: [PATCH 01/10] implemented signals for import-feature-flag --- frontend/package.json | 7 +- .../feature-flags/feature-flags.module.ts | 3 +- .../store/feature-flag.signal.store.ts | 94 +++++++++++++++++++ .../import-feature-flag-modal.component.ts | 28 ++++-- 4 files changed, 122 insertions(+), 10 deletions(-) create mode 100644 frontend/projects/upgrade/src/app/core/feature-flags/store/feature-flag.signal.store.ts diff --git a/frontend/package.json b/frontend/package.json index 2933962710..76c7814808 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -48,9 +48,11 @@ "@angular/platform-browser-dynamic": "^17.1.2", "@angular/router": "^17.1.2", "@danielmoncada/angular-datetime-picker": "^17.0.0", + "@ngrx/component-store": "^18.0.2", "@ngrx/effects": "^17.1.0", "@ngrx/entity": "^17.1.0", "@ngrx/router-store": "^17.1.0", + "@ngrx/signals": "^18.0.2", "@ngrx/store": "^17.1.0", "@ngrx/store-devtools": "^17.1.0", "@ngx-translate/core": "^15.0.0", @@ -69,6 +71,7 @@ "lodash.isequal": "^4.5.0", "ngx-skeleton-loader": "^9.0.0", "rxjs": "7.8.1", + "signals": "^1.0.0", "tslib": "^2.6.2", "uuid": "^9.0.1", "zone.js": "^0.14.3" @@ -101,12 +104,12 @@ "jest-environment-jsdom": "^29.5.0", "jest-preset-angular": "^13.1.4", "npm-run-all": "^4.1.5", + "replace-in-file": "^6.1.0", "rimraf": "^3.0.2", "standard-version": "^9.5.0", "ts-jest": "^29.0.8", "ts-node": "~10.8.0", "typescript": "~5.3.3", - "webpack-bundle-analyzer": "^4.6.1", - "replace-in-file": "^6.1.0" + "webpack-bundle-analyzer": "^4.6.1" } } diff --git a/frontend/projects/upgrade/src/app/core/feature-flags/feature-flags.module.ts b/frontend/projects/upgrade/src/app/core/feature-flags/feature-flags.module.ts index 4f3f243f47..dac975042d 100644 --- a/frontend/projects/upgrade/src/app/core/feature-flags/feature-flags.module.ts +++ b/frontend/projects/upgrade/src/app/core/feature-flags/feature-flags.module.ts @@ -6,6 +6,7 @@ import { EffectsModule } from '@ngrx/effects'; import { StoreModule } from '@ngrx/store'; import { featureFlagsReducer } from './store/feature-flags.reducer'; import { FeatureFlagsEffects } from './store/feature-flags.effects'; +import { FeatureFlagsStore } from './store/feature-flag.signal.store'; @NgModule({ declarations: [], @@ -14,6 +15,6 @@ import { FeatureFlagsEffects } from './store/feature-flags.effects'; EffectsModule.forFeature([FeatureFlagsEffects]), StoreModule.forFeature('featureFlags', featureFlagsReducer), ], - providers: [FeatureFlagsService, FeatureFlagsDataService], + providers: [FeatureFlagsService, FeatureFlagsDataService, FeatureFlagsStore], }) export class FeatureFlagsModule {} diff --git a/frontend/projects/upgrade/src/app/core/feature-flags/store/feature-flag.signal.store.ts b/frontend/projects/upgrade/src/app/core/feature-flags/store/feature-flag.signal.store.ts new file mode 100644 index 0000000000..6a57062692 --- /dev/null +++ b/frontend/projects/upgrade/src/app/core/feature-flags/store/feature-flag.signal.store.ts @@ -0,0 +1,94 @@ +import { FeatureFlag } from './feature-flags.model'; +import { FeatureFlagsDataService } from '../feature-flags.data.service'; +import { Injectable } from '@angular/core'; +import { ComponentStore } from '@ngrx/component-store'; +import { Observable, tap } from 'rxjs'; +import { IFeatureFlagFile } from 'upgrade_types'; +import { switchMap } from 'rxjs'; + +type FeatureFlagState = { + featureFlags: FeatureFlag[]; + isLoading: boolean; + importResults: { fileName: string; error: string | null }[]; +}; + +// const initialState: FeatureFlagState = { +// featureFlags: [], +// isLoading: false, +// }; + +@Injectable() +export class FeatureFlagsStore extends ComponentStore { + constructor(private featureFlagsDataService: FeatureFlagsDataService) { + super({ featureFlags: [], isLoading: false, importResults: [] }); + } + + // selectors + readonly featureFlags = this.selectSignal((state) => state.featureFlags); + readonly isLoading = this.selectSignal((state) => state.isLoading); + readonly importResults = this.selectSignal((state) => state.importResults); + + // computed + readonly featureFlagCount = this.selectSignal((state) => state.featureFlags.length); + + // Updaters + readonly setFeatureFlags = this.updater((state, featureFlags: FeatureFlag[]) => ({ + ...state, + featureFlags, + })); + + readonly setLoading = this.updater((state, loading: boolean) => ({ + ...state, + loading, + })); + + readonly setImportResults = this.updater((state, importResults: { fileName: string; error: string | null }[]) => ({ + ...state, + importResults, + })); + + // effects + + // Effect for Import Feature Flags + readonly importFeatureFlags = this.effect((featureFlagFiles$: Observable<{ files: IFeatureFlagFile[] }>) => { + return featureFlagFiles$.pipe( + tap(() => this.setLoading(true)), + switchMap((featureFlagFiles) => + this.featureFlagsDataService.importFeatureFlag(featureFlagFiles).pipe( + tap({ + next: (importResults: { fileName: string; error: string | null }[]) => { + this.setImportResults(importResults); + this.setLoading(false); + }, + error: (error) => { + console.log('Error importing feature flags', error); + // this.setError(error.message || 'An error occurred'); + this.setLoading(false); + }, + }) + ) + ) + ); + }); +} + +// export const featureFlagStore = signalStore( +// withState(initialState), +// withComputed(({ featureFlags }) => ({ +// featureFlagCount: computed(() => featureFlags().length), +// })), +// withMethods((store, service = inject(FeatureFlagsDataService)) => ({ +// async fetchFeatureFlags() { +// patchState(store, { isLoading: true }); +// const featureFlags = await service.fetchFeatureFlagsPaginated({ skip: 0, take: 10 }); +// patchState(store, { featureFlags.nodes, isLoading: false }); +// }, + +// async addFeatureFlag(flag: FeatureFlag) { +// patchState(store, { isLoading: true }); +// const newFlag = toSignal(await service.addFeatureFlag(flag)); +// patchState(store, (state) => ({ featureFlags: [ ...state.featureFlags, newFlag() ] })); +// } +// }) +// ) +// ); diff --git a/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.ts b/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.ts index 51413cc912..634606353d 100644 --- a/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.ts +++ b/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.ts @@ -1,4 +1,4 @@ -import { ChangeDetectionStrategy, Component, Inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, effect, Inject } from '@angular/core'; import { CommonModalComponent, CommonStatusIndicatorChipComponent, @@ -16,6 +16,7 @@ import { ValidateFeatureFlagError } from '../../../../../core/feature-flags/stor import { importError } from '../../../../../core/segments/store/segments.model'; import { NotificationService } from '../../../../../core/notifications/notification.service'; import { IFeatureFlagFile } from 'upgrade_types'; +import { FeatureFlagsStore } from '../../../../../core/feature-flags/store/feature-flag.signal.store'; @Component({ selector: 'app-import-feature-flag-modal', @@ -51,8 +52,18 @@ export class ImportFeatureFlagModalComponent { public featureFlagsService: FeatureFlagsService, public featureFlagsDataService: FeatureFlagsDataService, public dialogRef: MatDialogRef, - private notificationService: NotificationService - ) {} + private notificationService: NotificationService, + private featureFlagStore: FeatureFlagsStore + ) { + effect( + () => { + if (this.featureFlagStore.importResults().length > 0) { + this.showNotification(this.featureFlagStore.importResults()); + } + }, + { allowSignalWrites: true } + ); + } async handleFilesSelected(event) { if (event.length > 0) { @@ -113,11 +124,12 @@ export class ImportFeatureFlagModalComponent { async importFiles() { try { this.isImportActionBtnDisabled.next(true); - const importResult = (await firstValueFrom( - this.featureFlagsDataService.importFeatureFlag({ files: this.fileData }) - )) as importError[]; + this.featureFlagStore.importFeatureFlags({ files: this.fileData }); + // const importResult = (await firstValueFrom( + // this.featureFlagsDataService.importFeatureFlag({ files: this.fileData }) + // )) as importError[]; - this.showNotification(importResult); + //this.showNotification([]); this.isImportActionBtnDisabled.next(false); this.uploadedFileCount.next(0); this.fileData = []; @@ -143,6 +155,8 @@ export class ImportFeatureFlagModalComponent { importFailedFiles.forEach((data) => { this.notificationService.showError(`Failed to import ${data.fileName}: ${data.error}`); }); + + this.featureFlagStore.setImportResults([]); } closeModal() { From b08ef88b2b61415c69bae6ff398425986d8ed887 Mon Sep 17 00:00:00 2001 From: RidhamShah Date: Wed, 30 Oct 2024 10:22:04 +0530 Subject: [PATCH 02/10] added package json files --- frontend/package-lock.json | 49 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index de5266fec4..13d976d7f3 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -20,9 +20,11 @@ "@angular/platform-browser-dynamic": "^17.1.2", "@angular/router": "^17.1.2", "@danielmoncada/angular-datetime-picker": "^17.0.0", + "@ngrx/component-store": "^18.0.2", "@ngrx/effects": "^17.1.0", "@ngrx/entity": "^17.1.0", "@ngrx/router-store": "^17.1.0", + "@ngrx/signals": "^18.0.2", "@ngrx/store": "^17.1.0", "@ngrx/store-devtools": "^17.1.0", "@ngx-translate/core": "^15.0.0", @@ -41,6 +43,7 @@ "lodash.isequal": "^4.5.0", "ngx-skeleton-loader": "^9.0.0", "rxjs": "7.8.1", + "signals": "^1.0.0", "tslib": "^2.6.2", "uuid": "^9.0.1", "zone.js": "^0.14.3" @@ -4435,6 +4438,30 @@ "tslib": "^2.1.0" } }, + "node_modules/@ngrx/component-store": { + "version": "18.0.2", + "resolved": "https://registry.npmjs.org/@ngrx/component-store/-/component-store-18.0.2.tgz", + "integrity": "sha512-IB7ZKFqjDt4duQbfYqXxAOKf9Si9O1HFodqbNCSgi7gnovK/frf/H429a+lYOyItPcpno3ECom6/1k8pE8fWlg==", + "dependencies": { + "@ngrx/operators": "18.0.1", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "@angular/core": "^18.0.0", + "rxjs": "^6.5.3 || ^7.5.0" + } + }, + "node_modules/@ngrx/component-store/node_modules/@ngrx/operators": { + "version": "18.0.1", + "resolved": "https://registry.npmjs.org/@ngrx/operators/-/operators-18.0.1.tgz", + "integrity": "sha512-M+QMrHNKgcuiLaRGZxJ4aQi5/OCRfKC4+T/63dsHyLFZ53/FFpF6a/ytSO1Q+tzOplZ5o99S+i8FVaZqNQ3LmQ==", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "rxjs": "^6.5.3 || ^7.4.0" + } + }, "node_modules/@ngrx/effects": { "version": "17.1.1", "resolved": "https://registry.npmjs.org/@ngrx/effects/-/effects-17.1.1.tgz", @@ -4488,6 +4515,23 @@ "rxjs": "^6.5.3 || ^7.5.0" } }, + "node_modules/@ngrx/signals": { + "version": "18.0.2", + "resolved": "https://registry.npmjs.org/@ngrx/signals/-/signals-18.0.2.tgz", + "integrity": "sha512-FXmcY2cmkbhZtg9k8Ntq69SyelGmmb6fWtdButH4T8GGFH0o3f1FZTR829j4ynphy8SzuDhD/pzrnpWcV481oQ==", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/core": "^18.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + }, + "peerDependenciesMeta": { + "rxjs": { + "optional": true + } + } + }, "node_modules/@ngrx/store": { "version": "17.1.1", "resolved": "https://registry.npmjs.org/@ngrx/store/-/store-17.1.1.tgz", @@ -17224,6 +17268,11 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "node_modules/signals": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/signals/-/signals-1.0.0.tgz", + "integrity": "sha512-dE3lBiqgrgIvpGHYBy6/kiYKfh0HXRmbg0ocakBKiOefbal6ZeTtNlQlxsu9ADkNzv5OmRwRKu+IaTPSqJdZDg==" + }, "node_modules/sigstore": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-2.2.2.tgz", From 5e703e7e332dab2661a1c6226b46bf74c2faee32 Mon Sep 17 00:00:00 2001 From: Vivek Fitkariwala Date: Wed, 30 Oct 2024 13:01:15 +0530 Subject: [PATCH 03/10] =?UTF-8?q?=E2=AC=87=EF=B8=8F=20Downgrade=20ngrx=20s?= =?UTF-8?q?ignal=20and=20ngrx=20components?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/package-lock.json | 35 +++++++++++++---------------------- frontend/package.json | 4 ++-- 2 files changed, 15 insertions(+), 24 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 13d976d7f3..d5b39fb20a 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -20,11 +20,11 @@ "@angular/platform-browser-dynamic": "^17.1.2", "@angular/router": "^17.1.2", "@danielmoncada/angular-datetime-picker": "^17.0.0", - "@ngrx/component-store": "^18.0.2", + "@ngrx/component-store": "^17.2.0", "@ngrx/effects": "^17.1.0", "@ngrx/entity": "^17.1.0", "@ngrx/router-store": "^17.1.0", - "@ngrx/signals": "^18.0.2", + "@ngrx/signals": "^17.2.0", "@ngrx/store": "^17.1.0", "@ngrx/store-devtools": "^17.1.0", "@ngx-translate/core": "^15.0.0", @@ -4439,29 +4439,19 @@ } }, "node_modules/@ngrx/component-store": { - "version": "18.0.2", - "resolved": "https://registry.npmjs.org/@ngrx/component-store/-/component-store-18.0.2.tgz", - "integrity": "sha512-IB7ZKFqjDt4duQbfYqXxAOKf9Si9O1HFodqbNCSgi7gnovK/frf/H429a+lYOyItPcpno3ECom6/1k8pE8fWlg==", + "version": "17.2.0", + "resolved": "https://registry.npmjs.org/@ngrx/component-store/-/component-store-17.2.0.tgz", + "integrity": "sha512-ywhyoZpkbVIY1t5zf7xfWLGkY0A/fQdMjPehHloDI6bRLrmbllBhQRazwZ+FAGIi2myx1+mGcmAc6FbtIikedA==", + "license": "MIT", "dependencies": { - "@ngrx/operators": "18.0.1", + "@ngrx/operators": "17.0.0-beta.0", "tslib": "^2.0.0" }, "peerDependencies": { - "@angular/core": "^18.0.0", + "@angular/core": "^17.0.0", "rxjs": "^6.5.3 || ^7.5.0" } }, - "node_modules/@ngrx/component-store/node_modules/@ngrx/operators": { - "version": "18.0.1", - "resolved": "https://registry.npmjs.org/@ngrx/operators/-/operators-18.0.1.tgz", - "integrity": "sha512-M+QMrHNKgcuiLaRGZxJ4aQi5/OCRfKC4+T/63dsHyLFZ53/FFpF6a/ytSO1Q+tzOplZ5o99S+i8FVaZqNQ3LmQ==", - "dependencies": { - "tslib": "^2.3.0" - }, - "peerDependencies": { - "rxjs": "^6.5.3 || ^7.4.0" - } - }, "node_modules/@ngrx/effects": { "version": "17.1.1", "resolved": "https://registry.npmjs.org/@ngrx/effects/-/effects-17.1.1.tgz", @@ -4516,14 +4506,15 @@ } }, "node_modules/@ngrx/signals": { - "version": "18.0.2", - "resolved": "https://registry.npmjs.org/@ngrx/signals/-/signals-18.0.2.tgz", - "integrity": "sha512-FXmcY2cmkbhZtg9k8Ntq69SyelGmmb6fWtdButH4T8GGFH0o3f1FZTR829j4ynphy8SzuDhD/pzrnpWcV481oQ==", + "version": "17.2.0", + "resolved": "https://registry.npmjs.org/@ngrx/signals/-/signals-17.2.0.tgz", + "integrity": "sha512-tkkxifeOVPOhpTqbHyK1WOx4qz49HLR/h0vhaa/MRGRIZoOR/6gR4KB3hbC8FD3FdnuNqOgOZ2lGsTfWPB/6BQ==", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, "peerDependencies": { - "@angular/core": "^18.0.0", + "@angular/core": "^17.0.0", "rxjs": "^6.5.3 || ^7.4.0" }, "peerDependenciesMeta": { diff --git a/frontend/package.json b/frontend/package.json index 76c7814808..da2db4d79e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -48,11 +48,11 @@ "@angular/platform-browser-dynamic": "^17.1.2", "@angular/router": "^17.1.2", "@danielmoncada/angular-datetime-picker": "^17.0.0", - "@ngrx/component-store": "^18.0.2", + "@ngrx/component-store": "^17.2.0", "@ngrx/effects": "^17.1.0", "@ngrx/entity": "^17.1.0", "@ngrx/router-store": "^17.1.0", - "@ngrx/signals": "^18.0.2", + "@ngrx/signals": "^17.2.0", "@ngrx/store": "^17.1.0", "@ngrx/store-devtools": "^17.1.0", "@ngx-translate/core": "^15.0.0", From 391e280b31906ebfcc2015fb3a296a2e0d48899f Mon Sep 17 00:00:00 2001 From: RidhamShah Date: Tue, 5 Nov 2024 10:58:27 +0530 Subject: [PATCH 04/10] remove commented-out code --- .../store/feature-flag.signal.store.ts | 26 ------------------- .../import-feature-flag-modal.component.ts | 4 --- 2 files changed, 30 deletions(-) diff --git a/frontend/projects/upgrade/src/app/core/feature-flags/store/feature-flag.signal.store.ts b/frontend/projects/upgrade/src/app/core/feature-flags/store/feature-flag.signal.store.ts index 6a57062692..0acdaad78e 100644 --- a/frontend/projects/upgrade/src/app/core/feature-flags/store/feature-flag.signal.store.ts +++ b/frontend/projects/upgrade/src/app/core/feature-flags/store/feature-flag.signal.store.ts @@ -12,11 +12,6 @@ type FeatureFlagState = { importResults: { fileName: string; error: string | null }[]; }; -// const initialState: FeatureFlagState = { -// featureFlags: [], -// isLoading: false, -// }; - @Injectable() export class FeatureFlagsStore extends ComponentStore { constructor(private featureFlagsDataService: FeatureFlagsDataService) { @@ -71,24 +66,3 @@ export class FeatureFlagsStore extends ComponentStore { ); }); } - -// export const featureFlagStore = signalStore( -// withState(initialState), -// withComputed(({ featureFlags }) => ({ -// featureFlagCount: computed(() => featureFlags().length), -// })), -// withMethods((store, service = inject(FeatureFlagsDataService)) => ({ -// async fetchFeatureFlags() { -// patchState(store, { isLoading: true }); -// const featureFlags = await service.fetchFeatureFlagsPaginated({ skip: 0, take: 10 }); -// patchState(store, { featureFlags.nodes, isLoading: false }); -// }, - -// async addFeatureFlag(flag: FeatureFlag) { -// patchState(store, { isLoading: true }); -// const newFlag = toSignal(await service.addFeatureFlag(flag)); -// patchState(store, (state) => ({ featureFlags: [ ...state.featureFlags, newFlag() ] })); -// } -// }) -// ) -// ); diff --git a/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.ts b/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.ts index 634606353d..01fbef4cf6 100644 --- a/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.ts +++ b/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.ts @@ -125,11 +125,7 @@ export class ImportFeatureFlagModalComponent { try { this.isImportActionBtnDisabled.next(true); this.featureFlagStore.importFeatureFlags({ files: this.fileData }); - // const importResult = (await firstValueFrom( - // this.featureFlagsDataService.importFeatureFlag({ files: this.fileData }) - // )) as importError[]; - //this.showNotification([]); this.isImportActionBtnDisabled.next(false); this.uploadedFileCount.next(0); this.fileData = []; From 71a633f6298a91ad2a0b4d97d65eefe8a2057d27 Mon Sep 17 00:00:00 2001 From: RidhamShah Date: Wed, 20 Nov 2024 14:32:52 +0530 Subject: [PATCH 05/10] reorganize feature flag store and move component logic to store --- .../feature-flags/feature-flags.module.ts | 2 +- .../store/feature-flag.signal.store.ts | 68 ------------ .../feature-flag.signal.store.ts | 105 ++++++++++++++++++ .../import-feature-flag-modal.component.html | 4 +- .../import-feature-flag-modal.component.ts | 44 ++++---- 5 files changed, 128 insertions(+), 95 deletions(-) delete mode 100644 frontend/projects/upgrade/src/app/core/feature-flags/store/feature-flag.signal.store.ts create mode 100644 frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/feature-flag.signal.store.ts diff --git a/frontend/projects/upgrade/src/app/core/feature-flags/feature-flags.module.ts b/frontend/projects/upgrade/src/app/core/feature-flags/feature-flags.module.ts index dac975042d..da705ef885 100644 --- a/frontend/projects/upgrade/src/app/core/feature-flags/feature-flags.module.ts +++ b/frontend/projects/upgrade/src/app/core/feature-flags/feature-flags.module.ts @@ -6,7 +6,7 @@ import { EffectsModule } from '@ngrx/effects'; import { StoreModule } from '@ngrx/store'; import { featureFlagsReducer } from './store/feature-flags.reducer'; import { FeatureFlagsEffects } from './store/feature-flags.effects'; -import { FeatureFlagsStore } from './store/feature-flag.signal.store'; +import { FeatureFlagsStore } from '../../features/dashboard/feature-flags/modals/import-feature-flag-modal/feature-flag.signal.store'; @NgModule({ declarations: [], diff --git a/frontend/projects/upgrade/src/app/core/feature-flags/store/feature-flag.signal.store.ts b/frontend/projects/upgrade/src/app/core/feature-flags/store/feature-flag.signal.store.ts deleted file mode 100644 index 0acdaad78e..0000000000 --- a/frontend/projects/upgrade/src/app/core/feature-flags/store/feature-flag.signal.store.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { FeatureFlag } from './feature-flags.model'; -import { FeatureFlagsDataService } from '../feature-flags.data.service'; -import { Injectable } from '@angular/core'; -import { ComponentStore } from '@ngrx/component-store'; -import { Observable, tap } from 'rxjs'; -import { IFeatureFlagFile } from 'upgrade_types'; -import { switchMap } from 'rxjs'; - -type FeatureFlagState = { - featureFlags: FeatureFlag[]; - isLoading: boolean; - importResults: { fileName: string; error: string | null }[]; -}; - -@Injectable() -export class FeatureFlagsStore extends ComponentStore { - constructor(private featureFlagsDataService: FeatureFlagsDataService) { - super({ featureFlags: [], isLoading: false, importResults: [] }); - } - - // selectors - readonly featureFlags = this.selectSignal((state) => state.featureFlags); - readonly isLoading = this.selectSignal((state) => state.isLoading); - readonly importResults = this.selectSignal((state) => state.importResults); - - // computed - readonly featureFlagCount = this.selectSignal((state) => state.featureFlags.length); - - // Updaters - readonly setFeatureFlags = this.updater((state, featureFlags: FeatureFlag[]) => ({ - ...state, - featureFlags, - })); - - readonly setLoading = this.updater((state, loading: boolean) => ({ - ...state, - loading, - })); - - readonly setImportResults = this.updater((state, importResults: { fileName: string; error: string | null }[]) => ({ - ...state, - importResults, - })); - - // effects - - // Effect for Import Feature Flags - readonly importFeatureFlags = this.effect((featureFlagFiles$: Observable<{ files: IFeatureFlagFile[] }>) => { - return featureFlagFiles$.pipe( - tap(() => this.setLoading(true)), - switchMap((featureFlagFiles) => - this.featureFlagsDataService.importFeatureFlag(featureFlagFiles).pipe( - tap({ - next: (importResults: { fileName: string; error: string | null }[]) => { - this.setImportResults(importResults); - this.setLoading(false); - }, - error: (error) => { - console.log('Error importing feature flags', error); - // this.setError(error.message || 'An error occurred'); - this.setLoading(false); - }, - }) - ) - ) - ); - }); -} diff --git a/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/feature-flag.signal.store.ts b/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/feature-flag.signal.store.ts new file mode 100644 index 0000000000..9997ab2c83 --- /dev/null +++ b/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/feature-flag.signal.store.ts @@ -0,0 +1,105 @@ +import { FeatureFlag, ValidateFeatureFlagError } from '../../../../../core/feature-flags/store/feature-flags.model'; +import { FeatureFlagsDataService } from '../../../../../core/feature-flags/feature-flags.data.service'; +import { Injectable } from '@angular/core'; +import { ComponentStore } from '@ngrx/component-store'; +import { Observable, tap } from 'rxjs'; +import { IFeatureFlagFile } from 'upgrade_types'; +import { switchMap } from 'rxjs'; +import { FeatureFlagsService } from '../../../../../core/feature-flags/feature-flags.service'; + +type FeatureFlagState = { + isLoading: boolean; + isLoadingImportFeatureFlag: boolean; + importResults: { fileName: string; error: string | null }[]; + validationErrors: ValidateFeatureFlagError[]; +}; + +@Injectable() +export class FeatureFlagsStore extends ComponentStore { + constructor( + private featureFlagsDataService: FeatureFlagsDataService, + private featureFlagsService: FeatureFlagsService + ) { + super({ isLoading: false, isLoadingImportFeatureFlag: false, importResults: [], validationErrors: [] }); + } + + // selectors + readonly isLoading = this.selectSignal((state) => state.isLoading); + readonly isLoadingImportFeatureFlag = this.selectSignal((state) => state.isLoadingImportFeatureFlag); + readonly importResults = this.selectSignal((state) => state.importResults); + readonly validationErrors = this.selectSignal((state) => state.validationErrors); + + // computed + readonly featureFlagCount = this.selectSignal((state) => state.importResults.length); + + // Updaters + readonly setFeatureFlags = this.updater((state, featureFlags: FeatureFlag[]) => ({ + ...state, + featureFlags, + })); + + readonly setLoading = this.updater((state, isLoading: boolean) => ({ + ...state, + isLoading, + })); + + readonly setLoadingImportFeatureFlag = this.updater((state, isLoadingImportFeatureFlag: boolean) => ({ + ...state, + isLoadingImportFeatureFlag, + })); + + readonly setImportResults = this.updater((state, importResults: { fileName: string; error: string | null }[]) => ({ + ...state, + importResults, + })); + + readonly setValidationErrors = this.updater((state, validationErrors: ValidateFeatureFlagError[]) => ({ + ...state, + validationErrors, + })); + + // effects + + // Effect for Import Feature Flags + readonly importFeatureFlags = this.effect((featureFlagFiles$: Observable<{ files: IFeatureFlagFile[] }>) => { + return featureFlagFiles$.pipe( + tap(() => this.setLoading(true)), + switchMap((featureFlagFiles) => + this.featureFlagsDataService.importFeatureFlag(featureFlagFiles).pipe( + tap({ + next: (importResults: { fileName: string; error: string | null }[]) => { + this.setImportResults(importResults); + this.setLoading(false); + this.featureFlagsService.fetchFeatureFlags(true); + }, + error: (error) => { + console.log('Error importing feature flags', error); + // this.setError(error.message || 'An error occurred'); + this.setLoading(false); + }, + }) + ) + ) + ); + }); + + readonly validateFeatureFlags = this.effect((featureFlagFiles$: Observable) => { + return featureFlagFiles$.pipe( + tap(() => this.setLoading(true)), + switchMap((files) => + this.featureFlagsDataService.validateFeatureFlag({ files }).pipe( + tap({ + next: (validationErrors: ValidateFeatureFlagError[]) => { + this.setValidationErrors(validationErrors); + this.setLoading(false); + }, + error: (error) => { + console.error('Error during validation:', error); + this.setLoading(false); + }, + }) + ) + ) + ); + }); +} diff --git a/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.html b/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.html index 7f1581c123..926d2d0e52 100644 --- a/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.html +++ b/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.html @@ -7,8 +7,8 @@ (primaryActionBtnClicked)="importFiles()" >
- - + + (); fileValidationErrors: ValidateFeatureFlagError[] = []; fileData: IFeatureFlagFile[] = []; - uploadedFileCount = new BehaviorSubject(0); - isLoadingImportFeatureFlag$ = this.featureFlagsService.isLoadingImportFeatureFlag$; - isImportActionBtnDisabled$: Observable = combineLatest([ - this.uploadedFileCount, - this.isLoadingImportFeatureFlag$, - ]).pipe(map(([uploadedCount, isLoading]) => isLoading || uploadedCount === 0)); + uploadedFileCount = signal(0); + isLoadingImportFeatureFlag$ = this.featureFlagStore.isLoadingImportFeatureFlag; + isImportActionBtnDisabled$ = computed(() => { + const uploadedCount = this.uploadedFileCount(); + const isLoading = this.isLoadingImportFeatureFlag$(); + return isLoading || uploadedCount === 0; + }); constructor( @Inject(MAT_DIALOG_DATA) public data: CommonModalConfig, - public featureFlagsService: FeatureFlagsService, - public featureFlagsDataService: FeatureFlagsDataService, public dialogRef: MatDialogRef, private notificationService: NotificationService, private featureFlagStore: FeatureFlagsStore @@ -60,6 +57,9 @@ export class ImportFeatureFlagModalComponent { if (this.featureFlagStore.importResults().length > 0) { this.showNotification(this.featureFlagStore.importResults()); } + if (this.featureFlagStore.validationErrors().length > 0) { + this.checkValidation(this.featureFlagStore.validationErrors()); + } }, { allowSignalWrites: true } ); @@ -68,10 +68,10 @@ export class ImportFeatureFlagModalComponent { async handleFilesSelected(event) { if (event.length > 0) { this.isImportActionBtnDisabled.next(false); - this.featureFlagsService.setIsLoadingImportFeatureFlag(true); + this.featureFlagStore.setLoadingImportFeatureFlag(true); } - this.uploadedFileCount.next(event.length); + this.uploadedFileCount.set(event.length); this.fileValidationErrors = []; this.fileData = []; @@ -92,17 +92,14 @@ export class ImportFeatureFlagModalComponent { }) ); - await this.checkValidation(this.fileData); + this.featureFlagStore.validateFeatureFlags(this.fileData); } - async checkValidation(files: IFeatureFlagFile[]) { + async checkValidation(validationErrors: ValidateFeatureFlagError[]) { try { - const validationErrors = (await firstValueFrom( - this.featureFlagsDataService.validateFeatureFlag({ files: files }) - )) as ValidateFeatureFlagError[]; this.fileValidationErrors = validationErrors.filter((data) => data.compatibilityType != null) || []; this.fileValidationErrorDataSource.data = this.fileValidationErrors; - this.featureFlagsService.setIsLoadingImportFeatureFlag(false); + this.featureFlagStore.setLoadingImportFeatureFlag(false); if (this.fileValidationErrors.length > 0) { this.fileValidationErrors.forEach((error) => { @@ -113,8 +110,9 @@ export class ImportFeatureFlagModalComponent { } } catch (error) { console.error('Error during validation:', error); - this.featureFlagsService.setIsLoadingImportFeatureFlag(false); + this.featureFlagStore.setLoadingImportFeatureFlag(false); } + this.featureFlagStore.setValidationErrors([]); } toggleExpand() { @@ -127,7 +125,6 @@ export class ImportFeatureFlagModalComponent { this.featureFlagStore.importFeatureFlags({ files: this.fileData }); this.isImportActionBtnDisabled.next(false); - this.uploadedFileCount.next(0); this.fileData = []; } catch (error) { console.error('Error during import:', error); @@ -142,7 +139,6 @@ export class ImportFeatureFlagModalComponent { if (importSuccessFiles.length > 0) { importSuccessMsg = `Successfully imported ${importSuccessFiles.length} file/s: ${importSuccessFiles.join(', ')}`; this.closeModal(); - this.featureFlagsService.fetchFeatureFlags(true); } this.notificationService.showSuccess(importSuccessMsg); From 43d2e67122eb5f43c20b5e71b8c50421f8deb78f Mon Sep 17 00:00:00 2001 From: RidhamShah Date: Mon, 25 Nov 2024 09:53:22 +0530 Subject: [PATCH 06/10] Add import and validation effects for feature flag lists in the store --- .../feature-flag.signal.store.ts | 58 ++++++++++++++++++- .../import-feature-flag-modal.component.ts | 30 ++++------ 2 files changed, 68 insertions(+), 20 deletions(-) diff --git a/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/feature-flag.signal.store.ts b/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/feature-flag.signal.store.ts index 9997ab2c83..b0683813c6 100644 --- a/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/feature-flag.signal.store.ts +++ b/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/feature-flag.signal.store.ts @@ -3,7 +3,7 @@ import { FeatureFlagsDataService } from '../../../../../core/feature-flags/featu import { Injectable } from '@angular/core'; import { ComponentStore } from '@ngrx/component-store'; import { Observable, tap } from 'rxjs'; -import { IFeatureFlagFile } from 'upgrade_types'; +import { FEATURE_FLAG_LIST_FILTER_MODE, IFeatureFlagFile } from 'upgrade_types'; import { switchMap } from 'rxjs'; import { FeatureFlagsService } from '../../../../../core/feature-flags/feature-flags.service'; @@ -83,6 +83,34 @@ export class FeatureFlagsStore extends ComponentStore { ); }); + readonly importFeatureFlagList = this.effect( + ( + params$: Observable<{ + fileData: IFeatureFlagFile[]; + flagId: string; + listType: FEATURE_FLAG_LIST_FILTER_MODE; + }> + ) => { + return params$.pipe( + tap(() => this.setLoadingImportFeatureFlag(true)), + switchMap(({ fileData, flagId, listType }) => + this.featureFlagsDataService.importFeatureFlagList(fileData, flagId, listType).pipe( + tap({ + next: (importResults: { fileName: string; error: string | null }[]) => { + this.setImportResults(importResults); + this.setLoadingImportFeatureFlag(false); + }, + error: (error) => { + console.error('Error importing feature flag list:', error); + this.setLoadingImportFeatureFlag(false); + }, + }) + ) + ) + ); + } + ); + readonly validateFeatureFlags = this.effect((featureFlagFiles$: Observable) => { return featureFlagFiles$.pipe( tap(() => this.setLoading(true)), @@ -102,4 +130,32 @@ export class FeatureFlagsStore extends ComponentStore { ) ); }); + + readonly validateFeatureFlagList = this.effect( + ( + params$: Observable<{ + fileData: IFeatureFlagFile[]; + flagId: string; + listType: FEATURE_FLAG_LIST_FILTER_MODE; + }> + ) => { + return params$.pipe( + tap(() => this.setLoading(true)), + switchMap(({ fileData, flagId, listType }) => + this.featureFlagsDataService.validateFeatureFlagList(fileData, flagId, listType).pipe( + tap({ + next: (validationErrors: ValidateFeatureFlagError[]) => { + this.setValidationErrors(validationErrors); + this.setLoading(false); + }, + error: (error) => { + console.error('Error validating feature flag list:', error); + this.setLoading(false); + }, + }) + ) + ) + ); + } + ); } diff --git a/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.ts b/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.ts index 22002e2ba6..1b062ccb02 100644 --- a/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.ts +++ b/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.ts @@ -3,7 +3,7 @@ import { CommonModalComponent, CommonStatusIndicatorChipComponent, } from '../../../../../shared-standalone-component-lib/components'; -import { BehaviorSubject, firstValueFrom } from 'rxjs'; +import { BehaviorSubject } from 'rxjs'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { CommonModule } from '@angular/common'; import { SharedModule } from '../../../../../shared/shared.module'; @@ -15,7 +15,6 @@ import { importError, ImportListParams } from '../../../../../core/segments/stor import { NotificationService } from '../../../../../core/notifications/notification.service'; import { IFeatureFlagFile } from 'upgrade_types'; import { FeatureFlagsStore } from './feature-flag.signal.store'; -import { FeatureFlagsDataService } from '../../../../../core/feature-flags/feature-flags.data.service'; @Component({ selector: 'app-import-feature-flag-modal', @@ -49,7 +48,6 @@ export class ImportFeatureFlagModalComponent { constructor( @Inject(MAT_DIALOG_DATA) public data: CommonModalConfig, - private featureFlagsDataService: FeatureFlagsDataService, public dialogRef: MatDialogRef, private notificationService: NotificationService, private featureFlagStore: FeatureFlagsStore @@ -97,14 +95,11 @@ export class ImportFeatureFlagModalComponent { if (this.data.title === 'Import Feature Flag') { this.featureFlagStore.validateFeatureFlags(this.fileData); } else if (this.data.title === 'Import List') { - const validationErrors = (await firstValueFrom( - this.featureFlagsDataService.validateFeatureFlagList( - this.fileData, - this.data.params.flagId, - this.data.params.listType - ) - )) as ValidateFeatureFlagError[]; - this.checkValidation(validationErrors); + this.featureFlagStore.validateFeatureFlagList({ + fileData: this.fileData, + flagId: this.data.params.flagId, + listType: this.data.params.listType, + }); } } @@ -139,14 +134,11 @@ export class ImportFeatureFlagModalComponent { if (this.data.title === 'Import Feature Flag') { this.featureFlagStore.importFeatureFlags({ files: this.fileData }); } else if (this.data.title === 'Import List') { - const importResult: importError[] = (await firstValueFrom( - this.featureFlagsDataService.importFeatureFlagList( - this.fileData, - this.data.params.flagId, - this.data.params.listType - ) - )) as importError[]; - this.showNotification(importResult); + this.featureFlagStore.importFeatureFlagList({ + fileData: this.fileData, + flagId: this.data.params.flagId, + listType: this.data.params.listType, + }); } this.isImportActionBtnDisabled.next(false); From bfbdb03f281c43e3e1971b2792a1ecfd29556ede Mon Sep 17 00:00:00 2001 From: RidhamShah Date: Tue, 26 Nov 2024 10:31:02 +0530 Subject: [PATCH 07/10] Add modelType to ImportListParams and update modal logic for feature flag imports --- .../src/app/core/segments/store/segments.model.ts | 6 ++++++ .../import-feature-flag-modal.component.ts | 10 +++++----- .../src/app/shared/services/common-dialog.service.ts | 10 ++++++---- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/frontend/projects/upgrade/src/app/core/segments/store/segments.model.ts b/frontend/projects/upgrade/src/app/core/segments/store/segments.model.ts index 8738e72137..b4738eb92d 100644 --- a/frontend/projects/upgrade/src/app/core/segments/store/segments.model.ts +++ b/frontend/projects/upgrade/src/app/core/segments/store/segments.model.ts @@ -175,6 +175,7 @@ export interface UpsertPrivateSegmentListParams { export interface ImportListParams { listType: FEATURE_FLAG_LIST_FILTER_MODE; flagId: string; + modelType?: MODEL_TYPE; } export enum LIST_OPTION_TYPE { @@ -182,6 +183,11 @@ export enum LIST_OPTION_TYPE { SEGMENT = 'Segment', } +export enum MODEL_TYPE { + LIST = 'List', + FEATURE_FLAG = 'Feature Flag', +} + export const PRIVATE_SEGMENT_LIST_FORM_FIELDS = { LIST_TYPE: 'listType', SEGMENT: 'segment', diff --git a/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.ts b/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.ts index 1b062ccb02..6ad143029f 100644 --- a/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.ts +++ b/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.ts @@ -11,7 +11,7 @@ import { CommonImportContainerComponent } from '../../../../../shared-standalone import { CommonModalConfig } from '../../../../../shared-standalone-component-lib/components/common-modal/common-modal.types'; import { MatTableDataSource } from '@angular/material/table'; import { ValidateFeatureFlagError } from '../../../../../core/feature-flags/store/feature-flags.model'; -import { importError, ImportListParams } from '../../../../../core/segments/store/segments.model'; +import { importError, ImportListParams, MODEL_TYPE } from '../../../../../core/segments/store/segments.model'; import { NotificationService } from '../../../../../core/notifications/notification.service'; import { IFeatureFlagFile } from 'upgrade_types'; import { FeatureFlagsStore } from './feature-flag.signal.store'; @@ -92,9 +92,9 @@ export class ImportFeatureFlagModalComponent { }) ); - if (this.data.title === 'Import Feature Flag') { + if (this.data.params.modelType === MODEL_TYPE.FEATURE_FLAG) { this.featureFlagStore.validateFeatureFlags(this.fileData); - } else if (this.data.title === 'Import List') { + } else if (this.data.params.modelType === MODEL_TYPE.LIST) { this.featureFlagStore.validateFeatureFlagList({ fileData: this.fileData, flagId: this.data.params.flagId, @@ -131,9 +131,9 @@ export class ImportFeatureFlagModalComponent { try { this.isImportActionBtnDisabled.next(true); - if (this.data.title === 'Import Feature Flag') { + if (this.data.params.modelType === MODEL_TYPE.FEATURE_FLAG) { this.featureFlagStore.importFeatureFlags({ files: this.fileData }); - } else if (this.data.title === 'Import List') { + } else if (this.data.params.modelType === MODEL_TYPE.LIST) { this.featureFlagStore.importFeatureFlagList({ fileData: this.fileData, flagId: this.data.params.flagId, diff --git a/frontend/projects/upgrade/src/app/shared/services/common-dialog.service.ts b/frontend/projects/upgrade/src/app/shared/services/common-dialog.service.ts index ef2fbfb47c..a5c678fc62 100644 --- a/frontend/projects/upgrade/src/app/shared/services/common-dialog.service.ts +++ b/frontend/projects/upgrade/src/app/shared/services/common-dialog.service.ts @@ -6,6 +6,7 @@ import { ImportFeatureFlagModalComponent } from '../../features/dashboard/featur import { UpsertFeatureFlagModalComponent } from '../../features/dashboard/feature-flags/modals/upsert-feature-flag-modal/upsert-feature-flag-modal.component'; import { UpsertPrivateSegmentListModalComponent } from '../../features/dashboard/segments/modals/upsert-private-segment-list-modal/upsert-private-segment-list-modal.component'; import { + MODEL_TYPE, UPSERT_PRIVATE_SEGMENT_LIST_ACTION, UpsertPrivateSegmentListParams, } from '../../core/segments/store/segments.model'; @@ -353,18 +354,18 @@ export class DialogService { } openImportFeatureFlagModal() { - return this.openImportModal('Import Feature Flag', null, null); + return this.openImportModal('Import Feature Flag', null, null, MODEL_TYPE.FEATURE_FLAG); } openImportFeatureFlagIncludeListModal(flagId: string) { - return this.openImportModal('Import List', FEATURE_FLAG_LIST_FILTER_MODE.INCLUSION, flagId); + return this.openImportModal('Import List', FEATURE_FLAG_LIST_FILTER_MODE.INCLUSION, flagId, MODEL_TYPE.LIST); } openImportFeatureFlagExcludeListModal(flagId: string) { - return this.openImportModal('Import List', FEATURE_FLAG_LIST_FILTER_MODE.EXCLUSION, flagId); + return this.openImportModal('Import List', FEATURE_FLAG_LIST_FILTER_MODE.EXCLUSION, flagId, MODEL_TYPE.LIST); } - openImportModal(title: string, listType: FEATURE_FLAG_LIST_FILTER_MODE, flagId: string) { + openImportModal(title: string, listType: FEATURE_FLAG_LIST_FILTER_MODE, flagId: string, modelType?: MODEL_TYPE) { const commonModalConfig: CommonModalConfig = { title: title, primaryActionBtnLabel: 'Import', @@ -373,6 +374,7 @@ export class DialogService { params: { listType: listType, flagId: flagId, + modelType: modelType, }, }; From 3734005131c88ee75f06f78178232410dc910990 Mon Sep 17 00:00:00 2001 From: RidhamShah Date: Wed, 27 Nov 2024 08:58:11 +0530 Subject: [PATCH 08/10] solved git comments for module --- .../upgrade/src/app/core/feature-flags/feature-flags.module.ts | 3 +-- .../upgrade/src/app/shared/services/common-dialog.service.ts | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/frontend/projects/upgrade/src/app/core/feature-flags/feature-flags.module.ts b/frontend/projects/upgrade/src/app/core/feature-flags/feature-flags.module.ts index da705ef885..4f3f243f47 100644 --- a/frontend/projects/upgrade/src/app/core/feature-flags/feature-flags.module.ts +++ b/frontend/projects/upgrade/src/app/core/feature-flags/feature-flags.module.ts @@ -6,7 +6,6 @@ import { EffectsModule } from '@ngrx/effects'; import { StoreModule } from '@ngrx/store'; import { featureFlagsReducer } from './store/feature-flags.reducer'; import { FeatureFlagsEffects } from './store/feature-flags.effects'; -import { FeatureFlagsStore } from '../../features/dashboard/feature-flags/modals/import-feature-flag-modal/feature-flag.signal.store'; @NgModule({ declarations: [], @@ -15,6 +14,6 @@ import { FeatureFlagsStore } from '../../features/dashboard/feature-flags/modals EffectsModule.forFeature([FeatureFlagsEffects]), StoreModule.forFeature('featureFlags', featureFlagsReducer), ], - providers: [FeatureFlagsService, FeatureFlagsDataService, FeatureFlagsStore], + providers: [FeatureFlagsService, FeatureFlagsDataService], }) export class FeatureFlagsModule {} diff --git a/frontend/projects/upgrade/src/app/shared/services/common-dialog.service.ts b/frontend/projects/upgrade/src/app/shared/services/common-dialog.service.ts index a5c678fc62..78c440cf23 100644 --- a/frontend/projects/upgrade/src/app/shared/services/common-dialog.service.ts +++ b/frontend/projects/upgrade/src/app/shared/services/common-dialog.service.ts @@ -365,7 +365,7 @@ export class DialogService { return this.openImportModal('Import List', FEATURE_FLAG_LIST_FILTER_MODE.EXCLUSION, flagId, MODEL_TYPE.LIST); } - openImportModal(title: string, listType: FEATURE_FLAG_LIST_FILTER_MODE, flagId: string, modelType?: MODEL_TYPE) { + openImportModal(title: string, listType: FEATURE_FLAG_LIST_FILTER_MODE, flagId: string, modelType: MODEL_TYPE) { const commonModalConfig: CommonModalConfig = { title: title, primaryActionBtnLabel: 'Import', From 1fc99a02aa749d9e5f3979134b72e5d1dc183954 Mon Sep 17 00:00:00 2001 From: RidhamShah Date: Thu, 28 Nov 2024 20:21:59 +0530 Subject: [PATCH 09/10] Remove loading state for import feature flags from old store --- .../src/app/core/feature-flags/feature-flags.module.ts | 3 ++- .../src/app/core/feature-flags/feature-flags.service.ts | 6 ------ .../app/core/feature-flags/store/feature-flags.actions.ts | 5 ----- .../src/app/core/feature-flags/store/feature-flags.model.ts | 1 - .../app/core/feature-flags/store/feature-flags.reducer.ts | 5 ----- .../app/core/feature-flags/store/feature-flags.selectors.ts | 5 ----- .../src/app/core/local-storage/local-storage.service.ts | 1 - 7 files changed, 2 insertions(+), 24 deletions(-) diff --git a/frontend/projects/upgrade/src/app/core/feature-flags/feature-flags.module.ts b/frontend/projects/upgrade/src/app/core/feature-flags/feature-flags.module.ts index 4f3f243f47..da705ef885 100644 --- a/frontend/projects/upgrade/src/app/core/feature-flags/feature-flags.module.ts +++ b/frontend/projects/upgrade/src/app/core/feature-flags/feature-flags.module.ts @@ -6,6 +6,7 @@ import { EffectsModule } from '@ngrx/effects'; import { StoreModule } from '@ngrx/store'; import { featureFlagsReducer } from './store/feature-flags.reducer'; import { FeatureFlagsEffects } from './store/feature-flags.effects'; +import { FeatureFlagsStore } from '../../features/dashboard/feature-flags/modals/import-feature-flag-modal/feature-flag.signal.store'; @NgModule({ declarations: [], @@ -14,6 +15,6 @@ import { FeatureFlagsEffects } from './store/feature-flags.effects'; EffectsModule.forFeature([FeatureFlagsEffects]), StoreModule.forFeature('featureFlags', featureFlagsReducer), ], - providers: [FeatureFlagsService, FeatureFlagsDataService], + providers: [FeatureFlagsService, FeatureFlagsDataService, FeatureFlagsStore], }) export class FeatureFlagsModule {} diff --git a/frontend/projects/upgrade/src/app/core/feature-flags/feature-flags.service.ts b/frontend/projects/upgrade/src/app/core/feature-flags/feature-flags.service.ts index 2d85183a4b..1182948775 100644 --- a/frontend/projects/upgrade/src/app/core/feature-flags/feature-flags.service.ts +++ b/frontend/projects/upgrade/src/app/core/feature-flags/feature-flags.service.ts @@ -22,7 +22,6 @@ import { selectSortKey, selectSortAs, selectAppContexts, - selectIsLoadingImportFeatureFlag, selectFeatureFlagIds, selectShouldShowWarningForSelectedFlag, selectWarningStatusForAllFlags, @@ -56,7 +55,6 @@ export class FeatureFlagsService { isLoadingUpsertFeatureFlag$ = this.store$.pipe(select(selectIsLoadingUpsertFeatureFlag)); isDuplicateKeyFound$ = this.store$.pipe(select(selectDuplicateKeyFound)); isLoadingFeatureFlagDelete$ = this.store$.pipe(select(selectIsLoadingFeatureFlagDelete)); - isLoadingImportFeatureFlag$ = this.store$.pipe(select(selectIsLoadingImportFeatureFlag)); isLoadingUpdateFeatureFlagStatus$ = this.store$.pipe(select(selectIsLoadingUpdateFeatureFlagStatus)); isLoadingUpsertPrivateSegmentList$ = this.store$.pipe(select(selectIsLoadingUpsertFeatureFlag)); allFeatureFlags$ = this.store$.pipe(select(selectAllFeatureFlagsSortedByDate)); @@ -152,10 +150,6 @@ export class FeatureFlagsService { this.store$.dispatch(FeatureFlagsActions.actionDeleteFeatureFlag({ flagId })); } - setIsLoadingImportFeatureFlag(isLoadingImportFeatureFlag: boolean) { - this.store$.dispatch(FeatureFlagsActions.actionSetIsLoadingImportFeatureFlag({ isLoadingImportFeatureFlag })); - } - emailFeatureFlagData(featureFlagId: string) { this.store$.dispatch(FeatureFlagsActions.actionEmailFeatureFlagData({ featureFlagId })); } diff --git a/frontend/projects/upgrade/src/app/core/feature-flags/store/feature-flags.actions.ts b/frontend/projects/upgrade/src/app/core/feature-flags/store/feature-flags.actions.ts index 8eb5cc2bf2..25bb63fe10 100644 --- a/frontend/projects/upgrade/src/app/core/feature-flags/store/feature-flags.actions.ts +++ b/frontend/projects/upgrade/src/app/core/feature-flags/store/feature-flags.actions.ts @@ -71,11 +71,6 @@ export const actionUpdateFeatureFlagSuccess = createAction( export const actionUpdateFeatureFlagFailure = createAction('[Feature Flags] Update Feature Flag Failure'); -export const actionSetIsLoadingImportFeatureFlag = createAction( - '[Feature Flags] Set Is Loading for Flag Import', - props<{ isLoadingImportFeatureFlag: boolean }>() -); - export const actionEmailFeatureFlagData = createAction( '[Feature Flags] Email Feature Flag Data', props<{ featureFlagId: string }>() diff --git a/frontend/projects/upgrade/src/app/core/feature-flags/store/feature-flags.model.ts b/frontend/projects/upgrade/src/app/core/feature-flags/store/feature-flags.model.ts index c04f82e479..a367cc31ae 100644 --- a/frontend/projects/upgrade/src/app/core/feature-flags/store/feature-flags.model.ts +++ b/frontend/projects/upgrade/src/app/core/feature-flags/store/feature-flags.model.ts @@ -181,7 +181,6 @@ export const FLAG_ROOT_DISPLAYED_COLUMNS = Object.values(FLAG_ROOT_COLUMN_NAMES) export interface FeatureFlagState extends EntityState { isLoadingUpsertFeatureFlag: boolean; - isLoadingImportFeatureFlag: boolean; isLoadingSelectedFeatureFlag: boolean; isLoadingFeatureFlags: boolean; isLoadingUpdateFeatureFlagStatus: boolean; diff --git a/frontend/projects/upgrade/src/app/core/feature-flags/store/feature-flags.reducer.ts b/frontend/projects/upgrade/src/app/core/feature-flags/store/feature-flags.reducer.ts index 4244219965..5c5f1983fa 100644 --- a/frontend/projects/upgrade/src/app/core/feature-flags/store/feature-flags.reducer.ts +++ b/frontend/projects/upgrade/src/app/core/feature-flags/store/feature-flags.reducer.ts @@ -12,7 +12,6 @@ export const { selectIds, selectEntities, selectAll, selectTotal } = adapter.get export const initialState: FeatureFlagState = adapter.getInitialState({ isLoadingUpsertFeatureFlag: false, - isLoadingImportFeatureFlag: false, isLoadingFeatureFlags: false, isLoadingUpdateFeatureFlagStatus: false, isLoadingFeatureFlagDetail: false, @@ -121,10 +120,6 @@ const reducer = createReducer( ...state, isLoadingFeatureFlags, })), - on(FeatureFlagsActions.actionSetIsLoadingImportFeatureFlag, (state, { isLoadingImportFeatureFlag }) => ({ - ...state, - isLoadingImportFeatureFlag, - })), on(FeatureFlagsActions.actionSetSkipFlags, (state, { skipFlags }) => ({ ...state, skipFlags })), on(FeatureFlagsActions.actionSetSearchKey, (state, { searchKey }) => ({ ...state, searchKey })), on(FeatureFlagsActions.actionSetSearchString, (state, { searchString }) => ({ ...state, searchValue: searchString })), diff --git a/frontend/projects/upgrade/src/app/core/feature-flags/store/feature-flags.selectors.ts b/frontend/projects/upgrade/src/app/core/feature-flags/store/feature-flags.selectors.ts index 770cb9e0ed..bf4e431335 100644 --- a/frontend/projects/upgrade/src/app/core/feature-flags/store/feature-flags.selectors.ts +++ b/frontend/projects/upgrade/src/app/core/feature-flags/store/feature-flags.selectors.ts @@ -118,11 +118,6 @@ export const selectFeatureFlagsListLength = createSelector( (featureFlags) => featureFlags.length ); -export const selectIsLoadingImportFeatureFlag = createSelector( - selectFeatureFlagsState, - (state) => state.isLoadingImportFeatureFlag -); - export const selectIsLoadingUpdateFeatureFlagStatus = createSelector( selectFeatureFlagsState, (state) => state.isLoadingUpdateFeatureFlagStatus diff --git a/frontend/projects/upgrade/src/app/core/local-storage/local-storage.service.ts b/frontend/projects/upgrade/src/app/core/local-storage/local-storage.service.ts index f5a26eea7b..dd7074c533 100755 --- a/frontend/projects/upgrade/src/app/core/local-storage/local-storage.service.ts +++ b/frontend/projects/upgrade/src/app/core/local-storage/local-storage.service.ts @@ -61,7 +61,6 @@ export class LocalStorageService { ids: [], entities: {}, isLoadingUpsertFeatureFlag: false, - isLoadingImportFeatureFlag: false, isLoadingSelectedFeatureFlag: false, isLoadingFeatureFlags: false, isLoadingUpdateFeatureFlagStatus: false, From d9ecf8b50bbd9d13815b5b17d608002c236710bc Mon Sep 17 00:00:00 2001 From: RidhamShah Date: Mon, 2 Dec 2024 09:26:22 +0530 Subject: [PATCH 10/10] remove store from module --- .../upgrade/src/app/core/feature-flags/feature-flags.module.ts | 3 +-- .../import-feature-flag-modal.component.ts | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/projects/upgrade/src/app/core/feature-flags/feature-flags.module.ts b/frontend/projects/upgrade/src/app/core/feature-flags/feature-flags.module.ts index da705ef885..4f3f243f47 100644 --- a/frontend/projects/upgrade/src/app/core/feature-flags/feature-flags.module.ts +++ b/frontend/projects/upgrade/src/app/core/feature-flags/feature-flags.module.ts @@ -6,7 +6,6 @@ import { EffectsModule } from '@ngrx/effects'; import { StoreModule } from '@ngrx/store'; import { featureFlagsReducer } from './store/feature-flags.reducer'; import { FeatureFlagsEffects } from './store/feature-flags.effects'; -import { FeatureFlagsStore } from '../../features/dashboard/feature-flags/modals/import-feature-flag-modal/feature-flag.signal.store'; @NgModule({ declarations: [], @@ -15,6 +14,6 @@ import { FeatureFlagsStore } from '../../features/dashboard/feature-flags/modals EffectsModule.forFeature([FeatureFlagsEffects]), StoreModule.forFeature('featureFlags', featureFlagsReducer), ], - providers: [FeatureFlagsService, FeatureFlagsDataService, FeatureFlagsStore], + providers: [FeatureFlagsService, FeatureFlagsDataService], }) export class FeatureFlagsModule {} diff --git a/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.ts b/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.ts index 6ad143029f..cfaff9df68 100644 --- a/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.ts +++ b/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.ts @@ -28,6 +28,7 @@ import { FeatureFlagsStore } from './feature-flag.signal.store'; ], templateUrl: './import-feature-flag-modal.component.html', styleUrls: ['./import-feature-flag-modal.component.scss'], + providers: [FeatureFlagsStore], changeDetection: ChangeDetectionStrategy.OnPush, }) export class ImportFeatureFlagModalComponent {