@one-paragon/angular-utilities 2.8.3 → 2.8.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.
- package/karma.conf.js +43 -0
- package/ng-package.json +7 -0
- package/package.json +15 -27
- package/src/action-state/action-state-spinner/action-state-spinner.component.css +16 -0
- package/src/action-state/action-state-spinner/action-state-spinner.component.html +7 -0
- package/src/action-state/action-state-spinner/action-state-spinner.component.spec.ts +25 -0
- package/src/action-state/action-state-spinner/action-state-spinner.component.ts +26 -0
- package/src/action-state/action-state-ui/action-state-ui.module.ts +13 -0
- package/src/action-state/index.ts +8 -0
- package/src/action-state/ngrx-ext/ngrx-ext.module.ts +14 -0
- package/src/action-state/ngrx.ts +69 -0
- package/src/http-request-state/RequestStateFactory.ts +56 -0
- package/src/http-request-state/RequestStateStore.ts +360 -0
- package/src/http-request-state/deprecated.ts +20 -0
- package/src/http-request-state/directives/HttpStateDirectiveBase.ts +29 -0
- package/src/http-request-state/directives/http-error-state-directive.ts +21 -0
- package/src/http-request-state/directives/http-inProgress-state-directive.ts +19 -0
- package/src/http-request-state/directives/http-notStarted-state-directive.ts +19 -0
- package/src/http-request-state/directives/http-success-state-directive.ts +29 -0
- package/src/http-request-state/directives/index.ts +5 -0
- package/src/http-request-state/directives/request-state-directive.spec.ts +73 -0
- package/src/http-request-state/directives/request-state-directive.ts +78 -0
- package/src/http-request-state/documentation/CREATE-REQUESTOR.md +667 -0
- package/src/http-request-state/documentation/README.md +191 -0
- package/src/http-request-state/documentation/REQUEST-STATE-STORE-CONFIG.md +648 -0
- package/src/http-request-state/documentation/REQUESTOR.md +616 -0
- package/src/http-request-state/helpers.ts +30 -0
- package/src/http-request-state/http-state-module.ts +23 -0
- package/src/http-request-state/index.ts +7 -0
- package/src/http-request-state/models/view-context.ts +18 -0
- package/src/http-request-state/observable.spec.ts +43 -0
- package/src/http-request-state/request-state.ts +66 -0
- package/src/http-request-state/rxjs/getRequestorBody.ts +10 -0
- package/src/http-request-state/rxjs/getRequestorState.ts +8 -0
- package/src/http-request-state/rxjs/index.ts +4 -0
- package/src/http-request-state/rxjs/tapError.ts +16 -0
- package/src/http-request-state/rxjs/tapSuccess.ts +16 -0
- package/src/http-request-state/strategies.spec.ts +42 -0
- package/src/http-request-state/types.ts +54 -0
- package/src/ngrx/actionable-selector.ts +189 -0
- package/src/ngrx/index.ts +1 -0
- package/src/public-api.ts +40 -0
- package/src/rxjs/defaultShareReplay.ts +8 -0
- package/src/rxjs/index.ts +5 -0
- package/src/rxjs/mapError.ts +8 -0
- package/src/rxjs/rxjs-operators.ts +130 -0
- package/src/rxjs/subjectifier.ts +17 -0
- package/src/rxjs/subscriber.directive.ts +57 -0
- package/src/specs/clickSubject.spec.ts +99 -0
- package/src/specs/dialog.spec.ts +101 -0
- package/src/specs/toggleGroupDirective.spec.ts +229 -0
- package/src/table-builder/classes/DefaultSettings.ts +11 -0
- package/src/table-builder/classes/MatTableObservableDataSource.ts +23 -0
- package/src/table-builder/classes/TableBuilderConfig.ts +49 -0
- package/src/table-builder/classes/TableBuilderDataSource.ts +64 -0
- package/src/table-builder/classes/TableState.ts +96 -0
- package/src/table-builder/classes/data-store.ts +10 -0
- package/src/table-builder/classes/display-col.ts +5 -0
- package/src/table-builder/classes/filter-info.ts +129 -0
- package/src/table-builder/classes/table-builder-general-settings.ts +233 -0
- package/src/table-builder/classes/table-builder.ts +105 -0
- package/src/table-builder/classes/table-store.helpers.ts +109 -0
- package/src/table-builder/classes/table-store.ts +540 -0
- package/src/table-builder/components/array-column.component.ts +34 -0
- package/src/table-builder/components/column-builder/column-builder.component.html +109 -0
- package/src/table-builder/components/column-builder/column-builder.component.scss +43 -0
- package/src/table-builder/components/column-builder/column-builder.component.spec.ts +49 -0
- package/src/table-builder/components/column-builder/column-builder.component.ts +130 -0
- package/src/table-builder/components/column-builder/column-helpers.ts +54 -0
- package/src/table-builder/components/column-header-menu/column-header-menu.component.html +128 -0
- package/src/table-builder/components/column-header-menu/column-header-menu.component.scss +97 -0
- package/src/table-builder/components/column-header-menu/column-header-menu.component.ts +113 -0
- package/src/table-builder/components/date-filter/date-filter.component.html +39 -0
- package/src/table-builder/components/date-filter/date-filter.component.ts +33 -0
- package/src/table-builder/components/date-time-filter/date-time-filter.component.html +25 -0
- package/src/table-builder/components/date-time-filter/date-time-filter.component.ts +33 -0
- package/src/table-builder/components/filter/filter.component.html +120 -0
- package/src/table-builder/components/filter/filter.component.scss +60 -0
- package/src/table-builder/components/filter/filter.component.spec.ts +86 -0
- package/src/table-builder/components/filter/filter.component.ts +73 -0
- package/src/table-builder/components/filter/in-list/in-list-filter.component.ts +171 -0
- package/src/table-builder/components/gen-col-displayer/gen-col-displayer.component.html +60 -0
- package/src/table-builder/components/gen-col-displayer/gen-col-displayer.component.scss +57 -0
- package/src/table-builder/components/gen-col-displayer/gen-col-displayer.component.ts +44 -0
- package/src/table-builder/components/generic-table/generic-table.component.html +140 -0
- package/src/table-builder/components/generic-table/generic-table.component.scss +45 -0
- package/src/table-builder/components/generic-table/generic-table.component.ts +531 -0
- package/src/table-builder/components/generic-table/paginator.component.ts +125 -0
- package/src/table-builder/components/group-by-list/group-by-list.component.css +24 -0
- package/src/table-builder/components/group-by-list/group-by-list.component.html +21 -0
- package/src/table-builder/components/group-by-list/group-by-list.component.spec.ts +23 -0
- package/src/table-builder/components/group-by-list/group-by-list.component.ts +26 -0
- package/src/table-builder/components/in-filter/in-filter.component.css +22 -0
- package/src/table-builder/components/in-filter/in-filter.component.html +38 -0
- package/src/table-builder/components/in-filter/in-filter.component.ts +66 -0
- package/src/table-builder/components/index.ts +9 -0
- package/src/table-builder/components/initialization-component/initialization.component.html +78 -0
- package/src/table-builder/components/initialization-component/initialization.component.ts +28 -0
- package/src/table-builder/components/link-column.component.ts +42 -0
- package/src/table-builder/components/number-filter/number-filter.component.css +10 -0
- package/src/table-builder/components/number-filter/number-filter.component.html +32 -0
- package/src/table-builder/components/number-filter/number-filter.component.spec.ts +30 -0
- package/src/table-builder/components/number-filter/number-filter.component.ts +34 -0
- package/src/table-builder/components/profiles-menu/profiles-menu.component.html +77 -0
- package/src/table-builder/components/profiles-menu/profiles-menu.component.scss +126 -0
- package/src/table-builder/components/profiles-menu/profiles-menu.component.spec.ts +23 -0
- package/src/table-builder/components/profiles-menu/profiles-menu.component.ts +64 -0
- package/src/table-builder/components/reset-menu/reset-menu.component.css +3 -0
- package/src/table-builder/components/reset-menu/reset-menu.component.html +10 -0
- package/src/table-builder/components/reset-menu/reset-menu.component.ts +87 -0
- package/src/table-builder/components/scroll-strategy.ts +139 -0
- package/src/table-builder/components/sort-menu/sort-menu.component-store.ts +57 -0
- package/src/table-builder/components/sort-menu/sort-menu.component.html +115 -0
- package/src/table-builder/components/sort-menu/sort-menu.component.scss +119 -0
- package/src/table-builder/components/sort-menu/sort-menu.component.ts +88 -0
- package/src/table-builder/components/table-container/table-container.component.html +94 -0
- package/src/table-builder/components/table-container/table-container.component.scss +60 -0
- package/src/table-builder/components/table-container/table-container.component.ts +467 -0
- package/src/table-builder/components/table-container/table-container.helpers/data-state.helpers.ts +113 -0
- package/src/table-builder/components/table-container/table-container.helpers/filter-state.helpers.ts +125 -0
- package/src/table-builder/components/table-container/table-container.helpers/groupBy.helpers.ts +172 -0
- package/src/table-builder/components/table-container/table-container.helpers/meta-data.helpers.ts +19 -0
- package/src/table-builder/components/table-container/table-container.helpers/sort-state.helpers.ts +47 -0
- package/src/table-builder/components/table-container/tableProps.ts +21 -0
- package/src/table-builder/components/table-container/virtual-scroll-container.ts +216 -0
- package/src/table-builder/components/table-container-filter/filter-list/filter-list.component.html +42 -0
- package/src/table-builder/components/table-container-filter/filter-list/filter-list.component.ts +47 -0
- package/src/table-builder/components/table-container-filter/gen-filter-displayer/gen-filter-displayer.component.css +40 -0
- package/src/table-builder/components/table-container-filter/gen-filter-displayer/gen-filter-displayer.component.html +11 -0
- package/src/table-builder/components/table-container-filter/gen-filter-displayer/gen-filter-displayer.component.spec.ts +85 -0
- package/src/table-builder/components/table-container-filter/gen-filter-displayer/gen-filter-displayer.component.ts +35 -0
- package/src/table-builder/components/table-container-filter/table-wrapper-filter-store.ts +13 -0
- package/src/table-builder/components/table-header-menu/table-header-menu.component.css +21 -0
- package/src/table-builder/components/table-header-menu/table-header-menu.component.html +48 -0
- package/src/table-builder/components/table-header-menu/table-header-menu.component.ts +36 -0
- package/src/table-builder/directives/custom-cell-directive.ts +63 -0
- package/src/table-builder/directives/custom-header-directive.ts +16 -0
- package/src/table-builder/directives/group-row-directive.ts +91 -0
- package/src/table-builder/directives/index.ts +8 -0
- package/src/table-builder/directives/multi-sort.directive.spec.ts +124 -0
- package/src/table-builder/directives/multi-sort.directive.ts +58 -0
- package/src/table-builder/directives/resize-column.directive.ts +107 -0
- package/src/table-builder/directives/table-wrapper.directive.ts +13 -0
- package/src/table-builder/directives/tb-filter.directive.ts +376 -0
- package/src/table-builder/documentation/table-builder/CUSTOM-CELL.md +568 -0
- package/src/table-builder/documentation/table-builder/CUSTOM-GROUP-ROW.md +356 -0
- package/src/table-builder/documentation/table-builder/METADATA-DOCUMENTATION.md +517 -0
- package/src/table-builder/documentation/table-builder/STYLER-STYLE.md +228 -0
- package/src/table-builder/documentation/table-builder/TABLE-BUILDER-CONFIG.md +325 -0
- package/src/table-builder/documentation/table-builder/TABLE-BUILDER-SETTINGS.md +515 -0
- package/src/table-builder/documentation/table-builder/TABLE-BUILDER.md +430 -0
- package/src/table-builder/documentation/table-builder/TABLE-CONTAINER.md +628 -0
- package/src/table-builder/enums/filterTypes.ts +39 -0
- package/src/table-builder/functions/boolean-filter-function.ts +12 -0
- package/src/table-builder/functions/date-filter-function.ts +85 -0
- package/src/table-builder/functions/download-data.ts +11 -0
- package/src/table-builder/functions/null-filter-function.ts +9 -0
- package/src/table-builder/functions/number-filter-function.ts +47 -0
- package/src/table-builder/functions/sort-data-function.ts +80 -0
- package/src/table-builder/functions/string-filter-function.ts +59 -0
- package/src/table-builder/interfaces/ColumnInfo.ts +9 -0
- package/src/table-builder/interfaces/dictionary.ts +3 -0
- package/src/table-builder/interfaces/meta-data.ts +279 -0
- package/src/table-builder/ngrx/tableBuilderStateStore.ts +203 -0
- package/src/table-builder/pipes/column-total.pipe.ts +16 -0
- package/src/table-builder/pipes/format-filter-type.pipe.ts +12 -0
- package/src/table-builder/pipes/format-filter-value.pipe.ts +71 -0
- package/src/table-builder/pipes/key-display.ts +13 -0
- package/src/table-builder/services/all-values-filter-creator.service.ts +92 -0
- package/src/table-builder/services/export-to-csv.service.ts +117 -0
- package/src/table-builder/services/link-creator.service.ts +98 -0
- package/src/table-builder/services/table-template-service.ts +47 -0
- package/src/table-builder/services/transform-creator.ts +90 -0
- package/src/table-builder/specs/table-custom-filters.spec.ts +262 -0
- package/src/table-builder/styles/collapser.styles.scss +16 -0
- package/src/table-builder/table-builder.module.ts +42 -0
- package/src/table-builder/types/group-types.ts +42 -0
- package/src/table-builder/types/index.ts +1 -0
- package/src/test.ts +17 -0
- package/src/utilities/array-helpers.ts +13 -0
- package/src/utilities/directives/auto-focus.directive.ts +20 -0
- package/src/utilities/directives/clickEmitterDirective.ts +15 -0
- package/src/utilities/directives/clickSubject.ts +19 -0
- package/src/utilities/directives/conditional-classes.directive.ts +36 -0
- package/src/utilities/directives/dialog-service.ts +19 -0
- package/src/utilities/directives/dialog.ts +174 -0
- package/src/utilities/directives/mat-toggle-group-directive.ts +60 -0
- package/src/utilities/directives/prevent-enter.directive.ts +12 -0
- package/src/utilities/directives/stop-propagation.directive.ts +19 -0
- package/src/utilities/directives/styler.ts +45 -0
- package/src/utilities/directives/trim-whitespace.directive.ts +20 -0
- package/src/utilities/index.ts +22 -0
- package/src/utilities/module.ts +53 -0
- package/src/utilities/pipes/function.pipe.ts +21 -0
- package/src/utilities/pipes/phone.pipe.ts +20 -0
- package/src/utilities/pipes/space-case.pipes.spec.ts +47 -0
- package/src/utilities/pipes/space-case.pipes.ts +29 -0
- package/tsconfig.lib.json +20 -0
- package/tsconfig.lib.prod.json +10 -0
- package/tsconfig.spec.json +17 -0
- package/fesm2022/one-paragon-angular-utilities.mjs +0 -7328
- package/fesm2022/one-paragon-angular-utilities.mjs.map +0 -1
- package/types/one-paragon-angular-utilities.d.ts +0 -2197
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
.header-container {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: row;
|
|
4
|
+
width: 100%;
|
|
5
|
+
align-items: center;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.negative-currency {
|
|
9
|
+
color: red;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.column-head{
|
|
13
|
+
position: relative;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.bold,
|
|
17
|
+
.group-footer {
|
|
18
|
+
font-weight: 900;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.cdk-drag-preview {
|
|
22
|
+
background: white;
|
|
23
|
+
border-radius: 4px;
|
|
24
|
+
box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
|
|
25
|
+
0 8px 10px 1px rgba(0, 0, 0, 0.14),
|
|
26
|
+
0 3px 14px 2px rgba(0, 0, 0, 0.12);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.cdk-drag-placeholder {
|
|
30
|
+
opacity: 33%;
|
|
31
|
+
border-right-width: 0px;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.cdk-drag-animating {
|
|
35
|
+
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
|
|
36
|
+
}
|
|
37
|
+
.drag-handle{
|
|
38
|
+
color:lightblue;
|
|
39
|
+
cursor: move;
|
|
40
|
+
margin-right: 9px;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { ComponentFixture, ComponentFixtureAutoDetect, TestBed, waitForAsync } from '@angular/core/testing';
|
|
2
|
+
import { ColumnBuilderComponent } from './column-builder.component';
|
|
3
|
+
import { FieldType } from '../../interfaces/meta-data';
|
|
4
|
+
import { TableBuilderConfigToken } from '../../classes/TableBuilderConfig';
|
|
5
|
+
import { provideMockStore } from '@ngrx/store/testing';
|
|
6
|
+
import { SpaceCasePipe } from '../../../utilities/pipes/space-case.pipes';
|
|
7
|
+
import { CurrencyPipe, DatePipe } from '@angular/common';
|
|
8
|
+
import { PhoneNumberPipe } from 'projects/angular-utilities/src/utilities';
|
|
9
|
+
import { MatTable } from '@angular/material/table';
|
|
10
|
+
|
|
11
|
+
const initialState = { fullTableState: {
|
|
12
|
+
'test-id': {
|
|
13
|
+
metaData: [],
|
|
14
|
+
hiddenKeys: [],
|
|
15
|
+
pageSize: 10,
|
|
16
|
+
initialized: true,
|
|
17
|
+
}
|
|
18
|
+
} };
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
describe('ColumnBuilderComponent', () => {
|
|
22
|
+
let component: ColumnBuilderComponent;
|
|
23
|
+
let fixture: ComponentFixture<ColumnBuilderComponent>;
|
|
24
|
+
|
|
25
|
+
beforeEach(waitForAsync(() => {
|
|
26
|
+
TestBed.configureTestingModule({
|
|
27
|
+
declarations: [ColumnBuilderComponent, SpaceCasePipe],
|
|
28
|
+
providers: [
|
|
29
|
+
{ provide: TableBuilderConfigToken, useValue: { defaultTableState: { } } },
|
|
30
|
+
{ provide: MatTable, useValue: { addColumnDef: (colDef) => {} } },
|
|
31
|
+
provideMockStore({ initialState }),
|
|
32
|
+
DatePipe,
|
|
33
|
+
CurrencyPipe,
|
|
34
|
+
PhoneNumberPipe,
|
|
35
|
+
],
|
|
36
|
+
})
|
|
37
|
+
.compileComponents();
|
|
38
|
+
}));
|
|
39
|
+
|
|
40
|
+
beforeEach(() => {
|
|
41
|
+
fixture = TestBed.createComponent(ColumnBuilderComponent);
|
|
42
|
+
component = fixture.componentInstance;
|
|
43
|
+
component.metaData = { key: 'key', fieldType: FieldType.String };
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('should create', () => {
|
|
47
|
+
expect(component).toBeTruthy();
|
|
48
|
+
});
|
|
49
|
+
});
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { Component, ChangeDetectionStrategy, TemplateRef, Predicate, Injector, computed, inject, viewChild, signal, Signal, AfterViewInit } from '@angular/core';
|
|
2
|
+
import { ArrayAdditional, FieldType, MetaData } from '../../interfaces/meta-data';
|
|
3
|
+
import { MatColumnDef, MatTable, MatTableModule } from '@angular/material/table';
|
|
4
|
+
import { CustomCellDirective, CustomHeaderDirective, ResizeColumnDirective } from '../../directives';
|
|
5
|
+
import { createTransformer } from '../../services/transform-creator';
|
|
6
|
+
import { TableStore } from '../../classes/table-store';
|
|
7
|
+
import { TableTemplateService } from '../../services/table-template-service';
|
|
8
|
+
import { CdkDropList, CDK_DROP_LIST, DragDropModule } from '@angular/cdk/drag-drop';
|
|
9
|
+
import { Dictionary } from '@ngrx/entity';
|
|
10
|
+
import { CurrencyPipe, DecimalPipe, NgTemplateOutlet } from '@angular/common';
|
|
11
|
+
import { ConditionalClassesDirective, FunctionPipe, SpaceCasePipe } from '../../../utilities';
|
|
12
|
+
import { MatSortModule } from '@angular/material/sort';
|
|
13
|
+
import { ColumnHeaderMenuComponent } from '../column-header-menu/column-header-menu.component';
|
|
14
|
+
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
15
|
+
import { ColumnTotalPipe } from '../../pipes/column-total.pipe';
|
|
16
|
+
import { StylerDirective } from '../../../utilities/directives/styler';
|
|
17
|
+
import { columnStyles } from './column-helpers';
|
|
18
|
+
import { TableBuilderConfigToken } from '../../classes/TableBuilderConfig';
|
|
19
|
+
|
|
20
|
+
@Component({
|
|
21
|
+
templateUrl: './column-builder.component.html',
|
|
22
|
+
styleUrls: ['./column-builder.component.scss'],
|
|
23
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
24
|
+
viewProviders: [
|
|
25
|
+
{ provide: CDK_DROP_LIST, useExisting: CdkDropList },
|
|
26
|
+
],
|
|
27
|
+
imports: [
|
|
28
|
+
MatTableModule, NgTemplateOutlet, ResizeColumnDirective, FunctionPipe, StylerDirective,
|
|
29
|
+
ConditionalClassesDirective, DragDropModule, MatSortModule, SpaceCasePipe, ColumnHeaderMenuComponent,
|
|
30
|
+
MatTooltipModule, ColumnTotalPipe, CurrencyPipe, DecimalPipe
|
|
31
|
+
]
|
|
32
|
+
})
|
|
33
|
+
export class ColumnBuilderComponent implements AfterViewInit {
|
|
34
|
+
FieldType = FieldType;
|
|
35
|
+
private config = inject(TableBuilderConfigToken);
|
|
36
|
+
private table = inject<MatTable<any>>(MatTable);
|
|
37
|
+
private state = inject(TableStore);
|
|
38
|
+
private templateService = inject(TableTemplateService);
|
|
39
|
+
private tableConfig = inject(TableBuilderConfigToken);
|
|
40
|
+
protected injector = inject(Injector);
|
|
41
|
+
|
|
42
|
+
$columnDef = viewChild(MatColumnDef);
|
|
43
|
+
$bodyTemplate = viewChild<TemplateRef<any>>('body');
|
|
44
|
+
protected $metaData = signal<MetaData | undefined>(undefined);
|
|
45
|
+
$additional = computed(() => {
|
|
46
|
+
const metaData = this.$metaData();
|
|
47
|
+
if(!metaData) return;
|
|
48
|
+
const linkInfo = this.state.$getLinkInfo(metaData)();
|
|
49
|
+
if(linkInfo){
|
|
50
|
+
return linkInfo;
|
|
51
|
+
}
|
|
52
|
+
if(metaData.fieldType === FieldType.Array){
|
|
53
|
+
return (metaData.additional as ArrayAdditional)?.limit || this.tableConfig?.arrayDefaults?.limit;
|
|
54
|
+
}
|
|
55
|
+
return undefined;
|
|
56
|
+
});
|
|
57
|
+
setMetaData(md: MetaData){
|
|
58
|
+
this.$metaData.set(md);
|
|
59
|
+
}
|
|
60
|
+
$customCell = signal<CustomCellDirective | undefined>(undefined);
|
|
61
|
+
$customHeader = signal<CustomHeaderDirective | undefined>(undefined);
|
|
62
|
+
$data!: Signal<any[]>;
|
|
63
|
+
|
|
64
|
+
$transform = computed(() => {
|
|
65
|
+
const metaData = this.$metaData();
|
|
66
|
+
if(!metaData) return;
|
|
67
|
+
return createTransformer(metaData, this.config)
|
|
68
|
+
});
|
|
69
|
+
$innerTemplate = computed(() => {
|
|
70
|
+
const metaData = this.$metaData();
|
|
71
|
+
if(!metaData) return;
|
|
72
|
+
return metaData.template || this.$customCell()?.$templateRef() || this.templateService.getTemplate(metaData);
|
|
73
|
+
});
|
|
74
|
+
$showFilters = computed(() => {
|
|
75
|
+
const metaData = this.$metaData();
|
|
76
|
+
if(!metaData) return;
|
|
77
|
+
const settings = this.state.$tableSettings();
|
|
78
|
+
return !(settings.hideColumnHeaderFilters || metaData.noFilter)
|
|
79
|
+
});
|
|
80
|
+
$outerTemplate = computed(() => {
|
|
81
|
+
return this.$customCell()?.columnDef?.cell?.template ?? this.$bodyTemplate();
|
|
82
|
+
});
|
|
83
|
+
$classes: Signal<Dictionary<Predicate<any> | true> | undefined> = computed(() => {
|
|
84
|
+
const metaData = this.$metaData();
|
|
85
|
+
if(!metaData) return;
|
|
86
|
+
if(metaData.fieldType === FieldType.Currency) {
|
|
87
|
+
return ({
|
|
88
|
+
['negative-currency']: (element) => element[metaData.key] < 0,
|
|
89
|
+
...metaData.classes
|
|
90
|
+
})
|
|
91
|
+
}
|
|
92
|
+
return metaData.classes;
|
|
93
|
+
});
|
|
94
|
+
$styles = computed(() => {
|
|
95
|
+
const metaData = this.$metaData();
|
|
96
|
+
if(!metaData) return
|
|
97
|
+
return columnStyles(metaData, this.state.$getUserDefinedWidth(metaData.key)(), this.state.$tableSettingsMinWidth());
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
private viewInited = false;
|
|
101
|
+
ngAfterViewInit() {
|
|
102
|
+
this.table.addColumnDef(this.$columnDef()!);
|
|
103
|
+
this.onViewInit();
|
|
104
|
+
this.viewInited = true;
|
|
105
|
+
}
|
|
106
|
+
private onViewInit: () => void = () => {};
|
|
107
|
+
whenViewInited = (callback: () => void) => {
|
|
108
|
+
if(this.viewInited) {
|
|
109
|
+
callback();
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
this.onViewInit = callback;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
cellClicked(element: any, key: string, event: MouseEvent) {
|
|
116
|
+
const metaData = this.$metaData();
|
|
117
|
+
if(metaData?.click) {
|
|
118
|
+
metaData.click(element, key, event);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
getTooltip = (element: any) => {
|
|
123
|
+
const metaData = this.$metaData();
|
|
124
|
+
if(!metaData?.toolTip) return;
|
|
125
|
+
if(typeof metaData.toolTip === 'string') {
|
|
126
|
+
return metaData.toolTip;
|
|
127
|
+
}
|
|
128
|
+
return metaData.toolTip!(element);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Dictionary } from "@ngrx/entity";
|
|
2
|
+
import { MetaData, metaDataArrToDict } from "../../interfaces/meta-data";
|
|
3
|
+
import { StylerStyle } from "../../../utilities/directives/styler";
|
|
4
|
+
|
|
5
|
+
export const calculateWidths = (metaData: MetaData, userDefinedWidth: number | undefined) => {
|
|
6
|
+
const definedWidth = (userDefinedWidth && `${userDefinedWidth}px`) || metaData.width;
|
|
7
|
+
return definedWidth;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function calculateUserDefinedWidth(userDefinedWidth: number | undefined){
|
|
11
|
+
if(userDefinedWidth) return { flex: `0 0 ${userDefinedWidth}px`, maxWidth: 'none' };
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function calculateTableDefinedWidth(metaData: MetaData, tableSettingsMinWidth: number | undefined){
|
|
16
|
+
if(metaData.width) return ({ flex: `0 0 ${metaData.width}`, maxWidth: 'none' });
|
|
17
|
+
const style = { flex: `${1}` };
|
|
18
|
+
if(tableSettingsMinWidth) style['minWidth'] = `${tableSettingsMinWidth}px`;
|
|
19
|
+
return style;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const calculateFlexWidth = (metaData: MetaData, userDefinedWidth: number | undefined, tableSettingsMinWidth: number | undefined) => {
|
|
23
|
+
const definedWidth = calculateWidths(metaData, userDefinedWidth);
|
|
24
|
+
if(definedWidth) return ({ flex: `0 0 ${definedWidth}`, maxWidth: 'none' });
|
|
25
|
+
const style = { flex: `${1}` };
|
|
26
|
+
if(tableSettingsMinWidth) style['minWidth'] = `${tableSettingsMinWidth}px`;
|
|
27
|
+
return style;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const columnStyles = (metaData: MetaData, userDefinedWidth: number | undefined, tableSettingsMinWidth?: number | undefined) => {
|
|
31
|
+
const fullMetaStyles = metaData.additional?.styles ?? {};
|
|
32
|
+
const userWidth = calculateUserDefinedWidth(userDefinedWidth) ?? {};
|
|
33
|
+
const tableWidth = userDefinedWidth ? {} : calculateTableDefinedWidth(metaData, tableSettingsMinWidth);
|
|
34
|
+
const styles: {
|
|
35
|
+
header: Dictionary<string>;
|
|
36
|
+
body: StylerStyle;
|
|
37
|
+
innerBody: StylerStyle;
|
|
38
|
+
footer: Dictionary<string>;
|
|
39
|
+
} = {
|
|
40
|
+
header: { ...tableWidth, ...fullMetaStyles, ...metaData.additional?.columnPartStyles?.header, ...userWidth },
|
|
41
|
+
footer: { ...tableWidth, ...fullMetaStyles, ...metaData.additional?.columnPartStyles?.footer, ...userWidth },
|
|
42
|
+
innerBody: { ...metaData.additional?.columnPartStyles?.innerBody },
|
|
43
|
+
body: { ...tableWidth, ...fullMetaStyles, ...metaData.additional?.columnPartStyles?.body, ...userWidth },
|
|
44
|
+
};
|
|
45
|
+
return styles;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const calculateFlexWidths = (metaDatas: MetaData[], userDefinedWidths: Dictionary<number>, tableSettingsMinWidth: number | undefined) => {
|
|
49
|
+
return metaDataArrToDict(metaDatas, md => calculateFlexWidth(md, userDefinedWidths[md.key], tableSettingsMinWidth));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const columnsStyles = (metaDatas: MetaData[], userDefinedWidths: Dictionary<number>) => {
|
|
53
|
+
return metaDataArrToDict(metaDatas, md => columnStyles(md, userDefinedWidths[md.key]));
|
|
54
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
@let metaData = $metaData();
|
|
2
|
+
@let filterFieldType = $filterFieldType();
|
|
3
|
+
@let currentFilterType = $currentFilterType();
|
|
4
|
+
|
|
5
|
+
<button #b mat-icon-button class="open-menu-icon-button" disableRipple [matMenuTriggerFor]="menu" [matMenuTriggerRestoreFocus]="false">
|
|
6
|
+
<mat-icon class="menu-icon">more_vert</mat-icon>
|
|
7
|
+
</button>
|
|
8
|
+
<mat-menu #menu="matMenu" >
|
|
9
|
+
@if ($fieldType() !== FieldType.NotMapped || !!$metaData().groupByLogic?.groupBy)
|
|
10
|
+
{
|
|
11
|
+
<button color="primary" mat-menu-item (click)="tableState.addGroupByKey(metaData.key)">
|
|
12
|
+
<mat-icon color="primary">group</mat-icon>
|
|
13
|
+
<span>Group By</span>
|
|
14
|
+
</button>
|
|
15
|
+
}
|
|
16
|
+
<button color="primary" mat-menu-item (click)=hideField(metaData.key)>
|
|
17
|
+
<mat-icon color="primary">visibility_off</mat-icon>
|
|
18
|
+
<span>Hide Column</span>
|
|
19
|
+
</button>
|
|
20
|
+
@if((metaData.fieldType === FieldType.Number || metaData.fieldType === FieldType.Currency) && !metaData.additional?.footer)
|
|
21
|
+
{
|
|
22
|
+
<button color="primary" mat-menu-item (click)="tableState.addFooter(metaData.key)">
|
|
23
|
+
<mat-icon color="primary">calculate</mat-icon>
|
|
24
|
+
<span>Sum</span>
|
|
25
|
+
</button>
|
|
26
|
+
}
|
|
27
|
+
<div (keydown)="$event.stopImmediatePropagation()">
|
|
28
|
+
@let filterValue = $filterValue();
|
|
29
|
+
<ng-template matMenuContent>
|
|
30
|
+
@if (filterFieldType !== FieldType.NotMapped)
|
|
31
|
+
{
|
|
32
|
+
<button color="primary" mat-menu-item (click)="addFilter(metaData)">
|
|
33
|
+
<mat-icon color="primary">filter_list</mat-icon>
|
|
34
|
+
<span>Choose Other Filter</span>
|
|
35
|
+
</button>
|
|
36
|
+
<ng-form #myForm="ngForm" class="tb-header-filter" (keydown.enter)="onEnter(myForm.value, metaData)">
|
|
37
|
+
@if(currentFilterType === FilterType.In)
|
|
38
|
+
{
|
|
39
|
+
<tb-in-list-filter name="filterValue" [key]="metaData.key" [ngModel]="filterValue" [values]="filterValue" />
|
|
40
|
+
}
|
|
41
|
+
@else if(filterFieldType === FieldType.String || filterFieldType === FieldType.Array || filterFieldType === FieldType.Unknown || filterFieldType === FieldType.PhoneNumber)
|
|
42
|
+
{
|
|
43
|
+
<mat-form-field stop-propagation class="font auto-width">
|
|
44
|
+
<mat-icon matPrefix class="search-icon">search</mat-icon>
|
|
45
|
+
<mat-label>{{currentFilterType === FilterType.StringDoesNotContain ? 'Does Not Contain...' : 'Contains...'}}</mat-label>
|
|
46
|
+
<input matInput name="filterValue" [ngModel]="undefined"/>
|
|
47
|
+
<span matSuffix [matTooltip]="currentFilterType === FilterType.StringDoesNotContain ? 'Contains' : 'Does Not Contain'">
|
|
48
|
+
<button mat-icon-button color="primary" class="header-filter-icon-button" (click)="setStringFilterType()">
|
|
49
|
+
<mat-icon [class]="{'chosen-icon': currentFilterType === FilterType.StringDoesNotContain }">
|
|
50
|
+
block
|
|
51
|
+
</mat-icon>
|
|
52
|
+
</button>
|
|
53
|
+
</span>
|
|
54
|
+
</mat-form-field>
|
|
55
|
+
}
|
|
56
|
+
@else if (filterFieldType === FieldType.Number || filterFieldType === FieldType.Currency)
|
|
57
|
+
{
|
|
58
|
+
<mat-form-field class="auto-width" stop-propagation>
|
|
59
|
+
<mat-label>{{currentFilterType === FilterType.NumberEquals ? 'Equals...' : currentFilterType === FilterType.NumberLessThan ? 'Less Than...' : 'More Than...'}}</mat-label>
|
|
60
|
+
<input matInput type='number' name="filterValue" [ngModel]="undefined" />
|
|
61
|
+
<span matPrefix class="tb-header-prefix">
|
|
62
|
+
<button mat-icon-button disableRipple class="header-filter-icon-button" [class]="{'chosen-icon': currentFilterType === FilterType.NumberLessThan }"
|
|
63
|
+
(click)="setFilterType(FilterType.NumberLessThan)">
|
|
64
|
+
<mat-icon class="suffix-icons"
|
|
65
|
+
>
|
|
66
|
+
arrow_back_ios</mat-icon>
|
|
67
|
+
</button>
|
|
68
|
+
<button mat-icon-button disableRipple class="header-filter-icon-button" [class]="{'chosen-icon': currentFilterType === FilterType.NumberGreaterThan }"
|
|
69
|
+
(click)="setFilterType(FilterType.NumberGreaterThan)" >
|
|
70
|
+
<mat-icon class="suffix-icons">arrow_forward_ios</mat-icon>
|
|
71
|
+
</button>
|
|
72
|
+
<button mat-icon-button disableRipple class="header-filter-icon-button" [class]="{'chosen-icon': currentFilterType === FilterType.NumberEquals }"
|
|
73
|
+
(click)="setFilterType(FilterType.NumberEquals)">
|
|
74
|
+
<span class="suffix-icons">=</span>
|
|
75
|
+
</button>
|
|
76
|
+
</span>
|
|
77
|
+
</mat-form-field>
|
|
78
|
+
}
|
|
79
|
+
@else if (filterFieldType === FieldType.Boolean)
|
|
80
|
+
{
|
|
81
|
+
<div>
|
|
82
|
+
<label>
|
|
83
|
+
<mat-icon class="search-icon">filter_list</mat-icon>
|
|
84
|
+
</label>
|
|
85
|
+
<mat-radio-group #ctrl="matRadioGroup" #boolField='ngModel' stop-propagation class="font" name="filterValue" [ngModel]="undefined" >
|
|
86
|
+
<mat-radio-button class="filter-radio-button" [value]="true" (click)="boolField.control.setValue(true);">True</mat-radio-button><br/>
|
|
87
|
+
<mat-radio-button class="filter-radio-button" [value]="false" (click)="boolField.control.setValue(false)">False</mat-radio-button><br/>
|
|
88
|
+
</mat-radio-group>
|
|
89
|
+
</div>
|
|
90
|
+
}
|
|
91
|
+
@else if (filterFieldType === FieldType.Date || filterFieldType === FieldType.DateTime)
|
|
92
|
+
{
|
|
93
|
+
<mat-form-field class="font auto-width" stop-propagation >
|
|
94
|
+
<span matPrefix class="tb-header-prefix">
|
|
95
|
+
<button mat-icon-button disableRipple class="header-filter-icon-button" [class]="{'chosen-icon': currentFilterType === FilterType.DateOnOrAfter }"
|
|
96
|
+
(click)="setFilterType(FilterType.DateOnOrAfter)">
|
|
97
|
+
<mat-icon class="suffix-icons underline">arrow_forward_ios</mat-icon>
|
|
98
|
+
</button>
|
|
99
|
+
<button mat-icon-button disableRipple class="header-filter-icon-button" [class]="{'chosen-icon': currentFilterType === FilterType.DateOnOrBefore }"
|
|
100
|
+
(click)="setFilterType(FilterType.DateOnOrBefore)">
|
|
101
|
+
<mat-icon class="suffix-icons underline">arrow_back_ios</mat-icon>
|
|
102
|
+
</button>
|
|
103
|
+
<button mat-icon-button disableRipple class="header-filter-icon-button" [class]="{'chosen-icon': currentFilterType === FilterType.DateIsOn }"
|
|
104
|
+
(click)="setFilterType(FilterType.DateIsOn)">
|
|
105
|
+
<span class="suffix-icons underline"> =</span>
|
|
106
|
+
</button>
|
|
107
|
+
</span>
|
|
108
|
+
<mat-label>{{currentFilterType === FilterType.DateIsOn ? 'On...' :
|
|
109
|
+
currentFilterType === FilterType.DateOnOrBefore ? 'On or Before...' : 'On or After...'}}</mat-label>
|
|
110
|
+
<input matInput name="filterValue" [ngModel]="undefined" [matDatepicker]="calendar"
|
|
111
|
+
(click)="calendar.open()"/>
|
|
112
|
+
<mat-datepicker-toggle class="date-toggle header-filter-icon-button" matSuffix preventEnter [for]="calendar" />
|
|
113
|
+
<mat-datepicker #calendar />
|
|
114
|
+
</mat-form-field>
|
|
115
|
+
}
|
|
116
|
+
<button mat-button disableRipple [disabled]="myForm.value.filterValue == undefined" (click)="onEnter(myForm.value, metaData)">
|
|
117
|
+
Apply
|
|
118
|
+
</button>
|
|
119
|
+
</ng-form>
|
|
120
|
+
}
|
|
121
|
+
</ng-template>
|
|
122
|
+
</div>
|
|
123
|
+
|
|
124
|
+
</mat-menu>
|
|
125
|
+
|
|
126
|
+
<tb-filter
|
|
127
|
+
*opDialog="addFilter$; let filter; origin b._elementRef.nativeElement; positionOnScreen { width: 300 }"
|
|
128
|
+
[filter]="filter" (done)="addFilter$.next(null)" />
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
@use '@angular/material' as mat;
|
|
2
|
+
:host{
|
|
3
|
+
@include mat.button-density(-3);
|
|
4
|
+
@include mat.icon-density(-3);
|
|
5
|
+
}
|
|
6
|
+
input[type=number]::-webkit-inner-spin-button,
|
|
7
|
+
input[type=number]::-webkit-outer-spin-button {
|
|
8
|
+
-webkit-appearance: none;
|
|
9
|
+
margin: 0;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.menu-icon{
|
|
13
|
+
font-size: 16px;
|
|
14
|
+
line-height: 16px;
|
|
15
|
+
vertical-align: top;
|
|
16
|
+
height: 16px;
|
|
17
|
+
width: 16px;
|
|
18
|
+
}
|
|
19
|
+
.search-icon{
|
|
20
|
+
margin-right: 16px;
|
|
21
|
+
vertical-align: middle;
|
|
22
|
+
height: 24px;
|
|
23
|
+
width: 24px;
|
|
24
|
+
color: rgba(0,0,0,.54);
|
|
25
|
+
font-size: 21px;
|
|
26
|
+
line-height: 1.125
|
|
27
|
+
}
|
|
28
|
+
.font{
|
|
29
|
+
font-size: 14px;
|
|
30
|
+
}
|
|
31
|
+
.filter-radio-button:first-of-type{
|
|
32
|
+
padding-left: 0;
|
|
33
|
+
}
|
|
34
|
+
.filter-radio-button{
|
|
35
|
+
padding: 10px 40px;
|
|
36
|
+
min-width: 110px;
|
|
37
|
+
}
|
|
38
|
+
.auto-width {
|
|
39
|
+
width: 260px;
|
|
40
|
+
margin: 5px;
|
|
41
|
+
display: block;
|
|
42
|
+
height: 55px;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
.open-menu-icon-button{
|
|
47
|
+
height: 28px;
|
|
48
|
+
width: 28px;
|
|
49
|
+
padding: 6px;
|
|
50
|
+
}
|
|
51
|
+
.header-filter-icon-button {
|
|
52
|
+
height: 18px;
|
|
53
|
+
width: 18px;
|
|
54
|
+
font-size: 18px;
|
|
55
|
+
padding: 0;
|
|
56
|
+
margin: 0 2px;
|
|
57
|
+
|
|
58
|
+
::ng-deep * {
|
|
59
|
+
line-height: initial;
|
|
60
|
+
font-size: initial;
|
|
61
|
+
height: 18px;
|
|
62
|
+
width: 18px;
|
|
63
|
+
font-size: 18px;
|
|
64
|
+
bottom: initial;
|
|
65
|
+
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.chosen-icon,
|
|
69
|
+
&.chosen-icon ::ng-deep * {
|
|
70
|
+
height: 22px;
|
|
71
|
+
width: 22px;
|
|
72
|
+
font-size: 22px;
|
|
73
|
+
color: green;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
mat-icon.mat-icon.suffix-icons.underline{
|
|
77
|
+
height: 20px;
|
|
78
|
+
text-decoration: underline 0.1px solid;
|
|
79
|
+
.chosen-icon &{
|
|
80
|
+
height: 24px;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
::ng-deep.mat-mdc-form-field-icon-prefix:has(.tb-header-prefix), .tb-header-prefix{
|
|
84
|
+
padding: 0;
|
|
85
|
+
flex-basis: 36%;
|
|
86
|
+
}
|
|
87
|
+
.tb-header-filter ::ng-deep.mat-mdc-form-field-subscript-wrapper{
|
|
88
|
+
line-height: 0;
|
|
89
|
+
&::before{
|
|
90
|
+
height: 0;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
.date-toggle ::ng-deep svg{
|
|
94
|
+
position: absolute;
|
|
95
|
+
left: 0;
|
|
96
|
+
top: 0;
|
|
97
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component, computed, inject, input, linkedSignal, viewChild } from '@angular/core';
|
|
2
|
+
import { FieldType, MetaData } from '../../interfaces/meta-data';
|
|
3
|
+
import { FilterType } from '../../enums/filterTypes';
|
|
4
|
+
import { FilterInfo, isFilterInfo, PartialFilter } from '../../classes/filter-info';
|
|
5
|
+
import { TableStore } from '../../classes/table-store';
|
|
6
|
+
import { MatMenuModule, MatMenuTrigger } from '@angular/material/menu';
|
|
7
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
8
|
+
import { MatButtonModule } from '@angular/material/button';
|
|
9
|
+
import { FormsModule } from '@angular/forms';
|
|
10
|
+
import { InListFilterComponent } from '../filter/in-list/in-list-filter.component';
|
|
11
|
+
import { MatInputModule } from '@angular/material/input';
|
|
12
|
+
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
13
|
+
import { DialogDirective, StopPropagationDirective } from '../../../utilities';
|
|
14
|
+
import { MatRadioModule } from '@angular/material/radio';
|
|
15
|
+
import { MatDatepickerModule } from '@angular/material/datepicker';
|
|
16
|
+
import { WrapperFilterStore } from '../table-container-filter/table-wrapper-filter-store';
|
|
17
|
+
import { Subject } from 'rxjs';
|
|
18
|
+
import { FilterComponent } from '../filter/filter.component';
|
|
19
|
+
|
|
20
|
+
@Component({
|
|
21
|
+
selector: 'tb-header-menu',
|
|
22
|
+
templateUrl: './column-header-menu.component.html',
|
|
23
|
+
styleUrl: './column-header-menu.component.scss',
|
|
24
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
25
|
+
imports: [
|
|
26
|
+
MatMenuModule, MatIconModule, MatButtonModule, FormsModule, InListFilterComponent,
|
|
27
|
+
MatInputModule, MatTooltipModule, StopPropagationDirective, MatRadioModule, MatDatepickerModule,
|
|
28
|
+
DialogDirective, FilterComponent
|
|
29
|
+
]
|
|
30
|
+
})
|
|
31
|
+
export class ColumnHeaderMenuComponent {
|
|
32
|
+
protected tableState = inject(TableStore);
|
|
33
|
+
protected filterStore = inject(WrapperFilterStore, { optional: true });
|
|
34
|
+
FieldType = FieldType;
|
|
35
|
+
FilterType = FilterType;
|
|
36
|
+
|
|
37
|
+
$metaData = input.required<MetaData>({ alias: 'metaData' });
|
|
38
|
+
$fieldType = computed(() => this.$metaData().fieldType);
|
|
39
|
+
$filterFieldType = computed(() => this.$metaData().filterLogic?.filterType || this.$fieldType())
|
|
40
|
+
$filterValue = computed(() => this.tableState.$filtersArray().filter(isFilterInfo)
|
|
41
|
+
.find(f => f.key === this.$metaData().key && f.filterType === this.$currentFilterType())?.filterValue);
|
|
42
|
+
$trigger = viewChild(MatMenuTrigger);
|
|
43
|
+
|
|
44
|
+
hideField(key: string) {
|
|
45
|
+
this.tableState.hideColumn(key);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
$metaFilterType = computed<FilterType>(() => {
|
|
49
|
+
if(this.$metaData().additional?.filterOptions?.filterableValues) {
|
|
50
|
+
return FilterType.In;
|
|
51
|
+
}
|
|
52
|
+
switch (this.$filterFieldType()) {
|
|
53
|
+
case FieldType.String:
|
|
54
|
+
case FieldType.PhoneNumber:
|
|
55
|
+
case FieldType.Array:
|
|
56
|
+
case FieldType.Unknown:
|
|
57
|
+
return FilterType.StringContains;
|
|
58
|
+
case FieldType.Currency:
|
|
59
|
+
case FieldType.Number:
|
|
60
|
+
return FilterType.NumberEquals;
|
|
61
|
+
case FieldType.Boolean:
|
|
62
|
+
return FilterType.BooleanEquals;
|
|
63
|
+
case FieldType.Date:
|
|
64
|
+
case FieldType.DateTime:
|
|
65
|
+
return FilterType.DateIsOn;
|
|
66
|
+
case FieldType.Enum:
|
|
67
|
+
return FilterType.In;
|
|
68
|
+
default: return FilterType.StringContains
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
$currentFilterType = linkedSignal(() => this.$metaFilterType());
|
|
73
|
+
$key = computed(() => this.$metaData().key || crypto.randomUUID());
|
|
74
|
+
|
|
75
|
+
setStringFilterType() {
|
|
76
|
+
if(this.$currentFilterType() === FilterType.StringContains){
|
|
77
|
+
this.$currentFilterType.set(FilterType.StringDoesNotContain);
|
|
78
|
+
} else {
|
|
79
|
+
this.$currentFilterType.set(FilterType.StringContains);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
setFilterType(filterType: FilterType) {
|
|
84
|
+
this.$currentFilterType.set(filterType)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
onEnter(filter: FilterInfo, metaData: MetaData) {
|
|
88
|
+
if(this.$currentFilterType() === FilterType.In && !filter.filterValue.length){
|
|
89
|
+
|
|
90
|
+
this.tableState.removeFilter(`header-column-${metaData.key}`);
|
|
91
|
+
|
|
92
|
+
} else if(filter.filterValue != undefined && this.$currentFilterType()) {
|
|
93
|
+
this.tableState.addFilter({
|
|
94
|
+
fieldType: this.$filterFieldType(),
|
|
95
|
+
filterId: `header-column-${metaData.key}`,
|
|
96
|
+
filterType: this.$currentFilterType(),
|
|
97
|
+
filterValue: filter.filterValue,
|
|
98
|
+
key: metaData.key,
|
|
99
|
+
});
|
|
100
|
+
this.$trigger()!.closeMenu();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
addFilter(metaData: MetaData) {
|
|
105
|
+
if(!this.filterStore) return;
|
|
106
|
+
this.addFilter$.next({
|
|
107
|
+
key: metaData.key,
|
|
108
|
+
fieldType: metaData.filterLogic?.filterType || metaData.fieldType,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
addFilter$ = new Subject<PartialFilter | null>();
|
|
113
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
@let currentFilterType = $currentFilterType();
|
|
2
|
+
@let info = $info();
|
|
3
|
+
|
|
4
|
+
@if (currentFilterType !== FilterType.DateBetween && currentFilterType !== FilterType.IsNull && currentFilterType !== FilterType.In)
|
|
5
|
+
{
|
|
6
|
+
<mat-form-field>
|
|
7
|
+
<input matInput name="filterValue" [ngModel]="info.filterValue" [matDatepicker]="cal"/>
|
|
8
|
+
<mat-datepicker-toggle class="small-button date-toggle" matSuffix preventEnter [for]="cal" />
|
|
9
|
+
<mat-datepicker #cal />
|
|
10
|
+
</mat-form-field>
|
|
11
|
+
}
|
|
12
|
+
@if(currentFilterType === FilterType.DateBetween)
|
|
13
|
+
{
|
|
14
|
+
<ng-container ngModelGroup="filterValue">
|
|
15
|
+
<mat-form-field class="my-filter" >
|
|
16
|
+
<input matInput name="Start" placeholder="From" [ngModel]="info.filterValue?.Start" [matDatepicker]="fromVal"
|
|
17
|
+
(click)="fromVal.open()"/>
|
|
18
|
+
<mat-datepicker-toggle matSuffix class="small-button date-toggle" preventEnter [for]="fromVal" />
|
|
19
|
+
<mat-datepicker #fromVal />
|
|
20
|
+
</mat-form-field>
|
|
21
|
+
<mat-form-field>
|
|
22
|
+
<input matInput name="End" placeholder="To" [ngModel]="info.filterValue?.End" [matDatepicker]="toVal" (click)="toVal.open()"/>
|
|
23
|
+
<mat-datepicker-toggle matSuffix class="small-button date-toggle" preventEnter [for]="toVal" />
|
|
24
|
+
<mat-datepicker #toVal />
|
|
25
|
+
</mat-form-field>
|
|
26
|
+
</ng-container>
|
|
27
|
+
}
|
|
28
|
+
@if(currentFilterType === FilterType.In)
|
|
29
|
+
{
|
|
30
|
+
@if($allValuesInMeta())
|
|
31
|
+
{
|
|
32
|
+
<tb-in-list-filter name="filterValue" [key]="info.key" [values]="info.filterValue" [(ngModel)]="info.filterValue" />
|
|
33
|
+
}
|
|
34
|
+
@else
|
|
35
|
+
{
|
|
36
|
+
<lib-in-filter name="filterValue" [type]="FieldType.Date" [(ngModel)]="info.filterValue" />
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|