@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.
Files changed (168) hide show
  1. package/dist/buttons/ArchbaseSpeedDial.d.ts +59 -0
  2. package/dist/buttons/index.d.ts +2 -0
  3. package/dist/charts/ArchbaseArcGauge.d.ts +55 -0
  4. package/dist/charts/ArchbaseGantt.d.ts +70 -0
  5. package/dist/charts/ArchbaseLinearGauge.d.ts +55 -0
  6. package/dist/charts/ArchbaseResourceTimeline.d.ts +61 -0
  7. package/dist/charts/ArchbaseSparkline.d.ts +45 -0
  8. package/dist/charts/index.d.ts +10 -0
  9. package/dist/containers/ArchbaseExpansionPanel.d.ts +60 -0
  10. package/dist/containers/ArchbaseFloatingPanel.d.ts +91 -0
  11. package/dist/containers/index.d.ts +4 -0
  12. package/dist/datagrid/export/ArchbaseDataGridExcelExport.d.ts +67 -0
  13. package/dist/datagrid/export/index.d.ts +2 -0
  14. package/dist/datagrid/index.d.ts +1 -0
  15. package/dist/display/ArchbaseAnimationWrapper.d.ts +73 -0
  16. package/dist/display/ArchbaseBarcodeGenerator.d.ts +50 -0
  17. package/dist/display/ArchbaseCarousel.d.ts +100 -0
  18. package/dist/display/ArchbaseCodeViewer.d.ts +63 -0
  19. package/dist/display/ArchbaseDiffViewer.d.ts +41 -0
  20. package/dist/display/ArchbaseJsonTree.d.ts +34 -0
  21. package/dist/display/ArchbaseLightbox.d.ts +89 -0
  22. package/dist/display/ArchbaseMarquee.d.ts +46 -0
  23. package/dist/display/ArchbasePhotoAlbum.d.ts +58 -0
  24. package/dist/display/ArchbaseQRCode.d.ts +44 -0
  25. package/dist/display/ArchbaseTooltipRich.d.ts +82 -0
  26. package/dist/display/ArchbaseVirtualList.d.ts +116 -0
  27. package/dist/display/index.d.ts +24 -0
  28. package/dist/editors/ArchbaseAIPromptInput.d.ts +69 -0
  29. package/dist/editors/ArchbaseAsyncMultiSelect.d.ts +1 -1
  30. package/dist/editors/ArchbaseAsyncSelect.d.ts +1 -1
  31. package/dist/editors/ArchbaseBarcodeScanner.d.ts +63 -0
  32. package/dist/editors/ArchbaseCepInput.d.ts +26 -0
  33. package/dist/editors/ArchbaseColorGradientPicker.d.ts +80 -0
  34. package/dist/editors/ArchbaseCpfCnpjInput.d.ts +21 -0
  35. package/dist/editors/ArchbaseCurrencyInput.d.ts +25 -0
  36. package/dist/editors/ArchbaseDualListbox.d.ts +61 -0
  37. package/dist/editors/ArchbaseInPlaceEditor.d.ts +67 -0
  38. package/dist/editors/ArchbaseLightGrid.d.ts +56 -0
  39. package/dist/editors/ArchbaseMentionInput.d.ts +75 -0
  40. package/dist/editors/ArchbaseMultiEmail.d.ts +53 -0
  41. package/dist/editors/ArchbaseMultiViewCalendar.d.ts +47 -0
  42. package/dist/editors/ArchbaseNumberStepper.d.ts +66 -0
  43. package/dist/editors/ArchbaseOTPInput.d.ts +27 -0
  44. package/dist/editors/ArchbasePhoneInput.d.ts +52 -0
  45. package/dist/editors/ArchbaseRangeSlider.d.ts +22 -0
  46. package/dist/editors/ArchbaseSignaturePad.d.ts +60 -0
  47. package/dist/editors/ArchbaseSpeechToTextInput.d.ts +106 -0
  48. package/dist/editors/ArchbaseSpreadsheet.d.ts +56 -0
  49. package/dist/editors/ArchbaseTagInput.d.ts +55 -0
  50. package/dist/editors/index.d.ts +40 -0
  51. package/dist/feedback/ArchbaseChunkProgressBar.d.ts +35 -0
  52. package/dist/feedback/ArchbaseRipple.d.ts +43 -0
  53. package/dist/feedback/ArchbaseSkeleton.d.ts +115 -0
  54. package/dist/feedback/index.d.ts +6 -0
  55. package/dist/filters/ArchbaseColumnSelector.d.ts +38 -0
  56. package/dist/filters/index.d.ts +2 -0
  57. package/dist/forms/ArchbaseFieldArray.d.ts +80 -0
  58. package/dist/forms/ArchbaseFormWizard.d.ts +73 -0
  59. package/dist/forms/ArchbaseStepper.d.ts +51 -0
  60. package/dist/forms/index.d.ts +8 -0
  61. package/dist/forms/useArchbaseFormWizard.d.ts +74 -0
  62. package/dist/hooks/index.d.ts +2 -0
  63. package/dist/hooks/useArchbaseConfirm.d.ts +59 -0
  64. package/dist/image/editor/index.d.ts +43 -4
  65. package/dist/image/index.d.ts +1 -0
  66. package/dist/index.css +1 -1
  67. package/dist/index.d.ts +1 -0
  68. package/dist/index.js +22510 -13820
  69. package/dist/list/ArchbaseTreeList.d.ts +76 -0
  70. package/dist/list/index.d.ts +2 -0
  71. package/dist/navigation/ArchbaseActionSheet.d.ts +70 -0
  72. package/dist/navigation/ArchbaseAppBar.d.ts +63 -0
  73. package/dist/navigation/ArchbaseBottomNavigation.d.ts +61 -0
  74. package/dist/navigation/ArchbaseContextMenu.d.ts +76 -0
  75. package/dist/navigation/ArchbaseKeyboardShortcuts.d.ts +85 -0
  76. package/dist/navigation/ArchbaseSpotlight.d.ts +69 -0
  77. package/dist/navigation/index.d.ts +12 -0
  78. package/dist/notification/ArchbaseNotificationCenter.d.ts +56 -0
  79. package/dist/notification/index.d.ts +2 -0
  80. package/dist/onboarding/ArchbaseOnboardingTour.d.ts +27 -76
  81. package/dist/viewers/ArchbaseDocViewer.d.ts +40 -0
  82. package/dist/viewers/ArchbasePdfBuilder.d.ts +53 -0
  83. package/dist/viewers/ArchbaseXmlViewer.d.ts +36 -0
  84. package/dist/viewers/index.d.ts +6 -0
  85. package/package.json +41 -18
  86. package/src/buttons/ArchbaseSpeedDial.tsx +282 -0
  87. package/src/buttons/index.ts +3 -0
  88. package/src/charts/ArchbaseArcGauge.tsx +325 -0
  89. package/src/charts/ArchbaseGantt.tsx +494 -0
  90. package/src/charts/ArchbaseLinearGauge.tsx +288 -0
  91. package/src/charts/ArchbaseResourceTimeline.tsx +433 -0
  92. package/src/charts/ArchbaseSparkline.tsx +193 -0
  93. package/src/charts/index.ts +20 -1
  94. package/src/containers/ArchbaseExpansionPanel.tsx +208 -0
  95. package/src/containers/ArchbaseFloatingPanel.tsx +448 -0
  96. package/src/containers/index.ts +17 -0
  97. package/src/datagrid/components/pagination/grid-pagination.tsx +2 -2
  98. package/src/datagrid/export/ArchbaseDataGridExcelExport.tsx +293 -0
  99. package/src/datagrid/export/index.ts +8 -0
  100. package/src/datagrid/index.tsx +2 -0
  101. package/src/display/ArchbaseAnimationWrapper.tsx +272 -0
  102. package/src/display/ArchbaseBarcodeGenerator.tsx +303 -0
  103. package/src/display/ArchbaseCarousel.tsx +679 -0
  104. package/src/display/ArchbaseCodeViewer.tsx +271 -0
  105. package/src/display/ArchbaseDiffViewer.tsx +108 -0
  106. package/src/display/ArchbaseJsonTree.tsx +150 -0
  107. package/src/display/ArchbaseLightbox.tsx +279 -0
  108. package/src/display/ArchbaseMarquee.tsx +268 -0
  109. package/src/display/ArchbasePhotoAlbum.tsx +415 -0
  110. package/src/display/ArchbaseQRCode.tsx +137 -0
  111. package/src/display/ArchbaseTooltipRich.tsx +317 -0
  112. package/src/display/ArchbaseVirtualList.tsx +618 -0
  113. package/src/display/index.ts +94 -1
  114. package/src/editors/ArchbaseAIPromptInput.tsx +432 -0
  115. package/src/editors/ArchbaseBarcodeScanner.tsx +570 -0
  116. package/src/editors/ArchbaseCepInput.tsx +173 -0
  117. package/src/editors/ArchbaseColorGradientPicker.tsx +460 -0
  118. package/src/editors/ArchbaseCpfCnpjInput.tsx +193 -0
  119. package/src/editors/ArchbaseCurrencyInput.tsx +100 -0
  120. package/src/editors/ArchbaseDualListbox.tsx +671 -0
  121. package/src/editors/ArchbaseInPlaceEditor.tsx +406 -0
  122. package/src/editors/ArchbaseLightGrid.tsx +538 -0
  123. package/src/editors/ArchbaseMentionInput.tsx +384 -0
  124. package/src/editors/ArchbaseMultiEmail.tsx +367 -0
  125. package/src/editors/ArchbaseMultiViewCalendar.tsx +439 -0
  126. package/src/editors/ArchbaseNumberStepper.tsx +219 -0
  127. package/src/editors/ArchbaseOTPInput.tsx +133 -0
  128. package/src/editors/ArchbaseOperationHoursEditor.tsx +1 -1
  129. package/src/editors/ArchbasePhoneInput.tsx +355 -0
  130. package/src/editors/ArchbaseRangeSlider.tsx +109 -0
  131. package/src/editors/ArchbaseSignaturePad.tsx +425 -0
  132. package/src/editors/ArchbaseSpeechToTextInput.tsx +444 -0
  133. package/src/editors/ArchbaseSpreadsheet.tsx +388 -0
  134. package/src/editors/ArchbaseTagInput.tsx +326 -0
  135. package/src/editors/index.tsx +92 -0
  136. package/src/feedback/ArchbaseChunkProgressBar.tsx +156 -0
  137. package/src/feedback/ArchbaseRipple.tsx +278 -0
  138. package/src/feedback/ArchbaseSkeleton.tsx +419 -0
  139. package/src/feedback/index.ts +22 -1
  140. package/src/filters/ArchbaseColumnSelector.tsx +268 -0
  141. package/src/filters/index.ts +2 -0
  142. package/src/forms/ArchbaseFieldArray.tsx +305 -0
  143. package/src/forms/ArchbaseFormWizard.tsx +284 -0
  144. package/src/forms/ArchbaseStepper.tsx +137 -0
  145. package/src/forms/index.ts +24 -2
  146. package/src/forms/useArchbaseFormWizard.ts +283 -0
  147. package/src/hooks/index.ts +12 -0
  148. package/src/hooks/useArchbaseConfirm.ts +293 -0
  149. package/src/image/editor/functions/image-processing.ts +5 -0
  150. package/src/image/editor/index.tsx +305 -391
  151. package/src/image/index.ts +1 -0
  152. package/src/index.ts +3 -0
  153. package/src/list/ArchbaseTreeList.tsx +422 -0
  154. package/src/list/index.ts +3 -0
  155. package/src/navigation/ArchbaseActionSheet.tsx +301 -0
  156. package/src/navigation/ArchbaseAppBar.tsx +233 -0
  157. package/src/navigation/ArchbaseBottomNavigation.tsx +243 -0
  158. package/src/navigation/ArchbaseContextMenu.tsx +298 -0
  159. package/src/navigation/ArchbaseKeyboardShortcuts.tsx +472 -0
  160. package/src/navigation/ArchbaseSpotlight.tsx +483 -0
  161. package/src/navigation/index.ts +48 -1
  162. package/src/notification/ArchbaseNotificationCenter.tsx +502 -0
  163. package/src/notification/index.ts +2 -0
  164. package/src/onboarding/ArchbaseOnboardingTour.tsx +229 -102
  165. package/src/viewers/ArchbaseDocViewer.tsx +584 -0
  166. package/src/viewers/ArchbasePdfBuilder.tsx +291 -0
  167. package/src/viewers/ArchbaseXmlViewer.tsx +142 -0
  168. 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';