@porscheinformatik/clr-addons 13.2.1 → 13.3.0

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.
@@ -5,7 +5,7 @@ import { CommonModule, DOCUMENT } from '@angular/common';
5
5
  import * as i3$1 from '@angular/forms';
6
6
  import { FormsModule, NG_VALIDATORS, NgControl, NG_VALUE_ACCESSOR } from '@angular/forms';
7
7
  import * as i2 from '@clr/angular';
8
- import { ClarityModule, ClrFormsModule, ClrDropdown, ClrForm, ClrAlert, ClrAxis, ClrSide, ClrAlignment, ClrPopoverToggleService, ClrPopoverEventsService, ClrPopoverPositionService, ClrIconModule, ClrDropdownModule, ClrDatagridPagination } from '@clr/angular';
8
+ import { ClarityModule, ClrFormsModule, ClrDropdown, ClrForm, ClrAlert, ClrAxis, ClrSide, ClrAlignment, ClrPopoverToggleService, ClrPopoverEventsService, ClrPopoverPositionService, ClrIconModule, ClrDropdownModule, ClrDatagridPagination, ClrDatagridFilter } from '@clr/angular';
9
9
  import { Subject, BehaviorSubject, timer, asyncScheduler, interval, of, ReplaySubject, takeUntil as takeUntil$1 } from 'rxjs';
10
10
  import { takeUntil, observeOn, take } from 'rxjs/operators';
11
11
  import * as i3 from '@angular/router';
@@ -4622,39 +4622,146 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImpor
4622
4622
  type: Input
4623
4623
  }] } });
4624
4624
 
4625
+ const DATE_TYPE = 'date';
4625
4626
  class StatePersistenceKeyDirective {
4627
+ constructor(datagrid) {
4628
+ this.datagrid = datagrid;
4629
+ this.useLocalStoreOnly = false;
4630
+ this.destroy$ = new Subject();
4631
+ }
4626
4632
  ngAfterContentInit() {
4633
+ if (this.options.serverDriven) {
4634
+ this.init();
4635
+ }
4636
+ else {
4637
+ setTimeout(() => {
4638
+ this.init();
4639
+ });
4640
+ }
4641
+ }
4642
+ init() {
4643
+ const volatileDataState = this.getVolatileDataState();
4644
+ const localStorageState = this.getLocalStorageState();
4645
+ this.initFilter(volatileDataState);
4646
+ this.initDatagridPersister();
4627
4647
  if (this.pagination && this.pagination.page) {
4628
- /* persist page size changes in local storage */
4629
- this.pagination.page.sizeChange.subscribe(pageSize => {
4630
- let state = JSON.parse(localStorage.getItem(this.clrStatePersistenceKey));
4631
- if (!state) {
4632
- state = {};
4648
+ this.initPageSizePersister(localStorageState);
4649
+ this.initCurrentPage(volatileDataState);
4650
+ }
4651
+ }
4652
+ initPageSizePersister(savedState) {
4653
+ /* persist page size changes in local storage */
4654
+ this.pagination.page.sizeChange.pipe(takeUntil(this.destroy$)).subscribe(pageSize => {
4655
+ const state = this.getLocalStorageState();
4656
+ state.pageSize = pageSize;
4657
+ localStorage.setItem(this.options.key, JSON.stringify(state));
4658
+ });
4659
+ /* init page size of datagrid if already persisted in local storage */
4660
+ if (savedState.pageSize) {
4661
+ this.pagination.page.size = savedState.pageSize;
4662
+ }
4663
+ }
4664
+ initCurrentPage(savedState) {
4665
+ /* init current page of datagrid if already persisted */
4666
+ if (savedState?.currentPage) {
4667
+ this.pagination.page.current = savedState.currentPage;
4668
+ }
4669
+ }
4670
+ initFilter(savedState) {
4671
+ if (savedState.columns) {
4672
+ Object.keys(savedState.columns).forEach(prop => {
4673
+ const filter = this.getFilter(prop);
4674
+ if (filter) {
4675
+ const savedFilterValue = savedState.columns[prop].filterValue || {};
4676
+ Object.keys(savedFilterValue)
4677
+ .filter(valueKey => valueKey !== 'property')
4678
+ .forEach(valueKey => (filter[valueKey] = this.parseFilterValue(savedFilterValue[valueKey])));
4633
4679
  }
4634
- state.pageSize = pageSize;
4635
- localStorage.setItem(this.clrStatePersistenceKey, JSON.stringify(state));
4636
4680
  });
4637
- /* init page size of datagrid if already persisted in local storage */
4638
- const loadedState = JSON.parse(localStorage.getItem(this.clrStatePersistenceKey));
4639
- if (loadedState?.pageSize) {
4640
- /* postpone set size to other cycle as it is already set in this change detection cycle */
4641
- setTimeout(() => (this.pagination.page.size = loadedState.pageSize));
4642
- }
4643
4681
  }
4644
4682
  }
4683
+ initDatagridPersister() {
4684
+ this.datagrid.refresh.pipe(takeUntil(this.destroy$)).subscribe(dgState => {
4685
+ const state = this.getVolatileDataState();
4686
+ state.currentPage = dgState.page?.current;
4687
+ state.columns = state.columns || {};
4688
+ Object.keys(state.columns).forEach(prop => (state.columns[prop].filterValue = undefined));
4689
+ dgState.filters?.forEach(filter => {
4690
+ const property = this.getFilterPropertyName(filter);
4691
+ if (property) {
4692
+ state.columns[property] = state.columns[property] || {};
4693
+ state.columns[property].filterValue = this.enrichFilterValue(filter);
4694
+ }
4695
+ });
4696
+ (this.useLocalStoreOnly ? localStorage : sessionStorage).setItem(this.options.key, JSON.stringify(state));
4697
+ });
4698
+ }
4699
+ /**
4700
+ * Gets the state of volatile data. This can be influenced by clrUseLocalStoreOnly.
4701
+ */
4702
+ getVolatileDataState() {
4703
+ return JSON.parse((this.useLocalStoreOnly ? localStorage : sessionStorage).getItem(this.options.key)) || {};
4704
+ }
4705
+ getLocalStorageState() {
4706
+ return JSON.parse(localStorage.getItem(this.options.key)) || {};
4707
+ }
4708
+ /**
4709
+ * As a date is serialized as string, but not deserialized as date
4710
+ * we need to add some meta information to do that manually later
4711
+ */
4712
+ enrichFilterValue(filter) {
4713
+ const result = {};
4714
+ Object.keys(filter).forEach(key => (result[key] =
4715
+ filter[key] instanceof Date
4716
+ ? {
4717
+ type: DATE_TYPE,
4718
+ value: filter[key],
4719
+ }
4720
+ : filter[key]));
4721
+ return result;
4722
+ }
4723
+ /**
4724
+ * Parse filter values with meta information like date, which needs manual deserialization to a date object
4725
+ */
4726
+ parseFilterValue(value) {
4727
+ return value?.type === DATE_TYPE
4728
+ ? new Date(value.value)
4729
+ : value;
4730
+ }
4731
+ getFilter(prop) {
4732
+ // get default filter or custom filter
4733
+ return (this.datagrid.columns.find(col => col.field === prop)?.filter ||
4734
+ this.customFilters.find(filter => this.getFilterPropertyName(filter.filter) === prop)?.filter);
4735
+ }
4736
+ getFilterPropertyName(filter) {
4737
+ // for NestedProperty we need to get the original property
4738
+ const filterWithProp = filter;
4739
+ return (filterWithProp.property?.prop || filterWithProp.property);
4740
+ }
4741
+ ngOnDestroy() {
4742
+ this.destroy$.next();
4743
+ this.destroy$.complete();
4744
+ }
4645
4745
  }
4646
- StatePersistenceKeyDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: StatePersistenceKeyDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
4647
- StatePersistenceKeyDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.8", type: StatePersistenceKeyDirective, selector: "[clrStatePersistenceKey]", inputs: { clrStatePersistenceKey: "clrStatePersistenceKey" }, queries: [{ propertyName: "pagination", first: true, predicate: ClrDatagridPagination, descendants: true }], ngImport: i0 });
4746
+ StatePersistenceKeyDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: StatePersistenceKeyDirective, deps: [{ token: i2.ClrDatagrid }], target: i0.ɵɵFactoryTarget.Directive });
4747
+ StatePersistenceKeyDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.8", type: StatePersistenceKeyDirective, selector: "[clrStatePersistenceKey]", inputs: { options: ["clrStatePersistenceKey", "options"], useLocalStoreOnly: ["clrUseLocalStoreOnly", "useLocalStoreOnly"] }, queries: [{ propertyName: "pagination", first: true, predicate: ClrDatagridPagination, descendants: true }, { propertyName: "customFilters", predicate: ClrDatagridFilter, descendants: true }], ngImport: i0 });
4648
4748
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: StatePersistenceKeyDirective, decorators: [{
4649
4749
  type: Directive,
4650
4750
  args: [{
4651
4751
  selector: '[clrStatePersistenceKey]',
4652
4752
  }]
4653
- }], propDecorators: { clrStatePersistenceKey: [{
4654
- type: Input
4753
+ }], ctorParameters: function () { return [{ type: i2.ClrDatagrid }]; }, propDecorators: { options: [{
4754
+ type: Input,
4755
+ args: ['clrStatePersistenceKey']
4756
+ }], useLocalStoreOnly: [{
4757
+ type: Input,
4758
+ args: ['clrUseLocalStoreOnly']
4655
4759
  }], pagination: [{
4656
4760
  type: ContentChild,
4657
4761
  args: [ClrDatagridPagination]
4762
+ }], customFilters: [{
4763
+ type: ContentChildren,
4764
+ args: [ClrDatagridFilter, { descendants: true }]
4658
4765
  }] } });
4659
4766
 
4660
4767
  class ColumnHiddenStatePersistenceDirective {
@@ -4663,40 +4770,34 @@ class ColumnHiddenStatePersistenceDirective {
4663
4770
  this.statePersistenceKey = statePersistenceKey;
4664
4771
  this.datagrid = datagrid;
4665
4772
  this.hideableColumnDirective = hideableColumnDirective;
4773
+ this.destroy$ = new Subject();
4666
4774
  }
4667
4775
  ngOnInit() {
4668
- if (this.statePersistenceKey?.clrStatePersistenceKey && this.columnDirective?.clrDgField) {
4776
+ if (this.statePersistenceKey?.options.key && this.columnDirective?.clrDgField) {
4669
4777
  /* set hidden states from local storage (if existing) */
4670
4778
  this.initHiddenState();
4671
4779
  /* listen to state changes and persist in local storage */
4672
- this.hideableColumnDirective.hiddenChange.subscribe(hidden => {
4780
+ this.hideableColumnDirective.hiddenChange.pipe(takeUntil(this.destroy$)).subscribe(hidden => {
4673
4781
  this.setHiddenState(hidden);
4674
4782
  });
4675
4783
  }
4676
4784
  }
4677
4785
  initHiddenState() {
4678
4786
  /* read grid state if existing */
4679
- const persistedGridStateJson = localStorage.getItem(this.statePersistenceKey.clrStatePersistenceKey);
4680
- if (persistedGridStateJson !== null) {
4681
- const persistedGridState = JSON.parse(persistedGridStateJson);
4682
- /* read column state if existing */
4683
- if (persistedGridState.columns && persistedGridState.columns[this.columnDirective.clrDgField]) {
4684
- /* read column hidden state if existing */
4685
- const persistedColumnHiddenState = persistedGridState.columns[this.columnDirective.clrDgField].hidden;
4686
- if (persistedColumnHiddenState !== undefined) {
4687
- this.hideableColumnDirective.clrDgHidden = persistedColumnHiddenState === true;
4688
- }
4787
+ const persistedGridState = this.readStoredState();
4788
+ /* read column state if existing */
4789
+ if (persistedGridState?.columns?.[this.columnDirective.clrDgField]) {
4790
+ /* read column hidden state if existing */
4791
+ const persistedColumnHiddenState = persistedGridState.columns[this.columnDirective.clrDgField].hidden;
4792
+ if (persistedColumnHiddenState !== undefined) {
4793
+ this.hideableColumnDirective.clrDgHidden = persistedColumnHiddenState === true;
4689
4794
  }
4690
4795
  }
4691
4796
  }
4692
4797
  setHiddenState(hidden) {
4693
4798
  if (!this.datagrid?.detailService?.isOpen) {
4694
4799
  /* read grid state if existing */
4695
- const persistedGridStateJson = localStorage.getItem(this.statePersistenceKey.clrStatePersistenceKey);
4696
- let persistedGridState = {};
4697
- if (persistedGridStateJson !== null) {
4698
- persistedGridState = JSON.parse(persistedGridStateJson);
4699
- }
4800
+ const persistedGridState = this.readStoredState();
4700
4801
  /* read column state if existing */
4701
4802
  if (!persistedGridState.columns) {
4702
4803
  persistedGridState.columns = {};
@@ -4708,9 +4809,16 @@ class ColumnHiddenStatePersistenceDirective {
4708
4809
  }
4709
4810
  /* set column hidden state and persist in local storage */
4710
4811
  persistedColumnState.hidden = hidden;
4711
- localStorage.setItem(this.statePersistenceKey.clrStatePersistenceKey, JSON.stringify(persistedGridState));
4812
+ localStorage.setItem(this.statePersistenceKey.options.key, JSON.stringify(persistedGridState));
4712
4813
  }
4713
4814
  }
4815
+ readStoredState() {
4816
+ return JSON.parse(localStorage.getItem(this.statePersistenceKey.options.key)) || {};
4817
+ }
4818
+ ngOnDestroy() {
4819
+ this.destroy$.next();
4820
+ this.destroy$.complete();
4821
+ }
4714
4822
  }
4715
4823
  ColumnHiddenStatePersistenceDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: ColumnHiddenStatePersistenceDirective, deps: [{ token: DatagridFieldDirective, optional: true }, { token: StatePersistenceKeyDirective, optional: true }, { token: i2.ClrDatagrid }, { token: i2.ClrDatagridHideableColumn }], target: i0.ɵɵFactoryTarget.Directive });
4716
4824
  ColumnHiddenStatePersistenceDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.8", type: ColumnHiddenStatePersistenceDirective, selector: "[clrDgHideableColumn]", ngImport: i0 });
@@ -4756,6 +4864,7 @@ class ClrEnumFilterComponent {
4756
4864
  }
4757
4865
  set value(values) {
4758
4866
  this.filteredValues = values;
4867
+ this.changes.emit(true);
4759
4868
  }
4760
4869
  set clrPossibleValues(values) {
4761
4870
  this.setPossibleValues(values);
@@ -4781,6 +4890,12 @@ class ClrEnumFilterComponent {
4781
4890
  accepts(item) {
4782
4891
  return this.filteredValues.includes(item[this.property]);
4783
4892
  }
4893
+ get state() {
4894
+ return {
4895
+ property: this.property,
4896
+ value: this.filteredValues,
4897
+ };
4898
+ }
4784
4899
  ngOnDestroy() {
4785
4900
  this.destroyed$.next();
4786
4901
  this.destroyed$.complete();
@@ -4872,6 +4987,9 @@ class ClrDateFilterComponent {
4872
4987
  set property(value) {
4873
4988
  this.nestedProp = new NestedProperty(value);
4874
4989
  }
4990
+ get property() {
4991
+ return this.nestedProp.prop;
4992
+ }
4875
4993
  get maxPlaceholderValue() {
4876
4994
  return this.maxPlaceholder || this.commonStrings.keys.maxValue;
4877
4995
  }
@@ -4961,7 +5079,7 @@ class ClrDateFilterComponent {
4961
5079
  }
4962
5080
  }
4963
5081
  ClrDateFilterComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: ClrDateFilterComponent, deps: [{ token: i2.ClrDatagridFilter }, { token: i2.ClrCommonStringsService }], target: i0.ɵɵFactoryTarget.Component });
4964
- ClrDateFilterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.8", type: ClrDateFilterComponent, selector: "clr-date-filter", inputs: { property: ["clrProperty", "property"], maxPlaceholder: ["clrFilterMaxPlaceholder", "maxPlaceholder"], minPlaceholder: ["clrFilterMinPlaceholder", "minPlaceholder"], value: ["clrFilterValue", "value"] }, outputs: { filterValueChange: "clrFilterValueChange" }, ngImport: i0, template: "<clr-date-container>\n <input\n #input_from\n type=\"date\"\n name=\"from\"\n class=\"datagrid-date-filter-input\"\n [(clrDate)]=\"from\"\n [placeholder]=\"minPlaceholderValue\"\n [attr.aria-label]=\"minPlaceholderValue\"\n />\n</clr-date-container>\n<clr-date-container>\n <input\n type=\"date\"\n name=\"to\"\n class=\"datagrid-date-filter-input\"\n [(clrDate)]=\"to\"\n [placeholder]=\"maxPlaceholderValue\"\n [attr.aria-label]=\"maxPlaceholderValue\"\n />\n</clr-date-container>\n", styles: [""], dependencies: [{ kind: "component", type: i2.ClrDateContainer, selector: "clr-date-container", inputs: ["clrPosition"] }, { kind: "directive", type: i2.ClrDateInput, selector: "[clrDate]", inputs: ["placeholder", "clrDate", "min", "max", "disabled"], outputs: ["clrDateChange"] }] });
5082
+ ClrDateFilterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.8", type: ClrDateFilterComponent, selector: "clr-date-filter", inputs: { property: ["clrProperty", "property"], maxPlaceholder: ["clrFilterMaxPlaceholder", "maxPlaceholder"], minPlaceholder: ["clrFilterMinPlaceholder", "minPlaceholder"], value: ["clrFilterValue", "value"] }, outputs: { filterValueChange: "clrFilterValueChange" }, ngImport: i0, template: "<clr-date-container>\n <input\n #input_from\n type=\"date\"\n name=\"from\"\n class=\"datagrid-date-filter-input\"\n [(clrDate)]=\"from\"\n [placeholder]=\"minPlaceholderValue\"\n [attr.aria-label]=\"minPlaceholderValue\"\n />\n</clr-date-container>\n<clr-date-container>\n <input\n type=\"date\"\n name=\"to\"\n class=\"datagrid-date-filter-input\"\n [(clrDate)]=\"to\"\n [placeholder]=\"maxPlaceholderValue\"\n [attr.aria-label]=\"maxPlaceholderValue\"\n />\n</clr-date-container>\n", styles: [""], dependencies: [{ kind: "component", type: i2.ClrDateContainer, selector: "clr-date-container", inputs: ["clrPosition"] }, { kind: "directive", type: i2.ClrDateInput, selector: "[clrDate]", inputs: ["placeholder", "clrDate", "min", "max", "disabled"], outputs: ["clrDateChange"] }, { kind: "directive", type: i2.ClrDateInputValidator, selector: "[clrDate]" }] });
4965
5083
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: ClrDateFilterComponent, decorators: [{
4966
5084
  type: Component,
4967
5085
  args: [{ selector: 'clr-date-filter', template: "<clr-date-container>\n <input\n #input_from\n type=\"date\"\n name=\"from\"\n class=\"datagrid-date-filter-input\"\n [(clrDate)]=\"from\"\n [placeholder]=\"minPlaceholderValue\"\n [attr.aria-label]=\"minPlaceholderValue\"\n />\n</clr-date-container>\n<clr-date-container>\n <input\n type=\"date\"\n name=\"to\"\n class=\"datagrid-date-filter-input\"\n [(clrDate)]=\"to\"\n [placeholder]=\"maxPlaceholderValue\"\n [attr.aria-label]=\"maxPlaceholderValue\"\n />\n</clr-date-container>\n" }]