@budibase/frontend-core 2.5.6-alpha.3 → 2.5.6-alpha.31

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 (66) hide show
  1. package/package.json +6 -4
  2. package/src/api/other.js +0 -9
  3. package/src/components/grid/cells/AttachmentCell.svelte +154 -0
  4. package/src/components/grid/cells/BooleanCell.svelte +44 -0
  5. package/src/components/grid/cells/DataCell.svelte +88 -0
  6. package/src/components/grid/cells/DateCell.svelte +77 -0
  7. package/src/components/grid/cells/FormulaCell.svelte +5 -0
  8. package/src/components/grid/cells/GridCell.svelte +162 -0
  9. package/src/components/grid/cells/GutterCell.svelte +127 -0
  10. package/src/components/grid/cells/HeaderCell.svelte +246 -0
  11. package/src/components/grid/cells/JSONCell.svelte +36 -0
  12. package/src/components/grid/cells/LongFormCell.svelte +120 -0
  13. package/src/components/grid/cells/MultiSelectCell.svelte +7 -0
  14. package/src/components/grid/cells/NumberCell.svelte +7 -0
  15. package/src/components/grid/cells/OptionsCell.svelte +240 -0
  16. package/src/components/grid/cells/RelationshipCell.svelte +504 -0
  17. package/src/components/grid/cells/TextCell.svelte +111 -0
  18. package/src/components/grid/controls/AddColumnButton.svelte +16 -0
  19. package/src/components/grid/controls/AddRowButton.svelte +18 -0
  20. package/src/components/grid/controls/BetaButton.svelte +46 -0
  21. package/src/components/grid/controls/ColumnWidthButton.svelte +91 -0
  22. package/src/components/grid/controls/DeleteButton.svelte +66 -0
  23. package/src/components/grid/controls/HideColumnsButton.svelte +95 -0
  24. package/src/components/grid/controls/RowHeightButton.svelte +70 -0
  25. package/src/components/grid/controls/SortButton.svelte +116 -0
  26. package/src/components/grid/index.js +1 -0
  27. package/src/components/grid/layout/Avatar.svelte +24 -0
  28. package/src/components/grid/layout/Grid.svelte +254 -0
  29. package/src/components/grid/layout/GridBody.svelte +73 -0
  30. package/src/components/grid/layout/GridRow.svelte +57 -0
  31. package/src/components/grid/layout/GridScrollWrapper.svelte +81 -0
  32. package/src/components/grid/layout/HeaderRow.svelte +62 -0
  33. package/src/components/grid/layout/NewRow.svelte +265 -0
  34. package/src/components/grid/layout/RowCount.svelte +9 -0
  35. package/src/components/grid/layout/StickyColumn.svelte +171 -0
  36. package/src/components/grid/layout/UserAvatars.svelte +20 -0
  37. package/src/components/grid/lib/constants.js +14 -0
  38. package/src/components/grid/lib/events.js +29 -0
  39. package/src/components/grid/lib/renderers.js +29 -0
  40. package/src/components/grid/lib/utils.js +26 -0
  41. package/src/components/grid/lib/websocket.js +63 -0
  42. package/src/components/grid/overlays/KeyboardManager.svelte +223 -0
  43. package/src/components/grid/overlays/MenuOverlay.svelte +96 -0
  44. package/src/components/grid/overlays/ReorderOverlay.svelte +63 -0
  45. package/src/components/grid/overlays/ResizeOverlay.svelte +70 -0
  46. package/src/components/grid/overlays/ScrollOverlay.svelte +121 -0
  47. package/src/components/grid/stores/bounds.js +16 -0
  48. package/src/components/grid/stores/clipboard.js +34 -0
  49. package/src/components/grid/stores/columns.js +206 -0
  50. package/src/components/grid/stores/index.js +48 -0
  51. package/src/components/grid/stores/menu.js +49 -0
  52. package/src/components/grid/stores/pagination.js +24 -0
  53. package/src/components/grid/stores/reorder.js +155 -0
  54. package/src/components/grid/stores/resize.js +124 -0
  55. package/src/components/grid/stores/rows.js +467 -0
  56. package/src/components/grid/stores/scroll.js +201 -0
  57. package/src/components/grid/stores/ui.js +159 -0
  58. package/src/components/grid/stores/users.js +115 -0
  59. package/src/components/grid/stores/validation.js +45 -0
  60. package/src/components/grid/stores/viewport.js +145 -0
  61. package/src/components/index.js +1 -0
  62. package/src/fetch/DataFetch.js +27 -21
  63. package/src/fetch/QueryFetch.js +1 -1
  64. package/src/themes/midnight.css +3 -0
  65. package/src/themes/nord.css +3 -0
  66. package/src/utils/utils.js +20 -0
@@ -0,0 +1,254 @@
1
+ <script>
2
+ import { setContext } from "svelte"
3
+ import { writable } from "svelte/store"
4
+ import { fade } from "svelte/transition"
5
+ import { clickOutside, ProgressCircle } from "@budibase/bbui"
6
+ import { createEventManagers } from "../lib/events"
7
+ import { createAPIClient } from "../../../api"
8
+ import { attachStores } from "../stores"
9
+ import DeleteButton from "../controls/DeleteButton.svelte"
10
+ import BetaButton from "../controls/BetaButton.svelte"
11
+ import GridBody from "./GridBody.svelte"
12
+ import ResizeOverlay from "../overlays/ResizeOverlay.svelte"
13
+ import ReorderOverlay from "../overlays/ReorderOverlay.svelte"
14
+ import HeaderRow from "./HeaderRow.svelte"
15
+ import ScrollOverlay from "../overlays/ScrollOverlay.svelte"
16
+ import MenuOverlay from "../overlays/MenuOverlay.svelte"
17
+ import StickyColumn from "./StickyColumn.svelte"
18
+ import UserAvatars from "./UserAvatars.svelte"
19
+ import KeyboardManager from "../overlays/KeyboardManager.svelte"
20
+ import SortButton from "../controls/SortButton.svelte"
21
+ import AddColumnButton from "../controls/AddColumnButton.svelte"
22
+ import HideColumnsButton from "../controls/HideColumnsButton.svelte"
23
+ import AddRowButton from "../controls/AddRowButton.svelte"
24
+ import RowHeightButton from "../controls/RowHeightButton.svelte"
25
+ import ColumnWidthButton from "../controls/ColumnWidthButton.svelte"
26
+ import NewRow from "./NewRow.svelte"
27
+ import {
28
+ MaxCellRenderHeight,
29
+ MaxCellRenderWidthOverflow,
30
+ GutterWidth,
31
+ DefaultRowHeight,
32
+ } from "../lib/constants"
33
+
34
+ export let API = null
35
+ export let tableId = null
36
+ export let schemaOverrides = null
37
+ export let allowAddRows = true
38
+ export let allowAddColumns = true
39
+ export let allowEditColumns = true
40
+ export let allowExpandRows = true
41
+ export let allowEditRows = true
42
+ export let allowDeleteRows = true
43
+
44
+ // Unique identifier for DOM nodes inside this instance
45
+ const rand = Math.random()
46
+
47
+ // State stores
48
+ const tableIdStore = writable(tableId)
49
+ const schemaOverridesStore = writable(schemaOverrides)
50
+ const config = writable({
51
+ allowAddRows,
52
+ allowAddColumns,
53
+ allowEditColumns,
54
+ allowExpandRows,
55
+ allowEditRows,
56
+ allowDeleteRows,
57
+ })
58
+
59
+ // Build up context
60
+ let context = {
61
+ API: API || createAPIClient(),
62
+ rand,
63
+ config,
64
+ tableId: tableIdStore,
65
+ schemaOverrides: schemaOverridesStore,
66
+ }
67
+ context = { ...context, ...createEventManagers() }
68
+ context = attachStores(context)
69
+
70
+ // Reference some stores for local use
71
+ const {
72
+ isResizing,
73
+ isReordering,
74
+ ui,
75
+ loaded,
76
+ loading,
77
+ rowHeight,
78
+ contentLines,
79
+ } = context
80
+
81
+ // Keep stores up to date
82
+ $: tableIdStore.set(tableId)
83
+ $: schemaOverridesStore.set(schemaOverrides)
84
+ $: config.set({
85
+ allowAddRows,
86
+ allowAddColumns,
87
+ allowEditColumns,
88
+ allowExpandRows,
89
+ allowEditRows,
90
+ allowDeleteRows,
91
+ })
92
+
93
+ // Set context for children to consume
94
+ setContext("grid", context)
95
+
96
+ // Expose ability to retrieve context externally for external control
97
+ export const getContext = () => context
98
+
99
+ // Initialise websocket for multi-user
100
+ // onMount(() => createWebsocket(context))
101
+ </script>
102
+
103
+ <div
104
+ class="grid"
105
+ id="grid-{rand}"
106
+ class:is-resizing={$isResizing}
107
+ class:is-reordering={$isReordering}
108
+ style="--row-height:{$rowHeight}px; --default-row-height:{DefaultRowHeight}px; --gutter-width:{GutterWidth}px; --max-cell-render-height:{MaxCellRenderHeight}px; --max-cell-render-width-overflow:{MaxCellRenderWidthOverflow}px; --content-lines:{$contentLines};"
109
+ >
110
+ <div class="controls">
111
+ <div class="controls-left">
112
+ <AddRowButton />
113
+ <AddColumnButton />
114
+ <slot name="controls" />
115
+ <ColumnWidthButton />
116
+ <RowHeightButton />
117
+ <HideColumnsButton />
118
+ <SortButton />
119
+ </div>
120
+ <div class="controls-right">
121
+ <DeleteButton />
122
+ <UserAvatars />
123
+ </div>
124
+ </div>
125
+ {#if $loaded}
126
+ <div class="grid-data-outer" use:clickOutside={ui.actions.blur}>
127
+ <div class="grid-data-inner">
128
+ <StickyColumn />
129
+ <div class="grid-data-content">
130
+ <HeaderRow />
131
+ <GridBody />
132
+ </div>
133
+ <BetaButton />
134
+ <NewRow />
135
+ <div class="overlays">
136
+ <ResizeOverlay />
137
+ <ReorderOverlay />
138
+ <ScrollOverlay />
139
+ <MenuOverlay />
140
+ </div>
141
+ </div>
142
+ </div>
143
+ {/if}
144
+ {#if $loading}
145
+ <div in:fade|local={{ duration: 130 }} class="grid-loading">
146
+ <ProgressCircle />
147
+ </div>
148
+ {/if}
149
+ <KeyboardManager />
150
+ </div>
151
+
152
+ <style>
153
+ .grid {
154
+ flex: 1 1 auto;
155
+ display: flex;
156
+ flex-direction: column;
157
+ justify-content: flex-start;
158
+ align-items: stretch;
159
+ position: relative;
160
+ overflow: hidden;
161
+ background: var(--cell-background);
162
+
163
+ /* Variables */
164
+ --cell-background: var(--spectrum-global-color-gray-50);
165
+ --cell-background-hover: var(--spectrum-global-color-gray-100);
166
+ --cell-padding: 8px;
167
+ --cell-spacing: 4px;
168
+ --cell-border: 1px solid var(--spectrum-global-color-gray-200);
169
+ --cell-font-size: 14px;
170
+ --controls-height: 50px;
171
+ }
172
+ .grid,
173
+ .grid :global(*) {
174
+ box-sizing: border-box;
175
+ }
176
+ .grid.is-resizing :global(*) {
177
+ cursor: col-resize !important;
178
+ }
179
+ .grid.is-reordering :global(*) {
180
+ cursor: grabbing !important;
181
+ }
182
+
183
+ .grid-data-outer,
184
+ .grid-data-inner {
185
+ flex: 1 1 auto;
186
+ display: flex;
187
+ justify-items: flex-start;
188
+ align-items: stretch;
189
+ overflow: hidden;
190
+ }
191
+ .grid-data-outer {
192
+ height: 0;
193
+ flex-direction: column;
194
+ }
195
+ .grid-data-inner {
196
+ flex-direction: row;
197
+ position: relative;
198
+ }
199
+ .grid-data-content {
200
+ flex: 1 1 auto;
201
+ overflow: hidden;
202
+ display: flex;
203
+ flex-direction: column;
204
+ }
205
+
206
+ /* Controls */
207
+ .controls {
208
+ height: var(--controls-height);
209
+ display: flex;
210
+ flex-direction: row;
211
+ justify-content: space-between;
212
+ align-items: center;
213
+ border-bottom: 2px solid var(--spectrum-global-color-gray-200);
214
+ padding: var(--cell-padding);
215
+ gap: var(--cell-spacing);
216
+ background: var(--background);
217
+ }
218
+ .controls-left,
219
+ .controls-right {
220
+ display: flex;
221
+ flex-direction: row;
222
+ justify-content: flex-start;
223
+ align-items: center;
224
+ gap: var(--cell-spacing);
225
+ }
226
+ .controls-right {
227
+ gap: 12px;
228
+ }
229
+
230
+ /* Overlays */
231
+ .overlays {
232
+ z-index: 10;
233
+ }
234
+
235
+ /* Loading */
236
+ .grid-loading {
237
+ position: absolute;
238
+ width: 100%;
239
+ height: 100%;
240
+ display: grid;
241
+ place-items: center;
242
+ z-index: 10;
243
+ }
244
+ .grid-loading:before {
245
+ content: "";
246
+ position: absolute;
247
+ top: 0;
248
+ left: 0;
249
+ width: 100%;
250
+ height: 100%;
251
+ background: var(--background);
252
+ opacity: 0.6;
253
+ }
254
+ </style>
@@ -0,0 +1,73 @@
1
+ <script>
2
+ import { getContext, onMount } from "svelte"
3
+ import GridScrollWrapper from "./GridScrollWrapper.svelte"
4
+ import GridRow from "./GridRow.svelte"
5
+ import { BlankRowID } from "../lib/constants"
6
+
7
+ const {
8
+ bounds,
9
+ renderedRows,
10
+ renderedColumns,
11
+ rowVerticalInversionIndex,
12
+ config,
13
+ hoveredRowId,
14
+ dispatch,
15
+ } = getContext("grid")
16
+
17
+ let body
18
+
19
+ $: renderColumnsWidth = $renderedColumns.reduce(
20
+ (total, col) => (total += col.width),
21
+ 0
22
+ )
23
+
24
+ onMount(() => {
25
+ // Observe and record the height of the body
26
+ const observer = new ResizeObserver(() => {
27
+ bounds.set(body.getBoundingClientRect())
28
+ })
29
+ observer.observe(body)
30
+ return () => {
31
+ observer.disconnect()
32
+ }
33
+ })
34
+ </script>
35
+
36
+ <div bind:this={body} class="grid-body">
37
+ <GridScrollWrapper scrollHorizontally scrollVertically wheelInteractive>
38
+ {#each $renderedRows as row, idx}
39
+ <GridRow {row} {idx} invertY={idx >= $rowVerticalInversionIndex} />
40
+ {/each}
41
+ {#if $config.allowAddRows && $renderedColumns.length}
42
+ <div
43
+ class="blank"
44
+ class:highlighted={$hoveredRowId === BlankRowID}
45
+ style="width:{renderColumnsWidth}px"
46
+ on:mouseenter={() => ($hoveredRowId = BlankRowID)}
47
+ on:mouseleave={() => ($hoveredRowId = null)}
48
+ on:click={() => dispatch("add-row-inline")}
49
+ />
50
+ {/if}
51
+ </GridScrollWrapper>
52
+ </div>
53
+
54
+ <style>
55
+ .grid-body {
56
+ display: block;
57
+ position: relative;
58
+ cursor: default;
59
+ overflow: hidden;
60
+ flex: 1 1 auto;
61
+ }
62
+ .blank {
63
+ height: var(--row-height);
64
+ background: var(--cell-background);
65
+ border-bottom: var(--cell-border);
66
+ border-right: var(--cell-border);
67
+ position: absolute;
68
+ }
69
+ .blank.highlighted {
70
+ background: var(--cell-background-hover);
71
+ cursor: pointer;
72
+ }
73
+ </style>
@@ -0,0 +1,57 @@
1
+ <script>
2
+ import { getContext } from "svelte"
3
+ import DataCell from "../cells/DataCell.svelte"
4
+
5
+ export let row
6
+ export let idx
7
+ export let invertY = false
8
+
9
+ const {
10
+ focusedCellId,
11
+ reorder,
12
+ selectedRows,
13
+ renderedColumns,
14
+ hoveredRowId,
15
+ selectedCellMap,
16
+ focusedRow,
17
+ columnHorizontalInversionIndex,
18
+ } = getContext("grid")
19
+
20
+ $: rowSelected = !!$selectedRows[row._id]
21
+ $: rowHovered = $hoveredRowId === row._id
22
+ $: rowFocused = $focusedRow?._id === row._id
23
+ $: reorderSource = $reorder.sourceColumn
24
+ </script>
25
+
26
+ <div
27
+ class="row"
28
+ on:focus
29
+ on:mouseenter={() => ($hoveredRowId = row._id)}
30
+ on:mouseleave={() => ($hoveredRowId = null)}
31
+ >
32
+ {#each $renderedColumns as column, columnIdx (column.name)}
33
+ {@const cellId = `${row._id}-${column.name}`}
34
+ <DataCell
35
+ {cellId}
36
+ {column}
37
+ {row}
38
+ {invertY}
39
+ {rowFocused}
40
+ invertX={columnIdx >= $columnHorizontalInversionIndex}
41
+ highlighted={rowHovered || rowFocused || reorderSource === column.name}
42
+ selected={rowSelected}
43
+ rowIdx={idx}
44
+ focused={$focusedCellId === cellId}
45
+ selectedUser={$selectedCellMap[cellId]}
46
+ width={column.width}
47
+ />
48
+ {/each}
49
+ </div>
50
+
51
+ <style>
52
+ .row {
53
+ width: 0;
54
+ display: flex;
55
+ height: var(--row-height);
56
+ }
57
+ </style>
@@ -0,0 +1,81 @@
1
+ <script>
2
+ import { getContext } from "svelte"
3
+ import { domDebounce } from "../../../utils/utils"
4
+
5
+ const {
6
+ rowHeight,
7
+ scroll,
8
+ focusedCellId,
9
+ renderedRows,
10
+ maxScrollTop,
11
+ maxScrollLeft,
12
+ bounds,
13
+ hoveredRowId,
14
+ hiddenColumnsWidth,
15
+ } = getContext("grid")
16
+
17
+ export let scrollVertically = false
18
+ export let scrollHorizontally = false
19
+ export let wheelInteractive = false
20
+
21
+ $: style = generateStyle($scroll, $rowHeight, $hiddenColumnsWidth)
22
+
23
+ const generateStyle = (scroll, rowHeight, hiddenWidths) => {
24
+ const offsetX = scrollHorizontally ? -1 * scroll.left + hiddenWidths : 0
25
+ const offsetY = scrollVertically ? -1 * (scroll.top % rowHeight) : 0
26
+ return `transform: translate3d(${offsetX}px, ${offsetY}px, 0);`
27
+ }
28
+
29
+ // Handles a wheel even and updates the scroll offsets
30
+ const handleWheel = e => {
31
+ e.preventDefault()
32
+ debouncedHandleWheel(e.deltaX, e.deltaY, e.clientY)
33
+ }
34
+ const debouncedHandleWheel = domDebounce((deltaX, deltaY, clientY) => {
35
+ const { top, left } = $scroll
36
+
37
+ // Calculate new scroll top
38
+ let newScrollTop = top + deltaY
39
+ newScrollTop = Math.max(0, Math.min(newScrollTop, $maxScrollTop))
40
+
41
+ // Calculate new scroll left
42
+ let newScrollLeft = left + deltaX
43
+ newScrollLeft = Math.max(0, Math.min(newScrollLeft, $maxScrollLeft))
44
+
45
+ // Update state
46
+ scroll.set({
47
+ left: scrollHorizontally ? newScrollLeft : left,
48
+ top: scrollVertically ? newScrollTop : top,
49
+ })
50
+
51
+ // Hover row under cursor
52
+ const y = clientY - $bounds.top + (newScrollTop % $rowHeight)
53
+ const hoveredRow = $renderedRows[Math.floor(y / $rowHeight)]
54
+ hoveredRowId.set(hoveredRow?._id)
55
+ })
56
+ </script>
57
+
58
+ <div
59
+ class="outer"
60
+ on:wheel={wheelInteractive ? handleWheel : null}
61
+ on:click|self={() => ($focusedCellId = null)}
62
+ >
63
+ <div {style} class="inner">
64
+ <slot />
65
+ </div>
66
+ </div>
67
+
68
+ <style>
69
+ .outer {
70
+ min-width: 100%;
71
+ min-height: 100%;
72
+ height: 100%;
73
+ width: 100%;
74
+ max-height: 100%;
75
+ max-width: 100%;
76
+ overflow: hidden;
77
+ }
78
+ .inner {
79
+ position: absolute;
80
+ }
81
+ </style>
@@ -0,0 +1,62 @@
1
+ <script>
2
+ import { getContext } from "svelte"
3
+ import GridScrollWrapper from "./GridScrollWrapper.svelte"
4
+ import HeaderCell from "../cells/HeaderCell.svelte"
5
+ import { Icon } from "@budibase/bbui"
6
+
7
+ const { renderedColumns, dispatch, scroll, hiddenColumnsWidth, width } =
8
+ getContext("grid")
9
+
10
+ $: columnsWidth = $renderedColumns.reduce(
11
+ (total, col) => (total += col.width),
12
+ 0
13
+ )
14
+ $: end = $hiddenColumnsWidth + columnsWidth - 1 - $scroll.left
15
+ $: left = Math.min($width - 40, end)
16
+ </script>
17
+
18
+ <div class="header">
19
+ <GridScrollWrapper scrollHorizontally>
20
+ <div class="row">
21
+ {#each $renderedColumns as column, idx}
22
+ <HeaderCell {column} {idx} />
23
+ {/each}
24
+ </div>
25
+ </GridScrollWrapper>
26
+ <div
27
+ class="add"
28
+ style="left:{left}px"
29
+ on:click={() => dispatch("add-column")}
30
+ >
31
+ <Icon name="Add" />
32
+ </div>
33
+ </div>
34
+
35
+ <style>
36
+ .header {
37
+ background: var(--background);
38
+ border-bottom: var(--cell-border);
39
+ position: relative;
40
+ height: var(--default-row-height);
41
+ z-index: 1;
42
+ }
43
+ .row {
44
+ display: flex;
45
+ }
46
+ .add {
47
+ height: var(--default-row-height);
48
+ display: grid;
49
+ place-items: center;
50
+ width: 40px;
51
+ position: absolute;
52
+ top: 0;
53
+ border-left: var(--cell-border);
54
+ border-right: var(--cell-border);
55
+ border-bottom: var(--cell-border);
56
+ background: var(--spectrum-global-color-gray-100);
57
+ }
58
+ .add:hover {
59
+ background: var(--spectrum-global-color-gray-200);
60
+ cursor: pointer;
61
+ }
62
+ </style>