@wolkabout/commons 0.1.10 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -8,6 +8,7 @@ import * as i1$2 from '@angular/router';
|
|
|
8
8
|
import { RouterLink, RouterOutlet, RouterLinkActive, Router, NavigationEnd } from '@angular/router';
|
|
9
9
|
import * as i1$4 from '@angular/material/button';
|
|
10
10
|
import { MatButtonModule } from '@angular/material/button';
|
|
11
|
+
import * as i2$1 from '@angular/material/checkbox';
|
|
11
12
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
|
12
13
|
import { MatToolbarModule } from '@angular/material/toolbar';
|
|
13
14
|
import * as i2 from '@angular/material/form-field';
|
|
@@ -5439,6 +5440,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
|
|
|
5439
5440
|
|
|
5440
5441
|
class NestedListViewComponent {
|
|
5441
5442
|
destroyRef;
|
|
5443
|
+
onKeyDown(event) {
|
|
5444
|
+
if (event.key === 'Shift' && this.enableMultiSelect() && !this.ctrlPressed()) {
|
|
5445
|
+
event.preventDefault();
|
|
5446
|
+
this.shiftPressed.set(true);
|
|
5447
|
+
}
|
|
5448
|
+
if (event.key === 'Control' && this.enableMultiSelect()) {
|
|
5449
|
+
event.preventDefault();
|
|
5450
|
+
this.shiftPressed.set(false);
|
|
5451
|
+
this.ctrlPressed.set(true);
|
|
5452
|
+
}
|
|
5453
|
+
}
|
|
5454
|
+
onKeyUp(event) {
|
|
5455
|
+
if (event.key === 'Shift' && this.enableMultiSelect() && !this.ctrlPressed()) {
|
|
5456
|
+
event.preventDefault();
|
|
5457
|
+
this.shiftPressed.set(false);
|
|
5458
|
+
}
|
|
5459
|
+
if (event.key === 'Control' && this.enableMultiSelect()) {
|
|
5460
|
+
event.preventDefault();
|
|
5461
|
+
this.ctrlPressed.set(false);
|
|
5462
|
+
}
|
|
5463
|
+
}
|
|
5442
5464
|
dataSource = input.required(...(ngDevMode ? [{ debugName: "dataSource" }] : []));
|
|
5443
5465
|
dataControl = input.required(...(ngDevMode ? [{ debugName: "dataControl" }] : []));
|
|
5444
5466
|
width = input('quarter', ...(ngDevMode ? [{ debugName: "width" }] : []));
|
|
@@ -5447,6 +5469,9 @@ class NestedListViewComponent {
|
|
|
5447
5469
|
searchActions = input([], ...(ngDevMode ? [{ debugName: "searchActions" }] : []));
|
|
5448
5470
|
defaultSearchAction = computed(() => this.searchActions().find((action) => !!action.defaultAction), ...(ngDevMode ? [{ debugName: "defaultSearchAction" }] : []));
|
|
5449
5471
|
otherSearchActions = computed(() => this.searchActions().filter((action) => !action.defaultAction), ...(ngDevMode ? [{ debugName: "otherSearchActions" }] : []));
|
|
5472
|
+
enableMultiSelect = input(false, ...(ngDevMode ? [{ debugName: "enableMultiSelect" }] : []));
|
|
5473
|
+
ctrlPressed = signal(false, ...(ngDevMode ? [{ debugName: "ctrlPressed" }] : []));
|
|
5474
|
+
shiftPressed = signal(false, ...(ngDevMode ? [{ debugName: "shiftPressed" }] : []));
|
|
5450
5475
|
widthClass = computed(() => {
|
|
5451
5476
|
switch (this.width()) {
|
|
5452
5477
|
case 'full':
|
|
@@ -5463,6 +5488,7 @@ class NestedListViewComponent {
|
|
|
5463
5488
|
loadingBreadcrumbs = signal(true, ...(ngDevMode ? [{ debugName: "loadingBreadcrumbs" }] : []));
|
|
5464
5489
|
loadingChildren = signal(true, ...(ngDevMode ? [{ debugName: "loadingChildren" }] : []));
|
|
5465
5490
|
selectedItem = signal(null, ...(ngDevMode ? [{ debugName: "selectedItem" }] : []));
|
|
5491
|
+
selectedItems = signal([], ...(ngDevMode ? [{ debugName: "selectedItems" }] : []));
|
|
5466
5492
|
hideSearch = input(false, ...(ngDevMode ? [{ debugName: "hideSearch" }] : []));
|
|
5467
5493
|
nameSearchControl = new FormControl('');
|
|
5468
5494
|
searchTerm = toSignal(this.nameSearchControl.valueChanges.pipe(startWith(this.nameSearchControl.getRawValue())));
|
|
@@ -5482,6 +5508,7 @@ class NestedListViewComponent {
|
|
|
5482
5508
|
return this.children().filter(item => item.name.toLowerCase().includes(searchTerm.toLowerCase()));
|
|
5483
5509
|
}, ...(ngDevMode ? [{ debugName: "filteredChildren" }] : []));
|
|
5484
5510
|
itemSelected = output();
|
|
5511
|
+
itemsSelected = output();
|
|
5485
5512
|
countsMap = signal(new Map(), ...(ngDevMode ? [{ debugName: "countsMap" }] : []));
|
|
5486
5513
|
currentScopes = signal(null, ...(ngDevMode ? [{ debugName: "currentScopes" }] : []));
|
|
5487
5514
|
constructor(destroyRef) {
|
|
@@ -5565,6 +5592,11 @@ class NestedListViewComponent {
|
|
|
5565
5592
|
const isDragging = this.isDragging();
|
|
5566
5593
|
this.dragging.emit(isDragging);
|
|
5567
5594
|
});
|
|
5595
|
+
effect(() => {
|
|
5596
|
+
const searchTerm = this.searchTerm();
|
|
5597
|
+
this.selectedItems.set([]);
|
|
5598
|
+
this.itemsSelected.emit([]);
|
|
5599
|
+
});
|
|
5568
5600
|
}
|
|
5569
5601
|
initiateState(startingItem) {
|
|
5570
5602
|
const dataSource = this.dataSource();
|
|
@@ -5607,6 +5639,8 @@ class NestedListViewComponent {
|
|
|
5607
5639
|
const confirmationAction = this.selectionConfirmationAction();
|
|
5608
5640
|
confirmationAction().pipe(take(1)).subscribe((response) => {
|
|
5609
5641
|
if (response) {
|
|
5642
|
+
this.selectedItems.set([]);
|
|
5643
|
+
this.itemsSelected.emit([]);
|
|
5610
5644
|
if (this.selectedItem()?.id === item?.id) {
|
|
5611
5645
|
return;
|
|
5612
5646
|
}
|
|
@@ -5628,14 +5662,48 @@ class NestedListViewComponent {
|
|
|
5628
5662
|
const confirmationAction = this.selectionConfirmationAction();
|
|
5629
5663
|
confirmationAction().pipe(take(1)).subscribe((response) => {
|
|
5630
5664
|
if (response) {
|
|
5631
|
-
if (this.
|
|
5632
|
-
|
|
5665
|
+
if (this.ctrlPressed()) {
|
|
5666
|
+
const isSelected = this.isChildSelected(item);
|
|
5667
|
+
this.selectedItems.update((previous) => {
|
|
5668
|
+
if (isSelected) {
|
|
5669
|
+
return previous.filter((selected) => selected.id !== item.id);
|
|
5670
|
+
}
|
|
5671
|
+
else {
|
|
5672
|
+
return [...previous, item];
|
|
5673
|
+
}
|
|
5674
|
+
});
|
|
5675
|
+
this.itemsSelected.emit(this.selectedItems().map((item) => item.data));
|
|
5676
|
+
}
|
|
5677
|
+
else if (this.shiftPressed()) {
|
|
5678
|
+
window.getSelection()?.removeAllRanges();
|
|
5679
|
+
if (this.selectedItems().length === 0) {
|
|
5680
|
+
this.selectedItems.set(this.filteredChildren().slice(0, 1));
|
|
5681
|
+
}
|
|
5682
|
+
const firstSelectedItemIndex = this.filteredChildren().findIndex((selectedItem) => this.selectedItems()[0].id === selectedItem.id);
|
|
5683
|
+
const lastSelectedItemIndex = this.filteredChildren().findIndex((selectedItem) => this.selectedItems()[this.selectedItems().length - 1].id === selectedItem.id);
|
|
5684
|
+
const currentSelectionIndex = this.filteredChildren().findIndex((selectedItem) => item.id === selectedItem.id);
|
|
5685
|
+
if (currentSelectionIndex === -1 || firstSelectedItemIndex === -1 || lastSelectedItemIndex === -1) {
|
|
5686
|
+
return;
|
|
5687
|
+
}
|
|
5688
|
+
const startSelectedItemIndex = firstSelectedItemIndex < lastSelectedItemIndex ? firstSelectedItemIndex : lastSelectedItemIndex;
|
|
5689
|
+
const endSelectedItemIndex = firstSelectedItemIndex < lastSelectedItemIndex ? lastSelectedItemIndex : firstSelectedItemIndex;
|
|
5690
|
+
const startIndex = currentSelectionIndex < startSelectedItemIndex ? currentSelectionIndex : startSelectedItemIndex;
|
|
5691
|
+
const endIndex = currentSelectionIndex < endSelectedItemIndex ? endSelectedItemIndex : currentSelectionIndex;
|
|
5692
|
+
this.selectedItems.set(this.filteredChildren().slice(startIndex, endIndex + 1));
|
|
5693
|
+
this.itemsSelected.emit(this.selectedItems().map((item) => item.data));
|
|
5694
|
+
}
|
|
5695
|
+
else {
|
|
5696
|
+
if (this.selectedItem()?.id === item?.id) {
|
|
5697
|
+
return;
|
|
5698
|
+
}
|
|
5699
|
+
this.breadcrumbs.update(breadcrumbs => [...breadcrumbs, item]);
|
|
5700
|
+
this.nameSearchControl.setValue(null);
|
|
5701
|
+
this.selectedItem.set(item);
|
|
5702
|
+
this.selectedItems.set([]);
|
|
5703
|
+
this.itemSelected.emit(item.data);
|
|
5704
|
+
this.itemsSelected.emit([]);
|
|
5705
|
+
this.dataControl().persist(item.id);
|
|
5633
5706
|
}
|
|
5634
|
-
this.breadcrumbs.update(breadcrumbs => [...breadcrumbs, item]);
|
|
5635
|
-
this.nameSearchControl.setValue(null);
|
|
5636
|
-
this.selectedItem.set(item);
|
|
5637
|
-
this.itemSelected.emit(item.data);
|
|
5638
|
-
this.dataControl().persist(item.id);
|
|
5639
5707
|
}
|
|
5640
5708
|
});
|
|
5641
5709
|
}
|
|
@@ -5669,6 +5737,21 @@ class NestedListViewComponent {
|
|
|
5669
5737
|
}
|
|
5670
5738
|
this.countsMap.set(counts);
|
|
5671
5739
|
}
|
|
5740
|
+
toggleSelectAll() {
|
|
5741
|
+
if (this.selectedItems().length < this.filteredChildren().length) {
|
|
5742
|
+
this.selectedItems.set(this.filteredChildren());
|
|
5743
|
+
}
|
|
5744
|
+
else {
|
|
5745
|
+
this.selectedItems.set([]);
|
|
5746
|
+
}
|
|
5747
|
+
this.itemsSelected.emit(this.selectedItems().map((item) => item.data));
|
|
5748
|
+
}
|
|
5749
|
+
isChildSelected(item) {
|
|
5750
|
+
return !!this.selectedItems().find((selected) => selected.id === item.id);
|
|
5751
|
+
}
|
|
5752
|
+
isBreadcrumbSelected(item) {
|
|
5753
|
+
return this.selectedItem()?.id === item.id;
|
|
5754
|
+
}
|
|
5672
5755
|
refreshCount(guid) {
|
|
5673
5756
|
const count = this.countsMap().get(guid);
|
|
5674
5757
|
const rightNumber = count && count > 0 ? count : undefined;
|
|
@@ -5676,12 +5759,18 @@ class NestedListViewComponent {
|
|
|
5676
5759
|
this.children.update(items => items.map(item => item.id === guid ? { ...item, rightNumber } : item));
|
|
5677
5760
|
}
|
|
5678
5761
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: NestedListViewComponent, deps: [{ token: i0.DestroyRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
5679
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: NestedListViewComponent, isStandalone: true, selector: "app-nested-list-view", inputs: { dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: true, transformFunction: null }, dataControl: { classPropertyName: "dataControl", publicName: "dataControl", isSignal: true, isRequired: true, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, disableThresholdId: { classPropertyName: "disableThresholdId", publicName: "disableThresholdId", isSignal: true, isRequired: false, transformFunction: null }, isColoredInput: { classPropertyName: "isColoredInput", publicName: "isColoredInput", isSignal: true, isRequired: false, transformFunction: null }, searchActions: { classPropertyName: "searchActions", publicName: "searchActions", isSignal: true, isRequired: false, transformFunction: null }, selectionConfirmationAction: { classPropertyName: "selectionConfirmationAction", publicName: "selectionConfirmationAction", isSignal: true, isRequired: false, transformFunction: null }, hideSearch: { classPropertyName: "hideSearch", publicName: "hideSearch", isSignal: true, isRequired: false, transformFunction: null }, rootButtonText: { classPropertyName: "rootButtonText", publicName: "rootButtonText", isSignal: true, isRequired: false, transformFunction: null }, enableDrag: { classPropertyName: "enableDrag", publicName: "enableDrag", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dragging: "dragging", itemSelected: "itemSelected" }, ngImport: i0, template: "<div class=\"container flex h-full w-full min-w-full min-h-full relative overflow-hidden\">\r\n <div [ngClass]=\"widthClass()\" class=\"master flex shrink-0 grow-0 min-w-0\">\r\n\r\n <!-- LISTING -->\r\n <div class=\"w-full h-full flex flex-col gap-y-2 relative\" [ngClass]=\"hideSearch() ? 'pt-2' : 'pt-1'\">\r\n\r\n <!-- HEADER -->\r\n <div class=\"flex w-full flex-row gap-x-2\">\r\n\r\n <!-- SEARCH -->\r\n @if (!hideSearch()) {\r\n <div class=\"flex shrink grow flex-row pt-1 gap-x-2 overflow-hidden\">\r\n <mat-form-field class=\"flex grow shrink small-input search-control\" (keydown.enter)=\"defaultSearchAction()?.action({parent: this.selectedItem()?.data, control: this.nameSearchControl})\" [ngClass]=\"{'colored-input': isColoredInput()}\">\r\n <mat-label>{{ 'COMMON.SEARCH_IMMEDIATE_CHILDREN' | translate }}</mat-label>\r\n <input matInput type=\"text\" [formControl]=\"nameSearchControl\">\r\n <mat-icon matSuffix>search</mat-icon>\r\n </mat-form-field>\r\n @if (defaultSearchAction(); as defaultAction) {\r\n <div [matTooltip]=\"defaultAction.disabledTooltip ? (defaultAction.disabledTooltip | translate) : ''\" [matTooltipDisabled]=\"defaultAction.disableCondition ? !defaultAction.disableCondition({control: nameSearchControl}) : true\">\r\n <button mat-mini-fab [disabled]=\"defaultAction.disableCondition ? defaultAction.disableCondition({control: nameSearchControl}) : false\" (click)=\"defaultAction.action({parent: this.selectedItem()?.data, control: this.nameSearchControl})\" [matTooltip]=\"defaultAction.name | translate\">\r\n <mat-icon [svgIcon]=\"defaultAction.icon.id\"/>\r\n </button>\r\n </div>\r\n }\r\n @for (action of otherSearchActions(); track $index) {\r\n @if (action.condition() | async) {\r\n <div [matTooltip]=\"action.disabledTooltip ? (action.disabledTooltip | translate) : ''\" [matTooltipDisabled]=\"action.disableCondition ? !action.disableCondition() : true\">\r\n <button mat-mini-fab [disabled]=\"action.disableCondition ? action.disableCondition() : false\" (click)=\"action.action()\" [matTooltip]=\"action.name | translate\">\r\n <mat-icon [svgIcon]=\"action.icon.id\"/>\r\n </button>\r\n </div>\r\n }\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- LIST -->\r\n <div class=\"flex flex-col w-full h-full relative overflow-hidden\">\r\n\r\n <!-- BREADCRUMBS -->\r\n <div class=\"max-h-[50%] overflow-auto shrink-0\" [overflowClass]=\"'pr-4'\">\r\n @if (!loadingBreadcrumbs()) {\r\n @if (breadcrumbs(); as items) {\r\n <div class=\"flex flex-col w-full overflow-x-hidden\">\r\n @for (item of items; let i = $index; track i) {\r\n @if (selectedItem() && hasMultipleRoots() && i === 0) {\r\n <mat-card (click)=\"resetNavigation()\" class=\"mb-2 cursor-pointer regular-item hover:bg-hover-color\">\r\n <div class=\"px-3 flex flex-row items-center gap-x-2 item-card\">\r\n <div class=\"shrink-0 h-6\">\r\n <mat-icon>arrow_upward</mat-icon>\r\n </div>\r\n <span class=\"text-mat-sys-on-surface\">{{ rootButtonText() | translate: {default: rootButtonText()} }}</span>\r\n </div>\r\n </mat-card>\r\n }\r\n <mat-card class=\"mb-2 cursor-pointer\" (click)=\"selectBreadcrumb(item)\"\r\n [dndDraggable]=\"item.data\" [dndDisableDragIf]=\"!enableDrag() || !!shouldDisableBreadcrumbClick(item)\" (dndStart)=\"dragStart($event, item.data)\" (dndEnd)=\"isDragging.set(false)\"\r\n [ngClass]=\"[selectedItem()?.id === item.id ? 'selected-item' : 'regular-item hover:bg-hover-color', shouldDisableBreadcrumbClick(item) ? 'bg-disabled-color opacity-50 hover:cursor-auto pointer-events-none disabled' : '']\"\r\n [appScrollIntoView]=\"selectedItem()?.id === item.id\" [matTooltip]=\"item.name\" matTooltipPosition=\"right\">\r\n <div class=\"px-3 flex flex-row items-center justify-between gap-x-2 item-card\">\r\n <div class=\"flex flex-row grow items-center gap-x-2 overflow-hidden\">\r\n @if (item.icon; as icon) {\r\n <app-icon [icon]=\"icon\"/>\r\n }\r\n <span [ngClass]=\"[selectedItem()?.id === item.id ? 'text-mat-sys-surface-container' : 'text-mat-sys-on-surface']\" class=\"truncate\">{{ item.name }}</span>\r\n </div>\r\n @if (item.rightNumber && item.rightNumber > 0) {\r\n <span class=\"flex items-center justify-center shrink-0 min-w-5 h-5 px-1.5 rounded-full text-[11px] font-semibold\" [ngClass]=\"selectedItem()?.id === item.id ? 'bg-transparent text-mat-sys-surface-container' : 'bg-mat-sys-primary text-mat-sys-on-primary'\">{{ item.rightNumber }}</span>\r\n } @else if (enableDrag() && !shouldDisableBreadcrumbClick(item)) {\r\n <mat-icon>drag_indicator</mat-icon>\r\n }\r\n </div>\r\n </mat-card>\r\n }\r\n </div>\r\n }\r\n }\r\n </div>\r\n\r\n <mat-divider class=\"w-full pb-2\"/>\r\n\r\n <!-- CHILDREN -->\r\n @if (selectedItem()) {\r\n <div class=\"flex-1 overflow-auto min-h-0\" [overflowClass]=\"'pr-4'\">\r\n @if (!loadingChildren()) {\r\n @if (filteredChildren(); as items) {\r\n @if (items.length) {\r\n <div class=\"flex flex-col w-full overflow-y-auto overflow-x-hidden\">\r\n @for (item of items; track $index) {\r\n <mat-card class=\"mb-2 cursor-pointer regular-item hover:bg-hover-color\" (click)=\"selectChild(item)\" [matTooltip]=\"item.name\" matTooltipPosition=\"right\"\r\n [dndDraggable]=\"item.data\" [dndDisableDragIf]=\"!enableDrag()\" (dndStart)=\"dragStart($event, item.data)\" (dndEnd)=\"isDragging.set(false)\">\r\n <div class=\"px-3 flex flex-row items-center justify-between gap-x-2 item-card\">\r\n <div class=\"flex flex-row grow items-center gap-x-2 overflow-hidden\">\r\n @if (item.icon; as icon) {\r\n <app-icon [icon]=\"icon\"/>\r\n }\r\n <span [ngClass]=\"selectedItem()?.id === item.id ? 'text-mat-sys-surface-container' : 'text-mat-sys-on-surface'\" class=\"truncate\">{{ item.name }}</span>\r\n </div>\r\n @if (item.rightNumber && item.rightNumber > 0) {\r\n <span class=\"flex items-center justify-center shrink-0 min-w-5 h-5 px-1.5 rounded-full text-[11px] font-semibold\" [ngClass]=\"selectedItem()?.id === item.id ? 'bg-transparent text-mat-sys-surface-container' : 'bg-mat-sys-primary text-mat-sys-on-primary'\">{{ item.rightNumber }}</span>\r\n } @else if (enableDrag()) {\r\n <mat-icon>drag_indicator</mat-icon>\r\n }\r\n </div>\r\n </mat-card>\r\n }\r\n </div>\r\n } @else {\r\n <div class=\"flex flex-col grow justify-center items-center\">\r\n <ng-content select=\"[app-no-items-message]\"/>\r\n </div>\r\n }\r\n }\r\n } @else {\r\n <div class=\"flex flex-col grow justify-center items-center\">\r\n <mat-spinner diameter=\"30\"></mat-spinner>\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- ACTIONS (bottom right of the listing) -->\r\n <div class=\"absolute bottom-0 right-0 z-10\">\r\n <ng-content select=\"[app-actions]\"/>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n\r\n @if (width() !== 'full') {\r\n <mat-divider [vertical]=\"true\" class=\"relative top-2\"/>\r\n\r\n <!-- DETAILS -->\r\n <div class=\"details flex shrink grow overflow-hidden pt-2\">\r\n <ng-content select=\"[app-details]\"/>\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{display:block;height:100%;width:100%;overflow:hidden}mat-card,.item-card{height:40px!important}.container{background-color:var(--base-color-50)}.container .master{padding-right:16px}.container .details{padding-left:16px}.selected-item{background:var(--mat-sys-primary);fill:var(--mat-sys-on-primary);color:var(--mat-sys-on-primary)}.regular-item{fill:var(--mat-sys-primary);color:var(--mat-sys-primary)}.regular-item.disabled{color:unset}\n"], dependencies: [{ kind: "ngmodule", type: SharedModule }, { kind: "component", type: i1$4.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i5$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: i1$7.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i4$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i5$2.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { 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.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: ScrollIntoViewDirective, selector: "[appScrollIntoView]", inputs: ["appScrollIntoView"] }, { kind: "directive", type: OverflowClassDirective, selector: "[overflowClass]", inputs: ["overflowClass"] }, { kind: "directive", type: DndDraggableDirective, selector: "[dndDraggable]", inputs: ["dndDraggable", "dndEffectAllowed", "dndType", "dndDraggingClass", "dndDraggingSourceClass", "dndDraggableDisabledClass", "dndDragImageOffsetFunction", "dndDisableIf", "dndDisableDragIf"], outputs: ["dndStart", "dndDrag", "dndEnd", "dndMoved", "dndCopied", "dndLinked", "dndCanceled"] }, { kind: "component", type: IconComponent, selector: "app-icon", inputs: ["icon"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }] });
|
|
5762
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: NestedListViewComponent, isStandalone: true, selector: "app-nested-list-view", inputs: { dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: true, transformFunction: null }, dataControl: { classPropertyName: "dataControl", publicName: "dataControl", isSignal: true, isRequired: true, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, disableThresholdId: { classPropertyName: "disableThresholdId", publicName: "disableThresholdId", isSignal: true, isRequired: false, transformFunction: null }, isColoredInput: { classPropertyName: "isColoredInput", publicName: "isColoredInput", isSignal: true, isRequired: false, transformFunction: null }, searchActions: { classPropertyName: "searchActions", publicName: "searchActions", isSignal: true, isRequired: false, transformFunction: null }, enableMultiSelect: { classPropertyName: "enableMultiSelect", publicName: "enableMultiSelect", isSignal: true, isRequired: false, transformFunction: null }, selectionConfirmationAction: { classPropertyName: "selectionConfirmationAction", publicName: "selectionConfirmationAction", isSignal: true, isRequired: false, transformFunction: null }, hideSearch: { classPropertyName: "hideSearch", publicName: "hideSearch", isSignal: true, isRequired: false, transformFunction: null }, rootButtonText: { classPropertyName: "rootButtonText", publicName: "rootButtonText", isSignal: true, isRequired: false, transformFunction: null }, enableDrag: { classPropertyName: "enableDrag", publicName: "enableDrag", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dragging: "dragging", itemSelected: "itemSelected", itemsSelected: "itemsSelected" }, host: { listeners: { "window:keydown": "onKeyDown($event)", "window:keyup": "onKeyUp($event)" } }, ngImport: i0, template: "<div class=\"container flex h-full w-full min-w-full min-h-full relative overflow-hidden\">\r\n <div [ngClass]=\"widthClass()\" class=\"master flex shrink-0 grow-0 min-w-0\">\r\n\r\n <!-- LISTING -->\r\n <div class=\"w-full h-full flex flex-col gap-y-2 relative\" [ngClass]=\"hideSearch() ? 'pt-2' : 'pt-1'\">\r\n\r\n <!-- HEADER -->\r\n <div class=\"flex w-full flex-row gap-x-2\">\r\n\r\n <!-- SEARCH -->\r\n @if (!hideSearch()) {\r\n <div class=\"flex shrink grow flex-row pt-1 gap-x-2 overflow-hidden\">\r\n <mat-form-field class=\"flex grow shrink small-input search-control\" (keydown.enter)=\"defaultSearchAction()?.action({parent: this.selectedItem()?.data, control: this.nameSearchControl})\" [ngClass]=\"{'colored-input': isColoredInput()}\">\r\n <mat-label>{{ 'COMMON.SEARCH_IMMEDIATE_CHILDREN' | translate }}</mat-label>\r\n <input matInput type=\"text\" [formControl]=\"nameSearchControl\">\r\n <mat-icon matSuffix>search</mat-icon>\r\n </mat-form-field>\r\n @if (defaultSearchAction(); as defaultAction) {\r\n <div [matTooltip]=\"defaultAction.disabledTooltip ? (defaultAction.disabledTooltip | translate) : ''\" [matTooltipDisabled]=\"defaultAction.disableCondition ? !defaultAction.disableCondition({control: nameSearchControl}) : true\">\r\n <button mat-mini-fab [disabled]=\"defaultAction.disableCondition ? defaultAction.disableCondition({control: nameSearchControl}) : false\" (click)=\"defaultAction.action({parent: this.selectedItem()?.data, control: this.nameSearchControl})\" [matTooltip]=\"defaultAction.name | translate\">\r\n <mat-icon [svgIcon]=\"defaultAction.icon.id\"/>\r\n </button>\r\n </div>\r\n }\r\n @for (action of otherSearchActions(); track $index) {\r\n @if (action.condition() | async) {\r\n <div [matTooltip]=\"action.disabledTooltip ? (action.disabledTooltip | translate) : ''\" [matTooltipDisabled]=\"action.disableCondition ? !action.disableCondition() : true\">\r\n <button mat-mini-fab [disabled]=\"action.disableCondition ? action.disableCondition() : false\" (click)=\"action.action()\" [matTooltip]=\"action.name | translate\">\r\n <mat-icon [svgIcon]=\"action.icon.id\"/>\r\n </button>\r\n </div>\r\n }\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- LIST -->\r\n <div class=\"flex flex-col w-full h-full relative overflow-hidden\">\r\n\r\n <!-- BREADCRUMBS -->\r\n <div class=\"max-h-[50%] overflow-auto shrink-0\" [overflowClass]=\"'pr-4'\">\r\n @if (!loadingBreadcrumbs()) {\r\n @if (breadcrumbs(); as items) {\r\n <div class=\"flex flex-col w-full overflow-x-hidden\">\r\n @for (item of items; let i = $index; track i) {\r\n @if (selectedItem() && hasMultipleRoots() && i === 0) {\r\n <mat-card (click)=\"resetNavigation()\" class=\"mb-2 cursor-pointer regular-item hover:bg-hover-color\" [ngClass]=\"disableThresholdId() ? 'bg-disabled-color opacity-50 hover:cursor-auto pointer-events-none disabled' : ''\">\r\n <div class=\"px-3 flex flex-row items-center gap-x-2 item-card\">\r\n <div class=\"shrink-0 h-6\">\r\n <mat-icon>arrow_upward</mat-icon>\r\n </div>\r\n <span class=\"text-mat-sys-on-surface\">{{ rootButtonText() | translate: {default: rootButtonText()} }}</span>\r\n </div>\r\n </mat-card>\r\n }\r\n <mat-card class=\"mb-2 cursor-pointer\" (click)=\"selectBreadcrumb(item)\"\r\n [dndDraggable]=\"item.data\" [dndDisableDragIf]=\"!enableDrag() || !!shouldDisableBreadcrumbClick(item)\" (dndStart)=\"dragStart($event, item.data)\" (dndEnd)=\"isDragging.set(false)\"\r\n [ngClass]=\"[isBreadcrumbSelected(item) ? 'selected-item' : 'regular-item hover:bg-hover-color', selectedItems().length ? 'opacity-50' : '', shouldDisableBreadcrumbClick(item) ? 'bg-disabled-color opacity-50 hover:cursor-auto pointer-events-none disabled' : '']\"\r\n [appScrollIntoView]=\"isBreadcrumbSelected(item)\" [matTooltip]=\"item.name\" matTooltipPosition=\"right\">\r\n <div class=\"px-3 flex flex-row items-center justify-between gap-x-2 item-card\">\r\n <div class=\"flex flex-row grow items-center gap-x-2 overflow-hidden\">\r\n @if (item.icon; as icon) {\r\n <app-icon [icon]=\"icon\"/>\r\n }\r\n <span [ngClass]=\"[isBreadcrumbSelected(item) ? 'text-mat-sys-surface-container' : 'text-mat-sys-on-surface']\" class=\"truncate\">{{ item.name }}</span>\r\n </div>\r\n @if (item.rightNumber && item.rightNumber > 0) {\r\n <span class=\"flex items-center justify-center shrink-0 min-w-5 h-5 px-1.5 rounded-full text-[11px] font-semibold\" [ngClass]=\"isBreadcrumbSelected(item) ? 'bg-transparent text-mat-sys-surface-container' : 'bg-mat-sys-primary text-mat-sys-on-primary'\">{{ item.rightNumber }}</span>\r\n } @else if (enableDrag() && !shouldDisableBreadcrumbClick(item)) {\r\n <mat-icon>drag_indicator</mat-icon>\r\n }\r\n </div>\r\n </mat-card>\r\n }\r\n </div>\r\n }\r\n }\r\n </div>\r\n\r\n <mat-divider class=\"w-full pb-2\"/>\r\n\r\n <!-- CHILDREN -->\r\n @if (selectedItem()) {\r\n <div class=\"flex-1 overflow-auto min-h-0\" [overflowClass]=\"'pr-4'\">\r\n @if (!loadingChildren()) {\r\n @if (filteredChildren(); as items) {\r\n @if (items.length) {\r\n <div class=\"flex flex-col w-full overflow-y-auto overflow-x-hidden\">\r\n @for (item of items; track $index) {\r\n <mat-card class=\"mb-2 cursor-pointer\" [ngClass]=\"[isChildSelected(item) ? 'selected-item' : 'regular-item hover:bg-hover-color', shiftPressed() ? 'no-select-item' : '']\" (click)=\"selectChild(item)\" [matTooltip]=\"item.name\" matTooltipPosition=\"right\"\r\n [dndDraggable]=\"item.data\" [dndDisableDragIf]=\"!enableDrag()\" (dndStart)=\"dragStart($event, item.data)\" (dndEnd)=\"isDragging.set(false)\">\r\n <div class=\"px-3 flex flex-row items-center justify-between gap-x-2 item-card\">\r\n <div class=\"flex flex-row grow items-center gap-x-2 overflow-hidden\">\r\n @if (item.icon; as icon) {\r\n <app-icon [icon]=\"icon\"/>\r\n }\r\n <span [ngClass]=\"isChildSelected(item) ? 'text-mat-sys-surface-container' : 'text-mat-sys-on-surface'\" class=\"truncate\">{{ item.name }}</span>\r\n </div>\r\n @if (item.rightNumber && item.rightNumber > 0) {\r\n <span class=\"flex items-center justify-center shrink-0 min-w-5 h-5 px-1.5 rounded-full text-[11px] font-semibold\" [ngClass]=\"isChildSelected(item) ? 'bg-transparent text-mat-sys-surface-container' : 'bg-mat-sys-primary text-mat-sys-on-primary'\">{{ item.rightNumber }}</span>\r\n } @else if (enableDrag()) {\r\n <mat-icon>drag_indicator</mat-icon>\r\n }\r\n </div>\r\n </mat-card>\r\n }\r\n </div>\r\n } @else {\r\n <div class=\"flex flex-col grow justify-center items-center\">\r\n <ng-content select=\"[app-no-items-message]\"/>\r\n </div>\r\n }\r\n }\r\n } @else {\r\n <div class=\"flex flex-col grow justify-center items-center\">\r\n <mat-spinner diameter=\"30\"></mat-spinner>\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- ACTIONS (bottom right of the listing) -->\r\n <div class=\"absolute bottom-0 right-0 z-10\">\r\n <ng-content select=\"[app-actions]\"/>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n\r\n @if (width() !== 'full') {\r\n <mat-divider [vertical]=\"true\" class=\"relative top-2\"/>\r\n\r\n <!-- DETAILS -->\r\n <div class=\"details flex shrink grow overflow-hidden pt-2\">\r\n @if (!selectedItems().length) {\r\n <ng-content select=\"[app-details]\"/>\r\n } @else {\r\n <div class=\"h-full w-full flex flex-col items-center justify-center relative\">\r\n <div class=\"flex flex-col items-center justify-center\">\r\n <mat-checkbox class=\"w-full\"\r\n [checked]=\"selectedItems().length === filteredChildren().length\"\r\n (change)=\"toggleSelectAll()\">\r\n {{ 'COMMON.SELECT_ALL' | translate }}\r\n </mat-checkbox>\r\n <mat-divider class=\"w-full !mb-2 !mt-2\"></mat-divider>\r\n <span>{{ 'COMMON.NUMBER_OF_ITEMS_SELECTED' | translate: {numberOfItems: selectedItems().length} }} </span>\r\n </div>\r\n <div class=\"absolute bottom-0 right-0\">\r\n <ng-content select=\"[app-bulk-actions]\"/>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{display:block;height:100%;width:100%;overflow:hidden}mat-card,.item-card{height:40px!important}.container{background-color:var(--base-color-50)}.container .master{padding-right:16px}.container .details{padding-left:16px}.selected-item{background:var(--mat-sys-primary);fill:var(--mat-sys-on-primary);color:var(--mat-sys-on-primary)}.regular-item{fill:var(--mat-sys-primary);color:var(--mat-sys-primary)}.regular-item.disabled{color:unset}.no-select-item{user-select:none;-webkit-user-select:none}\n"], dependencies: [{ kind: "ngmodule", type: SharedModule }, { kind: "component", type: i1$4.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i5$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: i1$7.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i4$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i5$2.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { 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.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: ScrollIntoViewDirective, selector: "[appScrollIntoView]", inputs: ["appScrollIntoView"] }, { kind: "directive", type: OverflowClassDirective, selector: "[overflowClass]", inputs: ["overflowClass"] }, { kind: "directive", type: DndDraggableDirective, selector: "[dndDraggable]", inputs: ["dndDraggable", "dndEffectAllowed", "dndType", "dndDraggingClass", "dndDraggingSourceClass", "dndDraggableDisabledClass", "dndDragImageOffsetFunction", "dndDisableIf", "dndDisableDragIf"], outputs: ["dndStart", "dndDrag", "dndEnd", "dndMoved", "dndCopied", "dndLinked", "dndCanceled"] }, { kind: "component", type: IconComponent, selector: "app-icon", inputs: ["icon"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }] });
|
|
5680
5763
|
}
|
|
5681
5764
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: NestedListViewComponent, decorators: [{
|
|
5682
5765
|
type: Component,
|
|
5683
|
-
args: [{ selector: 'app-nested-list-view', imports: [SharedModule, ScrollIntoViewDirective, OverflowClassDirective, DndDraggableDirective, IconComponent], template: "<div class=\"container flex h-full w-full min-w-full min-h-full relative overflow-hidden\">\r\n <div [ngClass]=\"widthClass()\" class=\"master flex shrink-0 grow-0 min-w-0\">\r\n\r\n <!-- LISTING -->\r\n <div class=\"w-full h-full flex flex-col gap-y-2 relative\" [ngClass]=\"hideSearch() ? 'pt-2' : 'pt-1'\">\r\n\r\n <!-- HEADER -->\r\n <div class=\"flex w-full flex-row gap-x-2\">\r\n\r\n <!-- SEARCH -->\r\n @if (!hideSearch()) {\r\n <div class=\"flex shrink grow flex-row pt-1 gap-x-2 overflow-hidden\">\r\n <mat-form-field class=\"flex grow shrink small-input search-control\" (keydown.enter)=\"defaultSearchAction()?.action({parent: this.selectedItem()?.data, control: this.nameSearchControl})\" [ngClass]=\"{'colored-input': isColoredInput()}\">\r\n <mat-label>{{ 'COMMON.SEARCH_IMMEDIATE_CHILDREN' | translate }}</mat-label>\r\n <input matInput type=\"text\" [formControl]=\"nameSearchControl\">\r\n <mat-icon matSuffix>search</mat-icon>\r\n </mat-form-field>\r\n @if (defaultSearchAction(); as defaultAction) {\r\n <div [matTooltip]=\"defaultAction.disabledTooltip ? (defaultAction.disabledTooltip | translate) : ''\" [matTooltipDisabled]=\"defaultAction.disableCondition ? !defaultAction.disableCondition({control: nameSearchControl}) : true\">\r\n <button mat-mini-fab [disabled]=\"defaultAction.disableCondition ? defaultAction.disableCondition({control: nameSearchControl}) : false\" (click)=\"defaultAction.action({parent: this.selectedItem()?.data, control: this.nameSearchControl})\" [matTooltip]=\"defaultAction.name | translate\">\r\n <mat-icon [svgIcon]=\"defaultAction.icon.id\"/>\r\n </button>\r\n </div>\r\n }\r\n @for (action of otherSearchActions(); track $index) {\r\n @if (action.condition() | async) {\r\n <div [matTooltip]=\"action.disabledTooltip ? (action.disabledTooltip | translate) : ''\" [matTooltipDisabled]=\"action.disableCondition ? !action.disableCondition() : true\">\r\n <button mat-mini-fab [disabled]=\"action.disableCondition ? action.disableCondition() : false\" (click)=\"action.action()\" [matTooltip]=\"action.name | translate\">\r\n <mat-icon [svgIcon]=\"action.icon.id\"/>\r\n </button>\r\n </div>\r\n }\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- LIST -->\r\n <div class=\"flex flex-col w-full h-full relative overflow-hidden\">\r\n\r\n <!-- BREADCRUMBS -->\r\n <div class=\"max-h-[50%] overflow-auto shrink-0\" [overflowClass]=\"'pr-4'\">\r\n @if (!loadingBreadcrumbs()) {\r\n @if (breadcrumbs(); as items) {\r\n <div class=\"flex flex-col w-full overflow-x-hidden\">\r\n @for (item of items; let i = $index; track i) {\r\n @if (selectedItem() && hasMultipleRoots() && i === 0) {\r\n <mat-card (click)=\"resetNavigation()\" class=\"mb-2 cursor-pointer regular-item hover:bg-hover-color\">\r\n <div class=\"px-3 flex flex-row items-center gap-x-2 item-card\">\r\n <div class=\"shrink-0 h-6\">\r\n <mat-icon>arrow_upward</mat-icon>\r\n </div>\r\n <span class=\"text-mat-sys-on-surface\">{{ rootButtonText() | translate: {default: rootButtonText()} }}</span>\r\n </div>\r\n </mat-card>\r\n }\r\n <mat-card class=\"mb-2 cursor-pointer\" (click)=\"selectBreadcrumb(item)\"\r\n [dndDraggable]=\"item.data\" [dndDisableDragIf]=\"!enableDrag() || !!shouldDisableBreadcrumbClick(item)\" (dndStart)=\"dragStart($event, item.data)\" (dndEnd)=\"isDragging.set(false)\"\r\n [ngClass]=\"[selectedItem()?.id === item.id ? 'selected-item' : 'regular-item hover:bg-hover-color', shouldDisableBreadcrumbClick(item) ? 'bg-disabled-color opacity-50 hover:cursor-auto pointer-events-none disabled' : '']\"\r\n [appScrollIntoView]=\"selectedItem()?.id === item.id\" [matTooltip]=\"item.name\" matTooltipPosition=\"right\">\r\n <div class=\"px-3 flex flex-row items-center justify-between gap-x-2 item-card\">\r\n <div class=\"flex flex-row grow items-center gap-x-2 overflow-hidden\">\r\n @if (item.icon; as icon) {\r\n <app-icon [icon]=\"icon\"/>\r\n }\r\n <span [ngClass]=\"[selectedItem()?.id === item.id ? 'text-mat-sys-surface-container' : 'text-mat-sys-on-surface']\" class=\"truncate\">{{ item.name }}</span>\r\n </div>\r\n @if (item.rightNumber && item.rightNumber > 0) {\r\n <span class=\"flex items-center justify-center shrink-0 min-w-5 h-5 px-1.5 rounded-full text-[11px] font-semibold\" [ngClass]=\"selectedItem()?.id === item.id ? 'bg-transparent text-mat-sys-surface-container' : 'bg-mat-sys-primary text-mat-sys-on-primary'\">{{ item.rightNumber }}</span>\r\n } @else if (enableDrag() && !shouldDisableBreadcrumbClick(item)) {\r\n <mat-icon>drag_indicator</mat-icon>\r\n }\r\n </div>\r\n </mat-card>\r\n }\r\n </div>\r\n }\r\n }\r\n </div>\r\n\r\n <mat-divider class=\"w-full pb-2\"/>\r\n\r\n <!-- CHILDREN -->\r\n @if (selectedItem()) {\r\n <div class=\"flex-1 overflow-auto min-h-0\" [overflowClass]=\"'pr-4'\">\r\n @if (!loadingChildren()) {\r\n @if (filteredChildren(); as items) {\r\n @if (items.length) {\r\n <div class=\"flex flex-col w-full overflow-y-auto overflow-x-hidden\">\r\n @for (item of items; track $index) {\r\n <mat-card class=\"mb-2 cursor-pointer regular-item hover:bg-hover-color\" (click)=\"selectChild(item)\" [matTooltip]=\"item.name\" matTooltipPosition=\"right\"\r\n [dndDraggable]=\"item.data\" [dndDisableDragIf]=\"!enableDrag()\" (dndStart)=\"dragStart($event, item.data)\" (dndEnd)=\"isDragging.set(false)\">\r\n <div class=\"px-3 flex flex-row items-center justify-between gap-x-2 item-card\">\r\n <div class=\"flex flex-row grow items-center gap-x-2 overflow-hidden\">\r\n @if (item.icon; as icon) {\r\n <app-icon [icon]=\"icon\"/>\r\n }\r\n <span [ngClass]=\"selectedItem()?.id === item.id ? 'text-mat-sys-surface-container' : 'text-mat-sys-on-surface'\" class=\"truncate\">{{ item.name }}</span>\r\n </div>\r\n @if (item.rightNumber && item.rightNumber > 0) {\r\n <span class=\"flex items-center justify-center shrink-0 min-w-5 h-5 px-1.5 rounded-full text-[11px] font-semibold\" [ngClass]=\"selectedItem()?.id === item.id ? 'bg-transparent text-mat-sys-surface-container' : 'bg-mat-sys-primary text-mat-sys-on-primary'\">{{ item.rightNumber }}</span>\r\n } @else if (enableDrag()) {\r\n <mat-icon>drag_indicator</mat-icon>\r\n }\r\n </div>\r\n </mat-card>\r\n }\r\n </div>\r\n } @else {\r\n <div class=\"flex flex-col grow justify-center items-center\">\r\n <ng-content select=\"[app-no-items-message]\"/>\r\n </div>\r\n }\r\n }\r\n } @else {\r\n <div class=\"flex flex-col grow justify-center items-center\">\r\n <mat-spinner diameter=\"30\"></mat-spinner>\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- ACTIONS (bottom right of the listing) -->\r\n <div class=\"absolute bottom-0 right-0 z-10\">\r\n <ng-content select=\"[app-actions]\"/>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n\r\n @if (width() !== 'full') {\r\n <mat-divider [vertical]=\"true\" class=\"relative top-2\"/>\r\n\r\n <!-- DETAILS -->\r\n <div class=\"details flex shrink grow overflow-hidden pt-2\">\r\n <ng-content select=\"[app-details]\"/>\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{display:block;height:100%;width:100%;overflow:hidden}mat-card,.item-card{height:40px!important}.container{background-color:var(--base-color-50)}.container .master{padding-right:16px}.container .details{padding-left:16px}.selected-item{background:var(--mat-sys-primary);fill:var(--mat-sys-on-primary);color:var(--mat-sys-on-primary)}.regular-item{fill:var(--mat-sys-primary);color:var(--mat-sys-primary)}.regular-item.disabled{color:unset}\n"] }]
|
|
5684
|
-
}], ctorParameters: () => [{ type: i0.DestroyRef }], propDecorators: {
|
|
5766
|
+
args: [{ selector: 'app-nested-list-view', imports: [SharedModule, ScrollIntoViewDirective, OverflowClassDirective, DndDraggableDirective, IconComponent], template: "<div class=\"container flex h-full w-full min-w-full min-h-full relative overflow-hidden\">\r\n <div [ngClass]=\"widthClass()\" class=\"master flex shrink-0 grow-0 min-w-0\">\r\n\r\n <!-- LISTING -->\r\n <div class=\"w-full h-full flex flex-col gap-y-2 relative\" [ngClass]=\"hideSearch() ? 'pt-2' : 'pt-1'\">\r\n\r\n <!-- HEADER -->\r\n <div class=\"flex w-full flex-row gap-x-2\">\r\n\r\n <!-- SEARCH -->\r\n @if (!hideSearch()) {\r\n <div class=\"flex shrink grow flex-row pt-1 gap-x-2 overflow-hidden\">\r\n <mat-form-field class=\"flex grow shrink small-input search-control\" (keydown.enter)=\"defaultSearchAction()?.action({parent: this.selectedItem()?.data, control: this.nameSearchControl})\" [ngClass]=\"{'colored-input': isColoredInput()}\">\r\n <mat-label>{{ 'COMMON.SEARCH_IMMEDIATE_CHILDREN' | translate }}</mat-label>\r\n <input matInput type=\"text\" [formControl]=\"nameSearchControl\">\r\n <mat-icon matSuffix>search</mat-icon>\r\n </mat-form-field>\r\n @if (defaultSearchAction(); as defaultAction) {\r\n <div [matTooltip]=\"defaultAction.disabledTooltip ? (defaultAction.disabledTooltip | translate) : ''\" [matTooltipDisabled]=\"defaultAction.disableCondition ? !defaultAction.disableCondition({control: nameSearchControl}) : true\">\r\n <button mat-mini-fab [disabled]=\"defaultAction.disableCondition ? defaultAction.disableCondition({control: nameSearchControl}) : false\" (click)=\"defaultAction.action({parent: this.selectedItem()?.data, control: this.nameSearchControl})\" [matTooltip]=\"defaultAction.name | translate\">\r\n <mat-icon [svgIcon]=\"defaultAction.icon.id\"/>\r\n </button>\r\n </div>\r\n }\r\n @for (action of otherSearchActions(); track $index) {\r\n @if (action.condition() | async) {\r\n <div [matTooltip]=\"action.disabledTooltip ? (action.disabledTooltip | translate) : ''\" [matTooltipDisabled]=\"action.disableCondition ? !action.disableCondition() : true\">\r\n <button mat-mini-fab [disabled]=\"action.disableCondition ? action.disableCondition() : false\" (click)=\"action.action()\" [matTooltip]=\"action.name | translate\">\r\n <mat-icon [svgIcon]=\"action.icon.id\"/>\r\n </button>\r\n </div>\r\n }\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- LIST -->\r\n <div class=\"flex flex-col w-full h-full relative overflow-hidden\">\r\n\r\n <!-- BREADCRUMBS -->\r\n <div class=\"max-h-[50%] overflow-auto shrink-0\" [overflowClass]=\"'pr-4'\">\r\n @if (!loadingBreadcrumbs()) {\r\n @if (breadcrumbs(); as items) {\r\n <div class=\"flex flex-col w-full overflow-x-hidden\">\r\n @for (item of items; let i = $index; track i) {\r\n @if (selectedItem() && hasMultipleRoots() && i === 0) {\r\n <mat-card (click)=\"resetNavigation()\" class=\"mb-2 cursor-pointer regular-item hover:bg-hover-color\" [ngClass]=\"disableThresholdId() ? 'bg-disabled-color opacity-50 hover:cursor-auto pointer-events-none disabled' : ''\">\r\n <div class=\"px-3 flex flex-row items-center gap-x-2 item-card\">\r\n <div class=\"shrink-0 h-6\">\r\n <mat-icon>arrow_upward</mat-icon>\r\n </div>\r\n <span class=\"text-mat-sys-on-surface\">{{ rootButtonText() | translate: {default: rootButtonText()} }}</span>\r\n </div>\r\n </mat-card>\r\n }\r\n <mat-card class=\"mb-2 cursor-pointer\" (click)=\"selectBreadcrumb(item)\"\r\n [dndDraggable]=\"item.data\" [dndDisableDragIf]=\"!enableDrag() || !!shouldDisableBreadcrumbClick(item)\" (dndStart)=\"dragStart($event, item.data)\" (dndEnd)=\"isDragging.set(false)\"\r\n [ngClass]=\"[isBreadcrumbSelected(item) ? 'selected-item' : 'regular-item hover:bg-hover-color', selectedItems().length ? 'opacity-50' : '', shouldDisableBreadcrumbClick(item) ? 'bg-disabled-color opacity-50 hover:cursor-auto pointer-events-none disabled' : '']\"\r\n [appScrollIntoView]=\"isBreadcrumbSelected(item)\" [matTooltip]=\"item.name\" matTooltipPosition=\"right\">\r\n <div class=\"px-3 flex flex-row items-center justify-between gap-x-2 item-card\">\r\n <div class=\"flex flex-row grow items-center gap-x-2 overflow-hidden\">\r\n @if (item.icon; as icon) {\r\n <app-icon [icon]=\"icon\"/>\r\n }\r\n <span [ngClass]=\"[isBreadcrumbSelected(item) ? 'text-mat-sys-surface-container' : 'text-mat-sys-on-surface']\" class=\"truncate\">{{ item.name }}</span>\r\n </div>\r\n @if (item.rightNumber && item.rightNumber > 0) {\r\n <span class=\"flex items-center justify-center shrink-0 min-w-5 h-5 px-1.5 rounded-full text-[11px] font-semibold\" [ngClass]=\"isBreadcrumbSelected(item) ? 'bg-transparent text-mat-sys-surface-container' : 'bg-mat-sys-primary text-mat-sys-on-primary'\">{{ item.rightNumber }}</span>\r\n } @else if (enableDrag() && !shouldDisableBreadcrumbClick(item)) {\r\n <mat-icon>drag_indicator</mat-icon>\r\n }\r\n </div>\r\n </mat-card>\r\n }\r\n </div>\r\n }\r\n }\r\n </div>\r\n\r\n <mat-divider class=\"w-full pb-2\"/>\r\n\r\n <!-- CHILDREN -->\r\n @if (selectedItem()) {\r\n <div class=\"flex-1 overflow-auto min-h-0\" [overflowClass]=\"'pr-4'\">\r\n @if (!loadingChildren()) {\r\n @if (filteredChildren(); as items) {\r\n @if (items.length) {\r\n <div class=\"flex flex-col w-full overflow-y-auto overflow-x-hidden\">\r\n @for (item of items; track $index) {\r\n <mat-card class=\"mb-2 cursor-pointer\" [ngClass]=\"[isChildSelected(item) ? 'selected-item' : 'regular-item hover:bg-hover-color', shiftPressed() ? 'no-select-item' : '']\" (click)=\"selectChild(item)\" [matTooltip]=\"item.name\" matTooltipPosition=\"right\"\r\n [dndDraggable]=\"item.data\" [dndDisableDragIf]=\"!enableDrag()\" (dndStart)=\"dragStart($event, item.data)\" (dndEnd)=\"isDragging.set(false)\">\r\n <div class=\"px-3 flex flex-row items-center justify-between gap-x-2 item-card\">\r\n <div class=\"flex flex-row grow items-center gap-x-2 overflow-hidden\">\r\n @if (item.icon; as icon) {\r\n <app-icon [icon]=\"icon\"/>\r\n }\r\n <span [ngClass]=\"isChildSelected(item) ? 'text-mat-sys-surface-container' : 'text-mat-sys-on-surface'\" class=\"truncate\">{{ item.name }}</span>\r\n </div>\r\n @if (item.rightNumber && item.rightNumber > 0) {\r\n <span class=\"flex items-center justify-center shrink-0 min-w-5 h-5 px-1.5 rounded-full text-[11px] font-semibold\" [ngClass]=\"isChildSelected(item) ? 'bg-transparent text-mat-sys-surface-container' : 'bg-mat-sys-primary text-mat-sys-on-primary'\">{{ item.rightNumber }}</span>\r\n } @else if (enableDrag()) {\r\n <mat-icon>drag_indicator</mat-icon>\r\n }\r\n </div>\r\n </mat-card>\r\n }\r\n </div>\r\n } @else {\r\n <div class=\"flex flex-col grow justify-center items-center\">\r\n <ng-content select=\"[app-no-items-message]\"/>\r\n </div>\r\n }\r\n }\r\n } @else {\r\n <div class=\"flex flex-col grow justify-center items-center\">\r\n <mat-spinner diameter=\"30\"></mat-spinner>\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- ACTIONS (bottom right of the listing) -->\r\n <div class=\"absolute bottom-0 right-0 z-10\">\r\n <ng-content select=\"[app-actions]\"/>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n\r\n @if (width() !== 'full') {\r\n <mat-divider [vertical]=\"true\" class=\"relative top-2\"/>\r\n\r\n <!-- DETAILS -->\r\n <div class=\"details flex shrink grow overflow-hidden pt-2\">\r\n @if (!selectedItems().length) {\r\n <ng-content select=\"[app-details]\"/>\r\n } @else {\r\n <div class=\"h-full w-full flex flex-col items-center justify-center relative\">\r\n <div class=\"flex flex-col items-center justify-center\">\r\n <mat-checkbox class=\"w-full\"\r\n [checked]=\"selectedItems().length === filteredChildren().length\"\r\n (change)=\"toggleSelectAll()\">\r\n {{ 'COMMON.SELECT_ALL' | translate }}\r\n </mat-checkbox>\r\n <mat-divider class=\"w-full !mb-2 !mt-2\"></mat-divider>\r\n <span>{{ 'COMMON.NUMBER_OF_ITEMS_SELECTED' | translate: {numberOfItems: selectedItems().length} }} </span>\r\n </div>\r\n <div class=\"absolute bottom-0 right-0\">\r\n <ng-content select=\"[app-bulk-actions]\"/>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{display:block;height:100%;width:100%;overflow:hidden}mat-card,.item-card{height:40px!important}.container{background-color:var(--base-color-50)}.container .master{padding-right:16px}.container .details{padding-left:16px}.selected-item{background:var(--mat-sys-primary);fill:var(--mat-sys-on-primary);color:var(--mat-sys-on-primary)}.regular-item{fill:var(--mat-sys-primary);color:var(--mat-sys-primary)}.regular-item.disabled{color:unset}.no-select-item{user-select:none;-webkit-user-select:none}\n"] }]
|
|
5767
|
+
}], ctorParameters: () => [{ type: i0.DestroyRef }], propDecorators: { onKeyDown: [{
|
|
5768
|
+
type: HostListener,
|
|
5769
|
+
args: ['window:keydown', ['$event']]
|
|
5770
|
+
}], onKeyUp: [{
|
|
5771
|
+
type: HostListener,
|
|
5772
|
+
args: ['window:keyup', ['$event']]
|
|
5773
|
+
}], dataSource: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataSource", required: true }] }], dataControl: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataControl", required: true }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], disableThresholdId: [{ type: i0.Input, args: [{ isSignal: true, alias: "disableThresholdId", required: false }] }], isColoredInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "isColoredInput", required: false }] }], searchActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchActions", required: false }] }], enableMultiSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableMultiSelect", required: false }] }], selectionConfirmationAction: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionConfirmationAction", required: false }] }], hideSearch: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideSearch", required: false }] }], rootButtonText: [{ type: i0.Input, args: [{ isSignal: true, alias: "rootButtonText", required: false }] }], enableDrag: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableDrag", required: false }] }], dragging: [{ type: i0.Output, args: ["dragging"] }], itemSelected: [{ type: i0.Output, args: ["itemSelected"] }], itemsSelected: [{ type: i0.Output, args: ["itemsSelected"] }] } });
|
|
5685
5774
|
|
|
5686
5775
|
class NestedListDataControl {
|
|
5687
5776
|
navigationPersistence = inject(NavigationPersistenceService);
|
|
@@ -5797,13 +5886,37 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
|
|
|
5797
5886
|
}], ctorParameters: () => [{ type: i1$6.DomSanitizer }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }] } });
|
|
5798
5887
|
|
|
5799
5888
|
class StandardListViewComponent {
|
|
5889
|
+
onKeyDown(event) {
|
|
5890
|
+
if (event.key === 'Shift' && this.enableMultiSelect() && !this.ctrlPressed()) {
|
|
5891
|
+
event.preventDefault();
|
|
5892
|
+
this.shiftPressed.set(true);
|
|
5893
|
+
}
|
|
5894
|
+
if (event.key === 'Control' && this.enableMultiSelect()) {
|
|
5895
|
+
event.preventDefault();
|
|
5896
|
+
this.shiftPressed.set(false);
|
|
5897
|
+
this.ctrlPressed.set(true);
|
|
5898
|
+
}
|
|
5899
|
+
}
|
|
5900
|
+
onKeyUp(event) {
|
|
5901
|
+
if (event.key === 'Shift' && this.enableMultiSelect() && !this.ctrlPressed()) {
|
|
5902
|
+
event.preventDefault();
|
|
5903
|
+
this.shiftPressed.set(false);
|
|
5904
|
+
}
|
|
5905
|
+
if (event.key === 'Control' && this.enableMultiSelect()) {
|
|
5906
|
+
event.preventDefault();
|
|
5907
|
+
this.ctrlPressed.set(false);
|
|
5908
|
+
}
|
|
5909
|
+
}
|
|
5800
5910
|
dataSource = input.required(...(ngDevMode ? [{ debugName: "dataSource" }] : []));
|
|
5801
5911
|
dataControl = input.required(...(ngDevMode ? [{ debugName: "dataControl" }] : []));
|
|
5802
5912
|
position = input('outer', ...(ngDevMode ? [{ debugName: "position" }] : []));
|
|
5803
5913
|
isColoredInput = input(false, ...(ngDevMode ? [{ debugName: "isColoredInput" }] : []));
|
|
5914
|
+
enableMultiSelect = input(false, ...(ngDevMode ? [{ debugName: "enableMultiSelect" }] : []));
|
|
5915
|
+
ctrlPressed = signal(false, ...(ngDevMode ? [{ debugName: "ctrlPressed" }] : []));
|
|
5916
|
+
shiftPressed = signal(false, ...(ngDevMode ? [{ debugName: "shiftPressed" }] : []));
|
|
5804
5917
|
loadingData = signal(true, ...(ngDevMode ? [{ debugName: "loadingData" }] : []));
|
|
5805
5918
|
loadingPage = signal(false, ...(ngDevMode ? [{ debugName: "loadingPage" }] : []));
|
|
5806
|
-
|
|
5919
|
+
selectedItems = signal([], ...(ngDevMode ? [{ debugName: "selectedItems" }] : []));
|
|
5807
5920
|
hideSearch = input(false, ...(ngDevMode ? [{ debugName: "hideSearch" }] : []));
|
|
5808
5921
|
hideDetails = input(false, ...(ngDevMode ? [{ debugName: "hideDetails" }] : []));
|
|
5809
5922
|
hidePadding = input(false, ...(ngDevMode ? [{ debugName: "hidePadding" }] : [])); // TODO Remove, but the component should have innate outer padding :(
|
|
@@ -5824,6 +5937,7 @@ class StandardListViewComponent {
|
|
|
5824
5937
|
return this.items().filter(item => item.name.toLowerCase().includes(searchTerm.toLowerCase()));
|
|
5825
5938
|
}, ...(ngDevMode ? [{ debugName: "filteredItems" }] : []));
|
|
5826
5939
|
itemSelected = output();
|
|
5940
|
+
itemsSelected = output();
|
|
5827
5941
|
itemTemplate = contentChild('standardListItemTemplate', ...(ngDevMode ? [{ debugName: "itemTemplate" }] : []));
|
|
5828
5942
|
constructor(destroyRef) {
|
|
5829
5943
|
afterNextRender(() => {
|
|
@@ -5834,7 +5948,7 @@ class StandardListViewComponent {
|
|
|
5834
5948
|
return of([]);
|
|
5835
5949
|
}), takeUntilDestroyed(destroyRef)).subscribe((items) => {
|
|
5836
5950
|
this.loadingData.set(false);
|
|
5837
|
-
this.
|
|
5951
|
+
this.selectedItems.set([]);
|
|
5838
5952
|
this.items.set(items.sort(dataSource.sortingFunction));
|
|
5839
5953
|
if (items.length === 0) {
|
|
5840
5954
|
this.selectEmpty();
|
|
@@ -5842,40 +5956,45 @@ class StandardListViewComponent {
|
|
|
5842
5956
|
}
|
|
5843
5957
|
const initialSelection = dataSource.initialSelection();
|
|
5844
5958
|
if (initialSelection) {
|
|
5845
|
-
this.
|
|
5959
|
+
this.selectItems(items.find(item => item.id === initialSelection) ?? items[0]);
|
|
5846
5960
|
}
|
|
5847
5961
|
else {
|
|
5848
|
-
this.
|
|
5962
|
+
this.selectItems(items[0]);
|
|
5849
5963
|
}
|
|
5850
5964
|
});
|
|
5851
5965
|
dataControl.changeSelection$.pipe(takeUntilDestroyed(destroyRef)).subscribe((id) => {
|
|
5852
5966
|
const items = this.filteredItems();
|
|
5853
5967
|
const newSelection = items.find(item => item.id === id) ?? items[0];
|
|
5854
|
-
this.
|
|
5968
|
+
this.selectItems(newSelection);
|
|
5855
5969
|
});
|
|
5856
5970
|
dataControl.itemAdded$.pipe(map((item) => dataSource.prepareItem(item)), takeUntilDestroyed(destroyRef)).subscribe((item) => {
|
|
5857
5971
|
this.items.set([...this.items(), item].sort(dataSource.sortingFunction));
|
|
5858
|
-
this.
|
|
5972
|
+
this.selectItems(item);
|
|
5859
5973
|
});
|
|
5860
|
-
dataControl.itemRemoved$.pipe(takeUntilDestroyed(destroyRef)).subscribe((
|
|
5974
|
+
dataControl.itemRemoved$.pipe(takeUntilDestroyed(destroyRef)).subscribe((ids) => {
|
|
5861
5975
|
if (this.items().length === 0) {
|
|
5862
5976
|
this.selectEmpty();
|
|
5863
5977
|
return;
|
|
5864
5978
|
}
|
|
5865
|
-
const deletedItemPosition = this.items().
|
|
5866
|
-
this.items.set(this.items().filter(item => item.id
|
|
5979
|
+
const deletedItemPosition = this.items().findIndex((item) => item.id === ids[0]);
|
|
5980
|
+
this.items.set(this.items().filter(item => !ids.includes(item.id)));
|
|
5867
5981
|
if (deletedItemPosition > 0) {
|
|
5868
|
-
this.
|
|
5982
|
+
this.selectItems(this.items()[deletedItemPosition - 1]);
|
|
5869
5983
|
}
|
|
5870
5984
|
else if (deletedItemPosition === 0 && this.items().length > 0) {
|
|
5871
|
-
this.
|
|
5985
|
+
this.selectItems(this.items()[0]);
|
|
5872
5986
|
}
|
|
5873
5987
|
else {
|
|
5874
5988
|
this.selectEmpty();
|
|
5875
5989
|
}
|
|
5876
5990
|
});
|
|
5877
|
-
dataControl.itemUpdated$.pipe(map((item) => dataSource.prepareItem(item)), takeUntilDestroyed(destroyRef)).subscribe((
|
|
5878
|
-
this.items.update(items => items
|
|
5991
|
+
dataControl.itemUpdated$.pipe(map((items) => items.map((item) => dataSource.prepareItem(item))), takeUntilDestroyed(destroyRef)).subscribe((updatedItems) => {
|
|
5992
|
+
this.items.update(items => items
|
|
5993
|
+
.map(item => {
|
|
5994
|
+
const updatedItem = updatedItems.find((newItem) => newItem.id === item.id);
|
|
5995
|
+
return updatedItem ?? item;
|
|
5996
|
+
})
|
|
5997
|
+
.sort(dataSource.sortingFunction));
|
|
5879
5998
|
});
|
|
5880
5999
|
dataControl.itemPartiallyUpdated$.pipe(takeUntilDestroyed(destroyRef)).subscribe((partialUpdate) => {
|
|
5881
6000
|
this.items.update(items => items.map(item => item.id === partialUpdate.id ? dataSource.prepareItem(partialUpdate.update(item.data)) : item).sort(dataSource.sortingFunction));
|
|
@@ -5883,36 +6002,83 @@ class StandardListViewComponent {
|
|
|
5883
6002
|
});
|
|
5884
6003
|
afterRenderEffect(() => {
|
|
5885
6004
|
const items = this.filteredItems();
|
|
5886
|
-
const
|
|
6005
|
+
const selectedItems = this.selectedItems();
|
|
5887
6006
|
if (items.length === 0) {
|
|
5888
|
-
if (!
|
|
6007
|
+
if (!selectedItems.length) {
|
|
5889
6008
|
return;
|
|
5890
6009
|
}
|
|
5891
6010
|
this.selectEmpty();
|
|
5892
6011
|
return;
|
|
5893
6012
|
}
|
|
5894
|
-
if (!
|
|
5895
|
-
this.
|
|
6013
|
+
if (!selectedItems.length) {
|
|
6014
|
+
this.selectItems(items[0]);
|
|
5896
6015
|
}
|
|
5897
|
-
const selectedItemStillVisible = items.find((item) =>
|
|
6016
|
+
const selectedItemStillVisible = items.find((item) => selectedItems.find((selected) => selected.id === item.id));
|
|
5898
6017
|
if (!selectedItemStillVisible) {
|
|
5899
|
-
this.
|
|
6018
|
+
this.selectItems(items[0]);
|
|
5900
6019
|
}
|
|
5901
6020
|
});
|
|
6021
|
+
effect(() => {
|
|
6022
|
+
const searchTerm = this.searchTerm();
|
|
6023
|
+
this.selectedItems.set([]);
|
|
6024
|
+
this.itemsSelected.emit([]);
|
|
6025
|
+
});
|
|
5902
6026
|
}
|
|
5903
|
-
|
|
5904
|
-
|
|
5905
|
-
|
|
6027
|
+
selectItems(item) {
|
|
6028
|
+
const isSelected = this.isSelected(item);
|
|
6029
|
+
if (this.ctrlPressed()) {
|
|
6030
|
+
this.selectedItems.update((previous) => {
|
|
6031
|
+
if (isSelected) {
|
|
6032
|
+
return previous.length > 1 ? previous.filter((selected) => selected.id !== item.id) : previous;
|
|
6033
|
+
}
|
|
6034
|
+
else {
|
|
6035
|
+
return [...previous, item];
|
|
6036
|
+
}
|
|
6037
|
+
});
|
|
6038
|
+
this.itemsSelected.emit(this.selectedItems().map((item) => item.data));
|
|
6039
|
+
}
|
|
6040
|
+
else if (this.shiftPressed()) {
|
|
6041
|
+
window.getSelection()?.removeAllRanges();
|
|
6042
|
+
const firstSelectedItemIndex = this.filteredItems().findIndex((selectedItem) => this.selectedItems()[0].id === selectedItem.id);
|
|
6043
|
+
const lastSelectedItemIndex = this.filteredItems().findIndex((selectedItem) => this.selectedItems()[this.selectedItems().length - 1].id === selectedItem.id);
|
|
6044
|
+
const currentSelectionIndex = this.filteredItems().findIndex((selectedItem) => item.id === selectedItem.id);
|
|
6045
|
+
if (currentSelectionIndex === -1 || firstSelectedItemIndex === -1 || lastSelectedItemIndex === -1) {
|
|
6046
|
+
return;
|
|
6047
|
+
}
|
|
6048
|
+
const startSelectedItemIndex = firstSelectedItemIndex < lastSelectedItemIndex ? firstSelectedItemIndex : lastSelectedItemIndex;
|
|
6049
|
+
const endSelectedItemIndex = firstSelectedItemIndex < lastSelectedItemIndex ? lastSelectedItemIndex : firstSelectedItemIndex;
|
|
6050
|
+
const startIndex = currentSelectionIndex < startSelectedItemIndex ? currentSelectionIndex : startSelectedItemIndex;
|
|
6051
|
+
const endIndex = currentSelectionIndex < endSelectedItemIndex ? endSelectedItemIndex : currentSelectionIndex;
|
|
6052
|
+
this.selectedItems.set(this.filteredItems().slice(startIndex, endIndex + 1));
|
|
6053
|
+
this.itemsSelected.emit(this.selectedItems().map((item) => item.data));
|
|
6054
|
+
}
|
|
6055
|
+
else {
|
|
6056
|
+
if (isSelected && this.selectedItems().length === 1) {
|
|
6057
|
+
return;
|
|
6058
|
+
}
|
|
6059
|
+
this.selectedItems.set([item]);
|
|
6060
|
+
this.itemSelected.emit(item.data);
|
|
6061
|
+
this.itemsSelected.emit([]);
|
|
6062
|
+
this.dataControl().persist(item.id);
|
|
5906
6063
|
}
|
|
5907
|
-
this.selectedItem.set(item);
|
|
5908
|
-
this.itemSelected.emit(item.data);
|
|
5909
|
-
this.dataControl().persist(item.id);
|
|
5910
6064
|
}
|
|
5911
6065
|
selectEmpty() {
|
|
5912
|
-
this.
|
|
6066
|
+
this.selectedItems.set([]);
|
|
5913
6067
|
this.itemSelected.emit(null);
|
|
5914
6068
|
this.dataControl().persist(null);
|
|
5915
6069
|
}
|
|
6070
|
+
isSelected(item) {
|
|
6071
|
+
return !!this.selectedItems().find((selected) => selected.id === item.id);
|
|
6072
|
+
}
|
|
6073
|
+
toggleSelectAll() {
|
|
6074
|
+
if (this.selectedItems().length < this.filteredItems().length) {
|
|
6075
|
+
this.selectedItems.set(this.filteredItems());
|
|
6076
|
+
}
|
|
6077
|
+
else {
|
|
6078
|
+
this.selectedItems.set([]);
|
|
6079
|
+
}
|
|
6080
|
+
this.itemsSelected.emit(this.selectedItems().map((item) => item.data));
|
|
6081
|
+
}
|
|
5916
6082
|
loadMore() {
|
|
5917
6083
|
this.loadingPage.set(true);
|
|
5918
6084
|
this.dataSource().nextPage().pipe(map((data) => data.map((value) => this.dataSource().prepareItem(value))), catchError(() => {
|
|
@@ -5924,12 +6090,18 @@ class StandardListViewComponent {
|
|
|
5924
6090
|
});
|
|
5925
6091
|
}
|
|
5926
6092
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StandardListViewComponent, deps: [{ token: i0.DestroyRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
5927
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: StandardListViewComponent, isStandalone: true, selector: "app-standard-list-view", inputs: { dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: true, transformFunction: null }, dataControl: { classPropertyName: "dataControl", publicName: "dataControl", isSignal: true, isRequired: true, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, isColoredInput: { classPropertyName: "isColoredInput", publicName: "isColoredInput", isSignal: true, isRequired: false, transformFunction: null }, hideSearch: { classPropertyName: "hideSearch", publicName: "hideSearch", isSignal: true, isRequired: false, transformFunction: null }, hideDetails: { classPropertyName: "hideDetails", publicName: "hideDetails", isSignal: true, isRequired: false, transformFunction: null }, hidePadding: { classPropertyName: "hidePadding", publicName: "hidePadding", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemSelected: "itemSelected" }, queries: [{ propertyName: "itemTemplate", first: true, predicate: ["standardListItemTemplate"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"container flex h-full w-full min-w-full min-h-full relative overflow-hidden {{hidePadding() ? 'pt-0' : 'pt-2'}}\">\r\n <div [ngClass]=\"width()\" class=\"master flex shrink-0 grow-0 min-w-0\">\r\n\r\n <!-- LISTING -->\r\n <div class=\"w-full h-full flex flex-col gap-y-2 relative\">\r\n\r\n <!-- SEARCH -->\r\n @if (!hideSearch()) {\r\n <mat-form-field class=\"w-full small-input\" [ngClass]=\"{'colored-input': isColoredInput()}\">\r\n <mat-label>{{ 'COMMON.SEARCH' | translate }}</mat-label>\r\n <input matInput type=\"text\" [formControl]=\"nameSearchControl\">\r\n <mat-icon matSuffix>search</mat-icon>\r\n </mat-form-field>\r\n }\r\n\r\n <!-- LIST -->\r\n <div class=\"flex flex-col w-full h-full relative overflow-hidden\">\r\n @if (!loadingData()) {\r\n @if (filteredItems(); as items) {\r\n @if (items.length) {\r\n <div class=\"flex flex-col w-full grow shrink overflow-y-auto overflow-x-hidden\" [overflowClass]=\"'pr-4'\">\r\n @for (item of items; track $index) {\r\n <ng-container [ngTemplateOutlet]=\"itemTemplate() || defaultTemplate\" [ngTemplateOutletContext]=\"{$implicit: item, selectedItem: selectedItem(), selectItem: selectItem.bind(this)}\"/>\r\n\r\n <!--DEFAULT TEMPLATE-->\r\n <ng-template #defaultTemplate>\r\n <mat-card class=\"mb-2 cursor-pointer\" (click)=\"selectItem(item)\"\r\n [class]=\"selectedItem()?.id === item.id ? 'selected-item' : 'regular-item hover:bg-hover-color'\"\r\n [appScrollIntoView]=\"selectedItem()?.id === item.id\"\r\n [matTooltip]=\"item.name\" matTooltipPosition=\"right\">\r\n <div class=\"px-3 flex flex-row items-center gap-x-2 item-card\">\r\n @if (item.icon; as icon) {\r\n <app-icon [icon]=\"icon\"/>\r\n }\r\n <span [ngClass]=\"selectedItem()?.id === item.id ? 'text-mat-sys-surface-container' : 'text-mat-sys-on-surface'\" class=\"truncate flex-1\">{{ item.name }}</span>\r\n @if (item.rightIcon; as icon) {\r\n <app-icon [icon]=\"icon\"/>\r\n }\r\n </div>\r\n </mat-card>\r\n </ng-template>\r\n }\r\n\r\n <!-- Load more -->\r\n @if (this.dataSource().isPaged && !this.dataSource().isLastPage) {\r\n <mat-card class=\"mb-2 cursor-pointer regular-item hover:bg-hover-color\" (click)=\"loadMore()\">\r\n <div class=\"px-3 flex flex-row justify-center items-center gap-x-2 item-card\">\r\n @if (loadingPage()) {\r\n <mat-spinner diameter=\"30\"></mat-spinner>\r\n } @else {\r\n <span class=\"text-mat-sys-on-surface\">{{ 'COMMON.LOAD_MORE' | translate }}</span>\r\n }\r\n </div>\r\n </mat-card>\r\n }\r\n </div>\r\n } @else {\r\n <div class=\"flex flex-col grow justify-center items-center\">\r\n <ng-content select=\"[app-no-items-message]\"></ng-content>\r\n </div>\r\n }\r\n }\r\n } @else {\r\n <div class=\"flex flex-col grow justify-center items-center\">\r\n <mat-spinner diameter=\"30\"></mat-spinner>\r\n </div>\r\n }\r\n\r\n <!-- ACTIONS (bottom right of the listing) -->\r\n <div class=\"absolute bottom-0 right-0 z-10\">\r\n <ng-content select=\"[app-actions]\"/>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n\r\n @if (!hideDetails()) {\r\n <mat-divider [vertical]=\"true\"/>\r\n\r\n <!-- DETAILS -->\r\n <div class=\"details flex shrink grow overflow-hidden\">\r\n <ng-content select=\"[app-details]\"/>\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{display:block;height:100%;width:100%;overflow:hidden}mat-card,.item-card{height:40px!important}.container{background-color:var(--base-color-50)}.container .master{padding-right:16px}.container .details{padding-left:16px}.selected-item{background:var(--mat-sys-primary);fill:var(--mat-sys-on-primary);color:var(--mat-sys-on-primary)}.regular-item{fill:var(--mat-sys-primary);color:var(--mat-sys-primary)}\n"], dependencies: [{ kind: "ngmodule", type: SharedModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i5$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: i1$7.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i4$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i5$2.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { 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.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: OverflowClassDirective, selector: "[overflowClass]", inputs: ["overflowClass"] }, { kind: "directive", type: ScrollIntoViewDirective, selector: "[appScrollIntoView]", inputs: ["appScrollIntoView"] }, { kind: "component", type: IconComponent, selector: "app-icon", inputs: ["icon"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }] });
|
|
6093
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: StandardListViewComponent, isStandalone: true, selector: "app-standard-list-view", inputs: { dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: true, transformFunction: null }, dataControl: { classPropertyName: "dataControl", publicName: "dataControl", isSignal: true, isRequired: true, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, isColoredInput: { classPropertyName: "isColoredInput", publicName: "isColoredInput", isSignal: true, isRequired: false, transformFunction: null }, enableMultiSelect: { classPropertyName: "enableMultiSelect", publicName: "enableMultiSelect", isSignal: true, isRequired: false, transformFunction: null }, hideSearch: { classPropertyName: "hideSearch", publicName: "hideSearch", isSignal: true, isRequired: false, transformFunction: null }, hideDetails: { classPropertyName: "hideDetails", publicName: "hideDetails", isSignal: true, isRequired: false, transformFunction: null }, hidePadding: { classPropertyName: "hidePadding", publicName: "hidePadding", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemSelected: "itemSelected", itemsSelected: "itemsSelected" }, host: { listeners: { "window:keydown": "onKeyDown($event)", "window:keyup": "onKeyUp($event)" } }, queries: [{ propertyName: "itemTemplate", first: true, predicate: ["standardListItemTemplate"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"container flex h-full w-full min-w-full min-h-full relative overflow-hidden {{hidePadding() ? 'pt-0' : 'pt-2'}}\">\r\n <div [ngClass]=\"width()\" class=\"master flex shrink-0 grow-0 min-w-0\">\r\n\r\n <!-- LISTING -->\r\n <div class=\"w-full h-full flex flex-col gap-y-2 relative\">\r\n\r\n <!-- SEARCH -->\r\n @if (!hideSearch()) {\r\n <mat-form-field class=\"w-full small-input\" [ngClass]=\"{'colored-input': isColoredInput()}\">\r\n <mat-label>{{ 'COMMON.SEARCH' | translate }}</mat-label>\r\n <input matInput type=\"text\" [formControl]=\"nameSearchControl\">\r\n <mat-icon matSuffix>search</mat-icon>\r\n </mat-form-field>\r\n }\r\n\r\n <!-- LIST -->\r\n <div class=\"flex flex-col w-full h-full relative overflow-hidden\">\r\n @if (!loadingData()) {\r\n @if (filteredItems(); as items) {\r\n @if (items.length) {\r\n <div class=\"flex flex-col w-full grow shrink overflow-y-auto overflow-x-hidden\" [overflowClass]=\"'pr-4'\">\r\n @for (item of items; track $index) {\r\n <ng-container [ngTemplateOutlet]=\"itemTemplate() || defaultTemplate\" [ngTemplateOutletContext]=\"{$implicit: item, selectedItems: selectedItems(), selectItems: selectItems.bind(this) , isSelected: isSelected.bind(this)}\"/>\r\n\r\n <!--DEFAULT TEMPLATE-->\r\n <ng-template #defaultTemplate>\r\n <mat-card class=\"mb-2 cursor-pointer\" (click)=\"selectItems(item)\"\r\n [ngClass]=\"[isSelected(item) ? 'selected-item' : 'regular-item hover:bg-hover-color', shiftPressed() ? 'no-select-item' : '']\"\r\n [appScrollIntoView]=\"selectedItems().length ? false : isSelected(item)\"\r\n [matTooltip]=\"item.name\" matTooltipPosition=\"right\">\r\n <div class=\"px-3 flex flex-row items-center gap-x-2 item-card\">\r\n @if (item.icon; as icon) {\r\n <app-icon [icon]=\"icon\"/>\r\n }\r\n <span [ngClass]=\"isSelected(item) ? 'text-mat-sys-surface-container' : 'text-mat-sys-on-surface'\" class=\"truncate flex-1\">{{ item.name }}</span>\r\n @if (item.rightIcon; as icon) {\r\n <app-icon [icon]=\"icon\"/>\r\n }\r\n </div>\r\n </mat-card>\r\n </ng-template>\r\n }\r\n\r\n <!-- Load more -->\r\n @if (this.dataSource().isPaged && !this.dataSource().isLastPage) {\r\n <mat-card class=\"mb-2 cursor-pointer regular-item hover:bg-hover-color\" (click)=\"loadMore()\">\r\n <div class=\"px-3 flex flex-row justify-center items-center gap-x-2 item-card\">\r\n @if (loadingPage()) {\r\n <mat-spinner diameter=\"30\"></mat-spinner>\r\n } @else {\r\n <span class=\"text-mat-sys-on-surface\">{{ 'COMMON.LOAD_MORE' | translate }}</span>\r\n }\r\n </div>\r\n </mat-card>\r\n }\r\n </div>\r\n } @else {\r\n <div class=\"flex flex-col grow justify-center items-center\">\r\n <ng-content select=\"[app-no-items-message]\"></ng-content>\r\n </div>\r\n }\r\n }\r\n } @else {\r\n <div class=\"flex flex-col grow justify-center items-center\">\r\n <mat-spinner diameter=\"30\"></mat-spinner>\r\n </div>\r\n }\r\n\r\n <!-- ACTIONS (bottom right of the listing) -->\r\n <div class=\"absolute bottom-0 right-0 z-10\">\r\n <ng-content select=\"[app-actions]\"/>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n\r\n @if (!hideDetails()) {\r\n <mat-divider [vertical]=\"true\"/>\r\n\r\n <!-- DETAILS -->\r\n <div class=\"details flex shrink grow overflow-hidden\">\r\n @if (selectedItems().length <= 1) {\r\n <ng-content select=\"[app-details]\"/>\r\n } @else {\r\n <div class=\"h-full w-full flex flex-col items-center justify-center relative\">\r\n <div class=\"flex flex-col items-center justify-center\">\r\n <mat-checkbox class=\"w-full\"\r\n [checked]=\"selectedItems().length === filteredItems().length\"\r\n (change)=\"toggleSelectAll()\">\r\n {{ 'COMMON.SELECT_ALL' | translate }}\r\n </mat-checkbox>\r\n <mat-divider class=\"w-full !mb-2 !mt-2\"></mat-divider>\r\n <span>{{ 'COMMON.NUMBER_OF_ITEMS_SELECTED' | translate: {numberOfItems: selectedItems().length} }} </span>\r\n </div>\r\n <div class=\"absolute bottom-0 right-0\">\r\n <ng-content select=\"[app-bulk-actions]\"/>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{display:block;height:100%;width:100%;overflow:hidden}mat-card,.item-card{height:40px!important}.container{background-color:var(--base-color-50)}.container .master{padding-right:16px}.container .details{padding-left:16px}.selected-item{background:var(--mat-sys-primary);fill:var(--mat-sys-on-primary);color:var(--mat-sys-on-primary)}.regular-item{fill:var(--mat-sys-primary);color:var(--mat-sys-primary)}.no-select-item{user-select:none;-webkit-user-select:none}\n"], dependencies: [{ kind: "ngmodule", type: SharedModule }, { kind: "component", type: i2$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i5$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: i1$7.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i4$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i5$2.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { 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.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: OverflowClassDirective, selector: "[overflowClass]", inputs: ["overflowClass"] }, { kind: "directive", type: ScrollIntoViewDirective, selector: "[appScrollIntoView]", inputs: ["appScrollIntoView"] }, { kind: "component", type: IconComponent, selector: "app-icon", inputs: ["icon"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }] });
|
|
5928
6094
|
}
|
|
5929
6095
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StandardListViewComponent, decorators: [{
|
|
5930
6096
|
type: Component,
|
|
5931
|
-
args: [{ selector: 'app-standard-list-view', imports: [SharedModule, OverflowClassDirective, ScrollIntoViewDirective, IconComponent], template: "<div class=\"container flex h-full w-full min-w-full min-h-full relative overflow-hidden {{hidePadding() ? 'pt-0' : 'pt-2'}}\">\r\n <div [ngClass]=\"width()\" class=\"master flex shrink-0 grow-0 min-w-0\">\r\n\r\n <!-- LISTING -->\r\n <div class=\"w-full h-full flex flex-col gap-y-2 relative\">\r\n\r\n <!-- SEARCH -->\r\n @if (!hideSearch()) {\r\n <mat-form-field class=\"w-full small-input\" [ngClass]=\"{'colored-input': isColoredInput()}\">\r\n <mat-label>{{ 'COMMON.SEARCH' | translate }}</mat-label>\r\n <input matInput type=\"text\" [formControl]=\"nameSearchControl\">\r\n <mat-icon matSuffix>search</mat-icon>\r\n </mat-form-field>\r\n }\r\n\r\n <!-- LIST -->\r\n <div class=\"flex flex-col w-full h-full relative overflow-hidden\">\r\n @if (!loadingData()) {\r\n @if (filteredItems(); as items) {\r\n @if (items.length) {\r\n <div class=\"flex flex-col w-full grow shrink overflow-y-auto overflow-x-hidden\" [overflowClass]=\"'pr-4'\">\r\n @for (item of items; track $index) {\r\n <ng-container [ngTemplateOutlet]=\"itemTemplate() || defaultTemplate\" [ngTemplateOutletContext]=\"{$implicit: item,
|
|
5932
|
-
}], ctorParameters: () => [{ type: i0.DestroyRef }], propDecorators: {
|
|
6097
|
+
args: [{ selector: 'app-standard-list-view', imports: [SharedModule, OverflowClassDirective, ScrollIntoViewDirective, IconComponent], template: "<div class=\"container flex h-full w-full min-w-full min-h-full relative overflow-hidden {{hidePadding() ? 'pt-0' : 'pt-2'}}\">\r\n <div [ngClass]=\"width()\" class=\"master flex shrink-0 grow-0 min-w-0\">\r\n\r\n <!-- LISTING -->\r\n <div class=\"w-full h-full flex flex-col gap-y-2 relative\">\r\n\r\n <!-- SEARCH -->\r\n @if (!hideSearch()) {\r\n <mat-form-field class=\"w-full small-input\" [ngClass]=\"{'colored-input': isColoredInput()}\">\r\n <mat-label>{{ 'COMMON.SEARCH' | translate }}</mat-label>\r\n <input matInput type=\"text\" [formControl]=\"nameSearchControl\">\r\n <mat-icon matSuffix>search</mat-icon>\r\n </mat-form-field>\r\n }\r\n\r\n <!-- LIST -->\r\n <div class=\"flex flex-col w-full h-full relative overflow-hidden\">\r\n @if (!loadingData()) {\r\n @if (filteredItems(); as items) {\r\n @if (items.length) {\r\n <div class=\"flex flex-col w-full grow shrink overflow-y-auto overflow-x-hidden\" [overflowClass]=\"'pr-4'\">\r\n @for (item of items; track $index) {\r\n <ng-container [ngTemplateOutlet]=\"itemTemplate() || defaultTemplate\" [ngTemplateOutletContext]=\"{$implicit: item, selectedItems: selectedItems(), selectItems: selectItems.bind(this) , isSelected: isSelected.bind(this)}\"/>\r\n\r\n <!--DEFAULT TEMPLATE-->\r\n <ng-template #defaultTemplate>\r\n <mat-card class=\"mb-2 cursor-pointer\" (click)=\"selectItems(item)\"\r\n [ngClass]=\"[isSelected(item) ? 'selected-item' : 'regular-item hover:bg-hover-color', shiftPressed() ? 'no-select-item' : '']\"\r\n [appScrollIntoView]=\"selectedItems().length ? false : isSelected(item)\"\r\n [matTooltip]=\"item.name\" matTooltipPosition=\"right\">\r\n <div class=\"px-3 flex flex-row items-center gap-x-2 item-card\">\r\n @if (item.icon; as icon) {\r\n <app-icon [icon]=\"icon\"/>\r\n }\r\n <span [ngClass]=\"isSelected(item) ? 'text-mat-sys-surface-container' : 'text-mat-sys-on-surface'\" class=\"truncate flex-1\">{{ item.name }}</span>\r\n @if (item.rightIcon; as icon) {\r\n <app-icon [icon]=\"icon\"/>\r\n }\r\n </div>\r\n </mat-card>\r\n </ng-template>\r\n }\r\n\r\n <!-- Load more -->\r\n @if (this.dataSource().isPaged && !this.dataSource().isLastPage) {\r\n <mat-card class=\"mb-2 cursor-pointer regular-item hover:bg-hover-color\" (click)=\"loadMore()\">\r\n <div class=\"px-3 flex flex-row justify-center items-center gap-x-2 item-card\">\r\n @if (loadingPage()) {\r\n <mat-spinner diameter=\"30\"></mat-spinner>\r\n } @else {\r\n <span class=\"text-mat-sys-on-surface\">{{ 'COMMON.LOAD_MORE' | translate }}</span>\r\n }\r\n </div>\r\n </mat-card>\r\n }\r\n </div>\r\n } @else {\r\n <div class=\"flex flex-col grow justify-center items-center\">\r\n <ng-content select=\"[app-no-items-message]\"></ng-content>\r\n </div>\r\n }\r\n }\r\n } @else {\r\n <div class=\"flex flex-col grow justify-center items-center\">\r\n <mat-spinner diameter=\"30\"></mat-spinner>\r\n </div>\r\n }\r\n\r\n <!-- ACTIONS (bottom right of the listing) -->\r\n <div class=\"absolute bottom-0 right-0 z-10\">\r\n <ng-content select=\"[app-actions]\"/>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n\r\n @if (!hideDetails()) {\r\n <mat-divider [vertical]=\"true\"/>\r\n\r\n <!-- DETAILS -->\r\n <div class=\"details flex shrink grow overflow-hidden\">\r\n @if (selectedItems().length <= 1) {\r\n <ng-content select=\"[app-details]\"/>\r\n } @else {\r\n <div class=\"h-full w-full flex flex-col items-center justify-center relative\">\r\n <div class=\"flex flex-col items-center justify-center\">\r\n <mat-checkbox class=\"w-full\"\r\n [checked]=\"selectedItems().length === filteredItems().length\"\r\n (change)=\"toggleSelectAll()\">\r\n {{ 'COMMON.SELECT_ALL' | translate }}\r\n </mat-checkbox>\r\n <mat-divider class=\"w-full !mb-2 !mt-2\"></mat-divider>\r\n <span>{{ 'COMMON.NUMBER_OF_ITEMS_SELECTED' | translate: {numberOfItems: selectedItems().length} }} </span>\r\n </div>\r\n <div class=\"absolute bottom-0 right-0\">\r\n <ng-content select=\"[app-bulk-actions]\"/>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{display:block;height:100%;width:100%;overflow:hidden}mat-card,.item-card{height:40px!important}.container{background-color:var(--base-color-50)}.container .master{padding-right:16px}.container .details{padding-left:16px}.selected-item{background:var(--mat-sys-primary);fill:var(--mat-sys-on-primary);color:var(--mat-sys-on-primary)}.regular-item{fill:var(--mat-sys-primary);color:var(--mat-sys-primary)}.no-select-item{user-select:none;-webkit-user-select:none}\n"] }]
|
|
6098
|
+
}], ctorParameters: () => [{ type: i0.DestroyRef }], propDecorators: { onKeyDown: [{
|
|
6099
|
+
type: HostListener,
|
|
6100
|
+
args: ['window:keydown', ['$event']]
|
|
6101
|
+
}], onKeyUp: [{
|
|
6102
|
+
type: HostListener,
|
|
6103
|
+
args: ['window:keyup', ['$event']]
|
|
6104
|
+
}], dataSource: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataSource", required: true }] }], dataControl: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataControl", required: true }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], isColoredInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "isColoredInput", required: false }] }], enableMultiSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableMultiSelect", required: false }] }], hideSearch: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideSearch", required: false }] }], hideDetails: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideDetails", required: false }] }], hidePadding: [{ type: i0.Input, args: [{ isSignal: true, alias: "hidePadding", required: false }] }], itemSelected: [{ type: i0.Output, args: ["itemSelected"] }], itemsSelected: [{ type: i0.Output, args: ["itemsSelected"] }], itemTemplate: [{ type: i0.ContentChild, args: ['standardListItemTemplate', { isSignal: true }] }] } });
|
|
5933
6105
|
|
|
5934
6106
|
class StandardListDataControl {
|
|
5935
6107
|
navigationPersistence = inject(NavigationPersistenceService);
|
|
@@ -5944,10 +6116,10 @@ class StandardListDataControl {
|
|
|
5944
6116
|
}
|
|
5945
6117
|
selectItem = (id) => this._changeSelection$.next(id);
|
|
5946
6118
|
deselectItem = () => this._changeSelection$.next(null);
|
|
5947
|
-
updateItem = (item) => this._itemUpdated$.next(item);
|
|
6119
|
+
updateItem = (item) => this._itemUpdated$.next(Array.isArray(item) ? item : [item]);
|
|
5948
6120
|
updateItemPartially = (id, update) => this._itemPartiallyUpdated$.next({ id, update });
|
|
5949
6121
|
addItem = (item) => this._itemAdded$.next(item);
|
|
5950
|
-
removeItem = (id) => this._itemRemoved$.next(id);
|
|
6122
|
+
removeItem = (id) => this._itemRemoved$.next(Array.isArray(id) ? id : [id]);
|
|
5951
6123
|
/**
|
|
5952
6124
|
* Internal event hook. Do not use outside the Standard List Component
|
|
5953
6125
|
*/
|
|
@@ -6185,7 +6357,7 @@ class ValueInputBooleanComponent {
|
|
|
6185
6357
|
effect(() => {
|
|
6186
6358
|
const validators = this.validators() ?? [];
|
|
6187
6359
|
this.formControl.setValidators([...validators]);
|
|
6188
|
-
this.formControl.updateValueAndValidity({ emitEvent:
|
|
6360
|
+
this.formControl.updateValueAndValidity({ emitEvent: true });
|
|
6189
6361
|
});
|
|
6190
6362
|
}
|
|
6191
6363
|
onTouched = () => {
|
|
@@ -6273,7 +6445,7 @@ class ValueInputColorComponent {
|
|
|
6273
6445
|
effect(() => {
|
|
6274
6446
|
const validators = this.validators() ?? [];
|
|
6275
6447
|
this.formControl.setValidators([...validators, this.hexadecimalColorValidator]);
|
|
6276
|
-
this.formControl.updateValueAndValidity({ emitEvent:
|
|
6448
|
+
this.formControl.updateValueAndValidity({ emitEvent: true });
|
|
6277
6449
|
});
|
|
6278
6450
|
}
|
|
6279
6451
|
// ControlValueAccessor methods
|
|
@@ -6376,7 +6548,7 @@ class ValueInputDateComponent {
|
|
|
6376
6548
|
effect(() => {
|
|
6377
6549
|
const validators = this.validators() ?? [];
|
|
6378
6550
|
this.formControl.setValidators([...validators]);
|
|
6379
|
-
this.formControl.updateValueAndValidity({ emitEvent:
|
|
6551
|
+
this.formControl.updateValueAndValidity({ emitEvent: true });
|
|
6380
6552
|
});
|
|
6381
6553
|
}
|
|
6382
6554
|
// Control Value Accessor
|
|
@@ -6463,7 +6635,7 @@ class ValueInputEnumComponent {
|
|
|
6463
6635
|
effect(() => {
|
|
6464
6636
|
const validators = this.validators() ?? [];
|
|
6465
6637
|
this.formControl.setValidators([...validators]);
|
|
6466
|
-
this.formControl.updateValueAndValidity({ emitEvent:
|
|
6638
|
+
this.formControl.updateValueAndValidity({ emitEvent: true });
|
|
6467
6639
|
});
|
|
6468
6640
|
}
|
|
6469
6641
|
// ControlValueAccessor methods
|
|
@@ -6548,7 +6720,7 @@ class ValueInputHexadecimalComponent {
|
|
|
6548
6720
|
effect(() => {
|
|
6549
6721
|
const validators = this.validators() ?? [];
|
|
6550
6722
|
this.formControl.setValidators([...validators, this.hexadecimalValidator]);
|
|
6551
|
-
this.formControl.updateValueAndValidity({ emitEvent:
|
|
6723
|
+
this.formControl.updateValueAndValidity({ emitEvent: true });
|
|
6552
6724
|
});
|
|
6553
6725
|
}
|
|
6554
6726
|
onTouched = () => {
|
|
@@ -6644,7 +6816,7 @@ class ValueInputLinkComponent {
|
|
|
6644
6816
|
effect(() => {
|
|
6645
6817
|
const validators = this.validators() ?? [];
|
|
6646
6818
|
this.formControl.setValidators([...validators, this.linkValidator]);
|
|
6647
|
-
this.formControl.updateValueAndValidity({ emitEvent:
|
|
6819
|
+
this.formControl.updateValueAndValidity({ emitEvent: true });
|
|
6648
6820
|
});
|
|
6649
6821
|
}
|
|
6650
6822
|
// ControlValueAccessor methods
|
|
@@ -6742,8 +6914,8 @@ class ValueInputLocationComponent {
|
|
|
6742
6914
|
const validators = this.validators() ?? [];
|
|
6743
6915
|
this.formGroup.get('latitude')?.setValidators([...validators, Validators.min(-90), Validators.max(90)]);
|
|
6744
6916
|
this.formGroup.get('longitude')?.setValidators([...validators, Validators.min(-180), Validators.max(180)]);
|
|
6745
|
-
this.formGroup.get('latitude')?.updateValueAndValidity({ emitEvent:
|
|
6746
|
-
this.formGroup.get('longitude')?.updateValueAndValidity({ emitEvent:
|
|
6917
|
+
this.formGroup.get('latitude')?.updateValueAndValidity({ emitEvent: true });
|
|
6918
|
+
this.formGroup.get('longitude')?.updateValueAndValidity({ emitEvent: true });
|
|
6747
6919
|
});
|
|
6748
6920
|
}
|
|
6749
6921
|
// ControlValueAccessor methods
|
|
@@ -6849,7 +7021,7 @@ class ValueInputNumericComponent {
|
|
|
6849
7021
|
effect(() => {
|
|
6850
7022
|
const validators = this.validators() ?? [];
|
|
6851
7023
|
this.formControl.setValidators([...validators, this.numberValidator()]);
|
|
6852
|
-
this.formControl.updateValueAndValidity({ emitEvent:
|
|
7024
|
+
this.formControl.updateValueAndValidity({ emitEvent: true });
|
|
6853
7025
|
});
|
|
6854
7026
|
}
|
|
6855
7027
|
validate() {
|
|
@@ -6946,7 +7118,7 @@ class ValueInputStringComponent {
|
|
|
6946
7118
|
effect(() => {
|
|
6947
7119
|
const validators = this.validators() ?? [];
|
|
6948
7120
|
this.formControl.setValidators([...validators]);
|
|
6949
|
-
this.formControl.updateValueAndValidity({ emitEvent:
|
|
7121
|
+
this.formControl.updateValueAndValidity({ emitEvent: true });
|
|
6950
7122
|
});
|
|
6951
7123
|
}
|
|
6952
7124
|
// ControlValueAccessor methods
|
|
@@ -7036,7 +7208,7 @@ class ValueInputVectorComponent {
|
|
|
7036
7208
|
effect(() => {
|
|
7037
7209
|
const validators = this.validators() ?? [];
|
|
7038
7210
|
this.formControl.setValidators([...validators, this.validateOptions]);
|
|
7039
|
-
this.formControl.updateValueAndValidity({ emitEvent:
|
|
7211
|
+
this.formControl.updateValueAndValidity({ emitEvent: true });
|
|
7040
7212
|
});
|
|
7041
7213
|
effect(() => {
|
|
7042
7214
|
const options = this.options();
|
|
@@ -7152,7 +7324,7 @@ class ValueInputDurationComponent {
|
|
|
7152
7324
|
effect(() => {
|
|
7153
7325
|
const validators = this.validators() ?? [];
|
|
7154
7326
|
this.formControl.setValidators([...validators, this.durationValidator]);
|
|
7155
|
-
this.formControl.updateValueAndValidity({ emitEvent:
|
|
7327
|
+
this.formControl.updateValueAndValidity({ emitEvent: true });
|
|
7156
7328
|
});
|
|
7157
7329
|
}
|
|
7158
7330
|
writeValue(value) {
|
|
@@ -7259,6 +7431,7 @@ class ValueInputComponent {
|
|
|
7259
7431
|
const validationConditions = this.validationConditions();
|
|
7260
7432
|
const dataType = this.dataType();
|
|
7261
7433
|
this.setValidators(validationConditions, dataType);
|
|
7434
|
+
this.formControl.updateValueAndValidity();
|
|
7262
7435
|
});
|
|
7263
7436
|
}
|
|
7264
7437
|
validate() {
|
|
@@ -7308,6 +7481,7 @@ class ValueInputComponent {
|
|
|
7308
7481
|
validators.push(Validators.minLength(+validationConditions.minSize));
|
|
7309
7482
|
}
|
|
7310
7483
|
this.validators.set(validators);
|
|
7484
|
+
console.log("formControl in value-input.component", this.formControl);
|
|
7311
7485
|
}
|
|
7312
7486
|
DataType = DataType;
|
|
7313
7487
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ValueInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|