@stonecrop/atable 0.30.0 → 0.32.0
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 +804 -1
- package/dist/atable.js +2809 -1944
- package/dist/atable.js.map +1 -1
- package/dist/src/components/ACell.vue.d.ts +17 -0
- package/dist/src/components/ACell.vue.d.ts.map +1 -0
- package/dist/src/components/AGanttCell.vue.d.ts +34 -0
- package/dist/src/components/AGanttCell.vue.d.ts.map +1 -0
- package/dist/src/components/AGanttConnection.vue.d.ts +13 -0
- package/dist/src/components/AGanttConnection.vue.d.ts.map +1 -0
- package/dist/src/components/ARow.vue.d.ts +2693 -0
- package/dist/src/components/ARow.vue.d.ts.map +1 -0
- package/dist/src/components/ARowActions.vue.d.ts +16 -0
- package/dist/src/components/ARowActions.vue.d.ts.map +1 -0
- package/dist/src/components/ATable.vue.d.ts +13358 -0
- package/dist/src/components/ATable.vue.d.ts.map +1 -0
- package/dist/src/components/ATableColumnFilter.vue.d.ts +11 -0
- package/dist/src/components/ATableColumnFilter.vue.d.ts.map +1 -0
- package/dist/src/components/ATableHeader.vue.d.ts +20 -0
- package/dist/src/components/ATableHeader.vue.d.ts.map +1 -0
- package/dist/src/components/ATableLoading.vue.d.ts +14 -0
- package/dist/src/components/ATableLoading.vue.d.ts.map +1 -0
- package/dist/src/components/ATableLoadingBar.vue.d.ts +14 -0
- package/dist/src/components/ATableLoadingBar.vue.d.ts.map +1 -0
- package/dist/src/components/ATableModal.vue.d.ts +18 -0
- package/dist/src/components/ATableModal.vue.d.ts.map +1 -0
- package/dist/src/components/ATablePaginationFooter.vue.d.ts +17 -0
- package/dist/src/components/ATablePaginationFooter.vue.d.ts.map +1 -0
- package/dist/src/icons/index.d.ts +14 -7
- package/dist/src/icons/index.d.ts.map +1 -1
- package/dist/{tsdoc-metadata.json → src/tsdoc-metadata.json} +1 -1
- package/dist/src/types/index.d.ts.map +1 -1
- package/package.json +35 -29
- package/dist/atable.d.ts +0 -3560
- package/dist/atable.tsbuildinfo +0 -1
- package/dist/icons/stonecrop-ui-icon-add.svg +0 -5
- package/dist/icons/stonecrop-ui-icon-delete.svg +0 -5
- package/dist/icons/stonecrop-ui-icon-duplicate.svg +0 -5
- package/dist/icons/stonecrop-ui-icon-insert-above.svg +0 -15
- package/dist/icons/stonecrop-ui-icon-insert-below.svg +0 -15
- package/dist/icons/stonecrop-ui-icon-move.svg +0 -4
- package/dist/icons/stonecrop-ui-icon-open.svg +0 -5
- package/dist/src/composables/table-pagination.js +0 -108
- package/dist/src/icons/index.js +0 -32
- package/dist/src/index.js +0 -33
- package/dist/src/linkSearchableText.js +0 -44
- package/dist/src/resolveFilterType.js +0 -27
- package/dist/src/schemaToColumns.js +0 -59
- package/dist/src/stores/table.js +0 -833
- package/dist/src/types/index.js +0 -0
- package/dist/src/utils.js +0 -39
- package/src/components/ACell.vue +0 -410
- package/src/components/AGanttCell.vue +0 -638
- package/src/components/AGanttConnection.vue +0 -164
- package/src/components/ARow.vue +0 -251
- package/src/components/ARowActions.vue +0 -407
- package/src/components/ATable.vue +0 -538
- package/src/components/ATableColumnFilter.vue +0 -216
- package/src/components/ATableHeader.vue +0 -141
- package/src/components/ATableLoading.vue +0 -86
- package/src/components/ATableLoadingBar.vue +0 -81
- package/src/components/ATableModal.vue +0 -52
- package/src/components/ATablePaginationFooter.vue +0 -100
- package/src/composables/table-pagination.ts +0 -172
- package/src/icons/index.ts +0 -38
- package/src/icons/stonecrop-ui-icon-add.svg +0 -5
- package/src/icons/stonecrop-ui-icon-delete.svg +0 -5
- package/src/icons/stonecrop-ui-icon-duplicate.svg +0 -5
- package/src/icons/stonecrop-ui-icon-insert-above.svg +0 -15
- package/src/icons/stonecrop-ui-icon-insert-below.svg +0 -15
- package/src/icons/stonecrop-ui-icon-move.svg +0 -4
- package/src/icons/stonecrop-ui-icon-open.svg +0 -5
- package/src/index.ts +0 -62
- package/src/linkSearchableText.ts +0 -42
- package/src/resolveFilterType.ts +0 -32
- package/src/schemaToColumns.ts +0 -67
- package/src/shims-vue.d.ts +0 -10
- package/src/stores/table.ts +0 -978
- package/src/types/index.ts +0 -794
- package/src/utils.ts +0 -40
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
import type { GetRecordsOptions, GetRecordsResult } from '@stonecrop/schema'
|
|
2
|
-
import { computed, nextTick, ref, toValue, watch, type MaybeRefOrGetter, type Ref } from 'vue'
|
|
3
|
-
|
|
4
|
-
import type { TableRow } from '../types'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* A table row after filter/sort, with its index in the held row list.
|
|
8
|
-
* @public
|
|
9
|
-
*/
|
|
10
|
-
export type FilteredTableRow = TableRow & { originalIndex: number }
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Options for {@link useTablePagination}.
|
|
14
|
-
* @public
|
|
15
|
-
*/
|
|
16
|
-
export interface UseTablePaginationOptions {
|
|
17
|
-
/** Rows after filter and sort — pagination is a window over this list, not part of filtering. */
|
|
18
|
-
rows: MaybeRefOrGetter<FilteredTableRow[]>
|
|
19
|
-
/** When set, slice the held rows into windows of this size. Omit to show the whole held list. */
|
|
20
|
-
pageSize?: MaybeRefOrGetter<number | undefined>
|
|
21
|
-
/** Fetch the next server page. Typed from schema so ATable need not import Stonecrop. */
|
|
22
|
-
getRecords?: (options?: GetRecordsOptions) => Promise<GetRecordsResult>
|
|
23
|
-
/** When this changes, refetch from offset 0. */
|
|
24
|
-
sourceKey?: MaybeRefOrGetter<string | undefined>
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Pagination state and controls returned by {@link useTablePagination}.
|
|
29
|
-
* @public
|
|
30
|
-
*/
|
|
31
|
-
export interface TablePagination {
|
|
32
|
-
visibleRows: Ref<FilteredTableRow[]>
|
|
33
|
-
hasPrev: Ref<boolean>
|
|
34
|
-
hasNext: Ref<boolean>
|
|
35
|
-
/** Whether the server reported more records beyond what has been fetched. */
|
|
36
|
-
hasMore: Ref<boolean>
|
|
37
|
-
loading: Ref<boolean>
|
|
38
|
-
next: () => Promise<void>
|
|
39
|
-
prev: () => void
|
|
40
|
-
/** Whether footer chrome should render. */
|
|
41
|
-
showFooter: Ref<boolean>
|
|
42
|
-
/** Whether another in-memory window exists before asking the server. */
|
|
43
|
-
hasLocalNext: Ref<boolean>
|
|
44
|
-
/** Rows currently held after filter/sort — useful for a completion summary. */
|
|
45
|
-
loadedCount: Ref<number>
|
|
46
|
-
/** True once the server reported a further page existed (multi-page fetch). */
|
|
47
|
-
hasEverHadMore: Ref<boolean>
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Window rows after filter/sort, and optionally walk {@link @stonecrop/schema#GetRecordsOptions} for the next page.
|
|
52
|
-
* Pagination is not a filter — pass already-filtered rows.
|
|
53
|
-
* @public
|
|
54
|
-
*/
|
|
55
|
-
export function useTablePagination(options: UseTablePaginationOptions): TablePagination {
|
|
56
|
-
const heldRows = computed(() => toValue(options.rows))
|
|
57
|
-
const pageSize = computed(() => toValue(options.pageSize))
|
|
58
|
-
const sourceKey = computed(() => toValue(options.sourceKey))
|
|
59
|
-
|
|
60
|
-
const windowIndex = ref(0)
|
|
61
|
-
const loading = ref(false)
|
|
62
|
-
const serverHasMore = ref(false)
|
|
63
|
-
const hasEverHadMore = ref(false)
|
|
64
|
-
const lastFetchOffset = ref(0)
|
|
65
|
-
const lastPageLength = ref(0)
|
|
66
|
-
const loadedCount = computed(() => heldRows.value.length)
|
|
67
|
-
|
|
68
|
-
const effectivePageSize = computed(() => {
|
|
69
|
-
const size = pageSize.value
|
|
70
|
-
if (size != null && size > 0) {
|
|
71
|
-
return size
|
|
72
|
-
}
|
|
73
|
-
// No pageSize: one window over everything held (server list or full child table).
|
|
74
|
-
const count = heldRows.value.length
|
|
75
|
-
return count > 0 ? count : 1
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
const windowCount = computed(() => Math.max(1, Math.ceil(heldRows.value.length / effectivePageSize.value)))
|
|
79
|
-
|
|
80
|
-
const visibleRows = computed(() => {
|
|
81
|
-
const start = windowIndex.value * effectivePageSize.value
|
|
82
|
-
return heldRows.value.slice(start, start + effectivePageSize.value)
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
const hasLocalNext = computed(() => windowIndex.value < windowCount.value - 1)
|
|
86
|
-
const hasPrev = computed(() => windowIndex.value > 0)
|
|
87
|
-
const hasNext = computed(() => hasLocalNext.value || (Boolean(options.getRecords) && serverHasMore.value))
|
|
88
|
-
const hasMore = computed(() => serverHasMore.value)
|
|
89
|
-
|
|
90
|
-
const showFooter = computed(() => {
|
|
91
|
-
if (options.getRecords) {
|
|
92
|
-
// Keep the footer after the last "Load more" so completion is visible, not silent.
|
|
93
|
-
return serverHasMore.value || hasPrev.value || loading.value || (hasEverHadMore.value && !serverHasMore.value)
|
|
94
|
-
}
|
|
95
|
-
const size = pageSize.value
|
|
96
|
-
return size != null && size > 0 && heldRows.value.length > size
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
const resetWindow = () => {
|
|
100
|
-
windowIndex.value = 0
|
|
101
|
-
hasEverHadMore.value = false
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const fetchFromServer = async (fetchOptions?: GetRecordsOptions) => {
|
|
105
|
-
if (!options.getRecords) {
|
|
106
|
-
return
|
|
107
|
-
}
|
|
108
|
-
loading.value = true
|
|
109
|
-
try {
|
|
110
|
-
const result = await options.getRecords(fetchOptions)
|
|
111
|
-
serverHasMore.value = result.hasMore
|
|
112
|
-
if (result.hasMore) {
|
|
113
|
-
hasEverHadMore.value = true
|
|
114
|
-
}
|
|
115
|
-
lastFetchOffset.value = fetchOptions?.offset ?? 0
|
|
116
|
-
lastPageLength.value = result.data.length
|
|
117
|
-
} finally {
|
|
118
|
-
loading.value = false
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
watch(
|
|
123
|
-
() => sourceKey.value,
|
|
124
|
-
() => {
|
|
125
|
-
resetWindow()
|
|
126
|
-
if (options.getRecords) {
|
|
127
|
-
void fetchFromServer()
|
|
128
|
-
}
|
|
129
|
-
},
|
|
130
|
-
{ immediate: true }
|
|
131
|
-
)
|
|
132
|
-
|
|
133
|
-
watch(heldRows, () => {
|
|
134
|
-
// Shrinking the held set can leave the window past the end.
|
|
135
|
-
if (windowIndex.value >= windowCount.value) {
|
|
136
|
-
windowIndex.value = Math.max(0, windowCount.value - 1)
|
|
137
|
-
}
|
|
138
|
-
})
|
|
139
|
-
|
|
140
|
-
const next = async () => {
|
|
141
|
-
if (hasLocalNext.value) {
|
|
142
|
-
windowIndex.value += 1
|
|
143
|
-
return
|
|
144
|
-
}
|
|
145
|
-
if (options.getRecords && serverHasMore.value) {
|
|
146
|
-
await fetchFromServer({ offset: lastFetchOffset.value + lastPageLength.value })
|
|
147
|
-
await nextTick()
|
|
148
|
-
// Parent/HST grows rows; show the newly appended tail.
|
|
149
|
-
windowIndex.value = Math.max(0, windowCount.value - 1)
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
const prev = () => {
|
|
154
|
-
if (windowIndex.value > 0) {
|
|
155
|
-
windowIndex.value -= 1
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
return {
|
|
160
|
-
visibleRows,
|
|
161
|
-
hasPrev,
|
|
162
|
-
hasNext,
|
|
163
|
-
hasMore,
|
|
164
|
-
loading,
|
|
165
|
-
next,
|
|
166
|
-
prev,
|
|
167
|
-
showFooter,
|
|
168
|
-
hasLocalNext,
|
|
169
|
-
loadedCount,
|
|
170
|
-
hasEverHadMore,
|
|
171
|
-
}
|
|
172
|
-
}
|
package/src/icons/index.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Icon exports for ATable row actions.
|
|
3
|
-
* Icons are exported as raw SVG strings for flexibility in rendering.
|
|
4
|
-
* @packageDocumentation
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import AddIcon from './stonecrop-ui-icon-add.svg?raw'
|
|
8
|
-
import DeleteIcon from './stonecrop-ui-icon-delete.svg?raw'
|
|
9
|
-
import DuplicateIcon from './stonecrop-ui-icon-duplicate.svg?raw'
|
|
10
|
-
import InsertAboveIcon from './stonecrop-ui-icon-insert-above.svg?raw'
|
|
11
|
-
import InsertBelowIcon from './stonecrop-ui-icon-insert-below.svg?raw'
|
|
12
|
-
import MoveIcon from './stonecrop-ui-icon-move.svg?raw'
|
|
13
|
-
import OpenIcon from './stonecrop-ui-icon-open.svg?raw'
|
|
14
|
-
|
|
15
|
-
// Directional move icons are inline (no dedicated SVG asset): simple up/down chevrons.
|
|
16
|
-
const MoveUpIcon =
|
|
17
|
-
'<svg viewBox="0 0 16 16" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M8 13V3.5M4.5 7 8 3.5 11.5 7" stroke-linecap="round" stroke-linejoin="round"/></svg>'
|
|
18
|
-
const MoveDownIcon =
|
|
19
|
-
'<svg viewBox="0 0 16 16" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M8 3v9.5M4.5 9 8 12.5 11.5 9" stroke-linecap="round" stroke-linejoin="round"/></svg>'
|
|
20
|
-
|
|
21
|
-
export { AddIcon, DeleteIcon, DuplicateIcon, InsertAboveIcon, InsertBelowIcon, MoveIcon, OpenIcon }
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Map of action types to their default icons.
|
|
25
|
-
*
|
|
26
|
-
* @public
|
|
27
|
-
*/
|
|
28
|
-
export const actionIcons: Record<string, string> = {
|
|
29
|
-
add: AddIcon,
|
|
30
|
-
delete: DeleteIcon,
|
|
31
|
-
duplicate: DuplicateIcon,
|
|
32
|
-
insertAbove: InsertAboveIcon,
|
|
33
|
-
insertBelow: InsertBelowIcon,
|
|
34
|
-
move: MoveIcon,
|
|
35
|
-
moveUp: MoveUpIcon,
|
|
36
|
-
moveDown: MoveDownIcon,
|
|
37
|
-
open: OpenIcon,
|
|
38
|
-
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
|
3
|
-
<path d="M32,64C14.35,64,0,49.65,0,32S14.35,0,32,0s32,14.35,32,32-14.35,32-32,32ZM32,4c-15.44,0-28,12.56-28,28s12.56,28,28,28,28-12.56,28-28S47.44,4,32,4Z" style="fill: #000; stroke-width: 0px;"/>
|
|
4
|
-
<polygon points="34 18 30 18 30 30 18 30 18 34 30 34 30 46 34 46 34 34 46 34 46 30 34 30 34 18" style="fill: #000; stroke-width: 0px;"/>
|
|
5
|
-
</svg>
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
|
3
|
-
<path d="M32,64C14.35,64,0,49.65,0,32S14.35,0,32,0s32,14.35,32,32-14.35,32-32,32ZM32,4c-15.44,0-28,12.56-28,28s12.56,28,28,28,28-12.56,28-28S47.44,4,32,4Z" style="fill: #000; stroke-width: 0px;"/>
|
|
4
|
-
<polygon points="46.84 19.99 44.01 17.16 32 29.17 19.99 17.16 17.16 19.99 29.17 32 17.16 44.01 19.99 46.84 32 34.83 44.01 46.84 46.84 44.01 34.83 32 46.84 19.99" style="fill: #000; stroke-width: 0px;"/>
|
|
5
|
-
</svg>
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 70.67 70.67">
|
|
3
|
-
<path d="M68.67,16.67h-14.67V2c0-1.1-.9-2-2-2H2C.9,0,0,.9,0,2v50c0,1.1.9,2,2,2h14.67v14.67c0,1.1.9,2,2,2h50c1.1,0,2-.9,2-2V18.67c0-1.1-.9-2-2-2ZM4,4h46v46H4V4ZM66.67,66.67H20.67v-12.67h31.33c1.1,0,2-.9,2-2v-31.33h12.67v46Z" style="fill: #000; stroke-width: 0px;"/>
|
|
4
|
-
<polygon points="41 25 29 25 29 13 25 13 25 25 13 25 13 29 25 29 25 41 29 41 29 29 41 29 41 25" style="fill: #000; stroke-width: 0px;"/>
|
|
5
|
-
</svg>
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 70.6 61.5">
|
|
3
|
-
<path d="M68.6,45.8v13.7H2v-13.7h66.6M70.6,43.8H0v17.7h70.6v-17.7h0Z"/>
|
|
4
|
-
<path d="M68.6,24.2v13.7H2v-13.7h66.6M70.6,22.2H0v17.7h70.6v-17.7h0Z"/>
|
|
5
|
-
<g>
|
|
6
|
-
<polygon points="70.6 2.5 68.6 2.5 68.6 2 68.1 2 68.1 0 70.6 0 70.6 2.5"/>
|
|
7
|
-
<path d="M65.3,2h-2.9V0h2.9v2ZM59.6,2h-2.9V0h2.9v2ZM53.9,2h-2.9V0h2.9v2ZM48.2,2h-2.9V0h2.9v2ZM42.4,2h-2.9V0h2.9v2ZM36.7,2h-2.9V0h2.9v2ZM31,2h-2.9V0h2.9v2ZM25.3,2h-2.9V0h2.9v2ZM19.6,2h-2.9V0h2.9v2ZM13.9,2h-2.9V0h2.9v2ZM8.2,2h-2.9V0h2.9v2Z"/>
|
|
8
|
-
<polygon points="2 2.5 0 2.5 0 0 2.5 0 2.5 2 2 2 2 2.5"/>
|
|
9
|
-
<path d="M2,13.4H0v-2.7h2v2.7ZM2,8H0v-2.7h2v2.7Z"/>
|
|
10
|
-
<polygon points="2.5 18.7 0 18.7 0 16.2 2 16.2 2 16.7 2.5 16.7 2.5 18.7"/>
|
|
11
|
-
<path d="M65.3,18.7h-2.9v-2h2.9v2ZM59.6,18.7h-2.9v-2h2.9v2ZM53.9,18.7h-2.9v-2h2.9v2ZM48.2,18.7h-2.9v-2h2.9v2ZM42.4,18.7h-2.9v-2h2.9v2ZM36.7,18.7h-2.9v-2h2.9v2ZM31,18.7h-2.9v-2h2.9v2ZM25.3,18.7h-2.9v-2h2.9v2ZM19.6,18.7h-2.9v-2h2.9v2ZM13.9,18.7h-2.9v-2h2.9v2ZM8.2,18.7h-2.9v-2h2.9v2Z"/>
|
|
12
|
-
<polygon points="70.6 18.7 68.1 18.7 68.1 16.7 68.6 16.7 68.6 16.2 70.6 16.2 70.6 18.7"/>
|
|
13
|
-
<path d="M70.6,13.4h-2v-2.7h2v2.7ZM70.6,8h-2v-2.7h2v2.7Z"/>
|
|
14
|
-
</g>
|
|
15
|
-
</svg>
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 70.6 61.5">
|
|
3
|
-
<g>
|
|
4
|
-
<polygon points="70.6 45.3 68.6 45.3 68.6 44.8 68.1 44.8 68.1 42.8 70.6 42.8 70.6 45.3"/>
|
|
5
|
-
<path d="M65.3,44.8h-2.9v-2h2.9v2ZM59.6,44.8h-2.9v-2h2.9v2ZM53.9,44.8h-2.9v-2h2.9v2ZM48.2,44.8h-2.9v-2h2.9v2ZM42.4,44.8h-2.9v-2h2.9v2ZM36.7,44.8h-2.9v-2h2.9v2ZM31,44.8h-2.9v-2h2.9v2ZM25.3,44.8h-2.9v-2h2.9v2ZM19.6,44.8h-2.9v-2h2.9v2ZM13.9,44.8h-2.9v-2h2.9v2ZM8.2,44.8h-2.9v-2h2.9v2Z"/>
|
|
6
|
-
<polygon points="2 45.3 0 45.3 0 42.8 2.5 42.8 2.5 44.8 2 44.8 2 45.3"/>
|
|
7
|
-
<path d="M2,56.3H0v-2.7h2v2.7ZM2,50.8H0v-2.7h2v2.7Z"/>
|
|
8
|
-
<polygon points="2.5 61.5 0 61.5 0 59 2 59 2 59.5 2.5 59.5 2.5 61.5"/>
|
|
9
|
-
<path d="M65.3,61.5h-2.9v-2h2.9v2ZM59.6,61.5h-2.9v-2h2.9v2ZM53.9,61.5h-2.9v-2h2.9v2ZM48.2,61.5h-2.9v-2h2.9v2ZM42.4,61.5h-2.9v-2h2.9v2ZM36.7,61.5h-2.9v-2h2.9v2ZM31,61.5h-2.9v-2h2.9v2ZM25.3,61.5h-2.9v-2h2.9v2ZM19.6,61.5h-2.9v-2h2.9v2ZM13.9,61.5h-2.9v-2h2.9v2ZM8.2,61.5h-2.9v-2h2.9v2Z"/>
|
|
10
|
-
<polygon points="70.6 61.5 68.1 61.5 68.1 59.5 68.6 59.5 68.6 59 70.6 59 70.6 61.5"/>
|
|
11
|
-
<path d="M70.6,56.3h-2v-2.7h2v2.7ZM70.6,50.8h-2v-2.7h2v2.7Z"/>
|
|
12
|
-
</g>
|
|
13
|
-
<path d="M68.6,23.7v13.7H2v-13.7h66.6M70.6,21.7H0v17.7h70.6v-17.7h0Z"/>
|
|
14
|
-
<path d="M68.6,2v13.7H2V2h66.6M70.6,0H0v17.7h70.6V0h0Z"/>
|
|
15
|
-
</svg>
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 70.67 70.64">
|
|
3
|
-
<path d="M70.08,33.9l-9.75-9.75-2.83,2.83,6.33,6.33h-26.51V6.81l6.33,6.33,2.83-2.83L36.75.56c-.75-.75-2.08-.75-2.83,0l-9.75,9.75,2.83,2.83,6.33-6.33v26.5H6.83l6.33-6.33-2.83-2.83L.59,33.9c-.38.38-.59.88-.59,1.41s.21,1.04.59,1.41l9.75,9.75,2.83-2.83-6.33-6.33h26.5v26.51l-6.33-6.33-2.83,2.83,9.75,9.75c.38.38.88.59,1.41.59s1.04-.21,1.41-.59l9.75-9.75-2.83-2.83-6.33,6.33v-26.51h26.51l-6.33,6.33,2.83,2.83,9.75-9.75c.38-.38.59-.88.59-1.41s-.21-1.04-.59-1.41Z" style="fill: #000; stroke-width: 0px;"/>
|
|
4
|
-
</svg>
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
|
3
|
-
<path d="M32,64C14.35,64,0,49.65,0,32S14.35,0,32,0s32,14.35,32,32-14.35,32-32,32ZM32,4c-15.44,0-28,12.56-28,28s12.56,28,28,28,28-12.56,28-28S47.44,4,32,4Z" style="fill: #000; stroke-width: 0px;"/>
|
|
4
|
-
<polygon points="18,20 18,44 46,32" style="fill: #000; stroke-width: 0px;"/>
|
|
5
|
-
</svg>
|
package/src/index.ts
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { App } from 'vue'
|
|
2
|
-
|
|
3
|
-
import ACell from './components/ACell.vue'
|
|
4
|
-
import AGanttCell from './components/AGanttCell.vue'
|
|
5
|
-
import ARow from './components/ARow.vue'
|
|
6
|
-
import ARowActions from './components/ARowActions.vue'
|
|
7
|
-
import ATable from './components/ATable.vue'
|
|
8
|
-
import ATableHeader from './components/ATableHeader.vue'
|
|
9
|
-
import ATableLoading from './components/ATableLoading.vue'
|
|
10
|
-
import ATableLoadingBar from './components/ATableLoadingBar.vue'
|
|
11
|
-
import ATableModal from './components/ATableModal.vue'
|
|
12
|
-
import ATablePaginationFooter from './components/ATablePaginationFooter.vue'
|
|
13
|
-
export { createTableStore } from './stores/table'
|
|
14
|
-
export { useTablePagination } from './composables/table-pagination'
|
|
15
|
-
export type { FilteredTableRow, TablePagination, UseTablePaginationOptions } from './composables/table-pagination'
|
|
16
|
-
export type { FilterState, FilterStateRecord } from './stores/table'
|
|
17
|
-
export type * from './types'
|
|
18
|
-
export { schemaToColumns } from './schemaToColumns'
|
|
19
|
-
|
|
20
|
-
// Icon exports
|
|
21
|
-
export {
|
|
22
|
-
AddIcon,
|
|
23
|
-
DeleteIcon,
|
|
24
|
-
DuplicateIcon,
|
|
25
|
-
InsertAboveIcon,
|
|
26
|
-
InsertBelowIcon,
|
|
27
|
-
MoveIcon,
|
|
28
|
-
OpenIcon,
|
|
29
|
-
actionIcons,
|
|
30
|
-
} from './icons'
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Install all ATable components
|
|
34
|
-
* @param app - Vue app instance
|
|
35
|
-
* @public
|
|
36
|
-
*/
|
|
37
|
-
function install(app: App /* options */) {
|
|
38
|
-
app.component('ACell', ACell)
|
|
39
|
-
app.component('AGanttCell', AGanttCell)
|
|
40
|
-
app.component('ARow', ARow)
|
|
41
|
-
app.component('ARowActions', ARowActions)
|
|
42
|
-
app.component('ATable', ATable)
|
|
43
|
-
app.component('ATableHeader', ATableHeader)
|
|
44
|
-
app.component('ATableLoading', ATableLoading)
|
|
45
|
-
app.component('ATableLoadingBar', ATableLoadingBar)
|
|
46
|
-
app.component('ATableModal', ATableModal)
|
|
47
|
-
app.component('ATablePaginationFooter', ATablePaginationFooter)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export {
|
|
51
|
-
ACell,
|
|
52
|
-
AGanttCell,
|
|
53
|
-
ARow,
|
|
54
|
-
ARowActions,
|
|
55
|
-
ATable,
|
|
56
|
-
ATableHeader,
|
|
57
|
-
ATableLoading,
|
|
58
|
-
ATableLoadingBar,
|
|
59
|
-
ATableModal,
|
|
60
|
-
ATablePaginationFooter,
|
|
61
|
-
install,
|
|
62
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Normalize a scalar cell value to a non-empty string, or nothing.
|
|
3
|
-
*
|
|
4
|
-
* Rejecting objects is what the haystack wants: a nested value has no single textual form, and
|
|
5
|
-
* `String()` on one contributes `[object Object]`, which matches a search for "object" and nothing
|
|
6
|
-
* a user would actually type.
|
|
7
|
-
*/
|
|
8
|
-
function scalarText(value: unknown): string | undefined {
|
|
9
|
-
if (value == null || typeof value === 'object') return undefined
|
|
10
|
-
if (typeof value === 'string') return value === '' ? undefined : value
|
|
11
|
-
if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint') {
|
|
12
|
-
return String(value)
|
|
13
|
-
}
|
|
14
|
-
return undefined
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Build the substring-search haystack for a link column cell.
|
|
19
|
-
* Server middleware enriches inline FKs to `{ id, displayText }`; search both.
|
|
20
|
-
* @public
|
|
21
|
-
*/
|
|
22
|
-
export function linkSearchableText(cellValue: unknown): string {
|
|
23
|
-
if (cellValue == null || cellValue === '') return ''
|
|
24
|
-
|
|
25
|
-
// `in` rather than an assertion to `Record<string, unknown>`: the assertion claims the value has
|
|
26
|
-
// string keys of unknown type, which is narrower than `object` and so is a claim this function
|
|
27
|
-
// cannot make about a cell it did not build.
|
|
28
|
-
if (typeof cellValue === 'object') {
|
|
29
|
-
const parts: string[] = []
|
|
30
|
-
if ('id' in cellValue) {
|
|
31
|
-
const id = scalarText(cellValue.id)
|
|
32
|
-
if (id !== undefined) parts.push(id)
|
|
33
|
-
}
|
|
34
|
-
if ('displayText' in cellValue) {
|
|
35
|
-
const displayText = scalarText(cellValue.displayText)
|
|
36
|
-
if (displayText !== undefined) parts.push(displayText)
|
|
37
|
-
}
|
|
38
|
-
return parts.join(' ')
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return scalarText(cellValue) ?? ''
|
|
42
|
-
}
|
package/src/resolveFilterType.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { componentCategory, type ComponentCategory } from '@stonecrop/schema'
|
|
2
|
-
|
|
3
|
-
import type { TableColumn } from './types'
|
|
4
|
-
|
|
5
|
-
/** Filter widget type derived from a component's semantic category. */
|
|
6
|
-
export type ResolvedFilterType = 'text' | 'select' | 'number' | 'date' | 'dateRange' | 'checkbox' | 'component'
|
|
7
|
-
|
|
8
|
-
const CATEGORY_FILTER: Record<ComponentCategory, Exclude<ResolvedFilterType, 'component'>> = {
|
|
9
|
-
text: 'text',
|
|
10
|
-
number: 'number',
|
|
11
|
-
boolean: 'checkbox',
|
|
12
|
-
date: 'date',
|
|
13
|
-
datetime: 'dateRange',
|
|
14
|
-
select: 'select',
|
|
15
|
-
code: 'text',
|
|
16
|
-
link: 'text',
|
|
17
|
-
attach: 'text',
|
|
18
|
-
quantity: 'number',
|
|
19
|
-
currency: 'number',
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Resolve the filter widget and filter logic type for a column.
|
|
24
|
-
* Explicit `filterType` wins; otherwise derive from the component category.
|
|
25
|
-
* @public
|
|
26
|
-
*/
|
|
27
|
-
export function resolveFilterType(column: Pick<TableColumn, 'filterType' | 'component'>): ResolvedFilterType {
|
|
28
|
-
if (column.filterType) return column.filterType
|
|
29
|
-
const category = componentCategory(column.component)
|
|
30
|
-
if (category) return CATEGORY_FILTER[category]
|
|
31
|
-
return 'text'
|
|
32
|
-
}
|
package/src/schemaToColumns.ts
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { componentCategory } from '@stonecrop/schema'
|
|
2
|
-
import type { ColumnSchema } from '@stonecrop/schema'
|
|
3
|
-
|
|
4
|
-
import type { TableColumn } from './types'
|
|
5
|
-
import { formatCurrency, formatQuantity } from './utils'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Convert an array of doctype field descriptors into ATable column definitions.
|
|
9
|
-
*
|
|
10
|
-
* Fields are excluded when:
|
|
11
|
-
* - `hidden: true` — field should not be visible in any view
|
|
12
|
-
* - no `component` — non-scalar entry (nested table or fieldset), no column equivalent
|
|
13
|
-
*
|
|
14
|
-
* `fieldname` is renamed to `name`; `hidden` is stripped. All other `ColumnSchema` properties
|
|
15
|
-
* spread through automatically.
|
|
16
|
-
*
|
|
17
|
-
* For link fields (those carrying `doctype`) without an explicit `cellComponent`:
|
|
18
|
-
* - `linkDoctype` is set from the field's `doctype` property (used by ACell's async resolver).
|
|
19
|
-
* - A synchronous `format` function is added (unless the field already has one) that handles
|
|
20
|
-
* both bare ID strings and pre-resolved `{ id, displayText }` objects.
|
|
21
|
-
*
|
|
22
|
-
* For quantity fields — those whose `component` carries the `'quantity'` category — without an
|
|
23
|
-
* explicit `format`, a synchronous `format` is added that renders the `{ qty, uom }` value (see
|
|
24
|
-
* `QuantityValue` in `@stonecrop/aform`) as `"<qty> <uom>"`.
|
|
25
|
-
*
|
|
26
|
-
* For currency fields — those whose `component` carries the `'currency'` category — without an
|
|
27
|
-
* explicit `format`, a synchronous `format` is added that renders the `{ amount, currency }` value
|
|
28
|
-
* (see `CurrencyValue` in `@stonecrop/aform`) as `"<amount> <currency>"`.
|
|
29
|
-
*
|
|
30
|
-
* @public
|
|
31
|
-
*/
|
|
32
|
-
export function schemaToColumns(schema: ColumnSchema[]): TableColumn[] {
|
|
33
|
-
return schema
|
|
34
|
-
.filter(f => !f.hidden && f.component)
|
|
35
|
-
.map(({ fieldname, hidden: _hidden, ...rest }) => {
|
|
36
|
-
const col: TableColumn = Object.assign({ name: fieldname }, rest)
|
|
37
|
-
|
|
38
|
-
// Link fields: store the linked doctype for async resolution by ACell, and add a sync
|
|
39
|
-
// format that handles pre-resolved AFormLinkValue objects.
|
|
40
|
-
if (rest.doctype && !rest.cellComponent) {
|
|
41
|
-
col.linkDoctype = rest.doctype
|
|
42
|
-
|
|
43
|
-
if (!rest.format) {
|
|
44
|
-
col.format = (v: any): string => {
|
|
45
|
-
if (v === null || v === undefined) return ''
|
|
46
|
-
if (typeof v === 'object') {
|
|
47
|
-
const display: unknown = v.displayText ?? v.id ?? ''
|
|
48
|
-
return typeof display === 'string' || typeof display === 'number' ? String(display) : ''
|
|
49
|
-
}
|
|
50
|
-
return String(v)
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Quantity fields: render the composite { qty, uom } value as "<qty> <uom>".
|
|
56
|
-
if (componentCategory(rest.component) === 'quantity' && !rest.format) {
|
|
57
|
-
col.format = formatQuantity
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Currency fields: render the composite { amount, currency } value as "<amount> <currency>".
|
|
61
|
-
if (componentCategory(rest.component) === 'currency' && !rest.format) {
|
|
62
|
-
col.format = formatCurrency
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return col
|
|
66
|
-
})
|
|
67
|
-
}
|