@archbase/components 3.0.25 → 4.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/dist/buttons/ArchbaseSpeedDial.d.ts +59 -0
- package/dist/buttons/index.d.ts +2 -0
- package/dist/charts/ArchbaseArcGauge.d.ts +55 -0
- package/dist/charts/ArchbaseGantt.d.ts +70 -0
- package/dist/charts/ArchbaseLinearGauge.d.ts +55 -0
- package/dist/charts/ArchbaseResourceTimeline.d.ts +61 -0
- package/dist/charts/ArchbaseSparkline.d.ts +45 -0
- package/dist/charts/index.d.ts +10 -0
- package/dist/containers/ArchbaseExpansionPanel.d.ts +60 -0
- package/dist/containers/ArchbaseFloatingPanel.d.ts +91 -0
- package/dist/containers/index.d.ts +4 -0
- package/dist/datagrid/export/ArchbaseDataGridExcelExport.d.ts +67 -0
- package/dist/datagrid/export/index.d.ts +2 -0
- package/dist/datagrid/index.d.ts +1 -0
- package/dist/display/ArchbaseAnimationWrapper.d.ts +73 -0
- package/dist/display/ArchbaseBarcodeGenerator.d.ts +50 -0
- package/dist/display/ArchbaseCarousel.d.ts +100 -0
- package/dist/display/ArchbaseCodeViewer.d.ts +63 -0
- package/dist/display/ArchbaseDiffViewer.d.ts +41 -0
- package/dist/display/ArchbaseJsonTree.d.ts +34 -0
- package/dist/display/ArchbaseLightbox.d.ts +89 -0
- package/dist/display/ArchbaseMarquee.d.ts +46 -0
- package/dist/display/ArchbasePhotoAlbum.d.ts +58 -0
- package/dist/display/ArchbaseQRCode.d.ts +44 -0
- package/dist/display/ArchbaseTooltipRich.d.ts +82 -0
- package/dist/display/ArchbaseVirtualList.d.ts +116 -0
- package/dist/display/index.d.ts +24 -0
- package/dist/editors/ArchbaseAIPromptInput.d.ts +69 -0
- package/dist/editors/ArchbaseAsyncMultiSelect.d.ts +1 -1
- package/dist/editors/ArchbaseAsyncSelect.d.ts +1 -1
- package/dist/editors/ArchbaseBarcodeScanner.d.ts +63 -0
- package/dist/editors/ArchbaseCepInput.d.ts +26 -0
- package/dist/editors/ArchbaseColorGradientPicker.d.ts +80 -0
- package/dist/editors/ArchbaseCpfCnpjInput.d.ts +21 -0
- package/dist/editors/ArchbaseCurrencyInput.d.ts +25 -0
- package/dist/editors/ArchbaseDualListbox.d.ts +61 -0
- package/dist/editors/ArchbaseInPlaceEditor.d.ts +67 -0
- package/dist/editors/ArchbaseLightGrid.d.ts +56 -0
- package/dist/editors/ArchbaseMentionInput.d.ts +75 -0
- package/dist/editors/ArchbaseMultiEmail.d.ts +53 -0
- package/dist/editors/ArchbaseMultiViewCalendar.d.ts +47 -0
- package/dist/editors/ArchbaseNumberStepper.d.ts +66 -0
- package/dist/editors/ArchbaseOTPInput.d.ts +27 -0
- package/dist/editors/ArchbasePhoneInput.d.ts +52 -0
- package/dist/editors/ArchbaseRangeSlider.d.ts +22 -0
- package/dist/editors/ArchbaseSignaturePad.d.ts +60 -0
- package/dist/editors/ArchbaseSpeechToTextInput.d.ts +106 -0
- package/dist/editors/ArchbaseSpreadsheet.d.ts +56 -0
- package/dist/editors/ArchbaseTagInput.d.ts +55 -0
- package/dist/editors/index.d.ts +40 -0
- package/dist/feedback/ArchbaseChunkProgressBar.d.ts +35 -0
- package/dist/feedback/ArchbaseRipple.d.ts +43 -0
- package/dist/feedback/ArchbaseSkeleton.d.ts +115 -0
- package/dist/feedback/index.d.ts +6 -0
- package/dist/filters/ArchbaseColumnSelector.d.ts +38 -0
- package/dist/filters/index.d.ts +2 -0
- package/dist/forms/ArchbaseFieldArray.d.ts +80 -0
- package/dist/forms/ArchbaseFormWizard.d.ts +73 -0
- package/dist/forms/ArchbaseStepper.d.ts +51 -0
- package/dist/forms/index.d.ts +8 -0
- package/dist/forms/useArchbaseFormWizard.d.ts +74 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/useArchbaseConfirm.d.ts +59 -0
- package/dist/image/editor/index.d.ts +43 -4
- package/dist/image/index.d.ts +1 -0
- package/dist/index.css +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +22510 -13820
- package/dist/list/ArchbaseTreeList.d.ts +76 -0
- package/dist/list/index.d.ts +2 -0
- package/dist/navigation/ArchbaseActionSheet.d.ts +70 -0
- package/dist/navigation/ArchbaseAppBar.d.ts +63 -0
- package/dist/navigation/ArchbaseBottomNavigation.d.ts +61 -0
- package/dist/navigation/ArchbaseContextMenu.d.ts +76 -0
- package/dist/navigation/ArchbaseKeyboardShortcuts.d.ts +85 -0
- package/dist/navigation/ArchbaseSpotlight.d.ts +69 -0
- package/dist/navigation/index.d.ts +12 -0
- package/dist/notification/ArchbaseNotificationCenter.d.ts +56 -0
- package/dist/notification/index.d.ts +2 -0
- package/dist/onboarding/ArchbaseOnboardingTour.d.ts +27 -76
- package/dist/viewers/ArchbaseDocViewer.d.ts +40 -0
- package/dist/viewers/ArchbasePdfBuilder.d.ts +53 -0
- package/dist/viewers/ArchbaseXmlViewer.d.ts +36 -0
- package/dist/viewers/index.d.ts +6 -0
- package/package.json +41 -18
- package/src/buttons/ArchbaseSpeedDial.tsx +282 -0
- package/src/buttons/index.ts +3 -0
- package/src/charts/ArchbaseArcGauge.tsx +325 -0
- package/src/charts/ArchbaseGantt.tsx +494 -0
- package/src/charts/ArchbaseLinearGauge.tsx +288 -0
- package/src/charts/ArchbaseResourceTimeline.tsx +433 -0
- package/src/charts/ArchbaseSparkline.tsx +193 -0
- package/src/charts/index.ts +20 -1
- package/src/containers/ArchbaseExpansionPanel.tsx +208 -0
- package/src/containers/ArchbaseFloatingPanel.tsx +448 -0
- package/src/containers/index.ts +17 -0
- package/src/datagrid/components/pagination/grid-pagination.tsx +2 -2
- package/src/datagrid/export/ArchbaseDataGridExcelExport.tsx +293 -0
- package/src/datagrid/export/index.ts +8 -0
- package/src/datagrid/index.tsx +2 -0
- package/src/display/ArchbaseAnimationWrapper.tsx +272 -0
- package/src/display/ArchbaseBarcodeGenerator.tsx +303 -0
- package/src/display/ArchbaseCarousel.tsx +679 -0
- package/src/display/ArchbaseCodeViewer.tsx +271 -0
- package/src/display/ArchbaseDiffViewer.tsx +108 -0
- package/src/display/ArchbaseJsonTree.tsx +150 -0
- package/src/display/ArchbaseLightbox.tsx +279 -0
- package/src/display/ArchbaseMarquee.tsx +268 -0
- package/src/display/ArchbasePhotoAlbum.tsx +415 -0
- package/src/display/ArchbaseQRCode.tsx +137 -0
- package/src/display/ArchbaseTooltipRich.tsx +317 -0
- package/src/display/ArchbaseVirtualList.tsx +618 -0
- package/src/display/index.ts +94 -1
- package/src/editors/ArchbaseAIPromptInput.tsx +432 -0
- package/src/editors/ArchbaseBarcodeScanner.tsx +570 -0
- package/src/editors/ArchbaseCepInput.tsx +173 -0
- package/src/editors/ArchbaseColorGradientPicker.tsx +460 -0
- package/src/editors/ArchbaseCpfCnpjInput.tsx +193 -0
- package/src/editors/ArchbaseCurrencyInput.tsx +100 -0
- package/src/editors/ArchbaseDualListbox.tsx +671 -0
- package/src/editors/ArchbaseInPlaceEditor.tsx +406 -0
- package/src/editors/ArchbaseLightGrid.tsx +538 -0
- package/src/editors/ArchbaseMentionInput.tsx +384 -0
- package/src/editors/ArchbaseMultiEmail.tsx +367 -0
- package/src/editors/ArchbaseMultiViewCalendar.tsx +439 -0
- package/src/editors/ArchbaseNumberStepper.tsx +219 -0
- package/src/editors/ArchbaseOTPInput.tsx +133 -0
- package/src/editors/ArchbaseOperationHoursEditor.tsx +1 -1
- package/src/editors/ArchbasePhoneInput.tsx +355 -0
- package/src/editors/ArchbaseRangeSlider.tsx +109 -0
- package/src/editors/ArchbaseSignaturePad.tsx +425 -0
- package/src/editors/ArchbaseSpeechToTextInput.tsx +444 -0
- package/src/editors/ArchbaseSpreadsheet.tsx +388 -0
- package/src/editors/ArchbaseTagInput.tsx +326 -0
- package/src/editors/index.tsx +92 -0
- package/src/feedback/ArchbaseChunkProgressBar.tsx +156 -0
- package/src/feedback/ArchbaseRipple.tsx +278 -0
- package/src/feedback/ArchbaseSkeleton.tsx +419 -0
- package/src/feedback/index.ts +22 -1
- package/src/filters/ArchbaseColumnSelector.tsx +268 -0
- package/src/filters/index.ts +2 -0
- package/src/forms/ArchbaseFieldArray.tsx +305 -0
- package/src/forms/ArchbaseFormWizard.tsx +284 -0
- package/src/forms/ArchbaseStepper.tsx +137 -0
- package/src/forms/index.ts +24 -2
- package/src/forms/useArchbaseFormWizard.ts +283 -0
- package/src/hooks/index.ts +12 -0
- package/src/hooks/useArchbaseConfirm.ts +293 -0
- package/src/image/editor/functions/image-processing.ts +5 -0
- package/src/image/editor/index.tsx +305 -391
- package/src/image/index.ts +1 -0
- package/src/index.ts +3 -0
- package/src/list/ArchbaseTreeList.tsx +422 -0
- package/src/list/index.ts +3 -0
- package/src/navigation/ArchbaseActionSheet.tsx +301 -0
- package/src/navigation/ArchbaseAppBar.tsx +233 -0
- package/src/navigation/ArchbaseBottomNavigation.tsx +243 -0
- package/src/navigation/ArchbaseContextMenu.tsx +298 -0
- package/src/navigation/ArchbaseKeyboardShortcuts.tsx +472 -0
- package/src/navigation/ArchbaseSpotlight.tsx +483 -0
- package/src/navigation/index.ts +48 -1
- package/src/notification/ArchbaseNotificationCenter.tsx +502 -0
- package/src/notification/index.ts +2 -0
- package/src/onboarding/ArchbaseOnboardingTour.tsx +229 -102
- package/src/viewers/ArchbaseDocViewer.tsx +584 -0
- package/src/viewers/ArchbasePdfBuilder.tsx +291 -0
- package/src/viewers/ArchbaseXmlViewer.tsx +142 -0
- package/src/viewers/index.ts +12 -0
|
@@ -0,0 +1,494 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ArchbaseGantt — wrapper para gantt-task-react com suporte a DataSource.
|
|
3
|
+
*/
|
|
4
|
+
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
5
|
+
import { Gantt, Task, ViewMode } from 'gantt-task-react';
|
|
6
|
+
import 'gantt-task-react/dist/index.css';
|
|
7
|
+
import { Box, Input, useMantineTheme, useComputedColorScheme } from '@mantine/core';
|
|
8
|
+
import {
|
|
9
|
+
useArchbaseDataSourceListener,
|
|
10
|
+
DataSourceEvent,
|
|
11
|
+
DataSourceEventNames,
|
|
12
|
+
} from '@archbase/data';
|
|
13
|
+
import type { IArchbaseDataSourceBase } from '@archbase/data';
|
|
14
|
+
import { get } from 'lodash';
|
|
15
|
+
|
|
16
|
+
// Re-exporta tipos úteis do gantt-task-react
|
|
17
|
+
export { ViewMode } from 'gantt-task-react';
|
|
18
|
+
export type { Task } from 'gantt-task-react';
|
|
19
|
+
|
|
20
|
+
export interface ArchbaseGanttProps<T = any, ID = any> {
|
|
21
|
+
/** DataSource que fornece a coleção de tarefas */
|
|
22
|
+
dataSource?: IArchbaseDataSourceBase<T>;
|
|
23
|
+
/** Campo que mapeia o id da tarefa */
|
|
24
|
+
idField?: string;
|
|
25
|
+
/** Campo que mapeia o nome da tarefa */
|
|
26
|
+
nameField?: string;
|
|
27
|
+
/** Campo que mapeia a data de início */
|
|
28
|
+
startDateField?: string;
|
|
29
|
+
/** Campo que mapeia a data de término */
|
|
30
|
+
endDateField?: string;
|
|
31
|
+
/** Campo que mapeia o progresso (0-100) */
|
|
32
|
+
progressField?: string;
|
|
33
|
+
/** Campo que mapeia dependências (array de IDs) */
|
|
34
|
+
dependenciesField?: string;
|
|
35
|
+
/** Campo que mapeia o tipo ('task' | 'milestone' | 'project') */
|
|
36
|
+
typeField?: string;
|
|
37
|
+
/** Campo que mapeia o ID do registro pai */
|
|
38
|
+
parentIdField?: string;
|
|
39
|
+
/** Tarefas standalone (quando não se usa dataSource) */
|
|
40
|
+
tasks?: Task[];
|
|
41
|
+
/** Modo de visualização do gantt */
|
|
42
|
+
viewMode?: ViewMode;
|
|
43
|
+
/** Locale para formatação de datas */
|
|
44
|
+
locale?: string;
|
|
45
|
+
/** Largura das células da lista de tarefas */
|
|
46
|
+
listCellWidth?: string;
|
|
47
|
+
/** Largura de cada coluna do gantt */
|
|
48
|
+
columnWidth?: number;
|
|
49
|
+
/** Altura de cada linha */
|
|
50
|
+
rowHeight?: number;
|
|
51
|
+
/** Percentual de preenchimento da barra */
|
|
52
|
+
barFill?: number;
|
|
53
|
+
/** Exibe a lista de tarefas à esquerda */
|
|
54
|
+
showTaskList?: boolean;
|
|
55
|
+
/** Callback quando uma tarefa é alterada (data arrastada) */
|
|
56
|
+
onTaskChange?: (task: T) => void;
|
|
57
|
+
/** Callback quando uma tarefa é deletada */
|
|
58
|
+
onTaskDelete?: (task: T) => void;
|
|
59
|
+
/** Callback quando o progresso de uma tarefa é alterado */
|
|
60
|
+
onProgressChange?: (task: T, progress: number) => void;
|
|
61
|
+
/** Callback ao dar duplo clique em uma tarefa */
|
|
62
|
+
onDoubleClick?: (task: T) => void;
|
|
63
|
+
/** Callback ao clicar em uma tarefa */
|
|
64
|
+
onClick?: (task: T) => void;
|
|
65
|
+
/** Callback ao selecionar/deselecionar uma tarefa */
|
|
66
|
+
onSelect?: (task: T, isSelected: boolean) => void;
|
|
67
|
+
/** Label do componente (usado com Input.Wrapper) */
|
|
68
|
+
label?: React.ReactNode;
|
|
69
|
+
/** Descrição do componente (usado com Input.Wrapper) */
|
|
70
|
+
description?: React.ReactNode;
|
|
71
|
+
/** Somente leitura — desabilita edição por drag */
|
|
72
|
+
readOnly?: boolean;
|
|
73
|
+
/** Estilo inline do container */
|
|
74
|
+
style?: React.CSSProperties;
|
|
75
|
+
/** Classe CSS do container */
|
|
76
|
+
className?: string;
|
|
77
|
+
/** Largura do container */
|
|
78
|
+
width?: string | number;
|
|
79
|
+
/** Altura do container */
|
|
80
|
+
height?: string | number;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Obtém valor de um campo usando notação de ponto.
|
|
85
|
+
*/
|
|
86
|
+
function getFieldValue(record: any, field: string, defaultValue?: any): any {
|
|
87
|
+
return get(record, field, defaultValue);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Converte registros do DataSource para o formato Task do gantt-task-react.
|
|
92
|
+
*/
|
|
93
|
+
function recordsToTasks<T>(
|
|
94
|
+
records: T[],
|
|
95
|
+
idField: string,
|
|
96
|
+
nameField: string,
|
|
97
|
+
startDateField: string,
|
|
98
|
+
endDateField: string,
|
|
99
|
+
progressField: string,
|
|
100
|
+
dependenciesField: string,
|
|
101
|
+
typeField: string,
|
|
102
|
+
parentIdField: string,
|
|
103
|
+
): Task[] {
|
|
104
|
+
return records.map((record: any) => {
|
|
105
|
+
const id = String(getFieldValue(record, idField, ''));
|
|
106
|
+
const name = getFieldValue(record, nameField, '');
|
|
107
|
+
const startRaw = getFieldValue(record, startDateField);
|
|
108
|
+
const endRaw = getFieldValue(record, endDateField);
|
|
109
|
+
const progress = getFieldValue(record, progressField, 0);
|
|
110
|
+
const deps: string[] = (getFieldValue(record, dependenciesField) || []).map(String);
|
|
111
|
+
const type = getFieldValue(record, typeField, 'task') as 'task' | 'milestone' | 'project';
|
|
112
|
+
const parentId = getFieldValue(record, parentIdField);
|
|
113
|
+
|
|
114
|
+
const start = startRaw instanceof Date ? startRaw : new Date(startRaw);
|
|
115
|
+
const end = endRaw instanceof Date ? endRaw : new Date(endRaw);
|
|
116
|
+
|
|
117
|
+
const task: Task = {
|
|
118
|
+
id,
|
|
119
|
+
name,
|
|
120
|
+
start,
|
|
121
|
+
end,
|
|
122
|
+
progress: typeof progress === 'number' ? progress : Number(progress) || 0,
|
|
123
|
+
dependencies: deps,
|
|
124
|
+
type,
|
|
125
|
+
project: parentId != null ? String(parentId) : undefined,
|
|
126
|
+
isDisabled: false,
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
return task;
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Encontra o registro original pelo id da Task.
|
|
135
|
+
*/
|
|
136
|
+
function findRecordByTaskId<T>(
|
|
137
|
+
records: T[],
|
|
138
|
+
taskId: string,
|
|
139
|
+
idField: string,
|
|
140
|
+
): T | undefined {
|
|
141
|
+
return records.find((r: any) => String(getFieldValue(r, idField)) === taskId);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function ArchbaseGanttInner<T = any, ID = any>(
|
|
145
|
+
props: ArchbaseGanttProps<T, ID>,
|
|
146
|
+
ref: React.Ref<HTMLDivElement>,
|
|
147
|
+
) {
|
|
148
|
+
const {
|
|
149
|
+
dataSource,
|
|
150
|
+
idField = 'id',
|
|
151
|
+
nameField = 'name',
|
|
152
|
+
startDateField = 'startDate',
|
|
153
|
+
endDateField = 'endDate',
|
|
154
|
+
progressField = 'progress',
|
|
155
|
+
dependenciesField = 'dependencies',
|
|
156
|
+
typeField = 'type',
|
|
157
|
+
parentIdField = 'parentId',
|
|
158
|
+
tasks: standaloneTasks,
|
|
159
|
+
viewMode = ViewMode.Day,
|
|
160
|
+
locale = 'pt-BR',
|
|
161
|
+
listCellWidth = '155px',
|
|
162
|
+
columnWidth = 65,
|
|
163
|
+
rowHeight = 50,
|
|
164
|
+
barFill = 60,
|
|
165
|
+
showTaskList = true,
|
|
166
|
+
onTaskChange,
|
|
167
|
+
onTaskDelete,
|
|
168
|
+
onProgressChange,
|
|
169
|
+
onDoubleClick,
|
|
170
|
+
onClick,
|
|
171
|
+
onSelect,
|
|
172
|
+
label,
|
|
173
|
+
description,
|
|
174
|
+
readOnly = false,
|
|
175
|
+
style,
|
|
176
|
+
className,
|
|
177
|
+
width,
|
|
178
|
+
height,
|
|
179
|
+
} = props;
|
|
180
|
+
|
|
181
|
+
const theme = useMantineTheme();
|
|
182
|
+
const colorScheme = useComputedColorScheme('light');
|
|
183
|
+
const isDark = colorScheme === 'dark';
|
|
184
|
+
|
|
185
|
+
const [version, setVersion] = useState(0);
|
|
186
|
+
const [selectedTaskId, setSelectedTaskId] = useState<string | undefined>(undefined);
|
|
187
|
+
const recordsRef = useRef<T[]>([]);
|
|
188
|
+
|
|
189
|
+
// Obtém registros do DataSource
|
|
190
|
+
const getRecords = useCallback((): T[] => {
|
|
191
|
+
if (dataSource && dataSource.isActive() && !dataSource.isEmpty()) {
|
|
192
|
+
return dataSource.browseRecords();
|
|
193
|
+
}
|
|
194
|
+
return [];
|
|
195
|
+
}, [dataSource]);
|
|
196
|
+
|
|
197
|
+
// Atualiza referência de registros
|
|
198
|
+
useEffect(() => {
|
|
199
|
+
recordsRef.current = getRecords();
|
|
200
|
+
}, [getRecords, version]);
|
|
201
|
+
|
|
202
|
+
// Listener para eventos do DataSource
|
|
203
|
+
const handleDataSourceEvent = useCallback(
|
|
204
|
+
(event: DataSourceEvent<T>) => {
|
|
205
|
+
switch (event.type) {
|
|
206
|
+
case DataSourceEventNames.dataChanged:
|
|
207
|
+
case DataSourceEventNames.afterInsert:
|
|
208
|
+
case DataSourceEventNames.afterRemove:
|
|
209
|
+
case DataSourceEventNames.afterSave:
|
|
210
|
+
case DataSourceEventNames.afterCancel:
|
|
211
|
+
case DataSourceEventNames.refreshData:
|
|
212
|
+
setVersion((v) => v + 1);
|
|
213
|
+
break;
|
|
214
|
+
case DataSourceEventNames.afterScroll: {
|
|
215
|
+
const current = dataSource?.getCurrentRecord();
|
|
216
|
+
if (current) {
|
|
217
|
+
const id = String(getFieldValue(current, idField));
|
|
218
|
+
setSelectedTaskId(id);
|
|
219
|
+
}
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
[dataSource, idField],
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
if (dataSource) {
|
|
228
|
+
useArchbaseDataSourceListener<T>({
|
|
229
|
+
dataSource,
|
|
230
|
+
listener: handleDataSourceEvent,
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Converte registros para Tasks
|
|
235
|
+
const ganttTasks: Task[] = useMemo(() => {
|
|
236
|
+
if (standaloneTasks && standaloneTasks.length > 0) {
|
|
237
|
+
return standaloneTasks;
|
|
238
|
+
}
|
|
239
|
+
const records = getRecords();
|
|
240
|
+
if (records.length === 0) {
|
|
241
|
+
return [];
|
|
242
|
+
}
|
|
243
|
+
return recordsToTasks(
|
|
244
|
+
records,
|
|
245
|
+
idField,
|
|
246
|
+
nameField,
|
|
247
|
+
startDateField,
|
|
248
|
+
endDateField,
|
|
249
|
+
progressField,
|
|
250
|
+
dependenciesField,
|
|
251
|
+
typeField,
|
|
252
|
+
parentIdField,
|
|
253
|
+
);
|
|
254
|
+
}, [
|
|
255
|
+
standaloneTasks,
|
|
256
|
+
getRecords,
|
|
257
|
+
version,
|
|
258
|
+
idField,
|
|
259
|
+
nameField,
|
|
260
|
+
startDateField,
|
|
261
|
+
endDateField,
|
|
262
|
+
progressField,
|
|
263
|
+
dependenciesField,
|
|
264
|
+
typeField,
|
|
265
|
+
parentIdField,
|
|
266
|
+
]);
|
|
267
|
+
|
|
268
|
+
// Handler: data da tarefa alterada via drag
|
|
269
|
+
const handleDateChange = useCallback(
|
|
270
|
+
(task: Task) => {
|
|
271
|
+
if (readOnly) return;
|
|
272
|
+
if (dataSource) {
|
|
273
|
+
const records = recordsRef.current;
|
|
274
|
+
const record = findRecordByTaskId(records, task.id, idField);
|
|
275
|
+
if (record && dataSource.isEditing()) {
|
|
276
|
+
// Navega até o registro e atualiza os campos
|
|
277
|
+
dataSource.gotoRecordByData(record);
|
|
278
|
+
dataSource.setFieldValue(startDateField, task.start);
|
|
279
|
+
dataSource.setFieldValue(endDateField, task.end);
|
|
280
|
+
}
|
|
281
|
+
if (record && onTaskChange) {
|
|
282
|
+
onTaskChange(record);
|
|
283
|
+
}
|
|
284
|
+
} else if (onTaskChange) {
|
|
285
|
+
onTaskChange(task as unknown as T);
|
|
286
|
+
}
|
|
287
|
+
},
|
|
288
|
+
[readOnly, dataSource, idField, startDateField, endDateField, onTaskChange],
|
|
289
|
+
);
|
|
290
|
+
|
|
291
|
+
// Handler: progresso alterado via drag
|
|
292
|
+
const handleProgressChange = useCallback(
|
|
293
|
+
(task: Task) => {
|
|
294
|
+
if (readOnly) return;
|
|
295
|
+
if (dataSource) {
|
|
296
|
+
const records = recordsRef.current;
|
|
297
|
+
const record = findRecordByTaskId(records, task.id, idField);
|
|
298
|
+
if (record && dataSource.isEditing()) {
|
|
299
|
+
dataSource.gotoRecordByData(record);
|
|
300
|
+
dataSource.setFieldValue(progressField, task.progress);
|
|
301
|
+
}
|
|
302
|
+
if (record && onProgressChange) {
|
|
303
|
+
onProgressChange(record, task.progress);
|
|
304
|
+
}
|
|
305
|
+
} else if (onProgressChange) {
|
|
306
|
+
onProgressChange(task as unknown as T, task.progress);
|
|
307
|
+
}
|
|
308
|
+
},
|
|
309
|
+
[readOnly, dataSource, idField, progressField, onProgressChange],
|
|
310
|
+
);
|
|
311
|
+
|
|
312
|
+
// Handler: tarefa deletada
|
|
313
|
+
const handleDelete = useCallback(
|
|
314
|
+
(task: Task): boolean => {
|
|
315
|
+
if (readOnly) return false;
|
|
316
|
+
if (dataSource) {
|
|
317
|
+
const records = recordsRef.current;
|
|
318
|
+
const record = findRecordByTaskId(records, task.id, idField);
|
|
319
|
+
if (record && onTaskDelete) {
|
|
320
|
+
onTaskDelete(record);
|
|
321
|
+
}
|
|
322
|
+
} else if (onTaskDelete) {
|
|
323
|
+
onTaskDelete(task as unknown as T);
|
|
324
|
+
}
|
|
325
|
+
return true;
|
|
326
|
+
},
|
|
327
|
+
[readOnly, dataSource, idField, onTaskDelete],
|
|
328
|
+
);
|
|
329
|
+
|
|
330
|
+
// Handler: duplo clique
|
|
331
|
+
const handleDoubleClick = useCallback(
|
|
332
|
+
(task: Task) => {
|
|
333
|
+
if (dataSource) {
|
|
334
|
+
const records = recordsRef.current;
|
|
335
|
+
const record = findRecordByTaskId(records, task.id, idField);
|
|
336
|
+
if (record) {
|
|
337
|
+
dataSource.gotoRecordByData(record);
|
|
338
|
+
if (onDoubleClick) onDoubleClick(record);
|
|
339
|
+
}
|
|
340
|
+
} else if (onDoubleClick) {
|
|
341
|
+
onDoubleClick(task as unknown as T);
|
|
342
|
+
}
|
|
343
|
+
},
|
|
344
|
+
[dataSource, idField, onDoubleClick],
|
|
345
|
+
);
|
|
346
|
+
|
|
347
|
+
// Handler: clique
|
|
348
|
+
const handleClick = useCallback(
|
|
349
|
+
(task: Task) => {
|
|
350
|
+
if (dataSource) {
|
|
351
|
+
const records = recordsRef.current;
|
|
352
|
+
const record = findRecordByTaskId(records, task.id, idField);
|
|
353
|
+
if (record) {
|
|
354
|
+
dataSource.gotoRecordByData(record);
|
|
355
|
+
if (onClick) onClick(record);
|
|
356
|
+
}
|
|
357
|
+
} else if (onClick) {
|
|
358
|
+
onClick(task as unknown as T);
|
|
359
|
+
}
|
|
360
|
+
},
|
|
361
|
+
[dataSource, idField, onClick],
|
|
362
|
+
);
|
|
363
|
+
|
|
364
|
+
// Handler: seleção
|
|
365
|
+
const handleSelect = useCallback(
|
|
366
|
+
(task: Task, isSelected: boolean) => {
|
|
367
|
+
if (dataSource) {
|
|
368
|
+
const records = recordsRef.current;
|
|
369
|
+
const record = findRecordByTaskId(records, task.id, idField);
|
|
370
|
+
if (record) {
|
|
371
|
+
if (isSelected) {
|
|
372
|
+
dataSource.gotoRecordByData(record);
|
|
373
|
+
}
|
|
374
|
+
if (onSelect) onSelect(record, isSelected);
|
|
375
|
+
}
|
|
376
|
+
} else if (onSelect) {
|
|
377
|
+
onSelect(task as unknown as T, isSelected);
|
|
378
|
+
}
|
|
379
|
+
},
|
|
380
|
+
[dataSource, idField, onSelect],
|
|
381
|
+
);
|
|
382
|
+
|
|
383
|
+
// Cores para dark mode
|
|
384
|
+
const ganttColors = useMemo(() => {
|
|
385
|
+
if (isDark) {
|
|
386
|
+
return {
|
|
387
|
+
barProgressColor: theme.colors.blue[6],
|
|
388
|
+
barProgressSelectedColor: theme.colors.blue[4],
|
|
389
|
+
barBackgroundColor: theme.colors.dark[4],
|
|
390
|
+
barBackgroundSelectedColor: theme.colors.dark[3],
|
|
391
|
+
projectProgressColor: theme.colors.teal[6],
|
|
392
|
+
projectProgressSelectedColor: theme.colors.teal[4],
|
|
393
|
+
projectBackgroundColor: theme.colors.dark[5],
|
|
394
|
+
projectBackgroundSelectedColor: theme.colors.dark[4],
|
|
395
|
+
milestoneBackgroundColor: theme.colors.orange[6],
|
|
396
|
+
milestoneBackgroundSelectedColor: theme.colors.orange[4],
|
|
397
|
+
arrowColor: theme.colors.gray[5],
|
|
398
|
+
fontFamily: theme.fontFamily,
|
|
399
|
+
todayColor: 'rgba(252, 196, 25, 0.15)',
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
return {
|
|
403
|
+
barProgressColor: theme.colors.blue[5],
|
|
404
|
+
barProgressSelectedColor: theme.colors.blue[7],
|
|
405
|
+
barBackgroundColor: theme.colors.gray[3],
|
|
406
|
+
barBackgroundSelectedColor: theme.colors.gray[4],
|
|
407
|
+
projectProgressColor: theme.colors.teal[5],
|
|
408
|
+
projectProgressSelectedColor: theme.colors.teal[7],
|
|
409
|
+
projectBackgroundColor: theme.colors.gray[4],
|
|
410
|
+
projectBackgroundSelectedColor: theme.colors.gray[5],
|
|
411
|
+
milestoneBackgroundColor: theme.colors.orange[5],
|
|
412
|
+
milestoneBackgroundSelectedColor: theme.colors.orange[7],
|
|
413
|
+
arrowColor: theme.colors.gray[6],
|
|
414
|
+
fontFamily: theme.fontFamily,
|
|
415
|
+
todayColor: 'rgba(252, 196, 25, 0.2)',
|
|
416
|
+
};
|
|
417
|
+
}, [isDark, theme]);
|
|
418
|
+
|
|
419
|
+
// Se não houver tarefas, mostra mensagem ou vazio
|
|
420
|
+
if (ganttTasks.length === 0) {
|
|
421
|
+
const emptyContent = (
|
|
422
|
+
<Box
|
|
423
|
+
ref={ref}
|
|
424
|
+
className={className}
|
|
425
|
+
style={{
|
|
426
|
+
width: width ?? '100%',
|
|
427
|
+
height: height ?? 300,
|
|
428
|
+
display: 'flex',
|
|
429
|
+
alignItems: 'center',
|
|
430
|
+
justifyContent: 'center',
|
|
431
|
+
color: isDark ? theme.colors.dark[2] : theme.colors.gray[5],
|
|
432
|
+
...style,
|
|
433
|
+
}}
|
|
434
|
+
>
|
|
435
|
+
Nenhuma tarefa para exibir
|
|
436
|
+
</Box>
|
|
437
|
+
);
|
|
438
|
+
|
|
439
|
+
if (label || description) {
|
|
440
|
+
return (
|
|
441
|
+
<Input.Wrapper label={label} description={description}>
|
|
442
|
+
{emptyContent}
|
|
443
|
+
</Input.Wrapper>
|
|
444
|
+
);
|
|
445
|
+
}
|
|
446
|
+
return emptyContent;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
const ganttElement = (
|
|
450
|
+
<Box
|
|
451
|
+
ref={ref}
|
|
452
|
+
className={className}
|
|
453
|
+
style={{
|
|
454
|
+
width: width ?? '100%',
|
|
455
|
+
height: height ?? 'auto',
|
|
456
|
+
overflow: 'auto',
|
|
457
|
+
...style,
|
|
458
|
+
}}
|
|
459
|
+
>
|
|
460
|
+
<Gantt
|
|
461
|
+
tasks={ganttTasks}
|
|
462
|
+
viewMode={viewMode}
|
|
463
|
+
locale={locale}
|
|
464
|
+
listCellWidth={showTaskList ? listCellWidth : ''}
|
|
465
|
+
columnWidth={columnWidth}
|
|
466
|
+
rowHeight={rowHeight}
|
|
467
|
+
barFill={barFill}
|
|
468
|
+
onDateChange={readOnly ? undefined : handleDateChange}
|
|
469
|
+
onProgressChange={readOnly ? undefined : handleProgressChange}
|
|
470
|
+
onDelete={readOnly ? undefined : handleDelete}
|
|
471
|
+
onDoubleClick={handleDoubleClick}
|
|
472
|
+
onClick={handleClick}
|
|
473
|
+
onSelect={handleSelect}
|
|
474
|
+
{...ganttColors}
|
|
475
|
+
/>
|
|
476
|
+
</Box>
|
|
477
|
+
);
|
|
478
|
+
|
|
479
|
+
if (label || description) {
|
|
480
|
+
return (
|
|
481
|
+
<Input.Wrapper label={label} description={description}>
|
|
482
|
+
{ganttElement}
|
|
483
|
+
</Input.Wrapper>
|
|
484
|
+
);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
return ganttElement;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
export const ArchbaseGantt = React.forwardRef(ArchbaseGanttInner) as <T = any, ID = any>(
|
|
491
|
+
props: ArchbaseGanttProps<T, ID> & { ref?: React.Ref<HTMLDivElement> },
|
|
492
|
+
) => React.ReactElement | null;
|
|
493
|
+
|
|
494
|
+
(ArchbaseGantt as any).displayName = 'ArchbaseGantt';
|