@budibase/frontend-core 2.10.14 → 2.10.16-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.
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@budibase/frontend-core",
3
- "version": "2.10.14",
3
+ "version": "2.10.16-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.10.14",
10
- "@budibase/shared-core": "2.10.14",
11
- "dayjs": "^1.11.7",
9
+ "@budibase/bbui": "2.10.16-alpha.0",
10
+ "@budibase/shared-core": "2.10.16-alpha.0",
11
+ "dayjs": "^1.10.8",
12
12
  "lodash": "^4.17.21",
13
13
  "socket.io-client": "^4.6.1",
14
14
  "svelte": "^3.46.2"
15
15
  },
16
- "gitHead": "ab7ca87cce8a1e9acefb6386486fecefd18a97c1"
16
+ "gitHead": "f373448384d66541cf3dfaf59bd1df32efd3661b"
17
17
  }
package/src/api/app.js CHANGED
@@ -1,3 +1,5 @@
1
+ import { sdk } from "@budibase/shared-core"
2
+
1
3
  export const buildAppEndpoints = API => ({
2
4
  /**
3
5
  * Fetches screen definition for an app.
@@ -81,6 +83,22 @@ export const buildAppEndpoints = API => ({
81
83
  })
82
84
  },
83
85
 
86
+ /**
87
+ * Update an application using an export - the body
88
+ * should be of type FormData, with a "file" and a "password" if encrypted.
89
+ * @param appId The ID of the app to update - this will always be
90
+ * converted to development ID.
91
+ * @param body a FormData body with a file and password.
92
+ */
93
+ updateAppFromExport: async (appId, body) => {
94
+ const devId = sdk.applications.getDevAppID(appId)
95
+ return await API.post({
96
+ url: `/api/applications/${devId}/import`,
97
+ body,
98
+ json: false,
99
+ })
100
+ },
101
+
84
102
  /**
85
103
  * Imports an export of all apps.
86
104
  * @param apps the FormData containing the apps to import
package/src/api/tables.js CHANGED
@@ -82,8 +82,9 @@ export const buildTableEndpoints = API => ({
82
82
  },
83
83
  })
84
84
  },
85
+
85
86
  /**
86
- * Gets a list o tables.
87
+ * Gets a list of tables.
87
88
  */
88
89
  getTables: async () => {
89
90
  return await API.get({
@@ -91,6 +92,15 @@ export const buildTableEndpoints = API => ({
91
92
  })
92
93
  },
93
94
 
95
+ /**
96
+ * Get a single table based on table ID.
97
+ */
98
+ getTable: async tableId => {
99
+ return await API.get({
100
+ url: `/api/tables/${tableId}`,
101
+ })
102
+ },
103
+
94
104
  /**
95
105
  * Saves a table.
96
106
  * @param table the table to save
@@ -0,0 +1,38 @@
1
+ <script>
2
+ import { getContext } from "svelte"
3
+ import RelationshipCell from "./RelationshipCell.svelte"
4
+ import { FieldSubtype } from "@budibase/types"
5
+
6
+ const { API } = getContext("grid")
7
+ const { subtype } = $$props.schema
8
+
9
+ const schema = {
10
+ ...$$props.schema,
11
+ // This is not really used, just adding some content to be able to render the relationship cell
12
+ tableId: "external",
13
+ }
14
+
15
+ async function searchFunction(searchParams) {
16
+ if (subtype !== FieldSubtype.USER) {
17
+ throw `Search for '${subtype}' not implemented`
18
+ }
19
+
20
+ const results = await API.searchUsers({
21
+ ...searchParams,
22
+ })
23
+
24
+ // Mapping to the expected data within RelationshipCell
25
+ return {
26
+ ...results,
27
+ data: undefined,
28
+ rows: results.data,
29
+ }
30
+ }
31
+ </script>
32
+
33
+ <RelationshipCell
34
+ {...$$props}
35
+ {schema}
36
+ {searchFunction}
37
+ primaryDisplay={"email"}
38
+ />
@@ -20,6 +20,8 @@
20
20
  config,
21
21
  ui,
22
22
  columns,
23
+ definition,
24
+ datasource,
23
25
  } = getContext("grid")
24
26
 
25
27
  const bannedDisplayColumnTypes = [
@@ -118,6 +120,33 @@
118
120
  open = false
119
121
  }
120
122
 
123
+ const duplicateColumn = async () => {
124
+ open = false
125
+
126
+ // Generate new name
127
+ let newName = `${column.name} copy`
128
+ let attempts = 2
129
+ while ($definition.schema[newName]) {
130
+ newName = `${column.name} copy ${attempts++}`
131
+ }
132
+
133
+ // Save schema with new column
134
+ const existingColumnDefinition = $definition.schema[column.name]
135
+ await datasource.actions.saveDefinition({
136
+ ...$definition,
137
+ schema: {
138
+ ...$definition.schema,
139
+ [newName]: {
140
+ ...existingColumnDefinition,
141
+ name: newName,
142
+ schema: {
143
+ ...existingColumnDefinition.schema,
144
+ },
145
+ },
146
+ },
147
+ })
148
+ }
149
+
121
150
  onMount(() => subscribe("close-edit-column", cancelEdit))
122
151
  </script>
123
152
 
@@ -192,6 +221,13 @@
192
221
  >
193
222
  Edit column
194
223
  </MenuItem>
224
+ <MenuItem
225
+ icon="Duplicate"
226
+ on:click={duplicateColumn}
227
+ disabled={!$config.canEditColumns}
228
+ >
229
+ Duplicate column
230
+ </MenuItem>
195
231
  <MenuItem
196
232
  icon="Label"
197
233
  on:click={makeDisplayColumn}
@@ -21,6 +21,8 @@
21
21
  import { Icon, Input, ProgressCircle, clickOutside } from "@budibase/bbui"
22
22
  import { debounce } from "../../../utils/utils"
23
23
 
24
+ const { API, dispatch } = getContext("grid")
25
+
24
26
  export let value
25
27
  export let api
26
28
  export let readonly
@@ -30,15 +32,15 @@
30
32
  export let invertX = false
31
33
  export let invertY = false
32
34
  export let contentLines = 1
35
+ export let searchFunction = API.searchTable
36
+ export let primaryDisplay
33
37
 
34
- const { API, dispatch } = getContext("grid")
35
38
  const color = getColor(0)
36
39
 
37
40
  let isOpen = false
38
41
  let searchResults
39
42
  let searchString
40
43
  let lastSearchString
41
- let primaryDisplay
42
44
  let candidateIndex
43
45
  let lastSearchId
44
46
  let searching = false
@@ -96,7 +98,7 @@
96
98
  lastSearchId = Math.random()
97
99
  searching = true
98
100
  const thisSearchId = lastSearchId
99
- const results = await API.searchTable({
101
+ const results = await searchFunction({
100
102
  paginate: false,
101
103
  tableId: schema.tableId,
102
104
  limit: 20,
@@ -259,14 +261,16 @@
259
261
  on:wheel={e => (focused ? e.stopPropagation() : null)}
260
262
  >
261
263
  {#each value || [] as relationship}
262
- {#if relationship.primaryDisplay}
264
+ {#if relationship[primaryDisplay] || relationship.primaryDisplay}
263
265
  <div class="badge">
264
266
  <span
265
267
  on:click={editable
266
268
  ? () => showRelationship(relationship._id)
267
269
  : null}
268
270
  >
269
- {readable(relationship.primaryDisplay)}
271
+ {readable(
272
+ relationship[primaryDisplay] || relationship.primaryDisplay
273
+ )}
270
274
  </span>
271
275
  {#if editable}
272
276
  <Icon
@@ -45,7 +45,7 @@
45
45
  on:focus={() => (active = true)}
46
46
  on:blur={() => (active = false)}
47
47
  {type}
48
- value={value || ""}
48
+ value={value ?? ""}
49
49
  on:change={handleChange}
50
50
  spellcheck="false"
51
51
  />
@@ -9,6 +9,7 @@ import BooleanCell from "../cells/BooleanCell.svelte"
9
9
  import FormulaCell from "../cells/FormulaCell.svelte"
10
10
  import JSONCell from "../cells/JSONCell.svelte"
11
11
  import AttachmentCell from "../cells/AttachmentCell.svelte"
12
+ import BBReferenceCell from "../cells/BBReferenceCell.svelte"
12
13
 
13
14
  const TypeComponentMap = {
14
15
  text: TextCell,
@@ -23,6 +24,7 @@ const TypeComponentMap = {
23
24
  link: RelationshipCell,
24
25
  formula: FormulaCell,
25
26
  json: JSONCell,
27
+ bb_reference: BBReferenceCell,
26
28
  }
27
29
  export const getCellRenderer = column => {
28
30
  return TypeComponentMap[column?.schema?.type] || TextCell
@@ -19,12 +19,21 @@ const TypeIconMap = {
19
19
  formula: "Calculator",
20
20
  json: "Brackets",
21
21
  bigint: "TagBold",
22
+ bb_reference: {
23
+ user: "User",
24
+ },
22
25
  }
23
26
 
24
27
  export const getColumnIcon = column => {
25
28
  if (column.schema.autocolumn) {
26
29
  return "MagicWand"
27
30
  }
28
- const type = column.schema.type
29
- return TypeIconMap[type] || "Text"
31
+ const { type, subtype } = column.schema
32
+
33
+ const result =
34
+ typeof TypeIconMap[type] === "object" && subtype
35
+ ? TypeIconMap[type][subtype]
36
+ : TypeIconMap[type]
37
+
38
+ return result || "Text"
30
39
  }