@budibase/frontend-core 2.32.8 → 2.32.9
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/package.json +5 -5
- package/src/components/grid/cells/AttachmentCell.svelte +12 -1
- package/src/components/grid/cells/HeaderCell.svelte +15 -6
- package/src/components/grid/controls/ColumnsSettingButton.svelte +7 -5
- package/src/components/grid/controls/ColumnsSettingContent.svelte +2 -0
- package/src/components/grid/controls/SortButton.svelte +3 -2
- package/src/components/grid/lib/renderers.js +5 -1
- package/src/components/grid/stores/columns.js +22 -7
- package/src/components/grid/stores/datasource.js +7 -23
- package/src/components/grid/stores/datasources/viewV2.js +21 -17
- package/src/components/grid/stores/reorder.js +12 -3
- package/src/components/grid/stores/resize.js +9 -2
- package/src/components/grid/stores/rows.js +19 -7
- package/src/utils/index.js +2 -0
- package/src/utils/relatedColumns.js +107 -0
- package/src/utils/table.js +27 -0
package/package.json
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/frontend-core",
|
|
3
|
-
"version": "2.32.
|
|
3
|
+
"version": "2.32.9",
|
|
4
4
|
"description": "Budibase frontend core libraries used in builder and client",
|
|
5
5
|
"author": "Budibase",
|
|
6
6
|
"license": "MPL-2.0",
|
|
7
7
|
"svelte": "src/index.js",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@budibase/bbui": "2.32.
|
|
10
|
-
"@budibase/shared-core": "2.32.
|
|
11
|
-
"@budibase/types": "2.32.
|
|
9
|
+
"@budibase/bbui": "2.32.9",
|
|
10
|
+
"@budibase/shared-core": "2.32.9",
|
|
11
|
+
"@budibase/types": "2.32.9",
|
|
12
12
|
"dayjs": "^1.10.8",
|
|
13
13
|
"lodash": "4.17.21",
|
|
14
14
|
"shortid": "2.2.15",
|
|
15
15
|
"socket.io-client": "^4.7.5"
|
|
16
16
|
},
|
|
17
|
-
"gitHead": "
|
|
17
|
+
"gitHead": "c3d1bac34a42f0707e0cba968a4df9f58fa5088e"
|
|
18
18
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { onMount, getContext } from "svelte"
|
|
3
3
|
import { Dropzone } from "@budibase/bbui"
|
|
4
4
|
import GridPopover from "../overlays/GridPopover.svelte"
|
|
5
|
+
import { FieldType } from "@budibase/types"
|
|
5
6
|
|
|
6
7
|
export let value
|
|
7
8
|
export let focused = false
|
|
@@ -81,7 +82,12 @@
|
|
|
81
82
|
>
|
|
82
83
|
{#each value || [] as attachment}
|
|
83
84
|
{#if isImage(attachment.extension)}
|
|
84
|
-
<img
|
|
85
|
+
<img
|
|
86
|
+
class:light={!$props?.darkMode &&
|
|
87
|
+
schema.type === FieldType.SIGNATURE_SINGLE}
|
|
88
|
+
src={attachment.url}
|
|
89
|
+
alt={attachment.extension}
|
|
90
|
+
/>
|
|
85
91
|
{:else}
|
|
86
92
|
<div class="file" title={attachment.name}>
|
|
87
93
|
{attachment.extension}
|
|
@@ -140,4 +146,9 @@
|
|
|
140
146
|
width: 320px;
|
|
141
147
|
padding: var(--cell-padding);
|
|
142
148
|
}
|
|
149
|
+
|
|
150
|
+
.attachment-cell img.light {
|
|
151
|
+
-webkit-filter: invert(100%);
|
|
152
|
+
filter: invert(100%);
|
|
153
|
+
}
|
|
143
154
|
</style>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { getContext, onMount, tick } from "svelte"
|
|
3
|
-
import {
|
|
3
|
+
import { canBeSortColumn, canBeDisplayColumn } from "@budibase/frontend-core"
|
|
4
4
|
import { Icon, Menu, MenuItem, Modal } from "@budibase/bbui"
|
|
5
5
|
import GridCell from "./GridCell.svelte"
|
|
6
6
|
import { getColumnIcon } from "../lib/utils"
|
|
@@ -165,7 +165,17 @@
|
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
const hideColumn = () => {
|
|
168
|
-
|
|
168
|
+
const { related } = column
|
|
169
|
+
const mutation = { visible: false }
|
|
170
|
+
if (!related) {
|
|
171
|
+
datasource.actions.addSchemaMutation(column.name, mutation)
|
|
172
|
+
} else {
|
|
173
|
+
datasource.actions.addSubSchemaMutation(
|
|
174
|
+
related.subField,
|
|
175
|
+
related.field,
|
|
176
|
+
mutation
|
|
177
|
+
)
|
|
178
|
+
}
|
|
169
179
|
datasource.actions.saveSchemaMutations()
|
|
170
180
|
open = false
|
|
171
181
|
}
|
|
@@ -347,15 +357,14 @@
|
|
|
347
357
|
<MenuItem
|
|
348
358
|
icon="Label"
|
|
349
359
|
on:click={makeDisplayColumn}
|
|
350
|
-
disabled={column.primaryDisplay ||
|
|
351
|
-
!canBeDisplayColumn(column.schema.type)}
|
|
360
|
+
disabled={column.primaryDisplay || !canBeDisplayColumn(column.schema)}
|
|
352
361
|
>
|
|
353
362
|
Use as display column
|
|
354
363
|
</MenuItem>
|
|
355
364
|
<MenuItem
|
|
356
365
|
icon="SortOrderUp"
|
|
357
366
|
on:click={sortAscending}
|
|
358
|
-
disabled={!canBeSortColumn(column.schema
|
|
367
|
+
disabled={!canBeSortColumn(column.schema) ||
|
|
359
368
|
(column.name === $sort.column && $sort.order === "ascending")}
|
|
360
369
|
>
|
|
361
370
|
Sort {sortingLabels.ascending}
|
|
@@ -363,7 +372,7 @@
|
|
|
363
372
|
<MenuItem
|
|
364
373
|
icon="SortOrderDown"
|
|
365
374
|
on:click={sortDescending}
|
|
366
|
-
disabled={!canBeSortColumn(column.schema
|
|
375
|
+
disabled={!canBeSortColumn(column.schema) ||
|
|
367
376
|
(column.name === $sort.column && $sort.order === "descending")}
|
|
368
377
|
>
|
|
369
378
|
Sort {sortingLabels.descending}
|
|
@@ -4,13 +4,15 @@
|
|
|
4
4
|
import ColumnsSettingContent from "./ColumnsSettingContent.svelte"
|
|
5
5
|
import { FieldPermissions } from "../../../constants"
|
|
6
6
|
|
|
7
|
-
const {
|
|
7
|
+
const { tableColumns, datasource } = getContext("grid")
|
|
8
8
|
|
|
9
9
|
let open = false
|
|
10
10
|
let anchor
|
|
11
11
|
|
|
12
|
-
$: anyRestricted = $
|
|
13
|
-
|
|
12
|
+
$: anyRestricted = $tableColumns.filter(
|
|
13
|
+
col => !col.visible || col.readonly
|
|
14
|
+
).length
|
|
15
|
+
$: text = anyRestricted ? `Columns (${anyRestricted} restricted)` : "Columns"
|
|
14
16
|
$: permissions =
|
|
15
17
|
$datasource.type === "viewV2"
|
|
16
18
|
? [
|
|
@@ -28,12 +30,12 @@
|
|
|
28
30
|
size="M"
|
|
29
31
|
on:click={() => (open = !open)}
|
|
30
32
|
selected={open || anyRestricted}
|
|
31
|
-
disabled={!$
|
|
33
|
+
disabled={!$tableColumns.length}
|
|
32
34
|
>
|
|
33
35
|
{text}
|
|
34
36
|
</ActionButton>
|
|
35
37
|
</div>
|
|
36
38
|
|
|
37
39
|
<Popover bind:open {anchor} align="left">
|
|
38
|
-
<ColumnsSettingContent columns={$
|
|
40
|
+
<ColumnsSettingContent columns={$tableColumns} {permissions} />
|
|
39
41
|
</Popover>
|
|
@@ -122,8 +122,10 @@
|
|
|
122
122
|
label: name,
|
|
123
123
|
schema: {
|
|
124
124
|
type: column.type,
|
|
125
|
+
subtype: column.subtype,
|
|
125
126
|
visible: column.visible,
|
|
126
127
|
readonly: column.readonly,
|
|
128
|
+
constraints: column.constraints, // This is needed to properly display "users" column
|
|
127
129
|
},
|
|
128
130
|
}
|
|
129
131
|
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { getContext } from "svelte"
|
|
3
3
|
import { ActionButton, Popover, Select } from "@budibase/bbui"
|
|
4
|
-
import { canBeSortColumn } from "@budibase/
|
|
4
|
+
import { canBeSortColumn } from "@budibase/frontend-core"
|
|
5
5
|
|
|
6
6
|
const { sort, columns } = getContext("grid")
|
|
7
7
|
|
|
@@ -13,8 +13,9 @@
|
|
|
13
13
|
label: col.label || col.name,
|
|
14
14
|
value: col.name,
|
|
15
15
|
type: col.schema?.type,
|
|
16
|
+
related: col.related,
|
|
16
17
|
}))
|
|
17
|
-
.filter(col => canBeSortColumn(col
|
|
18
|
+
.filter(col => canBeSortColumn(col))
|
|
18
19
|
$: orderOptions = getOrderOptions($sort.column, columnOptions)
|
|
19
20
|
|
|
20
21
|
const getOrderOptions = (column, columnOptions) => {
|
|
@@ -35,5 +35,9 @@ const TypeComponentMap = {
|
|
|
35
35
|
[FieldType.BB_REFERENCE_SINGLE]: BBReferenceSingleCell,
|
|
36
36
|
}
|
|
37
37
|
export const getCellRenderer = column => {
|
|
38
|
-
return
|
|
38
|
+
return (
|
|
39
|
+
TypeComponentMap[column?.schema?.cellRenderType] ||
|
|
40
|
+
TypeComponentMap[column?.schema?.type] ||
|
|
41
|
+
TextCell
|
|
42
|
+
)
|
|
39
43
|
}
|
|
@@ -42,6 +42,11 @@ export const deriveStores = context => {
|
|
|
42
42
|
return map
|
|
43
43
|
})
|
|
44
44
|
|
|
45
|
+
// Derived list of columns which are direct part of the table
|
|
46
|
+
const tableColumns = derived(columns, $columns => {
|
|
47
|
+
return $columns.filter(col => !col.related)
|
|
48
|
+
})
|
|
49
|
+
|
|
45
50
|
// Derived list of columns which have not been explicitly hidden
|
|
46
51
|
const visibleColumns = derived(columns, $columns => {
|
|
47
52
|
return $columns.filter(col => col.visible)
|
|
@@ -64,6 +69,7 @@ export const deriveStores = context => {
|
|
|
64
69
|
})
|
|
65
70
|
|
|
66
71
|
return {
|
|
72
|
+
tableColumns,
|
|
67
73
|
displayColumn,
|
|
68
74
|
columnLookupMap,
|
|
69
75
|
visibleColumns,
|
|
@@ -73,16 +79,24 @@ export const deriveStores = context => {
|
|
|
73
79
|
}
|
|
74
80
|
|
|
75
81
|
export const createActions = context => {
|
|
76
|
-
const { columns, datasource
|
|
82
|
+
const { columns, datasource } = context
|
|
77
83
|
|
|
78
84
|
// Updates the width of all columns
|
|
79
85
|
const changeAllColumnWidths = async width => {
|
|
80
|
-
const $
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
86
|
+
const $columns = get(columns)
|
|
87
|
+
$columns.forEach(column => {
|
|
88
|
+
const { related } = column
|
|
89
|
+
const mutation = { width }
|
|
90
|
+
if (!related) {
|
|
91
|
+
datasource.actions.addSchemaMutation(column.name, mutation)
|
|
92
|
+
} else {
|
|
93
|
+
datasource.actions.addSubSchemaMutation(
|
|
94
|
+
related.subField,
|
|
95
|
+
related.field,
|
|
96
|
+
mutation
|
|
97
|
+
)
|
|
98
|
+
}
|
|
84
99
|
})
|
|
85
|
-
datasource.actions.addSchemaMutations(mutations)
|
|
86
100
|
await datasource.actions.saveSchemaMutations()
|
|
87
101
|
}
|
|
88
102
|
|
|
@@ -136,7 +150,7 @@ export const initialise = context => {
|
|
|
136
150
|
.map(field => {
|
|
137
151
|
const fieldSchema = $enrichedSchema[field]
|
|
138
152
|
const oldColumn = $columns?.find(col => col.name === field)
|
|
139
|
-
|
|
153
|
+
const column = {
|
|
140
154
|
name: field,
|
|
141
155
|
label: fieldSchema.displayName || field,
|
|
142
156
|
schema: fieldSchema,
|
|
@@ -145,6 +159,7 @@ export const initialise = context => {
|
|
|
145
159
|
readonly: fieldSchema.readonly,
|
|
146
160
|
order: fieldSchema.order ?? oldColumn?.order,
|
|
147
161
|
conditions: fieldSchema.conditions,
|
|
162
|
+
related: fieldSchema.related,
|
|
148
163
|
}
|
|
149
164
|
// Override a few properties for primary display
|
|
150
165
|
if (field === primaryDisplay) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { derived, get } from "svelte/store"
|
|
2
2
|
import { getDatasourceDefinition, getDatasourceSchema } from "../../../fetch"
|
|
3
|
-
import { memo } from "../../../utils"
|
|
3
|
+
import { enrichSchemaWithRelColumns, memo } from "../../../utils"
|
|
4
4
|
|
|
5
5
|
export const createStores = () => {
|
|
6
6
|
const definition = memo(null)
|
|
@@ -53,10 +53,13 @@ export const deriveStores = context => {
|
|
|
53
53
|
if (!$schema) {
|
|
54
54
|
return null
|
|
55
55
|
}
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
|
|
57
|
+
const schemaWithRelatedColumns = enrichSchemaWithRelColumns($schema)
|
|
58
|
+
|
|
59
|
+
const enrichedSchema = {}
|
|
60
|
+
Object.keys(schemaWithRelatedColumns).forEach(field => {
|
|
58
61
|
enrichedSchema[field] = {
|
|
59
|
-
|
|
62
|
+
...schemaWithRelatedColumns[field],
|
|
60
63
|
...$schemaOverrides?.[field],
|
|
61
64
|
...$schemaMutations[field],
|
|
62
65
|
}
|
|
@@ -202,24 +205,6 @@ export const createActions = context => {
|
|
|
202
205
|
})
|
|
203
206
|
}
|
|
204
207
|
|
|
205
|
-
// Adds schema mutations for multiple fields at once
|
|
206
|
-
const addSchemaMutations = mutations => {
|
|
207
|
-
const fields = Object.keys(mutations || {})
|
|
208
|
-
if (!fields.length) {
|
|
209
|
-
return
|
|
210
|
-
}
|
|
211
|
-
schemaMutations.update($schemaMutations => {
|
|
212
|
-
let newSchemaMutations = { ...$schemaMutations }
|
|
213
|
-
fields.forEach(field => {
|
|
214
|
-
newSchemaMutations[field] = {
|
|
215
|
-
...newSchemaMutations[field],
|
|
216
|
-
...mutations[field],
|
|
217
|
-
}
|
|
218
|
-
})
|
|
219
|
-
return newSchemaMutations
|
|
220
|
-
})
|
|
221
|
-
}
|
|
222
|
-
|
|
223
208
|
// Saves schema changes to the server, if possible
|
|
224
209
|
const saveSchemaMutations = async () => {
|
|
225
210
|
// If we can't save schema changes then we just want to keep this in memory
|
|
@@ -309,7 +294,6 @@ export const createActions = context => {
|
|
|
309
294
|
changePrimaryDisplay,
|
|
310
295
|
addSchemaMutation,
|
|
311
296
|
addSubSchemaMutation,
|
|
312
|
-
addSchemaMutations,
|
|
313
297
|
saveSchemaMutations,
|
|
314
298
|
resetSchemaMutations,
|
|
315
299
|
},
|
|
@@ -120,25 +120,29 @@ export const initialise = context => {
|
|
|
120
120
|
// When sorting changes, ensure view definition is kept up to date
|
|
121
121
|
unsubscribers.push(
|
|
122
122
|
sort.subscribe(async $sort => {
|
|
123
|
+
// Ensure we're updating the correct view
|
|
124
|
+
const $view = get(definition)
|
|
125
|
+
if ($view?.id !== $datasource.id) {
|
|
126
|
+
return
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Skip if nothing actually changed
|
|
130
|
+
if (
|
|
131
|
+
$sort?.column === $view.sort?.field &&
|
|
132
|
+
$sort?.order === $view.sort?.order
|
|
133
|
+
) {
|
|
134
|
+
return
|
|
135
|
+
}
|
|
136
|
+
|
|
123
137
|
// If we can mutate schema then update the view definition
|
|
124
138
|
if (get(config).canSaveSchema) {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
$sort?.order !== $view.sort?.order
|
|
133
|
-
) {
|
|
134
|
-
await datasource.actions.saveDefinition({
|
|
135
|
-
...$view,
|
|
136
|
-
sort: {
|
|
137
|
-
field: $sort.column,
|
|
138
|
-
order: $sort.order || "ascending",
|
|
139
|
-
},
|
|
140
|
-
})
|
|
141
|
-
}
|
|
139
|
+
await datasource.actions.saveDefinition({
|
|
140
|
+
...$view,
|
|
141
|
+
sort: {
|
|
142
|
+
field: $sort.column,
|
|
143
|
+
order: $sort.order || "ascending",
|
|
144
|
+
},
|
|
145
|
+
})
|
|
142
146
|
}
|
|
143
147
|
|
|
144
148
|
// Also update the fetch to ensure the new sort is respected.
|
|
@@ -214,11 +214,20 @@ export const createActions = context => {
|
|
|
214
214
|
})
|
|
215
215
|
|
|
216
216
|
// Extract new orders as schema mutations
|
|
217
|
-
let mutations = {}
|
|
218
217
|
get(columns).forEach((column, idx) => {
|
|
219
|
-
|
|
218
|
+
const { related } = column
|
|
219
|
+
const mutation = { order: idx }
|
|
220
|
+
if (!related) {
|
|
221
|
+
datasource.actions.addSchemaMutation(column.name, mutation)
|
|
222
|
+
} else {
|
|
223
|
+
datasource.actions.addSubSchemaMutation(
|
|
224
|
+
related.subField,
|
|
225
|
+
related.field,
|
|
226
|
+
mutation
|
|
227
|
+
)
|
|
228
|
+
}
|
|
220
229
|
})
|
|
221
|
-
|
|
230
|
+
|
|
222
231
|
await datasource.actions.saveSchemaMutations()
|
|
223
232
|
}
|
|
224
233
|
|
|
@@ -38,6 +38,7 @@ export const createActions = context => {
|
|
|
38
38
|
initialWidth: column.width,
|
|
39
39
|
initialMouseX: x,
|
|
40
40
|
column: column.name,
|
|
41
|
+
related: column.related,
|
|
41
42
|
})
|
|
42
43
|
|
|
43
44
|
// Add mouse event listeners to handle resizing
|
|
@@ -50,7 +51,7 @@ export const createActions = context => {
|
|
|
50
51
|
|
|
51
52
|
// Handler for moving the mouse to resize columns
|
|
52
53
|
const onResizeMouseMove = e => {
|
|
53
|
-
const { initialMouseX, initialWidth, width, column } = get(resize)
|
|
54
|
+
const { initialMouseX, initialWidth, width, column, related } = get(resize)
|
|
54
55
|
const { x } = parseEventLocation(e)
|
|
55
56
|
const dx = x - initialMouseX
|
|
56
57
|
const newWidth = Math.round(Math.max(MinColumnWidth, initialWidth + dx))
|
|
@@ -61,7 +62,13 @@ export const createActions = context => {
|
|
|
61
62
|
}
|
|
62
63
|
|
|
63
64
|
// Update column state
|
|
64
|
-
|
|
65
|
+
if (!related) {
|
|
66
|
+
datasource.actions.addSchemaMutation(column, { width })
|
|
67
|
+
} else {
|
|
68
|
+
datasource.actions.addSubSchemaMutation(related.subField, related.field, {
|
|
69
|
+
width,
|
|
70
|
+
})
|
|
71
|
+
}
|
|
65
72
|
|
|
66
73
|
// Update state
|
|
67
74
|
resize.update(state => ({
|
|
@@ -6,6 +6,7 @@ import { tick } from "svelte"
|
|
|
6
6
|
import { Helpers } from "@budibase/bbui"
|
|
7
7
|
import { sleep } from "../../../utils/utils"
|
|
8
8
|
import { FieldType } from "@budibase/types"
|
|
9
|
+
import { getRelatedTableValues } from "../../../utils"
|
|
9
10
|
|
|
10
11
|
export const createStores = () => {
|
|
11
12
|
const rows = writable([])
|
|
@@ -42,15 +43,26 @@ export const createStores = () => {
|
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
export const deriveStores = context => {
|
|
45
|
-
const { rows } = context
|
|
46
|
+
const { rows, enrichedSchema } = context
|
|
46
47
|
|
|
47
48
|
// Enrich rows with an index property and any pending changes
|
|
48
|
-
const enrichedRows = derived(
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
const enrichedRows = derived(
|
|
50
|
+
[rows, enrichedSchema],
|
|
51
|
+
([$rows, $enrichedSchema]) => {
|
|
52
|
+
const customColumns = Object.values($enrichedSchema || {}).filter(
|
|
53
|
+
f => f.related
|
|
54
|
+
)
|
|
55
|
+
return $rows.map((row, idx) => ({
|
|
56
|
+
...row,
|
|
57
|
+
__idx: idx,
|
|
58
|
+
...customColumns.reduce((map, column) => {
|
|
59
|
+
const fromField = $enrichedSchema[column.related.field]
|
|
60
|
+
map[column.name] = getRelatedTableValues(row, column, fromField)
|
|
61
|
+
return map
|
|
62
|
+
}, {}),
|
|
63
|
+
}))
|
|
64
|
+
}
|
|
65
|
+
)
|
|
54
66
|
|
|
55
67
|
// Generate a lookup map to quick find a row by ID
|
|
56
68
|
const rowLookupMap = derived(enrichedRows, $enrichedRows => {
|
package/src/utils/index.js
CHANGED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { FieldType, RelationshipType } from "@budibase/types"
|
|
2
|
+
import { Helpers } from "@budibase/bbui"
|
|
3
|
+
|
|
4
|
+
const columnTypeManyTypeOverrides = {
|
|
5
|
+
[FieldType.DATETIME]: FieldType.STRING,
|
|
6
|
+
[FieldType.BOOLEAN]: FieldType.STRING,
|
|
7
|
+
[FieldType.SIGNATURE_SINGLE]: FieldType.ATTACHMENTS,
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const columnTypeManyParser = {
|
|
11
|
+
[FieldType.DATETIME]: (value, field) => {
|
|
12
|
+
function parseDate(value) {
|
|
13
|
+
const { timeOnly, dateOnly, ignoreTimezones } = field || {}
|
|
14
|
+
const enableTime = !dateOnly
|
|
15
|
+
const parsedValue = Helpers.parseDate(value, {
|
|
16
|
+
timeOnly,
|
|
17
|
+
enableTime,
|
|
18
|
+
ignoreTimezones,
|
|
19
|
+
})
|
|
20
|
+
const parsed = Helpers.getDateDisplayValue(parsedValue, {
|
|
21
|
+
enableTime,
|
|
22
|
+
timeOnly,
|
|
23
|
+
})
|
|
24
|
+
return parsed
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return value?.map(v => parseDate(v))
|
|
28
|
+
},
|
|
29
|
+
[FieldType.BOOLEAN]: value => value?.map(v => !!v),
|
|
30
|
+
[FieldType.BB_REFERENCE_SINGLE]: value => [
|
|
31
|
+
...new Map(value.map(i => [i._id, i])).values(),
|
|
32
|
+
],
|
|
33
|
+
[FieldType.BB_REFERENCE]: value => [
|
|
34
|
+
...new Map(value.map(i => [i._id, i])).values(),
|
|
35
|
+
],
|
|
36
|
+
[FieldType.ARRAY]: value => Array.from(new Set(value)),
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function enrichSchemaWithRelColumns(schema) {
|
|
40
|
+
if (!schema) {
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
const result = Object.keys(schema).reduce((result, fieldName) => {
|
|
44
|
+
const field = schema[fieldName]
|
|
45
|
+
result[fieldName] = field
|
|
46
|
+
|
|
47
|
+
if (field.visible !== false && field.columns) {
|
|
48
|
+
const fromSingle =
|
|
49
|
+
field?.relationshipType === RelationshipType.ONE_TO_MANY
|
|
50
|
+
|
|
51
|
+
for (const relColumn of Object.keys(field.columns)) {
|
|
52
|
+
const relField = field.columns[relColumn]
|
|
53
|
+
if (!relField.visible) {
|
|
54
|
+
continue
|
|
55
|
+
}
|
|
56
|
+
const name = `${field.name}.${relColumn}`
|
|
57
|
+
result[name] = {
|
|
58
|
+
...relField,
|
|
59
|
+
name,
|
|
60
|
+
related: { field: fieldName, subField: relColumn },
|
|
61
|
+
cellRenderType:
|
|
62
|
+
(!fromSingle && columnTypeManyTypeOverrides[relField.type]) ||
|
|
63
|
+
relField.type,
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return result
|
|
68
|
+
}, {})
|
|
69
|
+
|
|
70
|
+
return result
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function getRelatedTableValues(row, field, fromField) {
|
|
74
|
+
const fromSingle =
|
|
75
|
+
fromField?.relationshipType === RelationshipType.ONE_TO_MANY
|
|
76
|
+
|
|
77
|
+
let result = ""
|
|
78
|
+
|
|
79
|
+
if (fromSingle) {
|
|
80
|
+
result = row[field.related.field]?.[0]?.[field.related.subField]
|
|
81
|
+
} else {
|
|
82
|
+
const parser = columnTypeManyParser[field.type] || (value => value)
|
|
83
|
+
|
|
84
|
+
result = parser(
|
|
85
|
+
row[field.related.field]
|
|
86
|
+
?.flatMap(r => r[field.related.subField])
|
|
87
|
+
?.filter(i => i !== undefined && i !== null),
|
|
88
|
+
field
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
if (
|
|
92
|
+
[
|
|
93
|
+
FieldType.STRING,
|
|
94
|
+
FieldType.NUMBER,
|
|
95
|
+
FieldType.BIGINT,
|
|
96
|
+
FieldType.BOOLEAN,
|
|
97
|
+
FieldType.DATETIME,
|
|
98
|
+
FieldType.LONGFORM,
|
|
99
|
+
FieldType.BARCODEQR,
|
|
100
|
+
].includes(field.type)
|
|
101
|
+
) {
|
|
102
|
+
result = result?.join(", ")
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return result
|
|
107
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as sharedCore from "@budibase/shared-core"
|
|
2
|
+
|
|
3
|
+
export function canBeDisplayColumn(column) {
|
|
4
|
+
if (!sharedCore.canBeDisplayColumn(column.type)) {
|
|
5
|
+
return false
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
if (column.related) {
|
|
9
|
+
// If it's a related column (only available in the frontend), don't allow using it as display column
|
|
10
|
+
return false
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return true
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function canBeSortColumn(column) {
|
|
17
|
+
if (!sharedCore.canBeSortColumn(column.type)) {
|
|
18
|
+
return false
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (column.related) {
|
|
22
|
+
// If it's a related column (only available in the frontend), don't allow using it as display column
|
|
23
|
+
return false
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return true
|
|
27
|
+
}
|