@budibase/frontend-core 2.29.3 → 2.29.4

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,18 +1,18 @@
1
1
  {
2
2
  "name": "@budibase/frontend-core",
3
- "version": "2.29.3",
3
+ "version": "2.29.4",
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.29.3",
10
- "@budibase/shared-core": "2.29.3",
11
- "@budibase/types": "2.29.3",
9
+ "@budibase/bbui": "2.29.4",
10
+ "@budibase/shared-core": "2.29.4",
11
+ "@budibase/types": "2.29.4",
12
12
  "dayjs": "^1.10.8",
13
13
  "lodash": "4.17.21",
14
14
  "shortid": "2.2.15",
15
15
  "socket.io-client": "^4.6.1"
16
16
  },
17
- "gitHead": "c2cc9ed214200effd8e97b69a01a3ab0fe811cc3"
17
+ "gitHead": "c2811340b5f09c75bc0fbc14232e6f52ec1361ae"
18
18
  }
@@ -16,7 +16,6 @@
16
16
  import { QueryUtils, Constants } from "@budibase/frontend-core"
17
17
  import { getContext } from "svelte"
18
18
  import FilterUsers from "./FilterUsers.svelte"
19
- import { getFields } from "../utils/searchFields"
20
19
 
21
20
  const { OperatorOptions, DEFAULT_BB_DATASOURCE_ID } = Constants
22
21
 
@@ -62,9 +61,7 @@
62
61
  ]
63
62
  const context = getContext("context")
64
63
 
65
- $: fieldOptions = getFields(tables, schemaFields || [], {
66
- allowLinks: true,
67
- }).map(field => ({
64
+ $: fieldOptions = (schemaFields || []).map(field => ({
68
65
  label: field.displayName || field.name,
69
66
  value: field.name,
70
67
  }))
@@ -3,6 +3,7 @@
3
3
  import { Button } from "@budibase/bbui"
4
4
  import GridCell from "../cells/GridCell.svelte"
5
5
  import GridScrollWrapper from "./GridScrollWrapper.svelte"
6
+ import { BlankRowID } from "../lib/constants"
6
7
 
7
8
  const {
8
9
  renderedRows,
@@ -17,6 +18,7 @@
17
18
  isDragging,
18
19
  buttonColumnWidth,
19
20
  showVScrollbar,
21
+ dispatch,
20
22
  } = getContext("grid")
21
23
 
22
24
  let container
@@ -89,6 +91,17 @@
89
91
  </GridCell>
90
92
  </div>
91
93
  {/each}
94
+ <div
95
+ class="row blank"
96
+ on:mouseenter={$isDragging ? null : () => ($hoveredRowId = BlankRowID)}
97
+ on:mouseleave={$isDragging ? null : () => ($hoveredRowId = null)}
98
+ >
99
+ <GridCell
100
+ width={$buttonColumnWidth}
101
+ highlighted={$hoveredRowId === BlankRowID}
102
+ on:click={() => dispatch("add-row-inline")}
103
+ />
104
+ </div>
92
105
  </GridScrollWrapper>
93
106
  </div>
94
107
  </div>
@@ -129,8 +142,11 @@
129
142
  align-items: center;
130
143
  gap: 4px;
131
144
  }
145
+ .blank :global(.cell:hover) {
146
+ cursor: pointer;
147
+ }
132
148
 
133
- /* Add left cell border */
149
+ /* Add left cell border to all cells */
134
150
  .button-column :global(.cell) {
135
151
  border-left: var(--cell-border);
136
152
  }
@@ -26,7 +26,7 @@
26
26
  MaxCellRenderOverflow,
27
27
  GutterWidth,
28
28
  DefaultRowHeight,
29
- Padding,
29
+ VPadding,
30
30
  SmallRowHeight,
31
31
  ControlsHeight,
32
32
  ScrollBarSize,
@@ -119,7 +119,7 @@
119
119
  // Derive min height and make available in context
120
120
  const minHeight = derived(rowHeight, $height => {
121
121
  const heightForControls = showControls ? ControlsHeight : 0
122
- return Padding + SmallRowHeight + $height + heightForControls
122
+ return VPadding + SmallRowHeight + $height + heightForControls
123
123
  })
124
124
  context = { ...context, minHeight }
125
125
 
@@ -354,8 +354,13 @@
354
354
  transition: none;
355
355
  }
356
356
 
357
- /* Overrides */
358
- .grid.quiet :global(.grid-data-content .row > .cell:not(:last-child)) {
357
+ /* Overrides for quiet */
358
+ .grid.quiet :global(.grid-data-content .row > .cell:not(:last-child)),
359
+ .grid.quiet :global(.sticky-column .row > .cell),
360
+ .grid.quiet :global(.new-row .row > .cell:not(:last-child)) {
359
361
  border-right: none;
360
362
  }
363
+ .grid.quiet :global(.sticky-column:before) {
364
+ display: none;
365
+ }
361
366
  </style>
@@ -2,6 +2,7 @@
2
2
  import { getContext, onMount } from "svelte"
3
3
  import GridScrollWrapper from "./GridScrollWrapper.svelte"
4
4
  import GridRow from "./GridRow.svelte"
5
+ import GridCell from "../cells/GridCell.svelte"
5
6
  import { BlankRowID } from "../lib/constants"
6
7
  import ButtonColumn from "./ButtonColumn.svelte"
7
8
 
@@ -46,7 +47,6 @@
46
47
  </script>
47
48
 
48
49
  <!-- svelte-ignore a11y-no-static-element-interactions -->
49
- <!-- svelte-ignore a11y-click-events-have-key-events -->
50
50
  <div bind:this={body} class="grid-body">
51
51
  <GridScrollWrapper scrollHorizontally scrollVertically attachHandlers>
52
52
  {#each $renderedRows as row, idx}
@@ -54,13 +54,16 @@
54
54
  {/each}
55
55
  {#if $config.canAddRows}
56
56
  <div
57
- class="blank"
58
- class:highlighted={$hoveredRowId === BlankRowID}
59
- style="width:{columnsWidth}px"
57
+ class="row blank"
60
58
  on:mouseenter={$isDragging ? null : () => ($hoveredRowId = BlankRowID)}
61
59
  on:mouseleave={$isDragging ? null : () => ($hoveredRowId = null)}
62
- on:click={() => dispatch("add-row-inline")}
63
- />
60
+ >
61
+ <GridCell
62
+ width={columnsWidth}
63
+ highlighted={$hoveredRowId === BlankRowID}
64
+ on:click={() => dispatch("add-row-inline")}
65
+ />
66
+ </div>
64
67
  {/if}
65
68
  </GridScrollWrapper>
66
69
  {#if $props.buttons?.length}
@@ -76,15 +79,13 @@
76
79
  overflow: hidden;
77
80
  flex: 1 1 auto;
78
81
  }
79
- .blank {
80
- height: var(--row-height);
81
- background: var(--cell-background);
82
- border-bottom: var(--cell-border);
83
- border-right: var(--cell-border);
84
- position: absolute;
82
+ .row {
83
+ display: flex;
84
+ flex-direction: row;
85
+ justify-content: flex-start;
86
+ align-items: stretch;
85
87
  }
86
- .blank.highlighted {
87
- background: var(--cell-background-hover);
88
+ .blank :global(.cell:hover) {
88
89
  cursor: pointer;
89
90
  }
90
91
  </style>
@@ -31,6 +31,7 @@
31
31
  filter,
32
32
  inlineFilters,
33
33
  columnRenderMap,
34
+ scrollTop,
34
35
  } = getContext("grid")
35
36
 
36
37
  let visible = false
@@ -43,6 +44,21 @@
43
44
  $: $datasource, (visible = false)
44
45
  $: selectedRowCount = Object.values($selectedRows).length
45
46
  $: hasNoRows = !$rows.length
47
+ $: renderedRowCount = $renderedRows.length
48
+ $: offset = getOffset($hasNextPage, renderedRowCount, $rowHeight, $scrollTop)
49
+
50
+ const getOffset = (hasNextPage, rowCount, rowHeight, scrollTop) => {
51
+ // If we have a next page of data then we aren't truly at the bottom, so we
52
+ // render the add row component at the top
53
+ if (hasNextPage) {
54
+ return 0
55
+ }
56
+ offset = rowCount * rowHeight - (scrollTop % rowHeight)
57
+ if (rowCount !== 0) {
58
+ offset -= 1
59
+ }
60
+ return offset
61
+ }
46
62
 
47
63
  const addRow = async () => {
48
64
  // Blur the active cell and tick to let final value updates propagate
@@ -85,23 +101,13 @@
85
101
  return
86
102
  }
87
103
 
88
- // If we have a next page of data then we aren't truly at the bottom, so we
89
- // render the add row component at the top
90
- if ($hasNextPage) {
91
- offset = 0
92
- }
93
-
94
104
  // If we don't have a next page then we're at the bottom and can scroll to
95
105
  // the max available offset
96
- else {
106
+ if (!$hasNextPage) {
97
107
  scroll.update(state => ({
98
108
  ...state,
99
109
  top: $maxScrollTop,
100
110
  }))
101
- offset = $renderedRows.length * $rowHeight - ($maxScrollTop % $rowHeight)
102
- if ($renderedRows.length !== 0) {
103
- offset -= 1
104
- }
105
111
  }
106
112
 
107
113
  // Update state and select initial cell
@@ -171,39 +177,41 @@
171
177
  <!-- Only show new row functionality if we have any columns -->
172
178
  {#if visible}
173
179
  <div
174
- class="container"
180
+ class="new-row"
175
181
  class:floating={offset > 0}
176
182
  style="--offset:{offset}px; --sticky-width:{width}px;"
177
183
  >
178
184
  <div class="underlay sticky" transition:fade|local={{ duration: 130 }} />
179
185
  <div class="underlay" transition:fade|local={{ duration: 130 }} />
180
186
  <div class="sticky-column" transition:fade|local={{ duration: 130 }}>
181
- <GutterCell expandable on:expand={addViaModal} rowHovered>
182
- <Icon name="Add" color="var(--spectrum-global-color-gray-500)" />
183
- {#if isAdding}
184
- <div in:fade={{ duration: 130 }} class="loading-overlay" />
185
- {/if}
186
- </GutterCell>
187
- {#if $stickyColumn}
188
- {@const cellId = getCellID(NewRowID, $stickyColumn.name)}
189
- <DataCell
190
- {cellId}
191
- rowFocused
192
- column={$stickyColumn}
193
- row={newRow}
194
- focused={$focusedCellId === cellId}
195
- width={$stickyColumn.width}
196
- {updateValue}
197
- topRow={offset === 0}
198
- >
199
- {#if $stickyColumn?.schema?.autocolumn}
200
- <div class="readonly-overlay">Can't edit auto column</div>
201
- {/if}
187
+ <div class="row">
188
+ <GutterCell expandable on:expand={addViaModal} rowHovered>
189
+ <Icon name="Add" color="var(--spectrum-global-color-gray-500)" />
202
190
  {#if isAdding}
203
191
  <div in:fade={{ duration: 130 }} class="loading-overlay" />
204
192
  {/if}
205
- </DataCell>
206
- {/if}
193
+ </GutterCell>
194
+ {#if $stickyColumn}
195
+ {@const cellId = getCellID(NewRowID, $stickyColumn.name)}
196
+ <DataCell
197
+ {cellId}
198
+ rowFocused
199
+ column={$stickyColumn}
200
+ row={newRow}
201
+ focused={$focusedCellId === cellId}
202
+ width={$stickyColumn.width}
203
+ {updateValue}
204
+ topRow={offset === 0}
205
+ >
206
+ {#if $stickyColumn?.schema?.autocolumn}
207
+ <div class="readonly-overlay">Can't edit auto column</div>
208
+ {/if}
209
+ {#if isAdding}
210
+ <div in:fade={{ duration: 130 }} class="loading-overlay" />
211
+ {/if}
212
+ </DataCell>
213
+ {/if}
214
+ </div>
207
215
  </div>
208
216
  <div class="normal-columns" transition:fade|local={{ duration: 130 }}>
209
217
  <GridScrollWrapper scrollHorizontally attachHandlers>
@@ -270,7 +278,7 @@
270
278
  margin-left: -6px;
271
279
  }
272
280
 
273
- .container {
281
+ .new-row {
274
282
  position: absolute;
275
283
  top: var(--default-row-height);
276
284
  left: 0;
@@ -280,10 +288,10 @@
280
288
  flex-direction: row;
281
289
  align-items: stretch;
282
290
  }
283
- .container :global(.cell) {
291
+ .new-row :global(.cell) {
284
292
  --cell-background: var(--spectrum-global-color-gray-75) !important;
285
293
  }
286
- .container.floating :global(.cell) {
294
+ .new-row.floating :global(.cell) {
287
295
  height: calc(var(--row-height) + 1px);
288
296
  border-top: var(--cell-border);
289
297
  }
@@ -312,8 +320,10 @@
312
320
  pointer-events: all;
313
321
  z-index: 3;
314
322
  position: absolute;
315
- top: calc(var(--row-height) + var(--offset) + 24px);
316
- left: 18px;
323
+ top: calc(
324
+ var(--row-height) + var(--offset) + var(--default-row-height) / 2
325
+ );
326
+ left: calc(var(--default-row-height) / 2);
317
327
  }
318
328
  .button-with-keys {
319
329
  display: flex;
@@ -66,62 +66,58 @@
66
66
 
67
67
  <!-- svelte-ignore a11y-no-static-element-interactions -->
68
68
  <!-- svelte-ignore a11y-click-events-have-key-events -->
69
- <div class="content">
70
- <GridScrollWrapper scrollVertically attachHandlers>
71
- {#each $renderedRows as row, idx}
72
- {@const rowSelected = !!$selectedRows[row._id]}
73
- {@const rowHovered = $hoveredRowId === row._id}
74
- {@const rowFocused = $focusedRow?._id === row._id}
75
- {@const cellId = getCellID(row._id, $stickyColumn?.name)}
76
- <div
77
- class="row"
78
- on:mouseenter={$isDragging ? null : () => ($hoveredRowId = row._id)}
79
- on:mouseleave={$isDragging ? null : () => ($hoveredRowId = null)}
80
- on:click={() => dispatch("rowclick", rows.actions.cleanRow(row))}
81
- >
82
- <GutterCell {row} {rowFocused} {rowHovered} {rowSelected} />
83
- {#if $stickyColumn}
84
- <DataCell
85
- {row}
86
- {cellId}
87
- {rowFocused}
88
- selected={rowSelected}
89
- highlighted={rowHovered || rowFocused}
90
- rowIdx={row.__idx}
91
- topRow={idx === 0}
92
- focused={$focusedCellId === cellId}
93
- selectedUser={$selectedCellMap[cellId]}
94
- width={$stickyColumn.width}
95
- column={$stickyColumn}
96
- contentLines={$contentLines}
97
- />
98
- {/if}
99
- </div>
100
- {/each}
101
- {#if $config.canAddRows}
102
- <div
103
- class="row new"
104
- on:mouseenter={$isDragging
105
- ? null
106
- : () => ($hoveredRowId = BlankRowID)}
107
- on:mouseleave={$isDragging ? null : () => ($hoveredRowId = null)}
108
- on:click={() => dispatch("add-row-inline")}
109
- >
110
- <GutterCell rowHovered={$hoveredRowId === BlankRowID}>
111
- <Icon name="Add" color="var(--spectrum-global-color-gray-500)" />
112
- </GutterCell>
113
- {#if $stickyColumn}
114
- <GridCell
115
- width={$stickyColumn.width}
116
- highlighted={$hoveredRowId === BlankRowID}
117
- >
118
- <KeyboardShortcut padded keybind="Ctrl+Enter" />
119
- </GridCell>
120
- {/if}
121
- </div>
122
- {/if}
123
- </GridScrollWrapper>
124
- </div>
69
+ <GridScrollWrapper scrollVertically attachHandlers>
70
+ {#each $renderedRows as row, idx}
71
+ {@const rowSelected = !!$selectedRows[row._id]}
72
+ {@const rowHovered = $hoveredRowId === row._id}
73
+ {@const rowFocused = $focusedRow?._id === row._id}
74
+ {@const cellId = getCellID(row._id, $stickyColumn?.name)}
75
+ <div
76
+ class="row"
77
+ on:mouseenter={$isDragging ? null : () => ($hoveredRowId = row._id)}
78
+ on:mouseleave={$isDragging ? null : () => ($hoveredRowId = null)}
79
+ on:click={() => dispatch("rowclick", rows.actions.cleanRow(row))}
80
+ >
81
+ <GutterCell {row} {rowFocused} {rowHovered} {rowSelected} />
82
+ {#if $stickyColumn}
83
+ <DataCell
84
+ {row}
85
+ {cellId}
86
+ {rowFocused}
87
+ selected={rowSelected}
88
+ highlighted={rowHovered || rowFocused}
89
+ rowIdx={row.__idx}
90
+ topRow={idx === 0}
91
+ focused={$focusedCellId === cellId}
92
+ selectedUser={$selectedCellMap[cellId]}
93
+ width={$stickyColumn.width}
94
+ column={$stickyColumn}
95
+ contentLines={$contentLines}
96
+ />
97
+ {/if}
98
+ </div>
99
+ {/each}
100
+ {#if $config.canAddRows}
101
+ <div
102
+ class="row blank"
103
+ on:mouseenter={$isDragging ? null : () => ($hoveredRowId = BlankRowID)}
104
+ on:mouseleave={$isDragging ? null : () => ($hoveredRowId = null)}
105
+ on:click={() => dispatch("add-row-inline")}
106
+ >
107
+ <GutterCell rowHovered={$hoveredRowId === BlankRowID}>
108
+ <Icon name="Add" color="var(--spectrum-global-color-gray-500)" />
109
+ </GutterCell>
110
+ {#if $stickyColumn}
111
+ <GridCell
112
+ width={$stickyColumn.width}
113
+ highlighted={$hoveredRowId === BlankRowID}
114
+ >
115
+ <KeyboardShortcut padded keybind="Ctrl+Enter" />
116
+ </GridCell>
117
+ {/if}
118
+ </div>
119
+ {/if}
120
+ </GridScrollWrapper>
125
121
  </div>
126
122
 
127
123
  <style>
@@ -174,11 +170,7 @@
174
170
  justify-content: flex-start;
175
171
  align-items: stretch;
176
172
  }
177
- .content {
178
- position: relative;
179
- flex: 1 1 auto;
180
- }
181
- .row.new :global(*:hover) {
173
+ .blank :global(.cell:hover) {
182
174
  cursor: pointer;
183
175
  }
184
176
  </style>
@@ -1,12 +1,13 @@
1
- export const Padding = 100
2
- export const ScrollBarSize = 8
3
- export const GutterWidth = 72
4
- export const DefaultColumnWidth = 200
5
- export const MinColumnWidth = 80
6
1
  export const SmallRowHeight = 36
7
2
  export const MediumRowHeight = 64
8
3
  export const LargeRowHeight = 92
9
4
  export const DefaultRowHeight = SmallRowHeight
5
+ export const VPadding = SmallRowHeight * 2
6
+ export const HPadding = 40
7
+ export const ScrollBarSize = 8
8
+ export const GutterWidth = 72
9
+ export const DefaultColumnWidth = 200
10
+ export const MinColumnWidth = 80
10
11
  export const NewRowID = "new"
11
12
  export const BlankRowID = "blank"
12
13
  export const RowPageSize = 100
@@ -1,6 +1,12 @@
1
1
  import { writable, derived, get } from "svelte/store"
2
2
  import { tick } from "svelte"
3
- import { Padding, GutterWidth, FocusedCellMinOffset } from "../lib/constants"
3
+ import {
4
+ GutterWidth,
5
+ FocusedCellMinOffset,
6
+ ScrollBarSize,
7
+ HPadding,
8
+ VPadding,
9
+ } from "../lib/constants"
4
10
  import { parseCellID } from "../lib/utils"
5
11
 
6
12
  export const createStores = () => {
@@ -34,28 +40,15 @@ export const deriveStores = context => {
34
40
  // Memoize store primitives
35
41
  const stickyColumnWidth = derived(stickyColumn, $col => $col?.width || 0, 0)
36
42
 
37
- // Derive vertical limits
38
- const contentHeight = derived(
39
- [rows, rowHeight],
40
- ([$rows, $rowHeight]) => ($rows.length + 1) * $rowHeight + Padding,
41
- 0
42
- )
43
- const maxScrollTop = derived(
44
- [height, contentHeight],
45
- ([$height, $contentHeight]) => Math.max($contentHeight - $height, 0),
46
- 0
47
- )
48
-
49
43
  // Derive horizontal limits
50
44
  const contentWidth = derived(
51
45
  [visibleColumns, stickyColumnWidth, buttonColumnWidth],
52
46
  ([$visibleColumns, $stickyColumnWidth, $buttonColumnWidth]) => {
53
- const space = Math.max(Padding, $buttonColumnWidth - 1)
54
- let width = GutterWidth + space + $stickyColumnWidth
47
+ let width = GutterWidth + $buttonColumnWidth + $stickyColumnWidth
55
48
  $visibleColumns.forEach(col => {
56
49
  width += col.width
57
50
  })
58
- return width
51
+ return width + HPadding
59
52
  },
60
53
  0
61
54
  )
@@ -71,20 +64,36 @@ export const deriveStores = context => {
71
64
  },
72
65
  0
73
66
  )
67
+ const showHScrollbar = derived(
68
+ [contentWidth, screenWidth],
69
+ ([$contentWidth, $screenWidth]) => {
70
+ return $contentWidth > $screenWidth
71
+ }
72
+ )
74
73
 
75
- // Derive whether to show scrollbars or not
74
+ // Derive vertical limits
75
+ const contentHeight = derived(
76
+ [rows, rowHeight, showHScrollbar],
77
+ ([$rows, $rowHeight, $showHScrollbar]) => {
78
+ let height = ($rows.length + 1) * $rowHeight + VPadding
79
+ if ($showHScrollbar) {
80
+ height += ScrollBarSize * 2
81
+ }
82
+ return height
83
+ },
84
+ 0
85
+ )
86
+ const maxScrollTop = derived(
87
+ [height, contentHeight],
88
+ ([$height, $contentHeight]) => Math.max($contentHeight - $height, 0),
89
+ 0
90
+ )
76
91
  const showVScrollbar = derived(
77
92
  [contentHeight, height],
78
93
  ([$contentHeight, $height]) => {
79
94
  return $contentHeight > $height
80
95
  }
81
96
  )
82
- const showHScrollbar = derived(
83
- [contentWidth, screenWidth],
84
- ([$contentWidth, $screenWidth]) => {
85
- return $contentWidth > $screenWidth
86
- }
87
- )
88
97
 
89
98
  return {
90
99
  contentHeight,