@masterteam/task-schedule 0.0.16 → 0.0.18

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,9 +1,10 @@
1
1
  import { CommonModule } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
- import { inject, Injectable, viewChild, input, signal, computed, effect, Component, linkedSignal, Injector, output, ViewChild } from '@angular/core';
3
+ import { inject, Injectable, viewChild, input, signal, computed, effect, Component, Injector, output, ViewChild } from '@angular/core';
4
4
  import * as i1$1 from '@syncfusion/ej2-angular-gantt';
5
5
  import { GanttModule, DayMarkersService, EditService, ExcelExportService, FilterService, CriticalPathService, PdfExportService, RowDDService, SelectionService, SortService, ToolbarService, ContextMenuService, ResizeService } from '@syncfusion/ej2-angular-gantt';
6
6
  import { switchMap, of, map, timeout, catchError, throwError, finalize, Subject, Subscription } from 'rxjs';
7
+ import { MT_DATE_FORMATS, toAngularDateFormat, MTDateFormatPipe } from '@masterteam/components';
7
8
  import { ModalService } from '@masterteam/components/modal';
8
9
  import { HttpClient } from '@angular/common/http';
9
10
  import { L10n, setCulture } from '@syncfusion/ej2-base';
@@ -17,10 +18,8 @@ import { SelectField } from '@masterteam/components/select-field';
17
18
  import { ClientForm } from '@masterteam/forms/client-form';
18
19
  import { toSignal } from '@angular/core/rxjs-interop';
19
20
  import { CheckboxField } from '@masterteam/components/checkbox-field';
20
- import { DateField } from '@masterteam/components/date-field';
21
- import { EntityPreview } from '@masterteam/components/entities';
22
- import { NumberField } from '@masterteam/components/number-field';
23
21
  import { TextField } from '@masterteam/components/text-field';
22
+ import { Tree } from '@masterteam/components/tree';
24
23
 
25
24
  function normalizeTaskScheduleModelType(modelType) {
26
25
  const normalized = String(modelType ?? '')
@@ -132,6 +131,7 @@ const NATIVE_PROPERTY_ALIAS_TARGETS = {
132
131
  };
133
132
  const DEFAULT_MPP_REQUEST_TIMEOUT_MS$1 = 300_000;
134
133
  const DEFAULT_MPP_PREVIEW_MAX_ROWS = 400;
134
+ const DEFAULT_MPP_PREVIEW_MAX_RESPONSE_BYTES = 5_000_000;
135
135
  class TaskScheduleFetchService {
136
136
  http = inject(HttpClient);
137
137
  load(modelType, context) {
@@ -155,10 +155,11 @@ class TaskScheduleFetchService {
155
155
  'levels/{levelId}/{levelDataId}/schedule/mpp', { levelId, levelDataId });
156
156
  const formData = new FormData();
157
157
  formData.append('file', file, file.name);
158
- return this.readData(this.http
159
- .post(endpoint, formData)
160
- .pipe(timeout(this.resolveMppRequestTimeoutMs(context)))).pipe(map((payload) => ({
158
+ return this.http.post(endpoint, formData, { responseType: 'text' }).pipe(timeout(this.resolveMppRequestTimeoutMs(context)), map((responseText) => this.parseImportResponseText(responseText, context, file.name)), map((payload) => ({
161
159
  fileName: this.toNullableString(this.readObjectValue(payload, ['fileName', 'name'])) ?? file.name,
160
+ applied: payload === null ||
161
+ payload === undefined ||
162
+ this.isImportAppliedMarker(payload),
162
163
  tasks: this.mapLooseTasks(this.extractTaskRows(payload), [], context.langCode === 'ar' ? 'ar' : 'en', new Map(), this.resolveMppPreviewMaxRows(context)),
163
164
  raw: context.mppKeepRawPayload ? payload : undefined,
164
165
  })));
@@ -707,7 +708,12 @@ class TaskScheduleFetchService {
707
708
  '');
708
709
  }
709
710
  readData(request$) {
710
- return request$.pipe(map((response) => response.data), catchError((error) => {
711
+ return request$.pipe(map((response) => {
712
+ if (response === null || response === undefined) {
713
+ return response;
714
+ }
715
+ return response.data;
716
+ }), catchError((error) => {
711
717
  const message = error?.error?.message ??
712
718
  error?.message ??
713
719
  error?.statusText ??
@@ -739,6 +745,42 @@ class TaskScheduleFetchService {
739
745
  ? Math.floor(value) + 1
740
746
  : DEFAULT_MPP_PREVIEW_MAX_ROWS + 1;
741
747
  }
748
+ resolveMppPreviewMaxResponseBytes(context) {
749
+ const value = Number(context.mppPreviewMaxResponseBytes);
750
+ return Number.isFinite(value) && value > 0
751
+ ? Math.floor(value)
752
+ : DEFAULT_MPP_PREVIEW_MAX_RESPONSE_BYTES;
753
+ }
754
+ parseImportResponseText(responseText, context, fileName) {
755
+ const text = String(responseText ?? '').trim();
756
+ if (!text) {
757
+ return null;
758
+ }
759
+ if (text.length > this.resolveMppPreviewMaxResponseBytes(context)) {
760
+ return {
761
+ fileName,
762
+ applied: true,
763
+ };
764
+ }
765
+ try {
766
+ const parsed = JSON.parse(text);
767
+ if (this.isObject(parsed) &&
768
+ Object.prototype.hasOwnProperty.call(parsed, 'data')) {
769
+ return parsed['data'];
770
+ }
771
+ return parsed;
772
+ }
773
+ catch {
774
+ return {
775
+ fileName,
776
+ applied: true,
777
+ };
778
+ }
779
+ }
780
+ isImportAppliedMarker(payload) {
781
+ return (this.isObject(payload) &&
782
+ (payload['applied'] === true || payload['imported'] === true));
783
+ }
742
784
  readEndpoint(context, key) {
743
785
  const value = context.endpoints?.[key];
744
786
  return typeof value === 'string' && value.trim() ? value.trim() : null;
@@ -1761,7 +1803,12 @@ class TaskScheduleActionService {
1761
1803
  return assigneeId === null ? [] : [{ resourceId: assigneeId }];
1762
1804
  }
1763
1805
  readData(request$) {
1764
- return request$.pipe(map((response) => response.data), catchError((error) => {
1806
+ return request$.pipe(map((response) => {
1807
+ if (response === null || response === undefined) {
1808
+ return response;
1809
+ }
1810
+ return response.data;
1811
+ }), catchError((error) => {
1765
1812
  const message = error?.error?.message ??
1766
1813
  error?.message ??
1767
1814
  error?.statusText ??
@@ -2609,7 +2656,7 @@ class TaskScheduleDialog {
2609
2656
  };
2610
2657
  }
2611
2658
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TaskScheduleDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
2612
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: TaskScheduleDialog, isStandalone: true, selector: "mt-task-schedule-dialog", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null }, task: { classPropertyName: "task", publicName: "task", isSignal: true, isRequired: false, transformFunction: null }, typeOptions: { classPropertyName: "typeOptions", publicName: "typeOptions", isSignal: true, isRequired: false, transformFunction: null }, langCode: { classPropertyName: "langCode", publicName: "langCode", isSignal: true, isRequired: false, transformFunction: null }, parentGuid: { classPropertyName: "parentGuid", publicName: "parentGuid", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "clientForm", first: true, predicate: ClientForm, descendants: true, isSignal: true }], ngImport: i0, template: "<div [class]=\"'p-4 overflow-y-auto ' + (modal.contentClass || '')\">\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-select-field\r\n [options]=\"typeSelectOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [label]=\"'task-schedule.dialog.type' | transloco\"\r\n [placeholder]=\"'task-schedule.dialog.typePlaceholder' | transloco\"\r\n [ngModel]=\"selectedType() ?? undefined\"\r\n (onChange)=\"onTypeChange($event)\"\r\n />\r\n\r\n @if (selectedType()) {\r\n <mt-client-form\r\n #clientForm\r\n [moduleKey]=\"'ModuleData'\"\r\n [moduleId]=\"selectedModuleId() ?? undefined\"\r\n [operationKey]=\"mode() === 'edit' ? 'Update' : 'Create'\"\r\n [formMode]=\"mode()\"\r\n [levelId]=\"context()?.levelId ?? undefined\"\r\n [levelDataId]=\"context()?.levelDataId ?? undefined\"\r\n [moduleDataId]=\"selectedModuleDataId() ?? undefined\"\r\n [lang]=\"langCode()\"\r\n [autoLoad]=\"true\"\r\n [ignoredFieldKeys]=\"ignoredFieldKeys()\"\r\n [submitRequestMapper]=\"submitRequestMapper\"\r\n (submitted)=\"onClientFormSubmitted($event)\"\r\n />\r\n } @else {\r\n <div\r\n class=\"rounded-xl border border-surface bg-content px-4 py-4 text-sm text-muted-color\"\r\n >\r\n {{ \"task-schedule.dialog.typeFirst\" | transloco }}\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n\r\n<div [class]=\"modal.footerClass\">\r\n <div class=\"flex items-center justify-end gap-3\">\r\n <mt-button\r\n [label]=\"'task-schedule.dialog.cancel' | transloco\"\r\n variant=\"outlined\"\r\n [disabled]=\"submitting()\"\r\n (onClick)=\"cancel()\"\r\n />\r\n <mt-button\r\n [label]=\"'task-schedule.dialog.save' | transloco\"\r\n severity=\"primary\"\r\n [loading]=\"submitting()\"\r\n [disabled]=\"submitting()\"\r\n (onClick)=\"save()\"\r\n />\r\n </div>\r\n</div>\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: SelectField, selector: "mt-select-field", inputs: ["field", "hint", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape", "markCurrentUser"], outputs: ["onChange"] }, { kind: "component", type: ClientForm, selector: "mt-client-form", inputs: ["moduleKey", "operationKey", "moduleId", "levelId", "levelDataId", "moduleDataId", "requestSchemaId", "draftProcessId", "preview", "returnUrl", "defaultValues", "submitRequestMapper", "readonly", "autoLoad", "formMode", "renderMode", "showInternalStepActions", "confirmWarningsOnSubmit", "confirmWarningsOnStepChange", "lookups", "statuses", "ignoredFieldKeys", "allowedFieldKeys"], outputs: ["loaded", "submitted", "errored", "modeDetected", "formSourceDetected", "footerStateChanged"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i2.TranslocoPipe, name: "transloco" }] });
2659
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: TaskScheduleDialog, isStandalone: true, selector: "mt-task-schedule-dialog", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null }, task: { classPropertyName: "task", publicName: "task", isSignal: true, isRequired: false, transformFunction: null }, typeOptions: { classPropertyName: "typeOptions", publicName: "typeOptions", isSignal: true, isRequired: false, transformFunction: null }, langCode: { classPropertyName: "langCode", publicName: "langCode", isSignal: true, isRequired: false, transformFunction: null }, parentGuid: { classPropertyName: "parentGuid", publicName: "parentGuid", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "clientForm", first: true, predicate: ClientForm, descendants: true, isSignal: true }], ngImport: i0, template: "<div [class]=\"'p-4 overflow-y-auto ' + (modal.contentClass || '')\">\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-select-field\r\n [options]=\"typeSelectOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [label]=\"'task-schedule.dialog.type' | transloco\"\r\n [placeholder]=\"'task-schedule.dialog.typePlaceholder' | transloco\"\r\n [ngModel]=\"selectedType() ?? undefined\"\r\n (onChange)=\"onTypeChange($event)\"\r\n />\r\n\r\n @if (selectedType()) {\r\n <mt-client-form\r\n #clientForm\r\n [moduleKey]=\"'ModuleData'\"\r\n [moduleId]=\"selectedModuleId() ?? undefined\"\r\n [operationKey]=\"mode() === 'edit' ? 'Update' : 'Create'\"\r\n [formMode]=\"mode()\"\r\n [levelId]=\"context()?.levelId ?? undefined\"\r\n [levelDataId]=\"context()?.levelDataId ?? undefined\"\r\n [moduleDataId]=\"selectedModuleDataId() ?? undefined\"\r\n [lang]=\"langCode()\"\r\n [autoLoad]=\"true\"\r\n [ignoredFieldKeys]=\"ignoredFieldKeys()\"\r\n [submitRequestMapper]=\"submitRequestMapper\"\r\n (submitted)=\"onClientFormSubmitted($event)\"\r\n />\r\n } @else {\r\n <div\r\n class=\"rounded-xl border border-surface bg-content px-4 py-4 text-sm text-muted-color\"\r\n >\r\n {{ \"task-schedule.dialog.typeFirst\" | transloco }}\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n\r\n<div [class]=\"modal.footerClass\">\r\n <div class=\"flex items-center justify-end gap-3\">\r\n <mt-button\r\n [label]=\"'task-schedule.dialog.cancel' | transloco\"\r\n variant=\"outlined\"\r\n [disabled]=\"submitting()\"\r\n (onClick)=\"cancel()\"\r\n />\r\n <mt-button\r\n [label]=\"'task-schedule.dialog.save' | transloco\"\r\n severity=\"primary\"\r\n [loading]=\"submitting()\"\r\n [disabled]=\"submitting()\"\r\n (onClick)=\"save()\"\r\n />\r\n </div>\r\n</div>\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: SelectField, selector: "mt-select-field", inputs: ["field", "hint", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape", "markCurrentUser"], outputs: ["onChange"] }, { kind: "component", type: ClientForm, selector: "mt-client-form", inputs: ["moduleKey", "operationKey", "moduleId", "levelId", "levelDataId", "moduleDataId", "requestSchemaId", "draftProcessId", "preview", "returnUrl", "defaultValues", "submitRequestMapper", "readonly", "autoLoad", "formMode", "renderMode", "showInternalStepActions", "confirmWarningsOnSubmit", "confirmWarningsOnStepChange", "readonlyFieldDisplayMode", "lookups", "statuses", "ignoredFieldKeys", "allowedFieldKeys"], outputs: ["loaded", "submitted", "errored", "modeDetected", "formSourceDetected", "footerStateChanged"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i2.TranslocoPipe, name: "transloco" }] });
2613
2660
  }
2614
2661
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TaskScheduleDialog, decorators: [{
2615
2662
  type: Component,
@@ -2629,14 +2676,6 @@ class TaskScheduleImportDialog {
2629
2676
  fetchService = inject(TaskScheduleFetchService);
2630
2677
  actionService = inject(TaskScheduleActionService);
2631
2678
  transloco = inject(TranslocoService);
2632
- selectionCellTpl = viewChild.required('selectionCellTpl');
2633
- taskCellTpl = viewChild.required('taskCellTpl');
2634
- startDateCellTpl = viewChild.required('startDateCellTpl');
2635
- finishDateCellTpl = viewChild.required('finishDateCellTpl');
2636
- actualStartDateCellTpl = viewChild.required('actualStartDateCellTpl');
2637
- actualFinishDateCellTpl = viewChild.required('actualFinishDateCellTpl');
2638
- assignedToCellTpl = viewChild.required('assignedToCellTpl');
2639
- progressCellTpl = viewChild.required('progressCellTpl');
2640
2679
  context = input(null, ...(ngDevMode ? [{ debugName: "context" }] : /* istanbul ignore next */ []));
2641
2680
  maxRows = input(400, ...(ngDevMode ? [{ debugName: "maxRows" }] : /* istanbul ignore next */ []));
2642
2681
  selectedFile = signal(null, ...(ngDevMode ? [{ debugName: "selectedFile" }] : /* istanbul ignore next */ []));
@@ -2644,6 +2683,7 @@ class TaskScheduleImportDialog {
2644
2683
  loadingApply = signal(false, ...(ngDevMode ? [{ debugName: "loadingApply" }] : /* istanbul ignore next */ []));
2645
2684
  importResult = signal(null, ...(ngDevMode ? [{ debugName: "importResult" }] : /* istanbul ignore next */ []));
2646
2685
  selectedTaskKeys = signal(new Set(), ...(ngDevMode ? [{ debugName: "selectedTaskKeys" }] : /* istanbul ignore next */ []));
2686
+ treeSelection = signal([], ...(ngDevMode ? [{ debugName: "treeSelection" }] : /* istanbul ignore next */ []));
2647
2687
  errorMessage = signal(null, ...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
2648
2688
  activeLang = toSignal(this.transloco.langChanges$, {
2649
2689
  initialValue: this.transloco.getActiveLang(),
@@ -2746,62 +2786,58 @@ class TaskScheduleImportDialog {
2746
2786
  !this.loadingApply() &&
2747
2787
  !this.loadingImport(), ...(ngDevMode ? [{ debugName: "canApply" }] : /* istanbul ignore next */ []));
2748
2788
  previewPageSize = computed(() => Math.min(Math.max(this.previewRows().length, 1), 50), ...(ngDevMode ? [{ debugName: "previewPageSize" }] : /* istanbul ignore next */ []));
2749
- previewColumns = linkedSignal(() => [
2750
- {
2751
- key: 'selected',
2752
- label: '',
2753
- type: 'custom',
2754
- customCellTpl: this.selectionCellTpl(),
2755
- },
2756
- {
2757
- key: 'task',
2758
- label: this.labels().task,
2759
- type: 'custom',
2760
- customCellTpl: this.taskCellTpl(),
2761
- },
2762
- {
2763
- key: 'startDate',
2764
- label: this.labels().startDate,
2765
- type: 'custom',
2766
- customCellTpl: this.startDateCellTpl(),
2767
- },
2768
- {
2769
- key: 'finishDate',
2770
- label: this.labels().finishDate,
2771
- type: 'custom',
2772
- customCellTpl: this.finishDateCellTpl(),
2773
- },
2774
- {
2775
- key: 'actualStartDate',
2776
- label: this.labels().actualStartDate,
2777
- type: 'custom',
2778
- customCellTpl: this.actualStartDateCellTpl(),
2779
- },
2780
- {
2781
- key: 'actualFinishDate',
2782
- label: this.labels().actualFinishDate,
2783
- type: 'custom',
2784
- customCellTpl: this.actualFinishDateCellTpl(),
2785
- },
2786
- {
2787
- key: 'assignedTo',
2788
- label: this.labels().assignedTo,
2789
- type: 'custom',
2790
- customCellTpl: this.assignedToCellTpl(),
2791
- },
2792
- {
2793
- key: 'progress',
2794
- label: this.labels().progress,
2795
- type: 'custom',
2796
- customCellTpl: this.progressCellTpl(),
2797
- },
2798
- ], ...(ngDevMode ? [{ debugName: "previewColumns" }] : /* istanbul ignore next */ []));
2789
+ previewTreeNodes = computed(() => {
2790
+ const maxRows = Math.max(1, this.maxRows());
2791
+ let remaining = maxRows;
2792
+ const mapNode = (task, depth, path) => {
2793
+ if (remaining <= 0) {
2794
+ return null;
2795
+ }
2796
+ remaining -= 1;
2797
+ const key = this.resolveTaskKey(task, path);
2798
+ const children = [];
2799
+ const childTasks = this.resolveChildTasks(task);
2800
+ for (let index = 0; index < childTasks.length; index += 1) {
2801
+ const child = mapNode(childTasks[index], depth + 1, `${path}.${index}`);
2802
+ if (child) {
2803
+ children.push(child);
2804
+ }
2805
+ if (remaining <= 0) {
2806
+ break;
2807
+ }
2808
+ }
2809
+ return {
2810
+ key,
2811
+ label: this.toTreeNodeLabel(task),
2812
+ icon: this.resolveTreeNodeIcon(task),
2813
+ expanded: depth < 2,
2814
+ data: {
2815
+ rowKey: key,
2816
+ task,
2817
+ },
2818
+ children,
2819
+ };
2820
+ };
2821
+ const nodes = [];
2822
+ const tasks = this.importResult()?.tasks ?? [];
2823
+ for (let index = 0; index < tasks.length; index += 1) {
2824
+ const node = mapNode(tasks[index], 0, `root.${index}`);
2825
+ if (node) {
2826
+ nodes.push(node);
2827
+ }
2828
+ if (remaining <= 0) {
2829
+ break;
2830
+ }
2831
+ }
2832
+ return nodes;
2833
+ }, ...(ngDevMode ? [{ debugName: "previewTreeNodes" }] : /* istanbul ignore next */ []));
2799
2834
  onFileChanged(event) {
2800
2835
  const input = event.target;
2801
2836
  const file = input?.files?.item(0) ?? null;
2802
2837
  this.selectedFile.set(file);
2803
2838
  this.importResult.set(null);
2804
2839
  this.selectedTaskKeys.set(new Set());
2840
+ this.treeSelection.set([]);
2805
2841
  this.errorMessage.set(null);
2806
2842
  }
2807
2843
  importFile() {
@@ -2833,6 +2869,10 @@ class TaskScheduleImportDialog {
2833
2869
  .pipe(finalize(() => this.loadingImport.set(false)))
2834
2870
  .subscribe({
2835
2871
  next: (result) => {
2872
+ if (result.applied) {
2873
+ this.ref.close(true);
2874
+ return;
2875
+ }
2836
2876
  this.importResult.set(result);
2837
2877
  this.selectAllRows(true);
2838
2878
  },
@@ -2853,12 +2893,33 @@ class TaskScheduleImportDialog {
2853
2893
  }
2854
2894
  selectAllRows(checked) {
2855
2895
  const next = new Set();
2896
+ const nextSelection = [];
2856
2897
  if (checked) {
2857
- this.previewRows().forEach(({ key }) => {
2858
- next.add(key);
2898
+ this.collectTreeNodes(this.previewTreeNodes()).forEach((node) => {
2899
+ if (node.key) {
2900
+ next.add(node.key);
2901
+ nextSelection.push(node);
2902
+ }
2859
2903
  });
2860
2904
  }
2861
2905
  this.selectedTaskKeys.set(next);
2906
+ this.treeSelection.set(nextSelection);
2907
+ }
2908
+ onTreeSelectionChange(selection) {
2909
+ const nodes = Array.isArray(selection)
2910
+ ? selection
2911
+ : selection
2912
+ ? [selection]
2913
+ : [];
2914
+ const next = new Set();
2915
+ nodes.forEach((node) => {
2916
+ const rowKey = this.readRowKeyFromTreeNode(node);
2917
+ if (rowKey) {
2918
+ next.add(rowKey);
2919
+ }
2920
+ });
2921
+ this.treeSelection.set(nodes);
2922
+ this.selectedTaskKeys.set(next);
2862
2923
  }
2863
2924
  applyImport(overrideCurrent) {
2864
2925
  if (this.loadingImport() || this.loadingApply()) {
@@ -3105,6 +3166,44 @@ class TaskScheduleImportDialog {
3105
3166
  const base = task.guid ?? task.id ?? path;
3106
3167
  return `${String(base)}::${path}`;
3107
3168
  }
3169
+ collectTreeNodes(nodes) {
3170
+ const output = [];
3171
+ const walk = (items) => {
3172
+ items.forEach((node) => {
3173
+ output.push(node);
3174
+ if (node.children?.length) {
3175
+ walk(node.children);
3176
+ }
3177
+ });
3178
+ };
3179
+ walk(nodes);
3180
+ return output;
3181
+ }
3182
+ readRowKeyFromTreeNode(node) {
3183
+ const data = node.data;
3184
+ return typeof data?.rowKey === 'string' && data.rowKey.trim()
3185
+ ? data.rowKey
3186
+ : null;
3187
+ }
3188
+ toTreeNodeLabel(task) {
3189
+ const title = String(task.title ?? task.name ?? '').trim();
3190
+ const type = String(task.type ?? task.typeLabel ?? task.typeLable ?? '').trim() ||
3191
+ (task.isMilestone ? 'Milestone' : task['isSummary'] ? 'Summary' : 'Task');
3192
+ return `${title || type}`;
3193
+ }
3194
+ resolveTreeNodeIcon(task) {
3195
+ if (task.isMilestone) {
3196
+ return 'map.flag-02';
3197
+ }
3198
+ if (task['isSummary'] || this.resolveChildTasks(task).length) {
3199
+ return 'files.folder-01';
3200
+ }
3201
+ return 'custom.task';
3202
+ }
3203
+ formatPreviewDate(value) {
3204
+ const normalized = this.toApiDate(value);
3205
+ return normalized ?? '';
3206
+ }
3108
3207
  resolveAssignedTo(task) {
3109
3208
  const assignedTo = task.assignedTo;
3110
3209
  if ((typeof assignedTo === 'string' || typeof assignedTo === 'number') &&
@@ -3249,24 +3348,20 @@ class TaskScheduleImportDialog {
3249
3348
  this.errorMessage.set(message);
3250
3349
  }
3251
3350
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TaskScheduleImportDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
3252
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: TaskScheduleImportDialog, isStandalone: true, selector: "mt-task-schedule-import-dialog", inputs: { context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null }, maxRows: { classPropertyName: "maxRows", publicName: "maxRows", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "selectionCellTpl", first: true, predicate: ["selectionCellTpl"], descendants: true, isSignal: true }, { propertyName: "taskCellTpl", first: true, predicate: ["taskCellTpl"], descendants: true, isSignal: true }, { propertyName: "startDateCellTpl", first: true, predicate: ["startDateCellTpl"], descendants: true, isSignal: true }, { propertyName: "finishDateCellTpl", first: true, predicate: ["finishDateCellTpl"], descendants: true, isSignal: true }, { propertyName: "actualStartDateCellTpl", first: true, predicate: ["actualStartDateCellTpl"], descendants: true, isSignal: true }, { propertyName: "actualFinishDateCellTpl", first: true, predicate: ["actualFinishDateCellTpl"], descendants: true, isSignal: true }, { propertyName: "assignedToCellTpl", first: true, predicate: ["assignedToCellTpl"], descendants: true, isSignal: true }, { propertyName: "progressCellTpl", first: true, predicate: ["progressCellTpl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n [class]=\"modal.contentClass\"\n [attr.dir]=\"isRtl() ? 'rtl' : 'ltr'\"\n class=\"flex h-full min-h-0 flex-col gap-4 !overflow-y-hidden p-5\"\n>\n <div class=\"rounded-lg border border-surface-200 bg-surface-50 p-4\">\n <div class=\"grid gap-3 lg:grid-cols-[minmax(0,1fr)_auto_auto] lg:items-end\">\n <input\n #fileInput\n class=\"hidden\"\n type=\"file\"\n accept=\".mpp,.xer\"\n (change)=\"onFileChanged($event)\"\n />\n\n <mt-text-field\n [ngModel]=\"selectedFile()?.name ?? ''\"\n [readonly]=\"true\"\n [placeholder]=\"labels().selectFile\"\n />\n\n <mt-button\n [label]=\"labels().selectFile\"\n severity=\"secondary\"\n variant=\"outlined\"\n [disabled]=\"loadingImport() || loadingApply()\"\n (onClick)=\"fileInput.click()\"\n />\n\n <mt-button\n [label]=\"labels().startImport\"\n [disabled]=\"!canImport()\"\n [loading]=\"loadingImport()\"\n (onClick)=\"importFile()\"\n />\n </div>\n </div>\n\n @if (errorMessage()) {\n <div\n class=\"rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700\"\n >\n {{ errorMessage() }}\n </div>\n }\n\n <div class=\"min-h-0 flex-1 overflow-y-auto\">\n @if (importResult()) {\n @if (!previewRows().length) {\n <div\n class=\"rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-800\"\n >\n {{ labels().noTasks }}\n </div>\n } @else {\n <div class=\"rounded-lg border border-surface-200 bg-surface-0\">\n <div\n class=\"flex flex-wrap items-center justify-between gap-3 border-b border-surface-200 bg-surface-50 px-4 py-3\"\n >\n <div class=\"flex items-center gap-3\">\n <mt-checkbox-field\n [ngModel]=\"allSelected()\"\n (ngModelChange)=\"selectAllRows(!!$event)\"\n />\n <span class=\"text-sm text-surface-600\">\n {{ selectedTaskKeys().size }} / {{ previewRows().length }}\n </span>\n </div>\n\n @if (isTruncated()) {\n <p class=\"text-xs text-surface-500\">\n {{ labels().rowsLimited }}\n </p>\n }\n </div>\n\n <div class=\"px-2 py-2\">\n @defer (on idle) {\n <mt-table\n [data]=\"previewRows()\"\n [columns]=\"previewColumns()\"\n dataKey=\"key\"\n storageKey=\"task-schedule-import-preview-table\"\n size=\"small\"\n [stripedRows]=\"true\"\n [showGridlines]=\"true\"\n [pageSize]=\"previewPageSize()\"\n />\n } @placeholder {\n <div class=\"space-y-2 p-2\">\n <div class=\"h-9 rounded bg-surface-100\"></div>\n <div class=\"h-9 rounded bg-surface-100\"></div>\n <div class=\"h-9 rounded bg-surface-100\"></div>\n </div>\n }\n </div>\n </div>\n }\n }\n </div>\n</div>\n\n<div [class]=\"modal.footerClass\">\n <mt-button\n [label]=\"labels().cancel\"\n variant=\"outlined\"\n [disabled]=\"loadingImport() || loadingApply()\"\n (onClick)=\"close()\"\n />\n\n <mt-button\n [label]=\"labels().replace\"\n [disabled]=\"!canApply()\"\n [loading]=\"loadingApply()\"\n (onClick)=\"applyImport(true)\"\n />\n\n <mt-button\n [label]=\"labels().append\"\n severity=\"secondary\"\n [disabled]=\"!canApply()\"\n [loading]=\"loadingApply()\"\n (onClick)=\"applyImport(false)\"\n />\n</div>\n\n<ng-template #selectionCellTpl let-row>\n <div class=\"flex items-center justify-center\">\n <mt-checkbox-field\n [ngModel]=\"selectedTaskKeys().has(row.key)\"\n (ngModelChange)=\"toggleRowSelection(row.key, !!$event)\"\n />\n </div>\n</ng-template>\n\n<ng-template #taskCellTpl let-row>\n <div class=\"min-w-0\" [style.paddingInlineStart.px]=\"row.depth * 18\">\n <mt-text-field\n [ngModel]=\"row.task.title || row.task.name || ''\"\n (ngModelChange)=\"onTaskTitleChanged(row.key, $event)\"\n />\n </div>\n</ng-template>\n\n<ng-template #startDateCellTpl let-row>\n <mt-date-field\n [ngModel]=\"toDateFieldValue(row.task.startDate)\"\n [showClear]=\"true\"\n (ngModelChange)=\"onTaskDateChanged(row.key, 'startDate', $event)\"\n />\n</ng-template>\n\n<ng-template #finishDateCellTpl let-row>\n <mt-date-field\n [ngModel]=\"toDateFieldValue(row.task.finishDate)\"\n [showClear]=\"true\"\n (ngModelChange)=\"onTaskDateChanged(row.key, 'finishDate', $event)\"\n />\n</ng-template>\n\n<ng-template #actualStartDateCellTpl let-row>\n <mt-date-field\n [ngModel]=\"\n toDateFieldValue(row.task.actualStartDate || row.task.actualStart)\n \"\n [showClear]=\"true\"\n (ngModelChange)=\"onTaskDateChanged(row.key, 'actualStartDate', $event)\"\n />\n</ng-template>\n\n<ng-template #actualFinishDateCellTpl let-row>\n <mt-date-field\n [ngModel]=\"\n toDateFieldValue(row.task.actualFinishDate || row.task.actualFinish)\n \"\n [showClear]=\"true\"\n (ngModelChange)=\"onTaskDateChanged(row.key, 'actualFinishDate', $event)\"\n />\n</ng-template>\n\n<ng-template #assignedToCellTpl let-row>\n <div class=\"min-w-0\">\n @if (resourceOptions().length) {\n <div class=\"space-y-2\">\n <mt-select-field\n [ngModel]=\"resolveAssignedValue(row.task)\"\n [options]=\"resourceOptions()\"\n optionLabel=\"label\"\n optionValue=\"id\"\n [showClear]=\"true\"\n [hasPlaceholderPrefix]=\"false\"\n [placeholder]=\"labels().assignedTo\"\n (ngModelChange)=\"onTaskAssignedToChanged(row.key, $event)\"\n />\n @if (row.task.assignedTo) {\n <mt-entity-preview [data]=\"toAssignedEntity(row.task)\" />\n }\n </div>\n } @else if (row.task.assignedTo) {\n <mt-entity-preview [data]=\"toAssignedEntity(row.task)\" />\n } @else {\n <span class=\"text-slate-400\">-</span>\n }\n </div>\n</ng-template>\n\n<ng-template #progressCellTpl let-row>\n <div class=\"space-y-2\">\n <mt-number-field\n [ngModel]=\"normalizeProgress(row.task.progress)\"\n [min]=\"0\"\n [max]=\"100\"\n [useGrouping]=\"false\"\n [maxFractionDigits]=\"0\"\n (ngModelChange)=\"onTaskProgressChanged(row.key, $event)\"\n />\n <mt-entity-preview [data]=\"toProgressEntity(row.task)\" />\n </div>\n</ng-template>\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: CheckboxField, selector: "mt-checkbox-field", inputs: ["label", "labelPosition", "placeholder", "readonly", "pInputs", "required"], outputs: ["onChange"] }, { kind: "component", type: DateField, selector: "mt-date-field", inputs: ["field", "hint", "label", "placeholder", "class", "readonly", "showIcon", "showClear", "showTime", "pInputs", "required"] }, { kind: "component", type: EntityPreview, selector: "mt-entity-preview", inputs: ["data", "attachmentShape"] }, { kind: "component", type: NumberField, selector: "mt-number-field", inputs: ["field", "hint", "label", "placeholder", "class", "readonly", "pInputs", "format", "useGrouping", "maxFractionDigits", "min", "max", "required"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "hint", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape", "markCurrentUser"], outputs: ["onChange"] }, { kind: "component", type: TextField, selector: "mt-text-field", inputs: ["field", "hint", "label", "placeholder", "class", "type", "readonly", "pInputs", "required", "maxLength", "icon", "iconPosition"] }, { kind: "ngmodule", type: TranslocoModule }], deferBlockDependencies: [() => [import('@masterteam/components/table').then(m => m.Table)]] });
3351
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: TaskScheduleImportDialog, isStandalone: true, selector: "mt-task-schedule-import-dialog", inputs: { context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null }, maxRows: { classPropertyName: "maxRows", publicName: "maxRows", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div\r\n [class]=\"modal.contentClass\"\r\n [attr.dir]=\"isRtl() ? 'rtl' : 'ltr'\"\r\n class=\"flex h-full min-h-0 flex-col gap-4 !overflow-y-hidden p-5\"\r\n>\r\n <div class=\"rounded-lg border border-surface-200 bg-surface-50 p-4\">\r\n <div class=\"grid gap-3 lg:grid-cols-[minmax(0,1fr)_auto_auto] lg:items-end\">\r\n <input\r\n #fileInput\r\n class=\"hidden\"\r\n type=\"file\"\r\n accept=\".mpp,.xer\"\r\n (change)=\"onFileChanged($event)\"\r\n />\r\n\r\n <mt-text-field\r\n [ngModel]=\"selectedFile()?.name ?? ''\"\r\n [readonly]=\"true\"\r\n [placeholder]=\"labels().selectFile\"\r\n />\r\n\r\n <mt-button\r\n [label]=\"labels().selectFile\"\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n [disabled]=\"loadingImport() || loadingApply()\"\r\n (onClick)=\"fileInput.click()\"\r\n />\r\n\r\n <mt-button\r\n [label]=\"labels().startImport\"\r\n [disabled]=\"!canImport()\"\r\n [loading]=\"loadingImport()\"\r\n (onClick)=\"importFile()\"\r\n />\r\n </div>\r\n </div>\r\n\r\n @if (errorMessage()) {\r\n <div\r\n class=\"rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700\"\r\n >\r\n {{ errorMessage() }}\r\n </div>\r\n }\r\n\r\n <div class=\"min-h-0 flex-1 overflow-y-auto\">\r\n @if (importResult()) {\r\n @if (!previewRows().length) {\r\n <div\r\n class=\"rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-800\"\r\n >\r\n {{ labels().noTasks }}\r\n </div>\r\n } @else {\r\n <div class=\"rounded-lg border border-surface-200 bg-surface-0\">\r\n <div\r\n class=\"flex flex-wrap items-center justify-between gap-3 border-b border-surface-200 bg-surface-50 px-4 py-3\"\r\n >\r\n <div class=\"flex items-center gap-3\">\r\n <mt-checkbox-field\r\n [ngModel]=\"allSelected()\"\r\n (ngModelChange)=\"selectAllRows(!!$event)\"\r\n />\r\n <span class=\"text-sm text-surface-600\">\r\n {{ selectedTaskKeys().size }} / {{ previewRows().length }}\r\n </span>\r\n </div>\r\n\r\n @if (isTruncated()) {\r\n <p class=\"text-xs text-surface-500\">\r\n {{ labels().rowsLimited }}\r\n </p>\r\n }\r\n </div>\r\n\r\n <div class=\"px-2 py-2\">\r\n <mt-tree\r\n [value]=\"previewTreeNodes()\"\r\n [selection]=\"treeSelection()\"\r\n selectionMode=\"checkbox\"\r\n [propagateSelectionUp]=\"false\"\r\n [propagateSelectionDown]=\"false\"\r\n [filter]=\"true\"\r\n scrollHeight=\"28rem\"\r\n styleClass=\"task-schedule-import-tree\"\r\n (selectionChange)=\"onTreeSelectionChange($event)\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n }\r\n </div>\r\n</div>\r\n\r\n<div [class]=\"modal.footerClass\">\r\n <mt-button\r\n [label]=\"labels().cancel\"\r\n variant=\"outlined\"\r\n [disabled]=\"loadingImport() || loadingApply()\"\r\n (onClick)=\"close()\"\r\n />\r\n\r\n <mt-button\r\n [label]=\"labels().replace\"\r\n [disabled]=\"!canApply()\"\r\n [loading]=\"loadingApply()\"\r\n (onClick)=\"applyImport(true)\"\r\n />\r\n\r\n <mt-button\r\n [label]=\"labels().append\"\r\n severity=\"secondary\"\r\n [disabled]=\"!canApply()\"\r\n [loading]=\"loadingApply()\"\r\n (onClick)=\"applyImport(false)\"\r\n />\r\n</div>\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: CheckboxField, selector: "mt-checkbox-field", inputs: ["label", "labelPosition", "placeholder", "readonly", "pInputs", "required"], outputs: ["onChange"] }, { kind: "component", type: TextField, selector: "mt-text-field", inputs: ["field", "hint", "label", "placeholder", "class", "type", "readonly", "pInputs", "required", "maxLength", "icon", "iconPosition"] }, { kind: "component", type: Tree, selector: "mt-tree", inputs: ["value", "selection", "selectionMode", "nodeIcon", "propagateSelectionUp", "propagateSelectionDown", "checkAllChildren", "loading", "emptyMessage", "checkAllLabel", "filterPlaceholder", "dataKey", "filter", "filterMode", "virtualScroll", "virtualScrollItemSize", "scrollHeight", "styleClass", "style", "pInputs", "nodeActions", "nodeContextmenuActions", "contextMenuSelection"], outputs: ["selectionChange", "contextMenuSelectionChange", "action"] }, { kind: "ngmodule", type: TranslocoModule }] });
3253
3352
  }
3254
- i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "21.2.8", ngImport: i0, type: TaskScheduleImportDialog, resolveDeferredDeps: () => [import('@masterteam/components/table').then(m => m.Table)], resolveMetadata: Table => ({ decorators: [{
3255
- type: Component,
3256
- args: [{ selector: 'mt-task-schedule-import-dialog', standalone: true, imports: [
3257
- CommonModule,
3258
- FormsModule,
3259
- Button,
3260
- CheckboxField,
3261
- DateField,
3262
- EntityPreview,
3263
- NumberField,
3264
- SelectField,
3265
- Table,
3266
- TextField,
3267
- TranslocoModule,
3268
- ], template: "<div\n [class]=\"modal.contentClass\"\n [attr.dir]=\"isRtl() ? 'rtl' : 'ltr'\"\n class=\"flex h-full min-h-0 flex-col gap-4 !overflow-y-hidden p-5\"\n>\n <div class=\"rounded-lg border border-surface-200 bg-surface-50 p-4\">\n <div class=\"grid gap-3 lg:grid-cols-[minmax(0,1fr)_auto_auto] lg:items-end\">\n <input\n #fileInput\n class=\"hidden\"\n type=\"file\"\n accept=\".mpp,.xer\"\n (change)=\"onFileChanged($event)\"\n />\n\n <mt-text-field\n [ngModel]=\"selectedFile()?.name ?? ''\"\n [readonly]=\"true\"\n [placeholder]=\"labels().selectFile\"\n />\n\n <mt-button\n [label]=\"labels().selectFile\"\n severity=\"secondary\"\n variant=\"outlined\"\n [disabled]=\"loadingImport() || loadingApply()\"\n (onClick)=\"fileInput.click()\"\n />\n\n <mt-button\n [label]=\"labels().startImport\"\n [disabled]=\"!canImport()\"\n [loading]=\"loadingImport()\"\n (onClick)=\"importFile()\"\n />\n </div>\n </div>\n\n @if (errorMessage()) {\n <div\n class=\"rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700\"\n >\n {{ errorMessage() }}\n </div>\n }\n\n <div class=\"min-h-0 flex-1 overflow-y-auto\">\n @if (importResult()) {\n @if (!previewRows().length) {\n <div\n class=\"rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-800\"\n >\n {{ labels().noTasks }}\n </div>\n } @else {\n <div class=\"rounded-lg border border-surface-200 bg-surface-0\">\n <div\n class=\"flex flex-wrap items-center justify-between gap-3 border-b border-surface-200 bg-surface-50 px-4 py-3\"\n >\n <div class=\"flex items-center gap-3\">\n <mt-checkbox-field\n [ngModel]=\"allSelected()\"\n (ngModelChange)=\"selectAllRows(!!$event)\"\n />\n <span class=\"text-sm text-surface-600\">\n {{ selectedTaskKeys().size }} / {{ previewRows().length }}\n </span>\n </div>\n\n @if (isTruncated()) {\n <p class=\"text-xs text-surface-500\">\n {{ labels().rowsLimited }}\n </p>\n }\n </div>\n\n <div class=\"px-2 py-2\">\n @defer (on idle) {\n <mt-table\n [data]=\"previewRows()\"\n [columns]=\"previewColumns()\"\n dataKey=\"key\"\n storageKey=\"task-schedule-import-preview-table\"\n size=\"small\"\n [stripedRows]=\"true\"\n [showGridlines]=\"true\"\n [pageSize]=\"previewPageSize()\"\n />\n } @placeholder {\n <div class=\"space-y-2 p-2\">\n <div class=\"h-9 rounded bg-surface-100\"></div>\n <div class=\"h-9 rounded bg-surface-100\"></div>\n <div class=\"h-9 rounded bg-surface-100\"></div>\n </div>\n }\n </div>\n </div>\n }\n }\n </div>\n</div>\n\n<div [class]=\"modal.footerClass\">\n <mt-button\n [label]=\"labels().cancel\"\n variant=\"outlined\"\n [disabled]=\"loadingImport() || loadingApply()\"\n (onClick)=\"close()\"\n />\n\n <mt-button\n [label]=\"labels().replace\"\n [disabled]=\"!canApply()\"\n [loading]=\"loadingApply()\"\n (onClick)=\"applyImport(true)\"\n />\n\n <mt-button\n [label]=\"labels().append\"\n severity=\"secondary\"\n [disabled]=\"!canApply()\"\n [loading]=\"loadingApply()\"\n (onClick)=\"applyImport(false)\"\n />\n</div>\n\n<ng-template #selectionCellTpl let-row>\n <div class=\"flex items-center justify-center\">\n <mt-checkbox-field\n [ngModel]=\"selectedTaskKeys().has(row.key)\"\n (ngModelChange)=\"toggleRowSelection(row.key, !!$event)\"\n />\n </div>\n</ng-template>\n\n<ng-template #taskCellTpl let-row>\n <div class=\"min-w-0\" [style.paddingInlineStart.px]=\"row.depth * 18\">\n <mt-text-field\n [ngModel]=\"row.task.title || row.task.name || ''\"\n (ngModelChange)=\"onTaskTitleChanged(row.key, $event)\"\n />\n </div>\n</ng-template>\n\n<ng-template #startDateCellTpl let-row>\n <mt-date-field\n [ngModel]=\"toDateFieldValue(row.task.startDate)\"\n [showClear]=\"true\"\n (ngModelChange)=\"onTaskDateChanged(row.key, 'startDate', $event)\"\n />\n</ng-template>\n\n<ng-template #finishDateCellTpl let-row>\n <mt-date-field\n [ngModel]=\"toDateFieldValue(row.task.finishDate)\"\n [showClear]=\"true\"\n (ngModelChange)=\"onTaskDateChanged(row.key, 'finishDate', $event)\"\n />\n</ng-template>\n\n<ng-template #actualStartDateCellTpl let-row>\n <mt-date-field\n [ngModel]=\"\n toDateFieldValue(row.task.actualStartDate || row.task.actualStart)\n \"\n [showClear]=\"true\"\n (ngModelChange)=\"onTaskDateChanged(row.key, 'actualStartDate', $event)\"\n />\n</ng-template>\n\n<ng-template #actualFinishDateCellTpl let-row>\n <mt-date-field\n [ngModel]=\"\n toDateFieldValue(row.task.actualFinishDate || row.task.actualFinish)\n \"\n [showClear]=\"true\"\n (ngModelChange)=\"onTaskDateChanged(row.key, 'actualFinishDate', $event)\"\n />\n</ng-template>\n\n<ng-template #assignedToCellTpl let-row>\n <div class=\"min-w-0\">\n @if (resourceOptions().length) {\n <div class=\"space-y-2\">\n <mt-select-field\n [ngModel]=\"resolveAssignedValue(row.task)\"\n [options]=\"resourceOptions()\"\n optionLabel=\"label\"\n optionValue=\"id\"\n [showClear]=\"true\"\n [hasPlaceholderPrefix]=\"false\"\n [placeholder]=\"labels().assignedTo\"\n (ngModelChange)=\"onTaskAssignedToChanged(row.key, $event)\"\n />\n @if (row.task.assignedTo) {\n <mt-entity-preview [data]=\"toAssignedEntity(row.task)\" />\n }\n </div>\n } @else if (row.task.assignedTo) {\n <mt-entity-preview [data]=\"toAssignedEntity(row.task)\" />\n } @else {\n <span class=\"text-slate-400\">-</span>\n }\n </div>\n</ng-template>\n\n<ng-template #progressCellTpl let-row>\n <div class=\"space-y-2\">\n <mt-number-field\n [ngModel]=\"normalizeProgress(row.task.progress)\"\n [min]=\"0\"\n [max]=\"100\"\n [useGrouping]=\"false\"\n [maxFractionDigits]=\"0\"\n (ngModelChange)=\"onTaskProgressChanged(row.key, $event)\"\n />\n <mt-entity-preview [data]=\"toProgressEntity(row.task)\" />\n </div>\n</ng-template>\n" }]
3269
- }], ctorParameters: null, propDecorators: { selectionCellTpl: [{ type: i0.ViewChild, args: ['selectionCellTpl', { isSignal: true }] }], taskCellTpl: [{ type: i0.ViewChild, args: ['taskCellTpl', { isSignal: true }] }], startDateCellTpl: [{ type: i0.ViewChild, args: ['startDateCellTpl', { isSignal: true }] }], finishDateCellTpl: [{ type: i0.ViewChild, args: ['finishDateCellTpl', { isSignal: true }] }], actualStartDateCellTpl: [{ type: i0.ViewChild, args: ['actualStartDateCellTpl', { isSignal: true }] }], actualFinishDateCellTpl: [{ type: i0.ViewChild, args: ['actualFinishDateCellTpl', { isSignal: true }] }], assignedToCellTpl: [{ type: i0.ViewChild, args: ['assignedToCellTpl', { isSignal: true }] }], progressCellTpl: [{ type: i0.ViewChild, args: ['progressCellTpl', { isSignal: true }] }], context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: false }] }], maxRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxRows", required: false }] }] } }) });
3353
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TaskScheduleImportDialog, decorators: [{
3354
+ type: Component,
3355
+ args: [{ selector: 'mt-task-schedule-import-dialog', standalone: true, imports: [
3356
+ CommonModule,
3357
+ FormsModule,
3358
+ Button,
3359
+ CheckboxField,
3360
+ TextField,
3361
+ Tree,
3362
+ TranslocoModule,
3363
+ ], template: "<div\r\n [class]=\"modal.contentClass\"\r\n [attr.dir]=\"isRtl() ? 'rtl' : 'ltr'\"\r\n class=\"flex h-full min-h-0 flex-col gap-4 !overflow-y-hidden p-5\"\r\n>\r\n <div class=\"rounded-lg border border-surface-200 bg-surface-50 p-4\">\r\n <div class=\"grid gap-3 lg:grid-cols-[minmax(0,1fr)_auto_auto] lg:items-end\">\r\n <input\r\n #fileInput\r\n class=\"hidden\"\r\n type=\"file\"\r\n accept=\".mpp,.xer\"\r\n (change)=\"onFileChanged($event)\"\r\n />\r\n\r\n <mt-text-field\r\n [ngModel]=\"selectedFile()?.name ?? ''\"\r\n [readonly]=\"true\"\r\n [placeholder]=\"labels().selectFile\"\r\n />\r\n\r\n <mt-button\r\n [label]=\"labels().selectFile\"\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n [disabled]=\"loadingImport() || loadingApply()\"\r\n (onClick)=\"fileInput.click()\"\r\n />\r\n\r\n <mt-button\r\n [label]=\"labels().startImport\"\r\n [disabled]=\"!canImport()\"\r\n [loading]=\"loadingImport()\"\r\n (onClick)=\"importFile()\"\r\n />\r\n </div>\r\n </div>\r\n\r\n @if (errorMessage()) {\r\n <div\r\n class=\"rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700\"\r\n >\r\n {{ errorMessage() }}\r\n </div>\r\n }\r\n\r\n <div class=\"min-h-0 flex-1 overflow-y-auto\">\r\n @if (importResult()) {\r\n @if (!previewRows().length) {\r\n <div\r\n class=\"rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-800\"\r\n >\r\n {{ labels().noTasks }}\r\n </div>\r\n } @else {\r\n <div class=\"rounded-lg border border-surface-200 bg-surface-0\">\r\n <div\r\n class=\"flex flex-wrap items-center justify-between gap-3 border-b border-surface-200 bg-surface-50 px-4 py-3\"\r\n >\r\n <div class=\"flex items-center gap-3\">\r\n <mt-checkbox-field\r\n [ngModel]=\"allSelected()\"\r\n (ngModelChange)=\"selectAllRows(!!$event)\"\r\n />\r\n <span class=\"text-sm text-surface-600\">\r\n {{ selectedTaskKeys().size }} / {{ previewRows().length }}\r\n </span>\r\n </div>\r\n\r\n @if (isTruncated()) {\r\n <p class=\"text-xs text-surface-500\">\r\n {{ labels().rowsLimited }}\r\n </p>\r\n }\r\n </div>\r\n\r\n <div class=\"px-2 py-2\">\r\n <mt-tree\r\n [value]=\"previewTreeNodes()\"\r\n [selection]=\"treeSelection()\"\r\n selectionMode=\"checkbox\"\r\n [propagateSelectionUp]=\"false\"\r\n [propagateSelectionDown]=\"false\"\r\n [filter]=\"true\"\r\n scrollHeight=\"28rem\"\r\n styleClass=\"task-schedule-import-tree\"\r\n (selectionChange)=\"onTreeSelectionChange($event)\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n }\r\n </div>\r\n</div>\r\n\r\n<div [class]=\"modal.footerClass\">\r\n <mt-button\r\n [label]=\"labels().cancel\"\r\n variant=\"outlined\"\r\n [disabled]=\"loadingImport() || loadingApply()\"\r\n (onClick)=\"close()\"\r\n />\r\n\r\n <mt-button\r\n [label]=\"labels().replace\"\r\n [disabled]=\"!canApply()\"\r\n [loading]=\"loadingApply()\"\r\n (onClick)=\"applyImport(true)\"\r\n />\r\n\r\n <mt-button\r\n [label]=\"labels().append\"\r\n severity=\"secondary\"\r\n [disabled]=\"!canApply()\"\r\n [loading]=\"loadingApply()\"\r\n (onClick)=\"applyImport(false)\"\r\n />\r\n</div>\r\n" }]
3364
+ }], propDecorators: { context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: false }] }], maxRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxRows", required: false }] }] } });
3270
3365
 
3271
3366
  class TaskScheduleQueueService {
3272
3367
  basicOrderColumns = new Map();
@@ -3475,6 +3570,7 @@ class TaskSchedule {
3475
3570
  fetchService = inject(TaskScheduleFetchService);
3476
3571
  actionService = inject(TaskScheduleActionService);
3477
3572
  modal = inject(ModalService);
3573
+ dateFormats = inject(MT_DATE_FORMATS);
3478
3574
  queueService = inject(TaskScheduleQueueService);
3479
3575
  injector = inject(Injector);
3480
3576
  loadEffect;
@@ -3504,7 +3600,7 @@ class TaskSchedule {
3504
3600
  }, ...(ngDevMode ? [{ debugName: "treeColumnIndex" }] : /* istanbul ignore next */ []));
3505
3601
  ganttId = `mtTaskScheduleGantt-${Math.random().toString(36).slice(2, 10)}`;
3506
3602
  resolvedModelTypeInput = computed(() => this.context()?.modelType ?? 'default', ...(ngDevMode ? [{ debugName: "resolvedModelTypeInput" }] : /* istanbul ignore next */ []));
3507
- resolvedDateFormat = computed(() => this.context()?.dateFormat ?? 'dd/MM/yyyy', ...(ngDevMode ? [{ debugName: "resolvedDateFormat" }] : /* istanbul ignore next */ []));
3603
+ resolvedDateFormat = computed(() => toAngularDateFormat(this.context()?.dateFormat ?? this.dateFormats.date), ...(ngDevMode ? [{ debugName: "resolvedDateFormat" }] : /* istanbul ignore next */ []));
3508
3604
  resolvedHeight = computed(() => this.context()?.height ?? '760px', ...(ngDevMode ? [{ debugName: "resolvedHeight" }] : /* istanbul ignore next */ []));
3509
3605
  resolvedModelType = computed(() => normalizeTaskScheduleModelType(this.resolvedModelTypeInput()), ...(ngDevMode ? [{ debugName: "resolvedModelType" }] : /* istanbul ignore next */ []));
3510
3606
  resolvedLangCode = computed(() => this.context()?.langCode === 'ar' ? 'ar' : 'en', ...(ngDevMode ? [{ debugName: "resolvedLangCode" }] : /* istanbul ignore next */ []));
@@ -4096,11 +4192,16 @@ class TaskSchedule {
4096
4192
  ToolbarService,
4097
4193
  ContextMenuService,
4098
4194
  ResizeService,
4099
- ], viewQueries: [{ propertyName: "ganttObj", first: true, predicate: ["ganttObj"], descendants: true }], ngImport: i0, template: "@if (!loading()) {\r\n <ejs-gantt\r\n #ganttObj\r\n [id]=\"ganttId\"\r\n [enableVirtualization]=\"true\"\r\n [enableTimelineVirtualization]=\"true\"\r\n [enableVirtualMaskRow]=\"false\"\r\n [allowResizing]=\"true\"\r\n [enableRtl]=\"enableRtl()\"\r\n [locale]=\"locale()\"\r\n [height]=\"resolvedHeight()\"\r\n [dataSource]=\"dataSource()\"\r\n [taskFields]=\"ganttConfig().taskFields\"\r\n [columns]=\"ganttConfig().columns\"\r\n [renderBaseline]=\"ganttConfig().renderBaseline\"\r\n [enableCriticalPath]=\"ganttConfig().enableCriticalPath\"\r\n [allowSelection]=\"true\"\r\n [labelSettings]=\"ganttConfig().labelSettings\"\r\n [treeColumnIndex]=\"treeColumnIndex()\"\r\n [workWeek]=\"ganttConfig().workWeek\"\r\n [highlightWeekends]=\"true\"\r\n [enablePredecessorValidation]=\"true\"\r\n [splitterSettings]=\"ganttConfig().splitterSettings\"\r\n [gridLines]=\"ganttConfig().gridLines\"\r\n [toolbar]=\"ganttConfig().toolbar\"\r\n [allowExcelExport]=\"ganttConfig().allowExcelExport\"\r\n [allowPdfExport]=\"ganttConfig().allowPdfExport\"\r\n [enableContextMenu]=\"ganttConfig().enableContextMenu\"\r\n [contextMenuItems]=\"ganttConfig().contextMenuItems\"\r\n [timelineSettings]=\"ganttConfig().timelineSettings\"\r\n [editSettings]=\"ganttConfig().editSettings\"\r\n [allowRowDragAndDrop]=\"ganttConfig().allowRowDragAndDrop\"\r\n [addDialogFields]=\"ganttConfig().addDialogFields\"\r\n [editDialogFields]=\"ganttConfig().editDialogFields\"\r\n [resourceFields]=\"ganttConfig().resourceFields\"\r\n [resources]=\"ganttConfig().resources\"\r\n [viewType]=\"ganttConfig().viewType\"\r\n [showOverAllocation]=\"ganttConfig().showOverAllocation\"\r\n [allowUnscheduledTasks]=\"ganttConfig().allowUnscheduledTasks\"\r\n [eventMarkers]=\"ganttConfig().eventMarkers\"\r\n [projectStartDate]=\"ganttConfig().projectStartDate\"\r\n [projectEndDate]=\"ganttConfig().projectEndDate\"\r\n [autoCalculateDateScheduling]=\"false\"\r\n [dateFormat]=\"resolvedDateFormat()\"\r\n [allowSorting]=\"true\"\r\n [holidays]=\"ganttConfig().holidays\"\r\n [enableWBS]=\"true\"\r\n [enableAutoWbsUpdate]=\"true\"\r\n [allowReordering]=\"true\"\r\n (toolbarClick)=\"onToolbarClick($event)\"\r\n (contextMenuOpen)=\"onContextMenuOpen($event)\"\r\n (contextMenuClick)=\"onContextMenuClick($event)\"\r\n (actionBegin)=\"onActionBegin($event)\"\r\n (actionComplete)=\"onActionComplete($event)\"\r\n (cellEdit)=\"onCellEdit($event)\"\r\n (queryTaskbarInfo)=\"onQueryTaskbarInfo($event)\"\r\n (dataBound)=\"onDataBound()\"\r\n >\r\n <ng-template #tooltipSettingsTaskbar let-data>\r\n <div class=\"px-2 py-1 text-xs\">\r\n <div class=\"font-medium\">{{ data?.title ?? \"-\" }}</div>\r\n <div>\r\n {{ tooltipTranslations().startsOn }}:\r\n {{ data?.startDate ?? \"-\" }}\r\n </div>\r\n <div>\r\n {{ tooltipTranslations().endsOn }}:\r\n {{ data?.finishDate ?? \"-\" }}\r\n </div>\r\n @if (data?.baselineStartDate) {\r\n <div>\r\n {{ tooltipTranslations().plannedStart }}:\r\n {{ data?.baselineStartDate ?? \"-\" }}\r\n </div>\r\n }\r\n @if (data?.baselineEndDate) {\r\n <div>\r\n {{ tooltipTranslations().plannedEnd }}:\r\n {{ data?.baselineEndDate ?? \"-\" }}\r\n </div>\r\n }\r\n <div>\r\n {{ tooltipTranslations().progress }}: {{ data?.progress ?? 0 }}\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template #taskbarTemplate let-data>\r\n <mt-task-schedule-taskbar-template\r\n [data]=\"data\"\r\n [langCode]=\"resolvedLangCode()\"\r\n />\r\n </ng-template>\r\n </ejs-gantt>\r\n} @else {\r\n <div class=\"task-schedule-loader\">\r\n <div class=\"task-schedule-loader__spinner\" aria-label=\"Loading\"></div>\r\n </div>\r\n}\r\n", styles: [":host{display:block}:host ::ng-deep .e-headercell .e-headercelldiv{height:auto;display:flex!important}:host ::ng-deep .e-custom-holiday{background-color:#0a0f32}:host ::ng-deep .e-gantt .e-gantt-chart .e-baseline-bar{height:7px!important;border-radius:3px}:host ::ng-deep .e-gantt .e-gantt-chart .e-gantt-child-taskbar-inner-div{height:17px!important}:host ::ng-deep .e-row{cursor:pointer!important}.task-schedule-loader{display:grid;place-items:center;min-height:18rem}.task-schedule-loader__spinner{width:2.25rem;height:2.25rem;border-radius:9999px;border:3px solid rgba(148,163,184,.3);border-top-color:#334155;animation:task-schedule-spin .8s linear infinite}@keyframes task-schedule-spin{to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: GanttModule }, { kind: "component", type: i1$1.GanttComponent, selector: "ejs-gantt", inputs: ["addDialogFields", "allowExcelExport", "allowFiltering", "allowKeyboard", "allowParentDependency", "allowPdfExport", "allowReordering", "allowResizing", "allowRowDragAndDrop", "allowSelection", "allowSorting", "allowTaskbarDragAndDrop", "allowTaskbarOverlap", "allowUnscheduledTasks", "autoCalculateDateScheduling", "autoFocusTasks", "baselineColor", "calendarSettings", "collapseAllParentTasks", "columnMenuItems", "columns", "connectorLineBackground", "connectorLineWidth", "contextMenuItems", "dataSource", "dateFormat", "dayWorkingTime", "disableHtmlEncode", "durationUnit", "editDialogFields", "editSettings", "emptyRecordTemplate", "enableAdaptiveUI", "enableAutoWbsUpdate", "enableContextMenu", "enableCriticalPath", "enableHover", "enableHtmlSanitizer", "enableImmutableMode", "enableMultiTaskbar", "enablePersistence", "enablePredecessorValidation", "enableRtl", "enableTimelineVirtualization", "enableUndoRedo", "enableVirtualMaskRow", "enableVirtualization", "enableWBS", "eventMarkers", "filterSettings", "frozenColumns", "gridLines", "height", "highlightWeekends", "holidays", "includeWeekend", "labelSettings", "loadChildOnDemand", "loadingIndicator", "locale", "milestoneTemplate", "parentTaskbarTemplate", "projectEndDate", "projectStartDate", "query", "readOnly", "renderBaseline", "resourceFields", "resourceIDMapping", "resourceNameMapping", "resources", "rowHeight", "searchSettings", "segmentData", "selectedRowIndex", "selectionSettings", "showColumnMenu", "showInlineNotes", "showOverAllocation", "sortSettings", "splitterSettings", "taskFields", "taskMode", "taskType", "taskbarHeight", "taskbarTemplate", "timelineSettings", "timelineTemplate", "timezone", "toolbar", "tooltipSettings", "treeColumnIndex", "undoRedoActions", "undoRedoStepsCount", "updateOffsetOnTaskbarEdit", "validateManualTasksOnLinking", "viewType", "weekWorkingTime", "width", "workUnit", "workWeek", "zoomingLevels"], outputs: ["actionBegin", "actionComplete", "actionFailure", "beforeDataBound", "beforeExcelExport", "beforePdfExport", "beforeTooltipRender", "cellDeselected", "cellDeselecting", "cellEdit", "cellSave", "cellSelected", "cellSelecting", "collapsed", "collapsing", "columnDrag", "columnDragStart", "columnDrop", "columnMenuClick", "columnMenuOpen", "contextMenuClick", "contextMenuOpen", "created", "dataBound", "dataStateChange", "destroyed", "endEdit", "excelExportComplete", "excelHeaderQueryCellInfo", "excelQueryCellInfo", "expanded", "expanding", "headerCellInfo", "load", "onMouseMove", "onTaskbarClick", "pdfColumnHeaderQueryCellInfo", "pdfExportComplete", "pdfQueryCellInfo", "pdfQueryTaskbarInfo", "pdfQueryTimelineCellInfo", "queryCellInfo", "queryTaskbarInfo", "recordDoubleClick", "resizeStart", "resizeStop", "resizing", "rowDataBound", "rowDeselected", "rowDeselecting", "rowDrag", "rowDragStart", "rowDragStartHelper", "rowDrop", "rowSelected", "rowSelecting", "splitterResizeStart", "splitterResized", "splitterResizing", "taskbarEdited", "taskbarEditing", "toolbarClick", "dataSourceChange"] }, { kind: "component", type: TaskScheduleTaskbarTemplate, selector: "mt-task-schedule-taskbar-template", inputs: ["data", "langCode"] }] });
4195
+ ], viewQueries: [{ propertyName: "ganttObj", first: true, predicate: ["ganttObj"], descendants: true }], ngImport: i0, template: "@if (!loading()) {\r\n <ejs-gantt\r\n #ganttObj\r\n [id]=\"ganttId\"\r\n [enableVirtualization]=\"true\"\r\n [enableTimelineVirtualization]=\"true\"\r\n [enableVirtualMaskRow]=\"false\"\r\n [allowResizing]=\"true\"\r\n [enableRtl]=\"enableRtl()\"\r\n [locale]=\"locale()\"\r\n [height]=\"resolvedHeight()\"\r\n [dataSource]=\"dataSource()\"\r\n [taskFields]=\"ganttConfig().taskFields\"\r\n [columns]=\"ganttConfig().columns\"\r\n [renderBaseline]=\"ganttConfig().renderBaseline\"\r\n [enableCriticalPath]=\"ganttConfig().enableCriticalPath\"\r\n [allowSelection]=\"true\"\r\n [labelSettings]=\"ganttConfig().labelSettings\"\r\n [treeColumnIndex]=\"treeColumnIndex()\"\r\n [workWeek]=\"ganttConfig().workWeek\"\r\n [highlightWeekends]=\"true\"\r\n [enablePredecessorValidation]=\"true\"\r\n [splitterSettings]=\"ganttConfig().splitterSettings\"\r\n [gridLines]=\"ganttConfig().gridLines\"\r\n [toolbar]=\"ganttConfig().toolbar\"\r\n [allowExcelExport]=\"ganttConfig().allowExcelExport\"\r\n [allowPdfExport]=\"ganttConfig().allowPdfExport\"\r\n [enableContextMenu]=\"ganttConfig().enableContextMenu\"\r\n [contextMenuItems]=\"ganttConfig().contextMenuItems\"\r\n [timelineSettings]=\"ganttConfig().timelineSettings\"\r\n [editSettings]=\"ganttConfig().editSettings\"\r\n [allowRowDragAndDrop]=\"ganttConfig().allowRowDragAndDrop\"\r\n [addDialogFields]=\"ganttConfig().addDialogFields\"\r\n [editDialogFields]=\"ganttConfig().editDialogFields\"\r\n [resourceFields]=\"ganttConfig().resourceFields\"\r\n [resources]=\"ganttConfig().resources\"\r\n [viewType]=\"ganttConfig().viewType\"\r\n [showOverAllocation]=\"ganttConfig().showOverAllocation\"\r\n [allowUnscheduledTasks]=\"ganttConfig().allowUnscheduledTasks\"\r\n [eventMarkers]=\"ganttConfig().eventMarkers\"\r\n [projectStartDate]=\"ganttConfig().projectStartDate\"\r\n [projectEndDate]=\"ganttConfig().projectEndDate\"\r\n [autoCalculateDateScheduling]=\"false\"\r\n [dateFormat]=\"resolvedDateFormat()\"\r\n [allowSorting]=\"true\"\r\n [holidays]=\"ganttConfig().holidays\"\r\n [enableWBS]=\"true\"\r\n [enableAutoWbsUpdate]=\"true\"\r\n [allowReordering]=\"true\"\r\n (toolbarClick)=\"onToolbarClick($event)\"\r\n (contextMenuOpen)=\"onContextMenuOpen($event)\"\r\n (contextMenuClick)=\"onContextMenuClick($event)\"\r\n (actionBegin)=\"onActionBegin($event)\"\r\n (actionComplete)=\"onActionComplete($event)\"\r\n (cellEdit)=\"onCellEdit($event)\"\r\n (queryTaskbarInfo)=\"onQueryTaskbarInfo($event)\"\r\n (dataBound)=\"onDataBound()\"\r\n >\r\n <ng-template #tooltipSettingsTaskbar let-data>\r\n <div class=\"px-2 py-1 text-xs\">\r\n <div class=\"font-medium\">{{ data?.title ?? \"-\" }}</div>\r\n <div>\r\n {{ tooltipTranslations().startsOn }}:\r\n {{ data?.startDate ? (data.startDate | mtDateFormat: \"date\") : \"-\" }}\r\n </div>\r\n <div>\r\n {{ tooltipTranslations().endsOn }}:\r\n {{\r\n data?.finishDate ? (data.finishDate | mtDateFormat: \"date\") : \"-\"\r\n }}\r\n </div>\r\n @if (data?.baselineStartDate) {\r\n <div>\r\n {{ tooltipTranslations().plannedStart }}:\r\n {{\r\n data?.baselineStartDate\r\n ? (data.baselineStartDate | mtDateFormat: \"date\")\r\n : \"-\"\r\n }}\r\n </div>\r\n }\r\n @if (data?.baselineEndDate) {\r\n <div>\r\n {{ tooltipTranslations().plannedEnd }}:\r\n {{\r\n data?.baselineEndDate\r\n ? (data.baselineEndDate | mtDateFormat: \"date\")\r\n : \"-\"\r\n }}\r\n </div>\r\n }\r\n <div>\r\n {{ tooltipTranslations().progress }}: {{ data?.progress ?? 0 }}\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template #taskbarTemplate let-data>\r\n <mt-task-schedule-taskbar-template\r\n [data]=\"data\"\r\n [langCode]=\"resolvedLangCode()\"\r\n />\r\n </ng-template>\r\n </ejs-gantt>\r\n} @else {\r\n <div class=\"task-schedule-loader\">\r\n <div class=\"task-schedule-loader__spinner\" aria-label=\"Loading\"></div>\r\n </div>\r\n}\r\n", styles: [":host{display:block}:host ::ng-deep .e-headercell .e-headercelldiv{height:auto;display:flex!important}:host ::ng-deep .e-custom-holiday{background-color:#0a0f32}:host ::ng-deep .e-gantt .e-gantt-chart .e-baseline-bar{height:7px!important;border-radius:3px}:host ::ng-deep .e-gantt .e-gantt-chart .e-gantt-child-taskbar-inner-div{height:17px!important}:host ::ng-deep .e-row{cursor:pointer!important}.task-schedule-loader{display:grid;place-items:center;min-height:18rem}.task-schedule-loader__spinner{width:2.25rem;height:2.25rem;border-radius:9999px;border:3px solid rgba(148,163,184,.3);border-top-color:#334155;animation:task-schedule-spin .8s linear infinite}@keyframes task-schedule-spin{to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: GanttModule }, { kind: "component", type: i1$1.GanttComponent, selector: "ejs-gantt", inputs: ["addDialogFields", "allowExcelExport", "allowFiltering", "allowKeyboard", "allowParentDependency", "allowPdfExport", "allowReordering", "allowResizing", "allowRowDragAndDrop", "allowSelection", "allowSorting", "allowTaskbarDragAndDrop", "allowTaskbarOverlap", "allowUnscheduledTasks", "autoCalculateDateScheduling", "autoFocusTasks", "baselineColor", "calendarSettings", "collapseAllParentTasks", "columnMenuItems", "columns", "connectorLineBackground", "connectorLineWidth", "contextMenuItems", "dataSource", "dateFormat", "dayWorkingTime", "disableHtmlEncode", "durationUnit", "editDialogFields", "editSettings", "emptyRecordTemplate", "enableAdaptiveUI", "enableAutoWbsUpdate", "enableContextMenu", "enableCriticalPath", "enableHover", "enableHtmlSanitizer", "enableImmutableMode", "enableMultiTaskbar", "enablePersistence", "enablePredecessorValidation", "enableRtl", "enableTimelineVirtualization", "enableUndoRedo", "enableVirtualMaskRow", "enableVirtualization", "enableWBS", "eventMarkers", "filterSettings", "frozenColumns", "gridLines", "height", "highlightWeekends", "holidays", "includeWeekend", "labelSettings", "loadChildOnDemand", "loadingIndicator", "locale", "milestoneTemplate", "parentTaskbarTemplate", "projectEndDate", "projectStartDate", "query", "readOnly", "renderBaseline", "resourceFields", "resourceIDMapping", "resourceNameMapping", "resources", "rowHeight", "searchSettings", "segmentData", "selectedRowIndex", "selectionSettings", "showColumnMenu", "showInlineNotes", "showOverAllocation", "sortSettings", "splitterSettings", "taskFields", "taskMode", "taskType", "taskbarHeight", "taskbarTemplate", "timelineSettings", "timelineTemplate", "timezone", "toolbar", "tooltipSettings", "treeColumnIndex", "undoRedoActions", "undoRedoStepsCount", "updateOffsetOnTaskbarEdit", "validateManualTasksOnLinking", "viewType", "weekWorkingTime", "width", "workUnit", "workWeek", "zoomingLevels"], outputs: ["actionBegin", "actionComplete", "actionFailure", "beforeDataBound", "beforeExcelExport", "beforePdfExport", "beforeTooltipRender", "cellDeselected", "cellDeselecting", "cellEdit", "cellSave", "cellSelected", "cellSelecting", "collapsed", "collapsing", "columnDrag", "columnDragStart", "columnDrop", "columnMenuClick", "columnMenuOpen", "contextMenuClick", "contextMenuOpen", "created", "dataBound", "dataStateChange", "destroyed", "endEdit", "excelExportComplete", "excelHeaderQueryCellInfo", "excelQueryCellInfo", "expanded", "expanding", "headerCellInfo", "load", "onMouseMove", "onTaskbarClick", "pdfColumnHeaderQueryCellInfo", "pdfExportComplete", "pdfQueryCellInfo", "pdfQueryTaskbarInfo", "pdfQueryTimelineCellInfo", "queryCellInfo", "queryTaskbarInfo", "recordDoubleClick", "resizeStart", "resizeStop", "resizing", "rowDataBound", "rowDeselected", "rowDeselecting", "rowDrag", "rowDragStart", "rowDragStartHelper", "rowDrop", "rowSelected", "rowSelecting", "splitterResizeStart", "splitterResized", "splitterResizing", "taskbarEdited", "taskbarEditing", "toolbarClick", "dataSourceChange"] }, { kind: "component", type: TaskScheduleTaskbarTemplate, selector: "mt-task-schedule-taskbar-template", inputs: ["data", "langCode"] }, { kind: "pipe", type: MTDateFormatPipe, name: "mtDateFormat" }] });
4100
4196
  }
4101
4197
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TaskSchedule, decorators: [{
4102
4198
  type: Component,
4103
- args: [{ selector: 'mt-task-schedule', standalone: true, imports: [CommonModule, GanttModule, TaskScheduleTaskbarTemplate], host: { class: 'block' }, providers: [
4199
+ args: [{ selector: 'mt-task-schedule', standalone: true, imports: [
4200
+ CommonModule,
4201
+ GanttModule,
4202
+ MTDateFormatPipe,
4203
+ TaskScheduleTaskbarTemplate,
4204
+ ], host: { class: 'block' }, providers: [
4104
4205
  DayMarkersService,
4105
4206
  EditService,
4106
4207
  ExcelExportService,
@@ -4113,7 +4214,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
4113
4214
  ToolbarService,
4114
4215
  ContextMenuService,
4115
4216
  ResizeService,
4116
- ], template: "@if (!loading()) {\r\n <ejs-gantt\r\n #ganttObj\r\n [id]=\"ganttId\"\r\n [enableVirtualization]=\"true\"\r\n [enableTimelineVirtualization]=\"true\"\r\n [enableVirtualMaskRow]=\"false\"\r\n [allowResizing]=\"true\"\r\n [enableRtl]=\"enableRtl()\"\r\n [locale]=\"locale()\"\r\n [height]=\"resolvedHeight()\"\r\n [dataSource]=\"dataSource()\"\r\n [taskFields]=\"ganttConfig().taskFields\"\r\n [columns]=\"ganttConfig().columns\"\r\n [renderBaseline]=\"ganttConfig().renderBaseline\"\r\n [enableCriticalPath]=\"ganttConfig().enableCriticalPath\"\r\n [allowSelection]=\"true\"\r\n [labelSettings]=\"ganttConfig().labelSettings\"\r\n [treeColumnIndex]=\"treeColumnIndex()\"\r\n [workWeek]=\"ganttConfig().workWeek\"\r\n [highlightWeekends]=\"true\"\r\n [enablePredecessorValidation]=\"true\"\r\n [splitterSettings]=\"ganttConfig().splitterSettings\"\r\n [gridLines]=\"ganttConfig().gridLines\"\r\n [toolbar]=\"ganttConfig().toolbar\"\r\n [allowExcelExport]=\"ganttConfig().allowExcelExport\"\r\n [allowPdfExport]=\"ganttConfig().allowPdfExport\"\r\n [enableContextMenu]=\"ganttConfig().enableContextMenu\"\r\n [contextMenuItems]=\"ganttConfig().contextMenuItems\"\r\n [timelineSettings]=\"ganttConfig().timelineSettings\"\r\n [editSettings]=\"ganttConfig().editSettings\"\r\n [allowRowDragAndDrop]=\"ganttConfig().allowRowDragAndDrop\"\r\n [addDialogFields]=\"ganttConfig().addDialogFields\"\r\n [editDialogFields]=\"ganttConfig().editDialogFields\"\r\n [resourceFields]=\"ganttConfig().resourceFields\"\r\n [resources]=\"ganttConfig().resources\"\r\n [viewType]=\"ganttConfig().viewType\"\r\n [showOverAllocation]=\"ganttConfig().showOverAllocation\"\r\n [allowUnscheduledTasks]=\"ganttConfig().allowUnscheduledTasks\"\r\n [eventMarkers]=\"ganttConfig().eventMarkers\"\r\n [projectStartDate]=\"ganttConfig().projectStartDate\"\r\n [projectEndDate]=\"ganttConfig().projectEndDate\"\r\n [autoCalculateDateScheduling]=\"false\"\r\n [dateFormat]=\"resolvedDateFormat()\"\r\n [allowSorting]=\"true\"\r\n [holidays]=\"ganttConfig().holidays\"\r\n [enableWBS]=\"true\"\r\n [enableAutoWbsUpdate]=\"true\"\r\n [allowReordering]=\"true\"\r\n (toolbarClick)=\"onToolbarClick($event)\"\r\n (contextMenuOpen)=\"onContextMenuOpen($event)\"\r\n (contextMenuClick)=\"onContextMenuClick($event)\"\r\n (actionBegin)=\"onActionBegin($event)\"\r\n (actionComplete)=\"onActionComplete($event)\"\r\n (cellEdit)=\"onCellEdit($event)\"\r\n (queryTaskbarInfo)=\"onQueryTaskbarInfo($event)\"\r\n (dataBound)=\"onDataBound()\"\r\n >\r\n <ng-template #tooltipSettingsTaskbar let-data>\r\n <div class=\"px-2 py-1 text-xs\">\r\n <div class=\"font-medium\">{{ data?.title ?? \"-\" }}</div>\r\n <div>\r\n {{ tooltipTranslations().startsOn }}:\r\n {{ data?.startDate ?? \"-\" }}\r\n </div>\r\n <div>\r\n {{ tooltipTranslations().endsOn }}:\r\n {{ data?.finishDate ?? \"-\" }}\r\n </div>\r\n @if (data?.baselineStartDate) {\r\n <div>\r\n {{ tooltipTranslations().plannedStart }}:\r\n {{ data?.baselineStartDate ?? \"-\" }}\r\n </div>\r\n }\r\n @if (data?.baselineEndDate) {\r\n <div>\r\n {{ tooltipTranslations().plannedEnd }}:\r\n {{ data?.baselineEndDate ?? \"-\" }}\r\n </div>\r\n }\r\n <div>\r\n {{ tooltipTranslations().progress }}: {{ data?.progress ?? 0 }}\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template #taskbarTemplate let-data>\r\n <mt-task-schedule-taskbar-template\r\n [data]=\"data\"\r\n [langCode]=\"resolvedLangCode()\"\r\n />\r\n </ng-template>\r\n </ejs-gantt>\r\n} @else {\r\n <div class=\"task-schedule-loader\">\r\n <div class=\"task-schedule-loader__spinner\" aria-label=\"Loading\"></div>\r\n </div>\r\n}\r\n", styles: [":host{display:block}:host ::ng-deep .e-headercell .e-headercelldiv{height:auto;display:flex!important}:host ::ng-deep .e-custom-holiday{background-color:#0a0f32}:host ::ng-deep .e-gantt .e-gantt-chart .e-baseline-bar{height:7px!important;border-radius:3px}:host ::ng-deep .e-gantt .e-gantt-chart .e-gantt-child-taskbar-inner-div{height:17px!important}:host ::ng-deep .e-row{cursor:pointer!important}.task-schedule-loader{display:grid;place-items:center;min-height:18rem}.task-schedule-loader__spinner{width:2.25rem;height:2.25rem;border-radius:9999px;border:3px solid rgba(148,163,184,.3);border-top-color:#334155;animation:task-schedule-spin .8s linear infinite}@keyframes task-schedule-spin{to{transform:rotate(360deg)}}\n"] }]
4217
+ ], template: "@if (!loading()) {\r\n <ejs-gantt\r\n #ganttObj\r\n [id]=\"ganttId\"\r\n [enableVirtualization]=\"true\"\r\n [enableTimelineVirtualization]=\"true\"\r\n [enableVirtualMaskRow]=\"false\"\r\n [allowResizing]=\"true\"\r\n [enableRtl]=\"enableRtl()\"\r\n [locale]=\"locale()\"\r\n [height]=\"resolvedHeight()\"\r\n [dataSource]=\"dataSource()\"\r\n [taskFields]=\"ganttConfig().taskFields\"\r\n [columns]=\"ganttConfig().columns\"\r\n [renderBaseline]=\"ganttConfig().renderBaseline\"\r\n [enableCriticalPath]=\"ganttConfig().enableCriticalPath\"\r\n [allowSelection]=\"true\"\r\n [labelSettings]=\"ganttConfig().labelSettings\"\r\n [treeColumnIndex]=\"treeColumnIndex()\"\r\n [workWeek]=\"ganttConfig().workWeek\"\r\n [highlightWeekends]=\"true\"\r\n [enablePredecessorValidation]=\"true\"\r\n [splitterSettings]=\"ganttConfig().splitterSettings\"\r\n [gridLines]=\"ganttConfig().gridLines\"\r\n [toolbar]=\"ganttConfig().toolbar\"\r\n [allowExcelExport]=\"ganttConfig().allowExcelExport\"\r\n [allowPdfExport]=\"ganttConfig().allowPdfExport\"\r\n [enableContextMenu]=\"ganttConfig().enableContextMenu\"\r\n [contextMenuItems]=\"ganttConfig().contextMenuItems\"\r\n [timelineSettings]=\"ganttConfig().timelineSettings\"\r\n [editSettings]=\"ganttConfig().editSettings\"\r\n [allowRowDragAndDrop]=\"ganttConfig().allowRowDragAndDrop\"\r\n [addDialogFields]=\"ganttConfig().addDialogFields\"\r\n [editDialogFields]=\"ganttConfig().editDialogFields\"\r\n [resourceFields]=\"ganttConfig().resourceFields\"\r\n [resources]=\"ganttConfig().resources\"\r\n [viewType]=\"ganttConfig().viewType\"\r\n [showOverAllocation]=\"ganttConfig().showOverAllocation\"\r\n [allowUnscheduledTasks]=\"ganttConfig().allowUnscheduledTasks\"\r\n [eventMarkers]=\"ganttConfig().eventMarkers\"\r\n [projectStartDate]=\"ganttConfig().projectStartDate\"\r\n [projectEndDate]=\"ganttConfig().projectEndDate\"\r\n [autoCalculateDateScheduling]=\"false\"\r\n [dateFormat]=\"resolvedDateFormat()\"\r\n [allowSorting]=\"true\"\r\n [holidays]=\"ganttConfig().holidays\"\r\n [enableWBS]=\"true\"\r\n [enableAutoWbsUpdate]=\"true\"\r\n [allowReordering]=\"true\"\r\n (toolbarClick)=\"onToolbarClick($event)\"\r\n (contextMenuOpen)=\"onContextMenuOpen($event)\"\r\n (contextMenuClick)=\"onContextMenuClick($event)\"\r\n (actionBegin)=\"onActionBegin($event)\"\r\n (actionComplete)=\"onActionComplete($event)\"\r\n (cellEdit)=\"onCellEdit($event)\"\r\n (queryTaskbarInfo)=\"onQueryTaskbarInfo($event)\"\r\n (dataBound)=\"onDataBound()\"\r\n >\r\n <ng-template #tooltipSettingsTaskbar let-data>\r\n <div class=\"px-2 py-1 text-xs\">\r\n <div class=\"font-medium\">{{ data?.title ?? \"-\" }}</div>\r\n <div>\r\n {{ tooltipTranslations().startsOn }}:\r\n {{ data?.startDate ? (data.startDate | mtDateFormat: \"date\") : \"-\" }}\r\n </div>\r\n <div>\r\n {{ tooltipTranslations().endsOn }}:\r\n {{\r\n data?.finishDate ? (data.finishDate | mtDateFormat: \"date\") : \"-\"\r\n }}\r\n </div>\r\n @if (data?.baselineStartDate) {\r\n <div>\r\n {{ tooltipTranslations().plannedStart }}:\r\n {{\r\n data?.baselineStartDate\r\n ? (data.baselineStartDate | mtDateFormat: \"date\")\r\n : \"-\"\r\n }}\r\n </div>\r\n }\r\n @if (data?.baselineEndDate) {\r\n <div>\r\n {{ tooltipTranslations().plannedEnd }}:\r\n {{\r\n data?.baselineEndDate\r\n ? (data.baselineEndDate | mtDateFormat: \"date\")\r\n : \"-\"\r\n }}\r\n </div>\r\n }\r\n <div>\r\n {{ tooltipTranslations().progress }}: {{ data?.progress ?? 0 }}\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template #taskbarTemplate let-data>\r\n <mt-task-schedule-taskbar-template\r\n [data]=\"data\"\r\n [langCode]=\"resolvedLangCode()\"\r\n />\r\n </ng-template>\r\n </ejs-gantt>\r\n} @else {\r\n <div class=\"task-schedule-loader\">\r\n <div class=\"task-schedule-loader__spinner\" aria-label=\"Loading\"></div>\r\n </div>\r\n}\r\n", styles: [":host{display:block}:host ::ng-deep .e-headercell .e-headercelldiv{height:auto;display:flex!important}:host ::ng-deep .e-custom-holiday{background-color:#0a0f32}:host ::ng-deep .e-gantt .e-gantt-chart .e-baseline-bar{height:7px!important;border-radius:3px}:host ::ng-deep .e-gantt .e-gantt-chart .e-gantt-child-taskbar-inner-div{height:17px!important}:host ::ng-deep .e-row{cursor:pointer!important}.task-schedule-loader{display:grid;place-items:center;min-height:18rem}.task-schedule-loader__spinner{width:2.25rem;height:2.25rem;border-radius:9999px;border:3px solid rgba(148,163,184,.3);border-top-color:#334155;animation:task-schedule-spin .8s linear infinite}@keyframes task-schedule-spin{to{transform:rotate(360deg)}}\n"] }]
4117
4218
  }], propDecorators: { ganttObj: [{
4118
4219
  type: ViewChild,
4119
4220
  args: ['ganttObj']