@budibase/frontend-core 2.8.29-alpha.5 → 2.8.30
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 -4
- package/src/api/app.js +0 -9
- package/src/api/index.js +0 -2
- package/src/components/UserAvatar.svelte +44 -9
- package/src/components/grid/cells/RelationshipCell.svelte +1 -1
- package/src/components/grid/controls/AddColumnButton.svelte +16 -0
- package/src/components/grid/controls/AddRowButton.svelte +18 -0
- package/src/components/grid/layout/Grid.svelte +1 -2
- package/src/components/grid/layout/GridBody.svelte +2 -2
- package/src/components/grid/layout/HeaderRow.svelte +9 -20
- package/src/components/grid/layout/NewRow.svelte +12 -20
- package/src/components/grid/layout/StickyColumn.svelte +3 -2
- package/src/components/grid/overlays/KeyboardManager.svelte +2 -3
- package/src/components/grid/overlays/MenuOverlay.svelte +1 -2
- package/src/components/grid/overlays/ResizeOverlay.svelte +9 -2
- package/src/components/grid/stores/columns.js +0 -16
- package/src/components/grid/stores/ui.js +0 -11
- package/src/components/grid/stores/users.js +2 -3
- package/src/components/index.js +0 -1
- package/src/utils/download.js +0 -23
- package/src/utils/index.js +1 -1
- package/src/api/logs.js +0 -14
- package/src/components/UserAvatars.svelte +0 -67
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/frontend-core",
|
|
3
|
-
"version": "2.8.
|
|
3
|
+
"version": "2.8.30",
|
|
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.8.
|
|
10
|
-
"@budibase/shared-core": "2.8.
|
|
9
|
+
"@budibase/bbui": "2.8.30",
|
|
10
|
+
"@budibase/shared-core": "2.8.30",
|
|
11
11
|
"dayjs": "^1.11.7",
|
|
12
12
|
"lodash": "^4.17.21",
|
|
13
13
|
"socket.io-client": "^4.6.1",
|
|
14
14
|
"svelte": "^3.46.2"
|
|
15
15
|
},
|
|
16
|
-
"gitHead": "
|
|
16
|
+
"gitHead": "0bb17a32b1120c5b2526983870dbec4ee8cd6086"
|
|
17
17
|
}
|
package/src/api/app.js
CHANGED
|
@@ -123,15 +123,6 @@ export const buildAppEndpoints = API => ({
|
|
|
123
123
|
})
|
|
124
124
|
},
|
|
125
125
|
|
|
126
|
-
/**
|
|
127
|
-
* Gets budibase platform debug information.
|
|
128
|
-
*/
|
|
129
|
-
fetchSystemDebugInfo: async () => {
|
|
130
|
-
return await API.get({
|
|
131
|
-
url: `/api/debug/diagnostics`,
|
|
132
|
-
})
|
|
133
|
-
},
|
|
134
|
-
|
|
135
126
|
/**
|
|
136
127
|
* Syncs an app with the production database.
|
|
137
128
|
* @param appId the ID of the app to sync
|
package/src/api/index.js
CHANGED
|
@@ -30,7 +30,6 @@ import { buildBackupsEndpoints } from "./backups"
|
|
|
30
30
|
import { buildEnvironmentVariableEndpoints } from "./environmentVariables"
|
|
31
31
|
import { buildEventEndpoints } from "./events"
|
|
32
32
|
import { buildAuditLogsEndpoints } from "./auditLogs"
|
|
33
|
-
import { buildLogsEndpoints } from "./logs"
|
|
34
33
|
|
|
35
34
|
/**
|
|
36
35
|
* Random identifier to uniquely identify a session in a tab. This is
|
|
@@ -278,6 +277,5 @@ export const createAPIClient = config => {
|
|
|
278
277
|
...buildEnvironmentVariableEndpoints(API),
|
|
279
278
|
...buildEventEndpoints(API),
|
|
280
279
|
...buildAuditLogsEndpoints(API),
|
|
281
|
-
...buildLogsEndpoints(API),
|
|
282
280
|
}
|
|
283
281
|
}
|
|
@@ -1,23 +1,58 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import { Avatar,
|
|
2
|
+
import { Avatar, Tooltip } from "@budibase/bbui"
|
|
3
3
|
import { helpers } from "@budibase/shared-core"
|
|
4
4
|
|
|
5
5
|
export let user
|
|
6
|
-
export let size
|
|
7
|
-
export let
|
|
6
|
+
export let size
|
|
7
|
+
export let tooltipDirection = "top"
|
|
8
8
|
export let showTooltip = true
|
|
9
|
+
|
|
10
|
+
$: tooltipStyle = getTooltipStyle(tooltipDirection)
|
|
11
|
+
|
|
12
|
+
const getTooltipStyle = direction => {
|
|
13
|
+
if (!direction) {
|
|
14
|
+
return ""
|
|
15
|
+
}
|
|
16
|
+
if (direction === "top") {
|
|
17
|
+
return "transform: translateX(-50%) translateY(-100%);"
|
|
18
|
+
} else if (direction === "bottom") {
|
|
19
|
+
return "transform: translateX(-50%) translateY(100%);"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
9
22
|
</script>
|
|
10
23
|
|
|
11
24
|
{#if user}
|
|
12
|
-
<
|
|
13
|
-
text={showTooltip ? helpers.getUserLabel(user) : null}
|
|
14
|
-
position={tooltipPosition}
|
|
15
|
-
color={helpers.getUserColor(user)}
|
|
16
|
-
>
|
|
25
|
+
<div class="user-avatar">
|
|
17
26
|
<Avatar
|
|
18
27
|
{size}
|
|
19
28
|
initials={helpers.getUserInitials(user)}
|
|
20
29
|
color={helpers.getUserColor(user)}
|
|
21
30
|
/>
|
|
22
|
-
|
|
31
|
+
{#if showTooltip}
|
|
32
|
+
<div class="tooltip" style={tooltipStyle}>
|
|
33
|
+
<Tooltip
|
|
34
|
+
direction={tooltipDirection}
|
|
35
|
+
textWrapping
|
|
36
|
+
text={user.email}
|
|
37
|
+
size="S"
|
|
38
|
+
/>
|
|
39
|
+
</div>
|
|
40
|
+
{/if}
|
|
41
|
+
</div>
|
|
23
42
|
{/if}
|
|
43
|
+
|
|
44
|
+
<style>
|
|
45
|
+
.user-avatar {
|
|
46
|
+
position: relative;
|
|
47
|
+
}
|
|
48
|
+
.tooltip {
|
|
49
|
+
display: none;
|
|
50
|
+
position: absolute;
|
|
51
|
+
top: 0;
|
|
52
|
+
left: 50%;
|
|
53
|
+
white-space: nowrap;
|
|
54
|
+
}
|
|
55
|
+
.user-avatar:hover .tooltip {
|
|
56
|
+
display: block;
|
|
57
|
+
}
|
|
58
|
+
</style>
|
|
@@ -258,7 +258,7 @@
|
|
|
258
258
|
class:wrap={editable || contentLines > 1}
|
|
259
259
|
on:wheel={e => (focused ? e.stopPropagation() : null)}
|
|
260
260
|
>
|
|
261
|
-
{#each value || [] as relationship}
|
|
261
|
+
{#each value || [] as relationship, idx}
|
|
262
262
|
{#if relationship.primaryDisplay}
|
|
263
263
|
<div class="badge">
|
|
264
264
|
<span
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { ActionButton } from "@budibase/bbui"
|
|
3
|
+
import { getContext } from "svelte"
|
|
4
|
+
|
|
5
|
+
const { config, dispatch } = getContext("grid")
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<ActionButton
|
|
9
|
+
icon="TableColumnAddRight"
|
|
10
|
+
quiet
|
|
11
|
+
size="M"
|
|
12
|
+
on:click={() => dispatch("add-column")}
|
|
13
|
+
disabled={!$config.allowSchemaChanges}
|
|
14
|
+
>
|
|
15
|
+
Add column
|
|
16
|
+
</ActionButton>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { ActionButton } from "@budibase/bbui"
|
|
3
|
+
import { getContext } from "svelte"
|
|
4
|
+
|
|
5
|
+
const { dispatch, columns, stickyColumn, config, loaded } = getContext("grid")
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<ActionButton
|
|
9
|
+
icon="TableRowAddBottom"
|
|
10
|
+
quiet
|
|
11
|
+
size="M"
|
|
12
|
+
on:click={() => dispatch("add-row-inline")}
|
|
13
|
+
disabled={!loaded ||
|
|
14
|
+
!$config.allowAddRows ||
|
|
15
|
+
(!$columns.length && !$stickyColumn)}
|
|
16
|
+
>
|
|
17
|
+
Add row
|
|
18
|
+
</ActionButton>
|
|
@@ -71,7 +71,6 @@
|
|
|
71
71
|
contentLines,
|
|
72
72
|
gridFocused,
|
|
73
73
|
error,
|
|
74
|
-
canAddRows,
|
|
75
74
|
} = context
|
|
76
75
|
|
|
77
76
|
// Keep config store up to date with props
|
|
@@ -144,7 +143,7 @@
|
|
|
144
143
|
<HeaderRow />
|
|
145
144
|
<GridBody />
|
|
146
145
|
</div>
|
|
147
|
-
{#if
|
|
146
|
+
{#if allowAddRows}
|
|
148
147
|
<NewRow />
|
|
149
148
|
{/if}
|
|
150
149
|
<div class="overlays">
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
renderedRows,
|
|
10
10
|
renderedColumns,
|
|
11
11
|
rowVerticalInversionIndex,
|
|
12
|
-
|
|
12
|
+
config,
|
|
13
13
|
hoveredRowId,
|
|
14
14
|
dispatch,
|
|
15
15
|
isDragging,
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
invertY={idx >= $rowVerticalInversionIndex}
|
|
44
44
|
/>
|
|
45
45
|
{/each}
|
|
46
|
-
{#if $
|
|
46
|
+
{#if $config.allowAddRows && $renderedColumns.length}
|
|
47
47
|
<div
|
|
48
48
|
class="blank"
|
|
49
49
|
class:highlighted={$hoveredRowId === BlankRowID}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { getContext } from "svelte"
|
|
3
3
|
import GridScrollWrapper from "./GridScrollWrapper.svelte"
|
|
4
4
|
import HeaderCell from "../cells/HeaderCell.svelte"
|
|
5
|
-
import { Icon
|
|
5
|
+
import { Icon } from "@budibase/bbui"
|
|
6
6
|
|
|
7
7
|
const {
|
|
8
8
|
renderedColumns,
|
|
@@ -11,13 +11,10 @@
|
|
|
11
11
|
hiddenColumnsWidth,
|
|
12
12
|
width,
|
|
13
13
|
config,
|
|
14
|
-
hasNonAutoColumn,
|
|
15
|
-
tableId,
|
|
16
|
-
loading,
|
|
17
14
|
} = getContext("grid")
|
|
18
15
|
|
|
19
16
|
$: columnsWidth = $renderedColumns.reduce(
|
|
20
|
-
(total, col) => total
|
|
17
|
+
(total, col) => (total += col.width),
|
|
21
18
|
0
|
|
22
19
|
)
|
|
23
20
|
$: end = $hiddenColumnsWidth + columnsWidth - 1 - $scroll.left
|
|
@@ -33,21 +30,13 @@
|
|
|
33
30
|
</div>
|
|
34
31
|
</GridScrollWrapper>
|
|
35
32
|
{#if $config.allowSchemaChanges}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
class="add"
|
|
44
|
-
style="left:{left}px;"
|
|
45
|
-
on:click={() => dispatch("add-column")}
|
|
46
|
-
>
|
|
47
|
-
<Icon name="Add" />
|
|
48
|
-
</div>
|
|
49
|
-
</TempTooltip>
|
|
50
|
-
{/key}
|
|
33
|
+
<div
|
|
34
|
+
class="add"
|
|
35
|
+
style="left:{left}px"
|
|
36
|
+
on:click={() => dispatch("add-column")}
|
|
37
|
+
>
|
|
38
|
+
<Icon name="Add" />
|
|
39
|
+
</div>
|
|
51
40
|
{/if}
|
|
52
41
|
</div>
|
|
53
42
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { getContext, onDestroy, onMount, tick } from "svelte"
|
|
3
|
-
import { Icon, Button
|
|
3
|
+
import { Icon, Button } from "@budibase/bbui"
|
|
4
4
|
import GridScrollWrapper from "./GridScrollWrapper.svelte"
|
|
5
5
|
import DataCell from "../cells/DataCell.svelte"
|
|
6
6
|
import { fade } from "svelte/transition"
|
|
@@ -27,8 +27,7 @@
|
|
|
27
27
|
rowVerticalInversionIndex,
|
|
28
28
|
columnHorizontalInversionIndex,
|
|
29
29
|
selectedRows,
|
|
30
|
-
|
|
31
|
-
canAddRows,
|
|
30
|
+
config,
|
|
32
31
|
} = getContext("grid")
|
|
33
32
|
|
|
34
33
|
let visible = false
|
|
@@ -41,7 +40,6 @@
|
|
|
41
40
|
$: $tableId, (visible = false)
|
|
42
41
|
$: invertY = shouldInvertY(offset, $rowVerticalInversionIndex, $renderedRows)
|
|
43
42
|
$: selectedRowCount = Object.values($selectedRows).length
|
|
44
|
-
$: hasNoRows = !$rows.length
|
|
45
43
|
|
|
46
44
|
const shouldInvertY = (offset, inversionIndex, rows) => {
|
|
47
45
|
if (offset === 0) {
|
|
@@ -149,22 +147,16 @@
|
|
|
149
147
|
</script>
|
|
150
148
|
|
|
151
149
|
<!-- New row FAB -->
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
class:offset={!$stickyColumn}
|
|
163
|
-
>
|
|
164
|
-
<Icon name="Add" size="S" />
|
|
165
|
-
</div>
|
|
166
|
-
{/if}
|
|
167
|
-
</TempTooltip>
|
|
150
|
+
{#if !visible && !selectedRowCount && $config.allowAddRows && firstColumn}
|
|
151
|
+
<div
|
|
152
|
+
class="new-row-fab"
|
|
153
|
+
on:click={() => dispatch("add-row-inline")}
|
|
154
|
+
transition:fade|local={{ duration: 130 }}
|
|
155
|
+
class:offset={!$stickyColumn}
|
|
156
|
+
>
|
|
157
|
+
<Icon name="Add" size="S" />
|
|
158
|
+
</div>
|
|
159
|
+
{/if}
|
|
168
160
|
|
|
169
161
|
<!-- Only show new row functionality if we have any columns -->
|
|
170
162
|
{#if visible}
|
|
@@ -13,10 +13,11 @@
|
|
|
13
13
|
rows,
|
|
14
14
|
selectedRows,
|
|
15
15
|
stickyColumn,
|
|
16
|
+
renderedColumns,
|
|
16
17
|
renderedRows,
|
|
17
18
|
focusedCellId,
|
|
18
19
|
hoveredRowId,
|
|
19
|
-
|
|
20
|
+
config,
|
|
20
21
|
selectedCellMap,
|
|
21
22
|
focusedRow,
|
|
22
23
|
scrollLeft,
|
|
@@ -92,7 +93,7 @@
|
|
|
92
93
|
{/if}
|
|
93
94
|
</div>
|
|
94
95
|
{/each}
|
|
95
|
-
{#if $
|
|
96
|
+
{#if $config.allowAddRows && ($renderedColumns.length || $stickyColumn)}
|
|
96
97
|
<div
|
|
97
98
|
class="row new"
|
|
98
99
|
on:mouseenter={$isDragging
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
config,
|
|
17
17
|
menu,
|
|
18
18
|
gridFocused,
|
|
19
|
-
canAddRows,
|
|
20
19
|
} = getContext("grid")
|
|
21
20
|
|
|
22
21
|
const ignoredOriginSelectors = [
|
|
@@ -46,7 +45,7 @@
|
|
|
46
45
|
e.preventDefault()
|
|
47
46
|
focusFirstCell()
|
|
48
47
|
} else if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
|
|
49
|
-
if ($
|
|
48
|
+
if ($config.allowAddRows) {
|
|
50
49
|
e.preventDefault()
|
|
51
50
|
dispatch("add-row-inline")
|
|
52
51
|
}
|
|
@@ -100,7 +99,7 @@
|
|
|
100
99
|
}
|
|
101
100
|
break
|
|
102
101
|
case "Enter":
|
|
103
|
-
if ($
|
|
102
|
+
if ($config.allowAddRows) {
|
|
104
103
|
dispatch("add-row-inline")
|
|
105
104
|
}
|
|
106
105
|
}
|
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
focusedCellAPI,
|
|
18
18
|
focusedRowId,
|
|
19
19
|
notifications,
|
|
20
|
-
canAddRows,
|
|
21
20
|
} = getContext("grid")
|
|
22
21
|
|
|
23
22
|
$: style = makeStyle($menu)
|
|
@@ -94,7 +93,7 @@
|
|
|
94
93
|
</MenuItem>
|
|
95
94
|
<MenuItem
|
|
96
95
|
icon="Duplicate"
|
|
97
|
-
disabled={isNewRow || !$
|
|
96
|
+
disabled={isNewRow || !$config.allowAddRows}
|
|
98
97
|
on:click={duplicate}
|
|
99
98
|
>
|
|
100
99
|
Duplicate row
|
|
@@ -2,9 +2,16 @@
|
|
|
2
2
|
import { getContext } from "svelte"
|
|
3
3
|
import { GutterWidth } from "../lib/constants"
|
|
4
4
|
|
|
5
|
-
const {
|
|
6
|
-
|
|
5
|
+
const {
|
|
6
|
+
columns,
|
|
7
|
+
resize,
|
|
8
|
+
renderedColumns,
|
|
9
|
+
stickyColumn,
|
|
10
|
+
isReordering,
|
|
11
|
+
scrollLeft,
|
|
12
|
+
} = getContext("grid")
|
|
7
13
|
|
|
14
|
+
$: cutoff = $scrollLeft + GutterWidth + ($columns[0]?.width || 0)
|
|
8
15
|
$: offset = GutterWidth + ($stickyColumn?.width || 0)
|
|
9
16
|
$: activeColumn = $resize.column
|
|
10
17
|
|
|
@@ -83,21 +83,6 @@ export const deriveStores = context => {
|
|
|
83
83
|
await saveChanges()
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
// Derive if we have any normal columns
|
|
87
|
-
const hasNonAutoColumn = derived(
|
|
88
|
-
[columns, stickyColumn],
|
|
89
|
-
([$columns, $stickyColumn]) => {
|
|
90
|
-
let allCols = $columns || []
|
|
91
|
-
if ($stickyColumn) {
|
|
92
|
-
allCols = [...allCols, $stickyColumn]
|
|
93
|
-
}
|
|
94
|
-
const normalCols = allCols.filter(column => {
|
|
95
|
-
return !column.schema?.autocolumn
|
|
96
|
-
})
|
|
97
|
-
return normalCols.length > 0
|
|
98
|
-
}
|
|
99
|
-
)
|
|
100
|
-
|
|
101
86
|
// Persists column changes by saving metadata against table schema
|
|
102
87
|
const saveChanges = async () => {
|
|
103
88
|
const $columns = get(columns)
|
|
@@ -143,7 +128,6 @@ export const deriveStores = context => {
|
|
|
143
128
|
}
|
|
144
129
|
|
|
145
130
|
return {
|
|
146
|
-
hasNonAutoColumn,
|
|
147
131
|
columns: {
|
|
148
132
|
...columns,
|
|
149
133
|
actions: {
|
|
@@ -70,8 +70,6 @@ export const deriveStores = context => {
|
|
|
70
70
|
rowHeight,
|
|
71
71
|
stickyColumn,
|
|
72
72
|
width,
|
|
73
|
-
hasNonAutoColumn,
|
|
74
|
-
config,
|
|
75
73
|
} = context
|
|
76
74
|
|
|
77
75
|
// Derive the row that contains the selected cell
|
|
@@ -114,16 +112,7 @@ export const deriveStores = context => {
|
|
|
114
112
|
return ($stickyColumn?.width || 0) + $width + GutterWidth < 1100
|
|
115
113
|
})
|
|
116
114
|
|
|
117
|
-
// Derive if we're able to add rows
|
|
118
|
-
const canAddRows = derived(
|
|
119
|
-
[config, hasNonAutoColumn],
|
|
120
|
-
([$config, $hasNonAutoColumn]) => {
|
|
121
|
-
return $config.allowAddRows && $hasNonAutoColumn
|
|
122
|
-
}
|
|
123
|
-
)
|
|
124
|
-
|
|
125
115
|
return {
|
|
126
|
-
canAddRows,
|
|
127
116
|
focusedRow,
|
|
128
117
|
contentLines,
|
|
129
118
|
compact,
|
|
@@ -30,9 +30,8 @@ export const deriveStores = context => {
|
|
|
30
30
|
([$users, $focusedCellId]) => {
|
|
31
31
|
let map = {}
|
|
32
32
|
$users.forEach(user => {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
map[cellId] = user
|
|
33
|
+
if (user.focusedCellId && user.focusedCellId !== $focusedCellId) {
|
|
34
|
+
map[user.focusedCellId] = user
|
|
36
35
|
}
|
|
37
36
|
})
|
|
38
37
|
return map
|
package/src/components/index.js
CHANGED
|
@@ -2,5 +2,4 @@ export { default as SplitPage } from "./SplitPage.svelte"
|
|
|
2
2
|
export { default as TestimonialPage } from "./TestimonialPage.svelte"
|
|
3
3
|
export { default as Testimonial } from "./Testimonial.svelte"
|
|
4
4
|
export { default as UserAvatar } from "./UserAvatar.svelte"
|
|
5
|
-
export { default as UserAvatars } from "./UserAvatars.svelte"
|
|
6
5
|
export { Grid } from "./grid"
|
package/src/utils/download.js
CHANGED
|
@@ -11,26 +11,3 @@ export function downloadText(filename, text) {
|
|
|
11
11
|
|
|
12
12
|
URL.revokeObjectURL(url)
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
export async function downloadStream(streamResponse) {
|
|
16
|
-
const blob = await streamResponse.blob()
|
|
17
|
-
|
|
18
|
-
const contentDisposition = streamResponse.headers.get("Content-Disposition")
|
|
19
|
-
|
|
20
|
-
const matches = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/.exec(
|
|
21
|
-
contentDisposition
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
const filename = matches[1].replace(/['"]/g, "")
|
|
25
|
-
|
|
26
|
-
const resBlob = new Blob([blob])
|
|
27
|
-
|
|
28
|
-
const blobUrl = URL.createObjectURL(resBlob)
|
|
29
|
-
|
|
30
|
-
const link = document.createElement("a")
|
|
31
|
-
link.href = blobUrl
|
|
32
|
-
link.download = filename
|
|
33
|
-
link.click()
|
|
34
|
-
|
|
35
|
-
URL.revokeObjectURL(blobUrl)
|
|
36
|
-
}
|
package/src/utils/index.js
CHANGED
package/src/api/logs.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export const buildLogsEndpoints = API => ({
|
|
2
|
-
/**
|
|
3
|
-
* Gets a stream for the system logs.
|
|
4
|
-
*/
|
|
5
|
-
getSystemLogs: async () => {
|
|
6
|
-
return await API.get({
|
|
7
|
-
url: "/api/system/logs",
|
|
8
|
-
json: false,
|
|
9
|
-
parseResponse: async response => {
|
|
10
|
-
return response
|
|
11
|
-
},
|
|
12
|
-
})
|
|
13
|
-
},
|
|
14
|
-
})
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { UserAvatar } from "@budibase/frontend-core"
|
|
3
|
-
import { TooltipPosition, Avatar } from "@budibase/bbui"
|
|
4
|
-
|
|
5
|
-
export let users = []
|
|
6
|
-
export let order = "ltr"
|
|
7
|
-
export let size = "S"
|
|
8
|
-
export let tooltipPosition = TooltipPosition.Top
|
|
9
|
-
|
|
10
|
-
$: uniqueUsers = unique(users, order)
|
|
11
|
-
$: avatars = getAvatars(uniqueUsers, order)
|
|
12
|
-
|
|
13
|
-
const unique = users => {
|
|
14
|
-
let uniqueUsers = {}
|
|
15
|
-
users?.forEach(user => {
|
|
16
|
-
uniqueUsers[user.email] = user
|
|
17
|
-
})
|
|
18
|
-
return Object.values(uniqueUsers)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const getAvatars = (users, order) => {
|
|
22
|
-
const avatars = users.slice(0, 3)
|
|
23
|
-
if (users.length > 3) {
|
|
24
|
-
const overflow = {
|
|
25
|
-
_id: "overflow",
|
|
26
|
-
label: `+${users.length - 3}`,
|
|
27
|
-
}
|
|
28
|
-
if (order === "ltr") {
|
|
29
|
-
avatars.push(overflow)
|
|
30
|
-
} else {
|
|
31
|
-
avatars.unshift(overflow)
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
return avatars.map((user, idx) => ({
|
|
35
|
-
...user,
|
|
36
|
-
zIndex: order === "ltr" ? idx : uniqueUsers.length - idx,
|
|
37
|
-
}))
|
|
38
|
-
}
|
|
39
|
-
</script>
|
|
40
|
-
|
|
41
|
-
<div class="avatars">
|
|
42
|
-
{#each avatars as user}
|
|
43
|
-
<span style="z-index:{user.zIndex};">
|
|
44
|
-
{#if user._id === "overflow"}
|
|
45
|
-
<Avatar
|
|
46
|
-
{size}
|
|
47
|
-
initials={user.label}
|
|
48
|
-
color="var(--spectrum-global-color-gray-500)"
|
|
49
|
-
/>
|
|
50
|
-
{:else}
|
|
51
|
-
<UserAvatar {size} {user} {tooltipPosition} />
|
|
52
|
-
{/if}
|
|
53
|
-
</span>
|
|
54
|
-
{/each}
|
|
55
|
-
</div>
|
|
56
|
-
|
|
57
|
-
<style>
|
|
58
|
-
.avatars {
|
|
59
|
-
display: flex;
|
|
60
|
-
}
|
|
61
|
-
span:not(:first-of-type) {
|
|
62
|
-
margin-left: -6px;
|
|
63
|
-
}
|
|
64
|
-
.avatars :global(.spectrum-Avatar) {
|
|
65
|
-
border: 2px solid var(--avatars-background, var(--background));
|
|
66
|
-
}
|
|
67
|
-
</style>
|