@masterteam/components 0.0.162 → 0.0.164
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/common.css +1 -1
- package/assets/i18n/ar.json +24 -0
- package/assets/i18n/en.json +24 -0
- package/fesm2022/masterteam-components-business-fields.mjs +290 -90
- package/fesm2022/masterteam-components-business-fields.mjs.map +1 -1
- package/fesm2022/masterteam-components-color-picker-field.mjs +11 -3
- package/fesm2022/masterteam-components-color-picker-field.mjs.map +1 -1
- package/fesm2022/masterteam-components-entities.mjs +3 -2
- package/fesm2022/masterteam-components-entities.mjs.map +1 -1
- package/fesm2022/masterteam-components-field-validation.mjs +19 -18
- package/fesm2022/masterteam-components-field-validation.mjs.map +1 -1
- package/fesm2022/masterteam-components-sidebar.mjs +2 -2
- package/fesm2022/masterteam-components-sidebar.mjs.map +1 -1
- package/fesm2022/masterteam-components-table.mjs +1 -11
- package/fesm2022/masterteam-components-table.mjs.map +1 -1
- package/fesm2022/masterteam-components-text-field.mjs +21 -26
- package/fesm2022/masterteam-components-text-field.mjs.map +1 -1
- package/fesm2022/masterteam-components-toast.mjs +28 -23
- package/fesm2022/masterteam-components-toast.mjs.map +1 -1
- package/fesm2022/masterteam-components-topbar.mjs +2 -2
- package/fesm2022/masterteam-components-topbar.mjs.map +1 -1
- package/fesm2022/masterteam-components-user-search-field.mjs +7 -3
- package/fesm2022/masterteam-components-user-search-field.mjs.map +1 -1
- package/fesm2022/masterteam-components.mjs +1 -1
- package/fesm2022/masterteam-components.mjs.map +1 -1
- package/package.json +2 -2
- package/types/masterteam-components-business-fields.d.ts +67 -21
- package/types/masterteam-components-entities.d.ts +1 -0
- package/types/masterteam-components-text-field.d.ts +11 -2
- package/types/masterteam-components-toast.d.ts +1 -0
- package/types/masterteam-components-user-search-field.d.ts +2 -0
- package/types/masterteam-components.d.ts +7 -5
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import * as i1 from '@angular/common';
|
|
2
2
|
import { CommonModule } from '@angular/common';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { input, inject, DestroyRef, signal, computed, ChangeDetectionStrategy, Component, effect, untracked, viewChild, linkedSignal } from '@angular/core';
|
|
4
|
+
import { input, inject, DestroyRef, signal, computed, ChangeDetectionStrategy, Component, effect, untracked, viewChild, linkedSignal, InjectionToken } from '@angular/core';
|
|
5
5
|
import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
|
|
6
6
|
import * as i1$1 from '@angular/forms';
|
|
7
7
|
import { ControlContainer, Validators, NgControl, FormsModule } from '@angular/forms';
|
|
8
|
-
import { startWith, finalize, catchError, of } from 'rxjs';
|
|
8
|
+
import { startWith, finalize, catchError, of, take } from 'rxjs';
|
|
9
9
|
import { Tooltip } from '@masterteam/components/tooltip';
|
|
10
10
|
import { Icon } from '@masterteam/icons';
|
|
11
11
|
import { SelectField } from '@masterteam/components/select-field';
|
|
12
12
|
import { MultiSelectField } from '@masterteam/components/multi-select-field';
|
|
13
13
|
import { FieldValidation } from '@masterteam/components/field-validation';
|
|
14
|
-
import { HttpClient
|
|
14
|
+
import { HttpClient } from '@angular/common/http';
|
|
15
15
|
import * as i2 from '@jsverse/transloco';
|
|
16
16
|
import { TranslocoService, TranslocoModule } from '@jsverse/transloco';
|
|
17
17
|
import { Button } from '@masterteam/components/button';
|
|
@@ -19,7 +19,7 @@ import { NumberField } from '@masterteam/components/number-field';
|
|
|
19
19
|
import { Table } from '@masterteam/components/table';
|
|
20
20
|
import { Skeleton } from 'primeng/skeleton';
|
|
21
21
|
import { Message } from 'primeng/message';
|
|
22
|
-
import {
|
|
22
|
+
import { ModalService } from '@masterteam/components/modal';
|
|
23
23
|
|
|
24
24
|
class LookupMatrixField {
|
|
25
25
|
config = input.required(...(ngDevMode ? [{ debugName: "config" }] : /* istanbul ignore next */ []));
|
|
@@ -352,13 +352,13 @@ class SchemaConnectionField {
|
|
|
352
352
|
this.disabled.set(disabled);
|
|
353
353
|
}
|
|
354
354
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: SchemaConnectionField, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
355
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: SchemaConnectionField, isStandalone: true, selector: "mt-schema-connection-field", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, configuration: { classPropertyName: "configuration", publicName: "configuration", isSignal: true, isRequired: true, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "grid gap-1" }, ngImport: i0, template: "<!-- @if (label()) {\r\n <label\r\n [class.required]=\"ngControl?.control?.hasValidator(requiredValidator)\"\r\n [for]=\"ngControl?.name || label()\"\r\n >\r\n {{ label() }}\r\n </label>\r\n} -->\r\n\r\n<div class=\"flex gap-4 w-full\">\r\n @for (state of sourceLevelStates(); track getSourceId(state.source)) {\r\n <div [style.width]=\"dropdownWidth()\" class=\"min-w-0\">\r\n @if (sourceLevelStates().length >
|
|
355
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: SchemaConnectionField, isStandalone: true, selector: "mt-schema-connection-field", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, configuration: { classPropertyName: "configuration", publicName: "configuration", isSignal: true, isRequired: true, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "grid gap-1" }, ngImport: i0, template: "<!-- @if (label()) {\r\n <label\r\n [class.required]=\"ngControl?.control?.hasValidator(requiredValidator)\"\r\n [for]=\"ngControl?.name || label()\"\r\n >\r\n {{ label() }}\r\n </label>\r\n} -->\r\n\r\n<div class=\"flex gap-4 w-full\">\r\n @for (state of sourceLevelStates(); track getSourceId(state.source)) {\r\n <div [style.width]=\"dropdownWidth()\" class=\"min-w-0\">\r\n @if (sourceLevelStates().length > 0) {\r\n <span class=\"text-sm text-muted-color mb-1 block truncate\">\r\n {{\r\n state.source.name?.en ||\r\n state.source.levelKey ||\r\n state.source.moduleKey\r\n }}\r\n </span>\r\n }\r\n\r\n @if (state.source.allowManyToMany) {\r\n <mt-multi-select-field\r\n [field]=\"false\"\r\n [(ngModel)]=\"selections[getSourceId(state.source)]\"\r\n (ngModelChange)=\"syncValue()\"\r\n [options]=\"state.options\"\r\n optionLabel=\"name\"\r\n optionValue=\"id\"\r\n [placeholder]=\"placeholder() || state.source.name?.en || 'Select...'\"\r\n [readonly]=\"disabled() || readonly()\"\r\n [filter]=\"filter()\"\r\n [showClear]=\"true\"\r\n display=\"chip\"\r\n />\r\n } @else {\r\n <mt-select-field\r\n [field]=\"false\"\r\n [(ngModel)]=\"selections[getSourceId(state.source)]\"\r\n (ngModelChange)=\"syncValue()\"\r\n [options]=\"state.options\"\r\n optionLabel=\"name\"\r\n optionValue=\"id\"\r\n [placeholder]=\"placeholder() || state.source.name?.en || 'Select...'\"\r\n [readonly]=\"disabled() || readonly()\"\r\n [filter]=\"filter()\"\r\n [loading]=\"state.loading\"\r\n [showClear]=\"true\"\r\n />\r\n }\r\n </div>\r\n }\r\n</div>\r\n\r\n<mt-field-validation [control]=\"ngControl?.control\"></mt-field-validation>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "hint", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape", "markCurrentUser"], outputs: ["onChange"] }, { kind: "component", type: MultiSelectField, selector: "mt-multi-select-field", inputs: ["field", "label", "placeholder", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "display", "required", "maxSelectedLabels", "group", "optionGroupLabel", "optionGroupChildren", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: FieldValidation, selector: "mt-field-validation", inputs: ["control", "touched"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
356
356
|
}
|
|
357
357
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: SchemaConnectionField, decorators: [{
|
|
358
358
|
type: Component,
|
|
359
359
|
args: [{ selector: 'mt-schema-connection-field', standalone: true, imports: [FormsModule, SelectField, MultiSelectField, FieldValidation], changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
360
360
|
class: 'grid gap-1',
|
|
361
|
-
}, template: "<!-- @if (label()) {\r\n <label\r\n [class.required]=\"ngControl?.control?.hasValidator(requiredValidator)\"\r\n [for]=\"ngControl?.name || label()\"\r\n >\r\n {{ label() }}\r\n </label>\r\n} -->\r\n\r\n<div class=\"flex gap-4 w-full\">\r\n @for (state of sourceLevelStates(); track getSourceId(state.source)) {\r\n <div [style.width]=\"dropdownWidth()\" class=\"min-w-0\">\r\n @if (sourceLevelStates().length >
|
|
361
|
+
}, template: "<!-- @if (label()) {\r\n <label\r\n [class.required]=\"ngControl?.control?.hasValidator(requiredValidator)\"\r\n [for]=\"ngControl?.name || label()\"\r\n >\r\n {{ label() }}\r\n </label>\r\n} -->\r\n\r\n<div class=\"flex gap-4 w-full\">\r\n @for (state of sourceLevelStates(); track getSourceId(state.source)) {\r\n <div [style.width]=\"dropdownWidth()\" class=\"min-w-0\">\r\n @if (sourceLevelStates().length > 0) {\r\n <span class=\"text-sm text-muted-color mb-1 block truncate\">\r\n {{\r\n state.source.name?.en ||\r\n state.source.levelKey ||\r\n state.source.moduleKey\r\n }}\r\n </span>\r\n }\r\n\r\n @if (state.source.allowManyToMany) {\r\n <mt-multi-select-field\r\n [field]=\"false\"\r\n [(ngModel)]=\"selections[getSourceId(state.source)]\"\r\n (ngModelChange)=\"syncValue()\"\r\n [options]=\"state.options\"\r\n optionLabel=\"name\"\r\n optionValue=\"id\"\r\n [placeholder]=\"placeholder() || state.source.name?.en || 'Select...'\"\r\n [readonly]=\"disabled() || readonly()\"\r\n [filter]=\"filter()\"\r\n [showClear]=\"true\"\r\n display=\"chip\"\r\n />\r\n } @else {\r\n <mt-select-field\r\n [field]=\"false\"\r\n [(ngModel)]=\"selections[getSourceId(state.source)]\"\r\n (ngModelChange)=\"syncValue()\"\r\n [options]=\"state.options\"\r\n optionLabel=\"name\"\r\n optionValue=\"id\"\r\n [placeholder]=\"placeholder() || state.source.name?.en || 'Select...'\"\r\n [readonly]=\"disabled() || readonly()\"\r\n [filter]=\"filter()\"\r\n [loading]=\"state.loading\"\r\n [showClear]=\"true\"\r\n />\r\n }\r\n </div>\r\n }\r\n</div>\r\n\r\n<mt-field-validation [control]=\"ngControl?.control\"></mt-field-validation>\r\n" }]
|
|
362
362
|
}], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "filter", required: false }] }], configuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "configuration", required: true }] }], context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: false }] }] } });
|
|
363
363
|
|
|
364
364
|
const PREDECESSOR_TYPE_BY_TOKEN = {
|
|
@@ -612,72 +612,126 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
|
|
|
612
612
|
}, template: "@if (label()) {\r\n <label\r\n [class.required]=\"ngControl?.control?.hasValidator(requiredValidator)\"\r\n [for]=\"ngControl?.name || label()\"\r\n >\r\n {{ label() }}\r\n </label>\r\n}\r\n\r\n<div class=\"grid gap-3\">\r\n <div class=\"flex items-center justify-end\">\r\n <mt-button\r\n icon=\"general.plus\"\r\n [label]=\"'components.schedulePredecessorField.add' | transloco\"\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n [disabled]=\"disabled() || readonly() || !canAddRow()\"\r\n [tooltip]=\"addTooltip()\"\r\n (onClick)=\"addRow()\"\r\n />\r\n </div>\r\n\r\n <ng-template #predecessorCellTpl let-row>\r\n <mt-select-field\r\n [field]=\"false\"\r\n [options]=\"availableTaskOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"\r\n placeholder() ||\r\n ('components.schedulePredecessorField.selectPredecessor' | transloco)\r\n \"\r\n [filter]=\"true\"\r\n [showClear]=\"true\"\r\n [loading]=\"loading()\"\r\n [readonly]=\"disabled() || readonly()\"\r\n [ngModel]=\"row.predecessorId || undefined\"\r\n (onChange)=\"updateRow(row.key, { predecessorId: $event ?? '' })\"\r\n />\r\n </ng-template>\r\n\r\n <ng-template #typeCellTpl let-row>\r\n <mt-select-field\r\n [field]=\"false\"\r\n [options]=\"typeOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [readonly]=\"disabled() || readonly()\"\r\n [ngModel]=\"row.type\"\r\n (onChange)=\"updateRow(row.key, { type: $event ?? 0 })\"\r\n />\r\n </ng-template>\r\n\r\n <ng-template #lagCellTpl let-row>\r\n <mt-number-field\r\n [field]=\"false\"\r\n [useGrouping]=\"false\"\r\n [placeholder]=\"'components.schedulePredecessorField.lagDays' | transloco\"\r\n [readonly]=\"disabled() || readonly()\"\r\n [ngModel]=\"row.lagDays\"\r\n (ngModelChange)=\"updateRow(row.key, { lagDays: $event ?? 0 })\"\r\n />\r\n </ng-template>\r\n\r\n <mt-table\r\n [data]=\"rows()\"\r\n [columns]=\"columns()\"\r\n [rowActions]=\"rowActions()\"\r\n [pageSize]=\"pageSize()\"\r\n [generalSearch]=\"false\"\r\n [showFilters]=\"false\"\r\n [dataKey]=\"'key'\"\r\n storageKey=\"schedule-predecessor-field-table\"\r\n [loading]=\"loading()\"\r\n >\r\n <ng-template #empty>\r\n <div\r\n class=\"rounded-xl border border-dashed border-surface px-4 py-5 text-sm text-muted-color\"\r\n >\r\n {{ \"components.schedulePredecessorField.empty\" | transloco }}\r\n </div>\r\n </ng-template>\r\n </mt-table>\r\n</div>\r\n\r\n<mt-field-validation [control]=\"ngControl?.control\"></mt-field-validation>\r\n" }]
|
|
613
613
|
}], ctorParameters: () => [], propDecorators: { predecessorCellTpl: [{ type: i0.ViewChild, args: ['predecessorCellTpl', { isSignal: true }] }], typeCellTpl: [{ type: i0.ViewChild, args: ['typeCellTpl', { isSignal: true }] }], lagCellTpl: [{ type: i0.ViewChild, args: ['lagCellTpl', { isSignal: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], configuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "configuration", required: false }] }], runtimeContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "runtimeContext", required: false }] }] } });
|
|
614
614
|
|
|
615
|
+
/**
|
|
616
|
+
* Token used by `mt-entity-list-field` (Write mode) to open the rich add-row
|
|
617
|
+
* dialog backed by `@masterteam/forms`'s `mt-client-form`. Apps that want this
|
|
618
|
+
* behavior should call `provideEntityListAddForm()` from
|
|
619
|
+
* `@masterteam/forms/entity-list-add-form` in their app providers. When the
|
|
620
|
+
* token is not registered, the field falls back to a minimal text-only popup.
|
|
621
|
+
*/
|
|
622
|
+
const ENTITY_LIST_ADD_DIALOG_COMPONENT = new InjectionToken('ENTITY_LIST_ADD_DIALOG_COMPONENT');
|
|
623
|
+
|
|
624
|
+
const UNSORTABLE_ENTITY_VIEW_TYPES = new Set([
|
|
625
|
+
'Attachment',
|
|
626
|
+
'Checkbox',
|
|
627
|
+
]);
|
|
615
628
|
class EntityListField {
|
|
616
629
|
// Inputs
|
|
617
630
|
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
618
631
|
readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
|
|
619
632
|
required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
|
|
620
|
-
/** EntityList property id
|
|
633
|
+
/** EntityList property id (kept for back-compat; unused by fetch/query). */
|
|
621
634
|
propertyId = input(null, ...(ngDevMode ? [{ debugName: "propertyId" }] : /* istanbul ignore next */ []));
|
|
622
|
-
/** Property configuration (sourceType, moduleId, access, etc). */
|
|
635
|
+
/** Property configuration (sourceType, moduleId, access, readFields, etc). */
|
|
623
636
|
configuration = input(null, ...(ngDevMode ? [{ debugName: "configuration" }] : /* istanbul ignore next */ []));
|
|
624
637
|
/** Runtime ids needed to call the read endpoint. */
|
|
625
638
|
runtimeContext = input(null, ...(ngDevMode ? [{ debugName: "runtimeContext" }] : /* istanbul ignore next */ []));
|
|
626
|
-
/** Optional HttpContext (
|
|
639
|
+
/** Optional HttpContext (kept for back-compat). */
|
|
627
640
|
context = input(undefined, ...(ngDevMode ? [{ debugName: "context" }] : /* istanbul ignore next */ []));
|
|
628
641
|
// CVA state — pass-through value (EntityList stored JSON shape).
|
|
629
642
|
storedValue = signal(null, ...(ngDevMode ? [{ debugName: "storedValue" }] : /* istanbul ignore next */ []));
|
|
630
|
-
// Loaded
|
|
643
|
+
// Loaded table state.
|
|
644
|
+
columns = signal([], ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
|
|
631
645
|
rows = signal([], ...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
|
|
632
646
|
loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
633
647
|
errorMessage = signal(null, ...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
|
|
634
648
|
disabled = signal(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
635
649
|
requiredValidator = Validators.required;
|
|
636
650
|
ngControl = null;
|
|
637
|
-
|
|
638
|
-
const
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
const id = typeof raw === 'string' ? Number(raw) : raw;
|
|
643
|
-
return Number.isFinite(id) && id > 0 ? id : null;
|
|
644
|
-
}, ...(ngDevMode ? [{ debugName: "sourceId" }] : /* istanbul ignore next */ []));
|
|
645
|
-
levelDataIdParam = computed(() => {
|
|
651
|
+
levelId = computed(() => {
|
|
652
|
+
const raw = this.runtimeContext()?.levelId ?? null;
|
|
653
|
+
return raw == null || raw === '' ? null : raw;
|
|
654
|
+
}, ...(ngDevMode ? [{ debugName: "levelId" }] : /* istanbul ignore next */ []));
|
|
655
|
+
levelDataId = computed(() => {
|
|
646
656
|
const raw = this.runtimeContext()?.levelDataId ?? null;
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
657
|
+
return raw == null || raw === '' ? null : raw;
|
|
658
|
+
}, ...(ngDevMode ? [{ debugName: "levelDataId" }] : /* istanbul ignore next */ []));
|
|
659
|
+
moduleId = computed(() => {
|
|
660
|
+
const raw = this.configuration()
|
|
661
|
+
?.moduleId;
|
|
662
|
+
return raw == null || raw === '' ? null : raw;
|
|
663
|
+
}, ...(ngDevMode ? [{ debugName: "moduleId" }] : /* istanbul ignore next */ []));
|
|
664
|
+
readFields = computed(() => {
|
|
665
|
+
const raw = this.configuration()
|
|
666
|
+
?.readFields;
|
|
667
|
+
if (!Array.isArray(raw))
|
|
668
|
+
return [];
|
|
669
|
+
return raw.filter((f) => typeof f === 'string' && f.length > 0);
|
|
670
|
+
}, ...(ngDevMode ? [{ debugName: "readFields" }] : /* istanbul ignore next */ []));
|
|
652
671
|
canRead = computed(() => {
|
|
653
672
|
const access = String(this.configuration()?.access ?? 'Auto');
|
|
654
673
|
return access !== 'Write' && access !== 'None';
|
|
655
674
|
}, ...(ngDevMode ? [{ debugName: "canRead" }] : /* istanbul ignore next */ []));
|
|
656
|
-
|
|
675
|
+
canWrite = computed(() => {
|
|
676
|
+
const access = String(this.configuration()?.access ?? 'Auto');
|
|
677
|
+
return access === 'Write';
|
|
678
|
+
}, ...(ngDevMode ? [{ debugName: "canWrite" }] : /* istanbul ignore next */ []));
|
|
679
|
+
writeFields = computed(() => {
|
|
680
|
+
const raw = this.configuration()
|
|
681
|
+
?.writeFields;
|
|
682
|
+
if (!Array.isArray(raw))
|
|
683
|
+
return [];
|
|
684
|
+
return raw.filter((f) => typeof f === 'string' && f.length > 0);
|
|
685
|
+
}, ...(ngDevMode ? [{ debugName: "writeFields" }] : /* istanbul ignore next */ []));
|
|
686
|
+
/** Locally-added rows (Write mode). Persisted via CVA value. */
|
|
687
|
+
localRows = signal([], ...(ngDevMode ? [{ debugName: "localRows" }] : /* istanbul ignore next */ []));
|
|
688
|
+
localRowSeq = 0;
|
|
689
|
+
displayRows = computed(() => this.canWrite() ? this.localRows() : this.rows(), ...(ngDevMode ? [{ debugName: "displayRows" }] : /* istanbul ignore next */ []));
|
|
690
|
+
hasRows = computed(() => this.displayRows().length > 0, ...(ngDevMode ? [{ debugName: "hasRows" }] : /* istanbul ignore next */ []));
|
|
691
|
+
hasRequiredContext = computed(() => this.levelId() != null &&
|
|
692
|
+
this.levelDataId() != null &&
|
|
693
|
+
this.moduleId() != null &&
|
|
694
|
+
this.readFields().length > 0, ...(ngDevMode ? [{ debugName: "hasRequiredContext" }] : /* istanbul ignore next */ []));
|
|
657
695
|
onTouched = () => { };
|
|
658
696
|
onModelChange = () => { };
|
|
659
697
|
http = inject(HttpClient);
|
|
660
698
|
destroyRef = inject(DestroyRef);
|
|
699
|
+
modal = inject(ModalService);
|
|
700
|
+
/**
|
|
701
|
+
* Optional rich add-row dialog (provided by `@masterteam/forms` via
|
|
702
|
+
* `provideEntityListAddForm()`). When available, used instead of the local
|
|
703
|
+
* minimal dialog so the popup renders `mt-client-form` filtered by
|
|
704
|
+
* `writeFields`.
|
|
705
|
+
*/
|
|
706
|
+
addDialogComponent = inject(ENTITY_LIST_ADD_DIALOG_COMPONENT, { optional: true });
|
|
661
707
|
constructor() {
|
|
662
708
|
this.ngControl = inject(NgControl, { self: true, optional: true });
|
|
663
709
|
if (this.ngControl) {
|
|
664
710
|
this.ngControl.valueAccessor = this;
|
|
665
711
|
}
|
|
666
|
-
// Trigger fetch when
|
|
712
|
+
// Trigger fetch when context inputs change. Always fetch columns from
|
|
713
|
+
// /api/fetch/query (both Read and Write modes); rows are ignored in Write
|
|
714
|
+
// mode and replaced by locally-added rows.
|
|
667
715
|
effect(() => {
|
|
668
|
-
const
|
|
669
|
-
const
|
|
670
|
-
const
|
|
671
|
-
const
|
|
672
|
-
const levelDataId = this.
|
|
716
|
+
const allowedRead = this.canRead();
|
|
717
|
+
const allowedWrite = this.canWrite();
|
|
718
|
+
const ready = this.hasRequiredContext();
|
|
719
|
+
const levelId = this.levelId();
|
|
720
|
+
const levelDataId = this.levelDataId();
|
|
721
|
+
const moduleId = this.moduleId();
|
|
722
|
+
const readFields = this.readFields();
|
|
673
723
|
untracked(() => {
|
|
674
|
-
if (!
|
|
724
|
+
if ((!allowedRead && !allowedWrite) ||
|
|
725
|
+
!ready ||
|
|
726
|
+
levelId == null ||
|
|
727
|
+
levelDataId == null ||
|
|
728
|
+
moduleId == null) {
|
|
729
|
+
this.columns.set([]);
|
|
675
730
|
this.rows.set([]);
|
|
676
731
|
this.errorMessage.set(null);
|
|
677
732
|
return;
|
|
678
733
|
}
|
|
679
|
-
|
|
680
|
-
this.fetchRows(sourceId, propertyId, levelDataId, selectedIds);
|
|
734
|
+
this.fetchRows(levelId, levelDataId, moduleId, readFields);
|
|
681
735
|
});
|
|
682
736
|
});
|
|
683
737
|
}
|
|
@@ -686,6 +740,12 @@ class EntityListField {
|
|
|
686
740
|
// ============================================================================
|
|
687
741
|
writeValue(value) {
|
|
688
742
|
this.storedValue.set(value ?? null);
|
|
743
|
+
const rows = Array.isArray(value?.rows)
|
|
744
|
+
? value.rows
|
|
745
|
+
: [];
|
|
746
|
+
// Re-hydrate local rows if a value is written (e.g. form reset / patch).
|
|
747
|
+
this.localRows.set(rows);
|
|
748
|
+
this.localRowSeq = rows.length;
|
|
689
749
|
}
|
|
690
750
|
registerOnChange(fn) {
|
|
691
751
|
this.onModelChange = fn;
|
|
@@ -697,84 +757,224 @@ class EntityListField {
|
|
|
697
757
|
this.disabled.set(isDisabled);
|
|
698
758
|
}
|
|
699
759
|
// ============================================================================
|
|
700
|
-
//
|
|
760
|
+
// Write mode — Add row dialog
|
|
761
|
+
// ============================================================================
|
|
762
|
+
/** Row actions shown in Write mode — edit and delete (local-only). */
|
|
763
|
+
writeRowActions = computed(() => [
|
|
764
|
+
{
|
|
765
|
+
icon: 'custom.pencil',
|
|
766
|
+
tooltip: 'Edit',
|
|
767
|
+
action: (row) => this.openEditDialog(row),
|
|
768
|
+
},
|
|
769
|
+
{
|
|
770
|
+
icon: 'general.trash-01',
|
|
771
|
+
tooltip: 'Delete',
|
|
772
|
+
color: 'danger',
|
|
773
|
+
confirmation: {
|
|
774
|
+
type: 'popup',
|
|
775
|
+
confirmationType: 'delete',
|
|
776
|
+
},
|
|
777
|
+
action: (row) => this.deleteLocalRow(row),
|
|
778
|
+
},
|
|
779
|
+
], ...(ngDevMode ? [{ debugName: "writeRowActions" }] : /* istanbul ignore next */ []));
|
|
780
|
+
openAddDialog() {
|
|
781
|
+
if (this.disabled())
|
|
782
|
+
return;
|
|
783
|
+
const component = this.addDialogComponent;
|
|
784
|
+
if (!component)
|
|
785
|
+
return;
|
|
786
|
+
const ref = this.modal.openModal(component, 'dialog', {
|
|
787
|
+
header: 'Add',
|
|
788
|
+
styleClass: '!w-[48rem] max-w-[96vw]',
|
|
789
|
+
dismissableMask: true,
|
|
790
|
+
inputValues: {
|
|
791
|
+
moduleId: this.moduleId(),
|
|
792
|
+
levelId: this.levelId(),
|
|
793
|
+
levelDataId: this.levelDataId(),
|
|
794
|
+
writeFields: this.writeFields(),
|
|
795
|
+
},
|
|
796
|
+
});
|
|
797
|
+
ref.onClose.pipe(take(1)).subscribe((result) => {
|
|
798
|
+
if (!result || typeof result !== 'object')
|
|
799
|
+
return;
|
|
800
|
+
const values = result;
|
|
801
|
+
this.localRowSeq += 1;
|
|
802
|
+
const newRow = this.buildRowFromValues(`local-${this.localRowSeq}`, values);
|
|
803
|
+
const next = [...this.localRows(), newRow];
|
|
804
|
+
this.localRows.set(next);
|
|
805
|
+
this.emitLocalValue(next);
|
|
806
|
+
});
|
|
807
|
+
}
|
|
808
|
+
openEditDialog(row) {
|
|
809
|
+
if (this.disabled())
|
|
810
|
+
return;
|
|
811
|
+
const component = this.addDialogComponent;
|
|
812
|
+
if (!component)
|
|
813
|
+
return;
|
|
814
|
+
const originalValues = row['__values'] ?? {};
|
|
815
|
+
const ref = this.modal.openModal(component, 'dialog', {
|
|
816
|
+
header: 'Edit',
|
|
817
|
+
styleClass: '!w-[48rem] max-w-[96vw]',
|
|
818
|
+
dismissableMask: true,
|
|
819
|
+
inputValues: {
|
|
820
|
+
moduleId: this.moduleId(),
|
|
821
|
+
levelId: this.levelId(),
|
|
822
|
+
levelDataId: this.levelDataId(),
|
|
823
|
+
writeFields: this.writeFields(),
|
|
824
|
+
initialValues: originalValues,
|
|
825
|
+
},
|
|
826
|
+
});
|
|
827
|
+
ref.onClose.pipe(take(1)).subscribe((result) => {
|
|
828
|
+
if (!result || typeof result !== 'object')
|
|
829
|
+
return;
|
|
830
|
+
const values = result;
|
|
831
|
+
const rowId = row['Id'];
|
|
832
|
+
const updatedRow = this.buildRowFromValues(rowId, values);
|
|
833
|
+
const next = this.localRows().map((r) => r['Id'] === rowId ? updatedRow : r);
|
|
834
|
+
this.localRows.set(next);
|
|
835
|
+
this.emitLocalValue(next);
|
|
836
|
+
});
|
|
837
|
+
}
|
|
838
|
+
deleteLocalRow(row) {
|
|
839
|
+
const rowId = row['Id'];
|
|
840
|
+
const next = this.localRows().filter((r) => r['Id'] !== rowId);
|
|
841
|
+
this.localRows.set(next);
|
|
842
|
+
this.emitLocalValue(next);
|
|
843
|
+
}
|
|
844
|
+
buildRowFromValues(id, values) {
|
|
845
|
+
const row = { Id: id, __values: values };
|
|
846
|
+
for (const column of this.columns()) {
|
|
847
|
+
// Form values are keyed by catalog property key (e.g. "task_name"),
|
|
848
|
+
// but column.key is the normalizedKey (e.g. "Name"). Use propertyKey
|
|
849
|
+
// for the lookup so the value is found.
|
|
850
|
+
const raw = values[column.propertyKey ?? column.key];
|
|
851
|
+
row[column.key] = {
|
|
852
|
+
name: column.label ?? column.key,
|
|
853
|
+
key: column.key,
|
|
854
|
+
viewType: column.viewType ?? 'Text',
|
|
855
|
+
value: raw ?? '',
|
|
856
|
+
rawValue: raw ?? null,
|
|
857
|
+
};
|
|
858
|
+
}
|
|
859
|
+
return row;
|
|
860
|
+
}
|
|
861
|
+
emitLocalValue(rows) {
|
|
862
|
+
const current = this.storedValue();
|
|
863
|
+
const next = { ...(current ?? {}), rows };
|
|
864
|
+
this.storedValue.set(next);
|
|
865
|
+
this.onModelChange(next);
|
|
866
|
+
this.onTouched();
|
|
867
|
+
}
|
|
868
|
+
// ============================================================================
|
|
869
|
+
// Read endpoint — POST /api/fetch/query (Table projection)
|
|
701
870
|
// ============================================================================
|
|
702
|
-
fetchRows(
|
|
871
|
+
fetchRows(levelId, levelDataId, moduleId, propertyKeys) {
|
|
703
872
|
this.loading.set(true);
|
|
704
873
|
this.errorMessage.set(null);
|
|
705
874
|
const ctx = this.context();
|
|
706
|
-
const
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
875
|
+
const body = {
|
|
876
|
+
contextKey: `level:${levelId}/module:${moduleId}`,
|
|
877
|
+
projection: 'Table',
|
|
878
|
+
surfaceKey: 'table',
|
|
879
|
+
propertyKeys,
|
|
880
|
+
filters: [
|
|
881
|
+
{
|
|
882
|
+
key: 'levelDataId',
|
|
883
|
+
operator: 'Equals',
|
|
884
|
+
value: String(levelDataId),
|
|
885
|
+
},
|
|
886
|
+
],
|
|
887
|
+
page: 1,
|
|
888
|
+
pageSize: 3000,
|
|
889
|
+
};
|
|
714
890
|
this.http
|
|
715
|
-
.
|
|
716
|
-
params,
|
|
717
|
-
...(ctx ? { context: ctx } : {}),
|
|
718
|
-
})
|
|
891
|
+
.post('fetch/query', body, ctx ? { context: ctx } : {})
|
|
719
892
|
.pipe(takeUntilDestroyed(this.destroyRef), finalize(() => this.loading.set(false)), catchError((err) => {
|
|
720
|
-
console.error('EntityList
|
|
893
|
+
console.error('EntityList fetch/query failed', err);
|
|
721
894
|
this.errorMessage.set('Failed to load related items');
|
|
722
|
-
return of(
|
|
895
|
+
return of({});
|
|
723
896
|
}))
|
|
724
897
|
.subscribe((response) => {
|
|
725
|
-
const
|
|
726
|
-
? response
|
|
727
|
-
:
|
|
728
|
-
this.
|
|
898
|
+
const payload = response && typeof response === 'object' && 'data' in response
|
|
899
|
+
? (response.data ?? response)
|
|
900
|
+
: response;
|
|
901
|
+
this.applyResponse(payload);
|
|
729
902
|
});
|
|
730
903
|
}
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
const
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
const match = values.find((v) => (v.propertyKey ?? '').toLowerCase() === key);
|
|
740
|
-
const value = match?.rawValue ?? match?.value;
|
|
741
|
-
if (value != null && value !== '')
|
|
742
|
-
return String(value);
|
|
904
|
+
applyResponse(response) {
|
|
905
|
+
// Build property maps first so column defs can include the propertyKey
|
|
906
|
+
// mapping (normalizedKey → catalog key) needed for Write-mode row lookup.
|
|
907
|
+
const propertyByKey = new Map();
|
|
908
|
+
const propertyByNormalizedKey = new Map();
|
|
909
|
+
for (const property of response.catalog?.properties ?? []) {
|
|
910
|
+
propertyByKey.set(property.key, property);
|
|
911
|
+
propertyByNormalizedKey.set(property.normalizedKey, property);
|
|
743
912
|
}
|
|
744
|
-
const
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
:
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
913
|
+
const columns = (response.projectionMeta?.columns ?? [])
|
|
914
|
+
.filter((column) => column.visible)
|
|
915
|
+
.sort((a, b) => a.order - b.order)
|
|
916
|
+
.map((column) => ({
|
|
917
|
+
key: column.key,
|
|
918
|
+
label: column.label,
|
|
919
|
+
type: 'entity',
|
|
920
|
+
sortable: !UNSORTABLE_ENTITY_VIEW_TYPES.has(column.viewType),
|
|
921
|
+
viewType: column.viewType,
|
|
922
|
+
order: column.order,
|
|
923
|
+
visible: column.visible,
|
|
924
|
+
configuration: column.configuration ?? null,
|
|
925
|
+
// Store the catalog property key so Write-mode buildRowFromValues can
|
|
926
|
+
// look up form values keyed by property key (e.g. "task_name") rather
|
|
927
|
+
// than the normalizedKey used as the column display key (e.g. "Name").
|
|
928
|
+
propertyKey: propertyByNormalizedKey.get(column.key)?.key ?? column.key,
|
|
929
|
+
}));
|
|
930
|
+
this.columns.set(columns);
|
|
931
|
+
// In Write mode the table is filled locally — ignore server records.
|
|
932
|
+
if (this.canWrite()) {
|
|
933
|
+
this.rows.set([]);
|
|
934
|
+
return;
|
|
935
|
+
}
|
|
936
|
+
const rows = (response.records ?? []).map((record) => {
|
|
937
|
+
const row = { Id: record.id };
|
|
938
|
+
for (const column of columns) {
|
|
939
|
+
const property = propertyByKey.get(column.key) ??
|
|
940
|
+
propertyByNormalizedKey.get(column.key);
|
|
941
|
+
const cell = record.values?.[property?.key ?? column.key];
|
|
942
|
+
row[column.key] = this.toEntityData(column, cell, property, record.id);
|
|
943
|
+
}
|
|
944
|
+
return row;
|
|
945
|
+
});
|
|
946
|
+
this.rows.set(rows);
|
|
758
947
|
}
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
948
|
+
toEntityData(column, cell, property, recordId) {
|
|
949
|
+
return {
|
|
950
|
+
id: recordId,
|
|
951
|
+
propertyId: property?.id,
|
|
952
|
+
key: property?.key ?? column.key,
|
|
953
|
+
normalizedKey: property?.normalizedKey ?? column.key,
|
|
954
|
+
name: column.label ?? property?.label ?? column.key,
|
|
955
|
+
rawValue: cell?.raw === null || cell?.raw === undefined
|
|
956
|
+
? undefined
|
|
957
|
+
: String(cell.raw),
|
|
958
|
+
value: (cell?.value ?? ''),
|
|
959
|
+
viewType: (column.viewType ?? 'Text'),
|
|
960
|
+
type: property?.source,
|
|
961
|
+
order: column.order ?? property?.order,
|
|
962
|
+
configuration: column.configuration,
|
|
963
|
+
propertyConfiguration: property?.configuration ?? undefined,
|
|
964
|
+
comparison: cell?.comparison,
|
|
965
|
+
};
|
|
766
966
|
}
|
|
767
967
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EntityListField, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
768
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: EntityListField, isStandalone: true, selector: "mt-entity-list-field", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, propertyId: { classPropertyName: "propertyId", publicName: "propertyId", isSignal: true, isRequired: false, transformFunction: null }, configuration: { classPropertyName: "configuration", publicName: "configuration", isSignal: true, isRequired: false, transformFunction: null }, runtimeContext: { classPropertyName: "runtimeContext", publicName: "runtimeContext", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "grid gap-1" }, ngImport: i0, template: "<div class=\"flex flex-col gap-2\">\r\n @if (label()) {\r\n <label class=\"text-sm font-medium text-color\">\r\n {{ label() }}\r\n @if (required()) {\r\n <span class=\"text-red-500\">*</span>\r\n }\r\n </label>\r\n }\r\n\r\n @if (
|
|
968
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: EntityListField, isStandalone: true, selector: "mt-entity-list-field", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, propertyId: { classPropertyName: "propertyId", publicName: "propertyId", isSignal: true, isRequired: false, transformFunction: null }, configuration: { classPropertyName: "configuration", publicName: "configuration", isSignal: true, isRequired: false, transformFunction: null }, runtimeContext: { classPropertyName: "runtimeContext", publicName: "runtimeContext", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "grid gap-1" }, ngImport: i0, template: "<div class=\"flex flex-col gap-2\">\r\n @if (label()) {\r\n <label class=\"text-sm font-medium text-color\">\r\n {{ label() }}\r\n @if (required()) {\r\n <span class=\"text-red-500\">*</span>\r\n }\r\n </label>\r\n }\r\n\r\n @if (errorMessage(); as err) {\r\n <p-message severity=\"error\" [text]=\"err\" styleClass=\"w-full\" />\r\n } @else if (canWrite()) {\r\n <div class=\"flex justify-end\">\r\n <mt-button\r\n label=\"Add\"\r\n icon=\"general.plus\"\r\n size=\"small\"\r\n [disabled]=\"disabled()\"\r\n (onClick)=\"openAddDialog()\"\r\n />\r\n </div>\r\n <mt-table\r\n [noCard]=\"true\"\r\n [data]=\"displayRows()\"\r\n [columns]=\"columns()\"\r\n [rowActions]=\"writeRowActions()\"\r\n dataKey=\"Id\"\r\n [loading]=\"loading()\"\r\n />\r\n } @else if (!canRead()) {\r\n <div\r\n class=\"rounded border border-dashed border-surface-300 bg-surface-50 p-3 text-sm text-muted-color\"\r\n >\r\n Reading is not allowed for this field.\r\n </div>\r\n } @else if (!hasRequiredContext()) {\r\n <div\r\n class=\"rounded border border-dashed border-surface-300 bg-surface-50 p-3 text-sm text-muted-color\"\r\n >\r\n Save the form first to manage related items.\r\n </div>\r\n } @else if (loading() && !hasRows()) {\r\n <div class=\"flex flex-col gap-2\">\r\n <p-skeleton width=\"100%\" height=\"3rem\" />\r\n <p-skeleton width=\"100%\" height=\"3rem\" />\r\n </div>\r\n } @else if (!hasRows()) {\r\n <div\r\n class=\"rounded border border-dashed border-surface-300 bg-surface-50 p-3 text-sm text-muted-color\"\r\n >\r\n No related items.\r\n </div>\r\n } @else {\r\n <mt-table\r\n [noCard]=\"true\"\r\n [data]=\"rows()\"\r\n [columns]=\"columns()\"\r\n dataKey=\"Id\"\r\n [loading]=\"loading()\"\r\n />\r\n }\r\n\r\n @if (ngControl?.control) {\r\n <mt-field-validation\r\n [control]=\"ngControl?.control!\"\r\n [touched]=\"ngControl?.touched ?? false\"\r\n />\r\n }\r\n</div>\r\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: FieldValidation, selector: "mt-field-validation", inputs: ["control", "touched"] }, { kind: "component", type: Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "component", type: Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant", "motionOptions"], outputs: ["onClose"] }, { kind: "component", type: Table, selector: "mt-table", inputs: ["filters", "data", "columns", "rowActions", "size", "showGridlines", "stripedRows", "selectableRows", "clickableRows", "generalSearch", "lazyLocalSearch", "showFilters", "filterMode", "loading", "updating", "lazy", "lazyLocalSort", "lazyTotalRecords", "reorderableColumns", "reorderableRows", "dataKey", "storageKey", "storageMode", "exportable", "printable", "groupable", "cellClickFilter", "freezeActions", "printTitle", "exportFilename", "actionShape", "rowActionsLoadingFn", "tableLayout", "noCard", "tabs", "tabsOptionLabel", "tabsOptionValue", "activeTab", "actions", "paginatorPosition", "alwaysShowPaginator", "rowsPerPageOptions", "pageSize", "currentPage", "first", "filterTerm", "groupBy"], outputs: ["selectionChange", "cellChange", "lazyLoad", "columnReorder", "rowReorder", "rowClick", "rowActionsRequested", "filtersChange", "activeTabChange", "onTabChange", "pageSizeChange", "currentPageChange", "firstChange", "filterTermChange", "groupByChange"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
769
969
|
}
|
|
770
970
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EntityListField, decorators: [{
|
|
771
971
|
type: Component,
|
|
772
|
-
args: [{ selector: 'mt-entity-list-field', standalone: true, imports: [CommonModule,
|
|
972
|
+
args: [{ selector: 'mt-entity-list-field', standalone: true, imports: [CommonModule, FieldValidation, Skeleton, Message, Table, Button], changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'grid gap-1' }, template: "<div class=\"flex flex-col gap-2\">\r\n @if (label()) {\r\n <label class=\"text-sm font-medium text-color\">\r\n {{ label() }}\r\n @if (required()) {\r\n <span class=\"text-red-500\">*</span>\r\n }\r\n </label>\r\n }\r\n\r\n @if (errorMessage(); as err) {\r\n <p-message severity=\"error\" [text]=\"err\" styleClass=\"w-full\" />\r\n } @else if (canWrite()) {\r\n <div class=\"flex justify-end\">\r\n <mt-button\r\n label=\"Add\"\r\n icon=\"general.plus\"\r\n size=\"small\"\r\n [disabled]=\"disabled()\"\r\n (onClick)=\"openAddDialog()\"\r\n />\r\n </div>\r\n <mt-table\r\n [noCard]=\"true\"\r\n [data]=\"displayRows()\"\r\n [columns]=\"columns()\"\r\n [rowActions]=\"writeRowActions()\"\r\n dataKey=\"Id\"\r\n [loading]=\"loading()\"\r\n />\r\n } @else if (!canRead()) {\r\n <div\r\n class=\"rounded border border-dashed border-surface-300 bg-surface-50 p-3 text-sm text-muted-color\"\r\n >\r\n Reading is not allowed for this field.\r\n </div>\r\n } @else if (!hasRequiredContext()) {\r\n <div\r\n class=\"rounded border border-dashed border-surface-300 bg-surface-50 p-3 text-sm text-muted-color\"\r\n >\r\n Save the form first to manage related items.\r\n </div>\r\n } @else if (loading() && !hasRows()) {\r\n <div class=\"flex flex-col gap-2\">\r\n <p-skeleton width=\"100%\" height=\"3rem\" />\r\n <p-skeleton width=\"100%\" height=\"3rem\" />\r\n </div>\r\n } @else if (!hasRows()) {\r\n <div\r\n class=\"rounded border border-dashed border-surface-300 bg-surface-50 p-3 text-sm text-muted-color\"\r\n >\r\n No related items.\r\n </div>\r\n } @else {\r\n <mt-table\r\n [noCard]=\"true\"\r\n [data]=\"rows()\"\r\n [columns]=\"columns()\"\r\n dataKey=\"Id\"\r\n [loading]=\"loading()\"\r\n />\r\n }\r\n\r\n @if (ngControl?.control) {\r\n <mt-field-validation\r\n [control]=\"ngControl?.control!\"\r\n [touched]=\"ngControl?.touched ?? false\"\r\n />\r\n }\r\n</div>\r\n", styles: [":host{display:block}\n"] }]
|
|
773
973
|
}], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], propertyId: [{ type: i0.Input, args: [{ isSignal: true, alias: "propertyId", required: false }] }], configuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "configuration", required: false }] }], runtimeContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "runtimeContext", required: false }] }], context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: false }] }] } });
|
|
774
974
|
|
|
775
975
|
/**
|
|
776
976
|
* Generated bundle index. Do not edit.
|
|
777
977
|
*/
|
|
778
978
|
|
|
779
|
-
export { EntityListField, LookupMatrixField, SchedulePredecessorField, SchemaConnectionField };
|
|
979
|
+
export { ENTITY_LIST_ADD_DIALOG_COMPONENT, EntityListField, LookupMatrixField, SchedulePredecessorField, SchemaConnectionField };
|
|
780
980
|
//# sourceMappingURL=masterteam-components-business-fields.mjs.map
|