import * as i0 from '@angular/core';
import { input, computed, ChangeDetectionStrategy, Component, inject, signal, effect, ElementRef, NgZone, output, Directive, model } from '@angular/core';
import { TruncateTooltip } from '@masterteam/components/tooltip';
import { HttpContext, HttpClient } from '@angular/common/http';
import { Avatar } from '@masterteam/components/avatar';
import { Button } from '@masterteam/components/button';
import { SecureImagePipe, UploadField } from '@masterteam/components/upload-field';
import { REQUEST_CONTEXT } from '@masterteam/components';
import { Progress } from '@masterteam/components/progress';
import * as i1 from '@angular/forms';
import { FormsModule } from '@angular/forms';
import { forkJoin, finalize, of, take, switchMap, EMPTY, map, catchError } from 'rxjs';
import { CdkDrag, CdkDropList, CdkDragPlaceholder } from '@angular/cdk/drag-drop';
import { DOCUMENT } from '@angular/common';

const ENTITY_EMPTY_VALUE_PLACEHOLDER = '_';
function isValueMissing(value) {
    if (value === null || value === undefined) {
        return true;
    }
    if (typeof value === 'string') {
        return value.trim().length === 0;
    }
    return false;
}
function displayOrPlaceholder(value) {
    if (isValueMissing(value)) {
        return ENTITY_EMPTY_VALUE_PLACEHOLDER;
    }
    return String(value);
}
function isEntityLabelHidden(configuration) {
    const config = configuration;
    return config?.hideLabel ?? config?.hideName ?? false;
}
function resolveEntityLabelPosition(configuration) {
    const config = configuration;
    return config?.labelPosition ?? config?.labelPostion ?? 'bottom';
}

class EntityField {
    label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
    configuration = input(...(ngDevMode ? [undefined, { debugName: "configuration" }] : []));
    gap = input('compact', ...(ngDevMode ? [{ debugName: "gap" }] : []));
    hideLabel = computed(() => isEntityLabelHidden(this.configuration()), ...(ngDevMode ? [{ debugName: "hideLabel" }] : []));
    labelPosition = computed(() => resolveEntityLabelPosition(this.configuration()), ...(ngDevMode ? [{ debugName: "labelPosition" }] : []));
    containerClass = computed(() => {
        const gapClass = this.gap() === 'relaxed'
            ? 'gap-2'
            : this.gap() === 'normal'
                ? 'gap-1'
                : 'gap-0.5';
        const directionClass = this.labelPosition() === 'top' ? 'flex-col-reverse' : 'flex-col';
        return `flex min-w-0 ${directionClass} ${gapClass}`;
    }, ...(ngDevMode ? [{ debugName: "containerClass" }] : []));
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityField, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: EntityField, isStandalone: true, selector: "mt-entity-field", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, configuration: { classPropertyName: "configuration", publicName: "configuration", isSignal: true, isRequired: false, transformFunction: null }, gap: { classPropertyName: "gap", publicName: "gap", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "block min-w-0 w-full" }, ngImport: i0, template: `
    <div [class]="containerClass()">
      <ng-content />
      @if (!hideLabel()) {
        <span
          class="block min-w-0 truncate text-sm text-gray-500"
          mtTruncateTooltip
          tooltipPosition="top"
        >
          {{ label() }}
        </span>
      }
    </div>
  `, isInline: true, dependencies: [{ kind: "directive", type: TruncateTooltip, selector: "[mtTruncateTooltip]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityField, decorators: [{
            type: Component,
            args: [{
                    selector: 'mt-entity-field',
                    changeDetection: ChangeDetectionStrategy.OnPush,
                    imports: [TruncateTooltip],
                    template: `
    <div [class]="containerClass()">
      <ng-content />
      @if (!hideLabel()) {
        <span
          class="block min-w-0 truncate text-sm text-gray-500"
          mtTruncateTooltip
          tooltipPosition="top"
        >
          {{ label() }}
        </span>
      }
    </div>
  `,
                    host: {
                        class: 'block min-w-0 w-full',
                    },
                }]
        }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], configuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "configuration", required: false }] }], gap: [{ type: i0.Input, args: [{ isSignal: true, alias: "gap", required: false }] }] } });

class EntityText {
    /** Full entity data object */
    data = input(...(ngDevMode ? [undefined, { debugName: "data" }] : []));
    /** Individual inputs (used when data is not provided) */
    name = input(...(ngDevMode ? [undefined, { debugName: "name" }] : []));
    value = input(...(ngDevMode ? [undefined, { debugName: "value" }] : []));
    displayName = computed(() => this.data()?.name ?? this.name() ?? '', ...(ngDevMode ? [{ debugName: "displayName" }] : []));
    displayValue = computed(() => {
        const d = this.data();
        if (d) {
            return displayOrPlaceholder(typeof d.value === 'string' ? d.value : null);
        }
        return displayOrPlaceholder(this.value());
    }, ...(ngDevMode ? [{ debugName: "displayValue" }] : []));
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityText, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.3", type: EntityText, isStandalone: true, selector: "mt-entity-text", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<mt-entity-field\n  [label]=\"displayName()\"\n  [configuration]=\"data()?.configuration\"\n>\n  <div\n    class=\"min-w-0 truncate text-sm font-semibold\"\n    mtTruncateTooltip\n    tooltipPosition=\"top\"\n    [innerHTML]=\"displayValue()\"\n  ></div>\n</mt-entity-field>\n", dependencies: [{ kind: "component", type: EntityField, selector: "mt-entity-field", inputs: ["label", "configuration", "gap"] }, { kind: "directive", type: TruncateTooltip, selector: "[mtTruncateTooltip]" }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityText, decorators: [{
            type: Component,
            args: [{ selector: 'mt-entity-text', standalone: true, imports: [EntityField, TruncateTooltip], template: "<mt-entity-field\n  [label]=\"displayName()\"\n  [configuration]=\"data()?.configuration\"\n>\n  <div\n    class=\"min-w-0 truncate text-sm font-semibold\"\n    mtTruncateTooltip\n    tooltipPosition=\"top\"\n    [innerHTML]=\"displayValue()\"\n  ></div>\n</mt-entity-field>\n" }]
        }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }] } });

class EntityDate {
    /** Full entity data object */
    data = input(...(ngDevMode ? [undefined, { debugName: "data" }] : []));
    /** Individual inputs (used when data is not provided) */
    name = input(...(ngDevMode ? [undefined, { debugName: "name" }] : []));
    value = input(...(ngDevMode ? [undefined, { debugName: "value" }] : []));
    displayName = computed(() => this.data()?.name ?? this.name() ?? '', ...(ngDevMode ? [{ debugName: "displayName" }] : []));
    displayValue = computed(() => {
        const d = this.data();
        if (d) {
            return displayOrPlaceholder(typeof d.value === 'string' ? d.value : null);
        }
        return displayOrPlaceholder(this.value());
    }, ...(ngDevMode ? [{ debugName: "displayValue" }] : []));
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityDate, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.3", type: EntityDate, isStandalone: true, selector: "mt-entity-date", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<mt-entity-field\n  [label]=\"displayName()\"\n  [configuration]=\"data()?.configuration\"\n>\n  <span\n    class=\"block min-w-0 truncate text-sm font-semibold\"\n    mtTruncateTooltip\n    tooltipPosition=\"top\"\n  >\n    {{ displayValue() }}\n  </span>\n</mt-entity-field>\n", dependencies: [{ kind: "component", type: EntityField, selector: "mt-entity-field", inputs: ["label", "configuration", "gap"] }, { kind: "directive", type: TruncateTooltip, selector: "[mtTruncateTooltip]" }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityDate, decorators: [{
            type: Component,
            args: [{ selector: 'mt-entity-date', standalone: true, imports: [EntityField, TruncateTooltip], template: "<mt-entity-field\n  [label]=\"displayName()\"\n  [configuration]=\"data()?.configuration\"\n>\n  <span\n    class=\"block min-w-0 truncate text-sm font-semibold\"\n    mtTruncateTooltip\n    tooltipPosition=\"top\"\n  >\n    {{ displayValue() }}\n  </span>\n</mt-entity-field>\n" }]
        }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }] } });

class EntityStatus {
    /** Full entity data object */
    data = input(...(ngDevMode ? [undefined, { debugName: "data" }] : []));
    /** Individual inputs (used when data is not provided) */
    name = input(...(ngDevMode ? [undefined, { debugName: "name" }] : []));
    value = input(...(ngDevMode ? [undefined, { debugName: "value" }] : []));
    displayName = computed(() => this.data()?.name ?? this.name() ?? '', ...(ngDevMode ? [{ debugName: "displayName" }] : []));
    statusValue = computed(() => {
        const d = this.data();
        if (d && typeof d.value === 'object' && d.value !== null) {
            return d.value;
        }
        return this.value() ?? null;
    }, ...(ngDevMode ? [{ debugName: "statusValue" }] : []));
    badgeStyle = computed(() => {
        const status = this.statusValue();
        if (!status?.color)
            return {};
        return {
            color: status.color,
            backgroundColor: this.hexToRgba(status.color, 0.12),
        };
    }, ...(ngDevMode ? [{ debugName: "badgeStyle" }] : []));
    emptyLabel = ENTITY_EMPTY_VALUE_PLACEHOLDER;
    statusLabel = computed(() => displayOrPlaceholder(this.statusValue()?.display), ...(ngDevMode ? [{ debugName: "statusLabel" }] : []));
    hexToRgba(hex, alpha) {
        const r = parseInt(hex.slice(1, 3), 16);
        const g = parseInt(hex.slice(3, 5), 16);
        const b = parseInt(hex.slice(5, 7), 16);
        return `rgba(${r}, ${g}, ${b}, ${alpha})`;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityStatus, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: EntityStatus, isStandalone: true, selector: "mt-entity-status", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<mt-entity-field\n  [label]=\"displayName()\"\n  [configuration]=\"data()?.configuration\"\n  gap=\"normal\"\n>\n  @if (statusValue(); as status) {\n    <span\n      class=\"inline-flex items-center px-3 py-2 rounded-md text-xs font-semibold w-fit\"\n      [style]=\"badgeStyle()\"\n    >\n      {{ statusLabel() }}\n    </span>\n  } @else {\n    <span\n      class=\"inline-flex items-center px-3 py-2 rounded-md text-xs font-semibold w-fit text-gray-500 bg-gray-100\"\n    >\n      {{ emptyLabel }}\n    </span>\n  }\n</mt-entity-field>\n", dependencies: [{ kind: "component", type: EntityField, selector: "mt-entity-field", inputs: ["label", "configuration", "gap"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityStatus, decorators: [{
            type: Component,
            args: [{ selector: 'mt-entity-status', standalone: true, imports: [EntityField], template: "<mt-entity-field\n  [label]=\"displayName()\"\n  [configuration]=\"data()?.configuration\"\n  gap=\"normal\"\n>\n  @if (statusValue(); as status) {\n    <span\n      class=\"inline-flex items-center px-3 py-2 rounded-md text-xs font-semibold w-fit\"\n      [style]=\"badgeStyle()\"\n    >\n      {{ statusLabel() }}\n    </span>\n  } @else {\n    <span\n      class=\"inline-flex items-center px-3 py-2 rounded-md text-xs font-semibold w-fit text-gray-500 bg-gray-100\"\n    >\n      {{ emptyLabel }}\n    </span>\n  }\n</mt-entity-field>\n" }]
        }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }] } });

class EntityUser {
    httpContext = new HttpContext().set(REQUEST_CONTEXT, {
        useBaseUrl: true,
    });
    /** Full entity data object */
    data = input(...(ngDevMode ? [undefined, { debugName: "data" }] : []));
    /** Resolved user value object from data().value */
    userValue = computed(() => {
        const val = this.data()?.value;
        if (val && typeof val === 'object' && 'displayName' in val) {
            return val;
        }
        return null;
    }, ...(ngDevMode ? [{ debugName: "userValue" }] : []));
    rawUserName = computed(() => this.userValue()?.displayName ?? null, ...(ngDevMode ? [{ debugName: "rawUserName" }] : []));
    userName = computed(() => displayOrPlaceholder(this.rawUserName()), ...(ngDevMode ? [{ debugName: "userName" }] : []));
    userPhoto = computed(() => this.userValue()?.photoUrl ?? '', ...(ngDevMode ? [{ debugName: "userPhoto" }] : []));
    labelText = computed(() => this.userValue()?.name ?? '', ...(ngDevMode ? [{ debugName: "labelText" }] : []));
    // ── Configuration-driven visibility ──
    config = computed(() => this.data()?.configuration ?? {}, ...(ngDevMode ? [{ debugName: "config" }] : []));
    showDisplayName = computed(() => this.config().showDisplayName ?? true, ...(ngDevMode ? [{ debugName: "showDisplayName" }] : []));
    showPhoneNumber = computed(() => this.config().showPhoneNumber ?? false, ...(ngDevMode ? [{ debugName: "showPhoneNumber" }] : []));
    showEmail = computed(() => this.config().showEmail ?? false, ...(ngDevMode ? [{ debugName: "showEmail" }] : []));
    phoneNumber = computed(() => this.userValue()?.phoneNumber ?? '', ...(ngDevMode ? [{ debugName: "phoneNumber" }] : []));
    email = computed(() => this.userValue()?.email ?? '', ...(ngDevMode ? [{ debugName: "email" }] : []));
    hasContactInfo = computed(() => (this.showPhoneNumber() && !!this.phoneNumber()) ||
        (this.showEmail() && !!this.email()), ...(ngDevMode ? [{ debugName: "hasContactInfo" }] : []));
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityUser, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: EntityUser, isStandalone: true, selector: "mt-entity-user", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"flex items-center gap-2\">\r\n  <mt-avatar\r\n    [image]=\"\r\n      userPhoto()\r\n        ? (userPhoto() | secureImage: true : httpContext : 'avatar/')\r\n        : ''\r\n    \"\r\n    [icon]=\"'user.user-01'\"\r\n    styleClass=\"w-10! h-10! text-white! text-xl!  bg-primary-500!\"\r\n  ></mt-avatar>\r\n\r\n  @if (showDisplayName()) {\r\n    <div class=\"flex flex-col min-w-0 flex-1\">\r\n      <span class=\"text-sm text-gray-700 truncate\">{{ userName() }}</span>\r\n      @if (labelText()) {\r\n        <span class=\"text-xs text-gray-500 truncate\">{{ labelText() }}</span>\r\n      }\r\n    </div>\r\n  }\r\n\r\n  @if (hasContactInfo()) {\r\n    <div class=\"flex items-center gap-1 ms-auto shrink-0\">\r\n      @if (showPhoneNumber() && phoneNumber()) {\r\n        <a [href]=\"'tel:' + phoneNumber()\" [title]=\"phoneNumber()\">\r\n          <mt-button\r\n            icon=\"communication.phone\"\r\n            [rounded]=\"true\"\r\n            [text]=\"true\"\r\n            severity=\"secondary\"\r\n            size=\"small\"\r\n            [tooltip]=\"phoneNumber()\"\r\n          />\r\n        </a>\r\n      }\r\n      @if (showEmail() && email()) {\r\n        <a [href]=\"'mailto:' + email()\" [title]=\"email()\">\r\n          <mt-button\r\n            icon=\"communication.mail-01\"\r\n            [rounded]=\"true\"\r\n            [text]=\"true\"\r\n            severity=\"secondary\"\r\n            size=\"small\"\r\n            [tooltip]=\"email()\"\r\n          />\r\n        </a>\r\n      }\r\n    </div>\r\n  }\r\n</div>\r\n", dependencies: [{ kind: "component", type: Avatar, selector: "mt-avatar", inputs: ["label", "icon", "image", "styleClass", "size", "shape", "badge", "badgeSize", "badgeSeverity"], outputs: ["onImageError"] }, { 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: SecureImagePipe, name: "secureImage" }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityUser, decorators: [{
            type: Component,
            args: [{ selector: 'mt-entity-user', standalone: true, imports: [Avatar, Button, SecureImagePipe], template: "<div class=\"flex items-center gap-2\">\r\n  <mt-avatar\r\n    [image]=\"\r\n      userPhoto()\r\n        ? (userPhoto() | secureImage: true : httpContext : 'avatar/')\r\n        : ''\r\n    \"\r\n    [icon]=\"'user.user-01'\"\r\n    styleClass=\"w-10! h-10! text-white! text-xl!  bg-primary-500!\"\r\n  ></mt-avatar>\r\n\r\n  @if (showDisplayName()) {\r\n    <div class=\"flex flex-col min-w-0 flex-1\">\r\n      <span class=\"text-sm text-gray-700 truncate\">{{ userName() }}</span>\r\n      @if (labelText()) {\r\n        <span class=\"text-xs text-gray-500 truncate\">{{ labelText() }}</span>\r\n      }\r\n    </div>\r\n  }\r\n\r\n  @if (hasContactInfo()) {\r\n    <div class=\"flex items-center gap-1 ms-auto shrink-0\">\r\n      @if (showPhoneNumber() && phoneNumber()) {\r\n        <a [href]=\"'tel:' + phoneNumber()\" [title]=\"phoneNumber()\">\r\n          <mt-button\r\n            icon=\"communication.phone\"\r\n            [rounded]=\"true\"\r\n            [text]=\"true\"\r\n            severity=\"secondary\"\r\n            size=\"small\"\r\n            [tooltip]=\"phoneNumber()\"\r\n          />\r\n        </a>\r\n      }\r\n      @if (showEmail() && email()) {\r\n        <a [href]=\"'mailto:' + email()\" [title]=\"email()\">\r\n          <mt-button\r\n            icon=\"communication.mail-01\"\r\n            [rounded]=\"true\"\r\n            [text]=\"true\"\r\n            severity=\"secondary\"\r\n            size=\"small\"\r\n            [tooltip]=\"email()\"\r\n          />\r\n        </a>\r\n      }\r\n    </div>\r\n  }\r\n</div>\r\n" }]
        }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }] } });

class EntityPercentage {
    /** Full entity data object */
    data = input(...(ngDevMode ? [undefined, { debugName: "data" }] : []));
    /** Individual inputs (used when data is not provided) */
    name = input(...(ngDevMode ? [undefined, { debugName: "name" }] : []));
    value = input(...(ngDevMode ? [undefined, { debugName: "value" }] : []));
    rawValue = input(...(ngDevMode ? [undefined, { debugName: "rawValue" }] : []));
    displayName = computed(() => this.data()?.name ?? this.name() ?? '', ...(ngDevMode ? [{ debugName: "displayName" }] : []));
    displayValue = computed(() => {
        const d = this.data();
        if (d) {
            return displayOrPlaceholder(typeof d.value === 'string' ? d.value : null);
        }
        return displayOrPlaceholder(this.value());
    }, ...(ngDevMode ? [{ debugName: "displayValue" }] : []));
    rawNumericValue = computed(() => this.data()?.rawValue ??
        this.rawValue() ??
        this.value() ??
        this.displayValue(), ...(ngDevMode ? [{ debugName: "rawNumericValue" }] : []));
    hasNumericValue = computed(() => {
        return this.parseNumericValue(this.rawNumericValue()) !== null;
    }, ...(ngDevMode ? [{ debugName: "hasNumericValue" }] : []));
    numericValue = computed(() => {
        const num = this.parseNumericValue(this.rawNumericValue());
        return num === null ? 0 : Math.min(num, 100);
    }, ...(ngDevMode ? [{ debugName: "numericValue" }] : []));
    maxValue = computed(() => {
        const num = this.parseNumericValue(this.rawNumericValue());
        if (num === null)
            return 100;
        return num > 100 ? Math.ceil(num) : 100;
    }, ...(ngDevMode ? [{ debugName: "maxValue" }] : []));
    // ── Configuration-driven visibility ──
    hideName = computed(() => isEntityLabelHidden(this.data()?.configuration), ...(ngDevMode ? [{ debugName: "hideName" }] : []));
    progressColor = computed(() => {
        const configuration = this.data()?.configuration;
        return configuration?.color?.trim() || 'primary';
    }, ...(ngDevMode ? [{ debugName: "progressColor" }] : []));
    parseNumericValue(raw) {
        if (isValueMissing(raw)) {
            return null;
        }
        const normalizedRawValue = String(raw).replace(/%/g, '').trim();
        if (!normalizedRawValue) {
            return null;
        }
        const numericValue = Number.parseFloat(normalizedRawValue);
        return Number.isNaN(numericValue) ? null : numericValue;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityPercentage, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: EntityPercentage, isStandalone: true, selector: "mt-entity-percentage", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, rawValue: { classPropertyName: "rawValue", publicName: "rawValue", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"flex flex-col gap-1\">\r\n  <div class=\"flex items-center justify-between\">\r\n    @if (!hideName()) {\r\n      <span class=\"text-xs font-semibold\">{{ displayName() }}</span>\r\n    }\r\n    <span class=\"text-xs font-bold\" [class.ms-auto]=\"hideName()\">{{\r\n      displayValue()\r\n    }}</span>\r\n  </div>\r\n  @if (hasNumericValue()) {\r\n    <mt-progress\r\n      [value]=\"numericValue()\"\r\n      [showLabel]=\"false\"\r\n      [height]=\"9\"\r\n      [maxValue]=\"maxValue()\"\r\n      [color]=\"progressColor()\"\r\n    >\r\n    </mt-progress>\r\n  } @else {\r\n    <div class=\"h-[9px] rounded-full bg-gray-200\"></div>\r\n  }\r\n</div>\r\n", dependencies: [{ kind: "component", type: Progress, selector: "mt-progress", inputs: ["value", "mode", "showLabel", "unit", "color", "minValue", "maxValue", "height", "circleSize", "strokeWidth", "customClass"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityPercentage, decorators: [{
            type: Component,
            args: [{ selector: 'mt-entity-percentage', standalone: true, imports: [Progress], template: "<div class=\"flex flex-col gap-1\">\r\n  <div class=\"flex items-center justify-between\">\r\n    @if (!hideName()) {\r\n      <span class=\"text-xs font-semibold\">{{ displayName() }}</span>\r\n    }\r\n    <span class=\"text-xs font-bold\" [class.ms-auto]=\"hideName()\">{{\r\n      displayValue()\r\n    }}</span>\r\n  </div>\r\n  @if (hasNumericValue()) {\r\n    <mt-progress\r\n      [value]=\"numericValue()\"\r\n      [showLabel]=\"false\"\r\n      [height]=\"9\"\r\n      [maxValue]=\"maxValue()\"\r\n      [color]=\"progressColor()\"\r\n    >\r\n    </mt-progress>\r\n  } @else {\r\n    <div class=\"h-[9px] rounded-full bg-gray-200\"></div>\r\n  }\r\n</div>\r\n" }]
        }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], rawValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "rawValue", required: false }] }] } });

class EntityCurrency {
    /** Full entity data object */
    data = input(...(ngDevMode ? [undefined, { debugName: "data" }] : []));
    /** Individual inputs (used when data is not provided) */
    name = input(...(ngDevMode ? [undefined, { debugName: "name" }] : []));
    value = input(...(ngDevMode ? [undefined, { debugName: "value" }] : []));
    displayName = computed(() => this.data()?.name ?? this.name() ?? '', ...(ngDevMode ? [{ debugName: "displayName" }] : []));
    displayValue = computed(() => {
        const d = this.data();
        if (d) {
            return displayOrPlaceholder(typeof d.value === 'string' ? d.value : null);
        }
        return displayOrPlaceholder(this.value());
    }, ...(ngDevMode ? [{ debugName: "displayValue" }] : []));
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityCurrency, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.3", type: EntityCurrency, isStandalone: true, selector: "mt-entity-currency", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<mt-entity-field\n  [label]=\"displayName()\"\n  [configuration]=\"data()?.configuration\"\n>\n  <span\n    class=\"block min-w-0 truncate text-sm font-semibold\"\n    mtTruncateTooltip\n    tooltipPosition=\"top\"\n  >\n    {{ displayValue() }}\n  </span>\n</mt-entity-field>\n", dependencies: [{ kind: "component", type: EntityField, selector: "mt-entity-field", inputs: ["label", "configuration", "gap"] }, { kind: "directive", type: TruncateTooltip, selector: "[mtTruncateTooltip]" }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityCurrency, decorators: [{
            type: Component,
            args: [{ selector: 'mt-entity-currency', standalone: true, imports: [EntityField, TruncateTooltip], template: "<mt-entity-field\n  [label]=\"displayName()\"\n  [configuration]=\"data()?.configuration\"\n>\n  <span\n    class=\"block min-w-0 truncate text-sm font-semibold\"\n    mtTruncateTooltip\n    tooltipPosition=\"top\"\n  >\n    {{ displayValue() }}\n  </span>\n</mt-entity-field>\n" }]
        }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }] } });

class EntityCheckbox {
    /** Full entity data object */
    data = input(...(ngDevMode ? [undefined, { debugName: "data" }] : []));
    /** Individual inputs (used when data is not provided) */
    name = input(...(ngDevMode ? [undefined, { debugName: "name" }] : []));
    value = input(...(ngDevMode ? [undefined, { debugName: "value" }] : []));
    rawValue = input(...(ngDevMode ? [undefined, { debugName: "rawValue" }] : []));
    displayName = computed(() => this.data()?.name ?? this.name() ?? '', ...(ngDevMode ? [{ debugName: "displayName" }] : []));
    emptyLabel = ENTITY_EMPTY_VALUE_PLACEHOLDER;
    hideName = computed(() => isEntityLabelHidden(this.data()?.configuration), ...(ngDevMode ? [{ debugName: "hideName" }] : []));
    checkboxState = computed(() => {
        const raw = this.data()?.rawValue ?? this.rawValue();
        if (raw !== undefined && raw !== null) {
            return this.parseBoolean(raw);
        }
        const val = this.data()?.value ?? this.value();
        if (typeof val === 'string') {
            return this.parseBoolean(val);
        }
        return null;
    }, ...(ngDevMode ? [{ debugName: "checkboxState" }] : []));
    parseBoolean(value) {
        const normalized = value.trim().toLowerCase();
        if (!normalized.length) {
            return null;
        }
        if (normalized === 'true') {
            return true;
        }
        if (normalized === 'false') {
            return false;
        }
        return null;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityCheckbox, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: EntityCheckbox, isStandalone: true, selector: "mt-entity-checkbox", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, rawValue: { classPropertyName: "rawValue", publicName: "rawValue", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"flex items-center gap-2\">\r\n  @if (checkboxState() === true) {\r\n    <svg class=\"w-5 h-5 text-green-500\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\r\n      <path\r\n        fill-rule=\"evenodd\"\r\n        d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z\"\r\n        clip-rule=\"evenodd\"\r\n      />\r\n    </svg>\r\n  } @else if (checkboxState() === false) {\r\n    <svg class=\"w-5 h-5 text-gray-300\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\r\n      <path\r\n        fill-rule=\"evenodd\"\r\n        d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm-1-5.414l-2.293-2.293a1 1 0 011.414-1.414L10 11.172l3.879-3.879a1 1 0 111.414 1.414L10 13.414l-.707-.707-.293-.293z\"\r\n        clip-rule=\"evenodd\"\r\n      />\r\n    </svg>\r\n  } @else {\r\n    <span\r\n      class=\"inline-flex h-5 min-w-5 items-center justify-center rounded-full bg-gray-100 px-1 text-[10px] font-semibold text-gray-500\"\r\n    >\r\n      {{ emptyLabel }}\r\n    </span>\r\n  }\r\n  @if (!hideName()) {\r\n    <span class=\"text-sm font-semibold\">{{ displayName() }}</span>\r\n  }\r\n</div>\r\n" });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityCheckbox, decorators: [{
            type: Component,
            args: [{ selector: 'mt-entity-checkbox', standalone: true, template: "<div class=\"flex items-center gap-2\">\r\n  @if (checkboxState() === true) {\r\n    <svg class=\"w-5 h-5 text-green-500\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\r\n      <path\r\n        fill-rule=\"evenodd\"\r\n        d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z\"\r\n        clip-rule=\"evenodd\"\r\n      />\r\n    </svg>\r\n  } @else if (checkboxState() === false) {\r\n    <svg class=\"w-5 h-5 text-gray-300\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\r\n      <path\r\n        fill-rule=\"evenodd\"\r\n        d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm-1-5.414l-2.293-2.293a1 1 0 011.414-1.414L10 11.172l3.879-3.879a1 1 0 111.414 1.414L10 13.414l-.707-.707-.293-.293z\"\r\n        clip-rule=\"evenodd\"\r\n      />\r\n    </svg>\r\n  } @else {\r\n    <span\r\n      class=\"inline-flex h-5 min-w-5 items-center justify-center rounded-full bg-gray-100 px-1 text-[10px] font-semibold text-gray-500\"\r\n    >\r\n      {{ emptyLabel }}\r\n    </span>\r\n  }\r\n  @if (!hideName()) {\r\n    <span class=\"text-sm font-semibold\">{{ displayName() }}</span>\r\n  }\r\n</div>\r\n" }]
        }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], rawValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "rawValue", required: false }] }] } });

class EntityLongText {
    /** Full entity data object */
    data = input(...(ngDevMode ? [undefined, { debugName: "data" }] : []));
    /** Individual inputs (used when data is not provided) */
    name = input(...(ngDevMode ? [undefined, { debugName: "name" }] : []));
    value = input(...(ngDevMode ? [undefined, { debugName: "value" }] : []));
    displayName = computed(() => this.data()?.name ?? this.name() ?? '', ...(ngDevMode ? [{ debugName: "displayName" }] : []));
    displayValue = computed(() => {
        const d = this.data();
        const raw = d
            ? typeof d.value === 'string'
                ? d.value
                : null
            : this.value();
        if (isValueMissing(raw)) {
            return ENTITY_EMPTY_VALUE_PLACEHOLDER;
        }
        return raw;
    }, ...(ngDevMode ? [{ debugName: "displayValue" }] : []));
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityLongText, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.3", type: EntityLongText, isStandalone: true, selector: "mt-entity-long-text", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<mt-entity-field\n  [label]=\"displayName()\"\n  [configuration]=\"data()?.configuration\"\n>\n  <div class=\"text-sm font-semibold\" [innerHTML]=\"displayValue()\"></div>\n</mt-entity-field>\n", dependencies: [{ kind: "component", type: EntityField, selector: "mt-entity-field", inputs: ["label", "configuration", "gap"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityLongText, decorators: [{
            type: Component,
            args: [{ selector: 'mt-entity-long-text', standalone: true, imports: [EntityField], template: "<mt-entity-field\n  [label]=\"displayName()\"\n  [configuration]=\"data()?.configuration\"\n>\n  <div class=\"text-sm font-semibold\" [innerHTML]=\"displayValue()\"></div>\n</mt-entity-field>\n" }]
        }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }] } });

class EntityLookup {
    /** Full entity data object */
    data = input(...(ngDevMode ? [undefined, { debugName: "data" }] : []));
    /** Individual inputs (used when data is not provided) */
    name = input(...(ngDevMode ? [undefined, { debugName: "name" }] : []));
    value = input(...(ngDevMode ? [undefined, { debugName: "value" }] : []));
    displayName = computed(() => this.data()?.name ?? this.name() ?? '', ...(ngDevMode ? [{ debugName: "displayName" }] : []));
    lookupValue = computed(() => {
        const d = this.data();
        if (d && typeof d.value === 'object' && d.value !== null) {
            return d.value;
        }
        return this.value() ?? null;
    }, ...(ngDevMode ? [{ debugName: "lookupValue" }] : []));
    badgeStyle = computed(() => {
        const lookup = this.lookupValue();
        if (!lookup?.color)
            return {};
        return {
            color: lookup.color,
            backgroundColor: this.hexToRgba(lookup.color, 0.12),
        };
    }, ...(ngDevMode ? [{ debugName: "badgeStyle" }] : []));
    emptyLabel = ENTITY_EMPTY_VALUE_PLACEHOLDER;
    lookupLabel = computed(() => displayOrPlaceholder(this.lookupValue()?.display), ...(ngDevMode ? [{ debugName: "lookupLabel" }] : []));
    hexToRgba(hex, alpha) {
        const r = parseInt(hex.slice(1, 3), 16);
        const g = parseInt(hex.slice(3, 5), 16);
        const b = parseInt(hex.slice(5, 7), 16);
        return `rgba(${r}, ${g}, ${b}, ${alpha})`;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityLookup, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: EntityLookup, isStandalone: true, selector: "mt-entity-lookup", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<mt-entity-field\n  [label]=\"displayName()\"\n  [configuration]=\"data()?.configuration\"\n  gap=\"normal\"\n>\n  @if (lookupValue(); as lookup) {\n    <span\n      class=\"inline-flex items-center px-3 py-2 rounded-md text-xs font-semibold w-fit\"\n      [style]=\"badgeStyle()\"\n    >\n      {{ lookupLabel() }}\n    </span>\n  } @else {\n    <span\n      class=\"inline-flex items-center px-3 py-2 rounded-md text-xs font-semibold w-fit text-gray-500 bg-gray-100\"\n    >\n      {{ emptyLabel }}\n    </span>\n  }\n</mt-entity-field>\n", dependencies: [{ kind: "component", type: EntityField, selector: "mt-entity-field", inputs: ["label", "configuration", "gap"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityLookup, decorators: [{
            type: Component,
            args: [{ selector: 'mt-entity-lookup', standalone: true, imports: [EntityField], template: "<mt-entity-field\n  [label]=\"displayName()\"\n  [configuration]=\"data()?.configuration\"\n  gap=\"normal\"\n>\n  @if (lookupValue(); as lookup) {\n    <span\n      class=\"inline-flex items-center px-3 py-2 rounded-md text-xs font-semibold w-fit\"\n      [style]=\"badgeStyle()\"\n    >\n      {{ lookupLabel() }}\n    </span>\n  } @else {\n    <span\n      class=\"inline-flex items-center px-3 py-2 rounded-md text-xs font-semibold w-fit text-gray-500 bg-gray-100\"\n    >\n      {{ emptyLabel }}\n    </span>\n  }\n</mt-entity-field>\n" }]
        }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }] } });

class EntityAttachment {
    data = input(...(ngDevMode ? [undefined, { debugName: "data" }] : []));
    name = input(...(ngDevMode ? [undefined, { debugName: "name" }] : []));
    shape = input('default', ...(ngDevMode ? [{ debugName: "shape" }] : []));
    value = input(...(ngDevMode ? [undefined, { debugName: "value" }] : []));
    endPoint = input('uploader', ...(ngDevMode ? [{ debugName: "endPoint" }] : []));
    context = input(undefined, ...(ngDevMode ? [{ debugName: "context" }] : []));
    httpClient = inject(HttpClient);
    displayName = computed(() => this.data()?.name ?? this.name() ?? '', ...(ngDevMode ? [{ debugName: "displayName" }] : []));
    loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
    attachments = signal([], ...(ngDevMode ? [{ debugName: "attachments" }] : []));
    attachmentReferences = computed(() => this.normalizeAttachmentValue(this.data()?.value ?? this.value()), ...(ngDevMode ? [{ debugName: "attachmentReferences" }] : []));
    uploadValue = computed(() => {
        const references = this.attachmentReferences().map((reference) => {
            if (typeof reference === 'string') {
                return reference.trim();
            }
            if (reference.fileName) {
                return reference;
            }
            return reference.id?.trim() || reference;
        });
        if (!references.length) {
            return null;
        }
        return references.length === 1 ? references[0] : references;
    }, ...(ngDevMode ? [{ debugName: "uploadValue" }] : []));
    hasAttachments = computed(() => this.shape() === 'compact'
        ? this.attachments().length > 0
        : this.uploadValue() != null, ...(ngDevMode ? [{ debugName: "hasAttachments" }] : []));
    isMultiple = computed(() => this.attachmentReferences().length > 1, ...(ngDevMode ? [{ debugName: "isMultiple" }] : []));
    empty = '-';
    constructor() {
        effect((onCleanup) => {
            if (this.shape() !== 'compact') {
                this.loading.set(false);
                this.attachments.set([]);
                return;
            }
            const references = this.attachmentReferences();
            if (!references.length) {
                this.loading.set(false);
                this.attachments.set([]);
                return;
            }
            const shouldFetchMetadata = references.some((reference) => this.requiresMetadataRequest(reference));
            if (!shouldFetchMetadata) {
                this.attachments.set(references.filter(this.isAttachmentItemValue).map((reference) => ({
                    ...reference,
                    name: reference.name ??
                        reference.fileName ??
                        reference.id ??
                        reference.name,
                    extension: this.resolveExtension(reference),
                })));
                this.loading.set(false);
                return;
            }
            this.loading.set(true);
            const sub = forkJoin(references.map((reference) => this.resolveAttachment$(reference)))
                .pipe(finalize(() => this.loading.set(false)))
                .subscribe((attachments) => {
                this.attachments.set(attachments.filter((attachment) => attachment != null));
            });
            onCleanup(() => sub.unsubscribe());
        });
    }
    attachmentTrackBy(index, attachment) {
        return (attachment.id ?? attachment.fileName ?? attachment.name ?? String(index));
    }
    attachmentTooltip(attachment) {
        return (attachment.name ?? attachment.fileName ?? attachment.id ?? 'Attachment');
    }
    attachmentIcon(attachment) {
        const extension = this.resolveExtension(attachment);
        const contentType = attachment.contentType?.toLowerCase() ?? '';
        if (contentType.startsWith('image/')) {
            return 'image.image-03';
        }
        switch (extension) {
            case '.pdf':
                return 'file.file-06';
            case '.doc':
            case '.docx':
            case '.txt':
            case '.rtf':
                return 'file.file-04';
            case '.xls':
            case '.xlsx':
            case '.csv':
                return 'file.file-03';
            case '.ppt':
            case '.pptx':
                return 'file.file-05';
            default:
                return 'file.clipboard-attachment';
        }
    }
    onCompactAttachmentClick(event, attachment) {
        event.stopPropagation();
        this.downloadAttachment(attachment);
    }
    downloadAttachment(attachment) {
        const resolvedAttachment$ = this.requiresMetadataRequest(attachment)
            ? this.resolveAttachment$(attachment)
            : of(this.normalizeAttachmentItem(attachment));
        resolvedAttachment$
            .pipe(take(1), switchMap((resolvedAttachment) => {
            if (!resolvedAttachment?.fileName) {
                return EMPTY;
            }
            return this.httpClient
                .get(`${this.endPoint()}/${resolvedAttachment.fileName}`, {
                responseType: 'blob',
                context: this.context(),
            })
                .pipe(take(1), map((blob) => ({
                attachment: resolvedAttachment,
                blob,
            })));
        }))
            .subscribe(({ attachment, blob }) => {
            const downloadBlob = new Blob([blob], {
                type: attachment.contentType || blob.type || 'application/octet-stream',
            });
            const objectUrl = window.URL.createObjectURL(downloadBlob);
            const anchor = document.createElement('a');
            anchor.href = objectUrl;
            anchor.download =
                attachment.name ??
                    attachment.fileName ??
                    attachment.id ??
                    'attachment';
            anchor.click();
            window.URL.revokeObjectURL(objectUrl);
        });
    }
    resolveAttachment$(reference) {
        const normalizedAttachment = this.normalizeAttachmentItem(reference);
        if (!this.requiresMetadataRequest(reference)) {
            return of(normalizedAttachment);
        }
        const attachmentId = typeof reference === 'string' ? reference.trim() : reference.id?.trim();
        if (!attachmentId) {
            return of(normalizedAttachment);
        }
        return this.httpClient
            .get(`${this.endPoint()}/${attachmentId}/metaData`, {
            context: this.context(),
        })
            .pipe(take(1), map((response) => this.normalizeAttachmentItem(response.data)), catchError(() => of(normalizedAttachment)));
    }
    normalizeAttachmentValue(value) {
        if (value === null || value === undefined) {
            return [];
        }
        if (Array.isArray(value)) {
            return value.flatMap((item) => this.normalizeAttachmentValue(item));
        }
        if (typeof value === 'string') {
            const trimmedValue = value.trim();
            if (!trimmedValue || trimmedValue === '[]') {
                return [];
            }
            if ((trimmedValue.startsWith('[') && trimmedValue.endsWith(']')) ||
                (trimmedValue.startsWith('{') && trimmedValue.endsWith('}'))) {
                try {
                    return this.normalizeAttachmentValue(JSON.parse(trimmedValue));
                }
                catch {
                    return [trimmedValue];
                }
            }
            return [trimmedValue];
        }
        if (typeof value === 'object') {
            return [value];
        }
        return [];
    }
    normalizeAttachmentItem(value) {
        if (!value) {
            return null;
        }
        if (typeof value === 'string') {
            const trimmedValue = value.trim();
            return trimmedValue
                ? {
                    id: trimmedValue,
                    name: trimmedValue,
                }
                : null;
        }
        const normalizedAttachment = {
            ...value,
            name: value.name ?? value.fileName ?? value.id ?? '',
            extension: this.resolveExtension(value),
        };
        return normalizedAttachment.name ||
            normalizedAttachment.fileName ||
            normalizedAttachment.id
            ? normalizedAttachment
            : null;
    }
    requiresMetadataRequest(reference) {
        if (typeof reference === 'string') {
            return reference.trim().length > 0;
        }
        return !!reference.id?.trim() && !reference.fileName;
    }
    isAttachmentItemValue(reference) {
        return typeof reference === 'object' && reference != null;
    }
    resolveExtension(value) {
        const explicitExtension = value.extension?.trim();
        if (explicitExtension) {
            return explicitExtension.startsWith('.')
                ? explicitExtension.toLowerCase()
                : `.${explicitExtension.toLowerCase()}`;
        }
        const fileName = value.fileName ?? value.name;
        if (!fileName || !fileName.includes('.')) {
            return undefined;
        }
        return `.${fileName.split('.').pop().toLowerCase()}`;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityAttachment, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: EntityAttachment, isStandalone: true, selector: "mt-entity-attachment", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, endPoint: { classPropertyName: "endPoint", publicName: "endPoint", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<mt-entity-field\n  [label]=\"displayName()\"\n  [configuration]=\"data()?.configuration\"\n  gap=\"relaxed\"\n>\n  @if (hasAttachments()) {\n    @if (shape() === \"compact\") {\n      <div class=\"flex flex-wrap items-center gap-2\">\n        @for (\n          attachment of attachments();\n          track attachmentTrackBy($index, attachment)\n        ) {\n          <mt-button\n            iconPos=\"top\"\n            size=\"small\"\n            severity=\"secondary\"\n            variant=\"outlined\"\n            [icon]=\"attachmentIcon(attachment)\"\n            [tooltip]=\"attachmentTooltip(attachment)\"\n            styleClass=\"h-9! w-9! rounded-lg!\"\n            (onClick)=\"onCompactAttachmentClick($event, attachment)\"\n          />\n        }\n      </div>\n    } @else {\n      <mt-upload-field\n        class=\"w-full\"\n        [ngModel]=\"uploadValue()\"\n        [ngModelOptions]=\"{ standalone: true }\"\n        [shape]=\"'card'\"\n        [multiple]=\"isMultiple()\"\n        [readonly]=\"true\"\n        [endPoint]=\"endPoint()\"\n        [context]=\"context()\"\n      />\n    }\n  } @else {\n    <span class=\"text-sm font-semibold\">{{ empty }}</span>\n  }\n</mt-entity-field>\n", 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: UploadField, selector: "mt-upload-field", inputs: ["label", "title", "description", "endPoint", "size", "userImgClass", "shape", "multiple", "accept", "isDragging", "fileSizeLimit", "readonly", "context"], outputs: ["isDraggingChange", "onChange"] }, { 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: EntityField, selector: "mt-entity-field", inputs: ["label", "configuration", "gap"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityAttachment, decorators: [{
            type: Component,
            args: [{ selector: 'mt-entity-attachment', standalone: true, imports: [FormsModule, UploadField, Button, EntityField], template: "<mt-entity-field\n  [label]=\"displayName()\"\n  [configuration]=\"data()?.configuration\"\n  gap=\"relaxed\"\n>\n  @if (hasAttachments()) {\n    @if (shape() === \"compact\") {\n      <div class=\"flex flex-wrap items-center gap-2\">\n        @for (\n          attachment of attachments();\n          track attachmentTrackBy($index, attachment)\n        ) {\n          <mt-button\n            iconPos=\"top\"\n            size=\"small\"\n            severity=\"secondary\"\n            variant=\"outlined\"\n            [icon]=\"attachmentIcon(attachment)\"\n            [tooltip]=\"attachmentTooltip(attachment)\"\n            styleClass=\"h-9! w-9! rounded-lg!\"\n            (onClick)=\"onCompactAttachmentClick($event, attachment)\"\n          />\n        }\n      </div>\n    } @else {\n      <mt-upload-field\n        class=\"w-full\"\n        [ngModel]=\"uploadValue()\"\n        [ngModelOptions]=\"{ standalone: true }\"\n        [shape]=\"'card'\"\n        [multiple]=\"isMultiple()\"\n        [readonly]=\"true\"\n        [endPoint]=\"endPoint()\"\n        [context]=\"context()\"\n      />\n    }\n  } @else {\n    <span class=\"text-sm font-semibold\">{{ empty }}</span>\n  }\n</mt-entity-field>\n" }]
        }], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], endPoint: [{ type: i0.Input, args: [{ isSignal: true, alias: "endPoint", required: false }] }], context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: false }] }] } });

class EntityPreview {
    /** Single entity data to display */
    data = input.required(...(ngDevMode ? [{ debugName: "data" }] : []));
    attachmentShape = input('default', ...(ngDevMode ? [{ debugName: "attachmentShape" }] : []));
    previewType = computed(() => {
        const viewType = this.data().viewType;
        return viewType === 'LookupMatrix' ? 'Lookup' : viewType;
    }, ...(ngDevMode ? [{ debugName: "previewType" }] : []));
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityPreview, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: EntityPreview, isStandalone: true, selector: "mt-entity-preview", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, attachmentShape: { classPropertyName: "attachmentShape", publicName: "attachmentShape", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "w-full" }, ngImport: i0, template: "@switch (previewType()) {\r\n  @case (\"Text\") {\r\n    <mt-entity-text [data]=\"data()\" />\r\n  }\r\n  @case (\"LongText\") {\r\n    <mt-entity-long-text [data]=\"data()\" />\r\n  }\r\n  @case (\"Date\") {\r\n    <mt-entity-date [data]=\"data()\" />\r\n  }\r\n  @case (\"DateTime\") {\r\n    <mt-entity-date [data]=\"data()\" />\r\n  }\r\n  @case (\"User\") {\r\n    <mt-entity-user [data]=\"data()\" />\r\n  }\r\n  @case (\"Percentage\") {\r\n    <mt-entity-percentage [data]=\"data()\" />\r\n  }\r\n  @case (\"Currency\") {\r\n    <mt-entity-currency [data]=\"data()\" />\r\n  }\r\n  @case (\"Checkbox\") {\r\n    <mt-entity-checkbox [data]=\"data()\" />\r\n  }\r\n  @case (\"Lookup\") {\r\n    <mt-entity-lookup [data]=\"data()\" />\r\n  }\r\n  @case (\"Status\") {\r\n    <mt-entity-status [data]=\"data()\" />\r\n  }\r\n  @case (\"Attachment\") {\r\n    <mt-entity-attachment [data]=\"data()\" [shape]=\"attachmentShape()\" />\r\n  }\r\n  @default {\r\n    <mt-entity-text [data]=\"data()\" />\r\n  }\r\n}\r\n", dependencies: [{ kind: "component", type: EntityText, selector: "mt-entity-text", inputs: ["data", "name", "value"] }, { kind: "component", type: EntityLongText, selector: "mt-entity-long-text", inputs: ["data", "name", "value"] }, { kind: "component", type: EntityDate, selector: "mt-entity-date", inputs: ["data", "name", "value"] }, { kind: "component", type: EntityUser, selector: "mt-entity-user", inputs: ["data"] }, { kind: "component", type: EntityPercentage, selector: "mt-entity-percentage", inputs: ["data", "name", "value", "rawValue"] }, { kind: "component", type: EntityCurrency, selector: "mt-entity-currency", inputs: ["data", "name", "value"] }, { kind: "component", type: EntityCheckbox, selector: "mt-entity-checkbox", inputs: ["data", "name", "value", "rawValue"] }, { kind: "component", type: EntityLookup, selector: "mt-entity-lookup", inputs: ["data", "name", "value"] }, { kind: "component", type: EntityAttachment, selector: "mt-entity-attachment", inputs: ["data", "name", "shape", "value", "endPoint", "context"] }, { kind: "component", type: EntityStatus, selector: "mt-entity-status", inputs: ["data", "name", "value"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityPreview, decorators: [{
            type: Component,
            args: [{ selector: 'mt-entity-preview', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
                        EntityText,
                        EntityLongText,
                        EntityDate,
                        EntityUser,
                        EntityPercentage,
                        EntityCurrency,
                        EntityCheckbox,
                        EntityLookup,
                        EntityAttachment,
                        EntityStatus,
                    ], host: {
                        class: 'w-full',
                    }, template: "@switch (previewType()) {\r\n  @case (\"Text\") {\r\n    <mt-entity-text [data]=\"data()\" />\r\n  }\r\n  @case (\"LongText\") {\r\n    <mt-entity-long-text [data]=\"data()\" />\r\n  }\r\n  @case (\"Date\") {\r\n    <mt-entity-date [data]=\"data()\" />\r\n  }\r\n  @case (\"DateTime\") {\r\n    <mt-entity-date [data]=\"data()\" />\r\n  }\r\n  @case (\"User\") {\r\n    <mt-entity-user [data]=\"data()\" />\r\n  }\r\n  @case (\"Percentage\") {\r\n    <mt-entity-percentage [data]=\"data()\" />\r\n  }\r\n  @case (\"Currency\") {\r\n    <mt-entity-currency [data]=\"data()\" />\r\n  }\r\n  @case (\"Checkbox\") {\r\n    <mt-entity-checkbox [data]=\"data()\" />\r\n  }\r\n  @case (\"Lookup\") {\r\n    <mt-entity-lookup [data]=\"data()\" />\r\n  }\r\n  @case (\"Status\") {\r\n    <mt-entity-status [data]=\"data()\" />\r\n  }\r\n  @case (\"Attachment\") {\r\n    <mt-entity-attachment [data]=\"data()\" [shape]=\"attachmentShape()\" />\r\n  }\r\n  @default {\r\n    <mt-entity-text [data]=\"data()\" />\r\n  }\r\n}\r\n" }]
        }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }], attachmentShape: [{ type: i0.Input, args: [{ isSignal: true, alias: "attachmentShape", required: false }] }] } });

class EntitiesPreview {
    /** Array of entity data to display */
    entities = input.required(...(ngDevMode ? [{ debugName: "entities" }] : []));
    attachmentShape = input('default', ...(ngDevMode ? [{ debugName: "attachmentShape" }] : []));
    /** Entities sorted by order */
    sortedEntities = computed(() => [...this.entities()].sort((a, b) => (a.order ?? 0) - (b.order ?? 0)), ...(ngDevMode ? [{ debugName: "sortedEntities" }] : []));
    /** Returns the grid-column span for a given entity size (1-24) */
    getColSpan(entity) {
        const size = entity.configuration?.size ?? 8;
        return `span ${size}`;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntitiesPreview, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: EntitiesPreview, isStandalone: true, selector: "mt-entities-preview", inputs: { entities: { classPropertyName: "entities", publicName: "entities", isSignal: true, isRequired: true, transformFunction: null }, attachmentShape: { classPropertyName: "attachmentShape", publicName: "attachmentShape", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"grid grid-cols-24 gap-x-3 gap-y-5\">\r\n  @for (entity of sortedEntities(); track $index) {\r\n    <div\r\n      class=\"min-w-0 flex items-center p-3\"\r\n      [class.border]=\"entity.configuration?.showBorder\"\r\n      [class.border-dashed]=\"entity.configuration?.showBorder\"\r\n      [class.border-gray-200]=\"entity.configuration?.showBorder\"\r\n      [class.rounded-lg]=\"entity.configuration?.showBorder\"\r\n      [style.grid-column]=\"getColSpan(entity)\"\r\n    >\r\n      <mt-entity-preview\r\n        [data]=\"entity\"\r\n        [attachmentShape]=\"attachmentShape()\"\r\n      />\r\n    </div>\r\n  }\r\n</div>\r\n", dependencies: [{ kind: "component", type: EntityPreview, selector: "mt-entity-preview", inputs: ["data", "attachmentShape"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntitiesPreview, decorators: [{
            type: Component,
            args: [{ selector: 'mt-entities-preview', standalone: true, imports: [EntityPreview], template: "<div class=\"grid grid-cols-24 gap-x-3 gap-y-5\">\r\n  @for (entity of sortedEntities(); track $index) {\r\n    <div\r\n      class=\"min-w-0 flex items-center p-3\"\r\n      [class.border]=\"entity.configuration?.showBorder\"\r\n      [class.border-dashed]=\"entity.configuration?.showBorder\"\r\n      [class.border-gray-200]=\"entity.configuration?.showBorder\"\r\n      [class.rounded-lg]=\"entity.configuration?.showBorder\"\r\n      [style.grid-column]=\"getColSpan(entity)\"\r\n    >\r\n      <mt-entity-preview\r\n        [data]=\"entity\"\r\n        [attachmentShape]=\"attachmentShape()\"\r\n      />\r\n    </div>\r\n  }\r\n</div>\r\n" }]
        }], propDecorators: { entities: [{ type: i0.Input, args: [{ isSignal: true, alias: "entities", required: true }] }], attachmentShape: [{ type: i0.Input, args: [{ isSignal: true, alias: "attachmentShape", required: false }] }] } });

/**
 * Base class that encapsulates all entity resize-via-drag logic.
 *
 * Extend this directive in any component that needs column-resize behaviour
 * on a 24-column CSS grid.  The subclass must:
 *   - Provide a `model.required<EntityData[]>()` (or equivalent) for the
 *     entity list so `updateEntitySize()` can be called after resize.
 *   - Contain a `.grid` element (or override `getGridElement()`).
 *
 * Resize flow:
 *   1. `onResizeStart(event, entity)` — called from a mousedown on the handle
 *   2. mousemove  → snaps to nearest column, updates `resizePreviewSize`
 *   3. mouseup    → emits `entityResized` with previous & new size
 */
class EntitiesResizeBase {
    elRef = inject(ElementRef);
    zone = inject(NgZone);
    doc = inject(DOCUMENT);
    /** Emits when an entity is resized via the drag handle */
    entityResized = output();
    // ── Resize state ──
    /** The entity currently being resized (null when idle) */
    resizingEntity = signal(null, ...(ngDevMode ? [{ debugName: "resizingEntity" }] : []));
    /** Live preview size while dragging */
    resizePreviewSize = signal(null, ...(ngDevMode ? [{ debugName: "resizePreviewSize" }] : []));
    /** Bound listeners kept for cleanup */
    _onMouseMove = null;
    _onMouseUp = null;
    // ── Public API ──
    /**
     * Returns the grid element used to compute column widths.
     * Override if the grid selector differs.
     */
    getGridElement() {
        return this.elRef.nativeElement.querySelector('.grid');
    }
    /**
     * Returns the grid-column span string for a given entity.
     * While resizing the active entity, returns the preview size.
     */
    getResizeColSpan(entity) {
        if (this.resizingEntity() === entity && this.resizePreviewSize() !== null) {
            return `span ${this.resizePreviewSize()}`;
        }
        const size = entity.configuration?.size ?? 8;
        return `span ${size}`;
    }
    /** Starts a resize operation from the right-edge handle */
    onResizeStart(event, entity) {
        // Prevent the drag-drop from starting
        event.preventDefault();
        event.stopPropagation();
        const gridEl = this.getGridElement();
        if (!gridEl)
            return;
        const gridRect = gridEl.getBoundingClientRect();
        const gridWidth = gridRect.width;
        const columnWidth = gridWidth / 24;
        const previousSize = entity.configuration?.size ?? 8;
        // Left edge of the entity cell
        const cellEl = event.target.closest('.entity-cell');
        if (!cellEl)
            return;
        const cellRect = cellEl.getBoundingClientRect();
        const isRtl = this.doc.documentElement.getAttribute('dir') === 'rtl' ||
            getComputedStyle(this.doc.documentElement).direction === 'rtl';
        this.resizingEntity.set(entity);
        this.resizePreviewSize.set(previousSize);
        // Run mouse listeners outside Angular zone for performance
        this.zone.runOutsideAngular(() => {
            this._onMouseMove = (e) => {
                // In RTL the logical end is the left edge; dragging left widens the cell
                const rawWidth = isRtl
                    ? cellRect.right - e.clientX
                    : e.clientX - cellRect.left;
                // Snap to nearest full column (min 1, max 12)
                let cols = Math.round(rawWidth / columnWidth);
                cols = Math.max(1, Math.min(24, cols));
                const current = this.resizePreviewSize();
                if (current !== cols) {
                    this.zone.run(() => this.resizePreviewSize.set(cols));
                }
            };
            this._onMouseUp = () => {
                this._cleanupListeners();
                const newSize = this.resizePreviewSize();
                this.resizingEntity.set(null);
                this.resizePreviewSize.set(null);
                if (newSize !== previousSize) {
                    this.zone.run(() => {
                        this.onResizeComplete(entity, previousSize, newSize);
                    });
                }
            };
            this.doc.addEventListener('mousemove', this._onMouseMove);
            this.doc.addEventListener('mouseup', this._onMouseUp, { once: true });
        });
    }
    /** Removes global mouse listeners */
    _cleanupListeners() {
        if (this._onMouseMove) {
            this.doc.removeEventListener('mousemove', this._onMouseMove);
            this._onMouseMove = null;
        }
        if (this._onMouseUp) {
            this.doc.removeEventListener('mouseup', this._onMouseUp);
            this._onMouseUp = null;
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntitiesResizeBase, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.3", type: EntitiesResizeBase, isStandalone: true, outputs: { entityResized: "entityResized" }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntitiesResizeBase, decorators: [{
            type: Directive
        }], propDecorators: { entityResized: [{ type: i0.Output, args: ["entityResized"] }] } });

class EntitiesManage extends EntitiesResizeBase {
    /** Array of entity data – supports two-way binding to keep order in sync */
    entities = model.required(...(ngDevMode ? [{ debugName: "entities" }] : []));
    /** Emits the reordered entities array after each drag-drop */
    entitiesReordered = output();
    /** Entities sorted by their order field */
    sortedEntities = computed(() => [...this.entities()].sort((a, b) => (a.order ?? 0) - (b.order ?? 0)), ...(ngDevMode ? [{ debugName: "sortedEntities" }] : []));
    /** Returns the grid-column span for a given entity size (1-24) */
    getColSpan(entity) {
        return this.getResizeColSpan(entity);
    }
    /** Handle drag-drop reorder */
    onDrop(event) {
        if (event.previousIndex === event.currentIndex)
            return;
        const items = [...this.sortedEntities()];
        const [moved] = items.splice(event.previousIndex, 1);
        items.splice(event.currentIndex, 0, moved);
        // Reassign order based on new positions
        const reordered = items.map((item, index) => ({
            ...item,
            order: index + 1,
        }));
        // Update the model (two-way binding)
        this.entities.set(reordered);
        // Emit the reordered list
        this.entitiesReordered.emit(reordered);
    }
    // ── Resize completion (from EntitiesResizeBase) ──
    onResizeComplete(entity, previousSize, newSize) {
        // Update entity in the list
        const updated = this.entities().map((e) => e === entity
            ? {
                ...e,
                configuration: {
                    ...e.configuration,
                    size: newSize,
                },
            }
            : e);
        this.entities.set(updated);
        this.entityResized.emit({
            entity: {
                ...entity,
                configuration: { ...entity.configuration, size: newSize },
            },
            previousSize,
            newSize,
        });
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntitiesManage, deps: null, target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: EntitiesManage, isStandalone: true, selector: "mt-entities-manage", inputs: { entities: { classPropertyName: "entities", publicName: "entities", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { entities: "entitiesChange", entitiesReordered: "entitiesReordered" }, usesInheritance: true, ngImport: i0, template: "<div\r\n  cdkDropList\r\n  cdkDropListOrientation=\"mixed\"\r\n  [cdkDropListData]=\"sortedEntities()\"\r\n  (cdkDropListDropped)=\"onDrop($event)\"\r\n  class=\"grid grid-cols-24 gap-x-4 gap-y-6\"\r\n>\r\n  @for (entity of sortedEntities(); track entity.order) {\r\n    <div\r\n      cdkDrag\r\n      [cdkDragData]=\"entity\"\r\n      class=\"entity-cell group relative min-w-0 flex items-center p-3 cursor-grab active:cursor-grabbing\"\r\n      [class.border]=\"entity.configuration?.showBorder\"\r\n      [class.border-dashed]=\"entity.configuration?.showBorder\"\r\n      [class.border-gray-200]=\"entity.configuration?.showBorder\"\r\n      [class.rounded-lg]=\"entity.configuration?.showBorder\"\r\n      [class.resizing]=\"resizingEntity() === entity\"\r\n      [style.grid-column]=\"getColSpan(entity)\"\r\n    >\r\n      <!-- Drag placeholder -->\r\n      <div\r\n        *cdkDragPlaceholder\r\n        class=\"h-full min-h-12 bg-black/10 rounded-xl\"\r\n        [style.grid-column]=\"getColSpan(entity)\"\r\n      ></div>\r\n\r\n      <mt-entity-preview [data]=\"entity\" class=\"flex-1 min-w-0\" />\r\n\r\n      <!-- Resize handle (right edge) -->\r\n      <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event, entity)\">\r\n        <div class=\"resize-handle-bar\"></div>\r\n      </div>\r\n    </div>\r\n  }\r\n</div>\r\n", styles: [".cdk-drag{cursor:grab}.cdk-drag:active{cursor:grabbing}.cdk-drag-preview{cursor:grabbing;overflow:hidden}.cdk-drag-placeholder{opacity:.5}.cdk-drop-list-dragging .cdk-drag{cursor:grabbing}.entity-cell{position:relative}.resize-handle{position:absolute;top:0;inset-inline-end:-4px;width:8px;height:100%;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s ease}.entity-cell:hover .resize-handle,.entity-cell.resizing .resize-handle{opacity:1}.resize-handle-bar{width:3px;height:24px;border-radius:2px;background-color:var(--p-primary-color, #6366f1);transition:height .15s ease,background-color .15s ease}.resize-handle:hover .resize-handle-bar{height:36px;background-color:var(--p-primary-color, #4f46e5)}.entity-cell.resizing{outline:2px dashed var(--p-primary-color, #6366f1);outline-offset:-1px;border-radius:8px;-webkit-user-select:none;user-select:none}\n"], dependencies: [{ kind: "component", type: EntityPreview, selector: "mt-entity-preview", inputs: ["data", "attachmentShape"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntitiesManage, decorators: [{
            type: Component,
            args: [{ selector: 'mt-entities-manage', standalone: true, imports: [EntityPreview, CdkDrag, CdkDropList, CdkDragPlaceholder], template: "<div\r\n  cdkDropList\r\n  cdkDropListOrientation=\"mixed\"\r\n  [cdkDropListData]=\"sortedEntities()\"\r\n  (cdkDropListDropped)=\"onDrop($event)\"\r\n  class=\"grid grid-cols-24 gap-x-4 gap-y-6\"\r\n>\r\n  @for (entity of sortedEntities(); track entity.order) {\r\n    <div\r\n      cdkDrag\r\n      [cdkDragData]=\"entity\"\r\n      class=\"entity-cell group relative min-w-0 flex items-center p-3 cursor-grab active:cursor-grabbing\"\r\n      [class.border]=\"entity.configuration?.showBorder\"\r\n      [class.border-dashed]=\"entity.configuration?.showBorder\"\r\n      [class.border-gray-200]=\"entity.configuration?.showBorder\"\r\n      [class.rounded-lg]=\"entity.configuration?.showBorder\"\r\n      [class.resizing]=\"resizingEntity() === entity\"\r\n      [style.grid-column]=\"getColSpan(entity)\"\r\n    >\r\n      <!-- Drag placeholder -->\r\n      <div\r\n        *cdkDragPlaceholder\r\n        class=\"h-full min-h-12 bg-black/10 rounded-xl\"\r\n        [style.grid-column]=\"getColSpan(entity)\"\r\n      ></div>\r\n\r\n      <mt-entity-preview [data]=\"entity\" class=\"flex-1 min-w-0\" />\r\n\r\n      <!-- Resize handle (right edge) -->\r\n      <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event, entity)\">\r\n        <div class=\"resize-handle-bar\"></div>\r\n      </div>\r\n    </div>\r\n  }\r\n</div>\r\n", styles: [".cdk-drag{cursor:grab}.cdk-drag:active{cursor:grabbing}.cdk-drag-preview{cursor:grabbing;overflow:hidden}.cdk-drag-placeholder{opacity:.5}.cdk-drop-list-dragging .cdk-drag{cursor:grabbing}.entity-cell{position:relative}.resize-handle{position:absolute;top:0;inset-inline-end:-4px;width:8px;height:100%;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s ease}.entity-cell:hover .resize-handle,.entity-cell.resizing .resize-handle{opacity:1}.resize-handle-bar{width:3px;height:24px;border-radius:2px;background-color:var(--p-primary-color, #6366f1);transition:height .15s ease,background-color .15s ease}.resize-handle:hover .resize-handle-bar{height:36px;background-color:var(--p-primary-color, #4f46e5)}.entity-cell.resizing{outline:2px dashed var(--p-primary-color, #6366f1);outline-offset:-1px;border-radius:8px;-webkit-user-select:none;user-select:none}\n"] }]
        }], propDecorators: { entities: [{ type: i0.Input, args: [{ isSignal: true, alias: "entities", required: true }] }, { type: i0.Output, args: ["entitiesChange"] }], entitiesReordered: [{ type: i0.Output, args: ["entitiesReordered"] }] } });

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

export { EntitiesManage, EntitiesPreview, EntitiesResizeBase, EntityAttachment, EntityCheckbox, EntityCurrency, EntityDate, EntityField, EntityLongText, EntityLookup, EntityPercentage, EntityPreview, EntityStatus, EntityText, EntityUser };
//# sourceMappingURL=masterteam-components-entities.mjs.map
