@porscheinformatik/clr-addons 13.2.1 → 13.3.1

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,8 +5,8 @@ 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';
9
- import { Subject, BehaviorSubject, timer, asyncScheduler, interval, of, ReplaySubject, takeUntil as takeUntil$1 } from 'rxjs';
8
+ import { ClarityModule, ClrFormsModule, ClrDropdown, ClrForm, ClrAlert, ClrAxis, ClrSide, ClrAlignment, ClrPopoverToggleService, ClrPopoverEventsService, ClrPopoverPositionService, ClrIconModule, ClrDropdownModule, ClrDatagridPagination, ClrDatagridFilter } from '@clr/angular';
9
+ import { Subject, BehaviorSubject, timer, asyncScheduler, interval, of, ReplaySubject, takeUntil as takeUntil$1, delay } from 'rxjs';
10
10
  import { takeUntil, observeOn, take } from 'rxjs/operators';
11
11
  import * as i3 from '@angular/router';
12
12
  import { RouterModule } from '@angular/router';
@@ -4622,39 +4622,148 @@ 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
+ // delay is needed, as onDestroy the filters emit empty values.
4685
+ // So delay it to the end of the current cycle, so the directive is also destroyed before it gets the next values
4686
+ this.datagrid.refresh.pipe(delay(0), takeUntil(this.destroy$)).subscribe(dgState => {
4687
+ const state = this.getVolatileDataState();
4688
+ state.currentPage = dgState.page?.current;
4689
+ state.columns = state.columns || {};
4690
+ Object.keys(state.columns).forEach(prop => (state.columns[prop].filterValue = undefined));
4691
+ dgState.filters?.forEach(filter => {
4692
+ const property = this.getFilterPropertyName(filter);
4693
+ if (property) {
4694
+ state.columns[property] = state.columns[property] || {};
4695
+ state.columns[property].filterValue = this.enrichFilterValue(filter);
4696
+ }
4697
+ });
4698
+ (this.useLocalStoreOnly ? localStorage : sessionStorage).setItem(this.options.key, JSON.stringify(state));
4699
+ });
4700
+ }
4701
+ /**
4702
+ * Gets the state of volatile data. This can be influenced by clrUseLocalStoreOnly.
4703
+ */
4704
+ getVolatileDataState() {
4705
+ return JSON.parse((this.useLocalStoreOnly ? localStorage : sessionStorage).getItem(this.options.key)) || {};
4706
+ }
4707
+ getLocalStorageState() {
4708
+ return JSON.parse(localStorage.getItem(this.options.key)) || {};
4709
+ }
4710
+ /**
4711
+ * As a date is serialized as string, but not deserialized as date
4712
+ * we need to add some meta information to do that manually later
4713
+ */
4714
+ enrichFilterValue(filter) {
4715
+ const result = {};
4716
+ Object.keys(filter).forEach(key => (result[key] =
4717
+ filter[key] instanceof Date
4718
+ ? {
4719
+ type: DATE_TYPE,
4720
+ value: filter[key],
4721
+ }
4722
+ : filter[key]));
4723
+ return result;
4724
+ }
4725
+ /**
4726
+ * Parse filter values with meta information like date, which needs manual deserialization to a date object
4727
+ */
4728
+ parseFilterValue(value) {
4729
+ return value?.type === DATE_TYPE
4730
+ ? new Date(value.value)
4731
+ : value;
4732
+ }
4733
+ getFilter(prop) {
4734
+ // get default filter or custom filter
4735
+ return (this.datagrid.columns.find(col => col.field === prop)?.filter ||
4736
+ this.customFilters.find(filter => this.getFilterPropertyName(filter.filter) === prop)?.filter);
4737
+ }
4738
+ getFilterPropertyName(filter) {
4739
+ // for NestedProperty we need to get the original property
4740
+ const filterWithProp = filter;
4741
+ return (filterWithProp.property?.prop || filterWithProp.property);
4742
+ }
4743
+ ngOnDestroy() {
4744
+ this.destroy$.next();
4745
+ this.destroy$.complete();
4746
+ }
4645
4747
  }
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 });
4748
+ StatePersistenceKeyDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: StatePersistenceKeyDirective, deps: [{ token: i2.ClrDatagrid }], target: i0.ɵɵFactoryTarget.Directive });
4749
+ 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
4750
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: StatePersistenceKeyDirective, decorators: [{
4649
4751
  type: Directive,
4650
4752
  args: [{
4651
4753
  selector: '[clrStatePersistenceKey]',
4652
4754
  }]
4653
- }], propDecorators: { clrStatePersistenceKey: [{
4654
- type: Input
4755
+ }], ctorParameters: function () { return [{ type: i2.ClrDatagrid }]; }, propDecorators: { options: [{
4756
+ type: Input,
4757
+ args: ['clrStatePersistenceKey']
4758
+ }], useLocalStoreOnly: [{
4759
+ type: Input,
4760
+ args: ['clrUseLocalStoreOnly']
4655
4761
  }], pagination: [{
4656
4762
  type: ContentChild,
4657
4763
  args: [ClrDatagridPagination]
4764
+ }], customFilters: [{
4765
+ type: ContentChildren,
4766
+ args: [ClrDatagridFilter, { descendants: true }]
4658
4767
  }] } });
4659
4768
 
4660
4769
  class ColumnHiddenStatePersistenceDirective {
@@ -4663,40 +4772,34 @@ class ColumnHiddenStatePersistenceDirective {
4663
4772
  this.statePersistenceKey = statePersistenceKey;
4664
4773
  this.datagrid = datagrid;
4665
4774
  this.hideableColumnDirective = hideableColumnDirective;
4775
+ this.destroy$ = new Subject();
4666
4776
  }
4667
4777
  ngOnInit() {
4668
- if (this.statePersistenceKey?.clrStatePersistenceKey && this.columnDirective?.clrDgField) {
4778
+ if (this.statePersistenceKey?.options.key && this.columnDirective?.clrDgField) {
4669
4779
  /* set hidden states from local storage (if existing) */
4670
4780
  this.initHiddenState();
4671
4781
  /* listen to state changes and persist in local storage */
4672
- this.hideableColumnDirective.hiddenChange.subscribe(hidden => {
4782
+ this.hideableColumnDirective.hiddenChange.pipe(takeUntil(this.destroy$)).subscribe(hidden => {
4673
4783
  this.setHiddenState(hidden);
4674
4784
  });
4675
4785
  }
4676
4786
  }
4677
4787
  initHiddenState() {
4678
4788
  /* 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
- }
4789
+ const persistedGridState = this.readStoredState();
4790
+ /* read column state if existing */
4791
+ if (persistedGridState?.columns?.[this.columnDirective.clrDgField]) {
4792
+ /* read column hidden state if existing */
4793
+ const persistedColumnHiddenState = persistedGridState.columns[this.columnDirective.clrDgField].hidden;
4794
+ if (persistedColumnHiddenState !== undefined) {
4795
+ this.hideableColumnDirective.clrDgHidden = persistedColumnHiddenState === true;
4689
4796
  }
4690
4797
  }
4691
4798
  }
4692
4799
  setHiddenState(hidden) {
4693
4800
  if (!this.datagrid?.detailService?.isOpen) {
4694
4801
  /* 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
- }
4802
+ const persistedGridState = this.readStoredState();
4700
4803
  /* read column state if existing */
4701
4804
  if (!persistedGridState.columns) {
4702
4805
  persistedGridState.columns = {};
@@ -4708,9 +4811,16 @@ class ColumnHiddenStatePersistenceDirective {
4708
4811
  }
4709
4812
  /* set column hidden state and persist in local storage */
4710
4813
  persistedColumnState.hidden = hidden;
4711
- localStorage.setItem(this.statePersistenceKey.clrStatePersistenceKey, JSON.stringify(persistedGridState));
4814
+ localStorage.setItem(this.statePersistenceKey.options.key, JSON.stringify(persistedGridState));
4712
4815
  }
4713
4816
  }
4817
+ readStoredState() {
4818
+ return JSON.parse(localStorage.getItem(this.statePersistenceKey.options.key)) || {};
4819
+ }
4820
+ ngOnDestroy() {
4821
+ this.destroy$.next();
4822
+ this.destroy$.complete();
4823
+ }
4714
4824
  }
4715
4825
  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
4826
  ColumnHiddenStatePersistenceDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.8", type: ColumnHiddenStatePersistenceDirective, selector: "[clrDgHideableColumn]", ngImport: i0 });
@@ -4756,6 +4866,7 @@ class ClrEnumFilterComponent {
4756
4866
  }
4757
4867
  set value(values) {
4758
4868
  this.filteredValues = values;
4869
+ this.changes.emit(true);
4759
4870
  }
4760
4871
  set clrPossibleValues(values) {
4761
4872
  this.setPossibleValues(values);
@@ -4781,6 +4892,12 @@ class ClrEnumFilterComponent {
4781
4892
  accepts(item) {
4782
4893
  return this.filteredValues.includes(item[this.property]);
4783
4894
  }
4895
+ get state() {
4896
+ return {
4897
+ property: this.property,
4898
+ value: this.filteredValues,
4899
+ };
4900
+ }
4784
4901
  ngOnDestroy() {
4785
4902
  this.destroyed$.next();
4786
4903
  this.destroyed$.complete();
@@ -4872,6 +4989,9 @@ class ClrDateFilterComponent {
4872
4989
  set property(value) {
4873
4990
  this.nestedProp = new NestedProperty(value);
4874
4991
  }
4992
+ get property() {
4993
+ return this.nestedProp.prop;
4994
+ }
4875
4995
  get maxPlaceholderValue() {
4876
4996
  return this.maxPlaceholder || this.commonStrings.keys.maxValue;
4877
4997
  }
@@ -4961,7 +5081,7 @@ class ClrDateFilterComponent {
4961
5081
  }
4962
5082
  }
4963
5083
  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"] }] });
5084
+ 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
5085
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: ClrDateFilterComponent, decorators: [{
4966
5086
  type: Component,
4967
5087
  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" }]