@masterteam/components 0.0.109 → 0.0.111

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.
@@ -1,13 +1,19 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, signal, inject, DestroyRef, computed, effect, untracked, ChangeDetectionStrategy, Component } from '@angular/core';
2
+ import { input, signal, inject, DestroyRef, computed, effect, untracked, ChangeDetectionStrategy, Component, viewChild, linkedSignal } from '@angular/core';
3
3
  import * as i1 from '@angular/forms';
4
4
  import { Validators, NgControl, FormsModule } from '@angular/forms';
5
5
  import { SelectField } from '@masterteam/components/select-field';
6
6
  import { MultiSelectField } from '@masterteam/components/multi-select-field';
7
7
  import { FieldValidation } from '@masterteam/components/field-validation';
8
8
  import { HttpClient } from '@angular/common/http';
9
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
9
+ import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
10
10
  import { finalize, catchError, of } from 'rxjs';
11
+ import { CommonModule } from '@angular/common';
12
+ import * as i2 from '@jsverse/transloco';
13
+ import { TranslocoService, TranslocoModule } from '@jsverse/transloco';
14
+ import { Button } from '@masterteam/components/button';
15
+ import { NumberField } from '@masterteam/components/number-field';
16
+ import { Table } from '@masterteam/components/table';
11
17
 
12
18
  class SchemaConnectionField {
13
19
  // ============================================================================
@@ -214,9 +220,260 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
214
220
  }, template: "<!-- @if (label()) {\r\n <label\r\n [class.required]=\"ngControl?.control?.hasValidator(requiredValidator)\"\r\n [for]=\"ngControl?.name || label()\"\r\n >\r\n {{ label() }}\r\n </label>\r\n} -->\r\n\r\n<div class=\"flex gap-4 w-full\">\r\n @for (state of sourceLevelStates(); track state.source.levelId) {\r\n <div [style.width]=\"dropdownWidth()\" class=\"min-w-0\">\r\n @if (sourceLevelStates().length > 1) {\r\n <span class=\"text-sm text-muted-color mb-1 block truncate\">\r\n {{ state.source.name?.en || state.source.levelKey }}\r\n </span>\r\n }\r\n\r\n @if (state.source.allowManyToMany) {\r\n <mt-multi-select-field\r\n [field]=\"false\"\r\n [(ngModel)]=\"selections[state.source.levelId]\"\r\n (ngModelChange)=\"syncValue()\"\r\n [options]=\"state.options\"\r\n optionLabel=\"name\"\r\n optionValue=\"id\"\r\n [placeholder]=\"placeholder() || state.source.name?.en || 'Select...'\"\r\n [readonly]=\"disabled() || readonly()\"\r\n [filter]=\"filter()\"\r\n [showClear]=\"true\"\r\n display=\"chip\"\r\n />\r\n } @else {\r\n <mt-select-field\r\n [field]=\"false\"\r\n [(ngModel)]=\"selections[state.source.levelId]\"\r\n (ngModelChange)=\"syncValue()\"\r\n [options]=\"state.options\"\r\n optionLabel=\"name\"\r\n optionValue=\"id\"\r\n [placeholder]=\"placeholder() || state.source.name?.en || 'Select...'\"\r\n [readonly]=\"disabled() || readonly()\"\r\n [filter]=\"filter()\"\r\n [loading]=\"state.loading\"\r\n [showClear]=\"true\"\r\n />\r\n }\r\n </div>\r\n }\r\n</div>\r\n\r\n<mt-field-validation [control]=\"ngControl?.control\"></mt-field-validation>\r\n" }]
215
221
  }], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "filter", required: false }] }], configuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "configuration", required: true }] }], context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: false }] }] } });
216
222
 
223
+ const PREDECESSOR_TYPE_BY_TOKEN = {
224
+ FS: 0,
225
+ SS: 1,
226
+ FF: 2,
227
+ SF: 3,
228
+ };
229
+ const PREDECESSOR_TOKEN_BY_TYPE = {
230
+ 0: 'FS',
231
+ 1: 'SS',
232
+ 2: 'FF',
233
+ 3: 'SF',
234
+ };
235
+ class SchedulePredecessorField {
236
+ predecessorCellTpl = viewChild.required('predecessorCellTpl');
237
+ typeCellTpl = viewChild.required('typeCellTpl');
238
+ lagCellTpl = viewChild.required('lagCellTpl');
239
+ label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
240
+ placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
241
+ readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : []));
242
+ required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : []));
243
+ configuration = input(null, ...(ngDevMode ? [{ debugName: "configuration" }] : []));
244
+ runtimeContext = input(null, ...(ngDevMode ? [{ debugName: "runtimeContext" }] : []));
245
+ loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
246
+ taskOptions = signal([], ...(ngDevMode ? [{ debugName: "taskOptions" }] : []));
247
+ rows = signal([], ...(ngDevMode ? [{ debugName: "rows" }] : []));
248
+ disabled = signal(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
249
+ typeOptions = computed(() => [
250
+ { label: 'FS', value: 0 },
251
+ { label: 'SS', value: 1 },
252
+ { label: 'FF', value: 2 },
253
+ { label: 'SF', value: 3 },
254
+ ], ...(ngDevMode ? [{ debugName: "typeOptions" }] : []));
255
+ availableTaskOptions = computed(() => {
256
+ const currentTaskId = this.runtimeContext()?.moduleDataId;
257
+ return this.taskOptions().filter((item) => String(item.value) !== String(currentTaskId ?? ''));
258
+ }, ...(ngDevMode ? [{ debugName: "availableTaskOptions" }] : []));
259
+ canAddRow = computed(() => !!this.runtimeContext()?.levelId &&
260
+ !!this.runtimeContext()?.levelDataId &&
261
+ this.availableTaskOptions().length > 0, ...(ngDevMode ? [{ debugName: "canAddRow" }] : []));
262
+ addTooltip = computed(() => this.canAddRow() ? undefined : this.texts().noAvailable, ...(ngDevMode ? [{ debugName: "addTooltip" }] : []));
263
+ pageSize = computed(() => this.rows().length > 0 ? this.rows().length : 1, ...(ngDevMode ? [{ debugName: "pageSize" }] : []));
264
+ columns = linkedSignal(() => [
265
+ {
266
+ key: 'predecessorId',
267
+ label: this.texts().predecessor,
268
+ type: 'custom',
269
+ customCellTpl: this.predecessorCellTpl(),
270
+ },
271
+ {
272
+ key: 'type',
273
+ label: this.texts().type,
274
+ type: 'custom',
275
+ customCellTpl: this.typeCellTpl(),
276
+ },
277
+ {
278
+ key: 'lagDays',
279
+ label: this.texts().lagDays,
280
+ type: 'custom',
281
+ customCellTpl: this.lagCellTpl(),
282
+ },
283
+ ], ...(ngDevMode ? [{ debugName: "columns" }] : []));
284
+ rowActions = computed(() => [
285
+ {
286
+ icon: 'general.trash-01',
287
+ color: 'danger',
288
+ variant: 'text',
289
+ tooltip: this.texts().delete,
290
+ hidden: () => this.disabled() || this.readonly(),
291
+ action: (row) => this.removeRow(row.key),
292
+ },
293
+ ], ...(ngDevMode ? [{ debugName: "rowActions" }] : []));
294
+ requiredValidator = Validators.required;
295
+ onTouched = () => { };
296
+ onModelChange = () => { };
297
+ ngControl = null;
298
+ http = inject(HttpClient);
299
+ transloco = inject(TranslocoService);
300
+ destroyRef = inject(DestroyRef);
301
+ activeLang = toSignal(this.transloco.langChanges$, {
302
+ initialValue: this.transloco.getActiveLang(),
303
+ });
304
+ rowKey = 0;
305
+ texts = computed(() => {
306
+ this.activeLang();
307
+ return {
308
+ noAvailable: this.transloco.translate('components.schedulePredecessorField.noAvailable'),
309
+ predecessor: this.transloco.translate('components.schedulePredecessorField.predecessor'),
310
+ type: this.transloco.translate('components.schedulePredecessorField.type'),
311
+ lagDays: this.transloco.translate('components.schedulePredecessorField.lagDays'),
312
+ delete: this.transloco.translate('components.schedulePredecessorField.delete'),
313
+ };
314
+ }, ...(ngDevMode ? [{ debugName: "texts" }] : []));
315
+ constructor() {
316
+ this.ngControl = inject(NgControl, { self: true, optional: true });
317
+ if (this.ngControl) {
318
+ this.ngControl.valueAccessor = this;
319
+ }
320
+ effect(() => {
321
+ if (this.ngControl?.control && this.required()) {
322
+ this.ngControl.control.addValidators(Validators.required);
323
+ this.ngControl.control.updateValueAndValidity();
324
+ }
325
+ });
326
+ effect(() => {
327
+ const context = this.runtimeContext();
328
+ const levelId = context?.levelId;
329
+ const levelDataId = context?.levelDataId;
330
+ if (levelId == null || levelDataId == null) {
331
+ this.taskOptions.set([]);
332
+ return;
333
+ }
334
+ untracked(() => this.loadTaskOptions(levelId, levelDataId));
335
+ });
336
+ }
337
+ addRow() {
338
+ if (this.disabled() || this.readonly() || !this.canAddRow()) {
339
+ return;
340
+ }
341
+ this.syncRows([
342
+ ...this.rows(),
343
+ {
344
+ key: this.nextRowKey(),
345
+ predecessorId: '',
346
+ type: 0,
347
+ lagDays: 0,
348
+ },
349
+ ]);
350
+ }
351
+ removeRow(key) {
352
+ if (this.disabled() || this.readonly()) {
353
+ return;
354
+ }
355
+ this.syncRows(this.rows().filter((row) => row.key !== key));
356
+ }
357
+ updateRow(key, patch) {
358
+ if (this.disabled() || this.readonly()) {
359
+ return;
360
+ }
361
+ this.syncRows(this.rows().map((row) => (row.key === key ? { ...row, ...patch } : row)));
362
+ }
363
+ writeValue(value) {
364
+ const rows = typeof value === 'string'
365
+ ? value
366
+ .split(',')
367
+ .map((item) => item.trim())
368
+ .filter(Boolean)
369
+ .map((item) => this.parseCompactValue(item))
370
+ .filter((item) => item != null)
371
+ .map((item) => ({
372
+ key: this.nextRowKey(),
373
+ ...item,
374
+ }))
375
+ : [];
376
+ this.rows.set(rows);
377
+ }
378
+ registerOnChange(fn) {
379
+ this.onModelChange = fn;
380
+ }
381
+ registerOnTouched(fn) {
382
+ this.onTouched = fn;
383
+ }
384
+ setDisabledState(disabled) {
385
+ this.disabled.set(disabled);
386
+ }
387
+ syncRows(rows) {
388
+ this.rows.set(rows);
389
+ const value = rows
390
+ .filter((row) => row.predecessorId !== null &&
391
+ row.predecessorId !== undefined &&
392
+ String(row.predecessorId).trim() !== '')
393
+ .map((row) => this.formatCompactValue(row))
394
+ .join(',');
395
+ this.onModelChange(value || null);
396
+ this.onTouched();
397
+ }
398
+ loadTaskOptions(levelId, levelDataId) {
399
+ this.loading.set(true);
400
+ this.http
401
+ .post(`levels/${levelId}/${levelDataId}/schedule/query`, {
402
+ projection: 'Tree',
403
+ propertyKeys: ['name'],
404
+ })
405
+ .pipe(takeUntilDestroyed(this.destroyRef), finalize(() => this.loading.set(false)), catchError(() => of({ data: { records: [] } })))
406
+ .subscribe((response) => {
407
+ this.taskOptions.set(this.mapTaskOptions(response.data));
408
+ });
409
+ }
410
+ mapTaskOptions(data) {
411
+ return this.flattenRecords(this.resolveRootRecords(data?.records ?? [], data?.projectionMeta?.rootIds ?? [])).map((record) => ({
412
+ label: `${record.id} - ${record.name ?? record.id}`,
413
+ value: String(record.id),
414
+ }));
415
+ }
416
+ resolveRootRecords(records, rootIds) {
417
+ if (!rootIds?.length) {
418
+ return records;
419
+ }
420
+ const recordsById = new Map(records.map((record) => [String(record.id), record]));
421
+ return rootIds
422
+ .map((id) => recordsById.get(String(id)))
423
+ .filter((record) => record != null);
424
+ }
425
+ flattenRecords(records) {
426
+ const output = [];
427
+ const walk = (items) => {
428
+ items.forEach((item) => {
429
+ output.push(item);
430
+ walk(item.children ?? []);
431
+ });
432
+ };
433
+ walk(records);
434
+ return output;
435
+ }
436
+ nextRowKey() {
437
+ this.rowKey += 1;
438
+ return `predecessor-${this.rowKey}`;
439
+ }
440
+ parseCompactValue(value) {
441
+ const match = value.match(/^(.+?)(FS|SS|FF|SF)([+-]\d+)?$/);
442
+ if (!match) {
443
+ return null;
444
+ }
445
+ return {
446
+ predecessorId: match[1],
447
+ type: PREDECESSOR_TYPE_BY_TOKEN[match[2]],
448
+ lagDays: match[3] ? Number(match[3]) : 0,
449
+ };
450
+ }
451
+ formatCompactValue(row) {
452
+ const lag = row.lagDays > 0 ? `+${row.lagDays}` : row.lagDays < 0 ? row.lagDays : '';
453
+ return `${row.predecessorId}${PREDECESSOR_TOKEN_BY_TYPE[row.type]}${lag}`;
454
+ }
455
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: SchedulePredecessorField, deps: [], target: i0.ɵɵFactoryTarget.Component });
456
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: SchedulePredecessorField, isStandalone: true, selector: "mt-schedule-predecessor-field", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, configuration: { classPropertyName: "configuration", publicName: "configuration", isSignal: true, isRequired: false, transformFunction: null }, runtimeContext: { classPropertyName: "runtimeContext", publicName: "runtimeContext", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "grid gap-1" }, viewQueries: [{ propertyName: "predecessorCellTpl", first: true, predicate: ["predecessorCellTpl"], descendants: true, isSignal: true }, { propertyName: "typeCellTpl", first: true, predicate: ["typeCellTpl"], descendants: true, isSignal: true }, { propertyName: "lagCellTpl", first: true, predicate: ["lagCellTpl"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (label()) {\r\n <label\r\n [class.required]=\"ngControl?.control?.hasValidator(requiredValidator)\"\r\n [for]=\"ngControl?.name || label()\"\r\n >\r\n {{ label() }}\r\n </label>\r\n}\r\n\r\n<div class=\"grid gap-3\">\r\n <div class=\"flex items-center justify-end\">\r\n <mt-button\r\n icon=\"general.plus\"\r\n [label]=\"'components.schedulePredecessorField.add' | transloco\"\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n [disabled]=\"disabled() || readonly() || !canAddRow()\"\r\n [tooltip]=\"addTooltip()\"\r\n (onClick)=\"addRow()\"\r\n />\r\n </div>\r\n\r\n <ng-template #predecessorCellTpl let-row>\r\n <mt-select-field\r\n [field]=\"false\"\r\n [options]=\"availableTaskOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"\r\n placeholder() ||\r\n ('components.schedulePredecessorField.selectPredecessor' | transloco)\r\n \"\r\n [filter]=\"true\"\r\n [showClear]=\"true\"\r\n [loading]=\"loading()\"\r\n [readonly]=\"disabled() || readonly()\"\r\n [ngModel]=\"row.predecessorId || undefined\"\r\n (onChange)=\"updateRow(row.key, { predecessorId: $event ?? '' })\"\r\n />\r\n </ng-template>\r\n\r\n <ng-template #typeCellTpl let-row>\r\n <mt-select-field\r\n [field]=\"false\"\r\n [options]=\"typeOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [readonly]=\"disabled() || readonly()\"\r\n [ngModel]=\"row.type\"\r\n (onChange)=\"updateRow(row.key, { type: $event ?? 0 })\"\r\n />\r\n </ng-template>\r\n\r\n <ng-template #lagCellTpl let-row>\r\n <mt-number-field\r\n [field]=\"false\"\r\n [useGrouping]=\"false\"\r\n [placeholder]=\"'components.schedulePredecessorField.lagDays' | transloco\"\r\n [readonly]=\"disabled() || readonly()\"\r\n [ngModel]=\"row.lagDays\"\r\n (ngModelChange)=\"updateRow(row.key, { lagDays: $event ?? 0 })\"\r\n />\r\n </ng-template>\r\n\r\n <mt-table\r\n [data]=\"rows()\"\r\n [columns]=\"columns()\"\r\n [rowActions]=\"rowActions()\"\r\n [pageSize]=\"pageSize()\"\r\n [generalSearch]=\"false\"\r\n [showFilters]=\"false\"\r\n [dataKey]=\"'key'\"\r\n [loading]=\"loading()\"\r\n >\r\n <ng-template #empty>\r\n <div\r\n class=\"rounded-xl border border-dashed border-surface px-4 py-5 text-sm text-muted-color\"\r\n >\r\n {{ \"components.schedulePredecessorField.empty\" | transloco }}\r\n </div>\r\n </ng-template>\r\n </mt-table>\r\n</div>\r\n\r\n<mt-field-validation [control]=\"ngControl?.control\"></mt-field-validation>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: FieldValidation, selector: "mt-field-validation", inputs: ["control", "touched"] }, { kind: "component", type: NumberField, selector: "mt-number-field", inputs: ["field", "label", "placeholder", "class", "readonly", "pInputs", "format", "useGrouping", "maxFractionDigits", "min", "max", "required"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: Table, selector: "mt-table", inputs: ["filters", "data", "columns", "rowActions", "size", "showGridlines", "stripedRows", "selectableRows", "clickableRows", "generalSearch", "showFilters", "loading", "updating", "lazy", "lazyTotalRecords", "reorderableColumns", "reorderableRows", "dataKey", "exportable", "exportFilename", "actionShape", "tabs", "tabsOptionLabel", "tabsOptionValue", "activeTab", "actions", "paginatorPosition", "pageSize", "currentPage", "first", "filterTerm"], outputs: ["selectionChange", "cellChange", "lazyLoad", "columnReorder", "rowReorder", "rowClick", "filtersChange", "activeTabChange", "onTabChange", "pageSizeChange", "currentPageChange", "firstChange", "filterTermChange"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i2.TranslocoPipe, name: "transloco" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
457
+ }
458
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: SchedulePredecessorField, decorators: [{
459
+ type: Component,
460
+ args: [{ selector: 'mt-schedule-predecessor-field', standalone: true, imports: [
461
+ CommonModule,
462
+ FormsModule,
463
+ Button,
464
+ FieldValidation,
465
+ NumberField,
466
+ SelectField,
467
+ Table,
468
+ TranslocoModule,
469
+ ], changeDetection: ChangeDetectionStrategy.OnPush, host: {
470
+ class: 'grid gap-1',
471
+ }, template: "@if (label()) {\r\n <label\r\n [class.required]=\"ngControl?.control?.hasValidator(requiredValidator)\"\r\n [for]=\"ngControl?.name || label()\"\r\n >\r\n {{ label() }}\r\n </label>\r\n}\r\n\r\n<div class=\"grid gap-3\">\r\n <div class=\"flex items-center justify-end\">\r\n <mt-button\r\n icon=\"general.plus\"\r\n [label]=\"'components.schedulePredecessorField.add' | transloco\"\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n [disabled]=\"disabled() || readonly() || !canAddRow()\"\r\n [tooltip]=\"addTooltip()\"\r\n (onClick)=\"addRow()\"\r\n />\r\n </div>\r\n\r\n <ng-template #predecessorCellTpl let-row>\r\n <mt-select-field\r\n [field]=\"false\"\r\n [options]=\"availableTaskOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"\r\n placeholder() ||\r\n ('components.schedulePredecessorField.selectPredecessor' | transloco)\r\n \"\r\n [filter]=\"true\"\r\n [showClear]=\"true\"\r\n [loading]=\"loading()\"\r\n [readonly]=\"disabled() || readonly()\"\r\n [ngModel]=\"row.predecessorId || undefined\"\r\n (onChange)=\"updateRow(row.key, { predecessorId: $event ?? '' })\"\r\n />\r\n </ng-template>\r\n\r\n <ng-template #typeCellTpl let-row>\r\n <mt-select-field\r\n [field]=\"false\"\r\n [options]=\"typeOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [readonly]=\"disabled() || readonly()\"\r\n [ngModel]=\"row.type\"\r\n (onChange)=\"updateRow(row.key, { type: $event ?? 0 })\"\r\n />\r\n </ng-template>\r\n\r\n <ng-template #lagCellTpl let-row>\r\n <mt-number-field\r\n [field]=\"false\"\r\n [useGrouping]=\"false\"\r\n [placeholder]=\"'components.schedulePredecessorField.lagDays' | transloco\"\r\n [readonly]=\"disabled() || readonly()\"\r\n [ngModel]=\"row.lagDays\"\r\n (ngModelChange)=\"updateRow(row.key, { lagDays: $event ?? 0 })\"\r\n />\r\n </ng-template>\r\n\r\n <mt-table\r\n [data]=\"rows()\"\r\n [columns]=\"columns()\"\r\n [rowActions]=\"rowActions()\"\r\n [pageSize]=\"pageSize()\"\r\n [generalSearch]=\"false\"\r\n [showFilters]=\"false\"\r\n [dataKey]=\"'key'\"\r\n [loading]=\"loading()\"\r\n >\r\n <ng-template #empty>\r\n <div\r\n class=\"rounded-xl border border-dashed border-surface px-4 py-5 text-sm text-muted-color\"\r\n >\r\n {{ \"components.schedulePredecessorField.empty\" | transloco }}\r\n </div>\r\n </ng-template>\r\n </mt-table>\r\n</div>\r\n\r\n<mt-field-validation [control]=\"ngControl?.control\"></mt-field-validation>\r\n" }]
472
+ }], ctorParameters: () => [], propDecorators: { predecessorCellTpl: [{ type: i0.ViewChild, args: ['predecessorCellTpl', { isSignal: true }] }], typeCellTpl: [{ type: i0.ViewChild, args: ['typeCellTpl', { isSignal: true }] }], lagCellTpl: [{ type: i0.ViewChild, args: ['lagCellTpl', { isSignal: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], configuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "configuration", required: false }] }], runtimeContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "runtimeContext", required: false }] }] } });
473
+
217
474
  /**
218
475
  * Generated bundle index. Do not edit.
219
476
  */
220
477
 
221
- export { SchemaConnectionField };
478
+ export { SchedulePredecessorField, SchemaConnectionField };
222
479
  //# sourceMappingURL=masterteam-components-business-fields.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"masterteam-components-business-fields.mjs","sources":["../../../../packages/masterteam/components/business-fields/schema-connection-field/schema-connection-field.ts","../../../../packages/masterteam/components/business-fields/schema-connection-field/schema-connection-field.html","../../../../packages/masterteam/components/business-fields/masterteam-components-business-fields.ts"],"sourcesContent":["import {\r\n Component,\r\n signal,\r\n input,\r\n computed,\r\n inject,\r\n ChangeDetectionStrategy,\r\n effect,\r\n untracked,\r\n DestroyRef,\r\n} from '@angular/core';\r\nimport {\r\n ControlValueAccessor,\r\n FormsModule,\r\n NgControl,\r\n Validators,\r\n} from '@angular/forms';\r\nimport { SelectField } from '@masterteam/components/select-field';\r\nimport { MultiSelectField } from '@masterteam/components/multi-select-field';\r\nimport { FieldValidation } from '@masterteam/components/field-validation';\r\nimport { HttpClient, HttpContext } from '@angular/common/http';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\nimport { finalize, catchError, of } from 'rxjs';\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/**\r\n * One source level inside connection configuration.\r\n * Comes from `field.propertyMetadata.configuration.sourceLevels[]`\r\n */\r\nexport interface ConnectionSourceLevel {\r\n levelId: number;\r\n levelKey: string;\r\n name: { en?: string; ar?: string; [k: string]: string | undefined };\r\n connectionId: number;\r\n isOptional: boolean;\r\n allowManyToMany: boolean;\r\n supportWeights: boolean;\r\n optionsQuery: {\r\n path: string;\r\n method?: string;\r\n query?: Record<string, unknown>;\r\n };\r\n}\r\n\r\n/**\r\n * Full connection configuration from `field.propertyMetadata.configuration`.\r\n * This is passed as a single input to the component.\r\n */\r\nexport interface SchemaConnectionConfig {\r\n targetLevelId: number;\r\n sourceLevelId?: number;\r\n propertyKey?: string;\r\n valueMode?: string;\r\n sourceLevels: ConnectionSourceLevel[];\r\n payloadTemplate?: { levelId: number; sources: any[] };\r\n sourceItemShape?: Record<string, string>;\r\n}\r\n\r\n/** One selected source in the connection payload */\r\nexport interface ConnectionSource {\r\n sourceLevelId: number;\r\n sourceLevelDataId: number;\r\n}\r\n\r\n/** The value shape for a connection field */\r\nexport interface ConnectionPayload {\r\n levelId: number;\r\n sources: ConnectionSource[];\r\n}\r\n\r\n/**\r\n * Internal state tracked per source level dropdown.\r\n */\r\nexport interface SourceLevelState {\r\n source: ConnectionSourceLevel;\r\n options: any[];\r\n loading: boolean;\r\n}\r\n\r\n@Component({\r\n selector: 'mt-schema-connection-field',\r\n standalone: true,\r\n imports: [FormsModule, SelectField, MultiSelectField, FieldValidation],\r\n templateUrl: './schema-connection-field.html',\r\n styleUrls: ['./schema-connection-field.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n host: {\r\n class: 'grid gap-1',\r\n },\r\n})\r\nexport class SchemaConnectionField implements ControlValueAccessor {\r\n // ============================================================================\r\n // Inputs\r\n // ============================================================================\r\n\r\n readonly label = input<string>('');\r\n readonly placeholder = input<string>('');\r\n readonly readonly = input<boolean>(false);\r\n readonly required = input<boolean>(false);\r\n readonly filter = input<boolean>(true);\r\n\r\n /**\r\n * Full connection configuration object from the API.\r\n * Includes `targetLevelId`, `sourceLevels[]`, `payloadTemplate`, etc.\r\n */\r\n readonly configuration = input.required<SchemaConnectionConfig>();\r\n\r\n /**\r\n * Optional HttpContext for API requests (e.g. to set base URL behavior).\r\n */\r\n readonly context = input<HttpContext | undefined>(undefined);\r\n\r\n // ============================================================================\r\n // Internal State\r\n // ============================================================================\r\n\r\n /** The full ConnectionPayload value */\r\n value = signal<ConnectionPayload | null>(null);\r\n disabled = signal<boolean>(false);\r\n\r\n /** Per-source-level state: options + loading */\r\n sourceLevelStates = signal<SourceLevelState[]>([]);\r\n\r\n /** Mutable selections per source level: sourceLevelId -> selected value */\r\n selections: Record<number, any> = {};\r\n\r\n requiredValidator = Validators.required;\r\n onTouched: () => void = () => {};\r\n onModelChange: (value: ConnectionPayload | null) => void = () => {};\r\n\r\n public ngControl: NgControl | null = null;\r\n private http = inject(HttpClient);\r\n private destroyRef = inject(DestroyRef);\r\n\r\n /**\r\n * Source levels from configuration.\r\n */\r\n readonly sourceLevels = computed<ConnectionSourceLevel[]>(() => {\r\n return this.configuration()?.sourceLevels ?? [];\r\n });\r\n\r\n /**\r\n * Percentage width for each dropdown, evenly divided.\r\n */\r\n readonly dropdownWidth = computed<string>(() => {\r\n const count = this.sourceLevels().length;\r\n if (count <= 0) return '100%';\r\n return `${100 / count}%`;\r\n });\r\n\r\n constructor() {\r\n this.ngControl = inject(NgControl, { self: true, optional: true });\r\n if (this.ngControl) {\r\n this.ngControl.valueAccessor = this;\r\n }\r\n\r\n effect(() => {\r\n if (this.ngControl?.control && this.required()) {\r\n this.ngControl.control.addValidators(Validators.required);\r\n this.ngControl.control.updateValueAndValidity();\r\n }\r\n });\r\n\r\n // Load options for each source level when configuration changes\r\n effect(() => {\r\n const levels = this.sourceLevels();\r\n if (!levels.length) return;\r\n\r\n // Everything below must NOT create signal dependencies,\r\n // only sourceLevels() (→ configuration) should trigger this effect.\r\n untracked(() => {\r\n // Initialize per-source states + selections\r\n this.sourceLevelStates.set(\r\n levels.map((source) => ({\r\n source,\r\n options: [],\r\n loading: false,\r\n })),\r\n );\r\n\r\n for (const source of levels) {\r\n if (!(source.levelId in this.selections)) {\r\n this.selections[source.levelId] = source.allowManyToMany\r\n ? []\r\n : null;\r\n }\r\n }\r\n\r\n // Distribute existing value to selections\r\n this.distributeToSelections(this.value());\r\n\r\n // Load options for each source level\r\n for (const source of levels) {\r\n this.loadOptions(source);\r\n }\r\n });\r\n });\r\n }\r\n\r\n // ============================================================================\r\n // Option Loading (per source level)\r\n // ============================================================================\r\n\r\n private loadOptions(source: ConnectionSourceLevel): void {\r\n this.updateSourceState(source.levelId, { loading: true });\r\n\r\n const ctx = this.context();\r\n const payload = {\r\n contextKey: `level:${source.levelId}`,\r\n projection: 'Flat',\r\n propertyKeys: ['name'],\r\n };\r\n\r\n this.http\r\n .post<unknown>('fetch/query', payload, {\r\n ...(ctx ? { context: ctx } : {}),\r\n })\r\n .pipe(\r\n takeUntilDestroyed(this.destroyRef),\r\n finalize(() =>\r\n this.updateSourceState(source.levelId, { loading: false }),\r\n ),\r\n catchError((err) => {\r\n console.error(\r\n `Connection options load failed for ${source.levelKey}:`,\r\n err,\r\n );\r\n return of({ data: { records: [] } });\r\n }),\r\n )\r\n .subscribe((response: any) => {\r\n const options = (response?.data?.records ?? [])\r\n .filter((record: any) => record?.id != null)\r\n .map((record: any) => ({\r\n ...record,\r\n id: record.id,\r\n name: record.name,\r\n }));\r\n\r\n this.updateSourceState(source.levelId, {\r\n options,\r\n loading: false,\r\n });\r\n });\r\n }\r\n\r\n private updateSourceState(\r\n levelId: number,\r\n patch: Partial<Pick<SourceLevelState, 'options' | 'loading'>>,\r\n ): void {\r\n this.sourceLevelStates.update((states) =>\r\n states.map((s) =>\r\n s.source.levelId === levelId ? { ...s, ...patch } : s,\r\n ),\r\n );\r\n }\r\n\r\n // ============================================================================\r\n // Value Handling\r\n // ============================================================================\r\n\r\n /**\r\n * Single handler — no params. Reads all selections, builds the combined payload.\r\n */\r\n syncValue(): void {\r\n const cfg = this.configuration();\r\n const states = this.sourceLevelStates();\r\n const sources: ConnectionSource[] = [];\r\n\r\n for (const state of states) {\r\n const val = this.selections[state.source.levelId];\r\n if (val == null) continue;\r\n\r\n if (state.source.allowManyToMany && Array.isArray(val)) {\r\n for (const id of val) {\r\n sources.push({\r\n sourceLevelId: state.source.levelId,\r\n sourceLevelDataId: id,\r\n });\r\n }\r\n } else if (typeof val === 'number') {\r\n sources.push({\r\n sourceLevelId: state.source.levelId,\r\n sourceLevelDataId: val,\r\n });\r\n }\r\n }\r\n\r\n const payload: ConnectionPayload | null =\r\n sources.length > 0 ? { levelId: cfg.targetLevelId, sources } : null;\r\n\r\n this.value.set(payload);\r\n this.onModelChange(payload);\r\n this.onTouched();\r\n }\r\n\r\n private distributeToSelections(payload: ConnectionPayload | null): void {\r\n const states = this.sourceLevelStates();\r\n for (const state of states) {\r\n const ids = (payload?.sources ?? [])\r\n .filter((s) => s.sourceLevelId === state.source.levelId)\r\n .map((s) => s.sourceLevelDataId);\r\n\r\n this.selections[state.source.levelId] = state.source.allowManyToMany\r\n ? ids\r\n : (ids[0] ?? null);\r\n }\r\n }\r\n\r\n // ============================================================================\r\n // ControlValueAccessor\r\n // ============================================================================\r\n\r\n writeValue(value: ConnectionPayload | string | null): void {\r\n if (typeof value === 'string') {\r\n try {\r\n value = JSON.parse(value) as ConnectionPayload;\r\n } catch {\r\n value = null;\r\n }\r\n }\r\n this.value.set(value ?? null);\r\n this.distributeToSelections(value ?? null);\r\n }\r\n\r\n registerOnChange(fn: (value: ConnectionPayload | null) => void): void {\r\n this.onModelChange = fn;\r\n }\r\n\r\n registerOnTouched(fn: any): void {\r\n this.onTouched = fn;\r\n }\r\n\r\n setDisabledState(disabled: boolean): void {\r\n this.disabled.set(disabled);\r\n }\r\n}\r\n","<!-- @if (label()) {\r\n <label\r\n [class.required]=\"ngControl?.control?.hasValidator(requiredValidator)\"\r\n [for]=\"ngControl?.name || label()\"\r\n >\r\n {{ label() }}\r\n </label>\r\n} -->\r\n\r\n<div class=\"flex gap-4 w-full\">\r\n @for (state of sourceLevelStates(); track state.source.levelId) {\r\n <div [style.width]=\"dropdownWidth()\" class=\"min-w-0\">\r\n @if (sourceLevelStates().length > 1) {\r\n <span class=\"text-sm text-muted-color mb-1 block truncate\">\r\n {{ state.source.name?.en || state.source.levelKey }}\r\n </span>\r\n }\r\n\r\n @if (state.source.allowManyToMany) {\r\n <mt-multi-select-field\r\n [field]=\"false\"\r\n [(ngModel)]=\"selections[state.source.levelId]\"\r\n (ngModelChange)=\"syncValue()\"\r\n [options]=\"state.options\"\r\n optionLabel=\"name\"\r\n optionValue=\"id\"\r\n [placeholder]=\"placeholder() || state.source.name?.en || 'Select...'\"\r\n [readonly]=\"disabled() || readonly()\"\r\n [filter]=\"filter()\"\r\n [showClear]=\"true\"\r\n display=\"chip\"\r\n />\r\n } @else {\r\n <mt-select-field\r\n [field]=\"false\"\r\n [(ngModel)]=\"selections[state.source.levelId]\"\r\n (ngModelChange)=\"syncValue()\"\r\n [options]=\"state.options\"\r\n optionLabel=\"name\"\r\n optionValue=\"id\"\r\n [placeholder]=\"placeholder() || state.source.name?.en || 'Select...'\"\r\n [readonly]=\"disabled() || readonly()\"\r\n [filter]=\"filter()\"\r\n [loading]=\"state.loading\"\r\n [showClear]=\"true\"\r\n />\r\n }\r\n </div>\r\n }\r\n</div>\r\n\r\n<mt-field-validation [control]=\"ngControl?.control\"></mt-field-validation>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"masterteam-components-business-fields.mjs","sources":["../../../../packages/masterteam/components/business-fields/schema-connection-field/schema-connection-field.ts","../../../../packages/masterteam/components/business-fields/schema-connection-field/schema-connection-field.html","../../../../packages/masterteam/components/business-fields/schedule-predecessor-field/schedule-predecessor-field.ts","../../../../packages/masterteam/components/business-fields/schedule-predecessor-field/schedule-predecessor-field.html","../../../../packages/masterteam/components/business-fields/masterteam-components-business-fields.ts"],"sourcesContent":["import {\r\n Component,\r\n signal,\r\n input,\r\n computed,\r\n inject,\r\n ChangeDetectionStrategy,\r\n effect,\r\n untracked,\r\n DestroyRef,\r\n} from '@angular/core';\r\nimport {\r\n ControlValueAccessor,\r\n FormsModule,\r\n NgControl,\r\n Validators,\r\n} from '@angular/forms';\r\nimport { SelectField } from '@masterteam/components/select-field';\r\nimport { MultiSelectField } from '@masterteam/components/multi-select-field';\r\nimport { FieldValidation } from '@masterteam/components/field-validation';\r\nimport { HttpClient, HttpContext } from '@angular/common/http';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\nimport { finalize, catchError, of } from 'rxjs';\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/**\r\n * One source level inside connection configuration.\r\n * Comes from `field.propertyMetadata.configuration.sourceLevels[]`\r\n */\r\nexport interface ConnectionSourceLevel {\r\n levelId: number;\r\n levelKey: string;\r\n name: { en?: string; ar?: string; [k: string]: string | undefined };\r\n connectionId: number;\r\n isOptional: boolean;\r\n allowManyToMany: boolean;\r\n supportWeights: boolean;\r\n optionsQuery: {\r\n path: string;\r\n method?: string;\r\n query?: Record<string, unknown>;\r\n };\r\n}\r\n\r\n/**\r\n * Full connection configuration from `field.propertyMetadata.configuration`.\r\n * This is passed as a single input to the component.\r\n */\r\nexport interface SchemaConnectionConfig {\r\n targetLevelId: number;\r\n sourceLevelId?: number;\r\n propertyKey?: string;\r\n valueMode?: string;\r\n sourceLevels: ConnectionSourceLevel[];\r\n payloadTemplate?: { levelId: number; sources: any[] };\r\n sourceItemShape?: Record<string, string>;\r\n}\r\n\r\n/** One selected source in the connection payload */\r\nexport interface ConnectionSource {\r\n sourceLevelId: number;\r\n sourceLevelDataId: number;\r\n}\r\n\r\n/** The value shape for a connection field */\r\nexport interface ConnectionPayload {\r\n levelId: number;\r\n sources: ConnectionSource[];\r\n}\r\n\r\n/**\r\n * Internal state tracked per source level dropdown.\r\n */\r\nexport interface SourceLevelState {\r\n source: ConnectionSourceLevel;\r\n options: any[];\r\n loading: boolean;\r\n}\r\n\r\n@Component({\r\n selector: 'mt-schema-connection-field',\r\n standalone: true,\r\n imports: [FormsModule, SelectField, MultiSelectField, FieldValidation],\r\n templateUrl: './schema-connection-field.html',\r\n styleUrls: ['./schema-connection-field.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n host: {\r\n class: 'grid gap-1',\r\n },\r\n})\r\nexport class SchemaConnectionField implements ControlValueAccessor {\r\n // ============================================================================\r\n // Inputs\r\n // ============================================================================\r\n\r\n readonly label = input<string>('');\r\n readonly placeholder = input<string>('');\r\n readonly readonly = input<boolean>(false);\r\n readonly required = input<boolean>(false);\r\n readonly filter = input<boolean>(true);\r\n\r\n /**\r\n * Full connection configuration object from the API.\r\n * Includes `targetLevelId`, `sourceLevels[]`, `payloadTemplate`, etc.\r\n */\r\n readonly configuration = input.required<SchemaConnectionConfig>();\r\n\r\n /**\r\n * Optional HttpContext for API requests (e.g. to set base URL behavior).\r\n */\r\n readonly context = input<HttpContext | undefined>(undefined);\r\n\r\n // ============================================================================\r\n // Internal State\r\n // ============================================================================\r\n\r\n /** The full ConnectionPayload value */\r\n value = signal<ConnectionPayload | null>(null);\r\n disabled = signal<boolean>(false);\r\n\r\n /** Per-source-level state: options + loading */\r\n sourceLevelStates = signal<SourceLevelState[]>([]);\r\n\r\n /** Mutable selections per source level: sourceLevelId -> selected value */\r\n selections: Record<number, any> = {};\r\n\r\n requiredValidator = Validators.required;\r\n onTouched: () => void = () => {};\r\n onModelChange: (value: ConnectionPayload | null) => void = () => {};\r\n\r\n public ngControl: NgControl | null = null;\r\n private http = inject(HttpClient);\r\n private destroyRef = inject(DestroyRef);\r\n\r\n /**\r\n * Source levels from configuration.\r\n */\r\n readonly sourceLevels = computed<ConnectionSourceLevel[]>(() => {\r\n return this.configuration()?.sourceLevels ?? [];\r\n });\r\n\r\n /**\r\n * Percentage width for each dropdown, evenly divided.\r\n */\r\n readonly dropdownWidth = computed<string>(() => {\r\n const count = this.sourceLevels().length;\r\n if (count <= 0) return '100%';\r\n return `${100 / count}%`;\r\n });\r\n\r\n constructor() {\r\n this.ngControl = inject(NgControl, { self: true, optional: true });\r\n if (this.ngControl) {\r\n this.ngControl.valueAccessor = this;\r\n }\r\n\r\n effect(() => {\r\n if (this.ngControl?.control && this.required()) {\r\n this.ngControl.control.addValidators(Validators.required);\r\n this.ngControl.control.updateValueAndValidity();\r\n }\r\n });\r\n\r\n // Load options for each source level when configuration changes\r\n effect(() => {\r\n const levels = this.sourceLevels();\r\n if (!levels.length) return;\r\n\r\n // Everything below must NOT create signal dependencies,\r\n // only sourceLevels() (→ configuration) should trigger this effect.\r\n untracked(() => {\r\n // Initialize per-source states + selections\r\n this.sourceLevelStates.set(\r\n levels.map((source) => ({\r\n source,\r\n options: [],\r\n loading: false,\r\n })),\r\n );\r\n\r\n for (const source of levels) {\r\n if (!(source.levelId in this.selections)) {\r\n this.selections[source.levelId] = source.allowManyToMany\r\n ? []\r\n : null;\r\n }\r\n }\r\n\r\n // Distribute existing value to selections\r\n this.distributeToSelections(this.value());\r\n\r\n // Load options for each source level\r\n for (const source of levels) {\r\n this.loadOptions(source);\r\n }\r\n });\r\n });\r\n }\r\n\r\n // ============================================================================\r\n // Option Loading (per source level)\r\n // ============================================================================\r\n\r\n private loadOptions(source: ConnectionSourceLevel): void {\r\n this.updateSourceState(source.levelId, { loading: true });\r\n\r\n const ctx = this.context();\r\n const payload = {\r\n contextKey: `level:${source.levelId}`,\r\n projection: 'Flat',\r\n propertyKeys: ['name'],\r\n };\r\n\r\n this.http\r\n .post<unknown>('fetch/query', payload, {\r\n ...(ctx ? { context: ctx } : {}),\r\n })\r\n .pipe(\r\n takeUntilDestroyed(this.destroyRef),\r\n finalize(() =>\r\n this.updateSourceState(source.levelId, { loading: false }),\r\n ),\r\n catchError((err) => {\r\n console.error(\r\n `Connection options load failed for ${source.levelKey}:`,\r\n err,\r\n );\r\n return of({ data: { records: [] } });\r\n }),\r\n )\r\n .subscribe((response: any) => {\r\n const options = (response?.data?.records ?? [])\r\n .filter((record: any) => record?.id != null)\r\n .map((record: any) => ({\r\n ...record,\r\n id: record.id,\r\n name: record.name,\r\n }));\r\n\r\n this.updateSourceState(source.levelId, {\r\n options,\r\n loading: false,\r\n });\r\n });\r\n }\r\n\r\n private updateSourceState(\r\n levelId: number,\r\n patch: Partial<Pick<SourceLevelState, 'options' | 'loading'>>,\r\n ): void {\r\n this.sourceLevelStates.update((states) =>\r\n states.map((s) =>\r\n s.source.levelId === levelId ? { ...s, ...patch } : s,\r\n ),\r\n );\r\n }\r\n\r\n // ============================================================================\r\n // Value Handling\r\n // ============================================================================\r\n\r\n /**\r\n * Single handler — no params. Reads all selections, builds the combined payload.\r\n */\r\n syncValue(): void {\r\n const cfg = this.configuration();\r\n const states = this.sourceLevelStates();\r\n const sources: ConnectionSource[] = [];\r\n\r\n for (const state of states) {\r\n const val = this.selections[state.source.levelId];\r\n if (val == null) continue;\r\n\r\n if (state.source.allowManyToMany && Array.isArray(val)) {\r\n for (const id of val) {\r\n sources.push({\r\n sourceLevelId: state.source.levelId,\r\n sourceLevelDataId: id,\r\n });\r\n }\r\n } else if (typeof val === 'number') {\r\n sources.push({\r\n sourceLevelId: state.source.levelId,\r\n sourceLevelDataId: val,\r\n });\r\n }\r\n }\r\n\r\n const payload: ConnectionPayload | null =\r\n sources.length > 0 ? { levelId: cfg.targetLevelId, sources } : null;\r\n\r\n this.value.set(payload);\r\n this.onModelChange(payload);\r\n this.onTouched();\r\n }\r\n\r\n private distributeToSelections(payload: ConnectionPayload | null): void {\r\n const states = this.sourceLevelStates();\r\n for (const state of states) {\r\n const ids = (payload?.sources ?? [])\r\n .filter((s) => s.sourceLevelId === state.source.levelId)\r\n .map((s) => s.sourceLevelDataId);\r\n\r\n this.selections[state.source.levelId] = state.source.allowManyToMany\r\n ? ids\r\n : (ids[0] ?? null);\r\n }\r\n }\r\n\r\n // ============================================================================\r\n // ControlValueAccessor\r\n // ============================================================================\r\n\r\n writeValue(value: ConnectionPayload | string | null): void {\r\n if (typeof value === 'string') {\r\n try {\r\n value = JSON.parse(value) as ConnectionPayload;\r\n } catch {\r\n value = null;\r\n }\r\n }\r\n this.value.set(value ?? null);\r\n this.distributeToSelections(value ?? null);\r\n }\r\n\r\n registerOnChange(fn: (value: ConnectionPayload | null) => void): void {\r\n this.onModelChange = fn;\r\n }\r\n\r\n registerOnTouched(fn: any): void {\r\n this.onTouched = fn;\r\n }\r\n\r\n setDisabledState(disabled: boolean): void {\r\n this.disabled.set(disabled);\r\n }\r\n}\r\n","<!-- @if (label()) {\r\n <label\r\n [class.required]=\"ngControl?.control?.hasValidator(requiredValidator)\"\r\n [for]=\"ngControl?.name || label()\"\r\n >\r\n {{ label() }}\r\n </label>\r\n} -->\r\n\r\n<div class=\"flex gap-4 w-full\">\r\n @for (state of sourceLevelStates(); track state.source.levelId) {\r\n <div [style.width]=\"dropdownWidth()\" class=\"min-w-0\">\r\n @if (sourceLevelStates().length > 1) {\r\n <span class=\"text-sm text-muted-color mb-1 block truncate\">\r\n {{ state.source.name?.en || state.source.levelKey }}\r\n </span>\r\n }\r\n\r\n @if (state.source.allowManyToMany) {\r\n <mt-multi-select-field\r\n [field]=\"false\"\r\n [(ngModel)]=\"selections[state.source.levelId]\"\r\n (ngModelChange)=\"syncValue()\"\r\n [options]=\"state.options\"\r\n optionLabel=\"name\"\r\n optionValue=\"id\"\r\n [placeholder]=\"placeholder() || state.source.name?.en || 'Select...'\"\r\n [readonly]=\"disabled() || readonly()\"\r\n [filter]=\"filter()\"\r\n [showClear]=\"true\"\r\n display=\"chip\"\r\n />\r\n } @else {\r\n <mt-select-field\r\n [field]=\"false\"\r\n [(ngModel)]=\"selections[state.source.levelId]\"\r\n (ngModelChange)=\"syncValue()\"\r\n [options]=\"state.options\"\r\n optionLabel=\"name\"\r\n optionValue=\"id\"\r\n [placeholder]=\"placeholder() || state.source.name?.en || 'Select...'\"\r\n [readonly]=\"disabled() || readonly()\"\r\n [filter]=\"filter()\"\r\n [loading]=\"state.loading\"\r\n [showClear]=\"true\"\r\n />\r\n }\r\n </div>\r\n }\r\n</div>\r\n\r\n<mt-field-validation [control]=\"ngControl?.control\"></mt-field-validation>\r\n","import { CommonModule } from '@angular/common';\r\nimport {\r\n ChangeDetectionStrategy,\r\n Component,\r\n computed,\r\n DestroyRef,\r\n effect,\r\n inject,\r\n input,\r\n linkedSignal,\r\n signal,\r\n TemplateRef,\r\n untracked,\r\n viewChild,\r\n} from '@angular/core';\r\nimport { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';\r\nimport {\r\n ControlValueAccessor,\r\n FormsModule,\r\n NgControl,\r\n Validators,\r\n} from '@angular/forms';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { catchError, finalize, of } from 'rxjs';\r\nimport { TranslocoModule, TranslocoService } from '@jsverse/transloco';\r\nimport { Button } from '@masterteam/components/button';\r\nimport { FieldValidation } from '@masterteam/components/field-validation';\r\nimport { NumberField } from '@masterteam/components/number-field';\r\nimport { SelectField } from '@masterteam/components/select-field';\r\nimport {\r\n Table,\r\n type ColumnDef,\r\n type TableAction,\r\n} from '@masterteam/components/table';\r\nimport type { SchedulePredecessorFieldRuntimeContext } from '@masterteam/components';\r\n\r\ntype PredecessorType = 0 | 1 | 2 | 3;\r\ntype PredecessorTypeToken = 'FS' | 'SS' | 'FF' | 'SF';\r\n\r\ninterface ScheduleQueryRecord {\r\n id: number | string;\r\n name?: string | null;\r\n children?: ScheduleQueryRecord[] | null;\r\n}\r\n\r\ninterface ScheduleQueryData {\r\n records?: ScheduleQueryRecord[] | null;\r\n projectionMeta?: {\r\n rootIds?: Array<number | string> | null;\r\n } | null;\r\n}\r\n\r\ninterface ScheduleQueryResponse {\r\n data?: ScheduleQueryData | null;\r\n}\r\n\r\ninterface SchedulePredecessorValue {\r\n predecessorId: number | string;\r\n type: PredecessorType;\r\n lagDays: number;\r\n}\r\n\r\ninterface SchedulePredecessorRow extends SchedulePredecessorValue {\r\n key: string;\r\n}\r\n\r\ninterface SelectOption {\r\n label: string;\r\n value: number | string;\r\n}\r\n\r\nconst PREDECESSOR_TYPE_BY_TOKEN: Record<PredecessorTypeToken, PredecessorType> =\r\n {\r\n FS: 0,\r\n SS: 1,\r\n FF: 2,\r\n SF: 3,\r\n };\r\n\r\nconst PREDECESSOR_TOKEN_BY_TYPE: Record<PredecessorType, PredecessorTypeToken> =\r\n {\r\n 0: 'FS',\r\n 1: 'SS',\r\n 2: 'FF',\r\n 3: 'SF',\r\n };\r\n\r\n@Component({\r\n selector: 'mt-schedule-predecessor-field',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n Button,\r\n FieldValidation,\r\n NumberField,\r\n SelectField,\r\n Table,\r\n TranslocoModule,\r\n ],\r\n templateUrl: './schedule-predecessor-field.html',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n host: {\r\n class: 'grid gap-1',\r\n },\r\n})\r\nexport class SchedulePredecessorField implements ControlValueAccessor {\r\n private readonly predecessorCellTpl =\r\n viewChild.required<TemplateRef<any>>('predecessorCellTpl');\r\n private readonly typeCellTpl =\r\n viewChild.required<TemplateRef<any>>('typeCellTpl');\r\n private readonly lagCellTpl =\r\n viewChild.required<TemplateRef<any>>('lagCellTpl');\r\n\r\n readonly label = input<string>('');\r\n readonly placeholder = input<string>('');\r\n readonly readonly = input<boolean>(false);\r\n readonly required = input<boolean>(false);\r\n readonly configuration = input<unknown>(null);\r\n readonly runtimeContext =\r\n input<SchedulePredecessorFieldRuntimeContext | null>(null);\r\n\r\n readonly loading = signal(false);\r\n readonly taskOptions = signal<SelectOption[]>([]);\r\n readonly rows = signal<SchedulePredecessorRow[]>([]);\r\n readonly disabled = signal(false);\r\n\r\n readonly typeOptions = computed<SelectOption[]>(() => [\r\n { label: 'FS', value: 0 },\r\n { label: 'SS', value: 1 },\r\n { label: 'FF', value: 2 },\r\n { label: 'SF', value: 3 },\r\n ]);\r\n\r\n readonly availableTaskOptions = computed(() => {\r\n const currentTaskId = this.runtimeContext()?.moduleDataId;\r\n return this.taskOptions().filter(\r\n (item) => String(item.value) !== String(currentTaskId ?? ''),\r\n );\r\n });\r\n\r\n readonly canAddRow = computed(\r\n () =>\r\n !!this.runtimeContext()?.levelId &&\r\n !!this.runtimeContext()?.levelDataId &&\r\n this.availableTaskOptions().length > 0,\r\n );\r\n\r\n readonly addTooltip = computed(() =>\r\n this.canAddRow() ? undefined : this.texts().noAvailable,\r\n );\r\n readonly pageSize = computed(() =>\r\n this.rows().length > 0 ? this.rows().length : 1,\r\n );\r\n\r\n readonly columns = linkedSignal<ColumnDef[]>(() => [\r\n {\r\n key: 'predecessorId',\r\n label: this.texts().predecessor,\r\n type: 'custom',\r\n customCellTpl: this.predecessorCellTpl(),\r\n },\r\n {\r\n key: 'type',\r\n label: this.texts().type,\r\n type: 'custom',\r\n customCellTpl: this.typeCellTpl(),\r\n },\r\n {\r\n key: 'lagDays',\r\n label: this.texts().lagDays,\r\n type: 'custom',\r\n customCellTpl: this.lagCellTpl(),\r\n },\r\n ]);\r\n\r\n readonly rowActions = computed<TableAction[]>(() => [\r\n {\r\n icon: 'general.trash-01',\r\n color: 'danger',\r\n variant: 'text',\r\n tooltip: this.texts().delete,\r\n hidden: () => this.disabled() || this.readonly(),\r\n action: (row) => this.removeRow(row.key),\r\n },\r\n ]);\r\n\r\n requiredValidator = Validators.required;\r\n onTouched: () => void = () => {};\r\n onModelChange: (value: string | null) => void = () => {};\r\n\r\n public ngControl: NgControl | null = null;\r\n\r\n private readonly http = inject(HttpClient);\r\n private readonly transloco = inject(TranslocoService);\r\n private readonly destroyRef = inject(DestroyRef);\r\n private readonly activeLang = toSignal(this.transloco.langChanges$, {\r\n initialValue: this.transloco.getActiveLang(),\r\n });\r\n private rowKey = 0;\r\n\r\n readonly texts = computed(() => {\r\n this.activeLang();\r\n\r\n return {\r\n noAvailable: this.transloco.translate(\r\n 'components.schedulePredecessorField.noAvailable',\r\n ),\r\n predecessor: this.transloco.translate(\r\n 'components.schedulePredecessorField.predecessor',\r\n ),\r\n type: this.transloco.translate(\r\n 'components.schedulePredecessorField.type',\r\n ),\r\n lagDays: this.transloco.translate(\r\n 'components.schedulePredecessorField.lagDays',\r\n ),\r\n delete: this.transloco.translate(\r\n 'components.schedulePredecessorField.delete',\r\n ),\r\n };\r\n });\r\n\r\n constructor() {\r\n this.ngControl = inject(NgControl, { self: true, optional: true });\r\n if (this.ngControl) {\r\n this.ngControl.valueAccessor = this;\r\n }\r\n\r\n effect(() => {\r\n if (this.ngControl?.control && this.required()) {\r\n this.ngControl.control.addValidators(Validators.required);\r\n this.ngControl.control.updateValueAndValidity();\r\n }\r\n });\r\n\r\n effect(() => {\r\n const context = this.runtimeContext();\r\n const levelId = context?.levelId;\r\n const levelDataId = context?.levelDataId;\r\n\r\n if (levelId == null || levelDataId == null) {\r\n this.taskOptions.set([]);\r\n return;\r\n }\r\n\r\n untracked(() => this.loadTaskOptions(levelId, levelDataId));\r\n });\r\n }\r\n\r\n addRow(): void {\r\n if (this.disabled() || this.readonly() || !this.canAddRow()) {\r\n return;\r\n }\r\n\r\n this.syncRows([\r\n ...this.rows(),\r\n {\r\n key: this.nextRowKey(),\r\n predecessorId: '',\r\n type: 0,\r\n lagDays: 0,\r\n },\r\n ]);\r\n }\r\n\r\n removeRow(key: string): void {\r\n if (this.disabled() || this.readonly()) {\r\n return;\r\n }\r\n\r\n this.syncRows(this.rows().filter((row) => row.key !== key));\r\n }\r\n\r\n updateRow(key: string, patch: Partial<SchedulePredecessorRow>): void {\r\n if (this.disabled() || this.readonly()) {\r\n return;\r\n }\r\n\r\n this.syncRows(\r\n this.rows().map((row) => (row.key === key ? { ...row, ...patch } : row)),\r\n );\r\n }\r\n\r\n writeValue(value: unknown): void {\r\n const rows =\r\n typeof value === 'string'\r\n ? value\r\n .split(',')\r\n .map((item) => item.trim())\r\n .filter(Boolean)\r\n .map((item) => this.parseCompactValue(item))\r\n .filter((item): item is SchedulePredecessorValue => item != null)\r\n .map((item) => ({\r\n key: this.nextRowKey(),\r\n ...item,\r\n }))\r\n : [];\r\n\r\n this.rows.set(rows);\r\n }\r\n\r\n registerOnChange(fn: (value: string | null) => void): void {\r\n this.onModelChange = fn;\r\n }\r\n\r\n registerOnTouched(fn: () => void): void {\r\n this.onTouched = fn;\r\n }\r\n\r\n setDisabledState(disabled: boolean): void {\r\n this.disabled.set(disabled);\r\n }\r\n\r\n private syncRows(rows: SchedulePredecessorRow[]): void {\r\n this.rows.set(rows);\r\n const value = rows\r\n .filter(\r\n (row) =>\r\n row.predecessorId !== null &&\r\n row.predecessorId !== undefined &&\r\n String(row.predecessorId).trim() !== '',\r\n )\r\n .map((row) => this.formatCompactValue(row))\r\n .join(',');\r\n\r\n this.onModelChange(value || null);\r\n this.onTouched();\r\n }\r\n\r\n private loadTaskOptions(\r\n levelId: number | string,\r\n levelDataId: number | string,\r\n ): void {\r\n this.loading.set(true);\r\n\r\n this.http\r\n .post<ScheduleQueryResponse>(\r\n `levels/${levelId}/${levelDataId}/schedule/query`,\r\n {\r\n projection: 'Tree',\r\n propertyKeys: ['name'],\r\n },\r\n )\r\n .pipe(\r\n takeUntilDestroyed(this.destroyRef),\r\n finalize(() => this.loading.set(false)),\r\n catchError(() => of({ data: { records: [] } })),\r\n )\r\n .subscribe((response) => {\r\n this.taskOptions.set(this.mapTaskOptions(response.data));\r\n });\r\n }\r\n\r\n private mapTaskOptions(\r\n data: ScheduleQueryData | null | undefined,\r\n ): SelectOption[] {\r\n return this.flattenRecords(\r\n this.resolveRootRecords(\r\n data?.records ?? [],\r\n data?.projectionMeta?.rootIds ?? [],\r\n ),\r\n ).map((record) => ({\r\n label: `${record.id} - ${record.name ?? record.id}`,\r\n value: String(record.id),\r\n }));\r\n }\r\n\r\n private resolveRootRecords(\r\n records: ScheduleQueryRecord[],\r\n rootIds: Array<number | string> | null | undefined,\r\n ): ScheduleQueryRecord[] {\r\n if (!rootIds?.length) {\r\n return records;\r\n }\r\n\r\n const recordsById = new Map(\r\n records.map((record) => [String(record.id), record]),\r\n );\r\n\r\n return rootIds\r\n .map((id) => recordsById.get(String(id)))\r\n .filter((record): record is ScheduleQueryRecord => record != null);\r\n }\r\n\r\n private flattenRecords(\r\n records: ScheduleQueryRecord[],\r\n ): ScheduleQueryRecord[] {\r\n const output: ScheduleQueryRecord[] = [];\r\n\r\n const walk = (items: ScheduleQueryRecord[]): void => {\r\n items.forEach((item) => {\r\n output.push(item);\r\n walk(item.children ?? []);\r\n });\r\n };\r\n\r\n walk(records);\r\n return output;\r\n }\r\n\r\n private nextRowKey(): string {\r\n this.rowKey += 1;\r\n return `predecessor-${this.rowKey}`;\r\n }\r\n\r\n private parseCompactValue(value: string): SchedulePredecessorValue | null {\r\n const match = value.match(/^(.+?)(FS|SS|FF|SF)([+-]\\d+)?$/);\r\n\r\n if (!match) {\r\n return null;\r\n }\r\n\r\n return {\r\n predecessorId: match[1],\r\n type: PREDECESSOR_TYPE_BY_TOKEN[match[2] as PredecessorTypeToken],\r\n lagDays: match[3] ? Number(match[3]) : 0,\r\n };\r\n }\r\n\r\n private formatCompactValue(row: SchedulePredecessorValue): string {\r\n const lag =\r\n row.lagDays > 0 ? `+${row.lagDays}` : row.lagDays < 0 ? row.lagDays : '';\r\n\r\n return `${row.predecessorId}${PREDECESSOR_TOKEN_BY_TYPE[row.type]}${lag}`;\r\n }\r\n}\r\n","@if (label()) {\r\n <label\r\n [class.required]=\"ngControl?.control?.hasValidator(requiredValidator)\"\r\n [for]=\"ngControl?.name || label()\"\r\n >\r\n {{ label() }}\r\n </label>\r\n}\r\n\r\n<div class=\"grid gap-3\">\r\n <div class=\"flex items-center justify-end\">\r\n <mt-button\r\n icon=\"general.plus\"\r\n [label]=\"'components.schedulePredecessorField.add' | transloco\"\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n [disabled]=\"disabled() || readonly() || !canAddRow()\"\r\n [tooltip]=\"addTooltip()\"\r\n (onClick)=\"addRow()\"\r\n />\r\n </div>\r\n\r\n <ng-template #predecessorCellTpl let-row>\r\n <mt-select-field\r\n [field]=\"false\"\r\n [options]=\"availableTaskOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"\r\n placeholder() ||\r\n ('components.schedulePredecessorField.selectPredecessor' | transloco)\r\n \"\r\n [filter]=\"true\"\r\n [showClear]=\"true\"\r\n [loading]=\"loading()\"\r\n [readonly]=\"disabled() || readonly()\"\r\n [ngModel]=\"row.predecessorId || undefined\"\r\n (onChange)=\"updateRow(row.key, { predecessorId: $event ?? '' })\"\r\n />\r\n </ng-template>\r\n\r\n <ng-template #typeCellTpl let-row>\r\n <mt-select-field\r\n [field]=\"false\"\r\n [options]=\"typeOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [readonly]=\"disabled() || readonly()\"\r\n [ngModel]=\"row.type\"\r\n (onChange)=\"updateRow(row.key, { type: $event ?? 0 })\"\r\n />\r\n </ng-template>\r\n\r\n <ng-template #lagCellTpl let-row>\r\n <mt-number-field\r\n [field]=\"false\"\r\n [useGrouping]=\"false\"\r\n [placeholder]=\"'components.schedulePredecessorField.lagDays' | transloco\"\r\n [readonly]=\"disabled() || readonly()\"\r\n [ngModel]=\"row.lagDays\"\r\n (ngModelChange)=\"updateRow(row.key, { lagDays: $event ?? 0 })\"\r\n />\r\n </ng-template>\r\n\r\n <mt-table\r\n [data]=\"rows()\"\r\n [columns]=\"columns()\"\r\n [rowActions]=\"rowActions()\"\r\n [pageSize]=\"pageSize()\"\r\n [generalSearch]=\"false\"\r\n [showFilters]=\"false\"\r\n [dataKey]=\"'key'\"\r\n [loading]=\"loading()\"\r\n >\r\n <ng-template #empty>\r\n <div\r\n class=\"rounded-xl border border-dashed border-surface px-4 py-5 text-sm text-muted-color\"\r\n >\r\n {{ \"components.schedulePredecessorField.empty\" | transloco }}\r\n </div>\r\n </ng-template>\r\n </mt-table>\r\n</div>\r\n\r\n<mt-field-validation [control]=\"ngControl?.control\"></mt-field-validation>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -388,11 +388,11 @@ class EntitiesPreview {
388
388
  return `span ${size}`;
389
389
  }
390
390
  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-4 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"] }] });
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"] }] });
392
392
  }
393
393
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntitiesPreview, decorators: [{
394
394
  type: Component,
395
- args: [{ selector: 'mt-entities-preview', standalone: true, imports: [EntityPreview], template: "<div class=\"grid grid-cols-24 gap-x-4 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" }]
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
396
  }], propDecorators: { entities: [{ type: i0.Input, args: [{ isSignal: true, alias: "entities", required: true }] }] } });
397
397
 
398
398
  /**