@masterteam/components 0.0.115 → 0.0.117

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/assets/common.css +172 -2
  2. package/fesm2022/masterteam-components-business-fields.mjs +1 -1
  3. package/fesm2022/masterteam-components-business-fields.mjs.map +1 -1
  4. package/fesm2022/masterteam-components-drawer.mjs +6 -6
  5. package/fesm2022/masterteam-components-drawer.mjs.map +1 -1
  6. package/fesm2022/masterteam-components-entities.mjs +257 -34
  7. package/fesm2022/masterteam-components-entities.mjs.map +1 -1
  8. package/fesm2022/masterteam-components-formula.mjs +25 -8
  9. package/fesm2022/masterteam-components-formula.mjs.map +1 -1
  10. package/fesm2022/masterteam-components-progress.mjs +10 -2
  11. package/fesm2022/masterteam-components-progress.mjs.map +1 -1
  12. package/fesm2022/masterteam-components-table.mjs +417 -55
  13. package/fesm2022/masterteam-components-table.mjs.map +1 -1
  14. package/package.json +16 -16
  15. package/types/masterteam-components-drawer.d.ts +1 -1
  16. package/types/masterteam-components-entities.d.ts +30 -6
  17. package/types/masterteam-components-formula.d.ts +8 -1
  18. package/types/masterteam-components-progress.d.ts +2 -0
  19. package/types/masterteam-components-table.d.ts +31 -2
  20. package/fesm2022/masterteam-components-sidebar.mjs +0 -36
  21. package/fesm2022/masterteam-components-sidebar.mjs.map +0 -1
  22. package/fesm2022/masterteam-components-slider-field.mjs +0 -104
  23. package/fesm2022/masterteam-components-slider-field.mjs.map +0 -1
  24. package/fesm2022/masterteam-components-statistic-card.mjs +0 -22
  25. package/fesm2022/masterteam-components-statistic-card.mjs.map +0 -1
  26. package/fesm2022/masterteam-components-textarea-field.mjs +0 -92
  27. package/fesm2022/masterteam-components-textarea-field.mjs.map +0 -1
  28. package/fesm2022/masterteam-components-toast.mjs +0 -75
  29. package/fesm2022/masterteam-components-toast.mjs.map +0 -1
  30. package/fesm2022/masterteam-components-topbar.mjs +0 -28
  31. package/fesm2022/masterteam-components-topbar.mjs.map +0 -1
  32. package/fesm2022/masterteam-components-tree.mjs +0 -219
  33. package/fesm2022/masterteam-components-tree.mjs.map +0 -1
  34. package/types/masterteam-components-sidebar.d.ts +0 -28
  35. package/types/masterteam-components-slider-field.d.ts +0 -45
  36. package/types/masterteam-components-statistic-card.d.ts +0 -18
  37. package/types/masterteam-components-textarea-field.d.ts +0 -38
  38. package/types/masterteam-components-toast.d.ts +0 -26
  39. package/types/masterteam-components-topbar.d.ts +0 -17
  40. package/types/masterteam-components-tree.d.ts +0 -98
@@ -1,6 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, computed, Component, inject, ElementRef, NgZone, output, signal, Directive, model } from '@angular/core';
3
- import { HttpContext } from '@angular/common/http';
2
+ import { input, computed, Component, inject, signal, effect, ChangeDetectionStrategy, ElementRef, NgZone, output, Directive, model } from '@angular/core';
3
+ import { HttpContext, HttpClient } from '@angular/common/http';
4
4
  import { Avatar } from '@masterteam/components/avatar';
5
5
  import { Button } from '@masterteam/components/button';
6
6
  import { SecureImagePipe, UploadField } from '@masterteam/components/upload-field';
@@ -8,6 +8,7 @@ import { REQUEST_CONTEXT } from '@masterteam/components';
8
8
  import { Progress } from '@masterteam/components/progress';
9
9
  import * as i1 from '@angular/forms';
10
10
  import { FormsModule } from '@angular/forms';
11
+ import { forkJoin, finalize, of, take, switchMap, EMPTY, map, catchError } from 'rxjs';
11
12
  import { CdkDrag, CdkDropList, CdkDragPlaceholder } from '@angular/cdk/drag-drop';
12
13
  import { DOCUMENT } from '@angular/common';
13
14
 
@@ -163,28 +164,36 @@ class EntityPercentage {
163
164
  }
164
165
  return displayOrPlaceholder(this.value());
165
166
  }, ...(ngDevMode ? [{ debugName: "displayValue" }] : []));
166
- rawNumericValue = computed(() => this.data()?.rawValue ?? this.rawValue() ?? this.value(), ...(ngDevMode ? [{ debugName: "rawNumericValue" }] : []));
167
+ rawNumericValue = computed(() => this.data()?.rawValue ??
168
+ this.rawValue() ??
169
+ this.value() ??
170
+ this.displayValue(), ...(ngDevMode ? [{ debugName: "rawNumericValue" }] : []));
167
171
  hasNumericValue = computed(() => {
168
- const raw = this.rawNumericValue();
169
- if (isValueMissing(raw)) {
170
- return false;
171
- }
172
- return !Number.isNaN(parseFloat(String(raw)));
172
+ return this.parseNumericValue(this.rawNumericValue()) !== null;
173
173
  }, ...(ngDevMode ? [{ debugName: "hasNumericValue" }] : []));
174
174
  numericValue = computed(() => {
175
- const raw = this.rawNumericValue();
176
- const num = parseFloat(raw ?? '0');
177
- return isNaN(num) ? 0 : Math.min(num, 100);
175
+ const num = this.parseNumericValue(this.rawNumericValue());
176
+ return num === null ? 0 : Math.min(num, 100);
178
177
  }, ...(ngDevMode ? [{ debugName: "numericValue" }] : []));
179
178
  maxValue = computed(() => {
180
- const raw = this.rawNumericValue();
181
- const num = parseFloat(raw ?? '0');
182
- if (isNaN(num))
179
+ const num = this.parseNumericValue(this.rawNumericValue());
180
+ if (num === null)
183
181
  return 100;
184
182
  return num > 100 ? Math.ceil(num) : 100;
185
183
  }, ...(ngDevMode ? [{ debugName: "maxValue" }] : []));
186
184
  // ── Configuration-driven visibility ──
187
185
  hideName = computed(() => this.data()?.configuration?.hideName ?? false, ...(ngDevMode ? [{ debugName: "hideName" }] : []));
186
+ parseNumericValue(raw) {
187
+ if (isValueMissing(raw)) {
188
+ return null;
189
+ }
190
+ const normalizedRawValue = String(raw).replace(/%/g, '').trim();
191
+ if (!normalizedRawValue) {
192
+ return null;
193
+ }
194
+ const numericValue = Number.parseFloat(normalizedRawValue);
195
+ return Number.isNaN(numericValue) ? null : numericValue;
196
+ }
188
197
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityPercentage, deps: [], target: i0.ɵɵFactoryTarget.Component });
189
198
  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 >\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"] }] });
190
199
  }
@@ -329,39 +338,252 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
329
338
  class EntityAttachment {
330
339
  data = input(...(ngDevMode ? [undefined, { debugName: "data" }] : []));
331
340
  name = input(...(ngDevMode ? [undefined, { debugName: "name" }] : []));
341
+ shape = input('default', ...(ngDevMode ? [{ debugName: "shape" }] : []));
332
342
  value = input(...(ngDevMode ? [undefined, { debugName: "value" }] : []));
343
+ endPoint = input('uploader', ...(ngDevMode ? [{ debugName: "endPoint" }] : []));
344
+ context = input(undefined, ...(ngDevMode ? [{ debugName: "context" }] : []));
345
+ httpClient = inject(HttpClient);
333
346
  displayName = computed(() => this.data()?.name ?? this.name() ?? '', ...(ngDevMode ? [{ debugName: "displayName" }] : []));
334
347
  hideName = computed(() => this.data()?.configuration?.hideName ?? false, ...(ngDevMode ? [{ debugName: "hideName" }] : []));
348
+ loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
349
+ attachments = signal([], ...(ngDevMode ? [{ debugName: "attachments" }] : []));
350
+ attachmentReferences = computed(() => this.normalizeAttachmentValue(this.data()?.value ?? this.value()), ...(ngDevMode ? [{ debugName: "attachmentReferences" }] : []));
335
351
  uploadValue = computed(() => {
336
- const value = this.data()?.value ?? this.value();
337
- if (Array.isArray(value)) {
338
- return value.filter((item) => item != null);
352
+ const references = this.attachmentReferences().map((reference) => {
353
+ if (typeof reference === 'string') {
354
+ return reference.trim();
355
+ }
356
+ if (reference.fileName) {
357
+ return reference;
358
+ }
359
+ return reference.id?.trim() || reference;
360
+ });
361
+ if (!references.length) {
362
+ return null;
339
363
  }
340
- return value ?? null;
364
+ return references.length === 1 ? references[0] : references;
341
365
  }, ...(ngDevMode ? [{ debugName: "uploadValue" }] : []));
342
- hasAttachments = computed(() => {
343
- const value = this.uploadValue();
344
- return Array.isArray(value) ? value.length > 0 : !!value;
345
- }, ...(ngDevMode ? [{ debugName: "hasAttachments" }] : []));
346
- isMultiple = computed(() => Array.isArray(this.uploadValue()), ...(ngDevMode ? [{ debugName: "isMultiple" }] : []));
366
+ hasAttachments = computed(() => this.shape() === 'compact'
367
+ ? this.attachments().length > 0
368
+ : this.uploadValue() != null, ...(ngDevMode ? [{ debugName: "hasAttachments" }] : []));
369
+ isMultiple = computed(() => this.attachmentReferences().length > 1, ...(ngDevMode ? [{ debugName: "isMultiple" }] : []));
347
370
  empty = '-';
371
+ constructor() {
372
+ effect((onCleanup) => {
373
+ if (this.shape() !== 'compact') {
374
+ this.loading.set(false);
375
+ this.attachments.set([]);
376
+ return;
377
+ }
378
+ const references = this.attachmentReferences();
379
+ if (!references.length) {
380
+ this.loading.set(false);
381
+ this.attachments.set([]);
382
+ return;
383
+ }
384
+ const shouldFetchMetadata = references.some((reference) => this.requiresMetadataRequest(reference));
385
+ if (!shouldFetchMetadata) {
386
+ this.attachments.set(references.filter(this.isAttachmentItemValue).map((reference) => ({
387
+ ...reference,
388
+ name: reference.name ??
389
+ reference.fileName ??
390
+ reference.id ??
391
+ reference.name,
392
+ extension: this.resolveExtension(reference),
393
+ })));
394
+ this.loading.set(false);
395
+ return;
396
+ }
397
+ this.loading.set(true);
398
+ const sub = forkJoin(references.map((reference) => this.resolveAttachment$(reference)))
399
+ .pipe(finalize(() => this.loading.set(false)))
400
+ .subscribe((attachments) => {
401
+ this.attachments.set(attachments.filter((attachment) => attachment != null));
402
+ });
403
+ onCleanup(() => sub.unsubscribe());
404
+ });
405
+ }
406
+ attachmentTrackBy(index, attachment) {
407
+ return (attachment.id ?? attachment.fileName ?? attachment.name ?? String(index));
408
+ }
409
+ attachmentTooltip(attachment) {
410
+ return (attachment.name ?? attachment.fileName ?? attachment.id ?? 'Attachment');
411
+ }
412
+ attachmentIcon(attachment) {
413
+ const extension = this.resolveExtension(attachment);
414
+ const contentType = attachment.contentType?.toLowerCase() ?? '';
415
+ if (contentType.startsWith('image/')) {
416
+ return 'image.image-03';
417
+ }
418
+ switch (extension) {
419
+ case '.pdf':
420
+ return 'file.file-06';
421
+ case '.doc':
422
+ case '.docx':
423
+ case '.txt':
424
+ case '.rtf':
425
+ return 'file.file-04';
426
+ case '.xls':
427
+ case '.xlsx':
428
+ case '.csv':
429
+ return 'file.file-03';
430
+ case '.ppt':
431
+ case '.pptx':
432
+ return 'file.file-05';
433
+ default:
434
+ return 'file.clipboard-attachment';
435
+ }
436
+ }
437
+ onCompactAttachmentClick(event, attachment) {
438
+ event.stopPropagation();
439
+ this.downloadAttachment(attachment);
440
+ }
441
+ downloadAttachment(attachment) {
442
+ const resolvedAttachment$ = this.requiresMetadataRequest(attachment)
443
+ ? this.resolveAttachment$(attachment)
444
+ : of(this.normalizeAttachmentItem(attachment));
445
+ resolvedAttachment$
446
+ .pipe(take(1), switchMap((resolvedAttachment) => {
447
+ if (!resolvedAttachment?.fileName) {
448
+ return EMPTY;
449
+ }
450
+ return this.httpClient
451
+ .get(`${this.endPoint()}/${resolvedAttachment.fileName}`, {
452
+ responseType: 'blob',
453
+ context: this.context(),
454
+ })
455
+ .pipe(take(1), map((blob) => ({
456
+ attachment: resolvedAttachment,
457
+ blob,
458
+ })));
459
+ }))
460
+ .subscribe(({ attachment, blob }) => {
461
+ const downloadBlob = new Blob([blob], {
462
+ type: attachment.contentType || blob.type || 'application/octet-stream',
463
+ });
464
+ const objectUrl = window.URL.createObjectURL(downloadBlob);
465
+ const anchor = document.createElement('a');
466
+ anchor.href = objectUrl;
467
+ anchor.download =
468
+ attachment.name ??
469
+ attachment.fileName ??
470
+ attachment.id ??
471
+ 'attachment';
472
+ anchor.click();
473
+ window.URL.revokeObjectURL(objectUrl);
474
+ });
475
+ }
476
+ resolveAttachment$(reference) {
477
+ const normalizedAttachment = this.normalizeAttachmentItem(reference);
478
+ if (!this.requiresMetadataRequest(reference)) {
479
+ return of(normalizedAttachment);
480
+ }
481
+ const attachmentId = typeof reference === 'string' ? reference.trim() : reference.id?.trim();
482
+ if (!attachmentId) {
483
+ return of(normalizedAttachment);
484
+ }
485
+ return this.httpClient
486
+ .get(`${this.endPoint()}/${attachmentId}/metaData`, {
487
+ context: this.context(),
488
+ })
489
+ .pipe(take(1), map((response) => this.normalizeAttachmentItem(response.data)), catchError(() => of(normalizedAttachment)));
490
+ }
491
+ normalizeAttachmentValue(value) {
492
+ if (value === null || value === undefined) {
493
+ return [];
494
+ }
495
+ if (Array.isArray(value)) {
496
+ return value.flatMap((item) => this.normalizeAttachmentValue(item));
497
+ }
498
+ if (typeof value === 'string') {
499
+ const trimmedValue = value.trim();
500
+ if (!trimmedValue || trimmedValue === '[]') {
501
+ return [];
502
+ }
503
+ if ((trimmedValue.startsWith('[') && trimmedValue.endsWith(']')) ||
504
+ (trimmedValue.startsWith('{') && trimmedValue.endsWith('}'))) {
505
+ try {
506
+ return this.normalizeAttachmentValue(JSON.parse(trimmedValue));
507
+ }
508
+ catch {
509
+ return [trimmedValue];
510
+ }
511
+ }
512
+ return [trimmedValue];
513
+ }
514
+ if (typeof value === 'object') {
515
+ return [value];
516
+ }
517
+ return [];
518
+ }
519
+ normalizeAttachmentItem(value) {
520
+ if (!value) {
521
+ return null;
522
+ }
523
+ if (typeof value === 'string') {
524
+ const trimmedValue = value.trim();
525
+ return trimmedValue
526
+ ? {
527
+ id: trimmedValue,
528
+ name: trimmedValue,
529
+ }
530
+ : null;
531
+ }
532
+ const normalizedAttachment = {
533
+ ...value,
534
+ name: value.name ?? value.fileName ?? value.id ?? '',
535
+ extension: this.resolveExtension(value),
536
+ };
537
+ return normalizedAttachment.name ||
538
+ normalizedAttachment.fileName ||
539
+ normalizedAttachment.id
540
+ ? normalizedAttachment
541
+ : null;
542
+ }
543
+ requiresMetadataRequest(reference) {
544
+ if (typeof reference === 'string') {
545
+ return reference.trim().length > 0;
546
+ }
547
+ return !!reference.id?.trim() && !reference.fileName;
548
+ }
549
+ isAttachmentItemValue(reference) {
550
+ return typeof reference === 'object' && reference != null;
551
+ }
552
+ resolveExtension(value) {
553
+ const explicitExtension = value.extension?.trim();
554
+ if (explicitExtension) {
555
+ return explicitExtension.startsWith('.')
556
+ ? explicitExtension.toLowerCase()
557
+ : `.${explicitExtension.toLowerCase()}`;
558
+ }
559
+ const fileName = value.fileName ?? value.name;
560
+ if (!fileName || !fileName.includes('.')) {
561
+ return undefined;
562
+ }
563
+ return `.${fileName.split('.').pop().toLowerCase()}`;
564
+ }
348
565
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityAttachment, deps: [], target: i0.ɵɵFactoryTarget.Component });
349
- 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 }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"flex w-full flex-col gap-2\">\r\n @if (!hideName()) {\r\n <span class=\"text-sm text-gray-500\">{{ displayName() }}</span>\r\n }\r\n\r\n @if (hasAttachments()) {\r\n <mt-upload-field\r\n class=\"w-full\"\r\n [ngModel]=\"uploadValue()\"\r\n [ngModelOptions]=\"{ standalone: true }\"\r\n [shape]=\"'card'\"\r\n [multiple]=\"isMultiple()\"\r\n [readonly]=\"true\"\r\n />\r\n } @else {\r\n <span class=\"text-sm font-semibold\">{{ empty }}</span>\r\n }\r\n</div>\r\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"] }] });
566
+ 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: "<div class=\"flex w-full flex-col gap-2\">\r\n @if (!hideName()) {\r\n <span class=\"text-sm text-gray-500\">{{ displayName() }}</span>\r\n }\r\n\r\n @if (hasAttachments()) {\r\n @if (shape() === \"compact\") {\r\n <div class=\"flex flex-wrap items-center gap-2\">\r\n @for (\r\n attachment of attachments();\r\n track attachmentTrackBy($index, attachment)\r\n ) {\r\n <mt-button\r\n iconPos=\"top\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n [icon]=\"attachmentIcon(attachment)\"\r\n [tooltip]=\"attachmentTooltip(attachment)\"\r\n styleClass=\"h-9! w-9! rounded-lg!\"\r\n (onClick)=\"onCompactAttachmentClick($event, attachment)\"\r\n />\r\n }\r\n </div>\r\n } @else {\r\n <mt-upload-field\r\n class=\"w-full\"\r\n [ngModel]=\"uploadValue()\"\r\n [ngModelOptions]=\"{ standalone: true }\"\r\n [shape]=\"'card'\"\r\n [multiple]=\"isMultiple()\"\r\n [readonly]=\"true\"\r\n [endPoint]=\"endPoint()\"\r\n [context]=\"context()\"\r\n />\r\n }\r\n } @else {\r\n <span class=\"text-sm font-semibold\">{{ empty }}</span>\r\n }\r\n</div>\r\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"] }] });
350
567
  }
351
568
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityAttachment, decorators: [{
352
569
  type: Component,
353
- args: [{ selector: 'mt-entity-attachment', standalone: true, imports: [FormsModule, UploadField], template: "<div class=\"flex w-full flex-col gap-2\">\r\n @if (!hideName()) {\r\n <span class=\"text-sm text-gray-500\">{{ displayName() }}</span>\r\n }\r\n\r\n @if (hasAttachments()) {\r\n <mt-upload-field\r\n class=\"w-full\"\r\n [ngModel]=\"uploadValue()\"\r\n [ngModelOptions]=\"{ standalone: true }\"\r\n [shape]=\"'card'\"\r\n [multiple]=\"isMultiple()\"\r\n [readonly]=\"true\"\r\n />\r\n } @else {\r\n <span class=\"text-sm font-semibold\">{{ empty }}</span>\r\n }\r\n</div>\r\n" }]
354
- }], 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 }] }] } });
570
+ args: [{ selector: 'mt-entity-attachment', standalone: true, imports: [FormsModule, UploadField, Button], template: "<div class=\"flex w-full flex-col gap-2\">\r\n @if (!hideName()) {\r\n <span class=\"text-sm text-gray-500\">{{ displayName() }}</span>\r\n }\r\n\r\n @if (hasAttachments()) {\r\n @if (shape() === \"compact\") {\r\n <div class=\"flex flex-wrap items-center gap-2\">\r\n @for (\r\n attachment of attachments();\r\n track attachmentTrackBy($index, attachment)\r\n ) {\r\n <mt-button\r\n iconPos=\"top\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n [icon]=\"attachmentIcon(attachment)\"\r\n [tooltip]=\"attachmentTooltip(attachment)\"\r\n styleClass=\"h-9! w-9! rounded-lg!\"\r\n (onClick)=\"onCompactAttachmentClick($event, attachment)\"\r\n />\r\n }\r\n </div>\r\n } @else {\r\n <mt-upload-field\r\n class=\"w-full\"\r\n [ngModel]=\"uploadValue()\"\r\n [ngModelOptions]=\"{ standalone: true }\"\r\n [shape]=\"'card'\"\r\n [multiple]=\"isMultiple()\"\r\n [readonly]=\"true\"\r\n [endPoint]=\"endPoint()\"\r\n [context]=\"context()\"\r\n />\r\n }\r\n } @else {\r\n <span class=\"text-sm font-semibold\">{{ empty }}</span>\r\n }\r\n</div>\r\n" }]
571
+ }], 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 }] }] } });
355
572
 
356
573
  class EntityPreview {
357
574
  /** Single entity data to display */
358
575
  data = input.required(...(ngDevMode ? [{ debugName: "data" }] : []));
576
+ attachmentShape = input('default', ...(ngDevMode ? [{ debugName: "attachmentShape" }] : []));
577
+ previewType = computed(() => {
578
+ const viewType = this.data().viewType;
579
+ return viewType === 'LookupMatrix' ? 'Lookup' : viewType;
580
+ }, ...(ngDevMode ? [{ debugName: "previewType" }] : []));
359
581
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityPreview, deps: [], target: i0.ɵɵFactoryTarget.Component });
360
- 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 } }, host: { classAttribute: "w-full" }, ngImport: i0, template: "@switch (data().viewType) {\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 (\"Status\") {\r\n <mt-entity-status [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 (\"Attachment\") {\r\n <mt-entity-attachment [data]=\"data()\" />\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: EntityStatus, selector: "mt-entity-status", 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", "value"] }] });
582
+ 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()) {\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 (\"Status\") {\r\n <mt-entity-status [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\") {\n <mt-entity-lookup [data]=\"data()\" />\n }\n @case (\"Attachment\") {\n <mt-entity-attachment [data]=\"data()\" [shape]=\"attachmentShape()\" />\n }\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: EntityStatus, selector: "mt-entity-status", 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
361
583
  }
362
584
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityPreview, decorators: [{
363
585
  type: Component,
364
- args: [{ selector: 'mt-entity-preview', standalone: true, imports: [
586
+ args: [{ selector: 'mt-entity-preview', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
365
587
  EntityText,
366
588
  EntityLongText,
367
589
  EntityDate,
@@ -374,12 +596,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
374
596
  EntityAttachment,
375
597
  ], host: {
376
598
  class: 'w-full',
377
- }, template: "@switch (data().viewType) {\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 (\"Status\") {\r\n <mt-entity-status [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 (\"Attachment\") {\r\n <mt-entity-attachment [data]=\"data()\" />\r\n }\r\n @default {\r\n <mt-entity-text [data]=\"data()\" />\r\n }\r\n}\r\n" }]
378
- }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }] } });
599
+ }, template: "@switch (previewType()) {\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 (\"Status\") {\r\n <mt-entity-status [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\") {\n <mt-entity-lookup [data]=\"data()\" />\n }\n @case (\"Attachment\") {\n <mt-entity-attachment [data]=\"data()\" [shape]=\"attachmentShape()\" />\n }\n @default {\r\n <mt-entity-text [data]=\"data()\" />\r\n }\r\n}\r\n" }]
600
+ }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }], attachmentShape: [{ type: i0.Input, args: [{ isSignal: true, alias: "attachmentShape", required: false }] }] } });
379
601
 
380
602
  class EntitiesPreview {
381
603
  /** Array of entity data to display */
382
604
  entities = input.required(...(ngDevMode ? [{ debugName: "entities" }] : []));
605
+ attachmentShape = input('default', ...(ngDevMode ? [{ debugName: "attachmentShape" }] : []));
383
606
  /** Entities sorted by order */
384
607
  sortedEntities = computed(() => [...this.entities()].sort((a, b) => (a.order ?? 0) - (b.order ?? 0)), ...(ngDevMode ? [{ debugName: "sortedEntities" }] : []));
385
608
  /** Returns the grid-column span for a given entity size (1-24) */
@@ -388,12 +611,12 @@ class EntitiesPreview {
388
611
  return `span ${size}`;
389
612
  }
390
613
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntitiesPreview, deps: [], target: i0.ɵɵFactoryTarget.Component });
391
- 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 } }, ngImport: i0, template: "<div class=\"grid grid-cols-24 gap-x-3 gap-y-7\">\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 [data]=\"entity\" />\r\n </div>\r\n }\r\n</div>\r\n", dependencies: [{ kind: "component", type: EntityPreview, selector: "mt-entity-preview", inputs: ["data"] }] });
614
+ 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-7\">\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"] }] });
392
615
  }
393
616
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntitiesPreview, decorators: [{
394
617
  type: Component,
395
- args: [{ selector: 'mt-entities-preview', standalone: true, imports: [EntityPreview], template: "<div class=\"grid grid-cols-24 gap-x-3 gap-y-7\">\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 [data]=\"entity\" />\r\n </div>\r\n }\r\n</div>\r\n" }]
396
- }], propDecorators: { entities: [{ type: i0.Input, args: [{ isSignal: true, alias: "entities", required: true }] }] } });
618
+ args: [{ selector: 'mt-entities-preview', standalone: true, imports: [EntityPreview], template: "<div class=\"grid grid-cols-24 gap-x-3 gap-y-7\">\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" }]
619
+ }], propDecorators: { entities: [{ type: i0.Input, args: [{ isSignal: true, alias: "entities", required: true }] }], attachmentShape: [{ type: i0.Input, args: [{ isSignal: true, alias: "attachmentShape", required: false }] }] } });
397
620
 
398
621
  /**
399
622
  * Base class that encapsulates all entity resize-via-drag logic.
@@ -557,7 +780,7 @@ class EntitiesManage extends EntitiesResizeBase {
557
780
  });
558
781
  }
559
782
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntitiesManage, deps: null, target: i0.ɵɵFactoryTarget.Component });
560
- 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-7\"\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;right:-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"] }, { 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"] }] });
783
+ 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-7\"\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;right:-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"] }] });
561
784
  }
562
785
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntitiesManage, decorators: [{
563
786
  type: Component,