@masterteam/task-schedule 0.0.2 → 0.0.3

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.
@@ -74,6 +74,30 @@ function normalizeTaskScheduleModelType(modelType) {
74
74
 
75
75
  const TASK_SCHEDULE_DATA_ADAPTER = new InjectionToken('TASK_SCHEDULE_DATA_ADAPTER');
76
76
  const DEFAULT_CUSTOM_PROPERTIES = [];
77
+ const SCHEDULE_NATIVE_KEYS = new Set([
78
+ 'name',
79
+ 'status',
80
+ 'plannedStart',
81
+ 'plannedFinish',
82
+ 'actualStart',
83
+ 'actualFinish',
84
+ 'baselineStart',
85
+ 'baselineFinish',
86
+ 'duration',
87
+ 'progress',
88
+ 'predecessor',
89
+ 'predecessors',
90
+ 'assignedTo',
91
+ 'resources',
92
+ 'order',
93
+ 'parentId',
94
+ 'phaseGate',
95
+ 'criticalPath',
96
+ 'type',
97
+ 'details',
98
+ 'id',
99
+ 'levelDataId',
100
+ ]);
77
101
  class TaskScheduleBackendAdapter {
78
102
  http = inject(HttpClient, { optional: true });
79
103
  load(modelType, context) {
@@ -81,21 +105,11 @@ class TaskScheduleBackendAdapter {
81
105
  return this.backendError('TaskScheduleBackendAdapter requires HttpClient. Configure provideHttpClient() in the host app.');
82
106
  }
83
107
  const normalizedModel = normalizeTaskScheduleModelType(modelType);
84
- const treeRouteTemplate = this.resolveTreeRouteTemplate(context, normalizedModel);
85
108
  const levelId = this.readId(context.levelId);
86
109
  if (!levelId) {
87
110
  return this.backendError('TaskSchedule context requires levelId for backend calls.');
88
111
  }
89
- const treeRouteParams = this.buildTreeRouteParams(context, treeRouteTemplate);
90
- if (!treeRouteParams) {
91
- return this.backendError('TaskSchedule context is missing required identifiers for the selected schedule endpoint.');
92
- }
93
- const treeUrl = this.resolveApiUrl(context, treeRouteTemplate, treeRouteParams);
94
- return this.http
95
- .get(treeUrl, {
96
- headers: this.readHeaders(context),
97
- })
98
- .pipe(map((response) => this.unwrapResponse(response, 'Failed to load schedule tree.')), map((payload) => ({
112
+ return this.resolveReadPayload(context, normalizedModel).pipe(map((payload) => ({
99
113
  payload,
100
114
  rows: this.extractTaskArray(payload),
101
115
  })), map(({ payload, rows }) => ({
@@ -153,6 +167,218 @@ class TaskScheduleBackendAdapter {
153
167
  }));
154
168
  }));
155
169
  }
170
+ resolveReadPayload(context, modelType) {
171
+ if (modelType === 'phaseGate') {
172
+ return this.loadLegacyPhaseGatePayload(context);
173
+ }
174
+ if (modelType === 'resources') {
175
+ return this.loadScheduleUtilityPayload(context, 'levels/{levelId}/{levelDataId}/schedule/by-resource', 'Failed to load schedule resources.');
176
+ }
177
+ if (modelType === 'unscheduled') {
178
+ return this.loadScheduleUtilityPayload(context, 'levels/{levelId}/{levelDataId}/schedule/unscheduled', 'Failed to load unscheduled schedule items.');
179
+ }
180
+ if (modelType === 'baseline') {
181
+ return this.loadScheduleUtilityPayload(context, 'levels/{levelId}/{levelDataId}/schedule/baselines/latest', 'Failed to load schedule baseline.');
182
+ }
183
+ return this.loadScheduleQueryPayload(context);
184
+ }
185
+ loadScheduleQueryPayload(context) {
186
+ if (!this.http) {
187
+ return this.backendError('Task schedule query loading requires HttpClient.');
188
+ }
189
+ const levelId = this.readId(context.levelId);
190
+ const levelDataId = this.readId(context.levelDataId);
191
+ if (!levelId || !levelDataId) {
192
+ return this.backendError('TaskSchedule context requires levelId and levelDataId for schedule reads.');
193
+ }
194
+ const endpoint = this.resolveApiUrl(context, 'levels/{levelId}/{levelDataId}/schedule/query', {
195
+ levelId,
196
+ levelDataId,
197
+ });
198
+ return this.http
199
+ .post(endpoint, {
200
+ projection: 'Tree',
201
+ }, {
202
+ headers: this.readHeaders(context),
203
+ })
204
+ .pipe(map((response) => this.unwrapResponse(response, 'Failed to load schedule records.')), map((data) => this.composeFetchPayload(data)));
205
+ }
206
+ loadScheduleUtilityPayload(context, template, fallbackMessage) {
207
+ if (!this.http) {
208
+ return this.backendError(fallbackMessage);
209
+ }
210
+ const levelId = this.readId(context.levelId);
211
+ const levelDataId = this.readId(context.levelDataId);
212
+ if (!levelId || !levelDataId) {
213
+ return this.backendError('TaskSchedule context requires levelId and levelDataId for schedule utility reads.');
214
+ }
215
+ const url = this.resolveApiUrl(context, template, {
216
+ levelId,
217
+ levelDataId,
218
+ });
219
+ return this.http
220
+ .get(url, {
221
+ headers: this.readHeaders(context),
222
+ })
223
+ .pipe(map((response) => this.unwrapResponse(response, fallbackMessage)));
224
+ }
225
+ loadLegacyPhaseGatePayload(context) {
226
+ if (!this.http) {
227
+ return this.backendError('Failed to load phase gate schedule tree.');
228
+ }
229
+ const treeRouteTemplate = this.resolveTreeRouteTemplate(context, 'phaseGate');
230
+ const treeRouteParams = this.buildTreeRouteParams(context, treeRouteTemplate);
231
+ if (!treeRouteParams) {
232
+ return this.backendError('TaskSchedule context is missing required identifiers for phase gate mode.');
233
+ }
234
+ const treeUrl = this.resolveApiUrl(context, treeRouteTemplate, treeRouteParams);
235
+ return this.http
236
+ .get(treeUrl, {
237
+ headers: this.readHeaders(context),
238
+ })
239
+ .pipe(map((response) => this.unwrapResponse(response, 'Failed to load phase gate schedule tree.')));
240
+ }
241
+ composeFetchPayload(data) {
242
+ const schemaMap = this.toFetchSchemaMap(data.schemas ?? []);
243
+ const tasks = this.mapFetchRecords(this.resolveFetchRootRecords(data.records ?? [], data.projectionMeta?.rootIds ?? []), schemaMap);
244
+ const customProperties = this.mergeFetchCustomProperties(this.mapFetchCustomProperties(data.catalog?.properties ?? []));
245
+ return {
246
+ tasks,
247
+ customProperties,
248
+ };
249
+ }
250
+ resolveFetchRootRecords(records, rootIds) {
251
+ if (!rootIds.length) {
252
+ return records;
253
+ }
254
+ const byId = new Map(records.map((record) => [String(record.id), record]));
255
+ return rootIds
256
+ .map((id) => byId.get(String(id)))
257
+ .filter((record) => record != null);
258
+ }
259
+ toFetchSchemaMap(schemas) {
260
+ return new Map(schemas
261
+ .filter((schema) => this.readId(schema.id) != null)
262
+ .map((schema) => [String(schema.id), schema]));
263
+ }
264
+ mapFetchRecords(records, schemaMap) {
265
+ return records.map((record, index) => this.mapFetchRecord(record, index + 1, schemaMap));
266
+ }
267
+ mapFetchRecord(record, fallbackOrder, schemaMap) {
268
+ const values = record.values ?? {};
269
+ const schema = this.readId(record.schemaId)
270
+ ? schemaMap.get(String(record.schemaId))
271
+ : undefined;
272
+ const type = this.readFetchCellDisplay(values['type']) ??
273
+ this.toNullableString(this.readFetchCellValue(values['type'])) ??
274
+ this.toNullableString(schema?.key) ??
275
+ 'Task';
276
+ const subtasks = (record.children ?? []).map((child, index) => this.mapFetchRecord(child, index + 1, schemaMap));
277
+ return {
278
+ id: record.id,
279
+ title: record.name ??
280
+ this.readFetchCellDisplay(values['name']) ??
281
+ `Task ${String(record.id)}`,
282
+ name: record.name ??
283
+ this.readFetchCellDisplay(values['name']) ??
284
+ `Task ${String(record.id)}`,
285
+ startDate: this.readFetchCellValue(values['plannedStart']),
286
+ finishDate: this.readFetchCellValue(values['plannedFinish']),
287
+ baselineStartDate: this.readFetchCellValue(values['baselineStart']),
288
+ baselineEndDate: this.readFetchCellValue(values['baselineFinish']),
289
+ actualStartDate: this.readFetchCellValue(values['actualStart']),
290
+ actualFinishDate: this.readFetchCellValue(values['actualFinish']),
291
+ predecessor: this.readFetchCellDisplay(values['predecessor']) ??
292
+ this.readFetchCellDisplay(values['predecessors']) ??
293
+ this.toNullableString(this.readFetchCellValue(values['predecessor'])) ??
294
+ this.toNullableString(this.readFetchCellValue(values['predecessors'])),
295
+ duration: this.readFetchCellValue(values['duration']),
296
+ progress: this.readFetchCellValue(values['progress']),
297
+ details: this.readFetchCellDisplay(values['details']) ??
298
+ this.toNullableString(this.readFetchCellValue(values['details'])),
299
+ status: this.readFetchCellValue(values['status']),
300
+ type,
301
+ typeLabel: this.toNullableString(schema?.name) ?? type,
302
+ typeLable: this.toNullableString(schema?.name) ?? type,
303
+ assignedTo: this.readFetchCellValue(values['assignedTo']),
304
+ resources: this.readFetchCellValue(values['resources']),
305
+ phaseGate: this.readFetchCellDisplay(values['phaseGate']) ??
306
+ this.toNullableString(this.readFetchCellValue(values['phaseGate'])),
307
+ criticalPath: Boolean(this.readFetchCellValue(values['criticalPath'])),
308
+ order: this.readFetchOrder(values['order']) ?? fallbackOrder,
309
+ props: this.readFetchCustomProps(values),
310
+ subtasks,
311
+ };
312
+ }
313
+ readFetchCustomProps(values) {
314
+ return Object.entries(values)
315
+ .filter(([key]) => !SCHEDULE_NATIVE_KEYS.has(key))
316
+ .map(([key, cell]) => ({
317
+ id: 0,
318
+ key,
319
+ rawValue: this.readFetchCellRaw(cell),
320
+ value: this.readFetchCellValue(cell),
321
+ }));
322
+ }
323
+ mapFetchCustomProperties(properties) {
324
+ return properties
325
+ .filter((property) => !SCHEDULE_NATIVE_KEYS.has(property.normalizedKey))
326
+ .sort((left, right) => (left.order ?? 0) - (right.order ?? 0))
327
+ .map((property) => ({
328
+ id: property.id,
329
+ key: property.normalizedKey,
330
+ name: property.label,
331
+ viewType: property.viewType,
332
+ normalizedKey: property.normalizedKey,
333
+ isRequired: !!property.isRequired,
334
+ isCalculated: !!property.isCalculated,
335
+ configuration: property.configuration ?? null,
336
+ }));
337
+ }
338
+ mergeFetchCustomProperties(properties) {
339
+ const byKey = new Map();
340
+ properties.forEach((property) => {
341
+ if (!byKey.has(property.key)) {
342
+ byKey.set(property.key, property);
343
+ }
344
+ });
345
+ return Array.from(byKey.values());
346
+ }
347
+ readFetchCellRaw(cell) {
348
+ if (!cell || typeof cell !== 'object') {
349
+ return cell;
350
+ }
351
+ const row = cell;
352
+ if ('raw' in row || 'value' in row || 'display' in row) {
353
+ return row['raw'] ?? row['value'] ?? row['display'] ?? null;
354
+ }
355
+ return cell;
356
+ }
357
+ readFetchCellValue(cell) {
358
+ if (!cell || typeof cell !== 'object') {
359
+ return cell;
360
+ }
361
+ const row = cell;
362
+ if ('raw' in row || 'value' in row || 'display' in row) {
363
+ return row['value'] ?? row['raw'] ?? row['display'] ?? null;
364
+ }
365
+ return cell;
366
+ }
367
+ readFetchCellDisplay(cell) {
368
+ if (!cell || typeof cell !== 'object') {
369
+ return this.toNullableString(cell);
370
+ }
371
+ const row = cell;
372
+ if ('display' in row || 'value' in row || 'raw' in row) {
373
+ return (this.toNullableString(row['display']) ??
374
+ this.toNullableString(row['value']) ??
375
+ this.toNullableString(row['raw']));
376
+ }
377
+ return this.toNullableString(cell);
378
+ }
379
+ readFetchOrder(cell) {
380
+ return this.toNullableNumber(this.readFetchCellValue(cell));
381
+ }
156
382
  createTask(context, payload) {
157
383
  if (!this.http) {
158
384
  return this.backendError('Task create requires HttpClient.');
@@ -490,60 +716,16 @@ class TaskScheduleBackendAdapter {
490
716
  null);
491
717
  }))), map((view) => this.mapScheduleColumns(view?.columns ?? [], context.langCode ?? 'en')));
492
718
  }
493
- resolveTreeRouteTemplate(context, modelType) {
494
- const modeEndpointKeyByModel = {
495
- default: 'scheduleTreeDefault',
496
- edit: 'scheduleTreeEdit',
497
- baseline: 'scheduleTreeBaseline',
498
- criticalPath: 'scheduleTreeCriticalPath',
499
- resources: 'scheduleTreeResources',
500
- unscheduled: 'scheduleTreeUnscheduled',
501
- phaseGate: 'scheduleTreePhaseGate',
502
- custom: 'scheduleTreeCustom',
503
- };
504
- const modeSpecificRoute = this.readEndpoint(context.endpoints, modeEndpointKeyByModel[modelType]);
505
- if (modeSpecificRoute) {
506
- return modeSpecificRoute;
719
+ resolveTreeRouteTemplate(context, _modelType) {
720
+ const phaseGateRoute = this.readEndpoint(context.endpoints, 'scheduleTreePhaseGate');
721
+ if (phaseGateRoute) {
722
+ return phaseGateRoute;
507
723
  }
508
724
  const customTreeRoute = this.readEndpoint(context.endpoints, 'scheduleTree');
509
725
  if (customTreeRoute) {
510
726
  return customTreeRoute;
511
727
  }
512
- const levelDataId = this.readId(context.levelDataId);
513
- if (levelDataId) {
514
- if (modelType === 'unscheduled') {
515
- return 'levels/{levelId}/{levelDataId}/schedule/unscheduled';
516
- }
517
- if (modelType === 'phaseGate') {
518
- return 'levels/{levelId}/{levelDataId}/schedule/tree?renderMode=PhaseGate';
519
- }
520
- if (modelType === 'resources') {
521
- return 'levels/{levelId}/{levelDataId}/schedule/by-resource';
522
- }
523
- return 'levels/{levelId}/{levelDataId}/schedule/tree';
524
- }
525
- if (this.readId(context.schemaId)) {
526
- if (modelType === 'baseline') {
527
- return 'tasks/{levelId}/GetAllBaseLine';
528
- }
529
- if (modelType === 'unscheduled') {
530
- return 'tasks/{levelId}/unscheduled';
531
- }
532
- if (modelType === 'phaseGate') {
533
- return 'tasks/{levelId}/GetAll?RenderMode=PhaseGate';
534
- }
535
- return 'tasks/{levelId}/GetAll';
536
- }
537
- if (modelType === 'baseline') {
538
- return 'tasks/{levelId}/GetAllBaseLine';
539
- }
540
- if (modelType === 'unscheduled') {
541
- return 'tasks/{levelId}/unscheduled';
542
- }
543
- if (modelType === 'phaseGate') {
544
- return 'tasks/{levelId}/GetAll?RenderMode=PhaseGate';
545
- }
546
- return 'tasks/{levelId}/GetAll';
728
+ return 'levels/{levelId}/{levelDataId}/schedule/tree?renderMode=PhaseGate';
547
729
  }
548
730
  buildTreeRouteParams(context, treeRouteTemplate) {
549
731
  const levelId = this.readId(context.levelId);
@@ -2208,14 +2390,7 @@ class TaskSchedule {
2208
2390
  operationSub = new Subscription();
2209
2391
  contextAddTask = signal('', ...(ngDevMode ? [{ debugName: "contextAddTask" }] : []));
2210
2392
  customProperties = signal([], ...(ngDevMode ? [{ debugName: "customProperties" }] : []));
2211
- modelType = input('default', ...(ngDevMode ? [{ debugName: "modelType" }] : []));
2212
2393
  context = input(null, ...(ngDevMode ? [{ debugName: "context" }] : []));
2213
- dateFormat = input('dd/MM/yyyy', ...(ngDevMode ? [{ debugName: "dateFormat" }] : []));
2214
- height = input('760px', ...(ngDevMode ? [{ debugName: "height" }] : []));
2215
- langCode = input(null, ...(ngDevMode ? [{ debugName: "langCode" }] : []));
2216
- pdfFontData = input(null, ...(ngDevMode ? [{ debugName: "pdfFontData" }] : []));
2217
- pdfRtlFontData = input(null, ...(ngDevMode ? [{ debugName: "pdfRtlFontData" }] : []));
2218
- pdfFontSize = input(11, ...(ngDevMode ? [{ debugName: "pdfFontSize" }] : []));
2219
2394
  toolbarAction = output();
2220
2395
  actionBegin = output();
2221
2396
  actionCompleted = output();
@@ -2226,8 +2401,11 @@ class TaskSchedule {
2226
2401
  dataSource = signal([], ...(ngDevMode ? [{ debugName: "dataSource" }] : []));
2227
2402
  ganttConfig = signal(createGanttConfig('default', EMPTY_RESULT, 'dd/MM/yyyy', 'en'), ...(ngDevMode ? [{ debugName: "ganttConfig" }] : []));
2228
2403
  ganttId = `mtTaskScheduleGantt-${Math.random().toString(36).slice(2, 10)}`;
2229
- resolvedModelType = computed(() => normalizeTaskScheduleModelType(this.modelType()), ...(ngDevMode ? [{ debugName: "resolvedModelType" }] : []));
2230
- resolvedLangCode = computed(() => resolveTaskScheduleLanguage(this.langCode(), this.context()?.langCode), ...(ngDevMode ? [{ debugName: "resolvedLangCode" }] : []));
2404
+ resolvedModelTypeInput = computed(() => this.context()?.modelType ?? 'default', ...(ngDevMode ? [{ debugName: "resolvedModelTypeInput" }] : []));
2405
+ resolvedDateFormat = computed(() => this.context()?.dateFormat ?? 'dd/MM/yyyy', ...(ngDevMode ? [{ debugName: "resolvedDateFormat" }] : []));
2406
+ resolvedHeight = computed(() => this.context()?.height ?? '760px', ...(ngDevMode ? [{ debugName: "resolvedHeight" }] : []));
2407
+ resolvedModelType = computed(() => normalizeTaskScheduleModelType(this.resolvedModelTypeInput()), ...(ngDevMode ? [{ debugName: "resolvedModelType" }] : []));
2408
+ resolvedLangCode = computed(() => resolveTaskScheduleLanguage(this.context()?.langCode), ...(ngDevMode ? [{ debugName: "resolvedLangCode" }] : []));
2231
2409
  isEditMode = computed(() => this.resolvedModelType() === 'edit', ...(ngDevMode ? [{ debugName: "isEditMode" }] : []));
2232
2410
  editTaskTypes = computed(() => resolveEditTaskTypes(this.resolvedLangCode()), ...(ngDevMode ? [{ debugName: "editTaskTypes" }] : []));
2233
2411
  enableRtl = computed(() => this.resolvedLangCode() === 'ar' ||
@@ -2255,7 +2433,7 @@ class TaskSchedule {
2255
2433
  return;
2256
2434
  }
2257
2435
  const langCode = this.resolvedLangCode();
2258
- this.loadSchedule(this.modelType(), context, this.dateFormat(), langCode);
2436
+ this.loadSchedule(this.resolvedModelTypeInput(), context, this.resolvedDateFormat(), langCode);
2259
2437
  }, { ...(ngDevMode ? { debugName: "loadEffect" } : {}), injector: this.injector });
2260
2438
  const refreshSub = this.queueService.refreshTasks$.subscribe(() => {
2261
2439
  this.reloadSchedule();
@@ -2339,7 +2517,7 @@ class TaskSchedule {
2339
2517
  onActionComplete(args) {
2340
2518
  const context = this.context();
2341
2519
  if (context) {
2342
- this.queueService.reorderColumn(args, this.modelType(), context);
2520
+ this.queueService.reorderColumn(args, this.resolvedModelTypeInput(), context);
2343
2521
  }
2344
2522
  if (this.isEditMode()) {
2345
2523
  if (args?.requestType === 'openEditDialog' ||
@@ -2443,7 +2621,7 @@ class TaskSchedule {
2443
2621
  dependsOn: property.dependsOn,
2444
2622
  };
2445
2623
  if (property.viewType === 'Date') {
2446
- column['format'] = { type: 'date', format: this.dateFormat() };
2624
+ column['format'] = { type: 'date', format: this.resolvedDateFormat() };
2447
2625
  column['type'] = 'date';
2448
2626
  }
2449
2627
  if (property.viewType === 'Lookup') {
@@ -2714,7 +2892,7 @@ class TaskSchedule {
2714
2892
  if (!context) {
2715
2893
  return;
2716
2894
  }
2717
- this.loadSchedule(this.modelType(), context, this.dateFormat(), this.resolvedLangCode());
2895
+ this.loadSchedule(this.resolvedModelTypeInput(), context, this.resolvedDateFormat(), this.resolvedLangCode());
2718
2896
  }
2719
2897
  normalizeTasks(tasks, customProps) {
2720
2898
  return [...tasks]
@@ -3041,15 +3219,10 @@ class TaskSchedule {
3041
3219
  resolvePdfExportFont() {
3042
3220
  const contextFonts = this.context()?.pdfFonts;
3043
3221
  const fontData = (this.enableRtl()
3044
- ? this.pdfRtlFontData() ??
3045
- contextFonts?.arabic ??
3046
- this.pdfFontData() ??
3047
- contextFonts?.regular
3048
- : this.pdfFontData() ??
3049
- contextFonts?.regular ??
3050
- this.pdfRtlFontData() ??
3051
- contextFonts?.arabic) ?? TASK_SCHEDULE_DEFAULT_PDF_FONT;
3052
- return this.createEmbeddedPdfFont(fontData, contextFonts?.size ?? this.pdfFontSize());
3222
+ ? contextFonts?.arabic ?? contextFonts?.regular
3223
+ : contextFonts?.regular ?? contextFonts?.arabic) ??
3224
+ TASK_SCHEDULE_DEFAULT_PDF_FONT;
3225
+ return this.createEmbeddedPdfFont(fontData, contextFonts?.size ?? 11);
3053
3226
  }
3054
3227
  createEmbeddedPdfFont(base64FontData, size) {
3055
3228
  try {
@@ -3186,7 +3359,7 @@ class TaskSchedule {
3186
3359
  }).format(date);
3187
3360
  }
3188
3361
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: TaskSchedule, deps: [], target: i0.ɵɵFactoryTarget.Component });
3189
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: TaskSchedule, isStandalone: true, selector: "mt-task-schedule", inputs: { modelType: { classPropertyName: "modelType", publicName: "modelType", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null }, dateFormat: { classPropertyName: "dateFormat", publicName: "dateFormat", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, langCode: { classPropertyName: "langCode", publicName: "langCode", isSignal: true, isRequired: false, transformFunction: null }, pdfFontData: { classPropertyName: "pdfFontData", publicName: "pdfFontData", isSignal: true, isRequired: false, transformFunction: null }, pdfRtlFontData: { classPropertyName: "pdfRtlFontData", publicName: "pdfRtlFontData", isSignal: true, isRequired: false, transformFunction: null }, pdfFontSize: { classPropertyName: "pdfFontSize", publicName: "pdfFontSize", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { toolbarAction: "toolbarAction", actionBegin: "actionBegin", actionCompleted: "actionCompleted", loaded: "loaded", loadError: "loadError" }, host: { classAttribute: "block" }, providers: [
3362
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: TaskSchedule, isStandalone: true, selector: "mt-task-schedule", inputs: { context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { toolbarAction: "toolbarAction", actionBegin: "actionBegin", actionCompleted: "actionCompleted", loaded: "loaded", loadError: "loadError" }, host: { classAttribute: "block" }, providers: [
3190
3363
  DayMarkersService,
3191
3364
  EditService,
3192
3365
  ExcelExportService,
@@ -3198,7 +3371,7 @@ class TaskSchedule {
3198
3371
  ToolbarService,
3199
3372
  ContextMenuService,
3200
3373
  ResizeService,
3201
- ], 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]=\"height()\"\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]=\"1\"\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 [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]=\"dateFormat()\"\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 {{ formatDateValue(data?.startDate) }}\r\n </div>\r\n <div>\r\n {{ tooltipTranslations().endsOn }}:\r\n {{ formatDateValue(data?.finishDate) }}\r\n </div>\r\n @if (data?.baselineStartDate) {\r\n <div>\r\n {{ tooltipTranslations().plannedStart }}:\r\n {{ formatDateValue(data?.baselineStartDate) }}\r\n </div>\r\n }\r\n @if (data?.baselineEndDate) {\r\n <div>\r\n {{ tooltipTranslations().plannedEnd }}:\r\n {{ formatDateValue(data?.baselineEndDate) }}\r\n </div>\r\n }\r\n <div>{{ tooltipTranslations().progress }}: {{ data?.progress ?? 0 }}</div>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template #taskbarTemplate let-data>\r\n <mt-task-schedule-taskbar-template [data]=\"data\" [langCode]=\"resolvedLangCode()\" />\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.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"] }] });
3374
+ ], 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\"\n [allowResizing]=\"true\"\n [enableRtl]=\"enableRtl()\"\n [locale]=\"locale()\"\n [height]=\"resolvedHeight()\"\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]=\"1\"\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 [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()\"\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 {{ formatDateValue(data?.startDate) }}\r\n </div>\r\n <div>\r\n {{ tooltipTranslations().endsOn }}:\r\n {{ formatDateValue(data?.finishDate) }}\r\n </div>\r\n @if (data?.baselineStartDate) {\r\n <div>\r\n {{ tooltipTranslations().plannedStart }}:\r\n {{ formatDateValue(data?.baselineStartDate) }}\r\n </div>\r\n }\r\n @if (data?.baselineEndDate) {\r\n <div>\r\n {{ tooltipTranslations().plannedEnd }}:\r\n {{ formatDateValue(data?.baselineEndDate) }}\r\n </div>\r\n }\r\n <div>{{ tooltipTranslations().progress }}: {{ data?.progress ?? 0 }}</div>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template #taskbarTemplate let-data>\r\n <mt-task-schedule-taskbar-template [data]=\"data\" [langCode]=\"resolvedLangCode()\" />\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.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"] }] });
3202
3375
  }
3203
3376
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: TaskSchedule, decorators: [{
3204
3377
  type: Component,
@@ -3214,18 +3387,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
3214
3387
  ToolbarService,
3215
3388
  ContextMenuService,
3216
3389
  ResizeService,
3217
- ], 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]=\"height()\"\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]=\"1\"\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 [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]=\"dateFormat()\"\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 {{ formatDateValue(data?.startDate) }}\r\n </div>\r\n <div>\r\n {{ tooltipTranslations().endsOn }}:\r\n {{ formatDateValue(data?.finishDate) }}\r\n </div>\r\n @if (data?.baselineStartDate) {\r\n <div>\r\n {{ tooltipTranslations().plannedStart }}:\r\n {{ formatDateValue(data?.baselineStartDate) }}\r\n </div>\r\n }\r\n @if (data?.baselineEndDate) {\r\n <div>\r\n {{ tooltipTranslations().plannedEnd }}:\r\n {{ formatDateValue(data?.baselineEndDate) }}\r\n </div>\r\n }\r\n <div>{{ tooltipTranslations().progress }}: {{ data?.progress ?? 0 }}</div>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template #taskbarTemplate let-data>\r\n <mt-task-schedule-taskbar-template [data]=\"data\" [langCode]=\"resolvedLangCode()\" />\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"] }]
3390
+ ], 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\"\n [allowResizing]=\"true\"\n [enableRtl]=\"enableRtl()\"\n [locale]=\"locale()\"\n [height]=\"resolvedHeight()\"\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]=\"1\"\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 [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()\"\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 {{ formatDateValue(data?.startDate) }}\r\n </div>\r\n <div>\r\n {{ tooltipTranslations().endsOn }}:\r\n {{ formatDateValue(data?.finishDate) }}\r\n </div>\r\n @if (data?.baselineStartDate) {\r\n <div>\r\n {{ tooltipTranslations().plannedStart }}:\r\n {{ formatDateValue(data?.baselineStartDate) }}\r\n </div>\r\n }\r\n @if (data?.baselineEndDate) {\r\n <div>\r\n {{ tooltipTranslations().plannedEnd }}:\r\n {{ formatDateValue(data?.baselineEndDate) }}\r\n </div>\r\n }\r\n <div>{{ tooltipTranslations().progress }}: {{ data?.progress ?? 0 }}</div>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template #taskbarTemplate let-data>\r\n <mt-task-schedule-taskbar-template [data]=\"data\" [langCode]=\"resolvedLangCode()\" />\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"] }]
3218
3391
  }], propDecorators: { ganttObj: [{
3219
3392
  type: ViewChild,
3220
3393
  args: ['ganttObj']
3221
- }], modelType: [{ type: i0.Input, args: [{ isSignal: true, alias: "modelType", required: false }] }], context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: false }] }], dateFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "dateFormat", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], langCode: [{ type: i0.Input, args: [{ isSignal: true, alias: "langCode", required: false }] }], pdfFontData: [{ type: i0.Input, args: [{ isSignal: true, alias: "pdfFontData", required: false }] }], pdfRtlFontData: [{ type: i0.Input, args: [{ isSignal: true, alias: "pdfRtlFontData", required: false }] }], pdfFontSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pdfFontSize", required: false }] }], toolbarAction: [{ type: i0.Output, args: ["toolbarAction"] }], actionBegin: [{ type: i0.Output, args: ["actionBegin"] }], actionCompleted: [{ type: i0.Output, args: ["actionCompleted"] }], loaded: [{ type: i0.Output, args: ["loaded"] }], loadError: [{ type: i0.Output, args: ["loadError"] }] } });
3394
+ }], context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: false }] }], toolbarAction: [{ type: i0.Output, args: ["toolbarAction"] }], actionBegin: [{ type: i0.Output, args: ["actionBegin"] }], actionCompleted: [{ type: i0.Output, args: ["actionCompleted"] }], loaded: [{ type: i0.Output, args: ["loaded"] }], loadError: [{ type: i0.Output, args: ["loadError"] }] } });
3222
3395
 
3223
3396
  class TaskScheduleImportModal {
3224
3397
  adapter = inject(TASK_SCHEDULE_DATA_ADAPTER, { optional: true }) ??
3225
3398
  inject(TaskScheduleBackendAdapter);
3226
3399
  visible = input(true, ...(ngDevMode ? [{ debugName: "visible" }] : []));
3227
3400
  context = input(null, ...(ngDevMode ? [{ debugName: "context" }] : []));
3228
- langCode = input(null, ...(ngDevMode ? [{ debugName: "langCode" }] : []));
3229
3401
  title = input(null, ...(ngDevMode ? [{ debugName: "title" }] : []));
3230
3402
  maxRows = input(400, ...(ngDevMode ? [{ debugName: "maxRows" }] : []));
3231
3403
  closed = output();
@@ -3237,7 +3409,7 @@ class TaskScheduleImportModal {
3237
3409
  loadingApply = signal(false, ...(ngDevMode ? [{ debugName: "loadingApply" }] : []));
3238
3410
  importResult = signal(null, ...(ngDevMode ? [{ debugName: "importResult" }] : []));
3239
3411
  selectedTaskKeys = signal(new Set(), ...(ngDevMode ? [{ debugName: "selectedTaskKeys" }] : []));
3240
- resolvedLangCode = computed(() => resolveTaskScheduleLanguage(this.langCode(), this.context()?.langCode), ...(ngDevMode ? [{ debugName: "resolvedLangCode" }] : []));
3412
+ resolvedLangCode = computed(() => resolveTaskScheduleLanguage(this.context()?.langCode), ...(ngDevMode ? [{ debugName: "resolvedLangCode" }] : []));
3241
3413
  isRtl = computed(() => this.resolvedLangCode() === 'ar', ...(ngDevMode ? [{ debugName: "isRtl" }] : []));
3242
3414
  labels = computed(() => this.resolvedLangCode() === 'ar'
3243
3415
  ? {
@@ -3802,12 +3974,12 @@ class TaskScheduleImportModal {
3802
3974
  this.failed.emit(message);
3803
3975
  }
3804
3976
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: TaskScheduleImportModal, deps: [], target: i0.ɵɵFactoryTarget.Component });
3805
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: TaskScheduleImportModal, isStandalone: true, selector: "mt-task-schedule-import-modal", inputs: { visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null }, langCode: { classPropertyName: "langCode", publicName: "langCode", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, maxRows: { classPropertyName: "maxRows", publicName: "maxRows", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed", imported: "imported", applied: "applied", failed: "failed" }, ngImport: i0, template: "@if (visible()) {\r\n <div class=\"fixed inset-0 z-[1000] grid place-items-center bg-slate-900/40 p-4\">\r\n <section\r\n class=\"w-full max-w-6xl overflow-hidden rounded-2xl bg-white shadow-2xl ring-1 ring-slate-200\"\r\n [attr.dir]=\"isRtl() ? 'rtl' : 'ltr'\"\r\n >\r\n <header class=\"flex items-center justify-between border-b border-slate-200 px-5 py-4\">\r\n <h2 class=\"text-base font-semibold text-slate-900\">\r\n {{ title() || labels().title }}\r\n </h2>\r\n\r\n <mt-button\r\n [label]=\"labels().cancel\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n (onClick)=\"close()\"\r\n />\r\n </header>\r\n\r\n <div class=\"space-y-4 p-5\">\r\n <div class=\"rounded-xl border border-slate-200 bg-slate-50 p-4\">\r\n <div class=\"flex flex-wrap items-center gap-3\">\r\n <label\r\n class=\"inline-flex cursor-pointer items-center rounded-lg border border-dashed border-slate-300 bg-white px-4 py-2 text-sm text-slate-700 hover:border-slate-400\"\r\n >\r\n <span>{{ labels().selectFile }}</span>\r\n <input\r\n class=\"hidden\"\r\n type=\"file\"\r\n accept=\".mpp,.xer\"\r\n (change)=\"onFileChanged($event)\"\r\n />\r\n </label>\r\n\r\n <span class=\"max-w-[22rem] truncate text-sm text-slate-500\">\r\n {{ selectedFile()?.name || '-' }}\r\n </span>\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 (importResult(); as result) {\r\n @if (!previewRows().length) {\r\n <div class=\"rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-800\">\r\n {{ labels().noTasks }}\r\n </div>\r\n } @else {\r\n <div class=\"overflow-hidden rounded-xl border border-slate-200\">\r\n <div class=\"grid min-w-[1180px] grid-cols-[40px_minmax(220px,2fr)_minmax(130px,1fr)_minmax(130px,1fr)_minmax(130px,1fr)_minmax(130px,1fr)_minmax(190px,1.1fr)_minmax(120px,0.8fr)] border-b border-slate-200 bg-slate-100 px-3 py-2 text-xs font-semibold uppercase tracking-wide text-slate-600\">\r\n <label class=\"inline-flex items-center justify-center\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"allSelected()\"\r\n (change)=\"selectAllRows($any($event.target).checked)\"\r\n />\r\n </label>\r\n <div>{{ labels().task }}</div>\r\n <div>{{ labels().startDate }}</div>\r\n <div>{{ labels().finishDate }}</div>\r\n <div>{{ labels().actualStartDate }}</div>\r\n <div>{{ labels().actualFinishDate }}</div>\r\n <div>{{ labels().assignedTo }}</div>\r\n <div>{{ labels().progress }}</div>\r\n </div>\r\n\r\n <div class=\"max-h-[28rem] overflow-auto\">\r\n @for (row of previewRows(); track trackByRow($index, row)) {\r\n <div class=\"grid min-w-[1180px] grid-cols-[40px_minmax(220px,2fr)_minmax(130px,1fr)_minmax(130px,1fr)_minmax(130px,1fr)_minmax(130px,1fr)_minmax(190px,1.1fr)_minmax(120px,0.8fr)] items-center gap-x-2 border-b border-slate-100 px-3 py-2 text-sm\">\r\n <label class=\"inline-flex items-center justify-center\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"selectedTaskKeys().has(row.key)\"\r\n (change)=\"toggleRowSelection(row.key, $any($event.target).checked)\"\r\n />\r\n </label>\r\n\r\n <div class=\"min-w-0\" [style.paddingInlineStart.px]=\"row.depth * 18\">\r\n <input\r\n class=\"w-full rounded-md border border-slate-300 px-2 py-1 text-sm text-slate-700 outline-none focus:border-slate-400\"\r\n type=\"text\"\r\n [value]=\"row.task.title || row.task.name || ''\"\r\n (input)=\"onTaskTitleChanged(row.key, $any($event.target).value)\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <input\r\n class=\"w-full rounded-md border border-slate-300 px-2 py-1 text-sm text-slate-700 outline-none focus:border-slate-400\"\r\n type=\"date\"\r\n [value]=\"toDateInputValue(row.task.startDate)\"\r\n (change)=\"onTaskDateChanged(row.key, 'startDate', $any($event.target).value)\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <input\r\n class=\"w-full rounded-md border border-slate-300 px-2 py-1 text-sm text-slate-700 outline-none focus:border-slate-400\"\r\n type=\"date\"\r\n [value]=\"toDateInputValue(row.task.finishDate)\"\r\n (change)=\"onTaskDateChanged(row.key, 'finishDate', $any($event.target).value)\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <input\r\n class=\"w-full rounded-md border border-slate-300 px-2 py-1 text-sm text-slate-700 outline-none focus:border-slate-400\"\r\n type=\"date\"\r\n [value]=\"toDateInputValue(row.task.actualStartDate || row.task.actualStart)\"\r\n (change)=\"onTaskDateChanged(row.key, 'actualStartDate', $any($event.target).value)\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <input\r\n class=\"w-full rounded-md border border-slate-300 px-2 py-1 text-sm text-slate-700 outline-none focus:border-slate-400\"\r\n type=\"date\"\r\n [value]=\"toDateInputValue(row.task.actualFinishDate || row.task.actualFinish)\"\r\n (change)=\"onTaskDateChanged(row.key, 'actualFinishDate', $any($event.target).value)\"\r\n />\r\n </div>\r\n\r\n <div class=\"min-w-0\">\r\n @if (resourceOptions().length) {\r\n <div class=\"space-y-1\">\r\n <select\r\n class=\"w-full rounded-md border border-slate-300 px-2 py-1 text-sm text-slate-700 outline-none focus:border-slate-400\"\r\n [value]=\"resolveAssignedValue(row.task)\"\r\n (change)=\"onTaskAssignedToChanged(row.key, $any($event.target).value)\"\r\n >\r\n <option value=\"\">-</option>\r\n @for (option of resourceOptions(); track option.id) {\r\n <option [value]=\"option.id\">{{ option.label }}</option>\r\n }\r\n </select>\r\n @if (row.task.assignedTo) {\r\n <mt-entity-preview [data]=\"toAssignedEntity(row.task)\" />\r\n }\r\n </div>\r\n } @else if (row.task.assignedTo) {\r\n <mt-entity-preview [data]=\"toAssignedEntity(row.task)\" />\r\n } @else {\r\n <span class=\"text-slate-400\">-</span>\r\n }\r\n </div>\r\n\r\n <div>\r\n <div class=\"space-y-1\">\r\n <input\r\n class=\"w-full rounded-md border border-slate-300 px-2 py-1 text-sm text-slate-700 outline-none focus:border-slate-400\"\r\n type=\"number\"\r\n min=\"0\"\r\n max=\"100\"\r\n [value]=\"normalizeProgress(row.task.progress)\"\r\n (input)=\"onTaskProgressChanged(row.key, $any($event.target).value)\"\r\n />\r\n <mt-entity-preview [data]=\"toProgressEntity(row.task)\" />\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n @if (isTruncated()) {\r\n <p class=\"text-xs text-slate-500\">{{ labels().rowsLimited }}</p>\r\n }\r\n }\r\n }\r\n </div>\r\n\r\n <footer class=\"flex flex-wrap items-center justify-end gap-2 border-t border-slate-200 px-5 py-4\">\r\n <mt-button\r\n [label]=\"labels().cancel\"\r\n severity=\"secondary\"\r\n [outlined]=\"true\"\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 </footer>\r\n </section>\r\n </div>\r\n}\r\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: EntityPreview, selector: "mt-entity-preview", inputs: ["data"] }] });
3977
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: TaskScheduleImportModal, isStandalone: true, selector: "mt-task-schedule-import-modal", inputs: { visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, maxRows: { classPropertyName: "maxRows", publicName: "maxRows", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed", imported: "imported", applied: "applied", failed: "failed" }, ngImport: i0, template: "@if (visible()) {\r\n <div class=\"fixed inset-0 z-[1000] grid place-items-center bg-slate-900/40 p-4\">\r\n <section\r\n class=\"w-full max-w-6xl overflow-hidden rounded-2xl bg-white shadow-2xl ring-1 ring-slate-200\"\r\n [attr.dir]=\"isRtl() ? 'rtl' : 'ltr'\"\r\n >\r\n <header class=\"flex items-center justify-between border-b border-slate-200 px-5 py-4\">\r\n <h2 class=\"text-base font-semibold text-slate-900\">\r\n {{ title() || labels().title }}\r\n </h2>\r\n\r\n <mt-button\r\n [label]=\"labels().cancel\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n (onClick)=\"close()\"\r\n />\r\n </header>\r\n\r\n <div class=\"space-y-4 p-5\">\r\n <div class=\"rounded-xl border border-slate-200 bg-slate-50 p-4\">\r\n <div class=\"flex flex-wrap items-center gap-3\">\r\n <label\r\n class=\"inline-flex cursor-pointer items-center rounded-lg border border-dashed border-slate-300 bg-white px-4 py-2 text-sm text-slate-700 hover:border-slate-400\"\r\n >\r\n <span>{{ labels().selectFile }}</span>\r\n <input\r\n class=\"hidden\"\r\n type=\"file\"\r\n accept=\".mpp,.xer\"\r\n (change)=\"onFileChanged($event)\"\r\n />\r\n </label>\r\n\r\n <span class=\"max-w-[22rem] truncate text-sm text-slate-500\">\r\n {{ selectedFile()?.name || '-' }}\r\n </span>\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 (importResult(); as result) {\r\n @if (!previewRows().length) {\r\n <div class=\"rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-800\">\r\n {{ labels().noTasks }}\r\n </div>\r\n } @else {\r\n <div class=\"overflow-hidden rounded-xl border border-slate-200\">\r\n <div class=\"grid min-w-[1180px] grid-cols-[40px_minmax(220px,2fr)_minmax(130px,1fr)_minmax(130px,1fr)_minmax(130px,1fr)_minmax(130px,1fr)_minmax(190px,1.1fr)_minmax(120px,0.8fr)] border-b border-slate-200 bg-slate-100 px-3 py-2 text-xs font-semibold uppercase tracking-wide text-slate-600\">\r\n <label class=\"inline-flex items-center justify-center\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"allSelected()\"\r\n (change)=\"selectAllRows($any($event.target).checked)\"\r\n />\r\n </label>\r\n <div>{{ labels().task }}</div>\r\n <div>{{ labels().startDate }}</div>\r\n <div>{{ labels().finishDate }}</div>\r\n <div>{{ labels().actualStartDate }}</div>\r\n <div>{{ labels().actualFinishDate }}</div>\r\n <div>{{ labels().assignedTo }}</div>\r\n <div>{{ labels().progress }}</div>\r\n </div>\r\n\r\n <div class=\"max-h-[28rem] overflow-auto\">\r\n @for (row of previewRows(); track trackByRow($index, row)) {\r\n <div class=\"grid min-w-[1180px] grid-cols-[40px_minmax(220px,2fr)_minmax(130px,1fr)_minmax(130px,1fr)_minmax(130px,1fr)_minmax(130px,1fr)_minmax(190px,1.1fr)_minmax(120px,0.8fr)] items-center gap-x-2 border-b border-slate-100 px-3 py-2 text-sm\">\r\n <label class=\"inline-flex items-center justify-center\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"selectedTaskKeys().has(row.key)\"\r\n (change)=\"toggleRowSelection(row.key, $any($event.target).checked)\"\r\n />\r\n </label>\r\n\r\n <div class=\"min-w-0\" [style.paddingInlineStart.px]=\"row.depth * 18\">\r\n <input\r\n class=\"w-full rounded-md border border-slate-300 px-2 py-1 text-sm text-slate-700 outline-none focus:border-slate-400\"\r\n type=\"text\"\r\n [value]=\"row.task.title || row.task.name || ''\"\r\n (input)=\"onTaskTitleChanged(row.key, $any($event.target).value)\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <input\r\n class=\"w-full rounded-md border border-slate-300 px-2 py-1 text-sm text-slate-700 outline-none focus:border-slate-400\"\r\n type=\"date\"\r\n [value]=\"toDateInputValue(row.task.startDate)\"\r\n (change)=\"onTaskDateChanged(row.key, 'startDate', $any($event.target).value)\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <input\r\n class=\"w-full rounded-md border border-slate-300 px-2 py-1 text-sm text-slate-700 outline-none focus:border-slate-400\"\r\n type=\"date\"\r\n [value]=\"toDateInputValue(row.task.finishDate)\"\r\n (change)=\"onTaskDateChanged(row.key, 'finishDate', $any($event.target).value)\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <input\r\n class=\"w-full rounded-md border border-slate-300 px-2 py-1 text-sm text-slate-700 outline-none focus:border-slate-400\"\r\n type=\"date\"\r\n [value]=\"toDateInputValue(row.task.actualStartDate || row.task.actualStart)\"\r\n (change)=\"onTaskDateChanged(row.key, 'actualStartDate', $any($event.target).value)\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <input\r\n class=\"w-full rounded-md border border-slate-300 px-2 py-1 text-sm text-slate-700 outline-none focus:border-slate-400\"\r\n type=\"date\"\r\n [value]=\"toDateInputValue(row.task.actualFinishDate || row.task.actualFinish)\"\r\n (change)=\"onTaskDateChanged(row.key, 'actualFinishDate', $any($event.target).value)\"\r\n />\r\n </div>\r\n\r\n <div class=\"min-w-0\">\r\n @if (resourceOptions().length) {\r\n <div class=\"space-y-1\">\r\n <select\r\n class=\"w-full rounded-md border border-slate-300 px-2 py-1 text-sm text-slate-700 outline-none focus:border-slate-400\"\r\n [value]=\"resolveAssignedValue(row.task)\"\r\n (change)=\"onTaskAssignedToChanged(row.key, $any($event.target).value)\"\r\n >\r\n <option value=\"\">-</option>\r\n @for (option of resourceOptions(); track option.id) {\r\n <option [value]=\"option.id\">{{ option.label }}</option>\r\n }\r\n </select>\r\n @if (row.task.assignedTo) {\r\n <mt-entity-preview [data]=\"toAssignedEntity(row.task)\" />\r\n }\r\n </div>\r\n } @else if (row.task.assignedTo) {\r\n <mt-entity-preview [data]=\"toAssignedEntity(row.task)\" />\r\n } @else {\r\n <span class=\"text-slate-400\">-</span>\r\n }\r\n </div>\r\n\r\n <div>\r\n <div class=\"space-y-1\">\r\n <input\r\n class=\"w-full rounded-md border border-slate-300 px-2 py-1 text-sm text-slate-700 outline-none focus:border-slate-400\"\r\n type=\"number\"\r\n min=\"0\"\r\n max=\"100\"\r\n [value]=\"normalizeProgress(row.task.progress)\"\r\n (input)=\"onTaskProgressChanged(row.key, $any($event.target).value)\"\r\n />\r\n <mt-entity-preview [data]=\"toProgressEntity(row.task)\" />\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n @if (isTruncated()) {\r\n <p class=\"text-xs text-slate-500\">{{ labels().rowsLimited }}</p>\r\n }\r\n }\r\n }\r\n </div>\r\n\r\n <footer class=\"flex flex-wrap items-center justify-end gap-2 border-t border-slate-200 px-5 py-4\">\r\n <mt-button\r\n [label]=\"labels().cancel\"\r\n severity=\"secondary\"\r\n [outlined]=\"true\"\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 </footer>\r\n </section>\r\n </div>\r\n}\r\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: EntityPreview, selector: "mt-entity-preview", inputs: ["data"] }] });
3806
3978
  }
3807
3979
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: TaskScheduleImportModal, decorators: [{
3808
3980
  type: Component,
3809
3981
  args: [{ selector: 'mt-task-schedule-import-modal', standalone: true, imports: [CommonModule, Button, EntityPreview], template: "@if (visible()) {\r\n <div class=\"fixed inset-0 z-[1000] grid place-items-center bg-slate-900/40 p-4\">\r\n <section\r\n class=\"w-full max-w-6xl overflow-hidden rounded-2xl bg-white shadow-2xl ring-1 ring-slate-200\"\r\n [attr.dir]=\"isRtl() ? 'rtl' : 'ltr'\"\r\n >\r\n <header class=\"flex items-center justify-between border-b border-slate-200 px-5 py-4\">\r\n <h2 class=\"text-base font-semibold text-slate-900\">\r\n {{ title() || labels().title }}\r\n </h2>\r\n\r\n <mt-button\r\n [label]=\"labels().cancel\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n (onClick)=\"close()\"\r\n />\r\n </header>\r\n\r\n <div class=\"space-y-4 p-5\">\r\n <div class=\"rounded-xl border border-slate-200 bg-slate-50 p-4\">\r\n <div class=\"flex flex-wrap items-center gap-3\">\r\n <label\r\n class=\"inline-flex cursor-pointer items-center rounded-lg border border-dashed border-slate-300 bg-white px-4 py-2 text-sm text-slate-700 hover:border-slate-400\"\r\n >\r\n <span>{{ labels().selectFile }}</span>\r\n <input\r\n class=\"hidden\"\r\n type=\"file\"\r\n accept=\".mpp,.xer\"\r\n (change)=\"onFileChanged($event)\"\r\n />\r\n </label>\r\n\r\n <span class=\"max-w-[22rem] truncate text-sm text-slate-500\">\r\n {{ selectedFile()?.name || '-' }}\r\n </span>\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 (importResult(); as result) {\r\n @if (!previewRows().length) {\r\n <div class=\"rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-800\">\r\n {{ labels().noTasks }}\r\n </div>\r\n } @else {\r\n <div class=\"overflow-hidden rounded-xl border border-slate-200\">\r\n <div class=\"grid min-w-[1180px] grid-cols-[40px_minmax(220px,2fr)_minmax(130px,1fr)_minmax(130px,1fr)_minmax(130px,1fr)_minmax(130px,1fr)_minmax(190px,1.1fr)_minmax(120px,0.8fr)] border-b border-slate-200 bg-slate-100 px-3 py-2 text-xs font-semibold uppercase tracking-wide text-slate-600\">\r\n <label class=\"inline-flex items-center justify-center\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"allSelected()\"\r\n (change)=\"selectAllRows($any($event.target).checked)\"\r\n />\r\n </label>\r\n <div>{{ labels().task }}</div>\r\n <div>{{ labels().startDate }}</div>\r\n <div>{{ labels().finishDate }}</div>\r\n <div>{{ labels().actualStartDate }}</div>\r\n <div>{{ labels().actualFinishDate }}</div>\r\n <div>{{ labels().assignedTo }}</div>\r\n <div>{{ labels().progress }}</div>\r\n </div>\r\n\r\n <div class=\"max-h-[28rem] overflow-auto\">\r\n @for (row of previewRows(); track trackByRow($index, row)) {\r\n <div class=\"grid min-w-[1180px] grid-cols-[40px_minmax(220px,2fr)_minmax(130px,1fr)_minmax(130px,1fr)_minmax(130px,1fr)_minmax(130px,1fr)_minmax(190px,1.1fr)_minmax(120px,0.8fr)] items-center gap-x-2 border-b border-slate-100 px-3 py-2 text-sm\">\r\n <label class=\"inline-flex items-center justify-center\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"selectedTaskKeys().has(row.key)\"\r\n (change)=\"toggleRowSelection(row.key, $any($event.target).checked)\"\r\n />\r\n </label>\r\n\r\n <div class=\"min-w-0\" [style.paddingInlineStart.px]=\"row.depth * 18\">\r\n <input\r\n class=\"w-full rounded-md border border-slate-300 px-2 py-1 text-sm text-slate-700 outline-none focus:border-slate-400\"\r\n type=\"text\"\r\n [value]=\"row.task.title || row.task.name || ''\"\r\n (input)=\"onTaskTitleChanged(row.key, $any($event.target).value)\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <input\r\n class=\"w-full rounded-md border border-slate-300 px-2 py-1 text-sm text-slate-700 outline-none focus:border-slate-400\"\r\n type=\"date\"\r\n [value]=\"toDateInputValue(row.task.startDate)\"\r\n (change)=\"onTaskDateChanged(row.key, 'startDate', $any($event.target).value)\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <input\r\n class=\"w-full rounded-md border border-slate-300 px-2 py-1 text-sm text-slate-700 outline-none focus:border-slate-400\"\r\n type=\"date\"\r\n [value]=\"toDateInputValue(row.task.finishDate)\"\r\n (change)=\"onTaskDateChanged(row.key, 'finishDate', $any($event.target).value)\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <input\r\n class=\"w-full rounded-md border border-slate-300 px-2 py-1 text-sm text-slate-700 outline-none focus:border-slate-400\"\r\n type=\"date\"\r\n [value]=\"toDateInputValue(row.task.actualStartDate || row.task.actualStart)\"\r\n (change)=\"onTaskDateChanged(row.key, 'actualStartDate', $any($event.target).value)\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <input\r\n class=\"w-full rounded-md border border-slate-300 px-2 py-1 text-sm text-slate-700 outline-none focus:border-slate-400\"\r\n type=\"date\"\r\n [value]=\"toDateInputValue(row.task.actualFinishDate || row.task.actualFinish)\"\r\n (change)=\"onTaskDateChanged(row.key, 'actualFinishDate', $any($event.target).value)\"\r\n />\r\n </div>\r\n\r\n <div class=\"min-w-0\">\r\n @if (resourceOptions().length) {\r\n <div class=\"space-y-1\">\r\n <select\r\n class=\"w-full rounded-md border border-slate-300 px-2 py-1 text-sm text-slate-700 outline-none focus:border-slate-400\"\r\n [value]=\"resolveAssignedValue(row.task)\"\r\n (change)=\"onTaskAssignedToChanged(row.key, $any($event.target).value)\"\r\n >\r\n <option value=\"\">-</option>\r\n @for (option of resourceOptions(); track option.id) {\r\n <option [value]=\"option.id\">{{ option.label }}</option>\r\n }\r\n </select>\r\n @if (row.task.assignedTo) {\r\n <mt-entity-preview [data]=\"toAssignedEntity(row.task)\" />\r\n }\r\n </div>\r\n } @else if (row.task.assignedTo) {\r\n <mt-entity-preview [data]=\"toAssignedEntity(row.task)\" />\r\n } @else {\r\n <span class=\"text-slate-400\">-</span>\r\n }\r\n </div>\r\n\r\n <div>\r\n <div class=\"space-y-1\">\r\n <input\r\n class=\"w-full rounded-md border border-slate-300 px-2 py-1 text-sm text-slate-700 outline-none focus:border-slate-400\"\r\n type=\"number\"\r\n min=\"0\"\r\n max=\"100\"\r\n [value]=\"normalizeProgress(row.task.progress)\"\r\n (input)=\"onTaskProgressChanged(row.key, $any($event.target).value)\"\r\n />\r\n <mt-entity-preview [data]=\"toProgressEntity(row.task)\" />\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n @if (isTruncated()) {\r\n <p class=\"text-xs text-slate-500\">{{ labels().rowsLimited }}</p>\r\n }\r\n }\r\n }\r\n </div>\r\n\r\n <footer class=\"flex flex-wrap items-center justify-end gap-2 border-t border-slate-200 px-5 py-4\">\r\n <mt-button\r\n [label]=\"labels().cancel\"\r\n severity=\"secondary\"\r\n [outlined]=\"true\"\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 </footer>\r\n </section>\r\n </div>\r\n}\r\n", styles: [":host{display:block}\n"] }]
3810
- }], propDecorators: { visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }], context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: false }] }], langCode: [{ type: i0.Input, args: [{ isSignal: true, alias: "langCode", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], maxRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxRows", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }], imported: [{ type: i0.Output, args: ["imported"] }], applied: [{ type: i0.Output, args: ["applied"] }], failed: [{ type: i0.Output, args: ["failed"] }] } });
3982
+ }], propDecorators: { visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }], context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], maxRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxRows", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }], imported: [{ type: i0.Output, args: ["imported"] }], applied: [{ type: i0.Output, args: ["applied"] }], failed: [{ type: i0.Output, args: ["failed"] }] } });
3811
3983
 
3812
3984
  const DEFAULT_MODES = [
3813
3985
  { value: 'default' },
@@ -3823,16 +3995,6 @@ class TaskScheduleShell {
3823
3995
  inject(TaskScheduleBackendAdapter);
3824
3996
  queueService = inject(TaskScheduleQueueService);
3825
3997
  context = input(null, ...(ngDevMode ? [{ debugName: "context" }] : []));
3826
- langCode = input(null, ...(ngDevMode ? [{ debugName: "langCode" }] : []));
3827
- dateFormat = input('dd/MM/yyyy', ...(ngDevMode ? [{ debugName: "dateFormat" }] : []));
3828
- height = input('760px', ...(ngDevMode ? [{ debugName: "height" }] : []));
3829
- modelType = input('default', ...(ngDevMode ? [{ debugName: "modelType" }] : []));
3830
- modeOptions = input(null, ...(ngDevMode ? [{ debugName: "modeOptions" }] : []));
3831
- allowEditMode = input(true, ...(ngDevMode ? [{ debugName: "allowEditMode" }] : []));
3832
- allowImport = input(true, ...(ngDevMode ? [{ debugName: "allowImport" }] : []));
3833
- allowSetBaseline = input(true, ...(ngDevMode ? [{ debugName: "allowSetBaseline" }] : []));
3834
- hasTasks = input(true, ...(ngDevMode ? [{ debugName: "hasTasks" }] : []));
3835
- baselinePending = input(false, ...(ngDevMode ? [{ debugName: "baselinePending" }] : []));
3836
3998
  modeChanged = output();
3837
3999
  baselineSet = output();
3838
4000
  tasksExported = output();
@@ -3841,7 +4003,17 @@ class TaskScheduleShell {
3841
4003
  showImportModal = signal(false, ...(ngDevMode ? [{ debugName: "showImportModal" }] : []));
3842
4004
  settingBaseline = signal(false, ...(ngDevMode ? [{ debugName: "settingBaseline" }] : []));
3843
4005
  exportingTasks = signal(false, ...(ngDevMode ? [{ debugName: "exportingTasks" }] : []));
3844
- resolvedLangCode = computed(() => resolveTaskScheduleLanguage(this.langCode(), this.context()?.langCode), ...(ngDevMode ? [{ debugName: "resolvedLangCode" }] : []));
4006
+ resolvedLangCode = computed(() => resolveTaskScheduleLanguage(this.context()?.langCode), ...(ngDevMode ? [{ debugName: "resolvedLangCode" }] : []));
4007
+ resolvedContext = computed(() => {
4008
+ const context = this.context();
4009
+ if (!context) {
4010
+ return null;
4011
+ }
4012
+ return {
4013
+ ...context,
4014
+ modelType: this.currentModelType(),
4015
+ };
4016
+ }, ...(ngDevMode ? [{ debugName: "resolvedContext" }] : []));
3845
4017
  labels = computed(() => this.resolvedLangCode() === 'ar'
3846
4018
  ? {
3847
4019
  mode: 'الوضع',
@@ -3869,29 +4041,30 @@ class TaskScheduleShell {
3869
4041
  }, ...(ngDevMode ? [{ debugName: "labels" }] : []));
3870
4042
  currentModelKey = computed(() => normalizeTaskScheduleModelType(this.currentModelType()), ...(ngDevMode ? [{ debugName: "currentModelKey" }] : []));
3871
4043
  resolvedModes = computed(() => {
3872
- const modes = this.modeOptions();
4044
+ const modes = this.context()?.modeOptions;
3873
4045
  const source = modes?.length ? modes : DEFAULT_MODES;
3874
4046
  return source
3875
- .filter((item) => this.allowEditMode() || normalizeTaskScheduleModelType(item.value) !== 'edit')
4047
+ .filter((item) => (this.context()?.allowEditMode ?? true) ||
4048
+ normalizeTaskScheduleModelType(item.value) !== 'edit')
3876
4049
  .map((item) => ({
3877
4050
  value: item.value,
3878
4051
  label: item.label || this.resolveModeLabel(item.value),
3879
4052
  }));
3880
4053
  }, ...(ngDevMode ? [{ debugName: "resolvedModes" }] : []));
3881
- showSetBaselineAction = computed(() => this.allowSetBaseline() &&
4054
+ showSetBaselineAction = computed(() => (this.context()?.allowSetBaseline ?? true) &&
3882
4055
  (this.currentModelKey() === 'default' || this.currentModelKey() === 'edit'), ...(ngDevMode ? [{ debugName: "showSetBaselineAction" }] : []));
3883
4056
  canSetBaselineAction = computed(() => this.showSetBaselineAction() &&
3884
4057
  !!this.context() &&
3885
4058
  !!this.adapter.setBaseline &&
3886
4059
  !this.settingBaseline() &&
3887
- !this.baselinePending() &&
3888
- this.hasTasks(), ...(ngDevMode ? [{ debugName: "canSetBaselineAction" }] : []));
3889
- showImportAction = computed(() => this.allowImport() && this.currentModelKey() === 'edit', ...(ngDevMode ? [{ debugName: "showImportAction" }] : []));
4060
+ !(this.context()?.baselinePending ?? false) &&
4061
+ (this.context()?.hasTasks ?? true), ...(ngDevMode ? [{ debugName: "canSetBaselineAction" }] : []));
4062
+ showImportAction = computed(() => (this.context()?.allowImport ?? true) && this.currentModelKey() === 'edit', ...(ngDevMode ? [{ debugName: "showImportAction" }] : []));
3890
4063
  canOpenImport = computed(() => this.showImportAction() && !!this.context(), ...(ngDevMode ? [{ debugName: "canOpenImport" }] : []));
3891
4064
  canExportTasks = computed(() => !!this.context() && !!this.adapter.exportTasks && !this.exportingTasks(), ...(ngDevMode ? [{ debugName: "canExportTasks" }] : []));
3892
4065
  constructor() {
3893
4066
  effect(() => {
3894
- this.currentModelType.set(this.modelType());
4067
+ this.currentModelType.set(this.context()?.modelType ?? 'default');
3895
4068
  });
3896
4069
  }
3897
4070
  onModeChange(nextValue) {
@@ -4018,12 +4191,12 @@ class TaskScheduleShell {
4018
4191
  this.actionError.emit(message);
4019
4192
  }
4020
4193
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: TaskScheduleShell, deps: [], target: i0.ɵɵFactoryTarget.Component });
4021
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: TaskScheduleShell, isStandalone: true, selector: "mt-task-schedule-shell", inputs: { context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null }, langCode: { classPropertyName: "langCode", publicName: "langCode", isSignal: true, isRequired: false, transformFunction: null }, dateFormat: { classPropertyName: "dateFormat", publicName: "dateFormat", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, modelType: { classPropertyName: "modelType", publicName: "modelType", isSignal: true, isRequired: false, transformFunction: null }, modeOptions: { classPropertyName: "modeOptions", publicName: "modeOptions", isSignal: true, isRequired: false, transformFunction: null }, allowEditMode: { classPropertyName: "allowEditMode", publicName: "allowEditMode", isSignal: true, isRequired: false, transformFunction: null }, allowImport: { classPropertyName: "allowImport", publicName: "allowImport", isSignal: true, isRequired: false, transformFunction: null }, allowSetBaseline: { classPropertyName: "allowSetBaseline", publicName: "allowSetBaseline", isSignal: true, isRequired: false, transformFunction: null }, hasTasks: { classPropertyName: "hasTasks", publicName: "hasTasks", isSignal: true, isRequired: false, transformFunction: null }, baselinePending: { classPropertyName: "baselinePending", publicName: "baselinePending", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { modeChanged: "modeChanged", baselineSet: "baselineSet", tasksExported: "tasksExported", actionError: "actionError" }, ngImport: i0, template: "<div class=\"task-schedule-shell\" [attr.dir]=\"resolvedLangCode() === 'ar' ? 'rtl' : 'ltr'\">\r\n <header class=\"task-schedule-shell__header\">\r\n <div class=\"task-schedule-shell__mode\">\r\n <label class=\"task-schedule-shell__label\">{{ labels().mode }}</label>\r\n <select\r\n class=\"task-schedule-shell__select\"\r\n [value]=\"currentModelType()\"\r\n (change)=\"onModeChange($any($event.target).value)\"\r\n >\r\n @for (mode of resolvedModes(); track mode.value) {\r\n <option [value]=\"mode.value\">{{ mode.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n\r\n <div class=\"task-schedule-shell__actions\">\r\n @if (showSetBaselineAction()) {\r\n <button\r\n type=\"button\"\r\n class=\"task-schedule-shell__btn\"\r\n [disabled]=\"!canSetBaselineAction()\"\r\n (click)=\"setBaseline()\"\r\n >\r\n {{ baselinePending() ? labels().pending : labels().setBaseline }}\r\n </button>\r\n }\r\n\r\n @if (showImportAction()) {\r\n <button\r\n type=\"button\"\r\n class=\"task-schedule-shell__btn\"\r\n [disabled]=\"!canOpenImport()\"\r\n (click)=\"openImportModal()\"\r\n >\r\n {{ labels().import }}\r\n </button>\r\n }\r\n\r\n <button\r\n type=\"button\"\r\n class=\"task-schedule-shell__btn\"\r\n [disabled]=\"!canExportTasks()\"\r\n (click)=\"exportTasks()\"\r\n >\r\n {{ labels().export }}\r\n </button>\r\n </div>\r\n </header>\r\n\r\n <mt-task-schedule\r\n [modelType]=\"currentModelType()\"\r\n [context]=\"context()\"\r\n [langCode]=\"resolvedLangCode()\"\r\n [dateFormat]=\"dateFormat()\"\r\n [height]=\"height()\"\r\n (loadError)=\"onActionError($event)\"\r\n />\r\n\r\n @if (showImportModal()) {\r\n <mt-task-schedule-import-modal\r\n [visible]=\"showImportModal()\"\r\n [context]=\"context()\"\r\n [langCode]=\"resolvedLangCode()\"\r\n (closed)=\"closeImportModal()\"\r\n (failed)=\"onActionError($event)\"\r\n (applied)=\"onImportedTasksApplied()\"\r\n />\r\n }\r\n</div>\r\n", styles: [":host{display:block}.task-schedule-shell{display:flex;flex-direction:column;gap:12px}.task-schedule-shell__header{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:10px}.task-schedule-shell__mode{display:flex;align-items:center;gap:8px}.task-schedule-shell__label{color:#334155;font-size:13px;font-weight:600}.task-schedule-shell__select{border:1px solid #cbd5e1;border-radius:8px;height:36px;padding:0 10px;min-width:180px;background-color:#fff}.task-schedule-shell__actions{display:flex;flex-wrap:wrap;gap:8px}.task-schedule-shell__btn{border:1px solid #14b8a6;background:#14b8a6;color:#fff;border-radius:999px;padding:7px 14px;font-size:13px;font-weight:600;cursor:pointer}.task-schedule-shell__btn:disabled{opacity:.55;cursor:not-allowed}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: TaskSchedule, selector: "mt-task-schedule", inputs: ["modelType", "context", "dateFormat", "height", "langCode", "pdfFontData", "pdfRtlFontData", "pdfFontSize"], outputs: ["toolbarAction", "actionBegin", "actionCompleted", "loaded", "loadError"] }, { kind: "component", type: TaskScheduleImportModal, selector: "mt-task-schedule-import-modal", inputs: ["visible", "context", "langCode", "title", "maxRows"], outputs: ["closed", "imported", "applied", "failed"] }] });
4194
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: TaskScheduleShell, isStandalone: true, selector: "mt-task-schedule-shell", inputs: { context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { modeChanged: "modeChanged", baselineSet: "baselineSet", tasksExported: "tasksExported", actionError: "actionError" }, ngImport: i0, template: "<div class=\"task-schedule-shell\" [attr.dir]=\"resolvedLangCode() === 'ar' ? 'rtl' : 'ltr'\">\r\n <header class=\"task-schedule-shell__header\">\r\n <div class=\"task-schedule-shell__mode\">\r\n <label class=\"task-schedule-shell__label\">{{ labels().mode }}</label>\r\n <select\r\n class=\"task-schedule-shell__select\"\r\n [value]=\"currentModelType()\"\r\n (change)=\"onModeChange($any($event.target).value)\"\r\n >\r\n @for (mode of resolvedModes(); track mode.value) {\r\n <option [value]=\"mode.value\">{{ mode.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n\r\n <div class=\"task-schedule-shell__actions\">\r\n @if (showSetBaselineAction()) {\r\n <button\r\n type=\"button\"\r\n class=\"task-schedule-shell__btn\"\r\n [disabled]=\"!canSetBaselineAction()\"\r\n (click)=\"setBaseline()\"\r\n >\r\n {{ baselinePending() ? labels().pending : labels().setBaseline }}\r\n </button>\r\n }\r\n\r\n @if (showImportAction()) {\r\n <button\r\n type=\"button\"\r\n class=\"task-schedule-shell__btn\"\r\n [disabled]=\"!canOpenImport()\"\r\n (click)=\"openImportModal()\"\r\n >\r\n {{ labels().import }}\r\n </button>\r\n }\r\n\r\n <button\r\n type=\"button\"\r\n class=\"task-schedule-shell__btn\"\r\n [disabled]=\"!canExportTasks()\"\r\n (click)=\"exportTasks()\"\r\n >\r\n {{ labels().export }}\r\n </button>\r\n </div>\r\n </header>\r\n\r\n <mt-task-schedule\n [context]=\"resolvedContext()\"\n (loadError)=\"onActionError($event)\"\n />\n\n @if (showImportModal()) {\n <mt-task-schedule-import-modal\n [visible]=\"showImportModal()\"\n [context]=\"resolvedContext()\"\n (closed)=\"closeImportModal()\"\n (failed)=\"onActionError($event)\"\n (applied)=\"onImportedTasksApplied()\"\n />\r\n }\r\n</div>\r\n", styles: [":host{display:block}.task-schedule-shell{display:flex;flex-direction:column;gap:12px}.task-schedule-shell__header{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:10px}.task-schedule-shell__mode{display:flex;align-items:center;gap:8px}.task-schedule-shell__label{color:#334155;font-size:13px;font-weight:600}.task-schedule-shell__select{border:1px solid #cbd5e1;border-radius:8px;height:36px;padding:0 10px;min-width:180px;background-color:#fff}.task-schedule-shell__actions{display:flex;flex-wrap:wrap;gap:8px}.task-schedule-shell__btn{border:1px solid #14b8a6;background:#14b8a6;color:#fff;border-radius:999px;padding:7px 14px;font-size:13px;font-weight:600;cursor:pointer}.task-schedule-shell__btn:disabled{opacity:.55;cursor:not-allowed}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: TaskSchedule, selector: "mt-task-schedule", inputs: ["context"], outputs: ["toolbarAction", "actionBegin", "actionCompleted", "loaded", "loadError"] }, { kind: "component", type: TaskScheduleImportModal, selector: "mt-task-schedule-import-modal", inputs: ["visible", "context", "title", "maxRows"], outputs: ["closed", "imported", "applied", "failed"] }] });
4022
4195
  }
4023
4196
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: TaskScheduleShell, decorators: [{
4024
4197
  type: Component,
4025
- args: [{ selector: 'mt-task-schedule-shell', standalone: true, imports: [CommonModule, TaskSchedule, TaskScheduleImportModal], template: "<div class=\"task-schedule-shell\" [attr.dir]=\"resolvedLangCode() === 'ar' ? 'rtl' : 'ltr'\">\r\n <header class=\"task-schedule-shell__header\">\r\n <div class=\"task-schedule-shell__mode\">\r\n <label class=\"task-schedule-shell__label\">{{ labels().mode }}</label>\r\n <select\r\n class=\"task-schedule-shell__select\"\r\n [value]=\"currentModelType()\"\r\n (change)=\"onModeChange($any($event.target).value)\"\r\n >\r\n @for (mode of resolvedModes(); track mode.value) {\r\n <option [value]=\"mode.value\">{{ mode.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n\r\n <div class=\"task-schedule-shell__actions\">\r\n @if (showSetBaselineAction()) {\r\n <button\r\n type=\"button\"\r\n class=\"task-schedule-shell__btn\"\r\n [disabled]=\"!canSetBaselineAction()\"\r\n (click)=\"setBaseline()\"\r\n >\r\n {{ baselinePending() ? labels().pending : labels().setBaseline }}\r\n </button>\r\n }\r\n\r\n @if (showImportAction()) {\r\n <button\r\n type=\"button\"\r\n class=\"task-schedule-shell__btn\"\r\n [disabled]=\"!canOpenImport()\"\r\n (click)=\"openImportModal()\"\r\n >\r\n {{ labels().import }}\r\n </button>\r\n }\r\n\r\n <button\r\n type=\"button\"\r\n class=\"task-schedule-shell__btn\"\r\n [disabled]=\"!canExportTasks()\"\r\n (click)=\"exportTasks()\"\r\n >\r\n {{ labels().export }}\r\n </button>\r\n </div>\r\n </header>\r\n\r\n <mt-task-schedule\r\n [modelType]=\"currentModelType()\"\r\n [context]=\"context()\"\r\n [langCode]=\"resolvedLangCode()\"\r\n [dateFormat]=\"dateFormat()\"\r\n [height]=\"height()\"\r\n (loadError)=\"onActionError($event)\"\r\n />\r\n\r\n @if (showImportModal()) {\r\n <mt-task-schedule-import-modal\r\n [visible]=\"showImportModal()\"\r\n [context]=\"context()\"\r\n [langCode]=\"resolvedLangCode()\"\r\n (closed)=\"closeImportModal()\"\r\n (failed)=\"onActionError($event)\"\r\n (applied)=\"onImportedTasksApplied()\"\r\n />\r\n }\r\n</div>\r\n", styles: [":host{display:block}.task-schedule-shell{display:flex;flex-direction:column;gap:12px}.task-schedule-shell__header{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:10px}.task-schedule-shell__mode{display:flex;align-items:center;gap:8px}.task-schedule-shell__label{color:#334155;font-size:13px;font-weight:600}.task-schedule-shell__select{border:1px solid #cbd5e1;border-radius:8px;height:36px;padding:0 10px;min-width:180px;background-color:#fff}.task-schedule-shell__actions{display:flex;flex-wrap:wrap;gap:8px}.task-schedule-shell__btn{border:1px solid #14b8a6;background:#14b8a6;color:#fff;border-radius:999px;padding:7px 14px;font-size:13px;font-weight:600;cursor:pointer}.task-schedule-shell__btn:disabled{opacity:.55;cursor:not-allowed}\n"] }]
4026
- }], ctorParameters: () => [], propDecorators: { context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: false }] }], langCode: [{ type: i0.Input, args: [{ isSignal: true, alias: "langCode", required: false }] }], dateFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "dateFormat", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], modelType: [{ type: i0.Input, args: [{ isSignal: true, alias: "modelType", required: false }] }], modeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "modeOptions", required: false }] }], allowEditMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowEditMode", required: false }] }], allowImport: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowImport", required: false }] }], allowSetBaseline: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowSetBaseline", required: false }] }], hasTasks: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasTasks", required: false }] }], baselinePending: [{ type: i0.Input, args: [{ isSignal: true, alias: "baselinePending", required: false }] }], modeChanged: [{ type: i0.Output, args: ["modeChanged"] }], baselineSet: [{ type: i0.Output, args: ["baselineSet"] }], tasksExported: [{ type: i0.Output, args: ["tasksExported"] }], actionError: [{ type: i0.Output, args: ["actionError"] }] } });
4198
+ args: [{ selector: 'mt-task-schedule-shell', standalone: true, imports: [CommonModule, TaskSchedule, TaskScheduleImportModal], template: "<div class=\"task-schedule-shell\" [attr.dir]=\"resolvedLangCode() === 'ar' ? 'rtl' : 'ltr'\">\r\n <header class=\"task-schedule-shell__header\">\r\n <div class=\"task-schedule-shell__mode\">\r\n <label class=\"task-schedule-shell__label\">{{ labels().mode }}</label>\r\n <select\r\n class=\"task-schedule-shell__select\"\r\n [value]=\"currentModelType()\"\r\n (change)=\"onModeChange($any($event.target).value)\"\r\n >\r\n @for (mode of resolvedModes(); track mode.value) {\r\n <option [value]=\"mode.value\">{{ mode.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n\r\n <div class=\"task-schedule-shell__actions\">\r\n @if (showSetBaselineAction()) {\r\n <button\r\n type=\"button\"\r\n class=\"task-schedule-shell__btn\"\r\n [disabled]=\"!canSetBaselineAction()\"\r\n (click)=\"setBaseline()\"\r\n >\r\n {{ baselinePending() ? labels().pending : labels().setBaseline }}\r\n </button>\r\n }\r\n\r\n @if (showImportAction()) {\r\n <button\r\n type=\"button\"\r\n class=\"task-schedule-shell__btn\"\r\n [disabled]=\"!canOpenImport()\"\r\n (click)=\"openImportModal()\"\r\n >\r\n {{ labels().import }}\r\n </button>\r\n }\r\n\r\n <button\r\n type=\"button\"\r\n class=\"task-schedule-shell__btn\"\r\n [disabled]=\"!canExportTasks()\"\r\n (click)=\"exportTasks()\"\r\n >\r\n {{ labels().export }}\r\n </button>\r\n </div>\r\n </header>\r\n\r\n <mt-task-schedule\n [context]=\"resolvedContext()\"\n (loadError)=\"onActionError($event)\"\n />\n\n @if (showImportModal()) {\n <mt-task-schedule-import-modal\n [visible]=\"showImportModal()\"\n [context]=\"resolvedContext()\"\n (closed)=\"closeImportModal()\"\n (failed)=\"onActionError($event)\"\n (applied)=\"onImportedTasksApplied()\"\n />\r\n }\r\n</div>\r\n", styles: [":host{display:block}.task-schedule-shell{display:flex;flex-direction:column;gap:12px}.task-schedule-shell__header{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:10px}.task-schedule-shell__mode{display:flex;align-items:center;gap:8px}.task-schedule-shell__label{color:#334155;font-size:13px;font-weight:600}.task-schedule-shell__select{border:1px solid #cbd5e1;border-radius:8px;height:36px;padding:0 10px;min-width:180px;background-color:#fff}.task-schedule-shell__actions{display:flex;flex-wrap:wrap;gap:8px}.task-schedule-shell__btn{border:1px solid #14b8a6;background:#14b8a6;color:#fff;border-radius:999px;padding:7px 14px;font-size:13px;font-weight:600;cursor:pointer}.task-schedule-shell__btn:disabled{opacity:.55;cursor:not-allowed}\n"] }]
4199
+ }], ctorParameters: () => [], propDecorators: { context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: false }] }], modeChanged: [{ type: i0.Output, args: ["modeChanged"] }], baselineSet: [{ type: i0.Output, args: ["baselineSet"] }], tasksExported: [{ type: i0.Output, args: ["tasksExported"] }], actionError: [{ type: i0.Output, args: ["actionError"] }] } });
4027
4200
 
4028
4201
  /**
4029
4202
  * Generated bundle index. Do not edit.