@masterteam/task-schedule 0.0.1

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.
package/README.md ADDED
@@ -0,0 +1,134 @@
1
+ # `@masterteam/task-schedule`
2
+
3
+ Syncfusion Gantt based task-schedule package with external model switching.
4
+
5
+ ## Public API
6
+
7
+ - `TaskSchedule` component (`mt-task-schedule`)
8
+ - `TaskScheduleShell` component (`mt-task-schedule-shell`)
9
+ - `TaskScheduleImportModal` component (`mt-task-schedule-import-modal`)
10
+ - `TASK_SCHEDULE_DATA_ADAPTER` injection token
11
+ - `TaskScheduleDataAdapter` interface
12
+ - `TaskScheduleBackendAdapter` (default built-in adapter)
13
+ - `TaskScheduleModelType`
14
+ - `TaskScheduleContext`
15
+ - `TASK_SCHEDULE_DEFAULT_PDF_FONT`
16
+
17
+ ## Inputs
18
+
19
+ - `modelType`: `'default' | 'edit' | 'baseline' | 'criticalPath' | 'critical-path' | 'resources' | 'unscheduled' | 'phaseGate' | 'phase-gate' | 'custom'`
20
+ - `context`: object with required `levelId` and `levelDataId` for runtime tree loading, plus optional `customViewId`, etc.
21
+ - `dateFormat`: default `dd/MM/yyyy`
22
+ - `height`: default `760px`
23
+ - `langCode`: `'en' | 'ar' | null` (optional; auto-resolves from context/localStorage/document)
24
+ - `pdfFontData`: optional base64 TTF string for PDF export font
25
+ - `pdfRtlFontData`: optional base64 TTF string used in RTL/Arabic PDF export
26
+ - `pdfFontSize`: optional PDF font size (default `11`)
27
+
28
+ ## Outputs
29
+
30
+ - `toolbarAction`
31
+ - `actionBegin`
32
+ - `actionCompleted`
33
+ - `loaded`
34
+ - `loadError`
35
+
36
+ `TaskScheduleDataAdapter` optional import methods:
37
+
38
+ - `importTasks(context, file)`
39
+ - `applyImportedTasks(context, payload)`
40
+ - `setBaseline(context, payload?)`
41
+ - `exportTasks(context)`
42
+
43
+ ## Usage
44
+
45
+ ```ts
46
+ import { Component, signal } from '@angular/core';
47
+ import {
48
+ TASK_SCHEDULE_DATA_ADAPTER,
49
+ TaskSchedule,
50
+ TaskScheduleDataAdapter,
51
+ TaskScheduleModelType,
52
+ } from '@masterteam/task-schedule';
53
+
54
+ @Component({
55
+ standalone: true,
56
+ imports: [TaskSchedule],
57
+ selector: 'app-task-schedule-host',
58
+ template: `
59
+ <mt-task-schedule
60
+ [modelType]="modelType()"
61
+ [context]="{ levelId: 12, levelDataId: 18 }"
62
+ [langCode]="'en'"
63
+ />
64
+ `,
65
+ providers: [
66
+ {
67
+ provide: TASK_SCHEDULE_DATA_ADAPTER,
68
+ useExisting: TaskScheduleApiAdapterService,
69
+ },
70
+ ],
71
+ })
72
+ export class TaskScheduleHostComponent {
73
+ readonly modelType = signal<TaskScheduleModelType>('default');
74
+ }
75
+ ```
76
+
77
+ The component uses `TaskScheduleBackendAdapter` by default.
78
+
79
+ Backend routes used:
80
+
81
+ - Runtime tree: `GET /api/levels/{levelId}/{levelDataId}/schedule/tree`
82
+ - Custom view config: `GET /api/schedulemanager/{levelId}/schedule/{customViewId}`
83
+ - Team members (edit/resources mode): `GET /api/levels/{levelId}/TeamMember`
84
+
85
+ Edit mutations require `levelId`:
86
+
87
+ - `POST /api/tasks/{levelId}/create`
88
+ - `PUT /api/tasks/{levelId}/update/{taskId}`
89
+ - `DELETE /api/tasks/{levelId}/delete/{taskId}`
90
+ - `PUT /api/tasks/{levelId}/bulkUpdate`
91
+ - `PUT /api/tasks/{levelId}/updateParent/{taskId}`
92
+ - `PUT /api/tasks/{levelId}/reorder`
93
+ - `PUT /api/tasks/{levelId}/updatePlanningModuleProgress`
94
+
95
+ Context options for backend routing:
96
+
97
+ - `apiBaseUrl`: optional base URL prefix
98
+ - `schemaId`: optional legacy API schema id (used for old `/tasks/{schemaId}/{levelId}/...` routes)
99
+ - `customViewId`: used in `custom` mode to load schedule-manager view columns
100
+ - `resources`: optional static resource list override
101
+ - `endpoints`: optional endpoint template overrides (`scheduleTree`, `scheduleViewById`, `teamMembers`, `createTask`, etc.)
102
+ - `endpoints.setBaseline`: optional override for baseline endpoint (legacy default: `/api/levels/{schemaId}/{levelId}/tasks/setBaseline`)
103
+ - `endpoints.exportTasks`: optional override for export endpoint (legacy default: `/api/tasks/levels/{levelId}/export`)
104
+ - `requestHeaders`: optional additional headers
105
+ - `pdfFonts`: optional `{ regular?: string; arabic?: string; size?: number }` base64 font config for PDF export
106
+
107
+ When no PDF font is provided, package fallback uses embedded `TASK_SCHEDULE_DEFAULT_PDF_FONT`.
108
+
109
+ ## Import Modal
110
+
111
+ Use `mt-task-schedule-import-modal` to import `.mpp`/`.xer` files and apply tasks (replace or append).
112
+ The modal is Tailwind-based and uses `@masterteam/components` (`mt-button`, `mt-entity-preview`).
113
+ Imported rows support inline editing before apply (task name, planned/actual dates, assignee, progress) with per-row selection.
114
+
115
+ ## Shell Component
116
+
117
+ Use `mt-task-schedule-shell` as the package-level host that combines:
118
+
119
+ - mode switcher
120
+ - Set Baseline action (adapter `setBaseline`)
121
+ - Import modal orchestration
122
+ - Export tasks action (adapter `exportTasks`)
123
+
124
+ Shell parity control inputs:
125
+
126
+ - `allowEditMode`
127
+ - `allowImport`
128
+ - `allowSetBaseline`
129
+ - `hasTasks`
130
+ - `baselinePending`
131
+
132
+ Use one adapter service per selector/source if needed. The component does not use NGXS.
133
+
134
+ See `PARITY_REPORT.md` for legacy-to-package migration coverage.
@@ -0,0 +1,2 @@
1
+ /*! tailwindcss v4.2.1 | MIT License | https://tailwindcss.com */
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-space-y-reverse:0;--tw-border-style:solid;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-amber-50:oklch(98.7% .022 95.277);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-800:oklch(47.3% .137 46.201);--color-slate-50:oklch(98.4% .003 247.858);--color-slate-100:oklch(96.8% .007 247.896);--color-slate-200:oklch(92.9% .013 255.508);--color-slate-300:oklch(86.9% .022 252.894);--color-slate-400:oklch(70.4% .04 256.788);--color-slate-500:oklch(55.4% .046 257.417);--color-slate-600:oklch(44.6% .043 257.281);--color-slate-700:oklch(37.2% .044 257.287);--color-slate-900:oklch(20.8% .042 265.755);--color-white:#fff;--spacing:.25rem;--container-6xl:72rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--font-weight-medium:500;--font-weight-semibold:600;--tracking-wide:.025em;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--radius-2xl:1rem;--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.visible{visibility:visible}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{inset:calc(var(--spacing) * 0)}.start{inset-inline-start:var(--spacing)}.z-\[1000\]{z-index:1000}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.max-h-\[28rem\]{max-height:28rem}.w-full{width:100%}.max-w-6xl{max-width:var(--container-6xl)}.max-w-\[22rem\]{max-width:22rem}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-\[1180px\]{min-width:1180px}.cursor-pointer{cursor:pointer}.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\)\]{grid-template-columns:40px minmax(220px,2fr) minmax(130px,1fr) minmax(130px,1fr) minmax(130px,1fr) minmax(130px,1fr) minmax(190px,1.1fr) minmax(120px,.8fr)}.flex-wrap{flex-wrap:wrap}.place-items-center{place-items:center}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-2{column-gap:calc(var(--spacing) * 2)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-amber-200{border-color:var(--color-amber-200)}.border-slate-100{border-color:var(--color-slate-100)}.border-slate-200{border-color:var(--color-slate-200)}.border-slate-300{border-color:var(--color-slate-300)}.bg-amber-50{background-color:var(--color-amber-50)}.bg-slate-50{background-color:var(--color-slate-50)}.bg-slate-100{background-color:var(--color-slate-100)}.bg-slate-900\/40{background-color:#0f172b66}@supports (color:color-mix(in lab, red, red)){.bg-slate-900\/40{background-color:color-mix(in oklab, var(--color-slate-900) 40%, transparent)}}.bg-white{background-color:var(--color-white)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.text-amber-800{color:var(--color-amber-800)}.text-slate-400{color:var(--color-slate-400)}.text-slate-500{color:var(--color-slate-500)}.text-slate-600{color:var(--color-slate-600)}.text-slate-700{color:var(--color-slate-700)}.text-slate-900{color:var(--color-slate-900)}.uppercase{text-transform:uppercase}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-slate-200{--tw-ring-color:var(--color-slate-200)}.outline-none{--tw-outline-style:none;outline-style:none}@media (hover:hover){.hover\:border-slate-400:hover{border-color:var(--color-slate-400)}}.focus\:border-slate-400:focus{border-color:var(--color-slate-400)}}@keyframes enter{0%{opacity:var(--p-enter-opacity,1);transform:translate3d(var(--p-enter-translate-x,0), var(--p-enter-translate-y,0), 0) scale3d(var(--p-enter-scale,1), var(--p-enter-scale,1), var(--p-enter-scale,1)) rotate(var(--p-enter-rotate,0))}}@keyframes leave{to{opacity:var(--p-leave-opacity,1);transform:translate3d(var(--p-leave-translate-x,0), var(--p-leave-translate-y,0), 0) scale3d(var(--p-leave-scale,1), var(--p-leave-scale,1), var(--p-leave-scale,1)) rotate(var(--p-leave-rotate,0))}}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}