@provoly/dashboard 0.23.2 → 0.23.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/admin/components/admin-dataset/admin-select-dataset/admin-select-dataset.component.d.ts +11 -7
  2. package/admin/i18n/fr.translations.d.ts +1 -0
  3. package/assets/svgs/six_dot.svg +15 -0
  4. package/esm2022/admin/components/admin-dataset/admin-select-dataset/admin-select-dataset.component.mjs +9 -4
  5. package/esm2022/admin/i18n/fr.translations.mjs +3 -2
  6. package/esm2022/admin/store/admin.effects.mjs +2 -2
  7. package/esm2022/lib/core/components/share/group-share/group-share.component.mjs +28 -15
  8. package/esm2022/lib/core/components/share/share.model.mjs +1 -1
  9. package/esm2022/lib/core/components/share/share.utils.mjs +19 -0
  10. package/esm2022/lib/core/i18n/en.translations.mjs +7 -2
  11. package/esm2022/lib/core/i18n/fr.translations.mjs +7 -2
  12. package/esm2022/lib/core/public-api.mjs +2 -1
  13. package/esm2022/lib/core/store/data-source/data-source.actions.mjs +2 -2
  14. package/esm2022/lib/core/store/data-source/data-source.effects.mjs +2 -2
  15. package/esm2022/lib/core/store/data-source/data-source.reducer.mjs +3 -3
  16. package/esm2022/lib/core/store/data-source/data-source.selectors.mjs +3 -3
  17. package/esm2022/lib/core/store/data-source/data-source.service.mjs +1 -1
  18. package/esm2022/lib/dashboard/store/dashboard.effects.mjs +32 -9
  19. package/esm2022/lib/dashboard/store/manifest.service.mjs +14 -12
  20. package/esm2022/presentation/components/presentation.component.mjs +23 -4
  21. package/esm2022/toolbox/components/save-view/save-view.component.mjs +1 -1
  22. package/esm2022/toolbox/components/share/share.component.mjs +1 -1
  23. package/fesm2022/provoly-dashboard-admin.mjs +11 -5
  24. package/fesm2022/provoly-dashboard-admin.mjs.map +1 -1
  25. package/fesm2022/provoly-dashboard-presentation.mjs +22 -3
  26. package/fesm2022/provoly-dashboard-presentation.mjs.map +1 -1
  27. package/fesm2022/provoly-dashboard-toolbox.mjs +2 -2
  28. package/fesm2022/provoly-dashboard-toolbox.mjs.map +1 -1
  29. package/fesm2022/provoly-dashboard.mjs +107 -41
  30. package/fesm2022/provoly-dashboard.mjs.map +1 -1
  31. package/lib/core/components/share/group-share/group-share.component.d.ts +12 -3
  32. package/lib/core/components/share/share.model.d.ts +2 -2
  33. package/lib/core/components/share/share.utils.d.ts +4 -0
  34. package/lib/core/i18n/en.translations.d.ts +5 -0
  35. package/lib/core/i18n/fr.translations.d.ts +5 -0
  36. package/lib/core/public-api.d.ts +1 -0
  37. package/lib/core/store/data-source/data-source.actions.d.ts +5 -5
  38. package/lib/core/store/data-source/data-source.effects.d.ts +3 -3
  39. package/lib/core/store/data-source/data-source.reducer.d.ts +2 -2
  40. package/lib/core/store/data-source/data-source.selectors.d.ts +1 -1
  41. package/lib/dashboard/store/dashboard.effects.d.ts +2 -1
  42. package/lib/dashboard/store/manifest.service.d.ts +2 -5
  43. package/package.json +43 -43
  44. package/presentation/components/presentation.component.d.ts +5 -1
  45. package/styles-theme/components-theme/_a-btn.theme.scss +0 -1
@@ -475,7 +475,12 @@ const enTranslations$1 = {
475
475
  public: 'Public',
476
476
  restricted: 'Restricted',
477
477
  type: 'Visibility',
478
- users: 'Authorized users'
478
+ users: 'Authorized users',
479
+ conflict: {
480
+ title: 'Warning',
481
+ main: 'The following data sources are not accessible to the selected user groups:',
482
+ unavailable: 'inaccessible aux groupes : '
483
+ }
479
484
  },
480
485
  homepage: {
481
486
  menu: {
@@ -866,7 +871,12 @@ const frTranslations$1 = {
866
871
  public: 'Public',
867
872
  restricted: 'Restreint',
868
873
  type: 'Visibilité',
869
- users: 'Utilisateurs autorisés'
874
+ users: 'Utilisateurs autorisés',
875
+ conflict: {
876
+ title: 'Warning',
877
+ main: 'Attention, les sources de données suivantes ne seront pas visible de toutes les personnes accédant à la présentation : ',
878
+ unavailable: 'inaccessible aux groupes : '
879
+ }
870
880
  },
871
881
  homepage: {
872
882
  menu: {
@@ -2339,7 +2349,7 @@ const DataSourceActions = {
2339
2349
  create: createAction('[Dataset] create Dataset', props()),
2340
2350
  created: createAction('[Dataset] Datadef is created call to admin', props()),
2341
2351
  update: createAction('[Dataset] update Dataset', props()),
2342
- setConflictGroups: createAction('[Dataset] set conflict groups', props()),
2352
+ setMissingGroups: createAction('[Dataset] set missing groups', props()),
2343
2353
  updated: createAction('[Dataset] Dataset is updated call to admin', props()),
2344
2354
  delete: createAction('[Dataset] delete Dataset', props()),
2345
2355
  deleted: createAction('[Dataset] Dataset is deleted call to admin', props()),
@@ -2409,9 +2419,9 @@ const dataSourceReducer = createReducer(initialDataSourceState, on(DataSourceAct
2409
2419
  ...state,
2410
2420
  datasets: action.datasets,
2411
2421
  isLoading: false
2412
- })), on(DataSourceActions.dataset.setConflictGroups, (state, { conflictGroups }) => ({
2422
+ })), on(DataSourceActions.dataset.setMissingGroups, (state, { missingGroups }) => ({
2413
2423
  ...state,
2414
- conflictGroups
2424
+ missingGroups
2415
2425
  })), on(DataSourceActions.dataset.unselectDataset, (state) => ({
2416
2426
  ...state,
2417
2427
  selectedDataset: null
@@ -2551,7 +2561,7 @@ const getDataSourcesSorted = createSelector(getAllNamedQuery, datasets, (nqs, ds
2551
2561
  const selectedDatasetId = createSelector(selectFeature, (state) => state?.selectedDataset?.id);
2552
2562
  const selectedDataset = createSelector(selectFeature, (state) => state?.selectedDataset);
2553
2563
  const selectedDatasetMetadata = createSelector(selectFeature, (state) => state?.selectedDataset?.metadata ?? []);
2554
- const selectedDatasetConflictGroups = createSelector(selectFeature, (state) => state?.conflictGroups);
2564
+ const selectedDatasetMissingGroups = createSelector(selectFeature, (state) => state?.missingGroups);
2555
2565
  const datasetVersions = createSelector(selectFeature, (state) => state?.datasetVersions ?? []);
2556
2566
  const memoizeDatasetVersions = {};
2557
2567
  const matchingDatasetVersions = (datasetId) => {
@@ -2580,7 +2590,7 @@ const DataSourceSelectors = {
2580
2590
  getDataSourcesSorted,
2581
2591
  selectedDataset,
2582
2592
  selectedDatasetMetadata,
2583
- selectedDatasetConflictGroups,
2593
+ selectedDatasetMissingGroups,
2584
2594
  datasetVersions,
2585
2595
  selectedDatasetId,
2586
2596
  matchingDatasetVersions,
@@ -4397,7 +4407,7 @@ class DataSourceEffects {
4397
4407
  DataSourceActions.dataset.unselectDataset(),
4398
4408
  DataSourceActions.dataset.created({ path: props.route })
4399
4409
  ]))), catchError((error) => [DataSourceActions.dataset.failure({ error })])));
4400
- this.unsetConflictGroupsOnDatasetSelection$ = createEffect(() => this.actions$.pipe(ofType(DataSourceActions.dataset.selectDataset), map(() => DataSourceActions.dataset.setConflictGroups({ conflictGroups: undefined }))));
4410
+ this.unsetMissingGroupsOnDatasetSelection$ = createEffect(() => this.actions$.pipe(ofType(DataSourceActions.dataset.selectDataset), map(() => DataSourceActions.dataset.setMissingGroups({ missingGroups: undefined }))));
4401
4411
  this.deleteDataset$ = createEffect(() => this.actions$.pipe(ofType(DataSourceActions.dataset.delete), switchMap((action) => this.dataSourceService.deleteDataset(action.name).pipe(mergeMap(() => [
4402
4412
  DataSourceActions.dataset.loadDataset(),
4403
4413
  DataSourceActions.dataset.unselectDataset(),
@@ -7337,22 +7347,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImpor
7337
7347
  }] } });
7338
7348
 
7339
7349
  class PryGroupShareComponent extends SubscriptionnerDirective {
7350
+ set disableRadios(value) {
7351
+ if (value)
7352
+ this._disableRadios$.next(value);
7353
+ }
7354
+ set allowedGroups(value) {
7355
+ if (value)
7356
+ this._allowedGroups$.next(value);
7357
+ }
7340
7358
  constructor(store, _cd) {
7341
7359
  super();
7342
7360
  this.store = store;
7343
7361
  this._cd = _cd;
7344
7362
  this._onChange = (groups) => groups;
7345
7363
  this._onTouched = () => { };
7346
- this._disabled = false;
7347
7364
  // for tracking input
7348
7365
  this.assignedGroupNames$ = new BehaviorSubject([]);
7349
7366
  this.radioValue = PryVisibilityType.PRIVATE;
7350
7367
  this.PryVisibilityType = PryVisibilityType;
7351
7368
  this.visibilityTypes = [];
7369
+ this._disableRadios$ = new BehaviorSubject({
7370
+ [PryVisibilityType.PRIVATE]: false,
7371
+ [PryVisibilityType.RESTRICTED]: false,
7372
+ [PryVisibilityType.PUBLIC]: false
7373
+ });
7374
+ this._allowedGroups$ = new BehaviorSubject(undefined);
7352
7375
  this.store.dispatch(ConfigActions.loadAccessGroups());
7353
- this.groups$ = this.store
7354
- .select(ConfigSelectors.accessGroups)
7355
- .pipe(map((groups) => groups.filter((group) => group.name !== 'ALL')));
7376
+ this.groups$ = combineLatest([this.store.select(ConfigSelectors.accessGroups), this._allowedGroups$]).pipe(map(([groups, allowedGroups]) => groups
7377
+ .filter((group) => group.name !== 'ALL')
7378
+ .filter((group) => allowedGroups?.includes('ALL') || !allowedGroups ? true : allowedGroups.includes(group.name))));
7356
7379
  this.assignedGroups$ = combineLatest([this.groups$, this.assignedGroupNames$]).pipe(map(([groups, groupNames]) => groups.filter((group) => {
7357
7380
  return groupNames.includes(group.name);
7358
7381
  }) ?? []));
@@ -7360,7 +7383,7 @@ class PryGroupShareComponent extends SubscriptionnerDirective {
7360
7383
  label: label.toLowerCase(),
7361
7384
  value: PryVisibilityType[label]
7362
7385
  }));
7363
- this.templateData$ = combineLatest([this.groups$, this.assignedGroups$]).pipe(map(([groups, assignedGroups]) => ({ groups, assignedGroups })));
7386
+ this.templateData$ = combineLatest([this.groups$, this.assignedGroups$, this._disableRadios$]).pipe(map(([groups, assignedGroups, disableRadios]) => ({ groups, assignedGroups, disableRadios })));
7364
7387
  }
7365
7388
  writeValue(value) {
7366
7389
  value = value ?? [];
@@ -7378,10 +7401,6 @@ class PryGroupShareComponent extends SubscriptionnerDirective {
7378
7401
  registerOnTouched(fn) {
7379
7402
  this._onTouched = fn;
7380
7403
  }
7381
- setDisabledState(isDisabled) {
7382
- this._disabled = isDisabled;
7383
- this._cd.markForCheck();
7384
- }
7385
7404
  updateRadioValue(groups) {
7386
7405
  if (groups.length === 0) {
7387
7406
  this.radioValue = PryVisibilityType.PRIVATE;
@@ -7417,13 +7436,13 @@ class PryGroupShareComponent extends SubscriptionnerDirective {
7417
7436
  }
7418
7437
  }
7419
7438
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: PryGroupShareComponent, deps: [{ token: i1.Store }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
7420
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.1.3", type: PryGroupShareComponent, selector: "pry-group-share", providers: [
7439
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.1.3", type: PryGroupShareComponent, selector: "pry-group-share", inputs: { disableRadios: "disableRadios", allowedGroups: "allowedGroups" }, providers: [
7421
7440
  {
7422
7441
  provide: NG_VALUE_ACCESSOR,
7423
7442
  useExisting: forwardRef(() => PryGroupShareComponent),
7424
7443
  multi: true
7425
7444
  }
7426
- ], usesInheritance: true, ngImport: i0, template: "<div class=\"m-form-radio-group\">\n <div *ngFor=\"let type of visibilityTypes\" class=\"m-form-radio-group__item\">\n <input\n type=\"radio\"\n name=\"visibility\"\n [id]=\"type.label\"\n [value]=\"type.value\"\n [ngModel]=\"radioValue\"\n (ngModelChange)=\"changeGroupsBasedOnRadioValue($event)\"\n [disabled]=\"_disabled\"\n />\n <label [for]=\"type.label\" class=\"a-label\">{{ '@pry.share.' + type.label | i18n }}</label>\n </div>\n</div>\n@if (radioValue === PryVisibilityType.RESTRICTED) {\n @if(templateData$ | async; as data) {\n <pry-chips-selector\n bindLabel=\"name\"\n bindValue=\"name\"\n translationStringBase=\"@pry.components.chipsSelector.share.\"\n itemTranslationStringBase=\"@pry.components.chipsSelector.share.groups.\"\n [showActionButtons]=\"false\"\n [items]=\"data.groups\"\n (itemsChanged)=\"changeGroups($event)\"\n [usedItems]=\"data.assignedGroups\"\n [showSearchbar]=\"data.groups.length > 6\"\n ></pry-chips-selector>\n }\n}\n", dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ChipsSelectorComponent, selector: "pry-chips-selector", inputs: ["bindValue", "bindLabel", "translationStringBase", "itemTranslationStringBase", "showActionButtons", "showSearchbar", "items", "usedItems"], outputs: ["cancel", "validated", "previousTab", "nextTab", "itemsChanged"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: I18nPipe, name: "i18n" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
7445
+ ], usesInheritance: true, ngImport: i0, template: "@if(templateData$ | async; as data) {\n <div class=\"m-form-radio-group\">\n <div *ngFor=\"let type of visibilityTypes\" class=\"m-form-radio-group__item\">\n <input\n type=\"radio\"\n name=\"visibility\"\n [id]=\"type.label\"\n [value]=\"type.value\"\n [ngModel]=\"radioValue\"\n (ngModelChange)=\"changeGroupsBasedOnRadioValue($event)\"\n [disabled]=\"data.disableRadios[type.value]\"\n />\n <label [for]=\"type.label\" class=\"a-label\">{{ '@pry.share.' + type.label | i18n }}</label>\n </div>\n </div>\n @if (radioValue === PryVisibilityType.RESTRICTED) {\n <pry-chips-selector\n bindLabel=\"name\"\n bindValue=\"name\"\n translationStringBase=\"@pry.components.chipsSelector.share.\"\n itemTranslationStringBase=\"@pry.components.chipsSelector.share.groups.\"\n [showActionButtons]=\"false\"\n [items]=\"data.groups\"\n (itemsChanged)=\"changeGroups($event)\"\n [usedItems]=\"data.assignedGroups\"\n [showSearchbar]=\"data.groups.length > 6\"\n ></pry-chips-selector>\n }\n}\n", dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ChipsSelectorComponent, selector: "pry-chips-selector", inputs: ["bindValue", "bindLabel", "translationStringBase", "itemTranslationStringBase", "showActionButtons", "showSearchbar", "items", "usedItems"], outputs: ["cancel", "validated", "previousTab", "nextTab", "itemsChanged"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: I18nPipe, name: "i18n" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
7427
7446
  }
7428
7447
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: PryGroupShareComponent, decorators: [{
7429
7448
  type: Component,
@@ -7433,8 +7452,31 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImpor
7433
7452
  useExisting: forwardRef(() => PryGroupShareComponent),
7434
7453
  multi: true
7435
7454
  }
7436
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"m-form-radio-group\">\n <div *ngFor=\"let type of visibilityTypes\" class=\"m-form-radio-group__item\">\n <input\n type=\"radio\"\n name=\"visibility\"\n [id]=\"type.label\"\n [value]=\"type.value\"\n [ngModel]=\"radioValue\"\n (ngModelChange)=\"changeGroupsBasedOnRadioValue($event)\"\n [disabled]=\"_disabled\"\n />\n <label [for]=\"type.label\" class=\"a-label\">{{ '@pry.share.' + type.label | i18n }}</label>\n </div>\n</div>\n@if (radioValue === PryVisibilityType.RESTRICTED) {\n @if(templateData$ | async; as data) {\n <pry-chips-selector\n bindLabel=\"name\"\n bindValue=\"name\"\n translationStringBase=\"@pry.components.chipsSelector.share.\"\n itemTranslationStringBase=\"@pry.components.chipsSelector.share.groups.\"\n [showActionButtons]=\"false\"\n [items]=\"data.groups\"\n (itemsChanged)=\"changeGroups($event)\"\n [usedItems]=\"data.assignedGroups\"\n [showSearchbar]=\"data.groups.length > 6\"\n ></pry-chips-selector>\n }\n}\n" }]
7437
- }], ctorParameters: () => [{ type: i1.Store }, { type: i0.ChangeDetectorRef }] });
7455
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if(templateData$ | async; as data) {\n <div class=\"m-form-radio-group\">\n <div *ngFor=\"let type of visibilityTypes\" class=\"m-form-radio-group__item\">\n <input\n type=\"radio\"\n name=\"visibility\"\n [id]=\"type.label\"\n [value]=\"type.value\"\n [ngModel]=\"radioValue\"\n (ngModelChange)=\"changeGroupsBasedOnRadioValue($event)\"\n [disabled]=\"data.disableRadios[type.value]\"\n />\n <label [for]=\"type.label\" class=\"a-label\">{{ '@pry.share.' + type.label | i18n }}</label>\n </div>\n </div>\n @if (radioValue === PryVisibilityType.RESTRICTED) {\n <pry-chips-selector\n bindLabel=\"name\"\n bindValue=\"name\"\n translationStringBase=\"@pry.components.chipsSelector.share.\"\n itemTranslationStringBase=\"@pry.components.chipsSelector.share.groups.\"\n [showActionButtons]=\"false\"\n [items]=\"data.groups\"\n (itemsChanged)=\"changeGroups($event)\"\n [usedItems]=\"data.assignedGroups\"\n [showSearchbar]=\"data.groups.length > 6\"\n ></pry-chips-selector>\n }\n}\n" }]
7456
+ }], ctorParameters: () => [{ type: i1.Store }, { type: i0.ChangeDetectorRef }], propDecorators: { disableRadios: [{
7457
+ type: Input
7458
+ }], allowedGroups: [{
7459
+ type: Input
7460
+ }] } });
7461
+
7462
+ const canManifestBeMadePublic = (manifest, datasets) => {
7463
+ return manifest.datasource.every((dsId) => {
7464
+ const datasource = datasets.find((d) => d.id === dsId);
7465
+ return datasource?.groups?.includes('ALL') ?? false;
7466
+ });
7467
+ };
7468
+ const getCommonDatasourceGroupsForManifest = (manifest, datasets) => {
7469
+ const result = [];
7470
+ const dsGroups = manifest.datasource.map((dsId) => datasets.find((d) => d.id === dsId)?.groups ?? []);
7471
+ const baseArray = dsGroups[0];
7472
+ for (let i = 0; i < baseArray.length; i++) {
7473
+ const element = baseArray[i];
7474
+ if (dsGroups.every((array) => array.includes(element))) {
7475
+ result.push(element);
7476
+ }
7477
+ }
7478
+ return result;
7479
+ };
7438
7480
 
7439
7481
  const MIME_TYPE_RESULTSET = 'application/resultset';
7440
7482
 
@@ -10582,17 +10624,19 @@ class ManifestService {
10582
10624
  .pipe(mergeMap((url) => this.httpClient.get(encodeURI(`${url}/users/me/dashboards/id/${id}/manifest`))));
10583
10625
  }
10584
10626
  save(name, manifest, id, description, image, cover, metadata, groups) {
10585
- return this.store.select(ConfigSelectors.refUrl).pipe(mergeMap((url) => this.httpClient.post(encodeURI(`${url}/users/me/dashboards`), {
10586
- id,
10587
- name,
10588
- description,
10589
- manifest,
10590
- image,
10591
- cover,
10592
- metadata,
10593
- datasource: ManifestUtils.getDatasourcesUsedByManifest(manifest).map((ds) => ds.datasetId),
10594
- groups
10595
- })));
10627
+ return this.store.select(ConfigSelectors.refUrl).pipe(mergeMap((url) => {
10628
+ return this.httpClient.post(encodeURI(`${url}/users/me/dashboards`), {
10629
+ id,
10630
+ name,
10631
+ description,
10632
+ manifest,
10633
+ image,
10634
+ cover,
10635
+ metadata,
10636
+ datasource: ManifestUtils.getDatasourcesUsedByManifest(manifest).map((ds) => ds.datasetId),
10637
+ groups
10638
+ });
10639
+ }));
10596
10640
  }
10597
10641
  delete(id) {
10598
10642
  return this.store
@@ -10756,7 +10800,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImpor
10756
10800
  }], ctorParameters: () => [{ type: i1$2.HttpClient }] });
10757
10801
 
10758
10802
  class DashboardEffects {
10759
- constructor(dashboardInitService, actions$, store, manifestService, itemService, titleService, translateService, snackBar, router, refreshService, toolboxManifestService, busService, searchService, pryDialog, wmsService, widgetFactoryService) {
10803
+ constructor(dashboardInitService, actions$, store, manifestService, itemService, titleService, translateService, snackBar, router, refreshService, toolboxManifestService, busService, searchService, pryDialog, wmsService, widgetFactoryService, i18nService) {
10760
10804
  this.dashboardInitService = dashboardInitService;
10761
10805
  this.actions$ = actions$;
10762
10806
  this.store = store;
@@ -10773,6 +10817,7 @@ class DashboardEffects {
10773
10817
  this.pryDialog = pryDialog;
10774
10818
  this.wmsService = wmsService;
10775
10819
  this.widgetFactoryService = widgetFactoryService;
10820
+ this.i18nService = i18nService;
10776
10821
  this.join$ = createEffect(() => this.actions$.pipe(ofType(DashboardActions.join), withLatestFrom(this.store.select(DashboardSelectors.rank), this.store.select(DashboardSelectors.tenants), this.store.select(DashboardSelectors.globalManifest), this.store.select(DashboardSelectors.resultSets), this.store.select(DashboardSelectors.selectedItemIds), this.store.select(DashboardSelectors.presentation), this.store.select(DashboardSelectors.displayOptions)), filter$1(([action, rank, tenants, manifest, resultSets, display]) => rank === 0), map$1(([action, rank, tenants, manifest, resultSets, selectedIds, presentation, display]) => DashboardActions.updateManifestAfterTenantJoin({
10777
10822
  tenants, // we already have added tenant in the reduce of the "join" action
10778
10823
  manifest: {
@@ -10897,12 +10942,33 @@ class DashboardEffects {
10897
10942
  }
10898
10943
  });
10899
10944
  })), { dispatch: false });
10900
- this.saveManifest$ = createEffect(() => this.actions$.pipe(ofType(DashboardActions.saveManifest), withLatestFrom(this.store.select(DashboardSelectors.globalManifest)), mergeMap$1(([action, currentManifest]) => this.manifestService
10945
+ this.saveManifest$ = createEffect(() => this.actions$.pipe(ofType(DashboardActions.saveManifest), withLatestFrom(this.store.select(DashboardSelectors.globalManifest)), withLatestFrom(this.store.select(DataSourceSelectors.datasets)), mergeMap$1(([[action, currentManifest], datasets]) => this.manifestService
10901
10946
  .save(action.name, action.manifest ?? currentManifest, action.id, action.description, action.image, action.cover, action.metadata, action.groups)
10902
- .pipe(tap(() => this.snackBar.open({
10903
- message: this.translateService.instant('@pry.toolbox.manifest.saved', { viewId: action.name }),
10904
- type: 'success'
10905
- })), map$1(() => action.manifest ?? currentManifest), catchError((error) => {
10947
+ .pipe(tap((response) => {
10948
+ this.snackBar.open({
10949
+ message: this.translateService.instant('@pry.toolbox.manifest.saved', { viewId: action.name }),
10950
+ type: 'success'
10951
+ });
10952
+ if (Object.keys(response.missingGroupsByEntity).length > 0) {
10953
+ const data = {
10954
+ title: '@pry.share.conflict.title',
10955
+ message: this.i18nService.instant('@pry.share.conflict.main') +
10956
+ '\r\n' +
10957
+ Object.keys(response.missingGroupsByEntity)
10958
+ .map((entity) => (datasets.find((ds) => ds.id === entity)?.name ?? entity) +
10959
+ ' : ' +
10960
+ response.missingGroupsByEntity[entity].join(', '))
10961
+ .join('\r\n'),
10962
+ actions: [
10963
+ {
10964
+ id: 0,
10965
+ label: '@pry.toolbox.close'
10966
+ }
10967
+ ]
10968
+ };
10969
+ this.pryDialog.open(PryDialogConfirmComponent, { data });
10970
+ }
10971
+ }), map$1(() => action.manifest ?? currentManifest), catchError((error) => {
10906
10972
  this.snackBar.open({
10907
10973
  message: this.translateService.instant('@pry.toolbox.manifest.saveErrorCode.' + (error.error?.code ?? 'UNKNOWN'), {
10908
10974
  name: action.name
@@ -11115,12 +11181,12 @@ class DashboardEffects {
11115
11181
  dashboardInitService.init();
11116
11182
  refreshService.start();
11117
11183
  }
11118
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DashboardEffects, deps: [{ token: DashboardInitService }, { token: i1$3.Actions }, { token: i1.Store }, { token: ManifestService }, { token: ItemService }, { token: PryTitleService }, { token: PryI18nService }, { token: PrySnackbarService }, { token: i3.Router }, { token: RefreshService }, { token: ToolboxManifestService }, { token: BusService }, { token: SearchService }, { token: PryDialogService }, { token: WmsService }, { token: WidgetFactoryService }], target: i0.ɵɵFactoryTarget.Injectable }); }
11184
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DashboardEffects, deps: [{ token: DashboardInitService }, { token: i1$3.Actions }, { token: i1.Store }, { token: ManifestService }, { token: ItemService }, { token: PryTitleService }, { token: PryI18nService }, { token: PrySnackbarService }, { token: i3.Router }, { token: RefreshService }, { token: ToolboxManifestService }, { token: BusService }, { token: SearchService }, { token: PryDialogService }, { token: WmsService }, { token: WidgetFactoryService }, { token: PryI18nService }], target: i0.ɵɵFactoryTarget.Injectable }); }
11119
11185
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DashboardEffects }); }
11120
11186
  }
11121
11187
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DashboardEffects, decorators: [{
11122
11188
  type: Injectable
11123
- }], ctorParameters: () => [{ type: DashboardInitService }, { type: i1$3.Actions }, { type: i1.Store }, { type: ManifestService }, { type: ItemService }, { type: PryTitleService }, { type: PryI18nService }, { type: PrySnackbarService }, { type: i3.Router }, { type: RefreshService }, { type: ToolboxManifestService }, { type: BusService }, { type: SearchService }, { type: PryDialogService }, { type: WmsService }, { type: WidgetFactoryService }] });
11189
+ }], ctorParameters: () => [{ type: DashboardInitService }, { type: i1$3.Actions }, { type: i1.Store }, { type: ManifestService }, { type: ItemService }, { type: PryTitleService }, { type: PryI18nService }, { type: PrySnackbarService }, { type: i3.Router }, { type: RefreshService }, { type: ToolboxManifestService }, { type: BusService }, { type: SearchService }, { type: PryDialogService }, { type: WmsService }, { type: WidgetFactoryService }, { type: PryI18nService }] });
11124
11190
 
11125
11191
  const dashboardFeatureKey = '@pry/dashboard';
11126
11192
  const dashboardInitialState = {
@@ -12423,5 +12489,5 @@ function filterLoader(module, prop) {
12423
12489
  * Generated bundle index. Do not edit.
12424
12490
  */
12425
12491
 
12426
- export { AccordionComponent, AccordionItemComponent, Aggregation, BASE_DISPLAY_OPTIONS, BaseFilterComponent, BaseFilterModule, BaseLayoutComponent, BaseMenuComponent, BaseToolboxComponent, BaseTooltipComponent, BaseTooltipModule, BaseWidgetComponent, BaseWidgetModule, BusService, CategoryActions, CategorySelectors, CategoryService, ChartOptionDefault, ChipsSelectorComponent, ClassActions, ClassSelectors, ClassService, ConfigActions, ConfigSelectors, ConfigService, ContextMenuActions, ContextMenuComponent, ContextMenuSelectors, DEFAULT_CATEGORY_UUID, DEFAULT_COLUMNS_NUMBER, DEFAULT_GAP_PX, DEFAULT_ICON_URL, DEFAULT_MSG_TIMEOUT, DEFAULT_NAMED_QUERY_ID, DEFAULT_PROJECTION, DEFAULT_RESTITUTION_ICON_URL, DEFAULT_ROWS_NUMBER, DEFAULT_ROW_HEIGHT_PX, DEFAULT_SEARCH_LIMIT_NUMBER, DELAY_FOR_HIDE, DashboardActions, DashboardComponent, DashboardGridLayout, DashboardSelectors, DataSourceActions, DataSourceSelectors, DataSourceService, DataWidgetComponent, DatasourceSelectorComponent, DatasourceUtils, DateRangeHighlightPipe, DateUtils, DefaultTooltipComponent, ENV_OPTIONS, EXPLORE_NAMED_QUERY_ID, EllipsisDirective, FIELD_OPTIONS, FIELD_UUID, FILTERS_DOMAIN, FILTER_DEFINITION, FieldActions, FieldSelectors, FieldService, FieldType, FilterFactoryService, FilterGroupComponent, FilterInstanciatorComponent, GeoMetadata, GeometricFieldTypes, GetSecuredImagePipe, GraphType, HTTP_ORIGIN_METADATA, I18nPipe, INTERNALLY_STORED_IMAGE_PREFIX, IconPosition, ImageActions, ImageService, ImagesSelectors, ItemUtils, LibraryTypes, LoopScrollColumnComponent, METADATA_TYPE, META_OPTIONS, MIME_TYPE_RESULTSET, MIME_TYPE_WIDGET_MANIFEST, MIME_TYPE_WIDGET_SIZE, MIME_TYPE_WIDGET_TYPE, ManifestService, ManifestUtils, ManifestsComponent, MarkSubType, MarkType, MetadataComponent, NamedQueryTypes, NumericFieldTypes, OPERATOR_OPTIONS, Operation, PRY_ACCESS_GUARD, PRY_ACCESS_TOKEN, PRY_CUSTOMEVENT_TYPE, PRY_DIALOG_DATA, PRY_GEOAUTH_TOKEN, PryAboutComponent, PryAboutModule, PryAccessDirective, PryAccessUtils, PryAggregationService, PryBackendAggregationService, PryBaseAccess, PryBaseAccessGuard, PryCoreModule, PryDashboardModule, PryDatasetType, PryDatePickerComponent, PryDatePickerModule, PryDefaultAccessGuard, PryDefaultAccessService, PryDefaultGeoAuthService, PryDialogConfirmComponent, PryDialogRef, PryDialogService, PryEditInputComponent, PryEditInputModule, PryFilterGroupCssComponent, PryFrontendAggregationService, PryGeoAuthService, PryGroupShareComponent, PryHiddenWhenOverlay, PryHiddenWhenOverlayDirective, PryHttpErrorInterceptorService, PryI18nModule, PryI18nService, PryIconComponent, PryIconModule, PryModalComponent, PryModalModule, PryModalStatusComponent, PryModalStatusModule, PryNqColorSelectorComponent, PryObjectEditionComponent, PryOverlayDirective, PryOverlayModule, PryRangeComponent, PryRangeModule, PrySelectComponent, PrySelectImageComponent, PrySelectModule, PryShareComponent, PryShareModule, PrySnackbarComponent, PrySnackbarModule, PrySnackbarService, PrySortDataPipe, PrySortHeaderComponent, PrySortHeaderDirective, PrySortModule, PrySortTableDirective, PryTimePickerComponent, PryTitleService, PryToggleComponent, PryToggleModule, PryUploadComponent, PryVisibilityType, PryWidgetHeaderComponent, RawService, RelationTypesActions, RelationTypesSelectors, RelationTypesService, ResultSetSizePipe, ResultsetUtils, SYMBOL_DOMAIN, SearchActions, SearchSelectors, SearchService, SettingsComponent, SubscriptionnerDirective, SymbolService, TABLE_ATTR_DOMAIN, TILE_ATTR_DOMAIN, TOOLTIPS_DOMAIN, TOOLTIP_DEFINITION, TabComponent, TabGroupComponent, TextFieldTypes, ToolboxManifestService, ToolboxMenuService, TooltipFactoryService, TooltipMode, TranslateIdPipe, TranslateItemToSymbolPipe, UNKNOWN_DATASOURCE, USE_CURRENT_RESULTSET, VARIABLE_TYPE, VegaColorType, VegaType, ViewMode, VizualizeRawComponent, WIDGET_DEFINITION, WIDGET_HEADER_HEIGHT, WebsocketService, WidgetFactoryService, WidgetInstanciatorComponent, WidgetPlaceholderComponent, WidgetPlacementUtils, WmsService, adapter$2 as adapter, aggregationDefault, baseItemProperties, classReducer, classesFeatureKey, compareOperationFunctions, contextMenuFeatureKey, contextMenuReducer, createPlacedWidgetCopy, dashboardFeatureKey, dashboardInitialState, dashboardReducer, dataSourceFeatureKey, dataSourceReducer, deepMerge, defaultColors, defaultMenuStructure, enTranslations$1 as enTranslations, filterLoader, frTranslations$1 as frTranslations, getDisplayOptions, httpErrorOptions, imageFeatureKey, imageReducer, initialClassState, initialContextMenuState, initialDataSourceState, initialImageState, initialSearchState, latLonToGeographicFieldTransformation, markTypesDefault, notificationFeatureKey, orderWidgetsAccordingToPlacement, searchFeatureKey, searchReducer, selectAll$2 as selectAll, selectEntities$2 as selectEntities, solveCollisions, solvingCollisionOptions, sortByName$2 as sortByName, subTypesDefault, tooltipLoader, vegaColorSchemesDefault, widgetLoader, widgetMapConfig };
12492
+ export { AccordionComponent, AccordionItemComponent, Aggregation, BASE_DISPLAY_OPTIONS, BaseFilterComponent, BaseFilterModule, BaseLayoutComponent, BaseMenuComponent, BaseToolboxComponent, BaseTooltipComponent, BaseTooltipModule, BaseWidgetComponent, BaseWidgetModule, BusService, CategoryActions, CategorySelectors, CategoryService, ChartOptionDefault, ChipsSelectorComponent, ClassActions, ClassSelectors, ClassService, ConfigActions, ConfigSelectors, ConfigService, ContextMenuActions, ContextMenuComponent, ContextMenuSelectors, DEFAULT_CATEGORY_UUID, DEFAULT_COLUMNS_NUMBER, DEFAULT_GAP_PX, DEFAULT_ICON_URL, DEFAULT_MSG_TIMEOUT, DEFAULT_NAMED_QUERY_ID, DEFAULT_PROJECTION, DEFAULT_RESTITUTION_ICON_URL, DEFAULT_ROWS_NUMBER, DEFAULT_ROW_HEIGHT_PX, DEFAULT_SEARCH_LIMIT_NUMBER, DELAY_FOR_HIDE, DashboardActions, DashboardComponent, DashboardGridLayout, DashboardSelectors, DataSourceActions, DataSourceSelectors, DataSourceService, DataWidgetComponent, DatasourceSelectorComponent, DatasourceUtils, DateRangeHighlightPipe, DateUtils, DefaultTooltipComponent, ENV_OPTIONS, EXPLORE_NAMED_QUERY_ID, EllipsisDirective, FIELD_OPTIONS, FIELD_UUID, FILTERS_DOMAIN, FILTER_DEFINITION, FieldActions, FieldSelectors, FieldService, FieldType, FilterFactoryService, FilterGroupComponent, FilterInstanciatorComponent, GeoMetadata, GeometricFieldTypes, GetSecuredImagePipe, GraphType, HTTP_ORIGIN_METADATA, I18nPipe, INTERNALLY_STORED_IMAGE_PREFIX, IconPosition, ImageActions, ImageService, ImagesSelectors, ItemUtils, LibraryTypes, LoopScrollColumnComponent, METADATA_TYPE, META_OPTIONS, MIME_TYPE_RESULTSET, MIME_TYPE_WIDGET_MANIFEST, MIME_TYPE_WIDGET_SIZE, MIME_TYPE_WIDGET_TYPE, ManifestService, ManifestUtils, ManifestsComponent, MarkSubType, MarkType, MetadataComponent, NamedQueryTypes, NumericFieldTypes, OPERATOR_OPTIONS, Operation, PRY_ACCESS_GUARD, PRY_ACCESS_TOKEN, PRY_CUSTOMEVENT_TYPE, PRY_DIALOG_DATA, PRY_GEOAUTH_TOKEN, PryAboutComponent, PryAboutModule, PryAccessDirective, PryAccessUtils, PryAggregationService, PryBackendAggregationService, PryBaseAccess, PryBaseAccessGuard, PryCoreModule, PryDashboardModule, PryDatasetType, PryDatePickerComponent, PryDatePickerModule, PryDefaultAccessGuard, PryDefaultAccessService, PryDefaultGeoAuthService, PryDialogConfirmComponent, PryDialogRef, PryDialogService, PryEditInputComponent, PryEditInputModule, PryFilterGroupCssComponent, PryFrontendAggregationService, PryGeoAuthService, PryGroupShareComponent, PryHiddenWhenOverlay, PryHiddenWhenOverlayDirective, PryHttpErrorInterceptorService, PryI18nModule, PryI18nService, PryIconComponent, PryIconModule, PryModalComponent, PryModalModule, PryModalStatusComponent, PryModalStatusModule, PryNqColorSelectorComponent, PryObjectEditionComponent, PryOverlayDirective, PryOverlayModule, PryRangeComponent, PryRangeModule, PrySelectComponent, PrySelectImageComponent, PrySelectModule, PryShareComponent, PryShareModule, PrySnackbarComponent, PrySnackbarModule, PrySnackbarService, PrySortDataPipe, PrySortHeaderComponent, PrySortHeaderDirective, PrySortModule, PrySortTableDirective, PryTimePickerComponent, PryTitleService, PryToggleComponent, PryToggleModule, PryUploadComponent, PryVisibilityType, PryWidgetHeaderComponent, RawService, RelationTypesActions, RelationTypesSelectors, RelationTypesService, ResultSetSizePipe, ResultsetUtils, SYMBOL_DOMAIN, SearchActions, SearchSelectors, SearchService, SettingsComponent, SubscriptionnerDirective, SymbolService, TABLE_ATTR_DOMAIN, TILE_ATTR_DOMAIN, TOOLTIPS_DOMAIN, TOOLTIP_DEFINITION, TabComponent, TabGroupComponent, TextFieldTypes, ToolboxManifestService, ToolboxMenuService, TooltipFactoryService, TooltipMode, TranslateIdPipe, TranslateItemToSymbolPipe, UNKNOWN_DATASOURCE, USE_CURRENT_RESULTSET, VARIABLE_TYPE, VegaColorType, VegaType, ViewMode, VizualizeRawComponent, WIDGET_DEFINITION, WIDGET_HEADER_HEIGHT, WebsocketService, WidgetFactoryService, WidgetInstanciatorComponent, WidgetPlaceholderComponent, WidgetPlacementUtils, WmsService, adapter$2 as adapter, aggregationDefault, baseItemProperties, canManifestBeMadePublic, classReducer, classesFeatureKey, compareOperationFunctions, contextMenuFeatureKey, contextMenuReducer, createPlacedWidgetCopy, dashboardFeatureKey, dashboardInitialState, dashboardReducer, dataSourceFeatureKey, dataSourceReducer, deepMerge, defaultColors, defaultMenuStructure, enTranslations$1 as enTranslations, filterLoader, frTranslations$1 as frTranslations, getCommonDatasourceGroupsForManifest, getDisplayOptions, httpErrorOptions, imageFeatureKey, imageReducer, initialClassState, initialContextMenuState, initialDataSourceState, initialImageState, initialSearchState, latLonToGeographicFieldTransformation, markTypesDefault, notificationFeatureKey, orderWidgetsAccordingToPlacement, searchFeatureKey, searchReducer, selectAll$2 as selectAll, selectEntities$2 as selectEntities, solveCollisions, solvingCollisionOptions, sortByName$2 as sortByName, subTypesDefault, tooltipLoader, vegaColorSchemesDefault, widgetLoader, widgetMapConfig };
12427
12493
  //# sourceMappingURL=provoly-dashboard.mjs.map