@stonecrop/atable 0.4.22 → 0.4.24
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/assets/index.css +1 -1
- package/dist/atable.d.ts +511 -25
- package/dist/atable.js +1327 -1060
- package/dist/atable.js.map +1 -1
- package/dist/atable.umd.cjs +2 -2
- package/dist/atable.umd.cjs.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/stores/table.d.ts +370 -16
- package/dist/src/stores/table.d.ts.map +1 -1
- package/dist/src/types/index.d.ts +138 -10
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/stores/table.js +116 -14
- package/package.json +3 -3
- package/src/components/AGanttCell.vue +444 -170
- package/src/components/AGanttConnection.vue +164 -0
- package/src/components/ARow.vue +1 -1
- package/src/components/ATable.vue +107 -77
- package/src/components/ATableHeader.vue +1 -1
- package/src/index.ts +4 -0
- package/src/stores/table.ts +134 -14
- package/src/types/index.ts +159 -10
package/src/stores/table.ts
CHANGED
|
@@ -3,6 +3,9 @@ import { type CSSProperties, computed, ref } from 'vue'
|
|
|
3
3
|
|
|
4
4
|
import type {
|
|
5
5
|
CellContext,
|
|
6
|
+
ConnectionHandle,
|
|
7
|
+
ConnectionPath,
|
|
8
|
+
GanttBarInfo,
|
|
6
9
|
GanttDragEvent,
|
|
7
10
|
TableColumn,
|
|
8
11
|
TableConfig,
|
|
@@ -56,12 +59,15 @@ export const createTableStore = (initData: {
|
|
|
56
59
|
|
|
57
60
|
// TODO: (typing) is this type correct for the parent set?
|
|
58
61
|
const parents = new Set<string | number>()
|
|
59
|
-
for (let rowIndex = rows.value.length
|
|
62
|
+
for (let rowIndex = 0; rowIndex < rows.value.length; rowIndex++) {
|
|
60
63
|
const row = rows.value[rowIndex]
|
|
61
|
-
if (row.parent) {
|
|
64
|
+
if (row.parent !== null && row.parent !== undefined) {
|
|
62
65
|
parents.add(row.parent)
|
|
63
66
|
}
|
|
67
|
+
}
|
|
64
68
|
|
|
69
|
+
for (let rowIndex = 0; rowIndex < rows.value.length; rowIndex++) {
|
|
70
|
+
const row = rows.value[rowIndex]
|
|
65
71
|
defaultDisplay[rowIndex] = {
|
|
66
72
|
childrenOpen: false,
|
|
67
73
|
expanded: false,
|
|
@@ -85,9 +91,14 @@ export const createTableStore = (initData: {
|
|
|
85
91
|
const display = ref(createDisplayObject(initData.display))
|
|
86
92
|
const modal = ref<TableModal>(initData.modal || { visible: false })
|
|
87
93
|
const updates = ref<Record<string, string>>({})
|
|
94
|
+
const ganttBars = ref<GanttBarInfo[]>([])
|
|
95
|
+
const connectionHandles = ref<ConnectionHandle[]>([])
|
|
96
|
+
const connectionPaths = ref<ConnectionPath[]>([])
|
|
88
97
|
|
|
89
98
|
// getters
|
|
90
99
|
const hasPinnedColumns = computed(() => columns.value.some(col => col.pinned))
|
|
100
|
+
const isGanttView = computed(() => config.value.view === 'gantt' || config.value.view === 'tree-gantt')
|
|
101
|
+
const isTreeView = computed(() => config.value.view === 'tree' || config.value.view === 'tree-gantt')
|
|
91
102
|
|
|
92
103
|
const numberedRowWidth = computed(() => {
|
|
93
104
|
const indent = Math.ceil(rows.value.length / 100 + 1)
|
|
@@ -95,7 +106,7 @@ export const createTableStore = (initData: {
|
|
|
95
106
|
})
|
|
96
107
|
|
|
97
108
|
const zeroColumn = computed(() =>
|
|
98
|
-
config.value.view ? ['list', 'tree', 'list-expansion'].includes(config.value.view) : false
|
|
109
|
+
config.value.view ? ['list', 'tree', 'tree-gantt', 'list-expansion'].includes(config.value.view) : false
|
|
99
110
|
)
|
|
100
111
|
|
|
101
112
|
// actions
|
|
@@ -109,7 +120,11 @@ export const createTableStore = (initData: {
|
|
|
109
120
|
}
|
|
110
121
|
|
|
111
122
|
table.value[index] = value
|
|
112
|
-
|
|
123
|
+
// Create a new row object to ensure reactivity
|
|
124
|
+
rows.value[rowIndex] = {
|
|
125
|
+
...rows.value[rowIndex],
|
|
126
|
+
[col.name]: value,
|
|
127
|
+
}
|
|
113
128
|
}
|
|
114
129
|
|
|
115
130
|
const setCellText = (colIndex: number, rowIndex: number, value: string) => {
|
|
@@ -154,32 +169,40 @@ export const createTableStore = (initData: {
|
|
|
154
169
|
|
|
155
170
|
const isRowGantt = (rowIndex: number) => {
|
|
156
171
|
const row = rows.value[rowIndex]
|
|
157
|
-
return
|
|
172
|
+
return isGanttView.value && row.gantt !== undefined
|
|
158
173
|
}
|
|
159
174
|
|
|
160
175
|
const isRowVisible = (rowIndex: number) => {
|
|
161
|
-
return
|
|
176
|
+
return !isTreeView.value || display.value[rowIndex].isRoot || display.value[rowIndex].open
|
|
162
177
|
}
|
|
163
178
|
|
|
164
179
|
const getRowExpandSymbol = (rowIndex: number) => {
|
|
165
|
-
if (config.value.view !== '
|
|
180
|
+
if (!isTreeView.value && config.value.view !== 'list-expansion') {
|
|
166
181
|
return ''
|
|
167
182
|
}
|
|
168
183
|
|
|
169
|
-
if (display.value[rowIndex].isRoot || display.value[rowIndex].isParent) {
|
|
170
|
-
return display.value[rowIndex].childrenOpen ? '
|
|
184
|
+
if (isTreeView.value && (display.value[rowIndex].isRoot || display.value[rowIndex].isParent)) {
|
|
185
|
+
return display.value[rowIndex].childrenOpen ? '▼' : '►'
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (config.value.view === 'list-expansion') {
|
|
189
|
+
return display.value[rowIndex].expanded ? '▼' : '►'
|
|
171
190
|
}
|
|
172
191
|
|
|
173
192
|
return ''
|
|
174
193
|
}
|
|
175
194
|
|
|
176
195
|
const toggleRowExpand = (rowIndex: number) => {
|
|
177
|
-
if (
|
|
196
|
+
if (isTreeView.value) {
|
|
178
197
|
display.value[rowIndex].childrenOpen = !display.value[rowIndex].childrenOpen
|
|
179
|
-
|
|
198
|
+
const isOpen = display.value[rowIndex].childrenOpen
|
|
199
|
+
|
|
200
|
+
for (let index = 0; index < rows.value.length; index++) {
|
|
180
201
|
if (display.value[index].parent === rowIndex) {
|
|
181
|
-
display.value[index].open =
|
|
182
|
-
if (
|
|
202
|
+
display.value[index].open = isOpen
|
|
203
|
+
if (!isOpen) {
|
|
204
|
+
// If we're closing, also close any children recursively
|
|
205
|
+
display.value[index].childrenOpen = false
|
|
183
206
|
toggleRowExpand(index)
|
|
184
207
|
}
|
|
185
208
|
}
|
|
@@ -255,11 +278,98 @@ export const createTableStore = (initData: {
|
|
|
255
278
|
}
|
|
256
279
|
}
|
|
257
280
|
|
|
281
|
+
const registerGanttBar = (barInfo: GanttBarInfo) => {
|
|
282
|
+
const existingIndex = ganttBars.value.findIndex(bar => bar.id === barInfo.id)
|
|
283
|
+
if (existingIndex >= 0) {
|
|
284
|
+
// @ts-expect-error TODO: for some reason, the IDE is expecting an unref'd value
|
|
285
|
+
ganttBars.value[existingIndex] = barInfo
|
|
286
|
+
} else {
|
|
287
|
+
// @ts-expect-error TODO: for some reason, the IDE is expecting an unref'd value
|
|
288
|
+
ganttBars.value.push(barInfo)
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const unregisterGanttBar = (barId: string) => {
|
|
293
|
+
const index = ganttBars.value.findIndex(bar => bar.id === barId)
|
|
294
|
+
if (index >= 0) {
|
|
295
|
+
ganttBars.value.splice(index, 1)
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const registerConnectionHandle = (handleInfo: ConnectionHandle) => {
|
|
300
|
+
const existingIndex = connectionHandles.value.findIndex(handle => handle.id === handleInfo.id)
|
|
301
|
+
if (existingIndex >= 0) {
|
|
302
|
+
// @ts-expect-error TODO: for some reason, the IDE is expecting an unref'd value
|
|
303
|
+
connectionHandles.value[existingIndex] = handleInfo
|
|
304
|
+
} else {
|
|
305
|
+
// @ts-expect-error TODO: for some reason, the IDE is expecting an unref'd value
|
|
306
|
+
connectionHandles.value.push(handleInfo)
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
const unregisterConnectionHandle = (handleId: string) => {
|
|
311
|
+
const index = connectionHandles.value.findIndex(handle => handle.id === handleId)
|
|
312
|
+
if (index >= 0) {
|
|
313
|
+
connectionHandles.value.splice(index, 1)
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const createConnection = (
|
|
318
|
+
fromHandleId: string,
|
|
319
|
+
toHandleId: string,
|
|
320
|
+
options?: { style?: ConnectionPath['style']; label?: string }
|
|
321
|
+
) => {
|
|
322
|
+
const fromHandle = connectionHandles.value.find(h => h.id === fromHandleId)
|
|
323
|
+
const toHandle = connectionHandles.value.find(h => h.id === toHandleId)
|
|
324
|
+
|
|
325
|
+
if (!fromHandle || !toHandle) {
|
|
326
|
+
console.warn('Cannot create connection: handle not found')
|
|
327
|
+
return null
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
const connection: ConnectionPath = {
|
|
331
|
+
id: `connection-${fromHandleId}-${toHandleId}`,
|
|
332
|
+
from: {
|
|
333
|
+
barId: fromHandle.barId,
|
|
334
|
+
side: fromHandle.side,
|
|
335
|
+
},
|
|
336
|
+
to: {
|
|
337
|
+
barId: toHandle.barId,
|
|
338
|
+
side: toHandle.side,
|
|
339
|
+
},
|
|
340
|
+
style: options?.style,
|
|
341
|
+
label: options?.label,
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
connectionPaths.value.push(connection)
|
|
345
|
+
return connection
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
const deleteConnection = (connectionId: string) => {
|
|
349
|
+
const index = connectionPaths.value.findIndex(conn => conn.id === connectionId)
|
|
350
|
+
if (index >= 0) {
|
|
351
|
+
connectionPaths.value.splice(index, 1)
|
|
352
|
+
return true
|
|
353
|
+
}
|
|
354
|
+
return false
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
const getConnectionsForBar = (barId: string) => {
|
|
358
|
+
return connectionPaths.value.filter(conn => conn.from.barId === barId || conn.to.barId === barId)
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
const getHandlesForBar = (barId: string) => {
|
|
362
|
+
return connectionHandles.value.filter(handle => handle.barId === barId)
|
|
363
|
+
}
|
|
364
|
+
|
|
258
365
|
return {
|
|
259
366
|
// state
|
|
260
367
|
columns,
|
|
261
368
|
config,
|
|
369
|
+
connectionHandles,
|
|
370
|
+
connectionPaths,
|
|
262
371
|
display,
|
|
372
|
+
ganttBars,
|
|
263
373
|
modal,
|
|
264
374
|
rows,
|
|
265
375
|
table,
|
|
@@ -267,23 +377,33 @@ export const createTableStore = (initData: {
|
|
|
267
377
|
|
|
268
378
|
// getters
|
|
269
379
|
hasPinnedColumns,
|
|
380
|
+
isGanttView,
|
|
381
|
+
isTreeView,
|
|
270
382
|
numberedRowWidth,
|
|
271
383
|
zeroColumn,
|
|
272
384
|
|
|
273
385
|
// actions
|
|
274
386
|
closeModal,
|
|
387
|
+
createConnection,
|
|
388
|
+
deleteConnection,
|
|
275
389
|
getCellData,
|
|
276
390
|
getCellDisplayValue,
|
|
391
|
+
getConnectionsForBar,
|
|
277
392
|
getFormattedValue,
|
|
393
|
+
getHandlesForBar,
|
|
278
394
|
getHeaderCellStyle,
|
|
279
|
-
resizeColumn,
|
|
280
395
|
getIndent,
|
|
281
396
|
getRowExpandSymbol,
|
|
282
397
|
isRowGantt,
|
|
283
398
|
isRowVisible,
|
|
399
|
+
registerConnectionHandle,
|
|
400
|
+
registerGanttBar,
|
|
401
|
+
resizeColumn,
|
|
284
402
|
setCellData,
|
|
285
403
|
setCellText,
|
|
286
404
|
toggleRowExpand,
|
|
405
|
+
unregisterConnectionHandle,
|
|
406
|
+
unregisterGanttBar,
|
|
287
407
|
updateGanttBar,
|
|
288
408
|
}
|
|
289
409
|
})
|
package/src/types/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useElementBounding } from '@vueuse/core'
|
|
2
|
+
import type { Ref, ShallowRef } from 'vue'
|
|
2
3
|
|
|
3
4
|
import { createTableStore } from '../stores/table'
|
|
4
5
|
|
|
@@ -133,8 +134,8 @@ export interface TableColumn {
|
|
|
133
134
|
ganttComponent?: string
|
|
134
135
|
|
|
135
136
|
/**
|
|
136
|
-
* The colspan of the Gantt
|
|
137
|
-
* the Gantt
|
|
137
|
+
* The colspan of the Gantt bar for the column. This determines how many columns
|
|
138
|
+
* the Gantt bar should span across.
|
|
138
139
|
*
|
|
139
140
|
* Only applicable for Gantt tables.
|
|
140
141
|
*
|
|
@@ -143,8 +144,8 @@ export interface TableColumn {
|
|
|
143
144
|
colspan?: number
|
|
144
145
|
|
|
145
146
|
/**
|
|
146
|
-
* The
|
|
147
|
-
* evaluated automatically while rendering the table.
|
|
147
|
+
* The original column index for the Gantt bar, excluding any pinned columns.
|
|
148
|
+
* This is evaluated automatically while rendering the table.
|
|
148
149
|
*
|
|
149
150
|
* Only applicable for Gantt tables.
|
|
150
151
|
*
|
|
@@ -185,8 +186,10 @@ export interface TableConfig {
|
|
|
185
186
|
* - `list` - row numbers are displayed in the table
|
|
186
187
|
* - `list-expansion` - carets are displayed in the number column that expand/collapse the row inline
|
|
187
188
|
* - `tree` - carets are displayed in the number column that expand/collapse grouped rows
|
|
189
|
+
* - `gantt` - view that allows specific rows to be displayed with Gantt functionality
|
|
190
|
+
* - `tree-gantt` - similar to `gantt`, but allows for tree functionality as well
|
|
188
191
|
*/
|
|
189
|
-
view?: 'uncounted' | 'list' | 'list-expansion' | 'tree' | 'gantt'
|
|
192
|
+
view?: 'uncounted' | 'list' | 'list-expansion' | 'tree' | 'gantt' | 'tree-gantt'
|
|
190
193
|
|
|
191
194
|
/**
|
|
192
195
|
* Control whether the table should be allowed to use the full width of its container.
|
|
@@ -303,29 +306,33 @@ export interface TableRow {
|
|
|
303
306
|
}
|
|
304
307
|
|
|
305
308
|
/**
|
|
306
|
-
*
|
|
309
|
+
* Gantt chart options for table rows.
|
|
307
310
|
* @public
|
|
308
311
|
*/
|
|
309
312
|
export interface GanttOptions {
|
|
310
313
|
/**
|
|
311
|
-
* The
|
|
314
|
+
* The color to be applied to the row's gantt bar.
|
|
315
|
+
*
|
|
316
|
+
* @defaultValue '#cccccc'
|
|
312
317
|
*/
|
|
313
318
|
color?: string
|
|
314
319
|
|
|
315
320
|
/**
|
|
316
321
|
* The starting column index for the gantt bar.
|
|
322
|
+
*
|
|
323
|
+
* @defaultValue 0
|
|
317
324
|
*/
|
|
318
325
|
startIndex?: number
|
|
319
326
|
|
|
320
327
|
/**
|
|
321
|
-
* The ending column index for the gantt bar. If
|
|
328
|
+
* The ending column index for the gantt bar. If endIndex and colspan are not provided,
|
|
322
329
|
* the bar will stretch to the end of the table.
|
|
323
330
|
*/
|
|
324
331
|
endIndex?: number
|
|
325
332
|
|
|
326
333
|
/**
|
|
327
|
-
* The length of the gantt bar. Useful when only the start index is provided.
|
|
328
|
-
* colspan and endIndex are not provided, the bar will stretch to the end of the table.
|
|
334
|
+
* The length of the gantt bar in columns. Useful when only the start index is provided.
|
|
335
|
+
* If colspan and endIndex are not provided, the bar will stretch to the end of the table.
|
|
329
336
|
*/
|
|
330
337
|
colspan?: number
|
|
331
338
|
}
|
|
@@ -468,3 +475,145 @@ export interface TableModalProps {
|
|
|
468
475
|
*/
|
|
469
476
|
store: ReturnType<typeof createTableStore>
|
|
470
477
|
}
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* Gantt bar information for VueFlow integration.
|
|
481
|
+
* @public
|
|
482
|
+
*/
|
|
483
|
+
export interface GanttBarInfo {
|
|
484
|
+
/**
|
|
485
|
+
* Unique identifier for the gantt bar.
|
|
486
|
+
*/
|
|
487
|
+
id: string
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* The row index of the gantt bar.
|
|
491
|
+
*/
|
|
492
|
+
rowIndex: number
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
* The primary column index of the gantt bar (typically the start index).
|
|
496
|
+
*/
|
|
497
|
+
colIndex: number
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* Starting column index of the gantt bar.
|
|
501
|
+
*/
|
|
502
|
+
startIndex: Ref<number>
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* Ending column index of the gantt bar.
|
|
506
|
+
*/
|
|
507
|
+
endIndex: Ref<number>
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* Color of the gantt bar.
|
|
511
|
+
*/
|
|
512
|
+
color: Ref<string>
|
|
513
|
+
|
|
514
|
+
/**
|
|
515
|
+
* The position of the gantt bar in the ATable component.
|
|
516
|
+
*/
|
|
517
|
+
position: {
|
|
518
|
+
x: ShallowRef<number>
|
|
519
|
+
y: ShallowRef<number>
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* Display label for the gantt bar.
|
|
524
|
+
*/
|
|
525
|
+
label?: string
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/**
|
|
529
|
+
* Connection handle information for gantt bar connections.
|
|
530
|
+
* @public
|
|
531
|
+
*/
|
|
532
|
+
export interface ConnectionHandle {
|
|
533
|
+
/**
|
|
534
|
+
* Unique identifier for the connection handle.
|
|
535
|
+
*/
|
|
536
|
+
id: string
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* The row index of the gantt bar this handle belongs to.
|
|
540
|
+
*/
|
|
541
|
+
rowIndex: number
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* The column index of the gantt bar this handle belongs to.
|
|
545
|
+
*/
|
|
546
|
+
colIndex: number
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* The side of the gantt bar where this handle is located.
|
|
550
|
+
*/
|
|
551
|
+
side: 'left' | 'right'
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* The position of the connection handle.
|
|
555
|
+
*/
|
|
556
|
+
position: {
|
|
557
|
+
x: ShallowRef<number>
|
|
558
|
+
y: ShallowRef<number>
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/**
|
|
562
|
+
* Whether the handle is currently visible (on hover).
|
|
563
|
+
*/
|
|
564
|
+
visible: Ref<boolean>
|
|
565
|
+
|
|
566
|
+
/**
|
|
567
|
+
* Reference to the gantt bar this handle belongs to.
|
|
568
|
+
*/
|
|
569
|
+
barId: string
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* Connection path between two gantt bars.
|
|
574
|
+
* @public
|
|
575
|
+
*/
|
|
576
|
+
export interface ConnectionPath {
|
|
577
|
+
/**
|
|
578
|
+
* Unique identifier for the connection path.
|
|
579
|
+
*/
|
|
580
|
+
id: string
|
|
581
|
+
|
|
582
|
+
/**
|
|
583
|
+
* The source connection handle.
|
|
584
|
+
*/
|
|
585
|
+
from: {
|
|
586
|
+
barId: string
|
|
587
|
+
side: 'left' | 'right'
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
/**
|
|
591
|
+
* The target connection handle.
|
|
592
|
+
*/
|
|
593
|
+
to: {
|
|
594
|
+
barId: string
|
|
595
|
+
side: 'left' | 'right'
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
/**
|
|
599
|
+
* Optional styling for the connection path.
|
|
600
|
+
*/
|
|
601
|
+
style?: {
|
|
602
|
+
color?: string
|
|
603
|
+
width?: number
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* Optional label for the connection.
|
|
608
|
+
*/
|
|
609
|
+
label?: string
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
/**
|
|
613
|
+
* Connection event for handling connection creation/deletion.
|
|
614
|
+
* @public
|
|
615
|
+
*/
|
|
616
|
+
export type ConnectionEvent = {
|
|
617
|
+
type: 'create' | 'delete'
|
|
618
|
+
connection: ConnectionPath
|
|
619
|
+
}
|