@budibase/frontend-core 3.8.1 → 3.8.3
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/frontend-core",
|
|
3
|
-
"version": "3.8.
|
|
3
|
+
"version": "3.8.3",
|
|
4
4
|
"description": "Budibase frontend core libraries used in builder and client",
|
|
5
5
|
"author": "Budibase",
|
|
6
6
|
"license": "MPL-2.0",
|
|
@@ -17,5 +17,5 @@
|
|
|
17
17
|
"shortid": "2.2.15",
|
|
18
18
|
"socket.io-client": "^4.7.5"
|
|
19
19
|
},
|
|
20
|
-
"gitHead": "
|
|
20
|
+
"gitHead": "9a13dc96f190861b4dda22f159bf85480c46782c"
|
|
21
21
|
}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
<script context="module">
|
|
2
|
-
const NumberFormatter = Intl.NumberFormat()
|
|
3
|
-
</script>
|
|
4
|
-
|
|
5
1
|
<script>
|
|
2
|
+
import { formatNumber } from "@budibase/frontend-core"
|
|
6
3
|
import TextCell from "./TextCell.svelte"
|
|
7
4
|
|
|
8
5
|
export let api
|
|
@@ -13,18 +10,6 @@
|
|
|
13
10
|
const newValue = isNaN(float) ? null : float
|
|
14
11
|
onChange(newValue)
|
|
15
12
|
}
|
|
16
|
-
|
|
17
|
-
const formatNumber = value => {
|
|
18
|
-
const type = typeof value
|
|
19
|
-
if (type !== "string" && type !== "number") {
|
|
20
|
-
return ""
|
|
21
|
-
}
|
|
22
|
-
if (type === "string" && !value.trim().length) {
|
|
23
|
-
return ""
|
|
24
|
-
}
|
|
25
|
-
const res = NumberFormatter.format(value)
|
|
26
|
-
return res === "NaN" ? value : res
|
|
27
|
-
}
|
|
28
13
|
</script>
|
|
29
14
|
|
|
30
15
|
<TextCell
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BBReferenceFieldSubType,
|
|
3
|
+
FieldSchema,
|
|
4
|
+
FieldType,
|
|
5
|
+
Row,
|
|
6
|
+
TableSchema,
|
|
7
|
+
} from "@budibase/types"
|
|
8
|
+
import { Helpers } from "@budibase/bbui"
|
|
9
|
+
|
|
10
|
+
// Singleton formatter to save us creating one every time
|
|
11
|
+
const NumberFormatter = Intl.NumberFormat()
|
|
12
|
+
|
|
13
|
+
export type StringifiedRow = { [key: string]: string }
|
|
14
|
+
|
|
15
|
+
// Formats a number according to the locale
|
|
16
|
+
export const formatNumber = (value: any): string => {
|
|
17
|
+
const type = typeof value
|
|
18
|
+
if (type !== "string" && type !== "number") {
|
|
19
|
+
return ""
|
|
20
|
+
}
|
|
21
|
+
if (type === "string" && !value.trim().length) {
|
|
22
|
+
return ""
|
|
23
|
+
}
|
|
24
|
+
const res = NumberFormatter.format(value)
|
|
25
|
+
return res === "NaN" ? stringifyValue(value) : res
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Attempts to stringify any type of value
|
|
29
|
+
const stringifyValue = (value: any): string => {
|
|
30
|
+
if (value == null) {
|
|
31
|
+
return ""
|
|
32
|
+
}
|
|
33
|
+
if (typeof value === "string") {
|
|
34
|
+
return value
|
|
35
|
+
}
|
|
36
|
+
if (typeof value.toString === "function") {
|
|
37
|
+
return stringifyValue(value.toString())
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
return JSON.stringify(value)
|
|
41
|
+
} catch (e) {
|
|
42
|
+
return ""
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const stringifyField = (value: any, schema: FieldSchema): string => {
|
|
47
|
+
switch (schema.type) {
|
|
48
|
+
// Auto should not exist as it should always be typed by its underlying
|
|
49
|
+
// real type, like date or user
|
|
50
|
+
case FieldType.AUTO:
|
|
51
|
+
return ""
|
|
52
|
+
|
|
53
|
+
// Just state whether signatures exist or not
|
|
54
|
+
case FieldType.SIGNATURE_SINGLE:
|
|
55
|
+
return value ? "Yes" : "No"
|
|
56
|
+
|
|
57
|
+
// Extract attachment names
|
|
58
|
+
case FieldType.ATTACHMENT_SINGLE:
|
|
59
|
+
case FieldType.ATTACHMENTS: {
|
|
60
|
+
if (!value) {
|
|
61
|
+
return ""
|
|
62
|
+
}
|
|
63
|
+
const arrayValue = Array.isArray(value) ? value : [value]
|
|
64
|
+
return arrayValue
|
|
65
|
+
.map(x => x.name)
|
|
66
|
+
.filter(x => !!x)
|
|
67
|
+
.join(", ")
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Extract primary displays from relationships
|
|
71
|
+
case FieldType.LINK: {
|
|
72
|
+
if (!value) {
|
|
73
|
+
return ""
|
|
74
|
+
}
|
|
75
|
+
const arrayValue = Array.isArray(value) ? value : [value]
|
|
76
|
+
return arrayValue
|
|
77
|
+
.map(x => x.primaryDisplay)
|
|
78
|
+
.filter(x => !!x)
|
|
79
|
+
.join(", ")
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Stringify JSON blobs
|
|
83
|
+
case FieldType.JSON:
|
|
84
|
+
return value ? JSON.stringify(value) : ""
|
|
85
|
+
|
|
86
|
+
// User is the only BB reference subtype right now
|
|
87
|
+
case FieldType.BB_REFERENCE:
|
|
88
|
+
case FieldType.BB_REFERENCE_SINGLE: {
|
|
89
|
+
if (
|
|
90
|
+
schema.subtype !== BBReferenceFieldSubType.USERS &&
|
|
91
|
+
schema.subtype !== BBReferenceFieldSubType.USER
|
|
92
|
+
) {
|
|
93
|
+
return ""
|
|
94
|
+
}
|
|
95
|
+
if (!value) {
|
|
96
|
+
return ""
|
|
97
|
+
}
|
|
98
|
+
const arrayVal = Array.isArray(value) ? value : [value]
|
|
99
|
+
return arrayVal?.map((user: any) => user.primaryDisplay).join(", ") || ""
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Join arrays with commas
|
|
103
|
+
case FieldType.ARRAY:
|
|
104
|
+
return value?.join(", ") || ""
|
|
105
|
+
|
|
106
|
+
// Just capitalise booleans
|
|
107
|
+
case FieldType.BOOLEAN:
|
|
108
|
+
return Helpers.capitalise(value?.toString() || "false")
|
|
109
|
+
|
|
110
|
+
// Format dates into something readable
|
|
111
|
+
case FieldType.DATETIME: {
|
|
112
|
+
return Helpers.getDateDisplayValue(value, {
|
|
113
|
+
enableTime: !schema.dateOnly,
|
|
114
|
+
timeOnly: schema.timeOnly,
|
|
115
|
+
})
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Format numbers using a locale string
|
|
119
|
+
case FieldType.NUMBER:
|
|
120
|
+
return formatNumber(value)
|
|
121
|
+
|
|
122
|
+
// Simple string types
|
|
123
|
+
case FieldType.STRING:
|
|
124
|
+
case FieldType.LONGFORM:
|
|
125
|
+
case FieldType.BIGINT:
|
|
126
|
+
case FieldType.OPTIONS:
|
|
127
|
+
case FieldType.AI:
|
|
128
|
+
case FieldType.BARCODEQR:
|
|
129
|
+
return value || ""
|
|
130
|
+
|
|
131
|
+
// Fallback for unknown types or future column types that we forget to add
|
|
132
|
+
case FieldType.FORMULA:
|
|
133
|
+
default:
|
|
134
|
+
return stringifyValue(value)
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Stringifies every property of a row, ensuring they are all human-readable
|
|
139
|
+
// strings for display
|
|
140
|
+
export const stringifyRow = (row: Row, schema: TableSchema): StringifiedRow => {
|
|
141
|
+
let stringified: StringifiedRow = {}
|
|
142
|
+
Object.entries(schema).forEach(([field, fieldSchema]) => {
|
|
143
|
+
stringified[field] = stringifyField(
|
|
144
|
+
Helpers.deepGet(row, field),
|
|
145
|
+
fieldSchema
|
|
146
|
+
)
|
|
147
|
+
})
|
|
148
|
+
return stringified
|
|
149
|
+
}
|
package/src/utils/index.ts
CHANGED
package/src/utils/schema.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { helpers } from "@budibase/shared-core"
|
|
2
2
|
import { TypeIconMap } from "../constants"
|
|
3
|
+
import { convertJSONSchemaToTableSchema } from "./json"
|
|
3
4
|
|
|
4
5
|
export const getColumnIcon = column => {
|
|
5
6
|
// For some reason we have remix icons saved under this property sometimes,
|
|
@@ -24,3 +25,25 @@ export const getColumnIcon = column => {
|
|
|
24
25
|
|
|
25
26
|
return result || "Text"
|
|
26
27
|
}
|
|
28
|
+
|
|
29
|
+
export const addNestedJSONSchemaFields = schema => {
|
|
30
|
+
if (!schema) {
|
|
31
|
+
return schema
|
|
32
|
+
}
|
|
33
|
+
let jsonAdditions = {}
|
|
34
|
+
Object.keys(schema).forEach(fieldKey => {
|
|
35
|
+
const fieldSchema = schema[fieldKey]
|
|
36
|
+
if (fieldSchema?.type === "json") {
|
|
37
|
+
const jsonSchema = convertJSONSchemaToTableSchema(fieldSchema, {
|
|
38
|
+
squashObjects: true,
|
|
39
|
+
})
|
|
40
|
+
Object.keys(jsonSchema).forEach(jsonKey => {
|
|
41
|
+
jsonAdditions[`${fieldKey}.${jsonKey}`] = {
|
|
42
|
+
type: jsonSchema[jsonKey].type,
|
|
43
|
+
nestedJSON: true,
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
return { ...schema, ...jsonAdditions }
|
|
49
|
+
}
|