@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.
- package/package.json +4 -6
- package/src/components/index.js +0 -1
- package/src/constants.js +0 -1
- package/src/fetch/DataFetch.js +21 -27
- package/src/fetch/QueryFetch.js +1 -1
- package/src/themes/midnight.css +0 -3
- package/src/themes/nord.css +0 -3
- package/src/utils/utils.js +0 -20
- package/src/components/grid/cells/AttachmentCell.svelte +0 -153
- package/src/components/grid/cells/BooleanCell.svelte +0 -44
- package/src/components/grid/cells/DataCell.svelte +0 -86
- package/src/components/grid/cells/DateCell.svelte +0 -77
- package/src/components/grid/cells/FormulaCell.svelte +0 -5
- package/src/components/grid/cells/GridCell.svelte +0 -159
- package/src/components/grid/cells/HeaderCell.svelte +0 -237
- package/src/components/grid/cells/JSONCell.svelte +0 -36
- package/src/components/grid/cells/LongFormCell.svelte +0 -117
- package/src/components/grid/cells/MultiSelectCell.svelte +0 -7
- package/src/components/grid/cells/NumberCell.svelte +0 -7
- package/src/components/grid/cells/OptionsCell.svelte +0 -239
- package/src/components/grid/cells/RelationshipCell.svelte +0 -503
- package/src/components/grid/cells/TextCell.svelte +0 -110
- package/src/components/grid/controls/AddColumnButton.svelte +0 -16
- package/src/components/grid/controls/AddRowButton.svelte +0 -18
- package/src/components/grid/controls/BetaButton.svelte +0 -46
- package/src/components/grid/controls/DeleteButton.svelte +0 -72
- package/src/components/grid/controls/HideColumnsButton.svelte +0 -91
- package/src/components/grid/controls/RowHeightButton.svelte +0 -70
- package/src/components/grid/controls/SortButton.svelte +0 -107
- package/src/components/grid/index.js +0 -1
- package/src/components/grid/layout/Avatar.svelte +0 -24
- package/src/components/grid/layout/Grid.svelte +0 -250
- package/src/components/grid/layout/GridBody.svelte +0 -38
- package/src/components/grid/layout/GridRow.svelte +0 -57
- package/src/components/grid/layout/GridScrollWrapper.svelte +0 -84
- package/src/components/grid/layout/HeaderRow.svelte +0 -30
- package/src/components/grid/layout/NewRowTop.svelte +0 -247
- package/src/components/grid/layout/RowCount.svelte +0 -9
- package/src/components/grid/layout/StickyColumn.svelte +0 -245
- package/src/components/grid/layout/UserAvatars.svelte +0 -20
- package/src/components/grid/lib/constants.js +0 -11
- package/src/components/grid/lib/events.js +0 -29
- package/src/components/grid/lib/renderers.js +0 -29
- package/src/components/grid/lib/utils.js +0 -26
- package/src/components/grid/lib/websocket.js +0 -63
- package/src/components/grid/overlays/KeyboardManager.svelte +0 -180
- package/src/components/grid/overlays/MenuOverlay.svelte +0 -95
- package/src/components/grid/overlays/ReorderOverlay.svelte +0 -63
- package/src/components/grid/overlays/ResizeOverlay.svelte +0 -70
- package/src/components/grid/overlays/ScrollOverlay.svelte +0 -121
- package/src/components/grid/stores/bounds.js +0 -16
- package/src/components/grid/stores/clipboard.js +0 -34
- package/src/components/grid/stores/columns.js +0 -206
- package/src/components/grid/stores/index.js +0 -48
- package/src/components/grid/stores/menu.js +0 -49
- package/src/components/grid/stores/pagination.js +0 -24
- package/src/components/grid/stores/reorder.js +0 -155
- package/src/components/grid/stores/resize.js +0 -124
- package/src/components/grid/stores/rows.js +0 -462
- package/src/components/grid/stores/scroll.js +0 -201
- package/src/components/grid/stores/ui.js +0 -168
- package/src/components/grid/stores/users.js +0 -115
- package/src/components/grid/stores/validation.js +0 -45
- 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.
|
|
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.
|
|
10
|
-
"@budibase/shared-core": "2.5.
|
|
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": "
|
|
14
|
+
"gitHead": "6c37b6a6c69a1da43a5c0930419e743cc18b5b42"
|
|
17
15
|
}
|
package/src/components/index.js
CHANGED
package/src/constants.js
CHANGED
package/src/fetch/DataFetch.js
CHANGED
|
@@ -21,11 +21,11 @@ export default class DataFetch {
|
|
|
21
21
|
this.API = null
|
|
22
22
|
|
|
23
23
|
// Feature flags
|
|
24
|
-
this.
|
|
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(
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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.
|
|
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
|
|
141
|
+
// If no sort column, use the first field in the schema
|
|
140
142
|
if (!this.options.sortColumn) {
|
|
141
|
-
|
|
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 {
|
|
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 (!
|
|
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 (!
|
|
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 (!
|
|
208
|
+
if (!features.supportsPagination) {
|
|
215
209
|
rows = luceneLimit(rows, limit)
|
|
216
210
|
}
|
|
217
211
|
|
package/src/fetch/QueryFetch.js
CHANGED
|
@@ -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.
|
|
34
|
+
const { supportsPagination } = get(this.featureStore)
|
|
35
35
|
const { cursor, definition } = get(this.store)
|
|
36
36
|
const type = definition?.fields?.pagination?.type
|
|
37
37
|
|
package/src/themes/midnight.css
CHANGED
|
@@ -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
|
|
package/src/themes/nord.css
CHANGED
|
@@ -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
|
}
|
package/src/utils/utils.js
CHANGED
|
@@ -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>
|