@budibase/frontend-core 2.5.6-alpha.9 → 2.5.7

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 (64) hide show
  1. package/package.json +4 -6
  2. package/src/components/index.js +0 -1
  3. package/src/constants.js +0 -1
  4. package/src/fetch/DataFetch.js +21 -27
  5. package/src/fetch/QueryFetch.js +1 -1
  6. package/src/themes/midnight.css +0 -3
  7. package/src/themes/nord.css +0 -3
  8. package/src/utils/utils.js +0 -20
  9. package/src/components/grid/cells/AttachmentCell.svelte +0 -153
  10. package/src/components/grid/cells/BooleanCell.svelte +0 -44
  11. package/src/components/grid/cells/DataCell.svelte +0 -86
  12. package/src/components/grid/cells/DateCell.svelte +0 -77
  13. package/src/components/grid/cells/FormulaCell.svelte +0 -5
  14. package/src/components/grid/cells/GridCell.svelte +0 -159
  15. package/src/components/grid/cells/HeaderCell.svelte +0 -237
  16. package/src/components/grid/cells/JSONCell.svelte +0 -36
  17. package/src/components/grid/cells/LongFormCell.svelte +0 -117
  18. package/src/components/grid/cells/MultiSelectCell.svelte +0 -7
  19. package/src/components/grid/cells/NumberCell.svelte +0 -7
  20. package/src/components/grid/cells/OptionsCell.svelte +0 -239
  21. package/src/components/grid/cells/RelationshipCell.svelte +0 -503
  22. package/src/components/grid/cells/TextCell.svelte +0 -110
  23. package/src/components/grid/controls/AddColumnButton.svelte +0 -16
  24. package/src/components/grid/controls/AddRowButton.svelte +0 -18
  25. package/src/components/grid/controls/BetaButton.svelte +0 -46
  26. package/src/components/grid/controls/DeleteButton.svelte +0 -72
  27. package/src/components/grid/controls/HideColumnsButton.svelte +0 -91
  28. package/src/components/grid/controls/RowHeightButton.svelte +0 -70
  29. package/src/components/grid/controls/SortButton.svelte +0 -107
  30. package/src/components/grid/index.js +0 -1
  31. package/src/components/grid/layout/Avatar.svelte +0 -24
  32. package/src/components/grid/layout/Grid.svelte +0 -250
  33. package/src/components/grid/layout/GridBody.svelte +0 -38
  34. package/src/components/grid/layout/GridRow.svelte +0 -57
  35. package/src/components/grid/layout/GridScrollWrapper.svelte +0 -84
  36. package/src/components/grid/layout/HeaderRow.svelte +0 -30
  37. package/src/components/grid/layout/NewRowTop.svelte +0 -247
  38. package/src/components/grid/layout/RowCount.svelte +0 -9
  39. package/src/components/grid/layout/StickyColumn.svelte +0 -245
  40. package/src/components/grid/layout/UserAvatars.svelte +0 -20
  41. package/src/components/grid/lib/constants.js +0 -11
  42. package/src/components/grid/lib/events.js +0 -29
  43. package/src/components/grid/lib/renderers.js +0 -29
  44. package/src/components/grid/lib/utils.js +0 -26
  45. package/src/components/grid/lib/websocket.js +0 -63
  46. package/src/components/grid/overlays/KeyboardManager.svelte +0 -180
  47. package/src/components/grid/overlays/MenuOverlay.svelte +0 -95
  48. package/src/components/grid/overlays/ReorderOverlay.svelte +0 -63
  49. package/src/components/grid/overlays/ResizeOverlay.svelte +0 -70
  50. package/src/components/grid/overlays/ScrollOverlay.svelte +0 -121
  51. package/src/components/grid/stores/bounds.js +0 -16
  52. package/src/components/grid/stores/clipboard.js +0 -34
  53. package/src/components/grid/stores/columns.js +0 -206
  54. package/src/components/grid/stores/index.js +0 -48
  55. package/src/components/grid/stores/menu.js +0 -49
  56. package/src/components/grid/stores/pagination.js +0 -24
  57. package/src/components/grid/stores/reorder.js +0 -155
  58. package/src/components/grid/stores/resize.js +0 -124
  59. package/src/components/grid/stores/rows.js +0 -462
  60. package/src/components/grid/stores/scroll.js +0 -201
  61. package/src/components/grid/stores/ui.js +0 -168
  62. package/src/components/grid/stores/users.js +0 -115
  63. package/src/components/grid/stores/validation.js +0 -45
  64. package/src/components/grid/stores/viewport.js +0 -141
package/package.json CHANGED
@@ -1,17 +1,15 @@
1
1
  {
2
2
  "name": "@budibase/frontend-core",
3
- "version": "2.5.6-alpha.9",
3
+ "version": "2.5.7",
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.5.6-alpha.9",
10
- "@budibase/shared-core": "2.5.6-alpha.9",
11
- "dayjs": "^1.11.7",
9
+ "@budibase/bbui": "^2.5.7",
10
+ "@budibase/shared-core": "^2.5.7",
12
11
  "lodash": "^4.17.21",
13
- "socket.io-client": "^4.6.1",
14
12
  "svelte": "^3.46.2"
15
13
  },
16
- "gitHead": "560204d82570bd22b987e6e35f8e659e9c047425"
14
+ "gitHead": "6c37b6a6c69a1da43a5c0930419e743cc18b5b42"
17
15
  }
@@ -1,3 +1,2 @@
1
1
  export { default as SplitPage } from "./SplitPage.svelte"
2
2
  export { default as TestimonialPage } from "./TestimonialPage.svelte"
3
- export { Grid } from "./grid"
package/src/constants.js CHANGED
@@ -69,7 +69,6 @@ export const Features = {
69
69
  AUDIT_LOGS: "auditLogs",
70
70
  ENFORCEABLE_SSO: "enforceableSSO",
71
71
  BRANDING: "branding",
72
- SCIM: "scim",
73
72
  }
74
73
 
75
74
  // Role IDs
@@ -21,11 +21,11 @@ export default class DataFetch {
21
21
  this.API = null
22
22
 
23
23
  // Feature flags
24
- this.features = {
24
+ this.featureStore = writable({
25
25
  supportsSearch: false,
26
26
  supportsSort: false,
27
27
  supportsPagination: false,
28
- }
28
+ })
29
29
 
30
30
  // Config
31
31
  this.options = {
@@ -56,7 +56,6 @@ export default class DataFetch {
56
56
  pageNumber: 0,
57
57
  cursor: null,
58
58
  cursors: [],
59
- resetKey: Math.random(),
60
59
  })
61
60
 
62
61
  // Merge options with their default values
@@ -82,14 +81,17 @@ export default class DataFetch {
82
81
  this.prevPage = this.prevPage.bind(this)
83
82
 
84
83
  // Derive certain properties to return
85
- this.derivedStore = derived(this.store, $store => {
86
- return {
87
- ...$store,
88
- ...this.features,
89
- hasNextPage: this.hasNextPage($store),
90
- hasPrevPage: this.hasPrevPage($store),
84
+ this.derivedStore = derived(
85
+ [this.store, this.featureStore],
86
+ ([$store, $featureStore]) => {
87
+ return {
88
+ ...$store,
89
+ ...$featureStore,
90
+ hasNextPage: this.hasNextPage($store),
91
+ hasPrevPage: this.hasPrevPage($store),
92
+ }
91
93
  }
92
- })
94
+ )
93
95
 
94
96
  // Mark as loaded if we have no datasource
95
97
  if (!this.options.datasource) {
@@ -118,11 +120,11 @@ export default class DataFetch {
118
120
  // Fetch datasource definition and determine feature flags
119
121
  const definition = await this.getDefinition(datasource)
120
122
  const features = this.determineFeatureFlags(definition)
121
- this.features = {
123
+ this.featureStore.set({
122
124
  supportsSearch: !!features?.supportsSearch,
123
125
  supportsSort: !!features?.supportsSort,
124
126
  supportsPagination: paginate && !!features?.supportsPagination,
125
- }
127
+ })
126
128
 
127
129
  // Fetch and enrich schema
128
130
  let schema = this.getSchema(datasource, definition)
@@ -136,17 +138,11 @@ export default class DataFetch {
136
138
  this.options.sortOrder = "ascending"
137
139
  }
138
140
 
139
- // If no sort column, use the primary display and fallback to first column
141
+ // If no sort column, use the first field in the schema
140
142
  if (!this.options.sortColumn) {
141
- let newSortColumn
142
- if (definition?.primaryDisplay && schema[definition.primaryDisplay]) {
143
- newSortColumn = definition.primaryDisplay
144
- } else {
145
- newSortColumn = Object.keys(schema)[0]
146
- }
147
- this.options.sortColumn = newSortColumn
143
+ this.options.sortColumn = Object.keys(schema)[0]
148
144
  }
149
- const { sortOrder, sortColumn } = this.options
145
+ const { sortColumn } = this.options
150
146
 
151
147
  // Determine what sort type to use
152
148
  let sortType = "string"
@@ -171,8 +167,6 @@ export default class DataFetch {
171
167
  loading: true,
172
168
  cursors: [],
173
169
  cursor: null,
174
- sortOrder,
175
- sortColumn,
176
170
  }))
177
171
 
178
172
  // Actually fetch data
@@ -186,7 +180,6 @@ export default class DataFetch {
186
180
  info: page.info,
187
181
  cursors: paginate && page.hasNextPage ? [null, page.cursor] : [null],
188
182
  error: page.error,
189
- resetKey: Math.random(),
190
183
  }))
191
184
  }
192
185
 
@@ -196,22 +189,23 @@ export default class DataFetch {
196
189
  async getPage() {
197
190
  const { sortColumn, sortOrder, sortType, limit } = this.options
198
191
  const { query } = get(this.store)
192
+ const features = get(this.featureStore)
199
193
 
200
194
  // Get the actual data
201
195
  let { rows, info, hasNextPage, cursor, error } = await this.getData()
202
196
 
203
197
  // If we don't support searching, do a client search
204
- if (!this.features.supportsSearch) {
198
+ if (!features.supportsSearch) {
205
199
  rows = runLuceneQuery(rows, query)
206
200
  }
207
201
 
208
202
  // If we don't support sorting, do a client-side sort
209
- if (!this.features.supportsSort) {
203
+ if (!features.supportsSort) {
210
204
  rows = luceneSort(rows, sortColumn, sortOrder, sortType)
211
205
  }
212
206
 
213
207
  // If we don't support pagination, do a client-side limit
214
- if (!this.features.supportsPagination) {
208
+ if (!features.supportsPagination) {
215
209
  rows = luceneLimit(rows, limit)
216
210
  }
217
211
 
@@ -31,7 +31,7 @@ export default class QueryFetch extends DataFetch {
31
31
 
32
32
  async getData() {
33
33
  const { datasource, limit, paginate } = this.options
34
- const { supportsPagination } = this.features
34
+ const { supportsPagination } = get(this.featureStore)
35
35
  const { cursor, definition } = get(this.store)
36
36
  const type = definition?.fields?.pagination?.type
37
37
 
@@ -13,9 +13,6 @@
13
13
  --spectrum-global-color-gray-800: hsl(var(--hue), var(--sat), 85%);
14
14
  --spectrum-global-color-gray-900: hsl(var(--hue), var(--sat), 95%);
15
15
 
16
- /* Custom additions */
17
16
  --modal-background: var(--spectrum-global-color-gray-50);
18
- --drop-shadow: rgba(0, 0, 0, 0.25) !important;
19
- --spectrum-global-color-blue-100: rgba(35, 40, 50) !important;
20
17
  }
21
18
 
@@ -46,8 +46,5 @@
46
46
  --spectrum-alias-highlight-active: rgba(169, 177, 193, 0.1);
47
47
  --spectrum-alias-background-color-hover-overlay: rgba(169, 177, 193, 0.1);
48
48
 
49
- /* Custom additions */
50
49
  --modal-background: var(--spectrum-global-color-gray-50);
51
- --drop-shadow: rgba(0, 0, 0, 0.15) !important;
52
- --spectrum-global-color-blue-100: rgb(56, 65, 84) !important;
53
50
  }
@@ -86,23 +86,3 @@ export const throttle = (callback, minDelay = 1000) => {
86
86
  }
87
87
  return invoke
88
88
  }
89
-
90
- /**
91
- * Utility to debounce DOM activities using requestAnimationFrame
92
- * @param callback the function to run
93
- * @returns {Function}
94
- */
95
- export const domDebounce = callback => {
96
- let active = false
97
- let lastParams
98
- return (...params) => {
99
- lastParams = params
100
- if (!active) {
101
- active = true
102
- requestAnimationFrame(() => {
103
- callback(...lastParams)
104
- active = false
105
- })
106
- }
107
- }
108
- }
@@ -1,153 +0,0 @@
1
- <script>
2
- import { onMount } from "svelte"
3
- import { getContext } from "svelte"
4
- import { Dropzone, notifications } from "@budibase/bbui"
5
-
6
- export let value
7
- export let focused = false
8
- export let onChange
9
- export let readonly = false
10
- export let api
11
- export let invertX = false
12
- export let invertY = false
13
-
14
- const { API } = getContext("grid")
15
- const imageExtensions = ["png", "tiff", "gif", "raw", "jpg", "jpeg"]
16
-
17
- let isOpen = false
18
-
19
- $: editable = focused && !readonly
20
- $: {
21
- if (!focused) {
22
- close()
23
- }
24
- }
25
-
26
- const onKeyDown = () => {
27
- return isOpen
28
- }
29
-
30
- const open = () => {
31
- isOpen = true
32
- }
33
-
34
- const close = () => {
35
- isOpen = false
36
- }
37
-
38
- const isImage = extension => {
39
- return imageExtensions.includes(extension?.toLowerCase())
40
- }
41
-
42
- const handleFileTooLarge = fileSizeLimit => {
43
- notifications.error(
44
- `Files cannot exceed ${
45
- fileSizeLimit / 1000000
46
- }MB. Please try again with smaller files.`
47
- )
48
- }
49
-
50
- const processFiles = async fileList => {
51
- let data = new FormData()
52
- for (let i = 0; i < fileList.length; i++) {
53
- data.append("file", fileList[i])
54
- }
55
- try {
56
- return await API.uploadBuilderAttachment(data)
57
- } catch (error) {
58
- notifications.error("Failed to upload attachment")
59
- return []
60
- }
61
- }
62
-
63
- const deleteAttachments = async fileList => {
64
- try {
65
- return await API.deleteBuilderAttachments(fileList)
66
- } catch (error) {
67
- return []
68
- }
69
- }
70
-
71
- onMount(() => {
72
- api = {
73
- focus: () => open(),
74
- blur: () => close(),
75
- onKeyDown,
76
- }
77
- })
78
- </script>
79
-
80
- <div class="attachment-cell" class:editable on:click={editable ? open : null}>
81
- {#each value || [] as attachment}
82
- {#if isImage(attachment.extension)}
83
- <img src={attachment.url} alt={attachment.extension} />
84
- {:else}
85
- <div class="file" title={attachment.name}>
86
- {attachment.extension}
87
- </div>
88
- {/if}
89
- {/each}
90
- </div>
91
-
92
- {#if isOpen}
93
- <div class="dropzone" class:invertX class:invertY>
94
- <Dropzone
95
- {value}
96
- compact
97
- on:change={e => onChange(e.detail)}
98
- {processFiles}
99
- {deleteAttachments}
100
- {handleFileTooLarge}
101
- />
102
- </div>
103
- {/if}
104
-
105
- <style>
106
- .attachment-cell {
107
- flex: 1 1 auto;
108
- display: flex;
109
- flex-direction: row;
110
- align-items: stretch;
111
- padding: var(--cell-padding);
112
- flex-wrap: nowrap;
113
- gap: var(--cell-spacing);
114
- align-self: stretch;
115
- overflow: hidden;
116
- user-select: none;
117
- }
118
- .attachment-cell.editable:hover {
119
- cursor: pointer;
120
- }
121
- .file {
122
- display: flex;
123
- flex-direction: row;
124
- justify-content: flex-start;
125
- align-items: center;
126
- padding: 0 10px;
127
- color: var(--spectrum-global-color-gray-700);
128
- border: 1px solid var(--spectrum-global-color-gray-300);
129
- border-radius: 4px;
130
- text-transform: uppercase;
131
- font-weight: 600;
132
- font-size: 12px;
133
- user-select: none;
134
- }
135
- .dropzone {
136
- position: absolute;
137
- top: 100%;
138
- left: 0;
139
- width: 320px;
140
- background: var(--background);
141
- border: var(--cell-border);
142
- padding: var(--cell-padding);
143
- box-shadow: 0 0 20px -4px rgba(0, 0, 0, 0.15);
144
- }
145
- .dropzone.invertX {
146
- left: auto;
147
- right: 0;
148
- }
149
- .dropzone.invertY {
150
- transform: translateY(-100%);
151
- top: 0;
152
- }
153
- </style>
@@ -1,44 +0,0 @@
1
- <script>
2
- import { onMount } from "svelte"
3
- import { Checkbox } from "@budibase/bbui"
4
-
5
- export let value
6
- export let focused = false
7
- export let onChange
8
- export let readonly = false
9
- export let api
10
-
11
- $: editable = focused && !readonly
12
-
13
- const handleChange = e => {
14
- onChange(e.detail)
15
- }
16
-
17
- const onKeyDown = e => {
18
- if (e.key === "Enter") {
19
- onChange(!value)
20
- return true
21
- }
22
- return false
23
- }
24
-
25
- onMount(() => {
26
- api = {
27
- onKeyDown,
28
- }
29
- })
30
- </script>
31
-
32
- <div class="boolean-cell" class:editable>
33
- <Checkbox {value} on:change={handleChange} />
34
- </div>
35
-
36
- <style>
37
- .boolean-cell {
38
- padding: 2px var(--cell-padding);
39
- pointer-events: none;
40
- }
41
- .boolean-cell.editable {
42
- pointer-events: all;
43
- }
44
- </style>
@@ -1,86 +0,0 @@
1
- <script>
2
- import { getContext } from "svelte"
3
- import GridCell from "./GridCell.svelte"
4
- import { getCellRenderer } from "../lib/renderers"
5
- import { derived, writable } from "svelte/store"
6
-
7
- const { rows, focusedCellId, focusedCellAPI, menu, config, validation } =
8
- getContext("grid")
9
-
10
- export let highlighted
11
- export let selected
12
- export let rowFocused
13
- export let rowIdx
14
- export let focused
15
- export let selectedUser
16
- export let column
17
- export let row
18
- export let cellId
19
- export let updateValue = rows.actions.updateValue
20
- export let invertX = false
21
- export let invertY = false
22
-
23
- const emptyError = writable(null)
24
-
25
- let api
26
-
27
- // Get the error for this cell if the row is focused
28
- $: error = getErrorStore(rowFocused, cellId)
29
-
30
- // Determine if the cell is editable
31
- $: readonly =
32
- column.schema.autocolumn ||
33
- column.schema.disabled ||
34
- (!$config.allowEditRows && row._id)
35
-
36
- // Register this cell API if the row is focused
37
- $: {
38
- if (focused) {
39
- focusedCellAPI.set(cellAPI)
40
- }
41
- }
42
-
43
- const getErrorStore = (selected, cellId) => {
44
- if (!selected) {
45
- return emptyError
46
- }
47
- return derived(validation, $validation => $validation[cellId])
48
- }
49
-
50
- const cellAPI = {
51
- focus: () => api?.focus(),
52
- blur: () => api?.blur(),
53
- onKeyDown: (...params) => api?.onKeyDown(...params),
54
- isReadonly: () => readonly,
55
- getType: () => column.schema.type,
56
- getValue: () => row[column.name],
57
- setValue: value => {
58
- validation.actions.setError(cellId, null)
59
- updateValue(row._id, column.name, value)
60
- },
61
- }
62
- </script>
63
-
64
- <GridCell
65
- {highlighted}
66
- {selected}
67
- {rowIdx}
68
- {focused}
69
- {selectedUser}
70
- error={$error}
71
- on:click={() => focusedCellId.set(cellId)}
72
- on:contextmenu={e => menu.actions.open(cellId, e)}
73
- width={column.width}
74
- >
75
- <svelte:component
76
- this={getCellRenderer(column)}
77
- bind:api
78
- value={row[column.name]}
79
- schema={column.schema}
80
- onChange={cellAPI.setValue}
81
- {focused}
82
- {readonly}
83
- {invertY}
84
- {invertX}
85
- />
86
- </GridCell>
@@ -1,77 +0,0 @@
1
- <script>
2
- import dayjs from "dayjs"
3
- import { CoreDatePicker, Icon } from "@budibase/bbui"
4
-
5
- export let value
6
- export let schema
7
- export let onChange
8
- export let focused = false
9
- export let readonly = false
10
-
11
- // adding the 0- will turn a string like 00:00:00 into a valid ISO
12
- // date, but will make actual ISO dates invalid
13
- $: time = new Date(`0-${value}`)
14
- $: timeOnly = !isNaN(time) || schema?.timeOnly
15
- $: dateOnly = schema?.dateOnly
16
- $: format = timeOnly
17
- ? "HH:mm:ss"
18
- : dateOnly
19
- ? "MMM D YYYY"
20
- : "MMM D YYYY, HH:mm"
21
- $: editable = focused && !readonly
22
- </script>
23
-
24
- <div class="container">
25
- <div class="value">
26
- {#if value}
27
- {dayjs(timeOnly ? time : value).format(format)}
28
- {/if}
29
- </div>
30
- {#if editable}
31
- <Icon name="Calendar" />
32
- {/if}
33
- </div>
34
-
35
- {#if editable}
36
- <div class="picker">
37
- <CoreDatePicker
38
- {value}
39
- on:change={e => onChange(e.detail)}
40
- appendTo={document.documentElement}
41
- enableTime={!dateOnly}
42
- {timeOnly}
43
- time24hr
44
- ignoreTimezones={schema.ignoreTimezones}
45
- />
46
- </div>
47
- {/if}
48
-
49
- <style>
50
- .container {
51
- padding: var(--cell-padding);
52
- display: flex;
53
- flex-direction: row;
54
- justify-content: space-between;
55
- align-items: center;
56
- flex: 1 1 auto;
57
- gap: var(--cell-spacing);
58
- }
59
- .value {
60
- flex: 1 1 auto;
61
- width: 0;
62
- overflow: hidden;
63
- text-overflow: ellipsis;
64
- white-space: nowrap;
65
- line-height: 20px;
66
- }
67
- .picker {
68
- position: absolute;
69
- opacity: 0;
70
- }
71
- .picker :global(.flatpickr) {
72
- min-width: 0;
73
- }
74
- .picker :global(.spectrum-Textfield-input) {
75
- width: 100%;
76
- }
77
- </style>
@@ -1,5 +0,0 @@
1
- <script>
2
- import TextCell from "./TextCell.svelte"
3
- </script>
4
-
5
- <TextCell {...$$props} readonly />