@budibase/frontend-core 3.2.28 → 3.2.30
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 +9 -3
- package/src/api/ai.ts +17 -0
- package/src/api/analytics.ts +39 -0
- package/src/api/{app.js → app.ts} +84 -5
- package/src/api/attachments.ts +121 -0
- package/src/api/auditLogs.ts +35 -0
- package/src/api/{auth.js → auth.ts} +44 -7
- package/src/api/automations.ts +158 -0
- package/src/api/backups.ts +50 -0
- package/src/api/{configs.js → configs.ts} +31 -3
- package/src/api/datasources.ts +132 -0
- package/src/api/environmentVariables.ts +58 -0
- package/src/api/events.ts +21 -0
- package/src/api/flags.ts +48 -0
- package/src/api/{groups.js → groups.ts} +73 -17
- package/src/api/{index.js → index.ts} +89 -102
- package/src/api/layouts.ts +35 -0
- package/src/api/licensing.ts +107 -0
- package/src/api/{logs.js → logs.ts} +7 -1
- package/src/api/migrations.ts +19 -0
- package/src/api/{other.js → other.ts} +19 -12
- package/src/api/{permissions.js → permissions.ts} +31 -5
- package/src/api/{plugins.js → plugins.ts} +18 -1
- package/src/api/{queries.js → queries.ts} +39 -14
- package/src/api/relationships.ts +31 -0
- package/src/api/{roles.js → roles.ts} +22 -5
- package/src/api/routes.ts +30 -0
- package/src/api/{rowActions.js → rowActions.ts} +45 -27
- package/src/api/rows.ts +120 -0
- package/src/api/screens.ts +35 -0
- package/src/api/{self.js → self.ts} +20 -4
- package/src/api/tables.ts +192 -0
- package/src/api/templates.ts +57 -0
- package/src/api/types.ts +136 -0
- package/src/api/{user.js → user.ts} +111 -119
- package/src/api/{views.js → views.ts} +18 -7
- package/src/api/{viewsV2.js → viewsV2.ts} +30 -27
- package/src/components/grid/cells/AICell.svelte +1 -0
- package/src/components/grid/cells/LongFormCell.svelte +1 -0
- package/src/components/grid/cells/RelationshipCell.svelte +1 -2
- package/src/components/grid/cells/TextCell.svelte +3 -0
- package/src/components/grid/controls/MigrationModal.svelte +5 -5
- package/src/components/grid/layout/Grid.svelte +5 -8
- package/src/components/grid/lib/constants.js +1 -1
- package/src/components/grid/lib/{events.js → events.ts} +3 -3
- package/src/components/grid/lib/utils.js +2 -0
- package/src/components/grid/lib/utils.ts +32 -0
- package/src/components/grid/stores/bounds.ts +29 -0
- package/src/components/grid/stores/{cache.js → cache.ts} +21 -6
- package/src/components/grid/stores/{clipboard.js → clipboard.ts} +55 -19
- package/src/components/grid/stores/{columns.js → columns.ts} +47 -19
- package/src/components/grid/stores/{conditions.js → conditions.ts} +32 -12
- package/src/components/grid/stores/{config.js → config.ts} +16 -6
- package/src/components/grid/stores/{datasource.js → datasource.ts} +86 -36
- package/src/components/grid/stores/datasources/index.ts +31 -0
- package/src/components/grid/stores/datasources/{nonPlus.js → nonPlus.ts} +21 -11
- package/src/components/grid/stores/datasources/{table.js → table.ts} +39 -21
- package/src/components/grid/stores/datasources/{viewV2.js → viewV2.ts} +74 -28
- package/src/components/grid/stores/{filter.js → filter.ts} +39 -16
- package/src/components/grid/stores/index.ts +143 -0
- package/src/components/grid/stores/{menu.js → menu.ts} +31 -6
- package/src/components/grid/stores/{notifications.js → notifications.ts} +12 -2
- package/src/components/grid/stores/{pagination.js → pagination.ts} +2 -1
- package/src/components/grid/stores/{reorder.js → reorder.ts} +47 -15
- package/src/components/grid/stores/{resize.js → resize.ts} +28 -10
- package/src/components/grid/stores/{rows.js → rows.ts} +167 -53
- package/src/components/grid/stores/{scroll.js → scroll.ts} +28 -5
- package/src/components/grid/stores/{sort.js → sort.ts} +13 -3
- package/src/components/grid/stores/{ui.js → ui.ts} +77 -20
- package/src/components/grid/stores/{users.js → users.ts} +36 -9
- package/src/components/grid/stores/{validation.js → validation.ts} +35 -12
- package/src/components/grid/stores/{viewport.js → viewport.ts} +14 -3
- package/src/{constants.js → constants.ts} +2 -2
- package/src/fetch/QueryFetch.js +2 -2
- package/src/fetch/RelationshipFetch.js +9 -6
- package/src/fetch/TableFetch.js +1 -2
- package/src/fetch/ViewFetch.js +1 -1
- package/src/fetch/ViewV2Fetch.js +1 -2
- package/src/utils/memo.d.ts +10 -0
- package/src/utils/relatedColumns.ts +126 -0
- package/tsconfig.json +14 -0
- package/src/api/ai.js +0 -11
- package/src/api/analytics.js +0 -17
- package/src/api/attachments.js +0 -78
- package/src/api/auditLogs.js +0 -63
- package/src/api/automations.js +0 -111
- package/src/api/backups.js +0 -46
- package/src/api/datasources.js +0 -92
- package/src/api/environmentVariables.js +0 -36
- package/src/api/events.js +0 -13
- package/src/api/flags.js +0 -34
- package/src/api/hosting.js +0 -19
- package/src/api/layouts.js +0 -23
- package/src/api/licensing.js +0 -75
- package/src/api/migrations.js +0 -10
- package/src/api/relationships.js +0 -21
- package/src/api/routes.js +0 -19
- package/src/api/rows.js +0 -117
- package/src/api/screens.js +0 -23
- package/src/api/tables.js +0 -152
- package/src/api/templates.js +0 -35
- package/src/components/grid/stores/bounds.js +0 -16
- package/src/components/grid/stores/index.js +0 -73
- package/src/utils/relatedColumns.js +0 -103
- /package/src/{index.js → index.ts} +0 -0
- /package/src/utils/{index.js → index.ts} +0 -0
|
@@ -1,10 +1,54 @@
|
|
|
1
|
-
import { derived, get } from "svelte/store"
|
|
1
|
+
import { derived, get, Readable, Writable } from "svelte/store"
|
|
2
2
|
import { getDatasourceDefinition, getDatasourceSchema } from "../../../fetch"
|
|
3
3
|
import { enrichSchemaWithRelColumns, memo } from "../../../utils"
|
|
4
4
|
import { cloneDeep } from "lodash"
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
SaveRowRequest,
|
|
7
|
+
SaveTableRequest,
|
|
8
|
+
UIDatasource,
|
|
9
|
+
UIFieldMutation,
|
|
10
|
+
UIFieldSchema,
|
|
11
|
+
UIRow,
|
|
12
|
+
UpdateViewRequest,
|
|
13
|
+
ViewV2Type,
|
|
14
|
+
} from "@budibase/types"
|
|
15
|
+
import { Store as StoreContext, BaseStoreProps } from "."
|
|
16
|
+
import { DatasourceActions } from "./datasources"
|
|
17
|
+
|
|
18
|
+
interface DatasourceStore {
|
|
19
|
+
definition: Writable<UIDatasource | null>
|
|
20
|
+
schemaMutations: Writable<Record<string, UIFieldMutation>>
|
|
21
|
+
subSchemaMutations: Writable<Record<string, Record<string, UIFieldMutation>>>
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
interface DerivedDatasourceStore {
|
|
25
|
+
schema: Readable<Record<string, UIFieldSchema> | null>
|
|
26
|
+
enrichedSchema: Readable<Record<string, UIFieldSchema> | null>
|
|
27
|
+
hasBudibaseIdentifiers: Readable<boolean>
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface ActionDatasourceStore {
|
|
31
|
+
datasource: BaseStoreProps["datasource"] & {
|
|
32
|
+
actions: DatasourceActions & {
|
|
33
|
+
refreshDefinition: () => Promise<void>
|
|
34
|
+
changePrimaryDisplay: (column: string) => Promise<void>
|
|
35
|
+
addSchemaMutation: (field: string, mutation: UIFieldMutation) => void
|
|
36
|
+
addSubSchemaMutation: (
|
|
37
|
+
field: string,
|
|
38
|
+
fromField: string,
|
|
39
|
+
mutation: UIFieldMutation
|
|
40
|
+
) => void
|
|
41
|
+
saveSchemaMutations: () => Promise<void>
|
|
42
|
+
resetSchemaMutations: () => void
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export type Store = DatasourceStore &
|
|
48
|
+
DerivedDatasourceStore &
|
|
49
|
+
ActionDatasourceStore
|
|
6
50
|
|
|
7
|
-
export const createStores = () => {
|
|
51
|
+
export const createStores = (): DatasourceStore => {
|
|
8
52
|
const definition = memo(null)
|
|
9
53
|
const schemaMutations = memo({})
|
|
10
54
|
const subSchemaMutations = memo({})
|
|
@@ -16,7 +60,7 @@ export const createStores = () => {
|
|
|
16
60
|
}
|
|
17
61
|
}
|
|
18
62
|
|
|
19
|
-
export const deriveStores = context => {
|
|
63
|
+
export const deriveStores = (context: StoreContext): DerivedDatasourceStore => {
|
|
20
64
|
const {
|
|
21
65
|
API,
|
|
22
66
|
definition,
|
|
@@ -27,7 +71,7 @@ export const deriveStores = context => {
|
|
|
27
71
|
} = context
|
|
28
72
|
|
|
29
73
|
const schema = derived(definition, $definition => {
|
|
30
|
-
let schema = getDatasourceSchema({
|
|
74
|
+
let schema: Record<string, UIFieldSchema> = getDatasourceSchema({
|
|
31
75
|
API,
|
|
32
76
|
datasource: get(datasource),
|
|
33
77
|
definition: $definition,
|
|
@@ -40,7 +84,7 @@ export const deriveStores = context => {
|
|
|
40
84
|
// Certain datasources like queries use primitives.
|
|
41
85
|
Object.keys(schema || {}).forEach(key => {
|
|
42
86
|
if (typeof schema[key] !== "object") {
|
|
43
|
-
schema[key] = { type: schema[key] }
|
|
87
|
+
schema[key] = { name: key, type: schema[key] }
|
|
44
88
|
}
|
|
45
89
|
})
|
|
46
90
|
|
|
@@ -58,19 +102,18 @@ export const deriveStores = context => {
|
|
|
58
102
|
|
|
59
103
|
const schemaWithRelatedColumns = enrichSchemaWithRelColumns($schema)
|
|
60
104
|
|
|
61
|
-
const enrichedSchema = {}
|
|
62
|
-
Object.keys(schemaWithRelatedColumns).forEach(field => {
|
|
105
|
+
const enrichedSchema: Record<string, UIFieldSchema> = {}
|
|
106
|
+
Object.keys(schemaWithRelatedColumns || {}).forEach(field => {
|
|
63
107
|
enrichedSchema[field] = {
|
|
64
|
-
...schemaWithRelatedColumns[field],
|
|
108
|
+
...schemaWithRelatedColumns?.[field],
|
|
65
109
|
...$schemaOverrides?.[field],
|
|
66
110
|
...$schemaMutations[field],
|
|
67
111
|
}
|
|
68
112
|
|
|
69
113
|
if ($subSchemaMutations[field]) {
|
|
70
114
|
enrichedSchema[field].columns ??= {}
|
|
71
|
-
for (const
|
|
72
|
-
$subSchemaMutations[field]
|
|
73
|
-
)) {
|
|
115
|
+
for (const fieldName of Object.keys($subSchemaMutations[field])) {
|
|
116
|
+
const mutation = $subSchemaMutations[field][fieldName]
|
|
74
117
|
enrichedSchema[field].columns[fieldName] = {
|
|
75
118
|
...enrichedSchema[field].columns[fieldName],
|
|
76
119
|
...mutation,
|
|
@@ -87,7 +130,7 @@ export const deriveStores = context => {
|
|
|
87
130
|
([$datasource, $definition]) => {
|
|
88
131
|
let type = $datasource?.type
|
|
89
132
|
if (type === "provider") {
|
|
90
|
-
type = $datasource.value?.datasource?.type
|
|
133
|
+
type = ($datasource as any).value?.datasource?.type
|
|
91
134
|
}
|
|
92
135
|
// Handle calculation views
|
|
93
136
|
if (type === "viewV2" && $definition?.type === ViewV2Type.CALCULATION) {
|
|
@@ -104,7 +147,7 @@ export const deriveStores = context => {
|
|
|
104
147
|
}
|
|
105
148
|
}
|
|
106
149
|
|
|
107
|
-
export const createActions = context => {
|
|
150
|
+
export const createActions = (context: StoreContext): ActionDatasourceStore => {
|
|
108
151
|
const {
|
|
109
152
|
API,
|
|
110
153
|
datasource,
|
|
@@ -147,21 +190,23 @@ export const createActions = context => {
|
|
|
147
190
|
}
|
|
148
191
|
|
|
149
192
|
// Saves the datasource definition
|
|
150
|
-
const saveDefinition = async
|
|
193
|
+
const saveDefinition = async (
|
|
194
|
+
newDefinition: SaveTableRequest | UpdateViewRequest
|
|
195
|
+
) => {
|
|
151
196
|
// Update local state
|
|
152
197
|
const originalDefinition = get(definition)
|
|
153
|
-
definition.set(newDefinition)
|
|
198
|
+
definition.set(newDefinition as UIDatasource)
|
|
154
199
|
|
|
155
200
|
// Update server
|
|
156
201
|
if (get(config).canSaveSchema) {
|
|
157
202
|
try {
|
|
158
|
-
await getAPI()?.actions.saveDefinition(newDefinition)
|
|
203
|
+
await getAPI()?.actions.saveDefinition(newDefinition as never)
|
|
159
204
|
|
|
160
205
|
// Broadcast change so external state can be updated, as this change
|
|
161
206
|
// will not be received by the builder websocket because we caused it
|
|
162
207
|
// ourselves
|
|
163
208
|
dispatch("updatedatasource", newDefinition)
|
|
164
|
-
} catch (error) {
|
|
209
|
+
} catch (error: any) {
|
|
165
210
|
const msg = error?.message || error || "Unknown error"
|
|
166
211
|
get(notifications).error(`Error saving schema: ${msg}`)
|
|
167
212
|
|
|
@@ -172,8 +217,8 @@ export const createActions = context => {
|
|
|
172
217
|
}
|
|
173
218
|
|
|
174
219
|
// Updates the datasources primary display column
|
|
175
|
-
const changePrimaryDisplay = async column => {
|
|
176
|
-
let newDefinition = cloneDeep(get(definition))
|
|
220
|
+
const changePrimaryDisplay = async (column: string) => {
|
|
221
|
+
let newDefinition = cloneDeep(get(definition)!)
|
|
177
222
|
|
|
178
223
|
// Update primary display
|
|
179
224
|
newDefinition.primaryDisplay = column
|
|
@@ -183,12 +228,14 @@ export const createActions = context => {
|
|
|
183
228
|
newDefinition.schema[column].constraints = {}
|
|
184
229
|
}
|
|
185
230
|
newDefinition.schema[column].constraints.presence = { allowEmpty: false }
|
|
186
|
-
|
|
187
|
-
|
|
231
|
+
if ("default" in newDefinition.schema[column]) {
|
|
232
|
+
delete newDefinition.schema[column].default
|
|
233
|
+
}
|
|
234
|
+
return await saveDefinition(newDefinition as any)
|
|
188
235
|
}
|
|
189
236
|
|
|
190
237
|
// Adds a schema mutation for a single field
|
|
191
|
-
const addSchemaMutation = (field, mutation) => {
|
|
238
|
+
const addSchemaMutation = (field: string, mutation: UIFieldMutation) => {
|
|
192
239
|
if (!field || !mutation) {
|
|
193
240
|
return
|
|
194
241
|
}
|
|
@@ -204,7 +251,11 @@ export const createActions = context => {
|
|
|
204
251
|
}
|
|
205
252
|
|
|
206
253
|
// Adds a nested schema mutation for a single field
|
|
207
|
-
const addSubSchemaMutation = (
|
|
254
|
+
const addSubSchemaMutation = (
|
|
255
|
+
field: string,
|
|
256
|
+
fromField: string,
|
|
257
|
+
mutation: UIFieldMutation
|
|
258
|
+
) => {
|
|
208
259
|
if (!field || !fromField || !mutation) {
|
|
209
260
|
return
|
|
210
261
|
}
|
|
@@ -231,8 +282,8 @@ export const createActions = context => {
|
|
|
231
282
|
const $definition = get(definition)
|
|
232
283
|
const $schemaMutations = get(schemaMutations)
|
|
233
284
|
const $subSchemaMutations = get(subSchemaMutations)
|
|
234
|
-
const $schema = get(schema)
|
|
235
|
-
let newSchema = {}
|
|
285
|
+
const $schema = get(schema) || {}
|
|
286
|
+
let newSchema: Record<string, UIFieldSchema> = {}
|
|
236
287
|
|
|
237
288
|
// Build new updated datasource schema
|
|
238
289
|
Object.keys($schema).forEach(column => {
|
|
@@ -242,9 +293,8 @@ export const createActions = context => {
|
|
|
242
293
|
}
|
|
243
294
|
if ($subSchemaMutations[column]) {
|
|
244
295
|
newSchema[column].columns ??= {}
|
|
245
|
-
for (const
|
|
246
|
-
$subSchemaMutations[column]
|
|
247
|
-
)) {
|
|
296
|
+
for (const fieldName of Object.keys($subSchemaMutations[column])) {
|
|
297
|
+
const mutation = $subSchemaMutations[column][fieldName]
|
|
248
298
|
newSchema[column].columns[fieldName] = {
|
|
249
299
|
...newSchema[column].columns[fieldName],
|
|
250
300
|
...mutation,
|
|
@@ -257,7 +307,7 @@ export const createActions = context => {
|
|
|
257
307
|
await saveDefinition({
|
|
258
308
|
...$definition,
|
|
259
309
|
schema: newSchema,
|
|
260
|
-
})
|
|
310
|
+
} as any)
|
|
261
311
|
resetSchemaMutations()
|
|
262
312
|
}
|
|
263
313
|
|
|
@@ -267,32 +317,32 @@ export const createActions = context => {
|
|
|
267
317
|
}
|
|
268
318
|
|
|
269
319
|
// Adds a row to the datasource
|
|
270
|
-
const addRow = async row => {
|
|
320
|
+
const addRow = async (row: SaveRowRequest) => {
|
|
271
321
|
return await getAPI()?.actions.addRow(row)
|
|
272
322
|
}
|
|
273
323
|
|
|
274
324
|
// Updates an existing row in the datasource
|
|
275
|
-
const updateRow = async row => {
|
|
325
|
+
const updateRow = async (row: SaveRowRequest) => {
|
|
276
326
|
return await getAPI()?.actions.updateRow(row)
|
|
277
327
|
}
|
|
278
328
|
|
|
279
329
|
// Deletes rows from the datasource
|
|
280
|
-
const deleteRows = async rows => {
|
|
330
|
+
const deleteRows = async (rows: UIRow[]) => {
|
|
281
331
|
return await getAPI()?.actions.deleteRows(rows)
|
|
282
332
|
}
|
|
283
333
|
|
|
284
334
|
// Gets a single row from a datasource
|
|
285
|
-
const getRow = async id => {
|
|
335
|
+
const getRow = async (id: string) => {
|
|
286
336
|
return await getAPI()?.actions.getRow(id)
|
|
287
337
|
}
|
|
288
338
|
|
|
289
339
|
// Checks if a certain datasource config is valid
|
|
290
|
-
const isDatasourceValid = datasource => {
|
|
340
|
+
const isDatasourceValid = (datasource: UIDatasource) => {
|
|
291
341
|
return getAPI()?.actions.isDatasourceValid(datasource)
|
|
292
342
|
}
|
|
293
343
|
|
|
294
344
|
// Checks if this datasource can use a specific column by name
|
|
295
|
-
const canUseColumn = name => {
|
|
345
|
+
const canUseColumn = (name: string) => {
|
|
296
346
|
return getAPI()?.actions.canUseColumn(name)
|
|
297
347
|
}
|
|
298
348
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SaveRowRequest,
|
|
3
|
+
SaveTableRequest,
|
|
4
|
+
UIDatasource,
|
|
5
|
+
UIRow,
|
|
6
|
+
UpdateViewRequest,
|
|
7
|
+
} from "@budibase/types"
|
|
8
|
+
|
|
9
|
+
interface DatasourceBaseActions<
|
|
10
|
+
TSaveDefinitionRequest = UpdateViewRequest | SaveTableRequest
|
|
11
|
+
> {
|
|
12
|
+
saveDefinition: (newDefinition: TSaveDefinitionRequest) => Promise<void>
|
|
13
|
+
addRow: (row: SaveRowRequest) => Promise<UIRow | undefined>
|
|
14
|
+
updateRow: (row: SaveRowRequest) => Promise<UIRow | undefined>
|
|
15
|
+
deleteRows: (rows: UIRow[]) => Promise<void>
|
|
16
|
+
getRow: (id: string) => Promise<UIRow | void>
|
|
17
|
+
isDatasourceValid: (datasource: UIDatasource) => boolean | void
|
|
18
|
+
canUseColumn: (name: string) => boolean | void
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface DatasourceTableActions
|
|
22
|
+
extends DatasourceBaseActions<SaveTableRequest> {}
|
|
23
|
+
|
|
24
|
+
export interface DatasourceViewActions
|
|
25
|
+
extends DatasourceBaseActions<UpdateViewRequest> {}
|
|
26
|
+
|
|
27
|
+
export interface DatasourceNonPlusActions
|
|
28
|
+
extends DatasourceBaseActions<never> {}
|
|
29
|
+
|
|
30
|
+
export type DatasourceActions =
|
|
31
|
+
| DatasourceTableActions & DatasourceViewActions & DatasourceNonPlusActions
|
|
@@ -1,7 +1,17 @@
|
|
|
1
|
-
import { SortOrder } from "@budibase/types"
|
|
1
|
+
import { SortOrder, UIDatasource } from "@budibase/types"
|
|
2
2
|
import { get } from "svelte/store"
|
|
3
|
+
import { Store as StoreContext } from ".."
|
|
4
|
+
import { DatasourceNonPlusActions } from "."
|
|
3
5
|
|
|
4
|
-
|
|
6
|
+
interface NonPlusActions {
|
|
7
|
+
nonPlus: {
|
|
8
|
+
actions: DatasourceNonPlusActions
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type Store = NonPlusActions
|
|
13
|
+
|
|
14
|
+
export const createActions = (context: StoreContext): NonPlusActions => {
|
|
5
15
|
const { columns, table, viewV2 } = context
|
|
6
16
|
|
|
7
17
|
const saveDefinition = async () => {
|
|
@@ -20,7 +30,7 @@ export const createActions = context => {
|
|
|
20
30
|
throw "This datasource does not support fetching individual rows"
|
|
21
31
|
}
|
|
22
32
|
|
|
23
|
-
const isDatasourceValid = datasource => {
|
|
33
|
+
const isDatasourceValid = (datasource: UIDatasource) => {
|
|
24
34
|
// There are many different types and shapes of datasource, so we only
|
|
25
35
|
// check that we aren't null
|
|
26
36
|
return (
|
|
@@ -30,7 +40,7 @@ export const createActions = context => {
|
|
|
30
40
|
)
|
|
31
41
|
}
|
|
32
42
|
|
|
33
|
-
const canUseColumn = name => {
|
|
43
|
+
const canUseColumn = (name: string) => {
|
|
34
44
|
return get(columns).some(col => col.name === name)
|
|
35
45
|
}
|
|
36
46
|
|
|
@@ -50,11 +60,11 @@ export const createActions = context => {
|
|
|
50
60
|
}
|
|
51
61
|
|
|
52
62
|
// Small util to compare datasource definitions
|
|
53
|
-
const isSameDatasource = (a, b) => {
|
|
63
|
+
const isSameDatasource = (a: any, b: any) => {
|
|
54
64
|
return JSON.stringify(a) === JSON.stringify(b)
|
|
55
65
|
}
|
|
56
66
|
|
|
57
|
-
export const initialise = context => {
|
|
67
|
+
export const initialise = (context: StoreContext) => {
|
|
58
68
|
const {
|
|
59
69
|
datasource,
|
|
60
70
|
sort,
|
|
@@ -69,7 +79,7 @@ export const initialise = context => {
|
|
|
69
79
|
} = context
|
|
70
80
|
// Keep a list of subscriptions so that we can clear them when the datasource
|
|
71
81
|
// config changes
|
|
72
|
-
let unsubscribers = []
|
|
82
|
+
let unsubscribers: any[] = []
|
|
73
83
|
|
|
74
84
|
// Observe datasource changes and apply logic for view V2 datasources
|
|
75
85
|
datasource.subscribe($datasource => {
|
|
@@ -81,7 +91,7 @@ export const initialise = context => {
|
|
|
81
91
|
}
|
|
82
92
|
|
|
83
93
|
// Wipe state
|
|
84
|
-
filter.set(get(initialFilter))
|
|
94
|
+
filter.set(get(initialFilter) ?? undefined)
|
|
85
95
|
inlineFilters.set([])
|
|
86
96
|
sort.set({
|
|
87
97
|
column: get(initialSortColumn),
|
|
@@ -96,7 +106,7 @@ export const initialise = context => {
|
|
|
96
106
|
if (!isSameDatasource($fetch?.options?.datasource, $datasource)) {
|
|
97
107
|
return
|
|
98
108
|
}
|
|
99
|
-
$fetch
|
|
109
|
+
$fetch?.update({
|
|
100
110
|
filter: $allFilters,
|
|
101
111
|
})
|
|
102
112
|
})
|
|
@@ -110,9 +120,9 @@ export const initialise = context => {
|
|
|
110
120
|
if (!isSameDatasource($fetch?.options?.datasource, $datasource)) {
|
|
111
121
|
return
|
|
112
122
|
}
|
|
113
|
-
$fetch
|
|
123
|
+
$fetch?.update({
|
|
114
124
|
sortOrder: $sort.order || SortOrder.ASCENDING,
|
|
115
|
-
sortColumn: $sort.column,
|
|
125
|
+
sortColumn: $sort.column ?? undefined,
|
|
116
126
|
})
|
|
117
127
|
})
|
|
118
128
|
)
|
|
@@ -1,37 +1,50 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
Row,
|
|
3
|
+
SaveRowRequest,
|
|
4
|
+
SaveTableRequest,
|
|
5
|
+
SortOrder,
|
|
6
|
+
UIDatasource,
|
|
7
|
+
} from "@budibase/types"
|
|
2
8
|
import { get } from "svelte/store"
|
|
9
|
+
import { Store as StoreContext } from ".."
|
|
10
|
+
import { DatasourceTableActions } from "."
|
|
3
11
|
|
|
4
12
|
const SuppressErrors = true
|
|
5
13
|
|
|
6
|
-
|
|
14
|
+
interface TableActions {
|
|
15
|
+
table: {
|
|
16
|
+
actions: DatasourceTableActions
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type Store = TableActions
|
|
21
|
+
|
|
22
|
+
export const createActions = (context: StoreContext): TableActions => {
|
|
7
23
|
const { API, datasource, columns } = context
|
|
8
24
|
|
|
9
|
-
const saveDefinition = async newDefinition => {
|
|
25
|
+
const saveDefinition = async (newDefinition: SaveTableRequest) => {
|
|
10
26
|
await API.saveTable(newDefinition)
|
|
11
27
|
}
|
|
12
28
|
|
|
13
|
-
const saveRow = async row => {
|
|
29
|
+
const saveRow = async (row: SaveRowRequest) => {
|
|
14
30
|
row = {
|
|
15
31
|
...row,
|
|
16
32
|
tableId: get(datasource)?.tableId,
|
|
17
33
|
}
|
|
18
|
-
|
|
34
|
+
const newRow = await API.saveRow(row, SuppressErrors)
|
|
35
|
+
return { ...newRow, _id: newRow._id! }
|
|
19
36
|
}
|
|
20
37
|
|
|
21
|
-
const deleteRows = async rows => {
|
|
22
|
-
await API.deleteRows(
|
|
23
|
-
tableId: get(datasource).tableId,
|
|
24
|
-
rows,
|
|
25
|
-
})
|
|
38
|
+
const deleteRows = async (rows: Row[]) => {
|
|
39
|
+
await API.deleteRows(get(datasource).tableId, rows)
|
|
26
40
|
}
|
|
27
41
|
|
|
28
|
-
const isDatasourceValid = datasource => {
|
|
29
|
-
return datasource?.type === "table" && datasource?.tableId
|
|
42
|
+
const isDatasourceValid = (datasource: UIDatasource) => {
|
|
43
|
+
return datasource?.type === "table" && !!datasource?.tableId
|
|
30
44
|
}
|
|
31
45
|
|
|
32
|
-
const getRow = async id => {
|
|
33
|
-
const res = await API.searchTable({
|
|
34
|
-
tableId: get(datasource).tableId,
|
|
46
|
+
const getRow = async (id: any) => {
|
|
47
|
+
const res = await API.searchTable(get(datasource).tableId, {
|
|
35
48
|
limit: 1,
|
|
36
49
|
query: {
|
|
37
50
|
equal: {
|
|
@@ -40,10 +53,15 @@ export const createActions = context => {
|
|
|
40
53
|
},
|
|
41
54
|
paginate: false,
|
|
42
55
|
})
|
|
43
|
-
|
|
56
|
+
const row = res?.rows?.[0]
|
|
57
|
+
if (!row) {
|
|
58
|
+
return
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return { ...row, _id: row._id! }
|
|
44
62
|
}
|
|
45
63
|
|
|
46
|
-
const canUseColumn = name => {
|
|
64
|
+
const canUseColumn = (name: string) => {
|
|
47
65
|
return get(columns).some(col => col.name === name)
|
|
48
66
|
}
|
|
49
67
|
|
|
@@ -62,7 +80,7 @@ export const createActions = context => {
|
|
|
62
80
|
}
|
|
63
81
|
}
|
|
64
82
|
|
|
65
|
-
export const initialise = context => {
|
|
83
|
+
export const initialise = (context: StoreContext) => {
|
|
66
84
|
const {
|
|
67
85
|
datasource,
|
|
68
86
|
fetch,
|
|
@@ -78,7 +96,7 @@ export const initialise = context => {
|
|
|
78
96
|
|
|
79
97
|
// Keep a list of subscriptions so that we can clear them when the datasource
|
|
80
98
|
// config changes
|
|
81
|
-
let unsubscribers = []
|
|
99
|
+
let unsubscribers: any[] = []
|
|
82
100
|
|
|
83
101
|
// Observe datasource changes and apply logic for table datasources
|
|
84
102
|
datasource.subscribe($datasource => {
|
|
@@ -90,7 +108,7 @@ export const initialise = context => {
|
|
|
90
108
|
}
|
|
91
109
|
|
|
92
110
|
// Wipe state
|
|
93
|
-
filter.set(get(initialFilter))
|
|
111
|
+
filter.set(get(initialFilter) ?? undefined)
|
|
94
112
|
inlineFilters.set([])
|
|
95
113
|
sort.set({
|
|
96
114
|
column: get(initialSortColumn),
|
|
@@ -121,7 +139,7 @@ export const initialise = context => {
|
|
|
121
139
|
}
|
|
122
140
|
$fetch.update({
|
|
123
141
|
sortOrder: $sort.order || SortOrder.ASCENDING,
|
|
124
|
-
sortColumn: $sort.column,
|
|
142
|
+
sortColumn: $sort.column ?? undefined,
|
|
125
143
|
})
|
|
126
144
|
})
|
|
127
145
|
)
|
|
@@ -1,38 +1,53 @@
|
|
|
1
1
|
import { get } from "svelte/store"
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Row,
|
|
4
|
+
SaveRowRequest,
|
|
5
|
+
SortOrder,
|
|
6
|
+
UIDatasource,
|
|
7
|
+
UIView,
|
|
8
|
+
UpdateViewRequest,
|
|
9
|
+
} from "@budibase/types"
|
|
10
|
+
import { Store as StoreContext } from ".."
|
|
11
|
+
import { DatasourceViewActions } from "."
|
|
3
12
|
|
|
4
13
|
const SuppressErrors = true
|
|
5
14
|
|
|
6
|
-
|
|
15
|
+
interface ViewActions {
|
|
16
|
+
viewV2: {
|
|
17
|
+
actions: DatasourceViewActions
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type Store = ViewActions
|
|
22
|
+
|
|
23
|
+
export const createActions = (context: StoreContext): ViewActions => {
|
|
7
24
|
const { API, datasource, columns } = context
|
|
8
25
|
|
|
9
|
-
const saveDefinition = async newDefinition => {
|
|
26
|
+
const saveDefinition = async (newDefinition: UpdateViewRequest) => {
|
|
10
27
|
await API.viewV2.update(newDefinition)
|
|
11
28
|
}
|
|
12
29
|
|
|
13
|
-
const saveRow = async row => {
|
|
30
|
+
const saveRow = async (row: SaveRowRequest) => {
|
|
14
31
|
const $datasource = get(datasource)
|
|
15
32
|
row = {
|
|
16
33
|
...row,
|
|
17
34
|
tableId: $datasource?.tableId,
|
|
18
35
|
_viewId: $datasource?.id,
|
|
19
36
|
}
|
|
37
|
+
const newRow = await API.saveRow(row, SuppressErrors)
|
|
20
38
|
return {
|
|
21
|
-
...
|
|
39
|
+
...newRow,
|
|
40
|
+
_id: newRow._id!,
|
|
22
41
|
_viewId: row._viewId,
|
|
23
42
|
}
|
|
24
43
|
}
|
|
25
44
|
|
|
26
|
-
const deleteRows = async rows => {
|
|
27
|
-
await API.deleteRows(
|
|
28
|
-
tableId: get(datasource).id,
|
|
29
|
-
rows,
|
|
30
|
-
})
|
|
45
|
+
const deleteRows = async (rows: Row[]) => {
|
|
46
|
+
await API.deleteRows(get(datasource).id, rows)
|
|
31
47
|
}
|
|
32
48
|
|
|
33
|
-
const getRow = async id => {
|
|
34
|
-
const res = await API.viewV2.fetch({
|
|
35
|
-
viewId: get(datasource).id,
|
|
49
|
+
const getRow = async (id: string) => {
|
|
50
|
+
const res = await API.viewV2.fetch(get(datasource).id, {
|
|
36
51
|
limit: 1,
|
|
37
52
|
query: {
|
|
38
53
|
equal: {
|
|
@@ -41,16 +56,21 @@ export const createActions = context => {
|
|
|
41
56
|
},
|
|
42
57
|
paginate: false,
|
|
43
58
|
})
|
|
44
|
-
|
|
59
|
+
const row = res?.rows?.[0]
|
|
60
|
+
if (!row) {
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return { ...row, _id: row._id! }
|
|
45
65
|
}
|
|
46
66
|
|
|
47
|
-
const isDatasourceValid = datasource => {
|
|
67
|
+
const isDatasourceValid = (datasource: UIDatasource) => {
|
|
48
68
|
return (
|
|
49
|
-
datasource?.type === "viewV2" && datasource?.id && datasource?.tableId
|
|
69
|
+
datasource?.type === "viewV2" && !!datasource?.id && !!datasource?.tableId
|
|
50
70
|
)
|
|
51
71
|
}
|
|
52
72
|
|
|
53
|
-
const canUseColumn = name => {
|
|
73
|
+
const canUseColumn = (name: string) => {
|
|
54
74
|
return get(columns).some(col => col.name === name && col.visible)
|
|
55
75
|
}
|
|
56
76
|
|
|
@@ -69,7 +89,7 @@ export const createActions = context => {
|
|
|
69
89
|
}
|
|
70
90
|
}
|
|
71
91
|
|
|
72
|
-
export const initialise = context => {
|
|
92
|
+
export const initialise = (context: StoreContext) => {
|
|
73
93
|
const {
|
|
74
94
|
definition,
|
|
75
95
|
datasource,
|
|
@@ -89,7 +109,7 @@ export const initialise = context => {
|
|
|
89
109
|
|
|
90
110
|
// Keep a list of subscriptions so that we can clear them when the datasource
|
|
91
111
|
// config changes
|
|
92
|
-
let unsubscribers = []
|
|
112
|
+
let unsubscribers: any[] = []
|
|
93
113
|
|
|
94
114
|
// Observe datasource changes and apply logic for view V2 datasources
|
|
95
115
|
datasource.subscribe($datasource => {
|
|
@@ -101,7 +121,7 @@ export const initialise = context => {
|
|
|
101
121
|
}
|
|
102
122
|
|
|
103
123
|
// Reset state for new view
|
|
104
|
-
filter.set(get(initialFilter))
|
|
124
|
+
filter.set(get(initialFilter) ?? undefined)
|
|
105
125
|
inlineFilters.set([])
|
|
106
126
|
sort.set({
|
|
107
127
|
column: get(initialSortColumn),
|
|
@@ -131,20 +151,46 @@ export const initialise = context => {
|
|
|
131
151
|
})
|
|
132
152
|
)
|
|
133
153
|
|
|
154
|
+
function sortHasChanged(
|
|
155
|
+
newSort: {
|
|
156
|
+
column: string | null | undefined
|
|
157
|
+
order: SortOrder
|
|
158
|
+
},
|
|
159
|
+
existingSort?: {
|
|
160
|
+
field: string
|
|
161
|
+
order?: SortOrder
|
|
162
|
+
}
|
|
163
|
+
) {
|
|
164
|
+
const newColumn = newSort.column ?? null
|
|
165
|
+
const existingColumn = existingSort?.field ?? null
|
|
166
|
+
if (newColumn !== existingColumn) {
|
|
167
|
+
return true
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (!newColumn) {
|
|
171
|
+
return false
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const newOrder = newSort.order ?? null
|
|
175
|
+
const existingOrder = existingSort?.order ?? null
|
|
176
|
+
if (newOrder !== existingOrder) {
|
|
177
|
+
return true
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return false
|
|
181
|
+
}
|
|
182
|
+
|
|
134
183
|
// When sorting changes, ensure view definition is kept up to date
|
|
135
184
|
unsubscribers.push(
|
|
136
185
|
sort.subscribe(async $sort => {
|
|
137
186
|
// Ensure we're updating the correct view
|
|
138
|
-
const $view = get(definition)
|
|
187
|
+
const $view = get(definition) as UIView
|
|
139
188
|
if ($view?.id !== $datasource.id) {
|
|
140
189
|
return
|
|
141
190
|
}
|
|
142
191
|
|
|
143
192
|
// Skip if nothing actually changed
|
|
144
|
-
if (
|
|
145
|
-
$sort?.column === $view.sort?.field &&
|
|
146
|
-
$sort?.order === $view.sort?.order
|
|
147
|
-
) {
|
|
193
|
+
if (!sortHasChanged($sort, $view.sort)) {
|
|
148
194
|
return
|
|
149
195
|
}
|
|
150
196
|
|
|
@@ -153,7 +199,7 @@ export const initialise = context => {
|
|
|
153
199
|
await datasource.actions.saveDefinition({
|
|
154
200
|
...$view,
|
|
155
201
|
sort: {
|
|
156
|
-
field: $sort.column
|
|
202
|
+
field: $sort.column!,
|
|
157
203
|
order: $sort.order || SortOrder.ASCENDING,
|
|
158
204
|
},
|
|
159
205
|
})
|
|
@@ -167,7 +213,7 @@ export const initialise = context => {
|
|
|
167
213
|
}
|
|
168
214
|
$fetch.update({
|
|
169
215
|
sortOrder: $sort.order,
|
|
170
|
-
sortColumn: $sort.column,
|
|
216
|
+
sortColumn: $sort.column ?? undefined,
|
|
171
217
|
})
|
|
172
218
|
})
|
|
173
219
|
)
|
|
@@ -186,7 +232,7 @@ export const initialise = context => {
|
|
|
186
232
|
await datasource.actions.saveDefinition({
|
|
187
233
|
...$view,
|
|
188
234
|
queryUI: $filter,
|
|
189
|
-
})
|
|
235
|
+
} as never as UpdateViewRequest)
|
|
190
236
|
|
|
191
237
|
// Refresh data since view definition changed
|
|
192
238
|
await rows.actions.refreshData()
|