@budibase/frontend-core 2.9.37 → 2.9.39-alpha.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.
Files changed (45) hide show
  1. package/package.json +4 -4
  2. package/src/api/groups.js +22 -0
  3. package/src/api/index.js +2 -0
  4. package/src/api/permissions.js +23 -0
  5. package/src/api/rows.js +22 -3
  6. package/src/api/user.js +27 -4
  7. package/src/api/viewsV2.js +72 -0
  8. package/src/components/grid/cells/DataCell.svelte +8 -3
  9. package/src/components/grid/cells/GutterCell.svelte +4 -4
  10. package/src/components/grid/cells/HeaderCell.svelte +3 -3
  11. package/src/components/grid/controls/HideColumnsButton.svelte +10 -7
  12. package/src/components/grid/controls/SizeButton.svelte +10 -4
  13. package/src/components/grid/controls/SortButton.svelte +12 -34
  14. package/src/components/grid/layout/Grid.svelte +22 -17
  15. package/src/components/grid/layout/GridBody.svelte +2 -2
  16. package/src/components/grid/layout/HeaderRow.svelte +3 -4
  17. package/src/components/grid/layout/NewColumnButton.svelte +3 -2
  18. package/src/components/grid/layout/NewRow.svelte +6 -6
  19. package/src/components/grid/layout/StickyColumn.svelte +2 -2
  20. package/src/components/grid/lib/websocket.js +18 -12
  21. package/src/components/grid/overlays/KeyboardManager.svelte +12 -11
  22. package/src/components/grid/overlays/MenuOverlay.svelte +3 -6
  23. package/src/components/grid/stores/clipboard.js +1 -1
  24. package/src/components/grid/stores/columns.js +39 -99
  25. package/src/components/grid/stores/config.js +33 -6
  26. package/src/components/grid/stores/datasource.js +131 -0
  27. package/src/components/grid/stores/filter.js +2 -2
  28. package/src/components/grid/stores/index.js +14 -3
  29. package/src/components/grid/stores/menu.js +1 -1
  30. package/src/components/grid/stores/pagination.js +3 -4
  31. package/src/components/grid/stores/reorder.js +1 -1
  32. package/src/components/grid/stores/resize.js +1 -1
  33. package/src/components/grid/stores/rows.js +61 -101
  34. package/src/components/grid/stores/sort.js +29 -6
  35. package/src/components/grid/stores/table.js +129 -0
  36. package/src/components/grid/stores/ui.js +24 -36
  37. package/src/components/grid/stores/users.js +8 -1
  38. package/src/components/grid/stores/viewV2.js +212 -0
  39. package/src/components/grid/stores/viewport.js +4 -4
  40. package/src/constants.js +21 -13
  41. package/src/fetch/DataFetch.js +35 -24
  42. package/src/fetch/QueryFetch.js +4 -0
  43. package/src/fetch/ViewV2Fetch.js +65 -0
  44. package/src/fetch/fetchData.js +2 -0
  45. package/src/utils/roles.js +5 -3
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@budibase/frontend-core",
3
- "version": "2.9.37",
3
+ "version": "2.9.39-alpha.0",
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.9.37",
10
- "@budibase/shared-core": "2.9.37",
9
+ "@budibase/bbui": "2.9.39-alpha.0",
10
+ "@budibase/shared-core": "2.9.39-alpha.0",
11
11
  "dayjs": "^1.11.7",
12
12
  "lodash": "^4.17.21",
13
13
  "socket.io-client": "^4.6.1",
14
14
  "svelte": "^3.46.2"
15
15
  },
16
- "gitHead": "3a27032e4470ba5d7400235f190105965697f158"
16
+ "gitHead": "a090d99e5c942eafaf36ccf946f40cf5c37c1f37"
17
17
  }
package/src/api/groups.js CHANGED
@@ -104,5 +104,27 @@ export const buildGroupsEndpoints = API => {
104
104
  removeAppsFromGroup: async (groupId, appArray) => {
105
105
  return updateGroupResource(groupId, "apps", "remove", appArray)
106
106
  },
107
+
108
+ /**
109
+ * Add app builder to group
110
+ * @param groupId The group to update
111
+ * @param appId The app id where the builder will be added
112
+ */
113
+ addGroupAppBuilder: async ({ groupId, appId }) => {
114
+ return await API.post({
115
+ url: `/api/global/groups/${groupId}/app/${appId}/builder`,
116
+ })
117
+ },
118
+
119
+ /**
120
+ * Remove app builder from group
121
+ * @param groupId The group to update
122
+ * @param appId The app id where the builder will be removed
123
+ */
124
+ removeGroupAppBuilder: async ({ groupId, appId }) => {
125
+ return await API.delete({
126
+ url: `/api/global/groups/${groupId}/app/${appId}/builder`,
127
+ })
128
+ },
107
129
  }
108
130
  }
package/src/api/index.js CHANGED
@@ -23,6 +23,7 @@ import { buildTemplateEndpoints } from "./templates"
23
23
  import { buildUserEndpoints } from "./user"
24
24
  import { buildSelfEndpoints } from "./self"
25
25
  import { buildViewEndpoints } from "./views"
26
+ import { buildViewV2Endpoints } from "./viewsV2"
26
27
  import { buildLicensingEndpoints } from "./licensing"
27
28
  import { buildGroupsEndpoints } from "./groups"
28
29
  import { buildPluginEndpoints } from "./plugins"
@@ -279,5 +280,6 @@ export const createAPIClient = config => {
279
280
  ...buildEventEndpoints(API),
280
281
  ...buildAuditLogsEndpoints(API),
281
282
  ...buildLogsEndpoints(API),
283
+ viewV2: buildViewV2Endpoints(API),
282
284
  }
283
285
  }
@@ -21,4 +21,27 @@ export const buildPermissionsEndpoints = API => ({
21
21
  url: `/api/permission/${roleId}/${resourceId}/${level}`,
22
22
  })
23
23
  },
24
+
25
+ /**
26
+ * Remove the the permissions for a certain resource
27
+ * @param resourceId the ID of the resource to update
28
+ * @param roleId the ID of the role to update the permissions of
29
+ * @param level the level to remove the role for this resource
30
+ * @return {Promise<*>}
31
+ */
32
+ removePermissionFromResource: async ({ resourceId, roleId, level }) => {
33
+ return await API.delete({
34
+ url: `/api/permission/${roleId}/${resourceId}/${level}`,
35
+ })
36
+ },
37
+
38
+ /**
39
+ * Gets info about the resources that depend on this resource permissions
40
+ * @param resourceId the resource ID to check
41
+ */
42
+ getDependants: async resourceId => {
43
+ return await API.get({
44
+ url: `/api/permission/${resourceId}/dependants`,
45
+ })
46
+ },
24
47
  })
package/src/api/rows.js CHANGED
@@ -23,7 +23,23 @@ export const buildRowEndpoints = API => ({
23
23
  return
24
24
  }
25
25
  return await API.post({
26
- url: `/api/${row.tableId}/rows`,
26
+ url: `/api/${row._viewId || row.tableId}/rows`,
27
+ body: row,
28
+ suppressErrors,
29
+ })
30
+ },
31
+
32
+ /**
33
+ * Patches a row in a table.
34
+ * @param row the row to patch
35
+ * @param suppressErrors whether or not to suppress error notifications
36
+ */
37
+ patchRow: async (row, suppressErrors = false) => {
38
+ if (!row?.tableId && !row?._viewId) {
39
+ return
40
+ }
41
+ return await API.patch({
42
+ url: `/api/${row._viewId || row.tableId}/rows`,
27
43
  body: row,
28
44
  suppressErrors,
29
45
  })
@@ -31,7 +47,7 @@ export const buildRowEndpoints = API => ({
31
47
 
32
48
  /**
33
49
  * Deletes a row from a table.
34
- * @param tableId the ID of the table to delete from
50
+ * @param tableId the ID of the table or view to delete from
35
51
  * @param rowId the ID of the row to delete
36
52
  * @param revId the rev of the row to delete
37
53
  */
@@ -50,10 +66,13 @@ export const buildRowEndpoints = API => ({
50
66
 
51
67
  /**
52
68
  * Deletes multiple rows from a table.
53
- * @param tableId the table ID to delete the rows from
69
+ * @param tableId the table or view ID to delete the rows from
54
70
  * @param rows the array of rows to delete
55
71
  */
56
72
  deleteRows: async ({ tableId, rows }) => {
73
+ rows?.forEach(row => {
74
+ delete row?._viewId
75
+ })
57
76
  return await API.delete({
58
77
  url: `/api/${tableId}/rows`,
59
78
  body: {
package/src/api/user.js CHANGED
@@ -144,8 +144,8 @@ export const buildUserEndpoints = API => ({
144
144
  body: {
145
145
  email,
146
146
  userInfo: {
147
- admin: admin ? { global: true } : undefined,
148
- builder: builder ? { global: true } : undefined,
147
+ admin: admin?.global ? { global: true } : undefined,
148
+ builder: builder?.global ? { global: true } : undefined,
149
149
  apps: apps ? apps : undefined,
150
150
  },
151
151
  },
@@ -160,8 +160,8 @@ export const buildUserEndpoints = API => ({
160
160
  return {
161
161
  email,
162
162
  userInfo: {
163
- admin: admin ? { global: true } : undefined,
164
- builder: builder ? { global: true } : undefined,
163
+ admin,
164
+ builder,
165
165
  apps: apps ? apps : undefined,
166
166
  },
167
167
  }
@@ -179,6 +179,7 @@ export const buildUserEndpoints = API => ({
179
179
  url: `/api/global/users/invite/update/${invite.code}`,
180
180
  body: {
181
181
  apps: invite.apps,
182
+ builder: invite.builder,
182
183
  },
183
184
  })
184
185
  },
@@ -250,4 +251,26 @@ export const buildUserEndpoints = API => ({
250
251
  url: `/api/global/users/count/${appId}`,
251
252
  })
252
253
  },
254
+
255
+ /**
256
+ * Adds a per app builder to the selected app
257
+ * @param appId the applications id
258
+ * @param userId The id of the user to add as a builder
259
+ */
260
+ addAppBuilder: async ({ userId, appId }) => {
261
+ return await API.post({
262
+ url: `/api/global/users/${userId}/app/${appId}/builder`,
263
+ })
264
+ },
265
+
266
+ /**
267
+ * Removes a per app builder to the selected app
268
+ * @param appId the applications id
269
+ * @param userId The id of the user to remove as a builder
270
+ */
271
+ removeAppBuilder: async ({ userId, appId }) => {
272
+ return await API.delete({
273
+ url: `/api/global/users/${userId}/app/${appId}/builder`,
274
+ })
275
+ },
253
276
  })
@@ -0,0 +1,72 @@
1
+ export const buildViewV2Endpoints = API => ({
2
+ /**
3
+ * Fetches the definition of a view
4
+ * @param viewId the ID of the view to fetch
5
+ */
6
+ fetchDefinition: async viewId => {
7
+ return await API.get({
8
+ url: `/api/v2/views/${viewId}`,
9
+ })
10
+ },
11
+ /**
12
+ * Create a new view
13
+ * @param view the view object
14
+ */
15
+ create: async view => {
16
+ return await API.post({
17
+ url: `/api/v2/views`,
18
+ body: view,
19
+ })
20
+ },
21
+ /**
22
+ * Updates a view
23
+ * @param view the view object
24
+ */
25
+ update: async view => {
26
+ return await API.put({
27
+ url: `/api/v2/views/${view.id}`,
28
+ body: view,
29
+ })
30
+ },
31
+ /**
32
+ * Fetches all rows in a view
33
+ * @param viewId the id of the view
34
+ * @param query the search query
35
+ * @param paginate whether to paginate or not
36
+ * @param limit page size
37
+ * @param bookmark pagination cursor
38
+ * @param sort sort column
39
+ * @param sortOrder sort order
40
+ * @param sortType sort type (text or numeric)
41
+ */
42
+ fetch: async ({
43
+ viewId,
44
+ query,
45
+ paginate,
46
+ limit,
47
+ bookmark,
48
+ sort,
49
+ sortOrder,
50
+ sortType,
51
+ }) => {
52
+ return await API.post({
53
+ url: `/api/v2/views/${viewId}/search`,
54
+ body: {
55
+ query,
56
+ paginate,
57
+ limit,
58
+ bookmark,
59
+ sort,
60
+ sortOrder,
61
+ sortType,
62
+ },
63
+ })
64
+ },
65
+ /**
66
+ * Delete a view
67
+ * @param viewId the id of the view
68
+ */
69
+ delete: async viewId => {
70
+ return await API.delete({ url: `/api/v2/views/${viewId}` })
71
+ },
72
+ })
@@ -34,7 +34,7 @@
34
34
  column.schema.autocolumn ||
35
35
  column.schema.disabled ||
36
36
  column.schema.type === "formula" ||
37
- (!$config.allowEditRows && row._id)
37
+ (!$config.canEditRows && row._id)
38
38
 
39
39
  // Register this cell API if the row is focused
40
40
  $: {
@@ -58,9 +58,14 @@
58
58
  isReadonly: () => readonly,
59
59
  getType: () => column.schema.type,
60
60
  getValue: () => row[column.name],
61
- setValue: value => {
61
+ setValue: (value, options = { save: true }) => {
62
62
  validation.actions.setError(cellId, null)
63
- updateValue(row._id, column.name, value)
63
+ updateValue({
64
+ rowId: row._id,
65
+ column: column.name,
66
+ value,
67
+ save: options?.save,
68
+ })
64
69
  },
65
70
  }
66
71
  </script>
@@ -40,7 +40,7 @@
40
40
  <div
41
41
  on:click={select}
42
42
  class="checkbox"
43
- class:visible={$config.allowDeleteRows &&
43
+ class:visible={$config.canDeleteRows &&
44
44
  (disableNumber || rowSelected || rowHovered || rowFocused)}
45
45
  >
46
46
  <Checkbox value={rowSelected} {disabled} />
@@ -48,14 +48,14 @@
48
48
  {#if !disableNumber}
49
49
  <div
50
50
  class="number"
51
- class:visible={!$config.allowDeleteRows ||
51
+ class:visible={!$config.canDeleteRows ||
52
52
  !(rowSelected || rowHovered || rowFocused)}
53
53
  >
54
54
  {row.__idx + 1}
55
55
  </div>
56
56
  {/if}
57
57
  {/if}
58
- {#if rowSelected && $config.allowDeleteRows}
58
+ {#if rowSelected && $config.canDeleteRows}
59
59
  <div class="delete" on:click={() => dispatch("request-bulk-delete")}>
60
60
  <Icon
61
61
  name="Delete"
@@ -64,7 +64,7 @@
64
64
  />
65
65
  </div>
66
66
  {:else}
67
- <div class="expand" class:visible={$config.allowExpandRows && expandable}>
67
+ <div class="expand" class:visible={$config.canExpandRows && expandable}>
68
68
  <Icon
69
69
  size="S"
70
70
  name="Maximize"
@@ -56,6 +56,7 @@
56
56
  popover.hide()
57
57
  editIsOpen = false
58
58
  }
59
+
59
60
  const onMouseDown = e => {
60
61
  if (e.button === 0 && orderable) {
61
62
  timeout = setTimeout(() => {
@@ -116,6 +117,7 @@
116
117
  columns.actions.saveChanges()
117
118
  open = false
118
119
  }
120
+
119
121
  onMount(() => subscribe("close-edit-column", cancelEdit))
120
122
  </script>
121
123
 
@@ -170,7 +172,6 @@
170
172
  align="right"
171
173
  offset={0}
172
174
  popoverTarget={document.getElementById(`grid-${rand}`)}
173
- animate={false}
174
175
  customZindex={100}
175
176
  >
176
177
  {#if editIsOpen}
@@ -187,7 +188,7 @@
187
188
  <MenuItem
188
189
  icon="Edit"
189
190
  on:click={editColumn}
190
- disabled={!$config.allowSchemaChanges || column.schema.disabled}
191
+ disabled={!$config.canEditColumns || column.schema.disabled}
191
192
  >
192
193
  Edit column
193
194
  </MenuItem>
@@ -195,7 +196,6 @@
195
196
  icon="Label"
196
197
  on:click={makeDisplayColumn}
197
198
  disabled={idx === "sticky" ||
198
- !$config.allowSchemaChanges ||
199
199
  bannedDisplayColumnTypes.includes(column.schema.type)}
200
200
  >
201
201
  Use as display column
@@ -3,7 +3,7 @@
3
3
  import { ActionButton, Popover, Toggle, Icon } from "@budibase/bbui"
4
4
  import { getColumnIcon } from "../lib/utils"
5
5
 
6
- const { columns, stickyColumn } = getContext("grid")
6
+ const { columns, stickyColumn, dispatch } = getContext("grid")
7
7
 
8
8
  let open = false
9
9
  let anchor
@@ -11,33 +11,36 @@
11
11
  $: anyHidden = $columns.some(col => !col.visible)
12
12
  $: text = getText($columns)
13
13
 
14
- const toggleVisibility = (column, visible) => {
14
+ const toggleVisibility = async (column, visible) => {
15
15
  columns.update(state => {
16
16
  const index = state.findIndex(col => col.name === column.name)
17
17
  state[index].visible = visible
18
18
  return state.slice()
19
19
  })
20
- columns.actions.saveChanges()
20
+ await columns.actions.saveChanges()
21
+ dispatch(visible ? "show-column" : "hide-column")
21
22
  }
22
23
 
23
- const showAll = () => {
24
+ const showAll = async () => {
24
25
  columns.update(state => {
25
26
  return state.map(col => ({
26
27
  ...col,
27
28
  visible: true,
28
29
  }))
29
30
  })
30
- columns.actions.saveChanges()
31
+ await columns.actions.saveChanges()
32
+ dispatch("show-column")
31
33
  }
32
34
 
33
- const hideAll = () => {
35
+ const hideAll = async () => {
34
36
  columns.update(state => {
35
37
  return state.map(col => ({
36
38
  ...col,
37
39
  visible: false,
38
40
  }))
39
41
  })
40
- columns.actions.saveChanges()
42
+ await columns.actions.saveChanges()
43
+ dispatch("hide-column")
41
44
  }
42
45
 
43
46
  const getText = columns => {
@@ -8,8 +8,14 @@
8
8
  SmallRowHeight,
9
9
  } from "../lib/constants"
10
10
 
11
- const { stickyColumn, columns, rowHeight, table, fixedRowHeight } =
12
- getContext("grid")
11
+ const {
12
+ stickyColumn,
13
+ columns,
14
+ rowHeight,
15
+ definition,
16
+ fixedRowHeight,
17
+ datasource,
18
+ } = getContext("grid")
13
19
 
14
20
  // Some constants for column width options
15
21
  const smallColSize = 120
@@ -60,8 +66,8 @@
60
66
  ]
61
67
 
62
68
  const changeRowHeight = height => {
63
- columns.actions.saveTable({
64
- ...$table,
69
+ datasource.actions.saveDefinition({
70
+ ...$definition,
65
71
  rowHeight: height,
66
72
  })
67
73
  }
@@ -8,7 +8,6 @@
8
8
  let anchor
9
9
 
10
10
  $: columnOptions = getColumnOptions($stickyColumn, $columns)
11
- $: checkValidSortColumn($sort.column, $stickyColumn, $columns)
12
11
  $: orderOptions = getOrderOptions($sort.column, columnOptions)
13
12
 
14
13
  const getColumnOptions = (stickyColumn, columns) => {
@@ -46,8 +45,8 @@
46
45
 
47
46
  const updateSortColumn = e => {
48
47
  sort.update(state => ({
49
- ...state,
50
48
  column: e.detail,
49
+ order: e.detail ? state.order : "ascending",
51
50
  }))
52
51
  }
53
52
 
@@ -57,29 +56,6 @@
57
56
  order: e.detail,
58
57
  }))
59
58
  }
60
-
61
- // Ensure we never have a sort column selected that is not visible
62
- const checkValidSortColumn = (sortColumn, stickyColumn, columns) => {
63
- if (!sortColumn) {
64
- return
65
- }
66
- if (
67
- sortColumn !== stickyColumn?.name &&
68
- !columns.some(col => col.name === sortColumn)
69
- ) {
70
- if (stickyColumn) {
71
- sort.update(state => ({
72
- ...state,
73
- column: stickyColumn.name,
74
- }))
75
- } else {
76
- sort.update(state => ({
77
- ...state,
78
- column: columns[0]?.name,
79
- }))
80
- }
81
- }
82
- }
83
59
  </script>
84
60
 
85
61
  <div bind:this={anchor}>
@@ -98,21 +74,23 @@
98
74
  <Popover bind:open {anchor} align="left">
99
75
  <div class="content">
100
76
  <Select
101
- placeholder={null}
77
+ placeholder="Default"
102
78
  value={$sort.column}
103
79
  options={columnOptions}
104
80
  autoWidth
105
81
  on:change={updateSortColumn}
106
82
  label="Column"
107
83
  />
108
- <Select
109
- placeholder={null}
110
- value={$sort.order}
111
- options={orderOptions}
112
- autoWidth
113
- on:change={updateSortOrder}
114
- label="Order"
115
- />
84
+ {#if $sort.column}
85
+ <Select
86
+ placeholder={null}
87
+ value={$sort.order || "ascending"}
88
+ options={orderOptions}
89
+ autoWidth
90
+ on:change={updateSortOrder}
91
+ label="Order"
92
+ />
93
+ {/if}
116
94
  </div>
117
95
  </Popover>
118
96
 
@@ -1,5 +1,6 @@
1
1
  <script>
2
2
  import { setContext, onMount } from "svelte"
3
+ import { writable } from "svelte/store"
3
4
  import { fade } from "svelte/transition"
4
5
  import { clickOutside, ProgressCircle } from "@budibase/bbui"
5
6
  import { createEventManagers } from "../lib/events"
@@ -28,14 +29,15 @@
28
29
  } from "../lib/constants"
29
30
 
30
31
  export let API = null
31
- export let tableId = null
32
+ export let datasource = null
32
33
  export let schemaOverrides = null
33
34
  export let columnWhitelist = null
34
- export let allowAddRows = true
35
- export let allowExpandRows = true
36
- export let allowEditRows = true
37
- export let allowDeleteRows = true
38
- export let allowSchemaChanges = true
35
+ export let canAddRows = true
36
+ export let canExpandRows = true
37
+ export let canEditRows = true
38
+ export let canDeleteRows = true
39
+ export let canEditColumns = true
40
+ export let canSaveSchema = true
39
41
  export let stripeRows = false
40
42
  export let collaboration = true
41
43
  export let showAvatars = true
@@ -50,11 +52,14 @@
50
52
  // Unique identifier for DOM nodes inside this instance
51
53
  const rand = Math.random()
52
54
 
55
+ // Store props in a store for reference in other stores
56
+ const props = writable($$props)
57
+
53
58
  // Build up context
54
59
  let context = {
55
60
  API: API || createAPIClient(),
56
61
  rand,
57
- props: $$props,
62
+ props,
58
63
  }
59
64
  context = { ...context, ...createEventManagers() }
60
65
  context = attachStores(context)
@@ -71,19 +76,19 @@
71
76
  contentLines,
72
77
  gridFocused,
73
78
  error,
74
- canAddRows,
75
79
  } = context
76
80
 
77
81
  // Keep config store up to date with props
78
- $: config.set({
79
- tableId,
82
+ $: props.set({
83
+ datasource,
80
84
  schemaOverrides,
81
85
  columnWhitelist,
82
- allowAddRows,
83
- allowExpandRows,
84
- allowEditRows,
85
- allowDeleteRows,
86
- allowSchemaChanges,
86
+ canAddRows,
87
+ canExpandRows,
88
+ canEditRows,
89
+ canDeleteRows,
90
+ canEditColumns,
91
+ canSaveSchema,
87
92
  stripeRows,
88
93
  collaboration,
89
94
  showAvatars,
@@ -155,7 +160,7 @@
155
160
  </HeaderRow>
156
161
  <GridBody />
157
162
  </div>
158
- {#if $canAddRows}
163
+ {#if $config.canAddRows}
159
164
  <NewRow />
160
165
  {/if}
161
166
  <div class="overlays">
@@ -179,7 +184,7 @@
179
184
  <ProgressCircle />
180
185
  </div>
181
186
  {/if}
182
- {#if allowDeleteRows}
187
+ {#if $config.canDeleteRows}
183
188
  <BulkDeleteHandler />
184
189
  {/if}
185
190
  <KeyboardManager />
@@ -9,10 +9,10 @@
9
9
  renderedRows,
10
10
  renderedColumns,
11
11
  rowVerticalInversionIndex,
12
- canAddRows,
13
12
  hoveredRowId,
14
13
  dispatch,
15
14
  isDragging,
15
+ config,
16
16
  } = getContext("grid")
17
17
 
18
18
  let body
@@ -43,7 +43,7 @@
43
43
  invertY={idx >= $rowVerticalInversionIndex}
44
44
  />
45
45
  {/each}
46
- {#if $canAddRows}
46
+ {#if $config.canAddRows}
47
47
  <div
48
48
  class="blank"
49
49
  class:highlighted={$hoveredRowId === BlankRowID}
@@ -1,12 +1,11 @@
1
1
  <script>
2
2
  import NewColumnButton from "./NewColumnButton.svelte"
3
-
4
3
  import { getContext } from "svelte"
5
4
  import GridScrollWrapper from "./GridScrollWrapper.svelte"
6
5
  import HeaderCell from "../cells/HeaderCell.svelte"
7
6
  import { TempTooltip, TooltipType } from "@budibase/bbui"
8
7
 
9
- const { renderedColumns, config, hasNonAutoColumn, tableId, loading } =
8
+ const { renderedColumns, config, hasNonAutoColumn, datasource, loading } =
10
9
  getContext("grid")
11
10
  </script>
12
11
 
@@ -20,8 +19,8 @@
20
19
  {/each}
21
20
  </div>
22
21
  </GridScrollWrapper>
23
- {#if $config.allowSchemaChanges}
24
- {#key $tableId}
22
+ {#if $config.canEditColumns}
23
+ {#key $datasource}
25
24
  <TempTooltip
26
25
  text="Click here to create your first column"
27
26
  type={TooltipType.Info}