@openziti/ziti-console-lib 0.12.3 → 0.12.5

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 (43) hide show
  1. package/esm2022/lib/features/data-table/cells/table-cell-name/table-cell-name.component.mjs +3 -3
  2. package/esm2022/lib/features/projectable-forms/edge-router-policy/edge-router-policy-form.service.mjs +4 -2
  3. package/esm2022/lib/features/projectable-forms/service-edge-router-policy/service-edge-router-policy-form.service.mjs +4 -2
  4. package/esm2022/lib/features/projectable-forms/service-policy/service-policy-form.service.mjs +4 -2
  5. package/esm2022/lib/pages/auth-policies/auth-policies-page.service.mjs +3 -2
  6. package/esm2022/lib/pages/certificate-authorities/certificate-authorities-page.service.mjs +3 -2
  7. package/esm2022/lib/pages/config-types/config-types-page.service.mjs +3 -2
  8. package/esm2022/lib/pages/configurations/configurations-page.service.mjs +3 -2
  9. package/esm2022/lib/pages/edge-router-policies/edge-router-policies-page.service.mjs +3 -2
  10. package/esm2022/lib/pages/edge-routers/edge-routers-page.service.mjs +3 -2
  11. package/esm2022/lib/pages/identities/identities-page.service.mjs +3 -2
  12. package/esm2022/lib/pages/jwt-signers/jwt-signers-page.service.mjs +3 -2
  13. package/esm2022/lib/pages/posture-checks/posture-checks-page.service.mjs +3 -2
  14. package/esm2022/lib/pages/service-edge-router-policies/service-edge-router-policies-page.service.mjs +3 -2
  15. package/esm2022/lib/pages/service-policies/service-policies-page.service.mjs +3 -2
  16. package/esm2022/lib/pages/services/services-page.service.mjs +3 -2
  17. package/esm2022/lib/pages/terminators/terminators-page.service.mjs +3 -2
  18. package/esm2022/lib/pages/transit-routers/transit-routers-page.service.mjs +3 -2
  19. package/esm2022/lib/services/ziti-controller-data.service.mjs +3 -3
  20. package/esm2022/lib/shared/list-page-service.class.mjs +21 -1
  21. package/esm2022/lib/version.mjs +2 -2
  22. package/fesm2022/openziti-ziti-console-lib.mjs +678 -639
  23. package/fesm2022/openziti-ziti-console-lib.mjs.map +1 -1
  24. package/lib/features/projectable-forms/edge-router-policy/edge-router-policy-form.service.d.ts.map +1 -1
  25. package/lib/features/projectable-forms/service-edge-router-policy/service-edge-router-policy-form.service.d.ts.map +1 -1
  26. package/lib/features/projectable-forms/service-policy/service-policy-form.service.d.ts.map +1 -1
  27. package/lib/pages/auth-policies/auth-policies-page.service.d.ts.map +1 -1
  28. package/lib/pages/certificate-authorities/certificate-authorities-page.service.d.ts.map +1 -1
  29. package/lib/pages/config-types/config-types-page.service.d.ts.map +1 -1
  30. package/lib/pages/configurations/configurations-page.service.d.ts.map +1 -1
  31. package/lib/pages/edge-router-policies/edge-router-policies-page.service.d.ts.map +1 -1
  32. package/lib/pages/edge-routers/edge-routers-page.service.d.ts.map +1 -1
  33. package/lib/pages/identities/identities-page.service.d.ts.map +1 -1
  34. package/lib/pages/jwt-signers/jwt-signers-page.service.d.ts.map +1 -1
  35. package/lib/pages/posture-checks/posture-checks-page.service.d.ts.map +1 -1
  36. package/lib/pages/service-edge-router-policies/service-edge-router-policies-page.service.d.ts.map +1 -1
  37. package/lib/pages/service-policies/service-policies-page.service.d.ts.map +1 -1
  38. package/lib/pages/services/services-page.service.d.ts.map +1 -1
  39. package/lib/pages/terminators/terminators-page.service.d.ts.map +1 -1
  40. package/lib/pages/transit-routers/transit-routers-page.service.d.ts.map +1 -1
  41. package/lib/shared/list-page-service.class.d.ts +21 -0
  42. package/lib/shared/list-page-service.class.d.ts.map +1 -1
  43. package/package.json +1 -1
@@ -4,7 +4,7 @@ import * as i4 from '@angular/router';
4
4
  import { NavigationEnd, RouterModule } from '@angular/router';
5
5
  import { Subject, BehaviorSubject, firstValueFrom, tap, map, Subscription } from 'rxjs';
6
6
  import { catchError } from 'rxjs/operators';
7
- import _, { isEmpty, isNumber, includes, isNil, defer, cloneDeep, set, invoke, get, debounce, isNaN as isNaN$1, forEach, isString, isFunction, unset, isBoolean, keys, isEqual, isObject, isArray, forOwn, invert, some, filter, sortedUniq, map as map$1, trim, delay } from 'lodash';
7
+ import _, { isEmpty, isNumber, includes, isNil, defer, cloneDeep, set, invoke, get, debounce, isNaN as isNaN$1, forEach, isString, isFunction, unset, isBoolean, keys, isEqual, isObject, isArray, forOwn, invert, some, filter, sortBy, sortedUniq, map as map$1, trim, delay } from 'lodash';
8
8
  import * as i1$1 from '@angular/common/http';
9
9
  import { HttpClient, HttpParams, HttpClientModule, HttpHeaders } from '@angular/common/http';
10
10
  import * as i1 from 'ngx-logger';
@@ -2792,456 +2792,335 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
2792
2792
  See the License for the specific language governing permissions and
2793
2793
  limitations under the License.
2794
2794
  */
2795
- let ListPageServiceClass = class ListPageServiceClass {
2796
- constructor(settings, filterService, csvDownloadService, extensionService, router) {
2797
- this.settings = settings;
2795
+ class TableColumnFilterComponent {
2796
+ constructor(filterService) {
2798
2797
  this.filterService = filterService;
2799
- this.csvDownloadService = csvDownloadService;
2800
- this.extensionService = extensionService;
2801
- this.router = router;
2802
- this.CSV_COLUMNS = [
2803
- { label: 'Name', path: 'name' },
2804
- { label: 'ID', path: 'id' },
2805
- { label: 'Created At', path: 'createdAt' }
2806
- ];
2807
- this.basePath = '';
2808
- this.headerComponentParams = {
2809
- filterType: 'TEXTINPUT',
2810
- enableSorting: true
2811
- };
2812
- this.DEFAULT_PAGING = {
2813
- filter: "",
2814
- noSearch: false,
2815
- order: "asc",
2816
- page: 1,
2817
- searchOn: "name",
2818
- sort: "name",
2819
- total: 50
2820
- };
2821
- this.totalCount = 0;
2822
- this.menuItems = [];
2823
- this.tableHeaderActions = [];
2824
- this.currentSettings = {};
2825
- this.sideModalOpen = false;
2826
- this.currentSort = {
2827
- sortBy: 'name',
2828
- ordering: 'asc'
2829
- };
2830
- this.nameColumnRenderer = (row) => {
2831
- return `<div class="col cell-name-renderer" data-id="${row?.data?.id}">
2832
- <strong>${row?.data?.name}</strong>
2833
- </div>`;
2834
- };
2835
- this.rolesRenderer = (row) => {
2836
- const colId = row.column.colId;
2837
- let roles = '';
2838
- if (row?.data?.[colId + 'Display']) {
2839
- row?.data?.[colId + 'Display'].forEach((attr) => {
2840
- const className = attr?.name?.indexOf('@') === 0 ? 'attag' : 'hashtag';
2841
- roles += `<div>
2842
- <div class="${className}">${attr.name}</div>
2843
- <div class="tag-name">${attr.name}</div>
2844
- </div>`;
2845
- });
2846
- }
2847
- else {
2848
- row?.data?.[colId]?.forEach((attr) => {
2849
- const className = attr.indexOf('@') === 0 ? 'attag' : 'hashtag';
2850
- roles += `<div>
2851
- <div class="${className}">${attr}</div>
2852
- <div class="tag-name">${attr}</div>
2853
- </div>`;
2854
- });
2855
- }
2856
- return roles;
2857
- };
2858
- this.createdAtFormatter = (row) => {
2859
- return moment(row?.data?.createdAt).local().format('M/D/YYYY HH:mm A');
2860
- };
2861
- this.dataService = inject(ZITI_DATA_SERVICE);
2862
- this.settings.settingsChange.subscribe((settings) => {
2863
- if (!isEmpty(this.settings?.settings?.session?.id) || this.dataService.dataServiceType === ZitiDataService.NODE_DATA_SERVICE_TYPE) {
2864
- if ((this.currentSettings?.session?.id !== settings?.session?.id || this.dataService.dataServiceType === ZitiDataService.NODE_DATA_SERVICE_TYPE) && this.refreshData) {
2865
- this.refreshData();
2866
- }
2867
- }
2868
- this.currentSettings = settings;
2869
- });
2870
- router.events.subscribe((event) => {
2871
- if (event => event instanceof NavigationEnd) {
2872
- if (!event?.snapshot?.routeConfig?.path) {
2873
- return;
2798
+ this.type = 'TEXTINPUT';
2799
+ this.filterString = '';
2800
+ this.filterName = '';
2801
+ this.dateFilter = '24h';
2802
+ this.subscription = new Subscription();
2803
+ this.setFilterDebounced = _.debounce(this.setFilter, 500);
2804
+ }
2805
+ ngOnInit() {
2806
+ this.subscription.add(this.filterService.filtersChanged.subscribe((filters) => {
2807
+ let tmp = '';
2808
+ for (let idx = 0; idx < filters.length; idx++) {
2809
+ if (filters[idx].columnId === this.columnDef?.colId) {
2810
+ tmp = filters[idx].value;
2811
+ break;
2874
2812
  }
2875
- const pathSegments = event.snapshot.routeConfig.path.split('/');
2876
- this.basePath = pathSegments[0];
2877
2813
  }
2878
- });
2879
- }
2880
- initMenuActions() {
2881
- if (this.extensionService.listActions) {
2882
- this.menuItems = this.menuItems.map((item) => {
2883
- this.extensionService.listActions.forEach((extItem) => {
2884
- if (item.action === extItem.action) {
2885
- item = extItem;
2886
- }
2887
- });
2888
- return item;
2889
- });
2890
- let filteredActions = this.extensionService.listActions.filter((extItem) => {
2891
- return !this.menuItems.some((item) => {
2892
- return item.action === extItem.action;
2893
- });
2894
- });
2895
- this.menuItems = [...this.menuItems, ...filteredActions];
2896
- }
2897
- }
2898
- addListItemExtensionActions(row) {
2899
- if (this.extensionService.listActions) {
2900
- const keys = this.extensionService.listActions.map((action) => {
2901
- return action.action;
2902
- });
2903
- row.actionList = [...row.actionList, ...keys];
2904
- }
2814
+ this.filterString = tmp;
2815
+ }));
2905
2816
  }
2906
- downloadItems(selectedItems) {
2907
- this.csvDownloadService.download(this.resourceType, selectedItems, this.CSV_COLUMNS, false, false, undefined, false);
2817
+ setFilter() {
2818
+ const filterObj = {
2819
+ filterName: this.filterName,
2820
+ columnId: this.columnDef?.colId,
2821
+ value: this.filterString,
2822
+ label: this.filterString,
2823
+ type: this.type,
2824
+ };
2825
+ this.filterService.updateFilter(filterObj);
2908
2826
  }
2909
- downloadAllItems() {
2910
- const paging = cloneDeep(this.DEFAULT_PAGING);
2911
- paging.total = -1;
2912
- return this.getTableData(this.resourceType, paging, undefined, undefined)
2913
- .then((results) => {
2914
- return this.downloadItems(results?.data);
2915
- });
2827
+ ngAfterViewInit() {
2828
+ this.filterInput?.nativeElement?.focus();
2916
2829
  }
2917
- getTableData(resourceType, paging, filters, sort) {
2918
- if (!paging) {
2919
- paging = { ...this.DEFAULT_PAGING };
2920
- }
2921
- if (sort) {
2922
- paging.sort = sort.sortBy;
2923
- paging.order = sort.ordering;
2924
- }
2925
- for (let idx = 0; idx < filters?.length; idx++) {
2926
- paging.noSearch = false;
2927
- paging.searchOn = filters[idx].columnId;
2928
- paging.filter = filters[idx].value;
2929
- paging.rawFilter = true;
2830
+ statusClicked(event) {
2831
+ if (event && this.openStatusMenu) {
2832
+ event.statusFilter = true;
2833
+ this.openStatusMenu(event);
2930
2834
  }
2931
- this.filterService.filtering.next(true);
2932
- return this.dataService.get(resourceType, paging, filters).finally(() => {
2933
- this.filterService.filtering.next(false);
2934
- });
2935
2835
  }
2936
- checkForAssociatedEntities(items, type, associatedType) {
2937
- const itemsWithAssociations = [];
2938
- const promises = [];
2939
- items.forEach((config) => {
2940
- const prom = this.dataService.getSubdata(type, config.id, associatedType).then((result) => {
2941
- const services = result.data || [];
2942
- if (services.length > 0) {
2943
- itemsWithAssociations.push(config);
2944
- }
2945
- });
2946
- promises.push(prom);
2947
- });
2948
- return Promise.all(promises).then(() => {
2949
- return itemsWithAssociations;
2950
- });
2951
- }
2952
- removeItems(ids) {
2953
- const promises = [];
2954
- ids.forEach((id) => {
2955
- const prom = this.dataService.delete(this.resourceType, id);
2956
- promises.push(prom);
2957
- });
2958
- return Promise.all(promises);
2836
+ ngOnDestroy() {
2837
+ if (this.subscription)
2838
+ this.subscription.unsubscribe();
2959
2839
  }
2960
- sort(sortBy, ordering = 'asc') {
2961
- this.currentSort = { sortBy, ordering };
2962
- if (this.refreshData)
2963
- this.refreshData({ sortBy, ordering });
2840
+ get availableRoleAttributes() {
2841
+ return this.columnDef?.headerComponentParams?.roleAttributes;
2964
2842
  }
2965
- hasSelectedText() {
2966
- let text = '';
2967
- if (window.getSelection) {
2968
- text = window.getSelection().toString();
2843
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TableColumnFilterComponent, deps: [{ token: DataTableFilterService }], target: i0.ɵɵFactoryTarget.Component }); }
2844
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TableColumnFilterComponent, selector: "app-table-column-filter", inputs: { type: "type", filterString: "filterString", filterName: "filterName", columnDef: "columnDef", openStatusMenu: "openStatusMenu", dateFilter: "dateFilter" }, viewQueries: [{ propertyName: "filterInput", first: true, predicate: ["filterInput"], descendants: true }], ngImport: i0, template: "<div class=\"header-filter-container\">\n <div *ngIf=\"type === 'TEXTINPUT' || type === 'COMBO'\" class=\"text-input-filter\">\n <input\n #filterInput\n (keyup)=\"setFilterDebounced()\"\n [(ngModel)]=\"filterString\"\n class=\"search\"\n id=\"SearchFilter\"\n placeholder=\"Type to Filter\"\n type=\"text\"\n />\n </div>\n <div *ngIf=\"type === 'SELECT'\"></div>\n</div>\n", styles: [".header-filter-container .search{height:2.5rem;border-width:0;font-size:.875rem;box-shadow:none;padding-left:0rem;margin-top:.9375rem}#TimeSearch{position:relative;float:left;display:inline-block;margin-left:.625rem;width:3.125rem;height:2.5rem;background-color:var(--primary)}#TimeSearch #TimeSearchList{width:2.75rem;height:0rem;position:absolute;top:0rem;left:-.125rem;overflow:hidden;transition:var(--transition);background-color:var(--menu);border-radius:.5rem;z-index:30}#TimeSearch #TimeSearchList .time{width:2.5rem;background-color:var(--background);padding-left:.5rem;padding-right:.5rem;border-radius:.5rem;line-height:1.625rem;font-size:.75rem;font-weight:700;text-align:center;margin-top:.125rem;margin-left:.125rem;left:-.125rem;top:-3.1875rem;cursor:pointer;transition:var(--transition)}#TimeSearch #TimeSearchList.open{top:-3.1875rem;width:2.75rem;height:14.125rem}#TimeSearch #TimeSelectButton{width:2.5rem;background-color:var(--background);padding-left:.5rem;padding-right:.5rem;border-radius:.5rem;line-height:1.625rem;text-align:center;font-size:.75rem;font-weight:700;margin-top:.4375rem;cursor:pointer;transition:var(--transition)}#TimeSearch #TimeSelectButton:hover,#TimeSearch #TimeSearchList .time:hover{background-color:var(--primaryColor);color:var(--white)}::ng-deep .tag-selector-filter .select2-selection{border:none!important}::ng-deep .tag-selector-filter .select2-selection .select2-search__field{height:2.1875rem!important}\n"], dependencies: [{ kind: "directive", type: i1$4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.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: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
2845
+ }
2846
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TableColumnFilterComponent, decorators: [{
2847
+ type: Component,
2848
+ args: [{ selector: 'app-table-column-filter', template: "<div class=\"header-filter-container\">\n <div *ngIf=\"type === 'TEXTINPUT' || type === 'COMBO'\" class=\"text-input-filter\">\n <input\n #filterInput\n (keyup)=\"setFilterDebounced()\"\n [(ngModel)]=\"filterString\"\n class=\"search\"\n id=\"SearchFilter\"\n placeholder=\"Type to Filter\"\n type=\"text\"\n />\n </div>\n <div *ngIf=\"type === 'SELECT'\"></div>\n</div>\n", styles: [".header-filter-container .search{height:2.5rem;border-width:0;font-size:.875rem;box-shadow:none;padding-left:0rem;margin-top:.9375rem}#TimeSearch{position:relative;float:left;display:inline-block;margin-left:.625rem;width:3.125rem;height:2.5rem;background-color:var(--primary)}#TimeSearch #TimeSearchList{width:2.75rem;height:0rem;position:absolute;top:0rem;left:-.125rem;overflow:hidden;transition:var(--transition);background-color:var(--menu);border-radius:.5rem;z-index:30}#TimeSearch #TimeSearchList .time{width:2.5rem;background-color:var(--background);padding-left:.5rem;padding-right:.5rem;border-radius:.5rem;line-height:1.625rem;font-size:.75rem;font-weight:700;text-align:center;margin-top:.125rem;margin-left:.125rem;left:-.125rem;top:-3.1875rem;cursor:pointer;transition:var(--transition)}#TimeSearch #TimeSearchList.open{top:-3.1875rem;width:2.75rem;height:14.125rem}#TimeSearch #TimeSelectButton{width:2.5rem;background-color:var(--background);padding-left:.5rem;padding-right:.5rem;border-radius:.5rem;line-height:1.625rem;text-align:center;font-size:.75rem;font-weight:700;margin-top:.4375rem;cursor:pointer;transition:var(--transition)}#TimeSearch #TimeSelectButton:hover,#TimeSearch #TimeSearchList .time:hover{background-color:var(--primaryColor);color:var(--white)}::ng-deep .tag-selector-filter .select2-selection{border:none!important}::ng-deep .tag-selector-filter .select2-selection .select2-search__field{height:2.1875rem!important}\n"] }]
2849
+ }], ctorParameters: function () { return [{ type: DataTableFilterService }]; }, propDecorators: { type: [{
2850
+ type: Input
2851
+ }], filterString: [{
2852
+ type: Input
2853
+ }], filterName: [{
2854
+ type: Input
2855
+ }], columnDef: [{
2856
+ type: Input
2857
+ }], openStatusMenu: [{
2858
+ type: Input
2859
+ }], dateFilter: [{
2860
+ type: Input
2861
+ }], filterInput: [{
2862
+ type: ViewChild,
2863
+ args: ['filterInput']
2864
+ }] } });
2865
+
2866
+ /*
2867
+ Copyright NetFoundry Inc.
2868
+
2869
+ Licensed under the Apache License, Version 2.0 (the "License");
2870
+ you may not use this file except in compliance with the License.
2871
+ You may obtain a copy of the License at
2872
+
2873
+ https://www.apache.org/licenses/LICENSE-2.0
2874
+
2875
+ Unless required by applicable law or agreed to in writing, software
2876
+ distributed under the License is distributed on an "AS IS" BASIS,
2877
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2878
+ See the License for the specific language governing permissions and
2879
+ limitations under the License.
2880
+ */
2881
+ class TableColumnDefaultComponent {
2882
+ constructor(filterService) {
2883
+ this.filterService = filterService;
2884
+ this.headerParams = {
2885
+ api: {},
2886
+ };
2887
+ this.columnDef = {
2888
+ sortDir: undefined,
2889
+ colId: undefined,
2890
+ pinColumn: undefined,
2891
+ sortColumn: undefined,
2892
+ };
2893
+ this.filterType = 'TEXTINPUT';
2894
+ this.filterOptions = [];
2895
+ this.columnFilters = {};
2896
+ this.filtering = false;
2897
+ this.showFilter = false;
2898
+ this.comboActive = false;
2899
+ this.showSecondaryFilter = false;
2900
+ this.showBubble = false;
2901
+ this.showLoader = false;
2902
+ this.subscription = new Subscription();
2903
+ this._statusClass = 'v7Offline';
2904
+ if (!this) {
2905
+ return;
2969
2906
  }
2970
- return text?.length > 0;
2971
- }
2972
- getNetworkJwt() {
2973
- return this.dataService.get('network-jwts', {}, []);
2907
+ this.item = {
2908
+ selected: false,
2909
+ };
2974
2910
  }
2975
- openEditForm(itemId = '', basePath) {
2976
- if (isEmpty(itemId)) {
2977
- itemId = 'create';
2911
+ get statusClass() {
2912
+ if (!this.showBubble) {
2913
+ return '';
2978
2914
  }
2979
- basePath = basePath ? basePath : this.basePath;
2980
- this.router?.navigateByUrl(`${basePath}/${itemId}`);
2981
- }
2982
- remToPx(remValue) {
2983
- const rootFontSize = parseFloat(window.getComputedStyle(document.documentElement).fontSize);
2984
- return remValue * rootFontSize;
2915
+ const status = _.get(this.columnObj, 'gridApi.columnFilters.hasApiSession', _.get(this.columnObj, 'gridApi.columnFilters.online'));
2916
+ switch (status) {
2917
+ case 'all':
2918
+ this._statusClass = 'v7OnlineOffline';
2919
+ break;
2920
+ case 'false':
2921
+ this._statusClass = 'v7Offline';
2922
+ break;
2923
+ case 'true':
2924
+ this._statusClass = 'v7Online';
2925
+ break;
2926
+ case 'provisioning':
2927
+ this._statusClass = '';
2928
+ this.showLoader = true;
2929
+ break;
2930
+ case 'error':
2931
+ this._statusClass = 'v7Error';
2932
+ break;
2933
+ default:
2934
+ this._statusClass = 'v7OnlineOffline';
2935
+ break;
2936
+ }
2937
+ return this._statusClass;
2985
2938
  }
2986
- ;
2987
- };
2988
- ListPageServiceClass = __decorate([
2989
- __param(0, Inject(SETTINGS_SERVICE)),
2990
- __param(3, Inject(SHAREDZ_EXTENSION))
2991
- ], ListPageServiceClass);
2992
-
2993
- class ListPageComponent {
2994
- constructor(filterService, svc, consoleEvents, dialogForm, extensionService) {
2995
- this.filterService = filterService;
2996
- this.svc = svc;
2997
- this.consoleEvents = consoleEvents;
2998
- this.dialogForm = dialogForm;
2999
- this.extensionService = extensionService;
3000
- this.startCount = '-';
3001
- this.endCount = '-';
3002
- this.totalCount = '-';
3003
- this.itemsSelected = false;
3004
- this.selectedItems = [];
3005
- this.columnDefs = [];
3006
- this.rowData = [];
3007
- this.reservedNames = [];
3008
- this.filterApplied = false;
3009
- this.modalOpen = false;
3010
- this.gridObj = {};
3011
- this.subscription = new Subscription();
3012
- this.growlerSvc = inject(GrowlerService);
2939
+ get filterApplied() {
2940
+ const columnId = _.get(this.columnDef, 'colId');
2941
+ const filterVal = _.get(this.headerParams, `api.columnFilters.${columnId}`);
2942
+ return !_.isEmpty(filterVal) || this.showFilter || this.filtering;
3013
2943
  }
3014
2944
  ngOnInit() {
3015
- this.filterService.currentPage = 1;
3016
- this.svc.sideModalOpen = false;
3017
- this.svc.refreshData = this.refreshData.bind(this);
3018
- this.svc.initMenuActions();
3019
- this.columnDefs = this.svc.initTableColumns();
3020
- this.filterService.clearFilters();
3021
- this.extensionService?.extendOnInit();
3022
- this.subscription.add(this.filterService.filtersChanged.subscribe(filters => {
3023
- this.filterApplied = filters && filters.length > 0;
3024
- this.refreshData();
3025
- }));
3026
- this.filterService.pageChanged.subscribe(page => {
3027
- this.refreshData();
3028
- });
3029
- this.subscription.add(this.consoleEvents.closeSideModal.subscribe((event) => {
3030
- this.closeModal();
3031
- }));
3032
- this.subscription.add(this.consoleEvents.refreshData.subscribe((event) => {
3033
- this.refreshData();
3034
- }));
3035
- this.consoleEvents.enableZACEvents();
3036
2945
  }
3037
2946
  ngOnDestroy() {
3038
2947
  this.subscription.unsubscribe();
3039
2948
  }
3040
- itemToggled(item) {
3041
- this.updateSelectedItems(item);
3042
- }
3043
- updateSelectedItems(toggledItem) {
3044
- let itemSelected = false;
3045
- this.selectedItems = [];
3046
- this.rowData.forEach((item) => {
3047
- const reserved = this.reservedNames?.includes(item.name);
3048
- if (reserved) {
3049
- item.selected = false;
3050
- }
3051
- else if (toggledItem?.id && toggledItem?.id === item?.id) {
3052
- item.selected = toggledItem.selected;
3053
- }
3054
- if (item.selected) {
3055
- itemSelected = true;
3056
- this.selectedItems.push(item);
3057
- }
3058
- });
3059
- this.itemsSelected = itemSelected;
3060
- }
3061
- refreshData(sort, hardRefresh = false) {
3062
- this.isLoading = true;
3063
- sort = sort ? sort : this.svc.currentSort;
3064
- this.svc.getData(this.filterService.filters, sort, this.filterService.currentPage)
3065
- .then((data) => {
3066
- this.rowData = [];
3067
- if (hardRefresh) {
3068
- defer(() => {
3069
- this.rowData = data.data;
3070
- });
3071
- }
3072
- else {
3073
- this.rowData = data.data;
3074
- }
3075
- this.totalCount = data.meta.pagination.totalCount;
3076
- this.startCount = (data.meta.pagination.offset + 1);
3077
- if (this.startCount + data.meta.pagination.limit > this.totalCount) {
3078
- this.endCount = this.totalCount;
2949
+ agInit(headerParams = {}) {
2950
+ if (!headerParams) {
2951
+ return;
2952
+ }
2953
+ this.headerParams = headerParams;
2954
+ this.enableSorting = headerParams.enableSorting;
2955
+ this.headerName = headerParams.displayName;
2956
+ this.columnObj = headerParams.column;
2957
+ this.filterType = headerParams.filterType || 'TEXTINPUT';
2958
+ this.columnFilters = headerParams.columnFilters;
2959
+ this.columnDef = this.columnObj.colDef;
2960
+ this.pinned = this.columnObj.pinned === 'left';
2961
+ this.sortDir = this.columnDef.sortDir || 'none';
2962
+ this.onlineStatusFilter = _.has(this.columnFilters, 'hasApiSession') ? 'hasApiSession' : 'online';
2963
+ this.showBubble =
2964
+ this.columnDef.colId === 'name' &&
2965
+ (_.has(this.columnFilters, 'hasApiSession') || _.has(this.columnFilters, 'online'));
2966
+ this._showColumnMenu = headerParams.showColumnMenu;
2967
+ this.updateFilterOptions();
2968
+ headerParams.api.addEventListener('sortChanged', (event) => {
2969
+ const colId = _.get(event, 'columnDef.colId', '');
2970
+ if (colId !== this.columnDef.colId) {
2971
+ this.sortDir = undefined;
3079
2972
  }
3080
2973
  else {
3081
- this.endCount = data.meta.pagination.offset + data.meta.pagination.limit;
2974
+ this.sortDir = _.get(event, 'sortDir');
3082
2975
  }
3083
- this.updateSelectedItems();
3084
- this.refreshCells();
3085
- }).finally(() => {
3086
- this.isLoading = false;
3087
2976
  });
3088
- }
3089
- downloadAllItems() {
3090
- this.isLoading = true;
3091
- this.svc.downloadAllItems().then(() => {
3092
- const growlerData = new GrowlerModel('success', 'Success', `Download Finished`, `The requested items have been downloaded`);
3093
- this.growlerSvc.show(growlerData);
3094
- }).catch(() => {
3095
- const growlerData = new GrowlerModel('error', 'Error', `Download Failed`, `Failed to retrieve items for download`);
3096
- this.growlerSvc.show(growlerData);
3097
- }).finally(() => {
3098
- this.isLoading = false;
2977
+ headerParams.api.addEventListener('columnEverythingChanged', (event) => {
2978
+ _.forEach(event.api?.columnModel?.columnDefs, colDef => {
2979
+ if (this.columnDef.colId === colDef.colId && colDef.headerComponentParams?.filterOptions) {
2980
+ this.updateFilterOptions();
2981
+ }
2982
+ });
3099
2983
  });
3100
2984
  }
3101
- openBulkDelete(selectedItems, entityTypeLabel = 'item(s)') {
3102
- const selectedIds = selectedItems.map((row) => {
3103
- return row.id;
3104
- });
3105
- const selectedNames = selectedItems.map((item) => {
3106
- return item.name;
3107
- });
3108
- const countLabel = selectedItems.length > 1 ? selectedItems.length : '';
3109
- const data = {
3110
- appendId: 'DeleteServices',
3111
- title: 'Delete',
3112
- message: `Are you sure you would like to delete the following ${countLabel} ${entityTypeLabel}?`,
3113
- bulletList: selectedNames,
3114
- confirmLabel: 'Yes',
3115
- cancelLabel: 'Oops, no get me out of here',
3116
- imageUrl: '../../assets/svgs/Confirm_Trash.svg',
3117
- showCancelLink: true
3118
- };
3119
- this.dialogRef = this.dialogForm.open(ConfirmComponent, {
3120
- data: data,
3121
- autoFocus: false,
3122
- });
3123
- this.dialogRef.afterClosed().subscribe((result) => {
3124
- if (result?.confirmed) {
3125
- this.svc.removeItems(selectedIds).then(() => {
3126
- this.refreshData(this.svc.currentSort);
3127
- });
3128
- }
3129
- });
2985
+ ngAfterViewInit() {
2986
+ if (this.showBubble) {
2987
+ // this.updateStatusClass();
2988
+ }
3130
2989
  }
3131
- handleExtensionActions(event) {
3132
- let extensionFound = false;
3133
- if (this.extensionService?.listActions?.length > 0) {
3134
- this.extensionService?.listActions?.forEach((extAction) => {
3135
- if (extAction?.action === event?.action) {
3136
- extAction.callback(event.item);
3137
- extensionFound = true;
3138
- }
2990
+ pin() {
2991
+ this.columnDef.pinColumn(this.columnObj, this.pinned ? false : 'left');
2992
+ this.pinned = !this.pinned;
2993
+ }
2994
+ hide() {
2995
+ this.headerParams.api.zitiHideColumn(this.columnObj, false);
2996
+ }
2997
+ sort(event) {
2998
+ if (!this.columnDef.sortable) {
2999
+ return;
3000
+ }
3001
+ const targetId = _.get(event, 'target.id');
3002
+ if (_.includes([`HeaderStatus_${this.columnDef.colId}`, 'SearchFilter', `HeaderFilterIcon_${this.columnDef.colId}`], targetId)) {
3003
+ return;
3004
+ }
3005
+ if (_.isEmpty(this.sortDir)) {
3006
+ this.sortDir = 'asc';
3007
+ }
3008
+ else if (this.sortDir === 'asc') {
3009
+ this.sortDir = 'desc';
3010
+ }
3011
+ else {
3012
+ this.sortDir = 'asc';
3013
+ }
3014
+ _.set(this.headerParams, 'api.sortDir', this.sortDir);
3015
+ _.set(this.headerParams, 'api.sortDir', this.columnDef.colId);
3016
+ if (this.columnDef.sortColumn) {
3017
+ this.columnDef.sortColumn(this.columnDef.colId, this.sortDir, this.headerParams.api);
3018
+ this.headerParams.api.dispatchEvent({
3019
+ type: 'sortChanged',
3020
+ columnDef: this.columnDef,
3021
+ sortDir: this.sortDir,
3139
3022
  });
3140
3023
  }
3141
- return extensionFound;
3142
- }
3143
- gridReady(event) {
3144
- this.gridObj = event;
3145
- }
3146
- refreshCells() {
3147
- defer(() => {
3148
- var params = {
3149
- force: true,
3150
- };
3151
- this.gridObj?.api?.refreshCells(params);
3152
- });
3153
- }
3154
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ListPageComponent, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable }); }
3155
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ListPageComponent }); }
3156
- }
3157
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ListPageComponent, decorators: [{
3158
- type: Injectable
3159
- }], ctorParameters: function () { return [{ type: DataTableFilterService }, { type: ListPageServiceClass }, { type: ConsoleEventsService }, { type: i5$1.MatDialog }, { type: undefined }]; } });
3160
-
3161
- /*
3162
- Copyright NetFoundry Inc.
3163
-
3164
- Licensed under the Apache License, Version 2.0 (the "License");
3165
- you may not use this file except in compliance with the License.
3166
- You may obtain a copy of the License at
3167
-
3168
- https://www.apache.org/licenses/LICENSE-2.0
3169
-
3170
- Unless required by applicable law or agreed to in writing, software
3171
- distributed under the License is distributed on an "AS IS" BASIS,
3172
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3173
- See the License for the specific language governing permissions and
3174
- limitations under the License.
3175
- */
3176
- class TableColumnFilterComponent {
3177
- constructor(filterService) {
3178
- this.filterService = filterService;
3179
- this.type = 'TEXTINPUT';
3180
- this.filterString = '';
3181
- this.filterName = '';
3182
- this.dateFilter = '24h';
3183
- this.subscription = new Subscription();
3184
- this.setFilterDebounced = _.debounce(this.setFilter, 500);
3185
3024
  }
3186
- ngOnInit() {
3187
- this.subscription.add(this.filterService.filtersChanged.subscribe((filters) => {
3188
- let tmp = '';
3189
- for (let idx = 0; idx < filters.length; idx++) {
3190
- if (filters[idx].columnId === this.columnDef?.colId) {
3191
- tmp = filters[idx].value;
3192
- break;
3193
- }
3025
+ toggleFilter(event) {
3026
+ this.showFilter = !this.showFilter;
3027
+ if (this.filterType === 'SELECT' || this.filterType === 'COMBO' || this.filterType === 'DATETIME' || this.filterType === 'ATTRIBUTE') {
3028
+ if (this.showFilter) {
3029
+ this.updateFilterOptions();
3030
+ _.invoke(this.headerParams, 'api.openHeaderFilter', event, this.filterOptions, this.filterType, this.columnDef?.colId, this.headerName, this.columnDef?.headerComponentParams);
3194
3031
  }
3195
- this.filterString = tmp;
3196
- }));
3197
- }
3198
- setFilter() {
3199
- const filterObj = {
3200
- filterName: this.filterName,
3201
- columnId: this.columnDef?.colId,
3202
- value: this.filterString,
3203
- label: this.filterString,
3204
- type: this.type,
3205
- };
3206
- this.filterService.updateFilter(filterObj);
3032
+ else {
3033
+ _.invoke(this.headerParams, 'api.closeHeaderFilter', event);
3034
+ }
3035
+ }
3036
+ else if (this.filterType === 'CUSTOM') {
3037
+ if (this.showFilter) {
3038
+ this.updateFilterOptions();
3039
+ _.invoke(this.headerParams, 'column.colDef.headerComponentParams.openHeaderFilter', event, this.filterOptions);
3040
+ }
3041
+ else {
3042
+ _.invoke(this.headerParams, 'column.colDef.headerComponentParams.closeHeaderFilter', event);
3043
+ }
3044
+ }
3207
3045
  }
3208
- ngAfterViewInit() {
3209
- this.filterInput?.nativeElement?.focus();
3046
+ toggleSecondaryFilter(event) {
3047
+ this.showSecondaryFilter = !this.showSecondaryFilter;
3048
+ if (this.showSecondaryFilter) {
3049
+ const options = [
3050
+ {
3051
+ label: 'Any',
3052
+ columnId: this.onlineStatusFilter,
3053
+ filterName: 'Status',
3054
+ value: undefined,
3055
+ bubbleClass: 'v7OnlineOffline',
3056
+ },
3057
+ {
3058
+ label: 'Online',
3059
+ columnId: this.onlineStatusFilter,
3060
+ filterName: 'Status',
3061
+ value: 'true',
3062
+ bubbleClass: 'v7Online',
3063
+ },
3064
+ {
3065
+ label: 'Offline',
3066
+ columnId: this.onlineStatusFilter,
3067
+ filterName: 'Status',
3068
+ value: 'false',
3069
+ bubbleClass: 'v7Offline',
3070
+ },
3071
+ ];
3072
+ _.invoke(this.headerParams, 'api.openHeaderFilter', event, options);
3073
+ }
3074
+ else {
3075
+ _.invoke(this.headerParams, 'api.closeHeaderFilter', event);
3076
+ }
3210
3077
  }
3211
- statusClicked(event) {
3212
- if (event && this.openStatusMenu) {
3213
- event.statusFilter = true;
3214
- this.openStatusMenu(event);
3078
+ hideFilter(event) {
3079
+ const targetId = _.get(event, 'target.id');
3080
+ if (_.includes([`HeaderFilterButton_${this.columnDef.colId}`, `HeaderFilterIcon_${this.columnDef.colId}`], targetId)) {
3081
+ return;
3215
3082
  }
3083
+ else if (targetId === this.columnDef?.colId && this.filterType === 'COMBO') {
3084
+ return;
3085
+ }
3086
+ _.invoke(this.headerParams, 'api.closeHeaderFilter', event);
3087
+ this.comboActive = false;
3088
+ this.showFilter = false;
3089
+ this.showSecondaryFilter = false;
3216
3090
  }
3217
- ngOnDestroy() {
3218
- if (this.subscription)
3219
- this.subscription.unsubscribe();
3091
+ refresh(params) {
3092
+ return true;
3220
3093
  }
3221
- get availableRoleAttributes() {
3222
- return this.columnDef?.headerComponentParams?.roleAttributes;
3094
+ openGridMenu() {
3095
+ if (!this._showColumnMenu) {
3096
+ return;
3097
+ }
3098
+ this._showColumnMenu(this.menuButton.nativeElement);
3223
3099
  }
3224
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TableColumnFilterComponent, deps: [{ token: DataTableFilterService }], target: i0.ɵɵFactoryTarget.Component }); }
3225
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TableColumnFilterComponent, selector: "app-table-column-filter", inputs: { type: "type", filterString: "filterString", filterName: "filterName", columnDef: "columnDef", openStatusMenu: "openStatusMenu", dateFilter: "dateFilter" }, viewQueries: [{ propertyName: "filterInput", first: true, predicate: ["filterInput"], descendants: true }], ngImport: i0, template: "<div class=\"header-filter-container\">\n <div *ngIf=\"type === 'TEXTINPUT' || type === 'COMBO'\" class=\"text-input-filter\">\n <input\n #filterInput\n (keyup)=\"setFilterDebounced()\"\n [(ngModel)]=\"filterString\"\n class=\"search\"\n id=\"SearchFilter\"\n placeholder=\"Type to Filter\"\n type=\"text\"\n />\n </div>\n <div *ngIf=\"type === 'SELECT'\"></div>\n</div>\n", styles: [".header-filter-container .search{height:2.5rem;border-width:0;font-size:.875rem;box-shadow:none;padding-left:0rem;margin-top:.9375rem}#TimeSearch{position:relative;float:left;display:inline-block;margin-left:.625rem;width:3.125rem;height:2.5rem;background-color:var(--primary)}#TimeSearch #TimeSearchList{width:2.75rem;height:0rem;position:absolute;top:0rem;left:-.125rem;overflow:hidden;transition:var(--transition);background-color:var(--menu);border-radius:.5rem;z-index:30}#TimeSearch #TimeSearchList .time{width:2.5rem;background-color:var(--background);padding-left:.5rem;padding-right:.5rem;border-radius:.5rem;line-height:1.625rem;font-size:.75rem;font-weight:700;text-align:center;margin-top:.125rem;margin-left:.125rem;left:-.125rem;top:-3.1875rem;cursor:pointer;transition:var(--transition)}#TimeSearch #TimeSearchList.open{top:-3.1875rem;width:2.75rem;height:14.125rem}#TimeSearch #TimeSelectButton{width:2.5rem;background-color:var(--background);padding-left:.5rem;padding-right:.5rem;border-radius:.5rem;line-height:1.625rem;text-align:center;font-size:.75rem;font-weight:700;margin-top:.4375rem;cursor:pointer;transition:var(--transition)}#TimeSearch #TimeSelectButton:hover,#TimeSearch #TimeSearchList .time:hover{background-color:var(--primaryColor);color:var(--white)}::ng-deep .tag-selector-filter .select2-selection{border:none!important}::ng-deep .tag-selector-filter .select2-selection .select2-search__field{height:2.1875rem!important}\n"], dependencies: [{ kind: "directive", type: i1$4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.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: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
3100
+ updateFilterOptions() {
3101
+ let options = [];
3102
+ if (this.headerParams.getFilterOptions) {
3103
+ options = this.headerParams.getFilterOptions();
3104
+ }
3105
+ else {
3106
+ options = this.headerParams.filterOptions;
3107
+ }
3108
+ this.filterOptions = _.map(options, (option) => {
3109
+ option.columnId = this.columnDef.colId;
3110
+ option.filterName = this.headerName;
3111
+ option.type = this.filterType;
3112
+ return option;
3113
+ });
3114
+ }
3115
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TableColumnDefaultComponent, deps: [{ token: DataTableFilterService }], target: i0.ɵɵFactoryTarget.Component }); }
3116
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TableColumnDefaultComponent, selector: "app-table-column-default", viewQueries: [{ propertyName: "menuButton", first: true, predicate: ["menuButton"], descendants: true }], ngImport: i0, template: "<div\n (click)=\"sort($event)\"\n [ngClass]=\"{ 'nf-can-sort': enableSorting }\"\n class=\"ag-cell-label-container ag-header-cell-sorted-none\"\n id=\"TableHeaderContainer_{{ columnDef.colId }}\"\n>\n <span\n #menuButton\n (click)=\"openGridMenu()\"\n *ngIf=\"false\"\n class=\"ag-header-icon ag-header-cell-menu-button\"\n id=\"HeaderMenu_{{ columnDef.colId }}\"\n ref=\"eMenu\"\n >\n <span class=\"ag-icon ag-icon-menu\" unselectable=\"on\"></span>\n </span>\n <span\n (click)=\"pin()\"\n class=\"ag-header-icon ag-header-col-pin-button\"\n id=\"HeaderPin_{{ columnDef.colId }}\"\n title=\"{{ pinned ? 'Unpin Column' : 'Pin Column' }}\"\n >\n <span class=\"ag-icon ag-icon-pin\"></span>\n </span>\n <span\n (click)=\"hide()\"\n class=\"ag-header-icon ag-header-col-hide-button\"\n id=\"HeaderHide_{{ columnDef.colId }}\"\n title=\"Hide Column\"\n >\n <span class=\"ag-icon ag-icon-eye-slash\"></span>\n </span>\n <div class=\"ag-header-cell-label\" ref=\"eLabel\" unselectable=\"on\">\n <span\n *ngIf=\"!headerParams.filterType\"\n [ngClass]=\"{ 'ag-filter-applied': filterApplied }\"\n class=\"ag-header-icon ag-header-col-filter-button\"\n id=\"HeaderFilterSpacer_{{ columnDef.colId }}\"\n >\n <span class=\"ag-icon ag-icon-filter\" id=\"HeaderFilterSpace_{{ columnDef.colId }}\" style=\"opacity: 0\"></span>\n </span>\n <span\n (click)=\"toggleFilter($event)\"\n *ngIf=\"headerParams.filterType\"\n [ngClass]=\"{ 'ag-filter-applied': filterApplied }\"\n class=\"ag-header-icon ag-header-col-filter-button\"\n id=\"HeaderFilterButton_{{ columnDef.colId }}\"\n >\n <span class=\"ag-icon ag-icon-filter\" id=\"HeaderFilterIcon_{{ columnDef.colId }}\"></span>\n </span>\n <div\n (clickOutside)=\"hideFilter($event)\"\n [ngClass]=\"{ 'show-input-filter': showFilter }\"\n class=\"header-text-container text-input-filter\"\n >\n <span\n (click)=\"toggleSecondaryFilter($event)\"\n *ngIf=\"showBubble\"\n [ngClass]=\"statusClass\"\n class=\"bubble\"\n id=\"HeaderStatus_{{ columnDef.colId }}\"\n >\n <svg *ngIf=\"showLoader\" class=\"circular\" viewBox=\"25 25 50 50\">\n <circle\n class=\"path\"\n cx=\"50\"\n cy=\"50\"\n fill=\"none\"\n r=\"20\"\n stroke-miterlimit=\"10\"\n stroke-width=\"3\"\n ></circle>\n </svg>\n </span>\n <app-table-column-filter\n *ngIf=\"((showFilter || comboActive) && !(filterType === 'COMBO' && !comboActive)) && filterType !== 'SELECT' && filterType !== 'CUSTOM'\"\n [columnDef]=\"columnDef\"\n [filterName]=\"headerName\"\n [filterString]=\"''\"\n [openStatusMenu]=\"toggleSecondaryFilter.bind(this)\"\n [type]=\"filterType\"\n ></app-table-column-filter>\n <span\n *ngIf=\"((!showFilter && !comboActive) || (filterType === 'COMBO' && !comboActive)) || filterType === 'SELECT' || filterType === 'CUSTOM'\"\n [title]=\"headerName\"\n class=\"ag-header-cell-text\"\n id=\"HeaderName_{{ columnDef.colId }}\"\n unselectable=\"on\"\n >{{ headerName }}</span\n >\n </div>\n <span\n *ngIf=\"enableSorting && !showFilter\"\n [ngClass]=\"{ 'ag-hidden': sortDir !== 'desc' }\"\n class=\"ag-header-icon ag-header-label-icon ag-sort-ascending-icon\"\n id=\"HeaderSortAsc_{{ columnDef.colId }}\"\n >\n <span class=\"ag-icon ag-icon-asc\" unselectable=\"on\"></span>\n </span>\n <span\n *ngIf=\"enableSorting && !showFilter\"\n [ngClass]=\"{ 'ag-hidden': sortDir !== 'asc' }\"\n class=\"ag-header-icon ag-header-label-icon ag-sort-descending-icon\"\n id=\"HeaderSortDesc_{{ columnDef.colId }}\"\n >\n <span class=\"ag-icon ag-icon-desc\" unselectable=\"on\"></span>\n </span>\n </div>\n</div>\n", styles: [".ag-header-sort-click-space{display:flex;height:100%;position:relative;width:100%}.ag-header-col-filter-button.ag-filter-applied{opacity:1!important}.Online,.v7Online,.v7Offline{margin-right:.5rem!important;height:.875rem!important;width:.875rem!important}.Online:hover,.v7Online:hover,.v7Offline:hover{border-color:var(--primaryColor)!important;border-style:solid;border-width:var(--inputBorderWidth);height:.625rem!important;width:.625rem!important}.header-text-container{white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis}.text-input-filter{display:flex;flex-direction:row;align-items:center}.text-input-filter .bubble{margin-top:.5rem;margin-left:.0625rem;margin-right:.5rem;width:.875rem;height:.875rem;flex-shrink:0}.ag-header-col-filter-button{margin-top:.5rem}.ag-header-cell-text{margin-top:.125rem;width:100%}.ag-header-cell-label .ag-sort-descending-icon{margin-top:1.25rem!important}.show-input-filter{width:100%}.filterButton{background-image:none}.filterButton .options{position:fixed}\n"], dependencies: [{ kind: "directive", type: i1$4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.ClickOutsideDirective, selector: "[clickOutside]", inputs: ["clickOutsideEnabled", "attachOutsideOnClick", "delayClickOutsideInit", "emitOnBlur", "exclude", "excludeBeforeClick", "clickOutsideEvents"], outputs: ["clickOutside"] }, { kind: "component", type: TableColumnFilterComponent, selector: "app-table-column-filter", inputs: ["type", "filterString", "filterName", "columnDef", "openStatusMenu", "dateFilter"] }] }); }
3226
3117
  }
3227
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TableColumnFilterComponent, decorators: [{
3118
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TableColumnDefaultComponent, decorators: [{
3228
3119
  type: Component,
3229
- args: [{ selector: 'app-table-column-filter', template: "<div class=\"header-filter-container\">\n <div *ngIf=\"type === 'TEXTINPUT' || type === 'COMBO'\" class=\"text-input-filter\">\n <input\n #filterInput\n (keyup)=\"setFilterDebounced()\"\n [(ngModel)]=\"filterString\"\n class=\"search\"\n id=\"SearchFilter\"\n placeholder=\"Type to Filter\"\n type=\"text\"\n />\n </div>\n <div *ngIf=\"type === 'SELECT'\"></div>\n</div>\n", styles: [".header-filter-container .search{height:2.5rem;border-width:0;font-size:.875rem;box-shadow:none;padding-left:0rem;margin-top:.9375rem}#TimeSearch{position:relative;float:left;display:inline-block;margin-left:.625rem;width:3.125rem;height:2.5rem;background-color:var(--primary)}#TimeSearch #TimeSearchList{width:2.75rem;height:0rem;position:absolute;top:0rem;left:-.125rem;overflow:hidden;transition:var(--transition);background-color:var(--menu);border-radius:.5rem;z-index:30}#TimeSearch #TimeSearchList .time{width:2.5rem;background-color:var(--background);padding-left:.5rem;padding-right:.5rem;border-radius:.5rem;line-height:1.625rem;font-size:.75rem;font-weight:700;text-align:center;margin-top:.125rem;margin-left:.125rem;left:-.125rem;top:-3.1875rem;cursor:pointer;transition:var(--transition)}#TimeSearch #TimeSearchList.open{top:-3.1875rem;width:2.75rem;height:14.125rem}#TimeSearch #TimeSelectButton{width:2.5rem;background-color:var(--background);padding-left:.5rem;padding-right:.5rem;border-radius:.5rem;line-height:1.625rem;text-align:center;font-size:.75rem;font-weight:700;margin-top:.4375rem;cursor:pointer;transition:var(--transition)}#TimeSearch #TimeSelectButton:hover,#TimeSearch #TimeSearchList .time:hover{background-color:var(--primaryColor);color:var(--white)}::ng-deep .tag-selector-filter .select2-selection{border:none!important}::ng-deep .tag-selector-filter .select2-selection .select2-search__field{height:2.1875rem!important}\n"] }]
3230
- }], ctorParameters: function () { return [{ type: DataTableFilterService }]; }, propDecorators: { type: [{
3231
- type: Input
3232
- }], filterString: [{
3233
- type: Input
3234
- }], filterName: [{
3235
- type: Input
3236
- }], columnDef: [{
3237
- type: Input
3238
- }], openStatusMenu: [{
3239
- type: Input
3240
- }], dateFilter: [{
3241
- type: Input
3242
- }], filterInput: [{
3120
+ args: [{ selector: 'app-table-column-default', template: "<div\n (click)=\"sort($event)\"\n [ngClass]=\"{ 'nf-can-sort': enableSorting }\"\n class=\"ag-cell-label-container ag-header-cell-sorted-none\"\n id=\"TableHeaderContainer_{{ columnDef.colId }}\"\n>\n <span\n #menuButton\n (click)=\"openGridMenu()\"\n *ngIf=\"false\"\n class=\"ag-header-icon ag-header-cell-menu-button\"\n id=\"HeaderMenu_{{ columnDef.colId }}\"\n ref=\"eMenu\"\n >\n <span class=\"ag-icon ag-icon-menu\" unselectable=\"on\"></span>\n </span>\n <span\n (click)=\"pin()\"\n class=\"ag-header-icon ag-header-col-pin-button\"\n id=\"HeaderPin_{{ columnDef.colId }}\"\n title=\"{{ pinned ? 'Unpin Column' : 'Pin Column' }}\"\n >\n <span class=\"ag-icon ag-icon-pin\"></span>\n </span>\n <span\n (click)=\"hide()\"\n class=\"ag-header-icon ag-header-col-hide-button\"\n id=\"HeaderHide_{{ columnDef.colId }}\"\n title=\"Hide Column\"\n >\n <span class=\"ag-icon ag-icon-eye-slash\"></span>\n </span>\n <div class=\"ag-header-cell-label\" ref=\"eLabel\" unselectable=\"on\">\n <span\n *ngIf=\"!headerParams.filterType\"\n [ngClass]=\"{ 'ag-filter-applied': filterApplied }\"\n class=\"ag-header-icon ag-header-col-filter-button\"\n id=\"HeaderFilterSpacer_{{ columnDef.colId }}\"\n >\n <span class=\"ag-icon ag-icon-filter\" id=\"HeaderFilterSpace_{{ columnDef.colId }}\" style=\"opacity: 0\"></span>\n </span>\n <span\n (click)=\"toggleFilter($event)\"\n *ngIf=\"headerParams.filterType\"\n [ngClass]=\"{ 'ag-filter-applied': filterApplied }\"\n class=\"ag-header-icon ag-header-col-filter-button\"\n id=\"HeaderFilterButton_{{ columnDef.colId }}\"\n >\n <span class=\"ag-icon ag-icon-filter\" id=\"HeaderFilterIcon_{{ columnDef.colId }}\"></span>\n </span>\n <div\n (clickOutside)=\"hideFilter($event)\"\n [ngClass]=\"{ 'show-input-filter': showFilter }\"\n class=\"header-text-container text-input-filter\"\n >\n <span\n (click)=\"toggleSecondaryFilter($event)\"\n *ngIf=\"showBubble\"\n [ngClass]=\"statusClass\"\n class=\"bubble\"\n id=\"HeaderStatus_{{ columnDef.colId }}\"\n >\n <svg *ngIf=\"showLoader\" class=\"circular\" viewBox=\"25 25 50 50\">\n <circle\n class=\"path\"\n cx=\"50\"\n cy=\"50\"\n fill=\"none\"\n r=\"20\"\n stroke-miterlimit=\"10\"\n stroke-width=\"3\"\n ></circle>\n </svg>\n </span>\n <app-table-column-filter\n *ngIf=\"((showFilter || comboActive) && !(filterType === 'COMBO' && !comboActive)) && filterType !== 'SELECT' && filterType !== 'CUSTOM'\"\n [columnDef]=\"columnDef\"\n [filterName]=\"headerName\"\n [filterString]=\"''\"\n [openStatusMenu]=\"toggleSecondaryFilter.bind(this)\"\n [type]=\"filterType\"\n ></app-table-column-filter>\n <span\n *ngIf=\"((!showFilter && !comboActive) || (filterType === 'COMBO' && !comboActive)) || filterType === 'SELECT' || filterType === 'CUSTOM'\"\n [title]=\"headerName\"\n class=\"ag-header-cell-text\"\n id=\"HeaderName_{{ columnDef.colId }}\"\n unselectable=\"on\"\n >{{ headerName }}</span\n >\n </div>\n <span\n *ngIf=\"enableSorting && !showFilter\"\n [ngClass]=\"{ 'ag-hidden': sortDir !== 'desc' }\"\n class=\"ag-header-icon ag-header-label-icon ag-sort-ascending-icon\"\n id=\"HeaderSortAsc_{{ columnDef.colId }}\"\n >\n <span class=\"ag-icon ag-icon-asc\" unselectable=\"on\"></span>\n </span>\n <span\n *ngIf=\"enableSorting && !showFilter\"\n [ngClass]=\"{ 'ag-hidden': sortDir !== 'asc' }\"\n class=\"ag-header-icon ag-header-label-icon ag-sort-descending-icon\"\n id=\"HeaderSortDesc_{{ columnDef.colId }}\"\n >\n <span class=\"ag-icon ag-icon-desc\" unselectable=\"on\"></span>\n </span>\n </div>\n</div>\n", styles: [".ag-header-sort-click-space{display:flex;height:100%;position:relative;width:100%}.ag-header-col-filter-button.ag-filter-applied{opacity:1!important}.Online,.v7Online,.v7Offline{margin-right:.5rem!important;height:.875rem!important;width:.875rem!important}.Online:hover,.v7Online:hover,.v7Offline:hover{border-color:var(--primaryColor)!important;border-style:solid;border-width:var(--inputBorderWidth);height:.625rem!important;width:.625rem!important}.header-text-container{white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis}.text-input-filter{display:flex;flex-direction:row;align-items:center}.text-input-filter .bubble{margin-top:.5rem;margin-left:.0625rem;margin-right:.5rem;width:.875rem;height:.875rem;flex-shrink:0}.ag-header-col-filter-button{margin-top:.5rem}.ag-header-cell-text{margin-top:.125rem;width:100%}.ag-header-cell-label .ag-sort-descending-icon{margin-top:1.25rem!important}.show-input-filter{width:100%}.filterButton{background-image:none}.filterButton .options{position:fixed}\n"] }]
3121
+ }], ctorParameters: function () { return [{ type: DataTableFilterService }]; }, propDecorators: { menuButton: [{
3243
3122
  type: ViewChild,
3244
- args: ['filterInput']
3123
+ args: ['menuButton']
3245
3124
  }] } });
3246
3125
 
3247
3126
  /*
@@ -3259,250 +3138,390 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
3259
3138
  See the License for the specific language governing permissions and
3260
3139
  limitations under the License.
3261
3140
  */
3262
- class TableColumnDefaultComponent {
3263
- constructor(filterService) {
3141
+ let ListPageServiceClass = class ListPageServiceClass {
3142
+ constructor(settings, filterService, csvDownloadService, extensionService, router) {
3143
+ this.settings = settings;
3264
3144
  this.filterService = filterService;
3265
- this.headerParams = {
3266
- api: {},
3145
+ this.csvDownloadService = csvDownloadService;
3146
+ this.extensionService = extensionService;
3147
+ this.router = router;
3148
+ this.CSV_COLUMNS = [
3149
+ { label: 'Name', path: 'name' },
3150
+ { label: 'ID', path: 'id' },
3151
+ { label: 'Created At', path: 'createdAt' }
3152
+ ];
3153
+ this.basePath = '';
3154
+ this.headerComponentParams = {
3155
+ filterType: 'TEXTINPUT',
3156
+ enableSorting: true
3267
3157
  };
3268
- this.columnDef = {
3269
- sortDir: undefined,
3270
- colId: undefined,
3271
- pinColumn: undefined,
3272
- sortColumn: undefined,
3158
+ this.ID_COLUMN_DEF = {
3159
+ colId: 'id',
3160
+ field: 'id',
3161
+ headerName: 'ID',
3162
+ headerComponent: TableColumnDefaultComponent,
3163
+ headerComponentParams: this.headerComponentParams,
3164
+ cellRendererParams: { pathRoot: this.basePath, showIdentityIcons: true },
3165
+ onCellClicked: (data) => {
3166
+ if (this.hasSelectedText()) {
3167
+ return;
3168
+ }
3169
+ this.openEditForm(data?.data?.id);
3170
+ },
3171
+ resizable: true,
3172
+ cellClass: 'nf-cell-vert-align tCol',
3173
+ sortable: true,
3174
+ filter: true,
3175
+ hide: true,
3176
+ };
3177
+ this.DEFAULT_PAGING = {
3178
+ filter: "",
3179
+ noSearch: false,
3180
+ order: "asc",
3181
+ page: 1,
3182
+ searchOn: "name",
3183
+ sort: "name",
3184
+ total: 50
3185
+ };
3186
+ this.totalCount = 0;
3187
+ this.menuItems = [];
3188
+ this.tableHeaderActions = [];
3189
+ this.currentSettings = {};
3190
+ this.sideModalOpen = false;
3191
+ this.currentSort = {
3192
+ sortBy: 'name',
3193
+ ordering: 'asc'
3194
+ };
3195
+ this.nameColumnRenderer = (row) => {
3196
+ return `<div class="col cell-name-renderer" data-id="${row?.data?.id}">
3197
+ <strong>${row?.data?.name}</strong>
3198
+ </div>`;
3199
+ };
3200
+ this.rolesRenderer = (row) => {
3201
+ const colId = row.column.colId;
3202
+ let roles = '';
3203
+ if (row?.data?.[colId + 'Display']) {
3204
+ row?.data?.[colId + 'Display'].forEach((attr) => {
3205
+ const className = attr?.name?.indexOf('@') === 0 ? 'attag' : 'hashtag';
3206
+ roles += `<div>
3207
+ <div class="${className}">${attr.name}</div>
3208
+ <div class="tag-name">${attr.name}</div>
3209
+ </div>`;
3210
+ });
3211
+ }
3212
+ else {
3213
+ row?.data?.[colId]?.forEach((attr) => {
3214
+ const className = attr.indexOf('@') === 0 ? 'attag' : 'hashtag';
3215
+ roles += `<div>
3216
+ <div class="${className}">${attr}</div>
3217
+ <div class="tag-name">${attr}</div>
3218
+ </div>`;
3219
+ });
3220
+ }
3221
+ return roles;
3273
3222
  };
3274
- this.filterType = 'TEXTINPUT';
3275
- this.filterOptions = [];
3276
- this.columnFilters = {};
3277
- this.filtering = false;
3278
- this.showFilter = false;
3279
- this.comboActive = false;
3280
- this.showSecondaryFilter = false;
3281
- this.showBubble = false;
3282
- this.showLoader = false;
3283
- this.subscription = new Subscription();
3284
- this._statusClass = 'v7Offline';
3285
- if (!this) {
3286
- return;
3287
- }
3288
- this.item = {
3289
- selected: false,
3223
+ this.createdAtFormatter = (row) => {
3224
+ return moment(row?.data?.createdAt).local().format('M/D/YYYY HH:mm A');
3290
3225
  };
3226
+ this.dataService = inject(ZITI_DATA_SERVICE);
3227
+ this.settings.settingsChange.subscribe((settings) => {
3228
+ if (!isEmpty(this.settings?.settings?.session?.id) || this.dataService.dataServiceType === ZitiDataService.NODE_DATA_SERVICE_TYPE) {
3229
+ if ((this.currentSettings?.session?.id !== settings?.session?.id || this.dataService.dataServiceType === ZitiDataService.NODE_DATA_SERVICE_TYPE) && this.refreshData) {
3230
+ this.refreshData();
3231
+ }
3232
+ }
3233
+ this.currentSettings = settings;
3234
+ });
3235
+ router.events.subscribe((event) => {
3236
+ if (event => event instanceof NavigationEnd) {
3237
+ if (!event?.snapshot?.routeConfig?.path) {
3238
+ return;
3239
+ }
3240
+ const pathSegments = event.snapshot.routeConfig.path.split('/');
3241
+ this.basePath = pathSegments[0];
3242
+ }
3243
+ });
3291
3244
  }
3292
- get statusClass() {
3293
- if (!this.showBubble) {
3294
- return '';
3295
- }
3296
- const status = _.get(this.columnObj, 'gridApi.columnFilters.hasApiSession', _.get(this.columnObj, 'gridApi.columnFilters.online'));
3297
- switch (status) {
3298
- case 'all':
3299
- this._statusClass = 'v7OnlineOffline';
3300
- break;
3301
- case 'false':
3302
- this._statusClass = 'v7Offline';
3303
- break;
3304
- case 'true':
3305
- this._statusClass = 'v7Online';
3306
- break;
3307
- case 'provisioning':
3308
- this._statusClass = '';
3309
- this.showLoader = true;
3310
- break;
3311
- case 'error':
3312
- this._statusClass = 'v7Error';
3313
- break;
3314
- default:
3315
- this._statusClass = 'v7OnlineOffline';
3316
- break;
3245
+ initMenuActions() {
3246
+ if (this.extensionService.listActions) {
3247
+ this.menuItems = this.menuItems.map((item) => {
3248
+ this.extensionService.listActions.forEach((extItem) => {
3249
+ if (item.action === extItem.action) {
3250
+ item = extItem;
3251
+ }
3252
+ });
3253
+ return item;
3254
+ });
3255
+ let filteredActions = this.extensionService.listActions.filter((extItem) => {
3256
+ return !this.menuItems.some((item) => {
3257
+ return item.action === extItem.action;
3258
+ });
3259
+ });
3260
+ this.menuItems = [...this.menuItems, ...filteredActions];
3317
3261
  }
3318
- return this._statusClass;
3319
3262
  }
3320
- get filterApplied() {
3321
- const columnId = _.get(this.columnDef, 'colId');
3322
- const filterVal = _.get(this.headerParams, `api.columnFilters.${columnId}`);
3323
- return !_.isEmpty(filterVal) || this.showFilter || this.filtering;
3263
+ addListItemExtensionActions(row) {
3264
+ if (this.extensionService.listActions) {
3265
+ const keys = this.extensionService.listActions.map((action) => {
3266
+ return action.action;
3267
+ });
3268
+ row.actionList = [...row.actionList, ...keys];
3269
+ }
3324
3270
  }
3325
- ngOnInit() {
3271
+ downloadItems(selectedItems) {
3272
+ this.csvDownloadService.download(this.resourceType, selectedItems, this.CSV_COLUMNS, false, false, undefined, false);
3326
3273
  }
3327
- ngOnDestroy() {
3328
- this.subscription.unsubscribe();
3274
+ downloadAllItems() {
3275
+ const paging = cloneDeep(this.DEFAULT_PAGING);
3276
+ paging.total = -1;
3277
+ return this.getTableData(this.resourceType, paging, undefined, undefined)
3278
+ .then((results) => {
3279
+ return this.downloadItems(results?.data);
3280
+ });
3329
3281
  }
3330
- agInit(headerParams = {}) {
3331
- if (!headerParams) {
3332
- return;
3282
+ getTableData(resourceType, paging, filters, sort) {
3283
+ if (!paging) {
3284
+ paging = { ...this.DEFAULT_PAGING };
3333
3285
  }
3334
- this.headerParams = headerParams;
3335
- this.enableSorting = headerParams.enableSorting;
3336
- this.headerName = headerParams.displayName;
3337
- this.columnObj = headerParams.column;
3338
- this.filterType = headerParams.filterType || 'TEXTINPUT';
3339
- this.columnFilters = headerParams.columnFilters;
3340
- this.columnDef = this.columnObj.colDef;
3341
- this.pinned = this.columnObj.pinned === 'left';
3342
- this.sortDir = this.columnDef.sortDir || 'none';
3343
- this.onlineStatusFilter = _.has(this.columnFilters, 'hasApiSession') ? 'hasApiSession' : 'online';
3344
- this.showBubble =
3345
- this.columnDef.colId === 'name' &&
3346
- (_.has(this.columnFilters, 'hasApiSession') || _.has(this.columnFilters, 'online'));
3347
- this._showColumnMenu = headerParams.showColumnMenu;
3348
- this.updateFilterOptions();
3349
- headerParams.api.addEventListener('sortChanged', (event) => {
3350
- const colId = _.get(event, 'columnDef.colId', '');
3351
- if (colId !== this.columnDef.colId) {
3352
- this.sortDir = undefined;
3353
- }
3354
- else {
3355
- this.sortDir = _.get(event, 'sortDir');
3356
- }
3286
+ if (sort) {
3287
+ paging.sort = sort.sortBy;
3288
+ paging.order = sort.ordering;
3289
+ }
3290
+ for (let idx = 0; idx < filters?.length; idx++) {
3291
+ paging.noSearch = false;
3292
+ paging.searchOn = filters[idx].columnId;
3293
+ paging.filter = filters[idx].value;
3294
+ paging.rawFilter = true;
3295
+ }
3296
+ this.filterService.filtering.next(true);
3297
+ return this.dataService.get(resourceType, paging, filters).finally(() => {
3298
+ this.filterService.filtering.next(false);
3357
3299
  });
3358
- headerParams.api.addEventListener('columnEverythingChanged', (event) => {
3359
- _.forEach(event.api?.columnModel?.columnDefs, colDef => {
3360
- if (this.columnDef.colId === colDef.colId && colDef.headerComponentParams?.filterOptions) {
3361
- this.updateFilterOptions();
3300
+ }
3301
+ checkForAssociatedEntities(items, type, associatedType) {
3302
+ const itemsWithAssociations = [];
3303
+ const promises = [];
3304
+ items.forEach((config) => {
3305
+ const prom = this.dataService.getSubdata(type, config.id, associatedType).then((result) => {
3306
+ const services = result.data || [];
3307
+ if (services.length > 0) {
3308
+ itemsWithAssociations.push(config);
3362
3309
  }
3363
3310
  });
3311
+ promises.push(prom);
3312
+ });
3313
+ return Promise.all(promises).then(() => {
3314
+ return itemsWithAssociations;
3364
3315
  });
3365
3316
  }
3366
- ngAfterViewInit() {
3367
- if (this.showBubble) {
3368
- // this.updateStatusClass();
3317
+ removeItems(ids) {
3318
+ const promises = [];
3319
+ ids.forEach((id) => {
3320
+ const prom = this.dataService.delete(this.resourceType, id);
3321
+ promises.push(prom);
3322
+ });
3323
+ return Promise.all(promises);
3324
+ }
3325
+ sort(sortBy, ordering = 'asc') {
3326
+ this.currentSort = { sortBy, ordering };
3327
+ if (this.refreshData)
3328
+ this.refreshData({ sortBy, ordering });
3329
+ }
3330
+ hasSelectedText() {
3331
+ let text = '';
3332
+ if (window.getSelection) {
3333
+ text = window.getSelection().toString();
3369
3334
  }
3335
+ return text?.length > 0;
3336
+ }
3337
+ getNetworkJwt() {
3338
+ return this.dataService.get('network-jwts', {}, []);
3339
+ }
3340
+ openEditForm(itemId = '', basePath) {
3341
+ if (isEmpty(itemId)) {
3342
+ itemId = 'create';
3343
+ }
3344
+ basePath = basePath ? basePath : this.basePath;
3345
+ this.router?.navigateByUrl(`${basePath}/${itemId}`);
3346
+ }
3347
+ remToPx(remValue) {
3348
+ const rootFontSize = parseFloat(window.getComputedStyle(document.documentElement).fontSize);
3349
+ return remValue * rootFontSize;
3350
+ }
3351
+ ;
3352
+ };
3353
+ ListPageServiceClass = __decorate([
3354
+ __param(0, Inject(SETTINGS_SERVICE)),
3355
+ __param(3, Inject(SHAREDZ_EXTENSION))
3356
+ ], ListPageServiceClass);
3357
+
3358
+ class ListPageComponent {
3359
+ constructor(filterService, svc, consoleEvents, dialogForm, extensionService) {
3360
+ this.filterService = filterService;
3361
+ this.svc = svc;
3362
+ this.consoleEvents = consoleEvents;
3363
+ this.dialogForm = dialogForm;
3364
+ this.extensionService = extensionService;
3365
+ this.startCount = '-';
3366
+ this.endCount = '-';
3367
+ this.totalCount = '-';
3368
+ this.itemsSelected = false;
3369
+ this.selectedItems = [];
3370
+ this.columnDefs = [];
3371
+ this.rowData = [];
3372
+ this.reservedNames = [];
3373
+ this.filterApplied = false;
3374
+ this.modalOpen = false;
3375
+ this.gridObj = {};
3376
+ this.subscription = new Subscription();
3377
+ this.growlerSvc = inject(GrowlerService);
3378
+ }
3379
+ ngOnInit() {
3380
+ this.filterService.currentPage = 1;
3381
+ this.svc.sideModalOpen = false;
3382
+ this.svc.refreshData = this.refreshData.bind(this);
3383
+ this.svc.initMenuActions();
3384
+ this.columnDefs = this.svc.initTableColumns();
3385
+ this.filterService.clearFilters();
3386
+ this.extensionService?.extendOnInit();
3387
+ this.subscription.add(this.filterService.filtersChanged.subscribe(filters => {
3388
+ this.filterApplied = filters && filters.length > 0;
3389
+ this.refreshData();
3390
+ }));
3391
+ this.filterService.pageChanged.subscribe(page => {
3392
+ this.refreshData();
3393
+ });
3394
+ this.subscription.add(this.consoleEvents.closeSideModal.subscribe((event) => {
3395
+ this.closeModal();
3396
+ }));
3397
+ this.subscription.add(this.consoleEvents.refreshData.subscribe((event) => {
3398
+ this.refreshData();
3399
+ }));
3400
+ this.consoleEvents.enableZACEvents();
3370
3401
  }
3371
- pin() {
3372
- this.columnDef.pinColumn(this.columnObj, this.pinned ? false : 'left');
3373
- this.pinned = !this.pinned;
3402
+ ngOnDestroy() {
3403
+ this.subscription.unsubscribe();
3374
3404
  }
3375
- hide() {
3376
- this.headerParams.api.zitiHideColumn(this.columnObj, false);
3405
+ itemToggled(item) {
3406
+ this.updateSelectedItems(item);
3377
3407
  }
3378
- sort(event) {
3379
- if (!this.columnDef.sortable) {
3380
- return;
3381
- }
3382
- const targetId = _.get(event, 'target.id');
3383
- if (_.includes([`HeaderStatus_${this.columnDef.colId}`, 'SearchFilter', `HeaderFilterIcon_${this.columnDef.colId}`], targetId)) {
3384
- return;
3385
- }
3386
- if (_.isEmpty(this.sortDir)) {
3387
- this.sortDir = 'asc';
3388
- }
3389
- else if (this.sortDir === 'asc') {
3390
- this.sortDir = 'desc';
3391
- }
3392
- else {
3393
- this.sortDir = 'asc';
3394
- }
3395
- _.set(this.headerParams, 'api.sortDir', this.sortDir);
3396
- _.set(this.headerParams, 'api.sortDir', this.columnDef.colId);
3397
- if (this.columnDef.sortColumn) {
3398
- this.columnDef.sortColumn(this.columnDef.colId, this.sortDir, this.headerParams.api);
3399
- this.headerParams.api.dispatchEvent({
3400
- type: 'sortChanged',
3401
- columnDef: this.columnDef,
3402
- sortDir: this.sortDir,
3403
- });
3404
- }
3408
+ updateSelectedItems(toggledItem) {
3409
+ let itemSelected = false;
3410
+ this.selectedItems = [];
3411
+ this.rowData.forEach((item) => {
3412
+ const reserved = this.reservedNames?.includes(item.name);
3413
+ if (reserved) {
3414
+ item.selected = false;
3415
+ }
3416
+ else if (toggledItem?.id && toggledItem?.id === item?.id) {
3417
+ item.selected = toggledItem.selected;
3418
+ }
3419
+ if (item.selected) {
3420
+ itemSelected = true;
3421
+ this.selectedItems.push(item);
3422
+ }
3423
+ });
3424
+ this.itemsSelected = itemSelected;
3405
3425
  }
3406
- toggleFilter(event) {
3407
- this.showFilter = !this.showFilter;
3408
- if (this.filterType === 'SELECT' || this.filterType === 'COMBO' || this.filterType === 'DATETIME' || this.filterType === 'ATTRIBUTE') {
3409
- if (this.showFilter) {
3410
- this.updateFilterOptions();
3411
- _.invoke(this.headerParams, 'api.openHeaderFilter', event, this.filterOptions, this.filterType, this.columnDef?.colId, this.headerName, this.columnDef?.headerComponentParams);
3426
+ refreshData(sort, hardRefresh = false) {
3427
+ this.isLoading = true;
3428
+ sort = sort ? sort : this.svc.currentSort;
3429
+ this.svc.getData(this.filterService.filters, sort, this.filterService.currentPage)
3430
+ .then((data) => {
3431
+ this.rowData = [];
3432
+ if (hardRefresh) {
3433
+ defer(() => {
3434
+ this.rowData = data.data;
3435
+ });
3412
3436
  }
3413
3437
  else {
3414
- _.invoke(this.headerParams, 'api.closeHeaderFilter', event);
3438
+ this.rowData = data.data;
3415
3439
  }
3416
- }
3417
- else if (this.filterType === 'CUSTOM') {
3418
- if (this.showFilter) {
3419
- this.updateFilterOptions();
3420
- _.invoke(this.headerParams, 'column.colDef.headerComponentParams.openHeaderFilter', event, this.filterOptions);
3440
+ this.totalCount = data.meta.pagination.totalCount;
3441
+ this.startCount = (data.meta.pagination.offset + 1);
3442
+ if (this.startCount + data.meta.pagination.limit > this.totalCount) {
3443
+ this.endCount = this.totalCount;
3421
3444
  }
3422
3445
  else {
3423
- _.invoke(this.headerParams, 'column.colDef.headerComponentParams.closeHeaderFilter', event);
3446
+ this.endCount = data.meta.pagination.offset + data.meta.pagination.limit;
3424
3447
  }
3425
- }
3426
- }
3427
- toggleSecondaryFilter(event) {
3428
- this.showSecondaryFilter = !this.showSecondaryFilter;
3429
- if (this.showSecondaryFilter) {
3430
- const options = [
3431
- {
3432
- label: 'Any',
3433
- columnId: this.onlineStatusFilter,
3434
- filterName: 'Status',
3435
- value: undefined,
3436
- bubbleClass: 'v7OnlineOffline',
3437
- },
3438
- {
3439
- label: 'Online',
3440
- columnId: this.onlineStatusFilter,
3441
- filterName: 'Status',
3442
- value: 'true',
3443
- bubbleClass: 'v7Online',
3444
- },
3445
- {
3446
- label: 'Offline',
3447
- columnId: this.onlineStatusFilter,
3448
- filterName: 'Status',
3449
- value: 'false',
3450
- bubbleClass: 'v7Offline',
3451
- },
3452
- ];
3453
- _.invoke(this.headerParams, 'api.openHeaderFilter', event, options);
3454
- }
3455
- else {
3456
- _.invoke(this.headerParams, 'api.closeHeaderFilter', event);
3457
- }
3448
+ this.updateSelectedItems();
3449
+ this.refreshCells();
3450
+ }).finally(() => {
3451
+ this.isLoading = false;
3452
+ });
3458
3453
  }
3459
- hideFilter(event) {
3460
- const targetId = _.get(event, 'target.id');
3461
- if (_.includes([`HeaderFilterButton_${this.columnDef.colId}`, `HeaderFilterIcon_${this.columnDef.colId}`], targetId)) {
3462
- return;
3463
- }
3464
- else if (targetId === this.columnDef?.colId && this.filterType === 'COMBO') {
3465
- return;
3466
- }
3467
- _.invoke(this.headerParams, 'api.closeHeaderFilter', event);
3468
- this.comboActive = false;
3469
- this.showFilter = false;
3470
- this.showSecondaryFilter = false;
3454
+ downloadAllItems() {
3455
+ this.isLoading = true;
3456
+ this.svc.downloadAllItems().then(() => {
3457
+ const growlerData = new GrowlerModel('success', 'Success', `Download Finished`, `The requested items have been downloaded`);
3458
+ this.growlerSvc.show(growlerData);
3459
+ }).catch(() => {
3460
+ const growlerData = new GrowlerModel('error', 'Error', `Download Failed`, `Failed to retrieve items for download`);
3461
+ this.growlerSvc.show(growlerData);
3462
+ }).finally(() => {
3463
+ this.isLoading = false;
3464
+ });
3471
3465
  }
3472
- refresh(params) {
3473
- return true;
3466
+ openBulkDelete(selectedItems, entityTypeLabel = 'item(s)') {
3467
+ const selectedIds = selectedItems.map((row) => {
3468
+ return row.id;
3469
+ });
3470
+ const selectedNames = selectedItems.map((item) => {
3471
+ return item.name;
3472
+ });
3473
+ const countLabel = selectedItems.length > 1 ? selectedItems.length : '';
3474
+ const data = {
3475
+ appendId: 'DeleteServices',
3476
+ title: 'Delete',
3477
+ message: `Are you sure you would like to delete the following ${countLabel} ${entityTypeLabel}?`,
3478
+ bulletList: selectedNames,
3479
+ confirmLabel: 'Yes',
3480
+ cancelLabel: 'Oops, no get me out of here',
3481
+ imageUrl: '../../assets/svgs/Confirm_Trash.svg',
3482
+ showCancelLink: true
3483
+ };
3484
+ this.dialogRef = this.dialogForm.open(ConfirmComponent, {
3485
+ data: data,
3486
+ autoFocus: false,
3487
+ });
3488
+ this.dialogRef.afterClosed().subscribe((result) => {
3489
+ if (result?.confirmed) {
3490
+ this.svc.removeItems(selectedIds).then(() => {
3491
+ this.refreshData(this.svc.currentSort);
3492
+ });
3493
+ }
3494
+ });
3474
3495
  }
3475
- openGridMenu() {
3476
- if (!this._showColumnMenu) {
3477
- return;
3496
+ handleExtensionActions(event) {
3497
+ let extensionFound = false;
3498
+ if (this.extensionService?.listActions?.length > 0) {
3499
+ this.extensionService?.listActions?.forEach((extAction) => {
3500
+ if (extAction?.action === event?.action) {
3501
+ extAction.callback(event.item);
3502
+ extensionFound = true;
3503
+ }
3504
+ });
3478
3505
  }
3479
- this._showColumnMenu(this.menuButton.nativeElement);
3506
+ return extensionFound;
3480
3507
  }
3481
- updateFilterOptions() {
3482
- let options = [];
3483
- if (this.headerParams.getFilterOptions) {
3484
- options = this.headerParams.getFilterOptions();
3485
- }
3486
- else {
3487
- options = this.headerParams.filterOptions;
3488
- }
3489
- this.filterOptions = _.map(options, (option) => {
3490
- option.columnId = this.columnDef.colId;
3491
- option.filterName = this.headerName;
3492
- option.type = this.filterType;
3493
- return option;
3508
+ gridReady(event) {
3509
+ this.gridObj = event;
3510
+ }
3511
+ refreshCells() {
3512
+ defer(() => {
3513
+ var params = {
3514
+ force: true,
3515
+ };
3516
+ this.gridObj?.api?.refreshCells(params);
3494
3517
  });
3495
3518
  }
3496
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TableColumnDefaultComponent, deps: [{ token: DataTableFilterService }], target: i0.ɵɵFactoryTarget.Component }); }
3497
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TableColumnDefaultComponent, selector: "app-table-column-default", viewQueries: [{ propertyName: "menuButton", first: true, predicate: ["menuButton"], descendants: true }], ngImport: i0, template: "<div\n (click)=\"sort($event)\"\n [ngClass]=\"{ 'nf-can-sort': enableSorting }\"\n class=\"ag-cell-label-container ag-header-cell-sorted-none\"\n id=\"TableHeaderContainer_{{ columnDef.colId }}\"\n>\n <span\n #menuButton\n (click)=\"openGridMenu()\"\n *ngIf=\"false\"\n class=\"ag-header-icon ag-header-cell-menu-button\"\n id=\"HeaderMenu_{{ columnDef.colId }}\"\n ref=\"eMenu\"\n >\n <span class=\"ag-icon ag-icon-menu\" unselectable=\"on\"></span>\n </span>\n <span\n (click)=\"pin()\"\n class=\"ag-header-icon ag-header-col-pin-button\"\n id=\"HeaderPin_{{ columnDef.colId }}\"\n title=\"{{ pinned ? 'Unpin Column' : 'Pin Column' }}\"\n >\n <span class=\"ag-icon ag-icon-pin\"></span>\n </span>\n <span\n (click)=\"hide()\"\n class=\"ag-header-icon ag-header-col-hide-button\"\n id=\"HeaderHide_{{ columnDef.colId }}\"\n title=\"Hide Column\"\n >\n <span class=\"ag-icon ag-icon-eye-slash\"></span>\n </span>\n <div class=\"ag-header-cell-label\" ref=\"eLabel\" unselectable=\"on\">\n <span\n *ngIf=\"!headerParams.filterType\"\n [ngClass]=\"{ 'ag-filter-applied': filterApplied }\"\n class=\"ag-header-icon ag-header-col-filter-button\"\n id=\"HeaderFilterSpacer_{{ columnDef.colId }}\"\n >\n <span class=\"ag-icon ag-icon-filter\" id=\"HeaderFilterSpace_{{ columnDef.colId }}\" style=\"opacity: 0\"></span>\n </span>\n <span\n (click)=\"toggleFilter($event)\"\n *ngIf=\"headerParams.filterType\"\n [ngClass]=\"{ 'ag-filter-applied': filterApplied }\"\n class=\"ag-header-icon ag-header-col-filter-button\"\n id=\"HeaderFilterButton_{{ columnDef.colId }}\"\n >\n <span class=\"ag-icon ag-icon-filter\" id=\"HeaderFilterIcon_{{ columnDef.colId }}\"></span>\n </span>\n <div\n (clickOutside)=\"hideFilter($event)\"\n [ngClass]=\"{ 'show-input-filter': showFilter }\"\n class=\"header-text-container text-input-filter\"\n >\n <span\n (click)=\"toggleSecondaryFilter($event)\"\n *ngIf=\"showBubble\"\n [ngClass]=\"statusClass\"\n class=\"bubble\"\n id=\"HeaderStatus_{{ columnDef.colId }}\"\n >\n <svg *ngIf=\"showLoader\" class=\"circular\" viewBox=\"25 25 50 50\">\n <circle\n class=\"path\"\n cx=\"50\"\n cy=\"50\"\n fill=\"none\"\n r=\"20\"\n stroke-miterlimit=\"10\"\n stroke-width=\"3\"\n ></circle>\n </svg>\n </span>\n <app-table-column-filter\n *ngIf=\"((showFilter || comboActive) && !(filterType === 'COMBO' && !comboActive)) && filterType !== 'SELECT' && filterType !== 'CUSTOM'\"\n [columnDef]=\"columnDef\"\n [filterName]=\"headerName\"\n [filterString]=\"''\"\n [openStatusMenu]=\"toggleSecondaryFilter.bind(this)\"\n [type]=\"filterType\"\n ></app-table-column-filter>\n <span\n *ngIf=\"((!showFilter && !comboActive) || (filterType === 'COMBO' && !comboActive)) || filterType === 'SELECT' || filterType === 'CUSTOM'\"\n [title]=\"headerName\"\n class=\"ag-header-cell-text\"\n id=\"HeaderName_{{ columnDef.colId }}\"\n unselectable=\"on\"\n >{{ headerName }}</span\n >\n </div>\n <span\n *ngIf=\"enableSorting && !showFilter\"\n [ngClass]=\"{ 'ag-hidden': sortDir !== 'desc' }\"\n class=\"ag-header-icon ag-header-label-icon ag-sort-ascending-icon\"\n id=\"HeaderSortAsc_{{ columnDef.colId }}\"\n >\n <span class=\"ag-icon ag-icon-asc\" unselectable=\"on\"></span>\n </span>\n <span\n *ngIf=\"enableSorting && !showFilter\"\n [ngClass]=\"{ 'ag-hidden': sortDir !== 'asc' }\"\n class=\"ag-header-icon ag-header-label-icon ag-sort-descending-icon\"\n id=\"HeaderSortDesc_{{ columnDef.colId }}\"\n >\n <span class=\"ag-icon ag-icon-desc\" unselectable=\"on\"></span>\n </span>\n </div>\n</div>\n", styles: [".ag-header-sort-click-space{display:flex;height:100%;position:relative;width:100%}.ag-header-col-filter-button.ag-filter-applied{opacity:1!important}.Online,.v7Online,.v7Offline{margin-right:.5rem!important;height:.875rem!important;width:.875rem!important}.Online:hover,.v7Online:hover,.v7Offline:hover{border-color:var(--primaryColor)!important;border-style:solid;border-width:var(--inputBorderWidth);height:.625rem!important;width:.625rem!important}.header-text-container{white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis}.text-input-filter{display:flex;flex-direction:row;align-items:center}.text-input-filter .bubble{margin-top:.5rem;margin-left:.0625rem;margin-right:.5rem;width:.875rem;height:.875rem;flex-shrink:0}.ag-header-col-filter-button{margin-top:.5rem}.ag-header-cell-text{margin-top:.125rem;width:100%}.ag-header-cell-label .ag-sort-descending-icon{margin-top:1.25rem!important}.show-input-filter{width:100%}.filterButton{background-image:none}.filterButton .options{position:fixed}\n"], dependencies: [{ kind: "directive", type: i1$4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.ClickOutsideDirective, selector: "[clickOutside]", inputs: ["clickOutsideEnabled", "attachOutsideOnClick", "delayClickOutsideInit", "emitOnBlur", "exclude", "excludeBeforeClick", "clickOutsideEvents"], outputs: ["clickOutside"] }, { kind: "component", type: TableColumnFilterComponent, selector: "app-table-column-filter", inputs: ["type", "filterString", "filterName", "columnDef", "openStatusMenu", "dateFilter"] }] }); }
3519
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ListPageComponent, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable }); }
3520
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ListPageComponent }); }
3498
3521
  }
3499
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TableColumnDefaultComponent, decorators: [{
3500
- type: Component,
3501
- args: [{ selector: 'app-table-column-default', template: "<div\n (click)=\"sort($event)\"\n [ngClass]=\"{ 'nf-can-sort': enableSorting }\"\n class=\"ag-cell-label-container ag-header-cell-sorted-none\"\n id=\"TableHeaderContainer_{{ columnDef.colId }}\"\n>\n <span\n #menuButton\n (click)=\"openGridMenu()\"\n *ngIf=\"false\"\n class=\"ag-header-icon ag-header-cell-menu-button\"\n id=\"HeaderMenu_{{ columnDef.colId }}\"\n ref=\"eMenu\"\n >\n <span class=\"ag-icon ag-icon-menu\" unselectable=\"on\"></span>\n </span>\n <span\n (click)=\"pin()\"\n class=\"ag-header-icon ag-header-col-pin-button\"\n id=\"HeaderPin_{{ columnDef.colId }}\"\n title=\"{{ pinned ? 'Unpin Column' : 'Pin Column' }}\"\n >\n <span class=\"ag-icon ag-icon-pin\"></span>\n </span>\n <span\n (click)=\"hide()\"\n class=\"ag-header-icon ag-header-col-hide-button\"\n id=\"HeaderHide_{{ columnDef.colId }}\"\n title=\"Hide Column\"\n >\n <span class=\"ag-icon ag-icon-eye-slash\"></span>\n </span>\n <div class=\"ag-header-cell-label\" ref=\"eLabel\" unselectable=\"on\">\n <span\n *ngIf=\"!headerParams.filterType\"\n [ngClass]=\"{ 'ag-filter-applied': filterApplied }\"\n class=\"ag-header-icon ag-header-col-filter-button\"\n id=\"HeaderFilterSpacer_{{ columnDef.colId }}\"\n >\n <span class=\"ag-icon ag-icon-filter\" id=\"HeaderFilterSpace_{{ columnDef.colId }}\" style=\"opacity: 0\"></span>\n </span>\n <span\n (click)=\"toggleFilter($event)\"\n *ngIf=\"headerParams.filterType\"\n [ngClass]=\"{ 'ag-filter-applied': filterApplied }\"\n class=\"ag-header-icon ag-header-col-filter-button\"\n id=\"HeaderFilterButton_{{ columnDef.colId }}\"\n >\n <span class=\"ag-icon ag-icon-filter\" id=\"HeaderFilterIcon_{{ columnDef.colId }}\"></span>\n </span>\n <div\n (clickOutside)=\"hideFilter($event)\"\n [ngClass]=\"{ 'show-input-filter': showFilter }\"\n class=\"header-text-container text-input-filter\"\n >\n <span\n (click)=\"toggleSecondaryFilter($event)\"\n *ngIf=\"showBubble\"\n [ngClass]=\"statusClass\"\n class=\"bubble\"\n id=\"HeaderStatus_{{ columnDef.colId }}\"\n >\n <svg *ngIf=\"showLoader\" class=\"circular\" viewBox=\"25 25 50 50\">\n <circle\n class=\"path\"\n cx=\"50\"\n cy=\"50\"\n fill=\"none\"\n r=\"20\"\n stroke-miterlimit=\"10\"\n stroke-width=\"3\"\n ></circle>\n </svg>\n </span>\n <app-table-column-filter\n *ngIf=\"((showFilter || comboActive) && !(filterType === 'COMBO' && !comboActive)) && filterType !== 'SELECT' && filterType !== 'CUSTOM'\"\n [columnDef]=\"columnDef\"\n [filterName]=\"headerName\"\n [filterString]=\"''\"\n [openStatusMenu]=\"toggleSecondaryFilter.bind(this)\"\n [type]=\"filterType\"\n ></app-table-column-filter>\n <span\n *ngIf=\"((!showFilter && !comboActive) || (filterType === 'COMBO' && !comboActive)) || filterType === 'SELECT' || filterType === 'CUSTOM'\"\n [title]=\"headerName\"\n class=\"ag-header-cell-text\"\n id=\"HeaderName_{{ columnDef.colId }}\"\n unselectable=\"on\"\n >{{ headerName }}</span\n >\n </div>\n <span\n *ngIf=\"enableSorting && !showFilter\"\n [ngClass]=\"{ 'ag-hidden': sortDir !== 'desc' }\"\n class=\"ag-header-icon ag-header-label-icon ag-sort-ascending-icon\"\n id=\"HeaderSortAsc_{{ columnDef.colId }}\"\n >\n <span class=\"ag-icon ag-icon-asc\" unselectable=\"on\"></span>\n </span>\n <span\n *ngIf=\"enableSorting && !showFilter\"\n [ngClass]=\"{ 'ag-hidden': sortDir !== 'asc' }\"\n class=\"ag-header-icon ag-header-label-icon ag-sort-descending-icon\"\n id=\"HeaderSortDesc_{{ columnDef.colId }}\"\n >\n <span class=\"ag-icon ag-icon-desc\" unselectable=\"on\"></span>\n </span>\n </div>\n</div>\n", styles: [".ag-header-sort-click-space{display:flex;height:100%;position:relative;width:100%}.ag-header-col-filter-button.ag-filter-applied{opacity:1!important}.Online,.v7Online,.v7Offline{margin-right:.5rem!important;height:.875rem!important;width:.875rem!important}.Online:hover,.v7Online:hover,.v7Offline:hover{border-color:var(--primaryColor)!important;border-style:solid;border-width:var(--inputBorderWidth);height:.625rem!important;width:.625rem!important}.header-text-container{white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis}.text-input-filter{display:flex;flex-direction:row;align-items:center}.text-input-filter .bubble{margin-top:.5rem;margin-left:.0625rem;margin-right:.5rem;width:.875rem;height:.875rem;flex-shrink:0}.ag-header-col-filter-button{margin-top:.5rem}.ag-header-cell-text{margin-top:.125rem;width:100%}.ag-header-cell-label .ag-sort-descending-icon{margin-top:1.25rem!important}.show-input-filter{width:100%}.filterButton{background-image:none}.filterButton .options{position:fixed}\n"] }]
3502
- }], ctorParameters: function () { return [{ type: DataTableFilterService }]; }, propDecorators: { menuButton: [{
3503
- type: ViewChild,
3504
- args: ['menuButton']
3505
- }] } });
3522
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ListPageComponent, decorators: [{
3523
+ type: Injectable
3524
+ }], ctorParameters: function () { return [{ type: DataTableFilterService }, { type: ListPageServiceClass }, { type: ConsoleEventsService }, { type: i5$1.MatDialog }, { type: undefined }]; } });
3506
3525
 
3507
3526
  let Service$1 = class Service {
3508
3527
  constructor() {
@@ -3552,11 +3571,11 @@ class TableCellNameComponent {
3552
3571
  return val;
3553
3572
  }
3554
3573
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TableCellNameComponent, deps: [{ token: i5$1.MatDialog }, { token: i4.Router }], target: i0.ɵɵFactoryTarget.Component }); }
3555
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TableCellNameComponent, selector: "lib-table-cell-name", ngImport: i0, template: "<span class=\"cell-name-container\">\n <a href=\"./{{cellParams.pathRoot}}/{{item.id}}\" (click)=\"linkClicked($event)\">\n <div class=\"col cell-name-renderer\" data-id=\"{{item.id}}\">\n <div *ngIf=\"cellParams.showIdentityIcons\" class=\"cell-status-container\">\n <span class=\"circle {{item.hasApiSession}}\" title=\"Api Session\"></span>\n <span class=\"circle {{item.hasEdgeRouterConnection}}\" title=\"Edge Router Connected\"></span>\n </div>\n <div *ngIf=\"cellParams.showRouterIcons\" class=\"cell-status-container\">\n <span class=\"circle {{item.isVerified}}\" title=\"Api Session\"></span>\n <span class=\"circle {{item.isOnline}}\" title=\"Edge Router Connected\"></span>\n </div>\n <strong>{{cellText}}</strong>\n </div>\n </a>\n</span>\n", styles: [".cell-name-renderer{display:flex;flex-direction:row;gap:.3125rem}.cell-name-container{display:flex;flex-direction:row;flex-wrap:nowrap}.cell-status-container{position:relative;display:flex;align-items:center;justify-content:center;gap:.25rem}\n"], dependencies: [{ kind: "directive", type: i1$4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
3574
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TableCellNameComponent, selector: "lib-table-cell-name", ngImport: i0, template: "<span class=\"cell-name-container\">\n <a href=\"./{{cellParams.pathRoot}}/{{item.id}}\" (click)=\"linkClicked($event)\">\n <div class=\"col cell-name-renderer\" data-id=\"{{item.id}}\">\n <div *ngIf=\"cellParams.showIdentityIcons && item.edgeRouterConnectionStatus\" class=\"cell-status-container\">\n <span class=\"circle {{item.edgeRouterConnectionStatus}}\" title=\"Edge Router Connection Status\"></span>\n </div>\n <div *ngIf=\"cellParams.showIdentityIcons && !item.edgeRouterConnectionStatus\" class=\"cell-status-container\">\n <span class=\"circle {{item.hasApiSession}}\" title=\"Api Session\"></span>\n <span class=\"circle {{item.hasEdgeRouterConnection}}\" title=\"Edge Router Connected\"></span>\n </div>\n <div *ngIf=\"cellParams.showRouterIcons\" class=\"cell-status-container\">\n <span class=\"circle {{item.isVerified}}\" title=\"Api Session\"></span>\n <span class=\"circle {{item.isOnline}}\" title=\"Edge Router Connected\"></span>\n </div>\n <strong>{{cellText}}</strong>\n </div>\n </a>\n</span>\n", styles: [".cell-name-renderer{display:flex;flex-direction:row;gap:.3125rem}.cell-name-container{display:flex;flex-direction:row;flex-wrap:nowrap}.cell-status-container{position:relative;display:flex;align-items:center;justify-content:center;gap:.25rem}.circle.online{background-color:var(--green)}.circle.unknown{background-color:var(--highlighted)}\n"], dependencies: [{ kind: "directive", type: i1$4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
3556
3575
  }
3557
3576
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TableCellNameComponent, decorators: [{
3558
3577
  type: Component,
3559
- args: [{ selector: 'lib-table-cell-name', template: "<span class=\"cell-name-container\">\n <a href=\"./{{cellParams.pathRoot}}/{{item.id}}\" (click)=\"linkClicked($event)\">\n <div class=\"col cell-name-renderer\" data-id=\"{{item.id}}\">\n <div *ngIf=\"cellParams.showIdentityIcons\" class=\"cell-status-container\">\n <span class=\"circle {{item.hasApiSession}}\" title=\"Api Session\"></span>\n <span class=\"circle {{item.hasEdgeRouterConnection}}\" title=\"Edge Router Connected\"></span>\n </div>\n <div *ngIf=\"cellParams.showRouterIcons\" class=\"cell-status-container\">\n <span class=\"circle {{item.isVerified}}\" title=\"Api Session\"></span>\n <span class=\"circle {{item.isOnline}}\" title=\"Edge Router Connected\"></span>\n </div>\n <strong>{{cellText}}</strong>\n </div>\n </a>\n</span>\n", styles: [".cell-name-renderer{display:flex;flex-direction:row;gap:.3125rem}.cell-name-container{display:flex;flex-direction:row;flex-wrap:nowrap}.cell-status-container{position:relative;display:flex;align-items:center;justify-content:center;gap:.25rem}\n"] }]
3578
+ args: [{ selector: 'lib-table-cell-name', template: "<span class=\"cell-name-container\">\n <a href=\"./{{cellParams.pathRoot}}/{{item.id}}\" (click)=\"linkClicked($event)\">\n <div class=\"col cell-name-renderer\" data-id=\"{{item.id}}\">\n <div *ngIf=\"cellParams.showIdentityIcons && item.edgeRouterConnectionStatus\" class=\"cell-status-container\">\n <span class=\"circle {{item.edgeRouterConnectionStatus}}\" title=\"Edge Router Connection Status\"></span>\n </div>\n <div *ngIf=\"cellParams.showIdentityIcons && !item.edgeRouterConnectionStatus\" class=\"cell-status-container\">\n <span class=\"circle {{item.hasApiSession}}\" title=\"Api Session\"></span>\n <span class=\"circle {{item.hasEdgeRouterConnection}}\" title=\"Edge Router Connected\"></span>\n </div>\n <div *ngIf=\"cellParams.showRouterIcons\" class=\"cell-status-container\">\n <span class=\"circle {{item.isVerified}}\" title=\"Api Session\"></span>\n <span class=\"circle {{item.isOnline}}\" title=\"Edge Router Connected\"></span>\n </div>\n <strong>{{cellText}}</strong>\n </div>\n </a>\n</span>\n", styles: [".cell-name-renderer{display:flex;flex-direction:row;gap:.3125rem}.cell-name-container{display:flex;flex-direction:row;flex-wrap:nowrap}.cell-status-container{position:relative;display:flex;align-items:center;justify-content:center;gap:.25rem}.circle.online{background-color:var(--green)}.circle.unknown{background-color:var(--highlighted)}\n"] }]
3560
3579
  }], ctorParameters: function () { return [{ type: i5$1.MatDialog }, { type: i4.Router }]; } });
3561
3580
 
3562
3581
  /*
@@ -4857,7 +4876,8 @@ class ConfigurationsPageService extends ListPageServiceClass {
4857
4876
  valueFormatter: this.createdAtFormatter,
4858
4877
  resizable: true,
4859
4878
  cellClass: 'nf-cell-vert-align tCol',
4860
- }
4879
+ },
4880
+ this.ID_COLUMN_DEF
4861
4881
  ];
4862
4882
  }
4863
4883
  get typeHeaderComponentParams() {
@@ -5874,7 +5894,8 @@ class IdentitiesPageService extends ListPageServiceClass {
5874
5894
  resizable: true,
5875
5895
  cellClass: 'nf-cell-vert-align tCol',
5876
5896
  width: 100,
5877
- }
5897
+ },
5898
+ this.ID_COLUMN_DEF
5878
5899
  ];
5879
5900
  }
5880
5901
  getData(filters, sort, page) {
@@ -6408,7 +6429,8 @@ class EdgeRoutersPageService extends ListPageServiceClass {
6408
6429
  cellRenderer: 'cellTokenComponent',
6409
6430
  resizable: true,
6410
6431
  cellClass: 'nf-cell-vert-align tCol',
6411
- }
6432
+ },
6433
+ this.ID_COLUMN_DEF
6412
6434
  ];
6413
6435
  if (this.extService.processTableColumns) {
6414
6436
  tableColumns = this.extService.processTableColumns(tableColumns);
@@ -11293,7 +11315,8 @@ class TransitRoutersPageService extends ListPageServiceClass {
11293
11315
  cellRenderer: 'cellTokenComponent',
11294
11316
  resizable: true,
11295
11317
  cellClass: 'nf-cell-vert-align tCol',
11296
- }
11318
+ },
11319
+ this.ID_COLUMN_DEF
11297
11320
  ];
11298
11321
  if (this.extService.processTableColumns) {
11299
11322
  tableColumns = this.extService.processTableColumns(tableColumns);
@@ -12151,6 +12174,7 @@ class ServicePolicyFormService {
12151
12174
  return svc.name;
12152
12175
  });
12153
12176
  this.associatedServiceNames = [...this.associatedServiceNames, ...namedAttributes];
12177
+ this.associatedServiceNames = sortBy(this.associatedServices);
12154
12178
  this.associatedServiceNames = sortedUniq(this.associatedServiceNames);
12155
12179
  return this.associatedServices;
12156
12180
  });
@@ -12170,6 +12194,7 @@ class ServicePolicyFormService {
12170
12194
  return svc.name;
12171
12195
  });
12172
12196
  this.associatedIdentityNames = [...this.associatedIdentityNames, ...namedAttributes];
12197
+ this.associatedIdentityNames = sortBy(this.associatedIdentityNames);
12173
12198
  this.associatedIdentityNames = sortedUniq(this.associatedIdentityNames);
12174
12199
  });
12175
12200
  }
@@ -12399,7 +12424,8 @@ class ServicesPageService extends ListPageServiceClass {
12399
12424
  this.serviceType = '';
12400
12425
  this.openAdvanced(data.data.id);
12401
12426
  },
12402
- }
12427
+ },
12428
+ this.ID_COLUMN_DEF
12403
12429
  ];
12404
12430
  }
12405
12431
  getData(filters, sort, page) {
@@ -19131,7 +19157,8 @@ class EdgeRouterPoliciesPageService extends ListPageServiceClass {
19131
19157
  this.openEditForm(data.data.id);
19132
19158
  },
19133
19159
  hide: true
19134
- }
19160
+ },
19161
+ this.ID_COLUMN_DEF
19135
19162
  ];
19136
19163
  }
19137
19164
  getData(filters, sort, page) {
@@ -19673,7 +19700,8 @@ class ServicePoliciesPageService extends ListPageServiceClass {
19673
19700
  this.openEditForm(data.data.id);
19674
19701
  },
19675
19702
  hide: true
19676
- }
19703
+ },
19704
+ this.ID_COLUMN_DEF
19677
19705
  ];
19678
19706
  }
19679
19707
  getData(filters, sort, page) {
@@ -20219,6 +20247,7 @@ class EdgeRouterPolicyFormService {
20219
20247
  return svc.name;
20220
20248
  });
20221
20249
  this.associatedEdgeRouterNames = [...this.associatedEdgeRouterNames, ...namedAttributes];
20250
+ this.associatedEdgeRouterNames = sortBy(this.associatedEdgeRouterNames);
20222
20251
  this.associatedEdgeRouterNames = sortedUniq(this.associatedEdgeRouterNames);
20223
20252
  });
20224
20253
  }
@@ -20237,6 +20266,7 @@ class EdgeRouterPolicyFormService {
20237
20266
  return svc.name;
20238
20267
  });
20239
20268
  this.associatedIdentityNames = [...this.associatedIdentityNames, ...namedAttributes];
20269
+ this.associatedIdentityNames = sortBy(this.associatedIdentityNames);
20240
20270
  this.associatedIdentityNames = sortedUniq(this.associatedIdentityNames);
20241
20271
  });
20242
20272
  }
@@ -20826,7 +20856,8 @@ class ServiceEdgeRouterPoliciesPageService extends ListPageServiceClass {
20826
20856
  this.openEditForm(data.data.id);
20827
20857
  },
20828
20858
  hide: true
20829
- }
20859
+ },
20860
+ this.ID_COLUMN_DEF
20830
20861
  ];
20831
20862
  }
20832
20863
  getData(filters, sort, page) {
@@ -21101,6 +21132,7 @@ class ServiceEdgeRouterPolicyFormService {
21101
21132
  return svc.name;
21102
21133
  });
21103
21134
  this.associatedEdgeRouterNames = [...this.associatedEdgeRouterNames, ...namedAttributes];
21135
+ this.associatedEdgeRouterNames = sortBy(this.associatedEdgeRouterNames);
21104
21136
  this.associatedEdgeRouterNames = sortedUniq(this.associatedEdgeRouterNames);
21105
21137
  });
21106
21138
  }
@@ -21119,6 +21151,7 @@ class ServiceEdgeRouterPolicyFormService {
21119
21151
  return svc.name;
21120
21152
  });
21121
21153
  this.associatedServiceNames = [...this.associatedServiceNames, ...namedAttributes];
21154
+ this.associatedServiceNames = sortBy(this.associatedServiceNames);
21122
21155
  this.associatedServiceNames = sortedUniq(this.associatedServiceNames);
21123
21156
  });
21124
21157
  }
@@ -21615,7 +21648,8 @@ class TerminatorsPageService extends ListPageServiceClass {
21615
21648
  this.openEditForm(data.data.id);
21616
21649
  },
21617
21650
  hide: false
21618
- }
21651
+ },
21652
+ this.ID_COLUMN_DEF
21619
21653
  ];
21620
21654
  }
21621
21655
  getData(filters, sort) {
@@ -22252,7 +22286,8 @@ class JwtSignersPageService extends ListPageServiceClass {
22252
22286
  valueFormatter: this.createdAtFormatter,
22253
22287
  resizable: true,
22254
22288
  cellClass: 'nf-cell-vert-align tCol',
22255
- }
22289
+ },
22290
+ this.ID_COLUMN_DEF
22256
22291
  ];
22257
22292
  }
22258
22293
  getData(filters, sort) {
@@ -23255,7 +23290,8 @@ class AuthPoliciesPageService extends ListPageServiceClass {
23255
23290
  valueFormatter: this.createdAtFormatter,
23256
23291
  resizable: true,
23257
23292
  cellClass: 'nf-cell-vert-align tCol',
23258
- }
23293
+ },
23294
+ this.ID_COLUMN_DEF
23259
23295
  ];
23260
23296
  }
23261
23297
  checkDefaultAuthPolicy(authPolicy) {
@@ -24036,7 +24072,8 @@ class CertificateAuthoritiesPageService extends ListPageServiceClass {
24036
24072
  valueFormatter: this.createdAtFormatter,
24037
24073
  resizable: true,
24038
24074
  cellClass: 'nf-cell-vert-align tCol',
24039
- }
24075
+ },
24076
+ this.ID_COLUMN_DEF
24040
24077
  ];
24041
24078
  }
24042
24079
  getData(filters, sort) {
@@ -25105,7 +25142,8 @@ class ConfigTypesPageService extends ListPageServiceClass {
25105
25142
  resizable: true,
25106
25143
  cellClass: 'nf-cell-vert-align tCol',
25107
25144
  width: this.remToPx(10),
25108
- }
25145
+ },
25146
+ this.ID_COLUMN_DEF
25109
25147
  ];
25110
25148
  }
25111
25149
  getData(filters, sort) {
@@ -25734,7 +25772,8 @@ class PostureChecksPageService extends ListPageServiceClass {
25734
25772
  resizable: true,
25735
25773
  cellClass: 'nf-cell-vert-align tCol',
25736
25774
  width: this.remToPx(10),
25737
- }
25775
+ },
25776
+ this.ID_COLUMN_DEF
25738
25777
  ];
25739
25778
  }
25740
25779
  getData(filters, sort) {
@@ -28058,7 +28097,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
28058
28097
  }] });
28059
28098
 
28060
28099
  const VERSION = {
28061
- "version": "3.12.2"
28100
+ "version": "3.12.4"
28062
28101
  };
28063
28102
 
28064
28103
  /*
@@ -29662,7 +29701,7 @@ class ZitiControllerDataService extends ZitiDataService {
29662
29701
  let filterVal = '';
29663
29702
  switch (filter.type) {
29664
29703
  case 'TEXTINPUT':
29665
- const verb = filter.verb ? filter.verb : 'contains';
29704
+ const verb = filter.verb ? filter.verb : 'icontains';
29666
29705
  filterVal = `${filter.columnId} ${verb} "${filter.value}"`;
29667
29706
  break;
29668
29707
  case 'SELECT':
@@ -29680,7 +29719,7 @@ class ZitiControllerDataService extends ZitiDataService {
29680
29719
  filterVal = `${filter.columnId}=${filter.value}`;
29681
29720
  break;
29682
29721
  default:
29683
- filterVal = `${filter.columnId} contains "${filter.value}"`;
29722
+ filterVal = `${filter.columnId} icontains "${filter.value}"`;
29684
29723
  break;
29685
29724
  }
29686
29725
  if (index <= 0) {