diff --git a/apps/mix-cms/src/app/pages/portal/order/order.component.html b/apps/mix-cms/src/app/pages/portal/order/order.component.html index 181ade3b..f512d714 100644 --- a/apps/mix-cms/src/app/pages/portal/order/order.component.html +++ b/apps/mix-cms/src/app/pages/portal/order/order.component.html @@ -77,10 +77,12 @@
- {{ data.createdDateTime | mixDate | date: 'dd/MM/yyyy, hh:mm a' }} + {{ + data.createdDateTime | mixDate | date : 'dd/MM/yyyy, hh:mm a' + }}
- {{ data.createdDateTime | mixDate | relativeTime | titlecase }} + {{ data.createdDateTime | mixDate | relativeTime }}
@@ -93,7 +95,7 @@
- {{ data.total | currency: data.currency }} + {{ data.total | currency : data.currency }}
preview @@ -159,11 +159,13 @@
- {{ data.createdDateTime | mixDate | date: 'dd/MM/yyyy, hh:mm a' }} + {{ + data.createdDateTime | mixDate | date : 'dd/MM/yyyy, hh:mm a' + }}
- {{ data.createdDateTime | mixDate | relativeTime | titlecase }} + {{ data.createdDateTime | mixDate | relativeTime }}
diff --git a/apps/mix-cms/src/app/pages/portal/promotion/promotion-detail/promotion-detail.component.ts b/apps/mix-cms/src/app/pages/portal/promotion/promotion-detail/promotion-detail.component.ts index 39d4a93c..daf73539 100644 --- a/apps/mix-cms/src/app/pages/portal/promotion/promotion-detail/promotion-detail.component.ts +++ b/apps/mix-cms/src/app/pages/portal/promotion/promotion-detail/promotion-detail.component.ts @@ -102,12 +102,12 @@ export class PromotionDetailComponent extends DetailPageKit { if (this.promotionData.fromDate) this.promotionData.fromDate = this.mixDatePipe.transform( this.promotionData.fromDate - ); + ) as string | null; if (this.promotionData.toDate) this.promotionData.toDate = this.mixDatePipe.transform( this.promotionData.toDate - ); + ) as string | null; this.promotionForm.patchValue(this.promotionData as any); diff --git a/apps/mix-kanban/src/app/app.component.scss b/apps/mix-kanban/src/app/app.component.scss index e3c45858..6b324a01 100644 --- a/apps/mix-kanban/src/app/app.component.scss +++ b/apps/mix-kanban/src/app/app.component.scss @@ -10,118 +10,4 @@ width: 100%; height: 100%; background-image: url(https://png.pngtree.com/png-clipart/20220429/original/pngtree-hexagon-abstract-shape-border-blue-tech-png-image_7587896.png) !important; - // background-image: radial-gradient( - // 50% 50% at 50% 50%, - // rgba(160, 51, 255, 0.024) 0, - // rgba(160, 51, 255, 0) 50% - // ), - // radial-gradient( - // 50% 50% at 50% 50%, - // rgba(160, 51, 255, 0.04) 0, - // rgba(160, 51, 255, 0) 75% - // ), - // radial-gradient( - // 50% 50% at 50% 50%, - // rgba(160, 51, 255, 0.064) 0, - // rgba(160, 51, 255, 0) 100% - // ), - // radial-gradient( - // 50% 50% at 50% 50%, - // rgba(24, 119, 242, 0.024) 0, - // rgba(24, 119, 242, 0) 50% - // ), - // radial-gradient( - // 50% 50% at 50% 50%, - // rgba(24, 119, 242, 0.04) 0, - // rgba(24, 119, 242, 0) 75% - // ), - // radial-gradient( - // 50% 50% at 50% 50%, - // rgba(24, 119, 242, 0.064) 0, - // rgba(24, 119, 242, 0) 100% - // ), - // radial-gradient( - // 50% 50% at 50% 50%, - // rgba(255, 108, 92, 0.024) 0, - // rgba(255, 108, 92, 0) 50% - // ), - // radial-gradient( - // 50% 50% at 50% 50%, - // rgba(255, 108, 92, 0.04) 0, - // rgba(255, 108, 92, 0) 75% - // ), - // radial-gradient( - // 50% 50% at 50% 50%, - // rgba(255, 108, 92, 0.064) 0, - // rgba(255, 108, 92, 0) 100% - // ), - // radial-gradient( - // 50% 50% at 50% 50%, - // rgba(245, 206, 51, 0.024) 0, - // rgba(245, 206, 51, 0) 50% - // ), - // radial-gradient( - // 50% 50% at 50% 50%, - // rgba(245, 206, 51, 0.04) 0, - // rgba(245, 206, 51, 0) 75% - // ), - // radial-gradient( - // 50% 50% at 50% 50%, - // rgba(245, 206, 51, 0.064) 0, - // rgba(245, 206, 51, 0) 100% - // ), - // radial-gradient( - // 50% 50% at 50% 50%, - // rgba(37, 211, 102, 0.024) 0, - // rgba(37, 211, 102, 0) 50% - // ), - // radial-gradient( - // 50% 50% at 50% 50%, - // rgba(37, 211, 102, 0.04) 0, - // rgba(37, 211, 102, 0) 75% - // ), - // radial-gradient( - // 50% 50% at 50% 50%, - // rgba(37, 211, 102, 0.064) 0, - // rgba(37, 211, 102, 0) 100% - // ), - // radial-gradient( - // 50% 50% at 50% 50%, - // rgba(24, 119, 242, 0.024) 0, - // rgba(24, 119, 242, 0) 50% - // ), - // radial-gradient( - // 50% 50% at 50% 50%, - // rgba(24, 119, 242, 0.04) 0, - // rgba(24, 119, 242, 0) 75% - // ), - // radial-gradient( - // 50% 50% at 50% 50%, - // rgba(24, 119, 242, 0.064) 0, - // rgba(24, 119, 242, 0) 100% - // ); - // background-size: 156.45vw 99.03vw, 156.45vw 99.03vw, 156.45vw 99.03vw, - // 226.86vw 145.44vw, 226.86vw 145.44vw, 226.86vw 145.44vw, 171.96vw 110.31vw, - // 171.96vw 110.31vw, 171.96vw 110.31vw, 130.29vw 83.58vw, 130.29vw 83.58vw, - // 130.29vw 83.58vw, 198vw 126.9vw, 198vw 126.9vw, 198vw 126.9vw, 300vw 192vw, - // 300vw 192vw, 300vw 192vw; - // background-attachment: fixed; - // background-position: 37.97vw calc(((300vw - 100vh) / 2 - 85.77vw) * -1), - // 37.97vw calc(((300vw - 100vh) / 2 - 85.77vw) * -1), - // 37.97vw calc(((300vw - 100vh) / 2 - 85.77vw) * -1), - // -100vw calc(((300vw - 100vh) / 2 - 154.56vw) * -1), - // -100vw calc(((300vw - 100vh) / 2 - 154.56vw) * -1), - // -100vw calc(((300vw - 100vh) / 2 - 154.56vw) * -1), - // 13.34vw calc(((300vw - 100vh) / 2 - 53.88vw) * -1), - // 13.34vw calc(((300vw - 100vh) / 2 - 53.88vw) * -1), - // 13.34vw calc(((300vw - 100vh) / 2 - 53.88vw) * -1), - // 10.64vw calc(((300vw - 100vh) / 2 - 17.19vw) * -1), - // 10.64vw calc(((300vw - 100vh) / 2 - 17.19vw) * -1), - // 10.64vw calc(((300vw - 100vh) / 2 - 17.19vw) * -1), - // -49vw calc(((300vw - 100vh) / 2 - 41.1vw) * -1), - // -49vw calc(((300vw - 100vh) / 2 - 41.1vw) * -1), - // -49vw calc(((300vw - 100vh) / 2 - 41.1vw) * -1), - // -100vw calc(((300vw - 100vh) / 2 - 78vw) * -1), - // -100vw calc(((300vw - 100vh) / 2 - 78vw) * -1), - // -100vw calc(((300vw - 100vh) / 2 - 78vw) * -1); } diff --git a/apps/mix-kanban/src/app/app.routes.ts b/apps/mix-kanban/src/app/app.routes.ts index 5aaf5f75..7d98ba51 100644 --- a/apps/mix-kanban/src/app/app.routes.ts +++ b/apps/mix-kanban/src/app/app.routes.ts @@ -21,9 +21,21 @@ export const CMS_ROUTES = { path: 'dashboard', fullPath: 'app/dashboard', }, - task: { - path: 'tasks', - fullPath: 'app/tasks', + workspace: { + path: 'workspace', + fullPath: 'app/workspace', + }, + board: { + path: 'board', + fullPath: 'app/workspace/board', + }, + project: { + path: 'project', + fullPath: 'app/workspace/project', + }, + timeline: { + path: 'timeline', + fullPath: 'app/workspace/timeline', }, }, }; diff --git a/apps/mix-kanban/src/app/pages/portal/portal.routes.ts b/apps/mix-kanban/src/app/pages/portal/portal.routes.ts index a3641bd0..7656f2a9 100644 --- a/apps/mix-kanban/src/app/pages/portal/portal.routes.ts +++ b/apps/mix-kanban/src/app/pages/portal/portal.routes.ts @@ -11,8 +11,8 @@ export const PortalRoutes: Routes = [ data: breadcrumbName('Dashboard'), }, { - path: CMS_ROUTES.portal.task.path, - data: breadcrumbName('Task Management'), + path: CMS_ROUTES.portal.workspace.path, + data: breadcrumbName('Workspace'), loadChildren: () => import('@mixcore/module/task').then((m) => m.taskManagementRoutes), }, diff --git a/apps/mix-kanban/src/app/shares/consts/app.menu.ts b/apps/mix-kanban/src/app/shares/consts/app.menu.ts index 3065fa0d..6ae49f7c 100644 --- a/apps/mix-kanban/src/app/shares/consts/app.menu.ts +++ b/apps/mix-kanban/src/app/shares/consts/app.menu.ts @@ -14,22 +14,22 @@ export const APP_MENU = [ ], }, { - title: 'Projects', + title: 'Project', icon: 'view_kanban', children: [ { - title: 'Project', - url: CMS_ROUTES.portal.task.fullPath, + title: 'Setting', + url: CMS_ROUTES.portal.project.fullPath, icon: 'view_kanban', }, { title: 'Board', - url: CMS_ROUTES.portal.task.fullPath, + url: CMS_ROUTES.portal.board.fullPath, icon: 'view_kanban', }, { title: 'Timeline', - url: CMS_ROUTES.portal.task.fullPath, + url: CMS_ROUTES.portal.timeline.fullPath, icon: 'view_kanban', }, ], diff --git a/apps/mix-kanban/src/index.html b/apps/mix-kanban/src/index.html index 2f6c87c7..18bc6905 100644 --- a/apps/mix-kanban/src/index.html +++ b/apps/mix-kanban/src/index.html @@ -20,9 +20,6 @@ rel="stylesheet" /> - - - diff --git a/libs/mix-share/src/bases/base-appconfig.ts b/libs/mix-share/src/bases/base-appconfig.ts index 1235eb29..1c7e11bf 100644 --- a/libs/mix-share/src/bases/base-appconfig.ts +++ b/libs/mix-share/src/bases/base-appconfig.ts @@ -103,7 +103,6 @@ export const BaseAppProvider = [ shouldCoalesceRunChangeDetection: true, }), }, - { provide: ERROR_MAP, useValue: errorMap, diff --git a/libs/mix-share/src/modules/task-manage/board/board.component.html b/libs/mix-share/src/modules/task-manage/board/board.component.html index fef68ca8..46ce9a83 100644 --- a/libs/mix-share/src/modules/task-manage/board/board.component.html +++ b/libs/mix-share/src/modules/task-manage/board/board.component.html @@ -11,8 +11,7 @@
+ class="board__main-view"> @@ -25,7 +24,8 @@ @for (task of tasks; track task.id) { + [taskStatuses]="taskStatuses" + cdkDropListGroup> } } }
diff --git a/libs/mix-share/src/modules/task-manage/board/board.component.scss b/libs/mix-share/src/modules/task-manage/board/board.component.scss index a4e929d5..023617dd 100644 --- a/libs/mix-share/src/modules/task-manage/board/board.component.scss +++ b/libs/mix-share/src/modules/task-manage/board/board.component.scss @@ -1,5 +1,5 @@ .board { - --task-min-col-w: 200px; + --task-min-col-w: 250px; --task-col-w: 320px; --task-list-bg: rgba(244, 244, 244, 1); --task-col-padding: 8px 16px; diff --git a/libs/mix-share/src/modules/task-manage/components/task-date-display/task-date-display.component.html b/libs/mix-share/src/modules/task-manage/components/task-date-display/task-date-display.component.html index 3e6d53c3..41184787 100644 --- a/libs/mix-share/src/modules/task-manage/components/task-date-display/task-date-display.component.html +++ b/libs/mix-share/src/modules/task-manage/components/task-date-display/task-date-display.component.html @@ -1,3 +1,9 @@
- {{ task.fromDate | date: 'hh:MM:yyyy' }} + schedule + + {{ task.fromDate | date : 'dd MMM yyyy' }} + + +  - {{ task.dueDate | date : 'dd MMM yyyy' }} +
diff --git a/libs/mix-share/src/modules/task-manage/components/task-date-display/task-date-display.component.scss b/libs/mix-share/src/modules/task-manage/components/task-date-display/task-date-display.component.scss index 71a9d884..8da6b149 100644 --- a/libs/mix-share/src/modules/task-manage/components/task-date-display/task-date-display.component.scss +++ b/libs/mix-share/src/modules/task-manage/components/task-date-display/task-date-display.component.scss @@ -1,6 +1,11 @@ .task-date-display { background-color: var(--success-color); color: var(--success-color-text); - padding: 4px; + padding: 4px 6px; width: fit-content; + height: fit-content; + display: flex; + align-items: center; + border-radius: 2px; + line-height: 1; } diff --git a/libs/mix-share/src/modules/task-manage/index.ts b/libs/mix-share/src/modules/task-manage/index.ts index d87075eb..5785b690 100644 --- a/libs/mix-share/src/modules/task-manage/index.ts +++ b/libs/mix-share/src/modules/task-manage/index.ts @@ -1 +1 @@ -export * from './task-manange.route'; +export * from './task-manage.route'; diff --git a/libs/mix-share/src/modules/task-manage/task-manange.route.ts b/libs/mix-share/src/modules/task-manage/task-manage.route.ts similarity index 77% rename from libs/mix-share/src/modules/task-manage/task-manange.route.ts rename to libs/mix-share/src/modules/task-manage/task-manage.route.ts index 21782ee2..def2f5b3 100644 --- a/libs/mix-share/src/modules/task-manage/task-manange.route.ts +++ b/libs/mix-share/src/modules/task-manage/task-manage.route.ts @@ -16,6 +16,13 @@ export const taskManagementRoutes: Routes = [ loadComponent: () => import('./project/project.component').then((c) => c.ProjectComponent), }, + { + path: 'timeline', + loadComponent: () => + import('./timeline/timeline.component').then( + (c) => c.TimelineComponent + ), + }, { path: '', redirectTo: 'board', diff --git a/libs/mix-share/src/modules/task-manage/timeline/timeline.component.html b/libs/mix-share/src/modules/task-manage/timeline/timeline.component.html new file mode 100644 index 00000000..82e9305b --- /dev/null +++ b/libs/mix-share/src/modules/task-manage/timeline/timeline.component.html @@ -0,0 +1,60 @@ +
+
+ + add   + {{ 'New' | transloco }} + + +
+
+
+ + {{ option | titlecase }} + +
+
+
+ +
+ + + + {{ item.title }} + + + + +
+ type + + +
+
+
+
+
+
+
+
diff --git a/libs/mix-share/src/modules/task-manage/timeline/timeline.component.scss b/libs/mix-share/src/modules/task-manage/timeline/timeline.component.scss new file mode 100644 index 00000000..b93fa9e0 --- /dev/null +++ b/libs/mix-share/src/modules/task-manage/timeline/timeline.component.scss @@ -0,0 +1,18 @@ +@import 'node_modules/@worktile/gantt/styles/index.scss'; + +.timeline { + &__toolbar { + padding: 12px; + + .tui-group { + width: 325px; + } + } + + &__main-view { + height: 100%; + width: 100%; + flex-grow: 1; + padding: 0px 12px; + } +} diff --git a/libs/mix-share/src/modules/task-manage/timeline/timeline.component.ts b/libs/mix-share/src/modules/task-manage/timeline/timeline.component.ts new file mode 100644 index 00000000..72fb16ef --- /dev/null +++ b/libs/mix-share/src/modules/task-manage/timeline/timeline.component.ts @@ -0,0 +1,111 @@ +import { CommonModule } from '@angular/common'; +import { Component, ViewChild, ViewEncapsulation, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; +import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms'; +import { TaskTypeIcons } from '@mixcore/lib/model'; +import { BaseComponent } from '@mixcore/share/base'; +import { MixSubToolbarComponent } from '@mixcore/share/components'; +import { MixButtonComponent } from '@mixcore/ui/button'; +import { DialogService } from '@ngneat/dialog'; +import { TranslocoModule } from '@ngneat/transloco'; +import { TuiGroupModule } from '@taiga-ui/core'; +import { TuiRadioBlockModule } from '@taiga-ui/kit'; +import { + GANTT_GLOBAL_CONFIG, + GanttGroup, + GanttItem, + GanttViewType, + NgxGanttModule, +} from '@worktile/gantt'; +import { setDefaultOptions } from 'date-fns'; +import { enUS } from 'date-fns/locale'; +import { TaskDateDisplayComponent } from '../components/task-date-display/task-date-display.component'; +import { TaskManageStore } from '../store/task-ui.store'; +import { TaskStore } from '../store/task.store'; +setDefaultOptions({ locale: enUS }); + +@Component({ + selector: 'timeline', + standalone: true, + imports: [ + CommonModule, + MixSubToolbarComponent, + MixButtonComponent, + TranslocoModule, + NgxGanttModule, + TaskDateDisplayComponent, + TuiRadioBlockModule, + ReactiveFormsModule, + TuiGroupModule, + ], + templateUrl: './timeline.component.html', + styleUrl: './timeline.component.scss', + encapsulation: ViewEncapsulation.None, + providers: [ + { + provide: GANTT_GLOBAL_CONFIG, + useValue: { + dateFormat: { + yearQuarter: `QQQ 'of' yyyy`, + month: 'LL', + yearMonth: `LLLL '('yyyy')'`, + year: `yyyy`, + }, + }, + }, + ], +}) +export class TimelineComponent extends BaseComponent { + @ViewChild('gantt') ganttElement!: Element; + public dialog = inject(DialogService); + public store = inject(TaskStore); + public taskManage = inject(TaskManageStore); + + public viewType: GanttViewType = GanttViewType.day; + public items: GanttItem[] = []; + public groups: GanttGroup[] = []; + public TaskTypeIcon = TaskTypeIcons; + + readonly modeOptions = [ + GanttViewType.day, + GanttViewType.month, + GanttViewType.quarter, + GanttViewType.year, + ]; + readonly modeForm = new FormGroup({ + value: new FormControl(GanttViewType.day), + }); + + constructor() { + super(); + + this.store + .getParentTasks() + .pipe(takeUntilDestroyed()) + .subscribe((parent) => { + this.groups = parent.map((p) => ({ + id: p.id.toString(), + title: p.title, + })); + }); + + this.store.vm$.pipe(takeUntilDestroyed()).subscribe((v) => { + this.items = v.data + .filter((x) => x.parentTaskId) + .map((x) => ({ + id: x.id.toString(), + title: x.title, + start: new Date(x.fromDate!).getTime(), + end: new Date(x.dueDate!).getTime(), + group_id: x.parentTaskId?.toString(), + ['task']: x, + })); + }); + + this.modeForm.controls.value.valueChanges + .pipe(takeUntilDestroyed()) + .subscribe((m) => { + this.viewType = m!; + }); + } +} diff --git a/libs/mix-share/src/pipes/mix-date.pipe.ts b/libs/mix-share/src/pipes/mix-date.pipe.ts index f6906599..b428f1c7 100644 --- a/libs/mix-share/src/pipes/mix-date.pipe.ts +++ b/libs/mix-share/src/pipes/mix-date.pipe.ts @@ -2,7 +2,7 @@ import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'mixDate', standalone: true }) export class MixUtcDatePipe implements PipeTransform { - public transform(utcDateString: string | null | Date) { + public transform(utcDateString: string | null | Date | undefined) { if ( utcDateString == null || utcDateString == undefined || diff --git a/libs/mix-share/src/pipes/relative-timespan.pipe.ts b/libs/mix-share/src/pipes/relative-timespan.pipe.ts index 5ec896c4..bd41834a 100644 --- a/libs/mix-share/src/pipes/relative-timespan.pipe.ts +++ b/libs/mix-share/src/pipes/relative-timespan.pipe.ts @@ -2,7 +2,7 @@ import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'relativeTimeSpan', standalone: true }) export class RelativeTimeSpanPipe implements PipeTransform { - public transform(value: string | null) { + public transform(value: string | null | Date | undefined) { if (value == null || value === '' || value === 'N/A' || value !== value) return value; @@ -24,7 +24,7 @@ export class RelativeTimeSpanPipe implements PipeTransform { @Pipe({ name: 'relativeTime', standalone: true }) export class RelativeTimePipe implements PipeTransform { - public transform(value: string | null) { + public transform(value: string | null | Date | undefined) { if (value == null || value === '' || value === 'N/A' || value !== value) return value; diff --git a/libs/mix-share/tsconfig.json b/libs/mix-share/tsconfig.json index 1c995b83..a4567428 100644 --- a/libs/mix-share/tsconfig.json +++ b/libs/mix-share/tsconfig.json @@ -17,12 +17,14 @@ "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true + "noFallthroughCasesInSwitch": true, + "allowSyntheticDefaultImports": true }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, - "strictTemplates": true + "strictTemplates": true, + "allowSyntheticDefaultImports": true } } diff --git a/package.json b/package.json index 1f191dc9..013800de 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "@taiga-ui/layout": "^3.57.0", "@tinkoff/ng-dompurify": "^4.0.0", "@tinkoff/ng-polymorpheus": "4.2.0", + "@worktile/gantt": "^16.0.2", "ag-grid-angular": "^30.0.6", "ag-grid-community": "^30.0.6", "ang-jsoneditor": "^3.1.0", @@ -66,9 +67,11 @@ "angularx-qrcode": "^16.0.0", "apollo-angular": "^5.0.0", "crypto-js": "^4.1.1", + "date-fns": "^2.30.0", "fs": "0.0.1-security", "glob": "^9.3.2", "graphql": "^16.7.1", + "html2canvas": "^1.4.1", "js-beautify": "^1.14.7", "jsoneditor": "^9.10.2", "lru-cache": "^9.1.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8fcb4ddd..591cda25 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -122,6 +122,9 @@ dependencies: '@tinkoff/ng-polymorpheus': specifier: 4.2.0 version: 4.2.0(@angular/core@17.0.2)(@angular/platform-browser@17.0.2) + '@worktile/gantt': + specifier: ^16.0.2 + version: 16.0.2(@angular/cdk@17.0.0)(@angular/common@17.0.2)(@angular/core@17.0.2)(date-fns@2.30.0)(rxjs@7.8.1) ag-grid-angular: specifier: ^30.0.6 version: 30.2.1(@angular/common@17.0.2)(@angular/core@17.0.2)(ag-grid-community@30.2.1) @@ -143,6 +146,12 @@ dependencies: crypto-js: specifier: ^4.1.1 version: 4.2.0 + date-fns: + specifier: ^2.30.0 + version: 2.30.0 + frappe-gantt: + specifier: ^0.6.1 + version: 0.6.1 fs: specifier: 0.0.1-security version: 0.0.1-security @@ -152,6 +161,9 @@ dependencies: graphql: specifier: ^16.7.1 version: 16.8.1 + html2canvas: + specifier: ^1.4.1 + version: 1.4.1 js-beautify: specifier: ^1.14.7 version: 1.14.11 @@ -265,6 +277,9 @@ devDependencies: '@types/crypto-js': specifier: ^4.1.1 version: 4.2.1 + '@types/frappe-gantt': + specifier: ^0.6.4 + version: 0.6.4 '@types/jest': specifier: 29.4.4 version: 29.4.4 @@ -5982,6 +5997,10 @@ packages: '@types/qs': 6.9.10 '@types/serve-static': 1.15.5 + /@types/frappe-gantt@0.6.4: + resolution: {integrity: sha512-HvF+ED1gwhyuN/pvJW5VdEL+JP95q3xyX3NMFcF6R0NJLukXVg/yz4znzSTd81mqzPABABa4Pj6YoQCUHiZa+A==} + dev: true + /@types/graceful-fs@4.1.9: resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} dependencies: @@ -6445,6 +6464,23 @@ packages: '@webassemblyjs/ast': 1.11.6 '@xtuc/long': 4.2.2 + /@worktile/gantt@16.0.2(@angular/cdk@17.0.0)(@angular/common@17.0.2)(@angular/core@17.0.2)(date-fns@2.30.0)(rxjs@7.8.1): + resolution: {integrity: sha512-GR2qDE3xTQhtxPwkEjZ5vxyDQK37pBeDS597r9HVAoFoD+brCdqdjI7Bts5EQ7yvuVy8xdm4V0/OdekFs5Ijmg==} + peerDependencies: + '@angular/cdk': '>=16.0.0' + '@angular/common': '>=16.0.0' + '@angular/core': '>=16.0.0' + date-fns: '>=2.0.0' + rxjs: ^6.5.0 || ^7.0.0 + dependencies: + '@angular/cdk': 17.0.0(@angular/common@17.0.2)(@angular/core@17.0.2)(rxjs@7.8.1) + '@angular/common': 17.0.2(@angular/core@17.0.2)(rxjs@7.8.1) + '@angular/core': 17.0.2(rxjs@7.8.1)(zone.js@0.14.2) + date-fns: 2.30.0 + rxjs: 7.8.1 + tslib: 2.6.2 + dev: false + /@wry/context@0.7.4: resolution: {integrity: sha512-jmT7Sb4ZQWI5iyu3lobQxICu2nC/vbUhP0vIdd6tHC9PTfenmRmuIFqktc6GH9cgi+ZHnsLWPvfSvc4DrYmKiQ==} engines: {node: '>=8'} @@ -7068,6 +7104,11 @@ packages: /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + /base64-arraybuffer@1.0.2: + resolution: {integrity: sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==} + engines: {node: '>= 0.6.0'} + dev: false + /base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -7811,6 +7852,12 @@ packages: postcss: 8.4.31 dev: false + /css-line-break@2.1.0: + resolution: {integrity: sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==} + dependencies: + utrie: 1.0.2 + dev: false + /css-loader@6.8.1(webpack@5.89.0): resolution: {integrity: sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g==} engines: {node: '>= 12.13.0'} @@ -8187,6 +8234,13 @@ packages: whatwg-mimetype: 3.0.0 whatwg-url: 11.0.0 + /date-fns@2.30.0: + resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} + engines: {node: '>=0.11'} + dependencies: + '@babel/runtime': 7.23.2 + dev: false + /dayjs@1.11.10: resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} @@ -9214,6 +9268,10 @@ packages: /fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + /frappe-gantt@0.6.1: + resolution: {integrity: sha512-1cSU9vLbwypjzaxnCfnEE03Xr3HlAV2S8dRtjxw62o+amkx1A8bBIFd2jp84mcDdTCM77Ij4LzZBslAKZB8oMg==} + dev: false + /fresh@0.5.2: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} @@ -9550,6 +9608,14 @@ packages: /html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + /html2canvas@1.4.1: + resolution: {integrity: sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==} + engines: {node: '>=8.0.0'} + dependencies: + css-line-break: 2.1.0 + text-segmentation: 1.0.3 + dev: false + /htmlparser2@7.2.0: resolution: {integrity: sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==} dependencies: @@ -13893,6 +13959,12 @@ packages: resolution: {integrity: sha512-VfkCMdmRRZqXgQZFlDMiavm3hzsMzBM23CxHZsaeAYg66ZhXCNJWrFmnJwNy8KF9f74YvAUAuQenxsMCfuvhUw==} dev: false + /text-segmentation@1.0.3: + resolution: {integrity: sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==} + dependencies: + utrie: 1.0.2 + dev: false + /text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} @@ -14285,6 +14357,12 @@ packages: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} + /utrie@1.0.2: + resolution: {integrity: sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==} + dependencies: + base64-arraybuffer: 1.0.2 + dev: false + /uuid@8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true