@stonecrop/atable 0.11.10 → 0.12.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/README.md +58 -52
- package/dist/assets/index.css +1 -1
- package/dist/atable.d.ts +83 -188
- package/dist/atable.js +1089 -1049
- package/dist/atable.js.map +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -0
- package/dist/src/schemaToColumns.d.ts +16 -0
- package/dist/src/schemaToColumns.d.ts.map +1 -0
- package/dist/src/schemaToColumns.js +20 -0
- package/dist/src/stores/table.d.ts +42 -42
- package/dist/src/stores/table.d.ts.map +1 -1
- package/dist/src/stores/table.js +10 -1
- package/dist/src/types/index.d.ts +27 -146
- package/dist/src/types/index.d.ts.map +1 -1
- package/package.json +6 -5
- package/src/components/AGanttCell.vue +3 -1
- package/src/components/ARowActions.vue +3 -1
- package/src/components/ATable.vue +15 -5
- package/src/components/ATableColumnFilter.vue +30 -8
- package/src/index.ts +1 -0
- package/src/schemaToColumns.ts +24 -0
- package/src/stores/table.ts +10 -1
- package/src/types/index.ts +59 -197
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="column-filter">
|
|
3
3
|
<input
|
|
4
|
-
v-if="
|
|
4
|
+
v-if="resolvedFilterType === 'text'"
|
|
5
5
|
v-model="filterValue"
|
|
6
6
|
type="text"
|
|
7
7
|
class="filter-input"
|
|
8
8
|
@input="updateFilter(filterValue)" />
|
|
9
9
|
|
|
10
10
|
<input
|
|
11
|
-
v-else-if="
|
|
11
|
+
v-else-if="resolvedFilterType === 'number'"
|
|
12
12
|
v-model="filterValue"
|
|
13
13
|
type="number"
|
|
14
14
|
class="filter-input"
|
|
15
15
|
@input="updateFilter(filterValue)" />
|
|
16
16
|
|
|
17
|
-
<label v-else-if="
|
|
17
|
+
<label v-else-if="resolvedFilterType === 'checkbox'" class="checkbox-filter">
|
|
18
18
|
<input v-model="filterValue" type="checkbox" class="filter-checkbox" @change="updateFilter(filterValue)" />
|
|
19
19
|
<span>{{ column.label }}</span>
|
|
20
20
|
</label>
|
|
21
21
|
|
|
22
22
|
<select
|
|
23
|
-
v-else-if="
|
|
23
|
+
v-else-if="resolvedFilterType === 'select'"
|
|
24
24
|
v-model="filterValue"
|
|
25
25
|
class="filter-select"
|
|
26
26
|
@change="updateFilter(filterValue)">
|
|
@@ -31,13 +31,13 @@
|
|
|
31
31
|
</select>
|
|
32
32
|
|
|
33
33
|
<input
|
|
34
|
-
v-else-if="
|
|
34
|
+
v-else-if="resolvedFilterType === 'date'"
|
|
35
35
|
v-model="filterValue"
|
|
36
36
|
type="date"
|
|
37
37
|
class="filter-input"
|
|
38
38
|
@change="updateFilter(filterValue)" />
|
|
39
39
|
|
|
40
|
-
<div v-else-if="
|
|
40
|
+
<div v-else-if="resolvedFilterType === 'dateRange'" class="date-range-filter">
|
|
41
41
|
<input
|
|
42
42
|
v-model="dateFilter.startValue"
|
|
43
43
|
type="date"
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
|
|
54
54
|
<component
|
|
55
55
|
:is="column.filterComponent"
|
|
56
|
-
v-else-if="
|
|
56
|
+
v-else-if="resolvedFilterType === 'component' && column.filterComponent"
|
|
57
57
|
:value="filterValue"
|
|
58
58
|
:column="column"
|
|
59
59
|
:col-index="colIndex"
|
|
@@ -81,6 +81,28 @@ const dateFilter = reactive({
|
|
|
81
81
|
endValue: '',
|
|
82
82
|
})
|
|
83
83
|
|
|
84
|
+
const resolvedFilterType = computed(() => {
|
|
85
|
+
if (column.filterType) return column.filterType
|
|
86
|
+
switch (column.fieldtype) {
|
|
87
|
+
case 'Check':
|
|
88
|
+
return 'checkbox'
|
|
89
|
+
case 'Date':
|
|
90
|
+
return 'date'
|
|
91
|
+
case 'Datetime':
|
|
92
|
+
return 'dateRange'
|
|
93
|
+
case 'Select':
|
|
94
|
+
return 'select'
|
|
95
|
+
case 'Int':
|
|
96
|
+
case 'Float':
|
|
97
|
+
case 'Currency':
|
|
98
|
+
case 'Decimal':
|
|
99
|
+
case 'Quantity':
|
|
100
|
+
return 'number'
|
|
101
|
+
default:
|
|
102
|
+
return 'text'
|
|
103
|
+
}
|
|
104
|
+
})
|
|
105
|
+
|
|
84
106
|
const getSelectOptions = (column: TableColumn): any[] => {
|
|
85
107
|
if (column.filterOptions) return column.filterOptions
|
|
86
108
|
|
|
@@ -105,7 +127,7 @@ const hasActiveFilter = computed(() => {
|
|
|
105
127
|
|
|
106
128
|
// Filter actions
|
|
107
129
|
const updateFilter = (value: any) => {
|
|
108
|
-
if (!value &&
|
|
130
|
+
if (!value && resolvedFilterType.value !== 'checkbox') {
|
|
109
131
|
store.clearFilter(colIndex)
|
|
110
132
|
filterValue.value = ''
|
|
111
133
|
} else {
|
package/src/index.ts
CHANGED
|
@@ -13,6 +13,7 @@ import ATableModal from './components/ATableModal.vue'
|
|
|
13
13
|
export { createTableStore } from './stores/table'
|
|
14
14
|
export type { FilterState, FilterStateRecord } from './stores/table'
|
|
15
15
|
export type * from './types'
|
|
16
|
+
export { schemaToColumns } from './schemaToColumns'
|
|
16
17
|
|
|
17
18
|
// Icon exports
|
|
18
19
|
export { AddIcon, DeleteIcon, DuplicateIcon, InsertAboveIcon, InsertBelowIcon, MoveIcon, actionIcons } from './icons'
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ColumnSchema } from '@stonecrop/schema'
|
|
2
|
+
|
|
3
|
+
import type { TableColumn } from './types'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Convert an array of doctype field descriptors into ATable column definitions.
|
|
7
|
+
*
|
|
8
|
+
* Fields are excluded when:
|
|
9
|
+
* - `hidden: true` — field should not be visible in any view
|
|
10
|
+
* - no `fieldtype` — non-scalar entry (nested table or fieldset), has no column equivalent
|
|
11
|
+
*
|
|
12
|
+
* `fieldname` is renamed to `name`; `hidden` is stripped. All other `ColumnSchema` properties
|
|
13
|
+
* spread through automatically.
|
|
14
|
+
*
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
17
|
+
export function schemaToColumns(schema: ColumnSchema[]): TableColumn[] {
|
|
18
|
+
return schema
|
|
19
|
+
.filter(f => !f.hidden && f.fieldtype)
|
|
20
|
+
.map(({ fieldname, hidden: _hidden, ...rest }) => ({
|
|
21
|
+
name: fieldname,
|
|
22
|
+
...rest,
|
|
23
|
+
}))
|
|
24
|
+
}
|
package/src/stores/table.ts
CHANGED
|
@@ -425,7 +425,16 @@ export const createTableStore = (initData: {
|
|
|
425
425
|
const format = column.format
|
|
426
426
|
|
|
427
427
|
if (!format) {
|
|
428
|
-
|
|
428
|
+
switch (column.fieldtype) {
|
|
429
|
+
case 'Check':
|
|
430
|
+
return value ? '✓' : '✗'
|
|
431
|
+
case 'Date':
|
|
432
|
+
return value != null ? new Date(value as string).toLocaleDateString() : value
|
|
433
|
+
case 'Datetime':
|
|
434
|
+
return value != null ? new Date(value as string).toLocaleString() : value
|
|
435
|
+
default:
|
|
436
|
+
return value
|
|
437
|
+
}
|
|
429
438
|
}
|
|
430
439
|
|
|
431
440
|
if (typeof format === 'function') {
|
package/src/types/index.ts
CHANGED
|
@@ -1,191 +1,54 @@
|
|
|
1
1
|
import { useElementBounding } from '@vueuse/core'
|
|
2
2
|
import type { Ref, ShallowRef } from 'vue'
|
|
3
3
|
|
|
4
|
+
import type { ColumnSchema } from '@stonecrop/schema'
|
|
5
|
+
|
|
4
6
|
import { createTableStore } from '../stores/table'
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
|
-
*
|
|
9
|
+
* Runtime column definition for ATable.
|
|
10
|
+
*
|
|
11
|
+
* Extends `ColumnSchema` from `@stonecrop/schema` — all authoring properties (`label`, `fieldtype`, `width`,
|
|
12
|
+
* `pinned`, filter config, cell/modal component names, etc.) are inherited. The overrides
|
|
13
|
+
* below widen three properties for runtime use (live functions, broader alignment values)
|
|
14
|
+
* and add two runtime-only additions (`mask`, `originalIndex`).
|
|
15
|
+
*
|
|
16
|
+
* Schema-based callers should author columns as `ColumnSchema[]` (using `fieldname`) and
|
|
17
|
+
* pass them via ATable's `:schema` prop — `TableColumn` is the internal runtime type and
|
|
18
|
+
* callers working from a doctype schema never need to construct it directly.
|
|
8
19
|
* @public
|
|
9
20
|
*/
|
|
10
|
-
export interface TableColumn {
|
|
11
|
-
/**
|
|
12
|
-
* The key of the column. This is used to identify the column in the table.
|
|
13
|
-
*/
|
|
21
|
+
export interface TableColumn extends Omit<ColumnSchema, 'fieldname' | 'hidden' | 'format' | 'modalComponent'> {
|
|
22
|
+
/** Runtime column key. Corresponds to `fieldname` in `ColumnSchema`; populated by `schemaToColumns`. */
|
|
14
23
|
name: string
|
|
15
24
|
|
|
16
25
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* - `center` - center aligned
|
|
20
|
-
* - `right` - right aligned
|
|
21
|
-
* - `start` - aligned to the start of the column
|
|
22
|
-
* - `end` - aligned to the end of the column
|
|
23
|
-
*
|
|
24
|
-
* @defaultValue 'center'
|
|
25
|
-
*/
|
|
26
|
-
align?: CanvasTextAlign
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Control whether cells for the column is editable.
|
|
30
|
-
*
|
|
31
|
-
* @defaultValue false
|
|
32
|
-
*/
|
|
33
|
-
edit?: boolean
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* The label of the column. This is displayed in the table header.
|
|
37
|
-
*
|
|
38
|
-
* @defaultValue If no label is provided, a character will be assigned alphabetically,
|
|
39
|
-
* starting from 'A' for the first column, 'B' for the second column, and so on.
|
|
40
|
-
*/
|
|
41
|
-
label?: string
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* The semantic field type of the column. Uses the same StonecropFieldType enum as forms.
|
|
45
|
-
* Common values: 'Data', 'Text', 'Int', 'Float', 'Date', 'Select', 'Link', 'Check', etc.
|
|
46
|
-
*
|
|
47
|
-
* @public
|
|
48
|
-
*/
|
|
49
|
-
fieldtype?: string
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* The width of the column. This can be a number (in pixels) or a string (in CSS units).
|
|
53
|
-
*
|
|
54
|
-
* @defaultValue '40ch'
|
|
55
|
-
*/
|
|
56
|
-
width?: string
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Control whether the column should be pinned to the table.
|
|
60
|
-
*
|
|
61
|
-
* @defaultValue false
|
|
62
|
-
*/
|
|
63
|
-
pinned?: boolean
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Control whether the column can be resized by the user.
|
|
67
|
-
*
|
|
68
|
-
* @defaultValue false
|
|
69
|
-
*/
|
|
70
|
-
resizable?: boolean
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Control whether the column should be sortable.
|
|
74
|
-
*
|
|
75
|
-
* @defaultValue true
|
|
76
|
-
*/
|
|
77
|
-
sortable?: boolean
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Control whether the column should be filterable and define filter configuration.
|
|
81
|
-
*
|
|
82
|
-
* @defaultValue true
|
|
83
|
-
*/
|
|
84
|
-
filterable?: boolean
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* The type of filter for the column.
|
|
88
|
-
*
|
|
89
|
-
* @defaultValue 'text'
|
|
26
|
+
* Widens `ColumnSchema.format` (string-only) to also accept a live function at runtime.
|
|
27
|
+
* Serialized string functions are deserialized by the table store's `getFormattedValue`.
|
|
90
28
|
*/
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Options for select-type filters.
|
|
95
|
-
*/
|
|
96
|
-
filterOptions?: any[]
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Custom component for filtering.
|
|
100
|
-
*/
|
|
101
|
-
filterComponent?: string
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* The component to use to render the cell for the column. If not provided, the table will
|
|
105
|
-
* render the default `<td>` element.
|
|
106
|
-
*/
|
|
107
|
-
cellComponent?: string
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Additional properties to pass to the table's cell component.
|
|
111
|
-
*
|
|
112
|
-
* Only applicable if the `cellComponent` property is set for the column.
|
|
113
|
-
*/
|
|
114
|
-
cellComponentProps?: Record<string, any>
|
|
29
|
+
format?: string | ((value: any, context: CellContext) => string)
|
|
115
30
|
|
|
116
31
|
/**
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
* - `
|
|
121
|
-
* - `
|
|
122
|
-
*
|
|
123
|
-
* The function should return the name of the component to use for the modal.
|
|
124
|
-
*
|
|
125
|
-
* Additionally, the following properties will be automatically passed to the modal component:
|
|
126
|
-
* - `colIndex` - the column index of the current cell
|
|
127
|
-
* - `rowIndex` - the row index of the current cell
|
|
128
|
-
* - `store` - the table data store
|
|
32
|
+
* Widens `ColumnSchema.modalComponent` (string-only) to also accept a factory function.
|
|
33
|
+
* When a function is provided it receives the cell context and returns the component name.
|
|
34
|
+
* The cell context exposes:
|
|
35
|
+
* - `row` — the row object for the current cell
|
|
36
|
+
* - `column` — the column object for the current cell
|
|
37
|
+
* - `table` — the table object
|
|
129
38
|
*/
|
|
130
|
-
|
|
131
39
|
modalComponent?: string | ((context: CellContext) => string)
|
|
132
40
|
|
|
133
41
|
/**
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
* Only applicable if the `modalComponent` property is set for the column.
|
|
137
|
-
*/
|
|
138
|
-
modalComponentExtraProps?: Record<string, any>
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* The format function to use to format the value of the cell. This can either be a normal or stringified
|
|
142
|
-
* function that takes the value and the cell context and returns a string.
|
|
143
|
-
*/
|
|
144
|
-
format?: string | ((value: any, context: CellContext) => string)
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* The masking function to use to apply an input mask to the cell. This will accept an input value and
|
|
148
|
-
* return the masked value.
|
|
42
|
+
* Input mask applied to the cell value before display. Accepts a live function only —
|
|
43
|
+
* masks cannot be serialized to JSON so they are absent from `ColumnSchema`.
|
|
149
44
|
*/
|
|
150
45
|
mask?: (value: any) => any
|
|
151
46
|
|
|
152
47
|
/**
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
* Only applicable for Gantt tables.
|
|
156
|
-
*
|
|
157
|
-
* @defaultValue false
|
|
158
|
-
*/
|
|
159
|
-
isGantt?: boolean
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* The component to use to render the Gantt bar for the column.
|
|
163
|
-
*
|
|
164
|
-
* Only applicable for Gantt tables.
|
|
165
|
-
*
|
|
166
|
-
* @defaultValue 'AGanttCell'
|
|
167
|
-
*/
|
|
168
|
-
ganttComponent?: string
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* The colspan of the Gantt bar for the column. This determines how many columns
|
|
172
|
-
* the Gantt bar should span across.
|
|
173
|
-
*
|
|
174
|
-
* Only applicable for Gantt tables.
|
|
175
|
-
*
|
|
176
|
-
* @defaultValue The number of columns in the table, excluding any pinned columns.
|
|
48
|
+
* Runtime Gantt column index (excluding pinned columns). Set automatically during
|
|
49
|
+
* Gantt table rendering.
|
|
177
50
|
*/
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* The original column index for the Gantt bar, excluding any pinned columns.
|
|
182
|
-
* This is evaluated automatically while rendering the table.
|
|
183
|
-
*
|
|
184
|
-
* Only applicable for Gantt tables.
|
|
185
|
-
*
|
|
186
|
-
* @defaultValue 0
|
|
187
|
-
*/
|
|
188
|
-
originalIndex?: number
|
|
51
|
+
readonly originalIndex?: number
|
|
189
52
|
}
|
|
190
53
|
|
|
191
54
|
/**
|
|
@@ -541,39 +404,38 @@ export interface GanttOptions {
|
|
|
541
404
|
* Gantt table drag event definition.
|
|
542
405
|
* @public
|
|
543
406
|
*/
|
|
544
|
-
export type GanttDragEvent =
|
|
407
|
+
export type GanttDragEvent = {
|
|
408
|
+
rowIndex: number
|
|
409
|
+
colIndex: number
|
|
410
|
+
delta: number
|
|
411
|
+
} & (
|
|
412
|
+
| {
|
|
413
|
+
type: 'bar'
|
|
414
|
+
oldStart: number
|
|
415
|
+
oldEnd: number
|
|
416
|
+
newStart: number
|
|
417
|
+
newEnd: number
|
|
418
|
+
colspan: number
|
|
419
|
+
}
|
|
420
|
+
| {
|
|
421
|
+
type: 'resize'
|
|
422
|
+
edge: 'start'
|
|
423
|
+
oldStart: number
|
|
424
|
+
newStart: number
|
|
425
|
+
end: number
|
|
426
|
+
oldColspan: number
|
|
427
|
+
newColspan: number
|
|
428
|
+
}
|
|
545
429
|
| {
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
newEnd: number
|
|
556
|
-
colspan: number
|
|
557
|
-
}
|
|
558
|
-
| {
|
|
559
|
-
type: 'resize'
|
|
560
|
-
edge: 'start'
|
|
561
|
-
oldStart: number
|
|
562
|
-
newStart: number
|
|
563
|
-
end: number
|
|
564
|
-
oldColspan: number
|
|
565
|
-
newColspan: number
|
|
566
|
-
}
|
|
567
|
-
| {
|
|
568
|
-
type: 'resize'
|
|
569
|
-
edge: 'end'
|
|
570
|
-
oldEnd: number
|
|
571
|
-
newEnd: number
|
|
572
|
-
start: number
|
|
573
|
-
oldColspan: number
|
|
574
|
-
newColspan: number
|
|
575
|
-
}
|
|
576
|
-
)
|
|
430
|
+
type: 'resize'
|
|
431
|
+
edge: 'end'
|
|
432
|
+
oldEnd: number
|
|
433
|
+
newEnd: number
|
|
434
|
+
start: number
|
|
435
|
+
oldColspan: number
|
|
436
|
+
newColspan: number
|
|
437
|
+
}
|
|
438
|
+
)
|
|
577
439
|
|
|
578
440
|
/**
|
|
579
441
|
* Table modal definition.
|