import { CommonModule } from '@angular/common';
import * as i0 from '@angular/core';
import { input, inject, DestroyRef, signal, computed, ChangeDetectionStrategy, Component, effect, untracked, viewChild, linkedSignal, InjectionToken } from '@angular/core';
import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
import * as i1 from '@angular/forms';
import { ControlContainer, Validators, NgControl, FormsModule } from '@angular/forms';
import * as i2 from '@jsverse/transloco';
import { TranslocoService, TranslocoPipe, TranslocoModule } from '@jsverse/transloco';
import { startWith, finalize, catchError, of, take } from 'rxjs';
import { Tooltip } from '@masterteam/components/tooltip';
import { Icon } from '@masterteam/icons';
import { SelectField } from '@masterteam/components/select-field';
import { MultiSelectField } from '@masterteam/components/multi-select-field';
import { FieldValidation } from '@masterteam/components/field-validation';
import { HttpClient } from '@angular/common/http';
import { Button } from '@masterteam/components/button';
import { NumberField } from '@masterteam/components/number-field';
import { Table } from '@masterteam/components/table';
import { Skeleton } from 'primeng/skeleton';
import { Message } from 'primeng/message';
import { ModalService } from '@masterteam/components/modal';

class LookupMatrixField {
    config = input.required(...(ngDevMode ? [{ debugName: "config" }] : /* istanbul ignore next */ []));
    controlContainer = inject(ControlContainer, {
        optional: true,
    });
    destroyRef = inject(DestroyRef);
    transloco = inject(TranslocoService);
    valueVersion = signal(0, ...(ngDevMode ? [{ debugName: "valueVersion" }] : /* istanbul ignore next */ []));
    subscribedControl = null;
    hasYAxis = computed(() => !!this.config().yFieldKey, ...(ngDevMode ? [{ debugName: "hasYAxis" }] : /* istanbul ignore next */ []));
    xOptions = computed(() => this.config().xOptions ?? [], ...(ngDevMode ? [{ debugName: "xOptions" }] : /* istanbul ignore next */ []));
    yOptions = computed(() => this.config().yOptions ?? [], ...(ngDevMode ? [{ debugName: "yOptions" }] : /* istanbul ignore next */ []));
    hasMatrix = computed(() => this.config().cells.length > 0, ...(ngDevMode ? [{ debugName: "hasMatrix" }] : /* istanbul ignore next */ []));
    cellMap = computed(() => new Map(this.config().cells.map((cell) => [
        this.cellKey(cell.xLookupItemId, cell.yLookupItemId),
        cell,
    ])), ...(ngDevMode ? [{ debugName: "cellMap" }] : /* istanbul ignore next */ []));
    selectedXOption = computed(() => {
        this.valueVersion();
        return this.resolveSelectedOption(this.xOptions(), this.getControlValue(this.config().xFieldKey));
    }, ...(ngDevMode ? [{ debugName: "selectedXOption" }] : /* istanbul ignore next */ []));
    selectedYOption = computed(() => {
        this.valueVersion();
        const yFieldKey = this.config().yFieldKey;
        if (!yFieldKey) {
            return null;
        }
        return this.resolveSelectedOption(this.yOptions(), this.getControlValue(yFieldKey));
    }, ...(ngDevMode ? [{ debugName: "selectedYOption" }] : /* istanbul ignore next */ []));
    activeCell = computed(() => {
        const selectedX = this.selectedXOption();
        if (!selectedX) {
            return null;
        }
        if (!this.hasYAxis()) {
            return this.getCell(selectedX.id ?? selectedX.value);
        }
        const selectedY = this.selectedYOption();
        if (!selectedY) {
            return null;
        }
        return this.getCell(selectedX.id ?? selectedX.value, selectedY.id ?? selectedY.value);
    }, ...(ngDevMode ? [{ debugName: "activeCell" }] : /* istanbul ignore next */ []));
    selectionSummary = computed(() => {
        const parts = [];
        const xAxisLabel = this.config().xAxisLabel.trim() ||
            this.transloco.translate('components.lookupMatrixField.xAxisFallback');
        const selectedX = this.selectedXOption();
        if (selectedX) {
            parts.push(`${xAxisLabel}: ${selectedX.label}`);
        }
        const selectedY = this.selectedYOption();
        const yAxisLabel = this.config().yAxisLabel?.trim() ||
            this.transloco.translate('components.lookupMatrixField.yAxisFallback');
        if (selectedY && this.hasYAxis()) {
            parts.push(`${yAxisLabel}: ${selectedY.label}`);
        }
        return parts.join(' / ');
    }, ...(ngDevMode ? [{ debugName: "selectionSummary" }] : /* istanbul ignore next */ []));
    pendingMessage = computed(() => {
        const xAxisLabel = this.config().xAxisLabel.trim() ||
            this.transloco.translate('components.lookupMatrixField.firstValueFallback');
        if (!this.hasYAxis()) {
            return this.transloco.translate('components.lookupMatrixField.selectXAxisFirst', { xAxisLabel });
        }
        const yAxisLabel = this.config().yAxisLabel?.trim() ||
            this.transloco.translate('components.lookupMatrixField.secondValueFallback');
        return this.transloco.translate('components.lookupMatrixField.selectAxesFirst', { xAxisLabel, yAxisLabel });
    }, ...(ngDevMode ? [{ debugName: "pendingMessage" }] : /* istanbul ignore next */ []));
    missingResultMessage = computed(() => {
        if (!this.selectedXOption()) {
            return this.pendingMessage();
        }
        if (this.hasYAxis() && !this.selectedYOption()) {
            return this.pendingMessage();
        }
        return this.transloco.translate('components.lookupMatrixField.noMatchingValue');
    }, ...(ngDevMode ? [{ debugName: "missingResultMessage" }] : /* istanbul ignore next */ []));
    ngAfterViewInit() {
        this.ensureControlSubscription();
    }
    getCell(xLookupItemId, yLookupItemId) {
        return (this.cellMap().get(this.cellKey(xLookupItemId, yLookupItemId)) ?? null);
    }
    getSwatchColor(color) {
        return this.resolveColor(color);
    }
    getControlValue(path) {
        if (!path)
            return null;
        return this.controlContainer?.control?.get(path)?.value ?? null;
    }
    ensureControlSubscription() {
        const control = this.controlContainer?.control;
        if (!control || control === this.subscribedControl) {
            return;
        }
        this.subscribedControl = control;
        control.valueChanges
            .pipe(startWith(control.getRawValue()), takeUntilDestroyed(this.destroyRef))
            .subscribe(() => {
            this.valueVersion.update((value) => value + 1);
        });
    }
    resolveSelectedOption(options, rawValue) {
        if (rawValue == null || rawValue === '')
            return null;
        return (options.find((option) => this.optionMatchesValue(option, rawValue)) ??
            null);
    }
    optionMatchesValue(option, rawValue) {
        return [option.value, option.key, option.id].some((candidate) => candidate != null && String(candidate) === String(rawValue));
    }
    cellKey(xLookupItemId, yLookupItemId) {
        return `${String(xLookupItemId)}::${String(yLookupItemId ?? '')}`;
    }
    resolveColor(color) {
        if (!color)
            return null;
        if (color.startsWith('#') ||
            color.startsWith('rgb') ||
            color.startsWith('hsl') ||
            color.startsWith('var(')) {
            return color;
        }
        return `var(--p-${color}-500)`;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: LookupMatrixField, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: LookupMatrixField, isStandalone: true, selector: "mt-lookup-matrix-field", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, host: { classAttribute: "grid gap-2" }, ngImport: i0, template: "@if (config().label) {\r\n  <label class=\"font-medium text-color\">\r\n    {{ config().label }}\r\n  </label>\r\n}\r\n\r\n<div\r\n  class=\"rounded-lg border border-surface-200 bg-surface-50 px-3 flex items-center\"\r\n>\r\n  @if (activeCell(); as cell) {\r\n    <div class=\"flex flex-1 min-h-6 items-center gap-2 justify-between\">\r\n      <span\r\n        class=\"h-6 w-2 shrink-0 rounded-[2px] border border-surface-200\"\r\n        [style.background-color]=\"getSwatchColor(cell.color)\"\r\n        [style.border-color]=\"getSwatchColor(cell.color)\"\r\n      ></span>\r\n\r\n      <div class=\"min-w-0 flex-1 py-2 flex items-center justify-between\">\r\n        <div class=\"truncate font-semibold text-gray-500\">\r\n          {{ cell.label }}\r\n        </div>\r\n\r\n        @if (selectionSummary()) {\r\n          <div class=\"font-bold text-gray-500\">\r\n            <mt-icon\r\n              [mtTooltip]=\"selectionSummary()\"\r\n              icon=\"general.info-circle\"\r\n            />\r\n          </div>\r\n        }\r\n      </div>\r\n    </div>\r\n  } @else {\r\n    <div class=\"flex min-h-6 items-center text-muted-color py-2\">\r\n      {{ hasMatrix() ? missingResultMessage() : config().emptyMessage }}\r\n    </div>\r\n  }\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: Tooltip, selector: "[mtTooltip]" }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: LookupMatrixField, decorators: [{
            type: Component,
            args: [{ selector: 'mt-lookup-matrix-field', standalone: true, imports: [CommonModule, Tooltip, Icon], changeDetection: ChangeDetectionStrategy.OnPush, host: {
                        class: 'grid gap-2',
                    }, template: "@if (config().label) {\r\n  <label class=\"font-medium text-color\">\r\n    {{ config().label }}\r\n  </label>\r\n}\r\n\r\n<div\r\n  class=\"rounded-lg border border-surface-200 bg-surface-50 px-3 flex items-center\"\r\n>\r\n  @if (activeCell(); as cell) {\r\n    <div class=\"flex flex-1 min-h-6 items-center gap-2 justify-between\">\r\n      <span\r\n        class=\"h-6 w-2 shrink-0 rounded-[2px] border border-surface-200\"\r\n        [style.background-color]=\"getSwatchColor(cell.color)\"\r\n        [style.border-color]=\"getSwatchColor(cell.color)\"\r\n      ></span>\r\n\r\n      <div class=\"min-w-0 flex-1 py-2 flex items-center justify-between\">\r\n        <div class=\"truncate font-semibold text-gray-500\">\r\n          {{ cell.label }}\r\n        </div>\r\n\r\n        @if (selectionSummary()) {\r\n          <div class=\"font-bold text-gray-500\">\r\n            <mt-icon\r\n              [mtTooltip]=\"selectionSummary()\"\r\n              icon=\"general.info-circle\"\r\n            />\r\n          </div>\r\n        }\r\n      </div>\r\n    </div>\r\n  } @else {\r\n    <div class=\"flex min-h-6 items-center text-muted-color py-2\">\r\n      {{ hasMatrix() ? missingResultMessage() : config().emptyMessage }}\r\n    </div>\r\n  }\r\n</div>\r\n" }]
        }], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }] } });

class SchemaConnectionField {
    // ============================================================================
    // Inputs
    // ============================================================================
    label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
    placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
    readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
    required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
    filter = input(true, ...(ngDevMode ? [{ debugName: "filter" }] : /* istanbul ignore next */ []));
    /**
     * Full connection configuration object from the API.
     * Includes `targetLevelId`, `sourceLevels[]`, `payloadTemplate`, etc.
     */
    configuration = input.required(...(ngDevMode ? [{ debugName: "configuration" }] : /* istanbul ignore next */ []));
    /**
     * Optional HttpContext for API requests (e.g. to set base URL behavior).
     */
    context = input(undefined, ...(ngDevMode ? [{ debugName: "context" }] : /* istanbul ignore next */ []));
    // ============================================================================
    // Internal State
    // ============================================================================
    /** The full ConnectionPayload value */
    value = signal(null, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
    disabled = signal(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
    /** Per-source-level state: options + loading */
    sourceLevelStates = signal([], ...(ngDevMode ? [{ debugName: "sourceLevelStates" }] : /* istanbul ignore next */ []));
    /** Mutable selections per source level: sourceLevelId -> selected value */
    selections = {};
    requiredValidator = Validators.required;
    onTouched = () => { };
    onModelChange = () => { };
    ngControl = null;
    http = inject(HttpClient);
    destroyRef = inject(DestroyRef);
    /**
     * Source levels from configuration.
     */
    sourceLevels = computed(() => {
        return this.configuration()?.sourceLevels ?? [];
    }, ...(ngDevMode ? [{ debugName: "sourceLevels" }] : /* istanbul ignore next */ []));
    /**
     * Percentage width for each dropdown, evenly divided.
     */
    dropdownWidth = computed(() => {
        const count = this.sourceLevels().length;
        if (count <= 0)
            return '100%';
        return `${100 / count}%`;
    }, ...(ngDevMode ? [{ debugName: "dropdownWidth" }] : /* istanbul ignore next */ []));
    constructor() {
        this.ngControl = inject(NgControl, { self: true, optional: true });
        if (this.ngControl) {
            this.ngControl.valueAccessor = this;
        }
        effect(() => {
            if (this.ngControl?.control && this.required()) {
                this.ngControl.control.addValidators(Validators.required);
                this.ngControl.control.updateValueAndValidity();
            }
        });
        // Load options for each source level when configuration changes
        effect(() => {
            const levels = this.sourceLevels();
            if (!levels.length)
                return;
            // Everything below must NOT create signal dependencies,
            // only sourceLevels() (→ configuration) should trigger this effect.
            untracked(() => {
                // Initialize per-source states + selections
                this.sourceLevelStates.set(levels.map((source) => ({
                    source,
                    options: [],
                    loading: false,
                })));
                for (const source of levels) {
                    const sourceId = this.getSourceId(source);
                    if (!(sourceId in this.selections)) {
                        this.selections[sourceId] = source.allowManyToMany ? [] : null;
                    }
                }
                // Distribute existing value to selections
                this.distributeToSelections(this.value());
                // Load options for each source level
                for (const source of levels) {
                    this.loadOptions(source);
                }
            });
        });
    }
    // ============================================================================
    // Source Level Helpers
    // ============================================================================
    /**
     * Returns a stable numeric ID for a source regardless of whether it is a
     * level (`levelId`) or a module (`moduleId`). Used as the key in `selections`
     * and `sourceLevelStates`.
     */
    getSourceId(source) {
        return (source.levelId ?? source.moduleId);
    }
    /**
     * Builds the `contextKey` for the `fetch/query` request based on source type.
     */
    getContextKey(source) {
        return source.levelId != null
            ? `level:${source.levelId}`
            : `module:${source.moduleId}`;
    }
    // ============================================================================
    // Option Loading (per source level)
    // ============================================================================
    loadOptions(source) {
        this.updateSourceState(this.getSourceId(source), { loading: true });
        const ctx = this.context();
        const payload = {
            contextKey: this.getContextKey(source),
            projection: 'Flat',
            propertyKeys: ['name'],
        };
        this.http
            .post('fetch/query', payload, {
            ...(ctx ? { context: ctx } : {}),
        })
            .pipe(takeUntilDestroyed(this.destroyRef), finalize(() => this.updateSourceState(this.getSourceId(source), { loading: false })), catchError((err) => {
            console.error(`Connection options load failed for ${source.levelKey ?? source.moduleKey}:`, err);
            return of({ data: { records: [] } });
        }))
            .subscribe((response) => {
            const options = (response?.data?.records ?? [])
                .filter((record) => record?.id != null)
                .map((record) => ({
                ...record,
                id: record.id,
                name: record.name,
            }));
            this.updateSourceState(this.getSourceId(source), {
                options,
                loading: false,
            });
        });
    }
    updateSourceState(sourceId, patch) {
        this.sourceLevelStates.update((states) => states.map((s) => this.getSourceId(s.source) === sourceId ? { ...s, ...patch } : s));
    }
    // ============================================================================
    // Value Handling
    // ============================================================================
    /**
     * Single handler — no params. Reads all selections, builds the combined payload.
     */
    syncValue() {
        const cfg = this.configuration();
        const states = this.sourceLevelStates();
        const sources = [];
        for (const state of states) {
            const val = this.selections[this.getSourceId(state.source)];
            if (val == null)
                continue;
            const effectiveId = this.getSourceId(state.source);
            if (state.source.allowManyToMany && Array.isArray(val)) {
                for (const id of val) {
                    sources.push({
                        sourceLevelId: effectiveId,
                        sourceLevelDataId: id,
                    });
                }
            }
            else if (typeof val === 'number') {
                sources.push({
                    sourceLevelId: effectiveId,
                    sourceLevelDataId: val,
                });
            }
        }
        const payload = sources.length > 0 ? { levelId: cfg.targetLevelId, sources } : null;
        this.value.set(payload);
        this.onModelChange(payload);
        this.onTouched();
    }
    distributeToSelections(payload) {
        const states = this.sourceLevelStates();
        for (const state of states) {
            const sourceId = this.getSourceId(state.source);
            const ids = (payload?.sources ?? [])
                .filter((s) => s.sourceLevelId === sourceId)
                .map((s) => s.sourceLevelDataId);
            this.selections[sourceId] = state.source.allowManyToMany
                ? ids
                : (ids[0] ?? null);
        }
    }
    // ============================================================================
    // ControlValueAccessor
    // ============================================================================
    writeValue(value) {
        if (typeof value === 'string') {
            try {
                value = JSON.parse(value);
            }
            catch {
                value = null;
            }
        }
        this.value.set(value ?? null);
        this.distributeToSelections(value ?? null);
    }
    registerOnChange(fn) {
        this.onModelChange = fn;
    }
    registerOnTouched(fn) {
        this.onTouched = fn;
    }
    setDisabledState(disabled) {
        this.disabled.set(disabled);
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: SchemaConnectionField, deps: [], target: i0.ɵɵFactoryTarget.Component });
    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]=\"\r\n            placeholder() ||\r\n            state.source.name?.en ||\r\n            ('components.selectPlaceholder' | transloco)\r\n          \"\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]=\"\r\n            placeholder() ||\r\n            state.source.name?.en ||\r\n            ('components.selectPlaceholder' | transloco)\r\n          \"\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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.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"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: SchemaConnectionField, decorators: [{
            type: Component,
            args: [{ selector: 'mt-schema-connection-field', standalone: true, imports: [
                        FormsModule,
                        SelectField,
                        MultiSelectField,
                        FieldValidation,
                        TranslocoPipe,
                    ], changeDetection: ChangeDetectionStrategy.OnPush, host: {
                        class: 'grid gap-1',
                    }, 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]=\"\r\n            placeholder() ||\r\n            state.source.name?.en ||\r\n            ('components.selectPlaceholder' | transloco)\r\n          \"\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]=\"\r\n            placeholder() ||\r\n            state.source.name?.en ||\r\n            ('components.selectPlaceholder' | transloco)\r\n          \"\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" }]
        }], 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 }] }] } });

const PREDECESSOR_TYPE_BY_TOKEN = {
    FS: 0,
    SS: 1,
    FF: 2,
    SF: 3,
};
const PREDECESSOR_TOKEN_BY_TYPE = {
    0: 'FS',
    1: 'SS',
    2: 'FF',
    3: 'SF',
};
class SchedulePredecessorField {
    predecessorCellTpl = viewChild.required('predecessorCellTpl');
    typeCellTpl = viewChild.required('typeCellTpl');
    lagCellTpl = viewChild.required('lagCellTpl');
    label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
    placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
    readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
    required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
    configuration = input(null, ...(ngDevMode ? [{ debugName: "configuration" }] : /* istanbul ignore next */ []));
    runtimeContext = input(null, ...(ngDevMode ? [{ debugName: "runtimeContext" }] : /* istanbul ignore next */ []));
    loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
    taskOptions = signal([], ...(ngDevMode ? [{ debugName: "taskOptions" }] : /* istanbul ignore next */ []));
    rows = signal([], ...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
    disabled = signal(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
    typeOptions = computed(() => [
        { label: 'FS', value: 0 },
        { label: 'SS', value: 1 },
        { label: 'FF', value: 2 },
        { label: 'SF', value: 3 },
    ], ...(ngDevMode ? [{ debugName: "typeOptions" }] : /* istanbul ignore next */ []));
    availableTaskOptions = computed(() => {
        const currentTaskId = this.runtimeContext()?.moduleDataId;
        return this.taskOptions().filter((item) => String(item.value) !== String(currentTaskId ?? ''));
    }, ...(ngDevMode ? [{ debugName: "availableTaskOptions" }] : /* istanbul ignore next */ []));
    canAddRow = computed(() => !!this.runtimeContext()?.levelId &&
        !!this.runtimeContext()?.levelDataId &&
        this.availableTaskOptions().length > 0, ...(ngDevMode ? [{ debugName: "canAddRow" }] : /* istanbul ignore next */ []));
    addTooltip = computed(() => this.canAddRow() ? undefined : this.texts().noAvailable, ...(ngDevMode ? [{ debugName: "addTooltip" }] : /* istanbul ignore next */ []));
    pageSize = computed(() => this.rows().length > 0 ? this.rows().length : 1, ...(ngDevMode ? [{ debugName: "pageSize" }] : /* istanbul ignore next */ []));
    columns = linkedSignal(() => [
        {
            key: 'predecessorId',
            label: this.texts().predecessor,
            type: 'custom',
            customCellTpl: this.predecessorCellTpl(),
        },
        {
            key: 'type',
            label: this.texts().type,
            type: 'custom',
            customCellTpl: this.typeCellTpl(),
        },
        {
            key: 'lagDays',
            label: this.texts().lagDays,
            type: 'custom',
            customCellTpl: this.lagCellTpl(),
        },
    ], ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
    rowActions = computed(() => [
        {
            icon: 'general.trash-01',
            color: 'danger',
            variant: 'text',
            tooltip: this.texts().delete,
            hidden: () => this.disabled() || this.readonly(),
            action: (row) => this.removeRow(row.key),
        },
    ], ...(ngDevMode ? [{ debugName: "rowActions" }] : /* istanbul ignore next */ []));
    requiredValidator = Validators.required;
    onTouched = () => { };
    onModelChange = () => { };
    ngControl = null;
    http = inject(HttpClient);
    transloco = inject(TranslocoService);
    destroyRef = inject(DestroyRef);
    activeLang = toSignal(this.transloco.langChanges$, {
        initialValue: this.transloco.getActiveLang(),
    });
    rowKey = 0;
    texts = computed(() => {
        this.activeLang();
        return {
            noAvailable: this.transloco.translate('components.schedulePredecessorField.noAvailable'),
            predecessor: this.transloco.translate('components.schedulePredecessorField.predecessor'),
            type: this.transloco.translate('components.schedulePredecessorField.type'),
            lagDays: this.transloco.translate('components.schedulePredecessorField.lagDays'),
            delete: this.transloco.translate('components.schedulePredecessorField.delete'),
        };
    }, ...(ngDevMode ? [{ debugName: "texts" }] : /* istanbul ignore next */ []));
    constructor() {
        this.ngControl = inject(NgControl, { self: true, optional: true });
        if (this.ngControl) {
            this.ngControl.valueAccessor = this;
        }
        effect(() => {
            if (this.ngControl?.control && this.required()) {
                this.ngControl.control.addValidators(Validators.required);
                this.ngControl.control.updateValueAndValidity();
            }
        });
        effect(() => {
            const context = this.runtimeContext();
            const levelId = context?.levelId;
            const levelDataId = context?.levelDataId;
            if (levelId == null || levelDataId == null) {
                this.taskOptions.set([]);
                return;
            }
            untracked(() => this.loadTaskOptions(levelId, levelDataId));
        });
    }
    addRow() {
        if (this.disabled() || this.readonly() || !this.canAddRow()) {
            return;
        }
        this.syncRows([
            ...this.rows(),
            {
                key: this.nextRowKey(),
                predecessorId: '',
                type: 0,
                lagDays: 0,
            },
        ]);
    }
    removeRow(key) {
        if (this.disabled() || this.readonly()) {
            return;
        }
        this.syncRows(this.rows().filter((row) => row.key !== key));
    }
    updateRow(key, patch) {
        if (this.disabled() || this.readonly()) {
            return;
        }
        this.syncRows(this.rows().map((row) => (row.key === key ? { ...row, ...patch } : row)));
    }
    writeValue(value) {
        const rows = typeof value === 'string'
            ? value
                .split(',')
                .map((item) => item.trim())
                .filter(Boolean)
                .map((item) => this.parseCompactValue(item))
                .filter((item) => item != null)
                .map((item) => ({
                key: this.nextRowKey(),
                ...item,
            }))
            : [];
        this.rows.set(rows);
    }
    registerOnChange(fn) {
        this.onModelChange = fn;
    }
    registerOnTouched(fn) {
        this.onTouched = fn;
    }
    setDisabledState(disabled) {
        this.disabled.set(disabled);
    }
    syncRows(rows) {
        this.rows.set(rows);
        const value = rows
            .filter((row) => row.predecessorId !== null &&
            row.predecessorId !== undefined &&
            String(row.predecessorId).trim() !== '')
            .map((row) => this.formatCompactValue(row))
            .join(',');
        this.onModelChange(value || null);
        this.onTouched();
    }
    loadTaskOptions(levelId, levelDataId) {
        this.loading.set(true);
        this.http
            .post(`levels/${levelId}/${levelDataId}/schedule/query`, {
            projection: 'Tree',
            propertyKeys: ['name'],
        })
            .pipe(takeUntilDestroyed(this.destroyRef), finalize(() => this.loading.set(false)), catchError(() => of({ data: { records: [] } })))
            .subscribe((response) => {
            this.taskOptions.set(this.mapTaskOptions(response.data));
        });
    }
    mapTaskOptions(data) {
        return this.flattenRecords(this.resolveRootRecords(data?.records ?? [], data?.projectionMeta?.rootIds ?? [])).map((record) => ({
            label: `${record.id} - ${record.name ?? record.id}`,
            value: String(record.id),
        }));
    }
    resolveRootRecords(records, rootIds) {
        if (!rootIds?.length) {
            return records;
        }
        const recordsById = new Map(records.map((record) => [String(record.id), record]));
        return rootIds
            .map((id) => recordsById.get(String(id)))
            .filter((record) => record != null);
    }
    flattenRecords(records) {
        const output = [];
        const walk = (items) => {
            items.forEach((item) => {
                output.push(item);
                walk(item.children ?? []);
            });
        };
        walk(records);
        return output;
    }
    nextRowKey() {
        this.rowKey += 1;
        return `predecessor-${this.rowKey}`;
    }
    parseCompactValue(value) {
        const match = value.match(/^(.+?)(FS|SS|FF|SF)([+-]\d+)?$/);
        if (!match) {
            return null;
        }
        return {
            predecessorId: match[1],
            type: PREDECESSOR_TYPE_BY_TOKEN[match[2]],
            lagDays: match[3] ? Number(match[3]) : 0,
        };
    }
    formatCompactValue(row) {
        const lag = row.lagDays > 0 ? `+${row.lagDays}` : row.lagDays < 0 ? row.lagDays : '';
        return `${row.predecessorId}${PREDECESSOR_TOKEN_BY_TYPE[row.type]}${lag}`;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: SchedulePredecessorField, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: SchedulePredecessorField, isStandalone: true, selector: "mt-schedule-predecessor-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 }, configuration: { classPropertyName: "configuration", publicName: "configuration", isSignal: true, isRequired: false, transformFunction: null }, runtimeContext: { classPropertyName: "runtimeContext", publicName: "runtimeContext", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "grid gap-1" }, viewQueries: [{ propertyName: "predecessorCellTpl", first: true, predicate: ["predecessorCellTpl"], descendants: true, isSignal: true }, { propertyName: "typeCellTpl", first: true, predicate: ["typeCellTpl"], descendants: true, isSignal: true }, { propertyName: "lagCellTpl", first: true, predicate: ["lagCellTpl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"gap-3 overflow-auto\">\r\n  <div class=\"flex items-center justify-between mb-2\">\r\n    <div>\r\n      @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    </div>\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      size=\"small\"\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    noCard\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", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { 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"] }, { kind: "component", type: FieldValidation, selector: "mt-field-validation", inputs: ["control", "touched"] }, { kind: "component", type: NumberField, selector: "mt-number-field", inputs: ["field", "hint", "label", "placeholder", "class", "readonly", "pInputs", "format", "useGrouping", "maxFractionDigits", "min", "max", "required"] }, { 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: 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: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i2.TranslocoPipe, name: "transloco" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: SchedulePredecessorField, decorators: [{
            type: Component,
            args: [{ selector: 'mt-schedule-predecessor-field', standalone: true, imports: [
                        CommonModule,
                        FormsModule,
                        Button,
                        FieldValidation,
                        NumberField,
                        SelectField,
                        Table,
                        TranslocoModule,
                    ], changeDetection: ChangeDetectionStrategy.OnPush, host: {
                        class: 'grid gap-1',
                    }, template: "<div class=\"gap-3 overflow-auto\">\r\n  <div class=\"flex items-center justify-between mb-2\">\r\n    <div>\r\n      @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    </div>\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      size=\"small\"\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    noCard\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" }]
        }], 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 }] }] } });

/**
 * Token used by `mt-entity-list-field` (Write mode) to open the rich add-row
 * dialog backed by `@masterteam/forms`'s `mt-client-form`. Apps that want this
 * behavior should call `provideEntityListAddForm()` from
 * `@masterteam/forms/entity-list-add-form` in their app providers. When the
 * token is not registered, the field falls back to a minimal text-only popup.
 */
const ENTITY_LIST_ADD_DIALOG_COMPONENT = new InjectionToken('ENTITY_LIST_ADD_DIALOG_COMPONENT');

const UNSORTABLE_ENTITY_VIEW_TYPES = new Set([
    'Attachment',
    'Checkbox',
]);
class EntityListField {
    // Inputs
    label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
    readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
    required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
    /** EntityList property id (kept for back-compat; unused by fetch/query). */
    propertyId = input(null, ...(ngDevMode ? [{ debugName: "propertyId" }] : /* istanbul ignore next */ []));
    /** Property configuration (sourceType, moduleId, access, readFields, etc). */
    configuration = input(null, ...(ngDevMode ? [{ debugName: "configuration" }] : /* istanbul ignore next */ []));
    /** Runtime ids needed to call the read endpoint. */
    runtimeContext = input(null, ...(ngDevMode ? [{ debugName: "runtimeContext" }] : /* istanbul ignore next */ []));
    /** Optional HttpContext (kept for back-compat). */
    context = input(undefined, ...(ngDevMode ? [{ debugName: "context" }] : /* istanbul ignore next */ []));
    // CVA state — pass-through value (EntityList stored JSON shape).
    storedValue = signal(null, ...(ngDevMode ? [{ debugName: "storedValue" }] : /* istanbul ignore next */ []));
    // Loaded table state.
    columns = signal([], ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
    rows = signal([], ...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
    loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
    errorMessage = signal(null, ...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
    disabled = signal(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
    requiredValidator = Validators.required;
    ngControl = null;
    levelId = computed(() => {
        const raw = this.runtimeContext()?.levelId ?? null;
        return raw == null || raw === '' ? null : raw;
    }, ...(ngDevMode ? [{ debugName: "levelId" }] : /* istanbul ignore next */ []));
    levelDataId = computed(() => {
        const raw = this.runtimeContext()?.levelDataId ?? null;
        return raw == null || raw === '' ? null : raw;
    }, ...(ngDevMode ? [{ debugName: "levelDataId" }] : /* istanbul ignore next */ []));
    moduleId = computed(() => {
        const raw = this.configuration()
            ?.moduleId;
        return raw == null || raw === '' ? null : raw;
    }, ...(ngDevMode ? [{ debugName: "moduleId" }] : /* istanbul ignore next */ []));
    readFields = computed(() => {
        const raw = this.configuration()
            ?.readFields;
        if (!Array.isArray(raw))
            return [];
        return raw.filter((f) => typeof f === 'string' && f.length > 0);
    }, ...(ngDevMode ? [{ debugName: "readFields" }] : /* istanbul ignore next */ []));
    canRead = computed(() => {
        const access = String(this.configuration()?.access ?? 'Auto');
        return access !== 'Write' && access !== 'None';
    }, ...(ngDevMode ? [{ debugName: "canRead" }] : /* istanbul ignore next */ []));
    canWrite = computed(() => {
        const access = String(this.configuration()?.access ?? 'Auto');
        return access === 'Write';
    }, ...(ngDevMode ? [{ debugName: "canWrite" }] : /* istanbul ignore next */ []));
    writeFields = computed(() => {
        const raw = this.configuration()
            ?.writeFields;
        if (!Array.isArray(raw))
            return [];
        return raw.filter((f) => typeof f === 'string' && f.length > 0);
    }, ...(ngDevMode ? [{ debugName: "writeFields" }] : /* istanbul ignore next */ []));
    /** Locally-added rows (Write mode). Persisted via CVA value. */
    localRows = signal([], ...(ngDevMode ? [{ debugName: "localRows" }] : /* istanbul ignore next */ []));
    localRowSeq = 0;
    displayRows = computed(() => this.canWrite() ? this.localRows() : this.rows(), ...(ngDevMode ? [{ debugName: "displayRows" }] : /* istanbul ignore next */ []));
    hasRows = computed(() => this.displayRows().length > 0, ...(ngDevMode ? [{ debugName: "hasRows" }] : /* istanbul ignore next */ []));
    hasRequiredContext = computed(() => this.levelId() != null &&
        this.levelDataId() != null &&
        this.moduleId() != null &&
        this.readFields().length > 0, ...(ngDevMode ? [{ debugName: "hasRequiredContext" }] : /* istanbul ignore next */ []));
    onTouched = () => { };
    onModelChange = () => { };
    http = inject(HttpClient);
    destroyRef = inject(DestroyRef);
    modal = inject(ModalService);
    transloco = inject(TranslocoService);
    /**
     * Optional rich add-row dialog (provided by `@masterteam/forms` via
     * `provideEntityListAddForm()`). When available, used instead of the local
     * minimal dialog so the popup renders `mt-client-form` filtered by
     * `writeFields`.
     */
    addDialogComponent = inject(ENTITY_LIST_ADD_DIALOG_COMPONENT, { optional: true });
    constructor() {
        this.ngControl = inject(NgControl, { self: true, optional: true });
        if (this.ngControl) {
            this.ngControl.valueAccessor = this;
        }
        // Trigger fetch when context inputs change. Always fetch columns from
        // /api/fetch/query (both Read and Write modes); rows are ignored in Write
        // mode and replaced by locally-added rows.
        effect(() => {
            const allowedRead = this.canRead();
            const allowedWrite = this.canWrite();
            const ready = this.hasRequiredContext();
            const levelId = this.levelId();
            const levelDataId = this.levelDataId();
            const moduleId = this.moduleId();
            const readFields = this.readFields();
            untracked(() => {
                if ((!allowedRead && !allowedWrite) ||
                    !ready ||
                    levelId == null ||
                    levelDataId == null ||
                    moduleId == null) {
                    this.columns.set([]);
                    this.rows.set([]);
                    this.errorMessage.set(null);
                    return;
                }
                this.fetchRows(levelId, levelDataId, moduleId, readFields);
            });
        });
    }
    // ============================================================================
    // CVA
    // ============================================================================
    writeValue(value) {
        this.storedValue.set(value ?? null);
        const rows = Array.isArray(value?.rows)
            ? value.rows
            : [];
        // Re-hydrate local rows if a value is written (e.g. form reset / patch).
        this.localRows.set(rows);
        this.localRowSeq = rows.length;
    }
    registerOnChange(fn) {
        this.onModelChange = fn;
    }
    registerOnTouched(fn) {
        this.onTouched = fn;
    }
    setDisabledState(isDisabled) {
        this.disabled.set(isDisabled);
    }
    // ============================================================================
    // Write mode — Add row dialog
    // ============================================================================
    /** Row actions shown in Write mode — edit and delete (local-only). */
    writeRowActions = computed(() => [
        {
            icon: 'custom.pencil',
            tooltip: this.transloco.translate('components.entityListField.edit'),
            action: (row) => this.openEditDialog(row),
        },
        {
            icon: 'general.trash-01',
            tooltip: this.transloco.translate('components.entityListField.delete'),
            color: 'danger',
            confirmation: {
                type: 'popup',
                confirmationType: 'delete',
            },
            action: (row) => this.deleteLocalRow(row),
        },
    ], ...(ngDevMode ? [{ debugName: "writeRowActions" }] : /* istanbul ignore next */ []));
    openAddDialog() {
        if (this.disabled())
            return;
        const component = this.addDialogComponent;
        if (!component)
            return;
        const ref = this.modal.openModal(component, 'dialog', {
            header: this.transloco.translate('components.entityListField.add'),
            styleClass: '!w-[48rem] max-w-[96vw]',
            dismissableMask: true,
            inputValues: {
                moduleId: this.moduleId(),
                levelId: this.levelId(),
                levelDataId: this.levelDataId(),
                writeFields: this.writeFields(),
            },
        });
        ref.onClose.pipe(take(1)).subscribe((result) => {
            if (!result || typeof result !== 'object')
                return;
            const values = result;
            this.localRowSeq += 1;
            const newRow = this.buildRowFromValues(`local-${this.localRowSeq}`, values);
            const next = [...this.localRows(), newRow];
            this.localRows.set(next);
            this.emitLocalValue(next);
        });
    }
    openEditDialog(row) {
        if (this.disabled())
            return;
        const component = this.addDialogComponent;
        if (!component)
            return;
        const originalValues = row['__values'] ?? {};
        const ref = this.modal.openModal(component, 'dialog', {
            header: this.transloco.translate('components.entityListField.edit'),
            styleClass: '!w-[48rem] max-w-[96vw]',
            dismissableMask: true,
            inputValues: {
                moduleId: this.moduleId(),
                levelId: this.levelId(),
                levelDataId: this.levelDataId(),
                writeFields: this.writeFields(),
                initialValues: originalValues,
            },
        });
        ref.onClose.pipe(take(1)).subscribe((result) => {
            if (!result || typeof result !== 'object')
                return;
            const values = result;
            const rowId = row['Id'];
            const updatedRow = this.buildRowFromValues(rowId, values);
            const next = this.localRows().map((r) => r['Id'] === rowId ? updatedRow : r);
            this.localRows.set(next);
            this.emitLocalValue(next);
        });
    }
    deleteLocalRow(row) {
        const rowId = row['Id'];
        const next = this.localRows().filter((r) => r['Id'] !== rowId);
        this.localRows.set(next);
        this.emitLocalValue(next);
    }
    buildRowFromValues(id, values) {
        const row = { Id: id, __values: values };
        for (const column of this.columns()) {
            // Form values are keyed by catalog property key (e.g. "task_name"),
            // but column.key is the normalizedKey (e.g. "Name"). Use propertyKey
            // for the lookup so the value is found.
            const raw = values[column.propertyKey ?? column.key];
            row[column.key] = {
                name: column.label ?? column.key,
                key: column.key,
                viewType: column.viewType ?? 'Text',
                value: raw ?? '',
                rawValue: raw ?? null,
            };
        }
        return row;
    }
    emitLocalValue(rows) {
        const current = this.storedValue();
        const next = { ...(current ?? {}), rows };
        this.storedValue.set(next);
        this.onModelChange(next);
        this.onTouched();
    }
    // ============================================================================
    // Read endpoint — POST /api/fetch/query (Table projection)
    // ============================================================================
    fetchRows(levelId, levelDataId, moduleId, propertyKeys) {
        this.loading.set(true);
        this.errorMessage.set(null);
        const ctx = this.context();
        const body = {
            contextKey: `level:${levelId}/module:${moduleId}`,
            projection: 'Table',
            surfaceKey: 'table',
            propertyKeys,
            filters: [
                {
                    key: 'levelDataId',
                    operator: 'Equals',
                    value: String(levelDataId),
                },
            ],
            page: 1,
            pageSize: 3000,
        };
        this.http
            .post('fetch/query', body, ctx ? { context: ctx } : {})
            .pipe(takeUntilDestroyed(this.destroyRef), finalize(() => this.loading.set(false)), catchError((err) => {
            console.error('EntityList fetch/query failed', err);
            this.errorMessage.set(this.transloco.translate('components.entityListField.loadFailed'));
            return of({});
        }))
            .subscribe((response) => {
            const payload = response && typeof response === 'object' && 'data' in response
                ? (response.data ?? response)
                : response;
            this.applyResponse(payload);
        });
    }
    applyResponse(response) {
        // Build property maps first so column defs can include the propertyKey
        // mapping (normalizedKey → catalog key) needed for Write-mode row lookup.
        const propertyByKey = new Map();
        const propertyByNormalizedKey = new Map();
        for (const property of response.catalog?.properties ?? []) {
            propertyByKey.set(property.key, property);
            propertyByNormalizedKey.set(property.normalizedKey, property);
        }
        const columns = (response.projectionMeta?.columns ?? [])
            .filter((column) => column.visible)
            .sort((a, b) => a.order - b.order)
            .map((column) => ({
            key: column.key,
            label: column.label,
            type: 'entity',
            sortable: !UNSORTABLE_ENTITY_VIEW_TYPES.has(column.viewType),
            viewType: column.viewType,
            order: column.order,
            visible: column.visible,
            configuration: column.configuration ?? null,
            // Store the catalog property key so Write-mode buildRowFromValues can
            // look up form values keyed by property key (e.g. "task_name") rather
            // than the normalizedKey used as the column display key (e.g. "Name").
            propertyKey: propertyByNormalizedKey.get(column.key)?.key ?? column.key,
        }));
        this.columns.set(columns);
        // In Write mode the table is filled locally — ignore server records.
        if (this.canWrite()) {
            this.rows.set([]);
            return;
        }
        const rows = (response.records ?? []).map((record) => {
            const row = { Id: record.id };
            for (const column of columns) {
                const property = propertyByKey.get(column.key) ??
                    propertyByNormalizedKey.get(column.key);
                const cell = record.values?.[property?.key ?? column.key];
                row[column.key] = this.toEntityData(column, cell, property, record.id);
            }
            return row;
        });
        this.rows.set(rows);
    }
    toEntityData(column, cell, property, recordId) {
        return {
            id: recordId,
            propertyId: property?.id,
            key: property?.key ?? column.key,
            normalizedKey: property?.normalizedKey ?? column.key,
            name: column.label ?? property?.label ?? column.key,
            rawValue: cell?.raw === null || cell?.raw === undefined
                ? undefined
                : String(cell.raw),
            value: (cell?.value ?? ''),
            viewType: (column.viewType ?? 'Text'),
            type: property?.source,
            order: column.order ?? property?.order,
            configuration: column.configuration,
            propertyConfiguration: property?.configuration ?? undefined,
            comparison: cell?.comparison,
        };
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EntityListField, deps: [], target: i0.ɵɵFactoryTarget.Component });
    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=\"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]=\"'components.entityListField.add' | transloco\"\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      {{ \"components.entityListField.readingNotAllowed\" | transloco }}\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      {{ \"components.entityListField.saveFormFirst\" | transloco }}\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      {{ \"components.entityListField.noRelatedItems\" | transloco }}\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"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EntityListField, decorators: [{
            type: Component,
            args: [{ selector: 'mt-entity-list-field', standalone: true, imports: [
                        CommonModule,
                        FieldValidation,
                        Skeleton,
                        Message,
                        Table,
                        Button,
                        TranslocoPipe,
                    ], changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'grid gap-1' }, template: "<div class=\"flex flex-col gap-2\">\r\n  @if (label()) {\r\n    <label class=\"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]=\"'components.entityListField.add' | transloco\"\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      {{ \"components.entityListField.readingNotAllowed\" | transloco }}\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      {{ \"components.entityListField.saveFormFirst\" | transloco }}\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      {{ \"components.entityListField.noRelatedItems\" | transloco }}\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"] }]
        }], 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 }] }] } });

/**
 * Generated bundle index. Do not edit.
 */

export { ENTITY_LIST_ADD_DIALOG_COMPONENT, EntityListField, LookupMatrixField, SchedulePredecessorField, SchemaConnectionField };
//# sourceMappingURL=masterteam-components-business-fields.mjs.map
