@stonecrop/atable 0.13.4 → 0.13.6

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.
@@ -34,6 +34,107 @@ export interface FilterState {
34
34
  */
35
35
  export type FilterStateRecord = Record<number, FilterState>
36
36
 
37
+ function isNodeOpen(rowIndex: number, treeDisplay: TableDisplay[]): boolean {
38
+ const row = treeDisplay[rowIndex]
39
+ if (row.isRoot) {
40
+ return true // Root nodes are always open
41
+ }
42
+
43
+ if (row.parent === null || row.parent === undefined) {
44
+ return true
45
+ }
46
+
47
+ const parentIndex = row.parent
48
+ if (parentIndex < 0 || parentIndex >= treeDisplay.length) {
49
+ return false
50
+ }
51
+
52
+ const parent = treeDisplay[parentIndex]
53
+ // Node is open if parent's children are open AND parent itself is open
54
+ return (parent.childrenOpen || false) && isNodeOpen(parentIndex, treeDisplay)
55
+ }
56
+
57
+ function applyFilter(cellValue: any, filter: FilterState, column: TableColumn): boolean {
58
+ const filterType = column.filterType || 'text'
59
+ const value = filter.value
60
+
61
+ if (!value && filterType !== 'dateRange' && filterType !== 'checkbox') return true
62
+
63
+ switch (filterType) {
64
+ case 'text': {
65
+ const searchableText =
66
+ typeof cellValue === 'object' && cellValue !== null
67
+ ? Object.values(cellValue).join(' ')
68
+ : String(cellValue || '')
69
+ return searchableText.toLowerCase().includes(String(value).toLowerCase())
70
+ }
71
+
72
+ case 'number': {
73
+ const numValue = Number(cellValue)
74
+ const filterNum = Number(value)
75
+ return !isNaN(numValue) && !isNaN(filterNum) && numValue === filterNum
76
+ }
77
+
78
+ case 'select':
79
+ return cellValue === value
80
+
81
+ case 'checkbox':
82
+ // For checkbox filter, if checked (true), show only truthy values
83
+ // If unchecked (false/undefined), show all values
84
+ if (value === true) {
85
+ return !!cellValue
86
+ }
87
+ return true
88
+
89
+ case 'date': {
90
+ // Handle both timestamp numbers and date strings
91
+ let cellDate: Date
92
+ if (typeof cellValue === 'number') {
93
+ // Apply the same year transformation as in the format function
94
+ const originalDate = new Date(cellValue)
95
+ const currentYear = new Date().getFullYear()
96
+ cellDate = new Date(currentYear, originalDate.getMonth(), originalDate.getDate())
97
+ } else {
98
+ cellDate = new Date(String(cellValue))
99
+ }
100
+ const filterDate = new Date(String(value))
101
+ return cellDate.toDateString() === filterDate.toDateString()
102
+ }
103
+
104
+ case 'dateRange': {
105
+ const startValue = filter.startValue
106
+ const endValue = filter.endValue
107
+ if (!startValue && !endValue) return true
108
+
109
+ // Handle both timestamp numbers and date strings
110
+ let cellDateRange: Date
111
+ if (typeof cellValue === 'number') {
112
+ // Apply the same year transformation as in the format function
113
+ const originalDate = new Date(cellValue)
114
+ const currentYear = new Date().getFullYear()
115
+ cellDateRange = new Date(currentYear, originalDate.getMonth(), originalDate.getDate())
116
+ } else {
117
+ cellDateRange = new Date(String(cellValue))
118
+ }
119
+ if (startValue && cellDateRange < new Date(String(startValue))) return false
120
+ if (endValue && cellDateRange > new Date(String(endValue))) return false
121
+
122
+ return true
123
+ }
124
+
125
+ default:
126
+ return true
127
+ }
128
+ }
129
+
130
+ function getIndent(colIndex: number, indentLevel?: number): string {
131
+ if (indentLevel && colIndex === 0 && indentLevel > 0) {
132
+ return `${indentLevel}ch`
133
+ } else {
134
+ return 'inherit'
135
+ }
136
+ }
137
+
37
138
  /**
38
139
  * Create a table store
39
140
  * @param initData - Initial data for the table store
@@ -133,13 +234,13 @@ export const createTableStore = (initData: {
133
234
  const rowExpandStates = ref<Record<number, { childrenOpen?: boolean; expanded?: boolean }>>({})
134
235
 
135
236
  const table = computed(() => {
136
- const table: Record<string, any> = {}
237
+ const tableData: Record<string, any> = {}
137
238
  for (const [colIndex, column] of columns.value.entries()) {
138
239
  for (const [rowIndex, row] of rows.value.entries()) {
139
- table[`${colIndex}:${rowIndex}`] = row[column.name]
240
+ tableData[`${colIndex}:${rowIndex}`] = row[column.name]
140
241
  }
141
242
  }
142
- return table
243
+ return tableData
143
244
  })
144
245
 
145
246
  const display = computed({
@@ -164,25 +265,6 @@ export const createTableStore = (initData: {
164
265
  // Calculate 'open' property for tree view based on parent's childrenOpen state
165
266
  if (isTreeView.value) {
166
267
  // Helper function to check if all ancestors are open
167
- const isNodeOpen = (rowIndex: number, display: TableDisplay[]): boolean => {
168
- const row = display[rowIndex]
169
- if (row.isRoot) {
170
- return true // Root nodes are always open
171
- }
172
-
173
- if (row.parent === null || row.parent === undefined) {
174
- return true
175
- }
176
-
177
- const parentIndex = row.parent
178
- if (parentIndex < 0 || parentIndex >= display.length) {
179
- return false
180
- }
181
-
182
- const parent = display[parentIndex]
183
- // Node is open if parent's children are open AND parent itself is open
184
- return (parent.childrenOpen || false) && isNodeOpen(parentIndex, display)
185
- }
186
268
 
187
269
  for (let i = 0; i < baseDisplay.length; i++) {
188
270
  const row = baseDisplay[i]
@@ -291,7 +373,7 @@ export const createTableStore = (initData: {
291
373
  })
292
374
 
293
375
  // actions
294
- const getCellData = <T = any>(colIndex: number, rowIndex: number): T => table.value[`${colIndex}:${rowIndex}`]
376
+ const getCellData = (colIndex: number, rowIndex: number): any => table.value[`${colIndex}:${rowIndex}`]
295
377
  const setCellData = (colIndex: number, rowIndex: number, value: any) => {
296
378
  const index = `${colIndex}:${rowIndex}`
297
379
  const col = columns.value[colIndex]
@@ -431,9 +513,9 @@ export const createTableStore = (initData: {
431
513
  case 'Check':
432
514
  return value ? '✓' : '✗'
433
515
  case 'Date':
434
- return value != null ? new Date(value as string).toLocaleDateString() : value
516
+ return value != null ? new Date(String(value)).toLocaleDateString() : value
435
517
  case 'Datetime':
436
- return value != null ? new Date(value as string).toLocaleString() : value
518
+ return value != null ? new Date(String(value)).toLocaleString() : value
437
519
  default:
438
520
  return value
439
521
  }
@@ -443,7 +525,7 @@ export const createTableStore = (initData: {
443
525
  return format(value, { table: table.value, row, column })
444
526
  } else if (typeof format === 'string') {
445
527
  // parse format function from string
446
- // eslint-disable-next-line @typescript-eslint/no-implied-eval, @typescript-eslint/no-unsafe-call
528
+ // oxlint-disable-next-line @typescript-eslint/no-implied-eval
447
529
  const formatFn: (value: any, context?: CellContext) => string = Function(`"use strict";return (${format})`)()
448
530
  return formatFn(value, { table: table.value, row, column })
449
531
  }
@@ -461,14 +543,6 @@ export const createTableStore = (initData: {
461
543
  }
462
544
  }
463
545
 
464
- const getIndent = (colIndex: number, indentLevel?: number) => {
465
- if (indentLevel && colIndex === 0 && indentLevel > 0) {
466
- return `${indentLevel}ch`
467
- } else {
468
- return 'inherit'
469
- }
470
- }
471
-
472
546
  const updateGanttBar = (event: GanttDragEvent) => {
473
547
  // update the local gantt bar cache
474
548
  const ganttBar = rows.value[event.rowIndex]?.gantt
@@ -536,7 +610,6 @@ export const createTableStore = (initData: {
536
610
  const toHandle = connectionHandles.value.find(h => h.id === toHandleId)
537
611
 
538
612
  if (!fromHandle || !toHandle) {
539
- // eslint-disable-next-line no-console
540
613
  console.warn('Cannot create connection: handle not found')
541
614
  return null
542
615
  }
@@ -598,79 +671,6 @@ export const createTableStore = (initData: {
598
671
  // This ensures that sorting works on filtered data without modifying the original rows
599
672
  }
600
673
 
601
- const applyFilter = (cellValue: any, filter: FilterState, column: TableColumn): boolean => {
602
- const filterType = column.filterType || 'text'
603
- const value = filter.value
604
-
605
- if (!value && filterType !== 'dateRange' && filterType !== 'checkbox') return true
606
-
607
- switch (filterType) {
608
- case 'text': {
609
- const searchableText =
610
- typeof cellValue === 'object' && cellValue !== null
611
- ? Object.values(cellValue as Record<string, unknown>).join(' ')
612
- : String(cellValue || '')
613
- return searchableText.toLowerCase().includes(String(value).toLowerCase())
614
- }
615
-
616
- case 'number': {
617
- const numValue = Number(cellValue)
618
- const filterNum = Number(value)
619
- return !isNaN(numValue) && !isNaN(filterNum) && numValue === filterNum
620
- }
621
-
622
- case 'select':
623
- return cellValue === value
624
-
625
- case 'checkbox':
626
- // For checkbox filter, if checked (true), show only truthy values
627
- // If unchecked (false/undefined), show all values
628
- if (value === true) {
629
- return !!cellValue
630
- }
631
- return true
632
-
633
- case 'date': {
634
- // Handle both timestamp numbers and date strings
635
- let cellDate: Date
636
- if (typeof cellValue === 'number') {
637
- // Apply the same year transformation as in the format function
638
- const originalDate = new Date(cellValue)
639
- const currentYear = new Date().getFullYear()
640
- cellDate = new Date(currentYear, originalDate.getMonth(), originalDate.getDate())
641
- } else {
642
- cellDate = new Date(String(cellValue))
643
- }
644
- const filterDate = new Date(String(value))
645
- return cellDate.toDateString() === filterDate.toDateString()
646
- }
647
-
648
- case 'dateRange': {
649
- const startValue = filter.startValue
650
- const endValue = filter.endValue
651
- if (!startValue && !endValue) return true
652
-
653
- // Handle both timestamp numbers and date strings
654
- let cellDateRange: Date
655
- if (typeof cellValue === 'number') {
656
- // Apply the same year transformation as in the format function
657
- const originalDate = new Date(cellValue)
658
- const currentYear = new Date().getFullYear()
659
- cellDateRange = new Date(currentYear, originalDate.getMonth(), originalDate.getDate())
660
- } else {
661
- cellDateRange = new Date(String(cellValue))
662
- }
663
- if (startValue && cellDateRange < new Date(String(startValue))) return false
664
- if (endValue && cellDateRange > new Date(String(endValue))) return false
665
-
666
- return true
667
- }
668
-
669
- default:
670
- return true
671
- }
672
- }
673
-
674
674
  const setFilter = (colIndex: number, filter: FilterState) => {
675
675
  if (!filter.value && !filter.startValue && !filter.endValue) {
676
676
  // Remove filter if empty