stacks 0.47.4 → 0.48.2
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/buddy/art/social.png +0 -0
- package/buddy/package.json +1 -1
- package/buddy/src/commands/make.ts +27 -12
- package/buddy/src/commands/test.ts +40 -2
- package/core/actions/package.json +2 -2
- package/core/actions/src/helpers/utils.ts +29 -3
- package/core/actions/src/make.ts +37 -6
- package/core/actions/src/test-coverage.ts +1 -1
- package/core/actions/src/test-feature.ts +5 -0
- package/core/actions/src/test-unit.ts +5 -0
- package/core/ai/package.json +1 -1
- package/core/alias/package.json +1 -1
- package/core/arrays/package.json +1 -1
- package/core/auth/package.json +1 -1
- package/core/build/package.json +3 -3
- package/core/cache/package.json +3 -3
- package/core/chat/README.md +33 -40
- package/core/chat/package.json +1 -1
- package/core/cli/package.json +1 -1
- package/core/cloud/package.json +1 -1
- package/core/collections/package.json +1 -1
- package/core/config/package.json +1 -1
- package/core/dashboard/package.json +1 -1
- package/core/database/package.json +1 -1
- package/core/datetime/package.json +1 -1
- package/core/desktop/package.json +1 -1
- package/core/docs/node_modules/.bin/vitepress +2 -2
- package/core/docs/package.json +2 -2
- package/core/domains/package.json +1 -1
- package/core/drivers/package.json +1 -1
- package/core/email/README.md +101 -35
- package/core/email/package.json +1 -1
- package/core/error-handling/package.json +2 -2
- package/core/events/package.json +1 -1
- package/core/git/package.json +1 -1
- package/core/health/package.json +1 -1
- package/core/lint/node_modules/.bin/eslint +2 -2
- package/core/lint/package.json +3 -3
- package/core/logging/package.json +1 -1
- package/core/modules/package.json +1 -1
- package/core/notifications/README.md +7 -2
- package/core/notifications/package.json +1 -1
- package/core/notifications/src/index.ts +37 -9
- package/core/notifications/tests/chat/Slack.test.ts +5 -4
- package/core/notifications/tests/email/Mailgun.test.ts +4 -3
- package/core/notifications/tests/email/Sendgrid.test.ts +3 -3
- package/core/notifications/tests/sms/Twilio.test.ts +3 -3
- package/core/objects/package.json +1 -1
- package/core/path/package.json +1 -1
- package/core/path/src/index.ts +5 -0
- package/core/payments/package.json +1 -1
- package/core/push/README.md +24 -42
- package/core/push/package.json +1 -1
- package/core/realtime/package.json +1 -1
- package/core/router/package.json +1 -1
- package/core/search-engine/package.json +1 -1
- package/core/security/package.json +1 -1
- package/core/server/package.json +1 -1
- package/core/sms/README.md +82 -35
- package/core/sms/package.json +1 -1
- package/core/storage/package.json +1 -1
- package/core/storage/src/index.ts +13 -0
- package/core/strings/README.md +10 -2
- package/core/strings/package.json +4 -2
- package/core/strings/src/case.ts +14 -0
- package/core/strings/src/index.ts +4 -97
- package/core/strings/src/pluralize.ts +1 -0
- package/core/strings/src/utils.ts +80 -0
- package/core/strings/src/validation.ts +182 -0
- package/core/tables/README.md +109 -0
- package/core/tables/examples/vue/App.vue +12 -0
- package/core/tables/examples/vue/favicon.png +0 -0
- package/core/tables/examples/vue/index.html +20 -0
- package/core/tables/examples/web/favicon.png +0 -0
- package/core/tables/examples/web/index.html +13 -0
- package/core/tables/node_modules/.bin/mkdist +17 -0
- package/core/tables/node_modules/.bin/tsc +17 -0
- package/core/tables/node_modules/.bin/tsserver +17 -0
- package/core/tables/node_modules/.bin/unbuild +17 -0
- package/core/tables/package.json +97 -0
- package/core/tables/src/cli/index.ts +1 -0
- package/core/tables/src/components/Demo.vue +89 -0
- package/core/tables/src/components/README.md +111 -0
- package/core/tables/src/components/Table.vue +342 -0
- package/core/tables/src/components/TableBody.vue +33 -0
- package/core/tables/src/components/TableCellActionItems.vue +9 -0
- package/core/tables/src/components/TableFilters.vue +703 -0
- package/core/tables/src/components/TableHead.vue +87 -0
- package/core/tables/src/components/TablePagination.vue +146 -0
- package/core/tables/src/components/TableRow.vue +78 -0
- package/core/tables/src/components/TableSearch.vue +38 -0
- package/core/tables/src/components/Tooltip.vue +10 -0
- package/core/tables/src/config/tables.ts +1 -0
- package/core/tables/src/docs/index.md +0 -0
- package/core/tables/src/functions/README.md +8 -0
- package/core/tables/src/functions/dark.ts +3 -0
- package/core/tables/src/functions/index.ts +2 -0
- package/core/tables/src/functions/table.ts +180 -0
- package/core/tables/tests/example.test.ts +7 -0
- package/core/testing/node_modules/.bin/vitest +2 -2
- package/core/testing/package.json +9 -6
- package/core/types/node_modules/.bin/vitepress +2 -2
- package/core/types/package.json +4 -3
- package/core/types/src/cli.ts +10 -2
- package/core/types/src/hashing.ts +15 -0
- package/core/types/src/index.ts +2 -0
- package/core/types/src/notifications.ts +1 -0
- package/core/types/src/reactivity.ts +3 -0
- package/core/types/src/tables.ts +48 -0
- package/core/ui/node_modules/.bin/vue-tsc +2 -2
- package/core/ui/package.json +2 -2
- package/core/utils/package.json +1 -1
- package/core/x-ray/package.json +1 -1
- package/package.json +3 -2
- package/tsconfig.json +8 -0
- package/vitest.config.ts +2 -0
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { isString } from '@stacksjs/utils'
|
|
3
|
+
import type { Hits, SearchResponse } from '@stacksjs/types'
|
|
4
|
+
import { useTable } from '../functions/table'
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
type: string // the Meilisearch index you would like to use for this table
|
|
8
|
+
columns: string | string[] // used as table heads/column titles
|
|
9
|
+
source?: string // optional: the Meilisearch host name/address (defaults: http://127.0.0.1:7700)
|
|
10
|
+
password?: string // optional: the Meilisearch password (defaults: '')
|
|
11
|
+
searchable?: string | boolean // optional: determines whether the table displays the search bar (defaults: true)
|
|
12
|
+
query?: string // optional: the "query" (= search input) used to search the table (defaults: '')
|
|
13
|
+
sortable?: string | boolean // optional: determines whether the table displays the "table head"-sorts (defaults: true)
|
|
14
|
+
sort?: string // optional: the only active sort to be applied to the table (defaults: '')
|
|
15
|
+
sorts?: string | string[] // optional: the specific type of sorts to be applied to the table (defaults: [])
|
|
16
|
+
filterable?: string | boolean // optional: determines whether the table displays the filters component (defaults: true)
|
|
17
|
+
filters?: string | string[] // optional: the specific type of filters to be displayed/utilized in the table (defaults: [])
|
|
18
|
+
actionable?: string | boolean // optional: determines whether the table displays any "action items" (defaults: true)
|
|
19
|
+
actions?: string | string[] // optional: the specific type of actions to be displayed/utilized in the table (defaults: 'Edit, Delete')
|
|
20
|
+
perPage?: string | number // optional: the number of rows (items) to be displayed per page (defaults: 10)
|
|
21
|
+
currentPage?: number // optional: the current page number (defaults: 1)
|
|
22
|
+
selectable?: string | boolean // optional: determines whether the table displays the checkboxes (defaults: true)
|
|
23
|
+
selectedRows?: number[] | string[] // optional: holds the selected rows (defaults: [])
|
|
24
|
+
selectedAll?: boolean // optional: determines whether all the rows are selected (defaults: false)
|
|
25
|
+
results?: SearchResponse<Record<string, any>> // optional: the Meilisearch search response (defaults: {})
|
|
26
|
+
hits?: Hits // optional: the Meilisearch hits (we could also name this "rows" as that would be more applicable to the "table domain" but choosing to stay in sync with Meilisearch right now until we implement for a second search engine driver)
|
|
27
|
+
// stickyHeader?: string | boolean // optional: holds the selected rows (defaults: [])
|
|
28
|
+
// stickyFooter?: string | boolean // optional: determines whether all the rows are selected (defaults: false)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const {
|
|
32
|
+
type,
|
|
33
|
+
columns,
|
|
34
|
+
source = 'http://127.0.0.1:7700',
|
|
35
|
+
password = '',
|
|
36
|
+
searchable = true,
|
|
37
|
+
query = '',
|
|
38
|
+
sortable = true,
|
|
39
|
+
sort = '',
|
|
40
|
+
sorts = [],
|
|
41
|
+
filterable = true,
|
|
42
|
+
filters = [],
|
|
43
|
+
actionable = false,
|
|
44
|
+
actions = ['Edit', 'Delete'],
|
|
45
|
+
perPage = 20,
|
|
46
|
+
selectable = true,
|
|
47
|
+
selectedRows = [],
|
|
48
|
+
selectedAll = false,
|
|
49
|
+
} = defineProps<Props>()
|
|
50
|
+
|
|
51
|
+
const parsedColumns = computed((): string[] => {
|
|
52
|
+
if (isString(columns))
|
|
53
|
+
return columns.split(',').map(col => col.trim())
|
|
54
|
+
|
|
55
|
+
return columns
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
const parsedSorts = computed((): string[] => {
|
|
59
|
+
if (isString(sorts))
|
|
60
|
+
return sorts.split(',').map(col => col.trim())
|
|
61
|
+
|
|
62
|
+
return sorts
|
|
63
|
+
})
|
|
64
|
+
const parsedFilters = computed((): string[] => {
|
|
65
|
+
if (isString(filters))
|
|
66
|
+
return filters.split(',').map(col => col.trim())
|
|
67
|
+
|
|
68
|
+
return filters
|
|
69
|
+
})
|
|
70
|
+
const itemsPerPage = computed((): number => {
|
|
71
|
+
if (isString(perPage))
|
|
72
|
+
return parseInt(perPage)
|
|
73
|
+
|
|
74
|
+
return perPage
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
// let's use (init) the table by passing the default state
|
|
78
|
+
const { table, search, columnName } = await useTable({
|
|
79
|
+
source,
|
|
80
|
+
password,
|
|
81
|
+
type,
|
|
82
|
+
columns: parsedColumns.value,
|
|
83
|
+
searchable,
|
|
84
|
+
query,
|
|
85
|
+
sortable,
|
|
86
|
+
sort,
|
|
87
|
+
sorts: parsedSorts.value,
|
|
88
|
+
filterable,
|
|
89
|
+
filters: parsedFilters.value,
|
|
90
|
+
actionable,
|
|
91
|
+
actions,
|
|
92
|
+
perPage: itemsPerPage.value,
|
|
93
|
+
currentPage: 1,
|
|
94
|
+
selectable: true,
|
|
95
|
+
selectedRows: [],
|
|
96
|
+
selectedAll: false,
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
// let's run the initial search upon page view/load
|
|
100
|
+
|
|
101
|
+
// console.log('running initial search')
|
|
102
|
+
const results = await search()
|
|
103
|
+
// eslint-disable-next-line no-console
|
|
104
|
+
console.log('initial search complete', results)
|
|
105
|
+
|
|
106
|
+
// now that we have the search results, let's update/set the state of the table
|
|
107
|
+
table.source = source
|
|
108
|
+
table.password = password
|
|
109
|
+
table.hits = results?.hits
|
|
110
|
+
table.type = type
|
|
111
|
+
table.columns = parsedColumns.value
|
|
112
|
+
table.searchable = searchable
|
|
113
|
+
table.query = query
|
|
114
|
+
table.filterable = filterable
|
|
115
|
+
table.filters = parsedFilters.value
|
|
116
|
+
table.sortable = sortable
|
|
117
|
+
table.sort = sort
|
|
118
|
+
table.sorts = parsedSorts.value
|
|
119
|
+
table.perPage = itemsPerPage.value
|
|
120
|
+
table.actionable = actionable
|
|
121
|
+
table.actions = actions
|
|
122
|
+
table.selectable = selectable
|
|
123
|
+
table.selectedRows = selectedRows
|
|
124
|
+
table.selectedAll = selectedAll
|
|
125
|
+
table.results = results as SearchResponse
|
|
126
|
+
</script>
|
|
127
|
+
|
|
128
|
+
<template>
|
|
129
|
+
<div class="px-4 sm:px-6 lg:px-8">
|
|
130
|
+
<div class="flex flex-col mt-8">
|
|
131
|
+
<div class="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
|
|
132
|
+
<div class="inline-block min-w-full py-2 align-middle md:px-6 lg:px-8">
|
|
133
|
+
<div class="overflow-hidden shadow ring-black ring-1 ring-opacity-5 md:rounded-lg">
|
|
134
|
+
<table class="min-w-full divide-y divide-gray-300">
|
|
135
|
+
<TableHead />
|
|
136
|
+
<TableBody>
|
|
137
|
+
<template #action_column="rowData">
|
|
138
|
+
<slot
|
|
139
|
+
name="action_column"
|
|
140
|
+
:value="rowData.rowData"
|
|
141
|
+
/>
|
|
142
|
+
</template>
|
|
143
|
+
<template
|
|
144
|
+
v-for="(col, x) in parsedColumns"
|
|
145
|
+
:key="x"
|
|
146
|
+
#[columnName(col)]="tableBodyData"
|
|
147
|
+
>
|
|
148
|
+
<slot
|
|
149
|
+
:name="columnName(col)"
|
|
150
|
+
:value="tableBodyData.tableRowData"
|
|
151
|
+
/>
|
|
152
|
+
</template>
|
|
153
|
+
</TableBody>
|
|
154
|
+
</table>
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
</div>
|
|
160
|
+
</template>
|
|
161
|
+
|
|
162
|
+
<style>
|
|
163
|
+
/* Our reset styles - many thanks to the Tailwind Labs team for gathering many of these */
|
|
164
|
+
|
|
165
|
+
/*
|
|
166
|
+
1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
|
|
167
|
+
2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
|
|
168
|
+
*/
|
|
169
|
+
|
|
170
|
+
*,
|
|
171
|
+
::before,
|
|
172
|
+
::after {
|
|
173
|
+
box-sizing: border-box; /* 1 */
|
|
174
|
+
border-width: 0; /* 2 */
|
|
175
|
+
border-style: solid; /* 2 */
|
|
176
|
+
border-color: currentColor; /* 2 */
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/*
|
|
180
|
+
1. Use a consistent sensible line-height in all browsers.
|
|
181
|
+
2. Prevent adjustments of font size after orientation changes in iOS.
|
|
182
|
+
3. Use a more readable tab size.
|
|
183
|
+
4. Use the user's configured `sans` font-family by default.
|
|
184
|
+
*/
|
|
185
|
+
|
|
186
|
+
html {
|
|
187
|
+
line-height: 1.5; /* 1 */
|
|
188
|
+
-webkit-text-size-adjust: 100%; /* 2 */
|
|
189
|
+
-moz-tab-size: 4; /* 3 */
|
|
190
|
+
tab-size: 4; /* 3 */
|
|
191
|
+
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /* 4 */
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/*
|
|
195
|
+
Reset links to optimize for opt-in styling instead of opt-out.
|
|
196
|
+
*/
|
|
197
|
+
|
|
198
|
+
a {
|
|
199
|
+
color: inherit;
|
|
200
|
+
text-decoration: inherit;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/*
|
|
204
|
+
1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
|
|
205
|
+
2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
|
|
206
|
+
3. Remove gaps between table borders by default.
|
|
207
|
+
*/
|
|
208
|
+
|
|
209
|
+
table {
|
|
210
|
+
text-indent: 0; /* 1 */
|
|
211
|
+
border-color: inherit; /* 2 */
|
|
212
|
+
border-collapse: collapse; /* 3 */
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/*
|
|
216
|
+
1. Change the font styles in all browsers.
|
|
217
|
+
2. Remove the margin in Firefox and Safari.
|
|
218
|
+
3. Remove default padding in all browsers.
|
|
219
|
+
*/
|
|
220
|
+
|
|
221
|
+
button,
|
|
222
|
+
input,
|
|
223
|
+
select {
|
|
224
|
+
font-family: inherit; /* 1 */
|
|
225
|
+
font-size: 100%; /* 1 */
|
|
226
|
+
font-weight: inherit; /* 1 */
|
|
227
|
+
line-height: inherit; /* 1 */
|
|
228
|
+
color: inherit; /* 1 */
|
|
229
|
+
margin: 0; /* 2 */
|
|
230
|
+
padding: 0; /* 3 */
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/*
|
|
234
|
+
Remove the inheritance of text transform in Edge and Firefox.
|
|
235
|
+
*/
|
|
236
|
+
|
|
237
|
+
button,
|
|
238
|
+
select {
|
|
239
|
+
text-transform: none;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/*
|
|
243
|
+
1. Correct the inability to style clickable types in iOS and Safari.
|
|
244
|
+
2. Remove default button styles.
|
|
245
|
+
*/
|
|
246
|
+
|
|
247
|
+
button,
|
|
248
|
+
[type='button'],
|
|
249
|
+
[type='submit'] {
|
|
250
|
+
-webkit-appearance: button; /* 1 */
|
|
251
|
+
background-color: transparent; /* 2 */
|
|
252
|
+
background-image: none; /* 2 */
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/*
|
|
256
|
+
Use the modern Firefox focus style for all focusable elements.
|
|
257
|
+
*/
|
|
258
|
+
|
|
259
|
+
:-moz-focusring {
|
|
260
|
+
outline: auto;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/*
|
|
264
|
+
Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
|
|
265
|
+
*/
|
|
266
|
+
|
|
267
|
+
:-moz-ui-invalid {
|
|
268
|
+
box-shadow: none;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/*
|
|
272
|
+
Correct the cursor style of increment and decrement buttons in Safari.
|
|
273
|
+
*/
|
|
274
|
+
|
|
275
|
+
::-webkit-inner-spin-button,
|
|
276
|
+
::-webkit-outer-spin-button {
|
|
277
|
+
height: auto;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/*
|
|
281
|
+
1. Correct the odd appearance in Chrome and Safari.
|
|
282
|
+
2. Correct the outline style in Safari.
|
|
283
|
+
*/
|
|
284
|
+
|
|
285
|
+
[type='search'] {
|
|
286
|
+
-webkit-appearance: textfield; /* 1 */
|
|
287
|
+
outline-offset: -2px; /* 2 */
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/*
|
|
291
|
+
Remove the inner padding in Chrome and Safari on macOS.
|
|
292
|
+
*/
|
|
293
|
+
|
|
294
|
+
::-webkit-search-decoration {
|
|
295
|
+
-webkit-appearance: none;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/*
|
|
299
|
+
1. Correct the inability to style clickable types in iOS and Safari.
|
|
300
|
+
2. Change font properties to `inherit` in Safari.
|
|
301
|
+
*/
|
|
302
|
+
|
|
303
|
+
::-webkit-file-upload-button {
|
|
304
|
+
-webkit-appearance: button; /* 1 */
|
|
305
|
+
font: inherit; /* 2 */
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/*
|
|
309
|
+
Prevent resizing textareas horizontally by default.
|
|
310
|
+
*/
|
|
311
|
+
|
|
312
|
+
textarea {
|
|
313
|
+
resize: vertical;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/*
|
|
317
|
+
1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
|
|
318
|
+
2. Set the default placeholder color to the user's configured gray 400 color.
|
|
319
|
+
*/
|
|
320
|
+
|
|
321
|
+
input::placeholder,
|
|
322
|
+
textarea::placeholder {
|
|
323
|
+
opacity: 1; /* 1 */
|
|
324
|
+
color: #9ca3af; /* 2 */
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/*
|
|
328
|
+
Set the default cursor for buttons.
|
|
329
|
+
*/
|
|
330
|
+
|
|
331
|
+
button,
|
|
332
|
+
[role="button"] {
|
|
333
|
+
cursor: pointer;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/*
|
|
337
|
+
Make sure disabled buttons don't get the pointer cursor.
|
|
338
|
+
*/
|
|
339
|
+
:disabled {
|
|
340
|
+
cursor: default;
|
|
341
|
+
}
|
|
342
|
+
</style>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// console.log('TableBody.vue')
|
|
3
|
+
|
|
4
|
+
const { table, columnName } = await useTable()
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<template>
|
|
8
|
+
<tbody class="bg-white divide-y divide-gray-200">
|
|
9
|
+
<TableRow
|
|
10
|
+
v-for="(hit, index) in table.results?.hits"
|
|
11
|
+
:key="index"
|
|
12
|
+
:index="index"
|
|
13
|
+
:hit="hit"
|
|
14
|
+
>
|
|
15
|
+
<template #action_column="rowData">
|
|
16
|
+
<slot
|
|
17
|
+
name="action_column"
|
|
18
|
+
:row-data="rowData.rowData"
|
|
19
|
+
/>
|
|
20
|
+
</template>
|
|
21
|
+
<template
|
|
22
|
+
v-for="(col, x) in table.columns"
|
|
23
|
+
:key="x"
|
|
24
|
+
#[columnName(col)]="tableRowData"
|
|
25
|
+
>
|
|
26
|
+
<slot
|
|
27
|
+
:name="columnName(col)"
|
|
28
|
+
:table-row-data="tableRowData.colData"
|
|
29
|
+
/>
|
|
30
|
+
</template>
|
|
31
|
+
</TableRow>
|
|
32
|
+
</tbody>
|
|
33
|
+
</template>
|