Update buttons for views
This commit is contained in:
parent
38bd64cebd
commit
54f9507e53
|
@ -34,7 +34,7 @@
|
||||||
"dist"
|
"dist"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@adobe/spectrum-css-workflow-icons": "1.2.1",
|
"@adobe/spectrum-css-workflow-icons": "3.0.0",
|
||||||
"@budibase/shared-core": "0.0.0",
|
"@budibase/shared-core": "0.0.0",
|
||||||
"@budibase/string-templates": "0.0.0",
|
"@budibase/string-templates": "0.0.0",
|
||||||
"@spectrum-css/accordion": "3.0.24",
|
"@spectrum-css/accordion": "3.0.24",
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
<script>
|
|
||||||
import { API } from "api"
|
|
||||||
import Table from "./Table.svelte"
|
|
||||||
import { tables } from "stores/builder"
|
|
||||||
import { notifications } from "@budibase/bbui"
|
|
||||||
|
|
||||||
export let tableId
|
|
||||||
export let rowId
|
|
||||||
export let fieldName
|
|
||||||
|
|
||||||
let row
|
|
||||||
let title
|
|
||||||
|
|
||||||
$: data = row?.[fieldName] ?? []
|
|
||||||
$: linkedTableId = data?.length ? data[0].tableId : null
|
|
||||||
$: linkedTable = $tables.list.find(table => table._id === linkedTableId)
|
|
||||||
$: schema = linkedTable?.schema
|
|
||||||
$: table = $tables.list.find(table => table._id === tableId)
|
|
||||||
$: fetchData(tableId, rowId)
|
|
||||||
$: {
|
|
||||||
let rowLabel = row?.[table?.primaryDisplay]
|
|
||||||
if (rowLabel) {
|
|
||||||
title = `${rowLabel} - ${fieldName}`
|
|
||||||
} else {
|
|
||||||
title = fieldName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function fetchData(tableId, rowId) {
|
|
||||||
try {
|
|
||||||
row = await API.fetchRelationshipData({
|
|
||||||
tableId,
|
|
||||||
rowId,
|
|
||||||
})
|
|
||||||
} catch (error) {
|
|
||||||
row = null
|
|
||||||
notifications.error("Error fetching relationship data")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{#if row && row._id === rowId}
|
|
||||||
<Table {title} {schema} {data} />
|
|
||||||
{/if}
|
|
|
@ -1,39 +0,0 @@
|
||||||
<script>
|
|
||||||
import { viewsV2 } from "stores/builder"
|
|
||||||
import { admin, licensing } from "stores/portal"
|
|
||||||
import { Grid } from "@budibase/frontend-core"
|
|
||||||
import { API } from "api"
|
|
||||||
import GridCreateEditRowModal from "components/backend/DataTable/modals/grid/GridCreateEditRowModal.svelte"
|
|
||||||
import GridFilterButton from "components/backend/DataTable/buttons/grid/GridFilterButton.svelte"
|
|
||||||
import GridManageAccessButton from "components/backend/DataTable/buttons/grid/GridManageAccessButton.svelte"
|
|
||||||
|
|
||||||
$: id = $viewsV2.selected?.id
|
|
||||||
$: datasource = {
|
|
||||||
type: "viewV2",
|
|
||||||
id,
|
|
||||||
tableId: $viewsV2.selected?.tableId,
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleGridViewUpdate = async e => {
|
|
||||||
viewsV2.replaceView(id, e.detail)
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<Grid
|
|
||||||
{API}
|
|
||||||
{datasource}
|
|
||||||
allowAddRows
|
|
||||||
allowDeleteRows
|
|
||||||
showAvatars={false}
|
|
||||||
on:updatedatasource={handleGridViewUpdate}
|
|
||||||
isCloud={$admin.cloud}
|
|
||||||
allowViewReadonlyColumns={$licensing.isViewReadonlyColumnsEnabled}
|
|
||||||
>
|
|
||||||
<svelte:fragment slot="filter">
|
|
||||||
<GridFilterButton />
|
|
||||||
</svelte:fragment>
|
|
||||||
<svelte:fragment slot="controls">
|
|
||||||
<GridCreateEditRowModal />
|
|
||||||
<GridManageAccessButton />
|
|
||||||
</svelte:fragment>
|
|
||||||
</Grid>
|
|
|
@ -1,9 +1,9 @@
|
||||||
<script>
|
<script>
|
||||||
import { getContext } from "svelte"
|
import { getContext } from "svelte"
|
||||||
import { ActionButton, Popover, Icon, notifications } from "@budibase/bbui"
|
import { ActionButton, Popover, Icon, notifications } from "@budibase/bbui"
|
||||||
import { getColumnIcon } from "../lib/utils"
|
import ToggleActionButtonGroup from "components/common/ToggleActionButtonGroup.svelte"
|
||||||
import ToggleActionButtonGroup from "./ToggleActionButtonGroup.svelte"
|
|
||||||
import { helpers } from "@budibase/shared-core"
|
import { helpers } from "@budibase/shared-core"
|
||||||
|
import { SchemaUtils } from "@budibase/frontend-core"
|
||||||
|
|
||||||
export let allowViewReadonlyColumns = false
|
export let allowViewReadonlyColumns = false
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@
|
||||||
<div class="columns">
|
<div class="columns">
|
||||||
{#each displayColumns as column}
|
{#each displayColumns as column}
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<Icon size="S" name={getColumnIcon(column)} />
|
<Icon size="S" name={SchemaUtils.getColumnIcon(column)} />
|
||||||
<div class="column-label" title={column.label}>
|
<div class="column-label" title={column.label}>
|
||||||
{column.label}
|
{column.label}
|
||||||
</div>
|
</div>
|
|
@ -1,34 +1,34 @@
|
||||||
<script>
|
<script>
|
||||||
import { getContext } from "svelte"
|
import { getContext } from "svelte"
|
||||||
import { ActionButton, Popover, Label } from "@budibase/bbui"
|
import { ActionButton, Popover, Label } from "@budibase/bbui"
|
||||||
import {
|
|
||||||
DefaultColumnWidth,
|
|
||||||
LargeRowHeight,
|
|
||||||
MediumRowHeight,
|
|
||||||
SmallRowHeight,
|
|
||||||
} from "../lib/constants"
|
|
||||||
|
|
||||||
const { columns, rowHeight, definition, fixedRowHeight, datasource } =
|
const {
|
||||||
getContext("grid")
|
Constants,
|
||||||
|
columns,
|
||||||
|
rowHeight,
|
||||||
|
definition,
|
||||||
|
fixedRowHeight,
|
||||||
|
datasource,
|
||||||
|
} = getContext("grid")
|
||||||
|
|
||||||
// Some constants for column width options
|
// Some constants for column width options
|
||||||
const smallColSize = 120
|
const smallColSize = 120
|
||||||
const mediumColSize = DefaultColumnWidth
|
const mediumColSize = Constants.DefaultColumnWidth
|
||||||
const largeColSize = DefaultColumnWidth * 1.5
|
const largeColSize = Constants.DefaultColumnWidth * 1.5
|
||||||
|
|
||||||
// Row height sizes
|
// Row height sizes
|
||||||
const rowSizeOptions = [
|
const rowSizeOptions = [
|
||||||
{
|
{
|
||||||
label: "Small",
|
label: "Small",
|
||||||
size: SmallRowHeight,
|
size: Constants.SmallRowHeight,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Medium",
|
label: "Medium",
|
||||||
size: MediumRowHeight,
|
size: Constants.MediumRowHeight,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Large",
|
label: "Large",
|
||||||
size: LargeRowHeight,
|
size: Constants.LargeRowHeight,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -66,7 +66,6 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
#
|
|
||||||
<div bind:this={anchor}>
|
<div bind:this={anchor}>
|
||||||
<ActionButton
|
<ActionButton
|
||||||
icon="MoveUpDown"
|
icon="MoveUpDown"
|
|
@ -9,7 +9,7 @@
|
||||||
export let options
|
export let options
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="permissionPicker">
|
<div>
|
||||||
{#each options as option}
|
{#each options as option}
|
||||||
<AbsTooltip text={option.tooltip} type={TooltipType.Info}>
|
<AbsTooltip text={option.tooltip} type={TooltipType.Info}>
|
||||||
<ActionButton
|
<ActionButton
|
||||||
|
@ -26,15 +26,14 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.permissionPicker {
|
div {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: var(--spacing-xs);
|
gap: var(--spacing-xs);
|
||||||
}
|
}
|
||||||
|
div :global(.spectrum-Icon) {
|
||||||
.permissionPicker :global(.spectrum-Icon) {
|
|
||||||
width: 14px;
|
width: 14px;
|
||||||
}
|
}
|
||||||
.permissionPicker :global(.spectrum-ActionButton) {
|
div :global(.spectrum-ActionButton) {
|
||||||
width: 28px;
|
width: 28px;
|
||||||
height: 28px;
|
height: 28px;
|
||||||
}
|
}
|
|
@ -1,5 +1,45 @@
|
||||||
<script>
|
<script>
|
||||||
import ViewV2DataTable from "components/backend/DataTable/ViewV2DataTable.svelte"
|
import { viewsV2 } from "stores/builder"
|
||||||
|
import { admin, licensing } from "stores/portal"
|
||||||
|
import { Grid } from "@budibase/frontend-core"
|
||||||
|
import { API } from "api"
|
||||||
|
import GridCreateEditRowModal from "components/backend/DataTable/modals/grid/GridCreateEditRowModal.svelte"
|
||||||
|
import GridFilterButton from "components/backend/DataTable/buttons/grid/GridFilterButton.svelte"
|
||||||
|
import GridManageAccessButton from "components/backend/DataTable/buttons/grid/GridManageAccessButton.svelte"
|
||||||
|
import GridSortButton from "components/backend/DataTable/buttons/grid/GridSortButton.svelte"
|
||||||
|
import GridColumnsSettingButton from "components/backend/DataTable/buttons/grid/GridColumnsSettingButton.svelte"
|
||||||
|
import GridSizeButton from "components/backend/DataTable/buttons/grid/GridSizeButton.svelte"
|
||||||
|
import GridCreateAutomationButton from "components/backend/DataTable/buttons/grid/GridCreateAutomationButton.svelte"
|
||||||
|
|
||||||
|
$: id = $viewsV2.selected?.id
|
||||||
|
$: datasource = {
|
||||||
|
type: "viewV2",
|
||||||
|
id,
|
||||||
|
tableId: $viewsV2.selected?.tableId,
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleGridViewUpdate = async e => {
|
||||||
|
viewsV2.replaceView(id, e.detail)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ViewV2DataTable />
|
<Grid
|
||||||
|
{API}
|
||||||
|
{datasource}
|
||||||
|
allowAddRows
|
||||||
|
allowDeleteRows
|
||||||
|
showAvatars={false}
|
||||||
|
on:updatedatasource={handleGridViewUpdate}
|
||||||
|
isCloud={$admin.cloud}
|
||||||
|
allowViewReadonlyColumns={$licensing.isViewReadonlyColumnsEnabled}
|
||||||
|
>
|
||||||
|
<svelte:fragment slot="controls">
|
||||||
|
<GridFilterButton />
|
||||||
|
<GridSortButton />
|
||||||
|
<GridColumnsSettingButton />
|
||||||
|
<GridManageAccessButton />
|
||||||
|
<GridSizeButton />
|
||||||
|
<GridCreateAutomationButton />
|
||||||
|
</svelte:fragment>
|
||||||
|
<GridCreateEditRowModal />
|
||||||
|
</Grid>
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
<script>
|
|
||||||
import { params } from "@roxi/routify"
|
|
||||||
import RelationshipDataTable from "components/backend/DataTable/RelationshipDataTable.svelte"
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<RelationshipDataTable
|
|
||||||
tableId={$params.tableId}
|
|
||||||
rowId={$params.rowId}
|
|
||||||
fieldName={decodeURI($params.field)}
|
|
||||||
/>
|
|
|
@ -1,7 +0,0 @@
|
||||||
<script>
|
|
||||||
import { redirect } from "@roxi/routify"
|
|
||||||
|
|
||||||
$redirect("../../")
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- routify:options index=false -->
|
|
|
@ -1,7 +0,0 @@
|
||||||
<script>
|
|
||||||
import { redirect } from "@roxi/routify"
|
|
||||||
|
|
||||||
$redirect("../")
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- routify:options index=false -->
|
|
|
@ -1,24 +0,0 @@
|
||||||
<script>
|
|
||||||
import { viewsV2, builderStore } from "stores/builder"
|
|
||||||
import { syncURLToState } from "helpers/urlStateSync"
|
|
||||||
import * as routify from "@roxi/routify"
|
|
||||||
import { onDestroy } from "svelte"
|
|
||||||
|
|
||||||
$: id = $viewsV2.selectedViewId
|
|
||||||
$: builderStore.selectResource(id)
|
|
||||||
|
|
||||||
const stopSyncing = syncURLToState({
|
|
||||||
urlParam: "viewId",
|
|
||||||
stateKey: "selectedViewId",
|
|
||||||
validate: id => $viewsV2.list?.some(view => view.id === id),
|
|
||||||
update: viewsV2.select,
|
|
||||||
fallbackUrl: "../../",
|
|
||||||
store: viewsV2,
|
|
||||||
routify,
|
|
||||||
decode: decodeURIComponent,
|
|
||||||
})
|
|
||||||
|
|
||||||
onDestroy(stopSyncing)
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<slot />
|
|
|
@ -1,5 +0,0 @@
|
||||||
<script>
|
|
||||||
import ViewV2DataTable from "components/backend/DataTable/ViewV2DataTable.svelte"
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<ViewV2DataTable />
|
|
|
@ -1,5 +0,0 @@
|
||||||
<script>
|
|
||||||
import { redirect } from "@roxi/routify"
|
|
||||||
|
|
||||||
$redirect("../")
|
|
||||||
</script>
|
|
|
@ -3,7 +3,7 @@
|
||||||
import { canBeDisplayColumn, canBeSortColumn } from "@budibase/shared-core"
|
import { canBeDisplayColumn, canBeSortColumn } from "@budibase/shared-core"
|
||||||
import { Icon, Menu, MenuItem, Modal } from "@budibase/bbui"
|
import { Icon, Menu, MenuItem, Modal } from "@budibase/bbui"
|
||||||
import GridCell from "./GridCell.svelte"
|
import GridCell from "./GridCell.svelte"
|
||||||
import { getColumnIcon } from "../lib/utils"
|
import { getColumnIcon } from "../../../utils/schema"
|
||||||
import MigrationModal from "../controls/MigrationModal.svelte"
|
import MigrationModal from "../controls/MigrationModal.svelte"
|
||||||
import { debounce } from "../../../utils/utils"
|
import { debounce } from "../../../utils/utils"
|
||||||
import { FieldType, FormulaType } from "@budibase/types"
|
import { FieldType, FormulaType } from "@budibase/types"
|
||||||
|
|
|
@ -21,15 +21,7 @@
|
||||||
import KeyboardManager from "../overlays/KeyboardManager.svelte"
|
import KeyboardManager from "../overlays/KeyboardManager.svelte"
|
||||||
import NewRow from "./NewRow.svelte"
|
import NewRow from "./NewRow.svelte"
|
||||||
import { createGridWebsocket } from "../lib/websocket"
|
import { createGridWebsocket } from "../lib/websocket"
|
||||||
import {
|
import * as Constants from "../lib/constants"
|
||||||
MaxCellRenderOverflow,
|
|
||||||
GutterWidth,
|
|
||||||
DefaultRowHeight,
|
|
||||||
VPadding,
|
|
||||||
SmallRowHeight,
|
|
||||||
ControlsHeight,
|
|
||||||
ScrollBarSize,
|
|
||||||
} from "../lib/constants"
|
|
||||||
|
|
||||||
export let API = null
|
export let API = null
|
||||||
export let datasource = null
|
export let datasource = null
|
||||||
|
@ -64,6 +56,7 @@
|
||||||
// Build up context
|
// Build up context
|
||||||
let context = {
|
let context = {
|
||||||
API: API || createAPIClient(),
|
API: API || createAPIClient(),
|
||||||
|
Constants,
|
||||||
gridID,
|
gridID,
|
||||||
props,
|
props,
|
||||||
}
|
}
|
||||||
|
@ -112,8 +105,13 @@
|
||||||
|
|
||||||
// Derive min height and make available in context
|
// Derive min height and make available in context
|
||||||
const minHeight = derived(rowHeight, $height => {
|
const minHeight = derived(rowHeight, $height => {
|
||||||
const heightForControls = $$slots.controls ? ControlsHeight : 0
|
const heightForControls = $$slots.controls ? Constants.ControlsHeight : 0
|
||||||
return VPadding + SmallRowHeight + $height + heightForControls
|
return (
|
||||||
|
Constants.VPadding +
|
||||||
|
Constants.SmallRowHeight +
|
||||||
|
$height +
|
||||||
|
heightForControls
|
||||||
|
)
|
||||||
})
|
})
|
||||||
context = { ...context, minHeight }
|
context = { ...context, minHeight }
|
||||||
|
|
||||||
|
@ -141,7 +139,7 @@
|
||||||
class:quiet
|
class:quiet
|
||||||
on:mouseenter={() => gridFocused.set(true)}
|
on:mouseenter={() => gridFocused.set(true)}
|
||||||
on:mouseleave={() => gridFocused.set(false)}
|
on:mouseleave={() => gridFocused.set(false)}
|
||||||
style="--row-height:{$rowHeight}px; --default-row-height:{DefaultRowHeight}px; --gutter-width:{GutterWidth}px; --max-cell-render-overflow:{MaxCellRenderOverflow}px; --content-lines:{$contentLines}; --min-height:{$minHeight}px; --controls-height:{ControlsHeight}px; --scroll-bar-size:{ScrollBarSize}px;"
|
style="--row-height:{$rowHeight}px; --default-row-height:{Constants.DefaultRowHeight}px; --gutter-width:{Constants.GutterWidth}px; --max-cell-render-overflow:{Constants.MaxCellRenderOverflow}px; --content-lines:{$contentLines}; --min-height:{$minHeight}px; --controls-height:{Constants.ControlsHeight}px; --scroll-bar-size:{Constants.ScrollBarSize}px;"
|
||||||
>
|
>
|
||||||
{#if $$slots.controls}
|
{#if $$slots.controls}
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
import { helpers } from "@budibase/shared-core"
|
|
||||||
import { TypeIconMap } from "../../../constants"
|
|
||||||
|
|
||||||
// We can't use "-" as a separator as this can be present in the ID
|
// We can't use "-" as a separator as this can be present in the ID
|
||||||
// or column name, so we use something very unusual to avoid this problem
|
// or column name, so we use something very unusual to avoid this problem
|
||||||
const JOINING_CHARACTER = "‽‽"
|
const JOINING_CHARACTER = "‽‽"
|
||||||
|
@ -18,24 +15,6 @@ export const getCellID = (rowId, fieldName) => {
|
||||||
return `${rowId}${JOINING_CHARACTER}${fieldName}`
|
return `${rowId}${JOINING_CHARACTER}${fieldName}`
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getColumnIcon = column => {
|
|
||||||
if (column.schema.autocolumn) {
|
|
||||||
return "MagicWand"
|
|
||||||
}
|
|
||||||
|
|
||||||
if (helpers.schema.isDeprecatedSingleUserColumn(column.schema)) {
|
|
||||||
return "User"
|
|
||||||
}
|
|
||||||
|
|
||||||
const { type, subtype } = column.schema
|
|
||||||
const result =
|
|
||||||
typeof TypeIconMap[type] === "object" && subtype
|
|
||||||
? TypeIconMap[type][subtype]
|
|
||||||
: TypeIconMap[type]
|
|
||||||
|
|
||||||
return result || "Text"
|
|
||||||
}
|
|
||||||
|
|
||||||
export const parseEventLocation = e => {
|
export const parseEventLocation = e => {
|
||||||
return {
|
return {
|
||||||
x: e.clientX ?? e.touches?.[0]?.clientX,
|
x: e.clientX ?? e.touches?.[0]?.clientX,
|
||||||
|
|
|
@ -5,6 +5,7 @@ export * as RoleUtils from "./roles"
|
||||||
export * as Utils from "./utils"
|
export * as Utils from "./utils"
|
||||||
export * as RowUtils from "./rows"
|
export * as RowUtils from "./rows"
|
||||||
export * as search from "./searchFields"
|
export * as search from "./searchFields"
|
||||||
|
export * as SchemaUtils from "./schema"
|
||||||
export { memo, derivedMemo } from "./memo"
|
export { memo, derivedMemo } from "./memo"
|
||||||
export { createWebsocket } from "./websocket"
|
export { createWebsocket } from "./websocket"
|
||||||
export * from "./download"
|
export * from "./download"
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
import { helpers } from "@budibase/shared-core"
|
||||||
|
import { TypeIconMap } from "../constants"
|
||||||
|
|
||||||
|
export const getColumnIcon = column => {
|
||||||
|
if (column.schema.autocolumn) {
|
||||||
|
return "MagicWand"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (helpers.schema.isDeprecatedSingleUserColumn(column.schema)) {
|
||||||
|
return "User"
|
||||||
|
}
|
||||||
|
|
||||||
|
const { type, subtype } = column.schema
|
||||||
|
const result =
|
||||||
|
typeof TypeIconMap[type] === "object" && subtype
|
||||||
|
? TypeIconMap[type][subtype]
|
||||||
|
: TypeIconMap[type]
|
||||||
|
|
||||||
|
return result || "Text"
|
||||||
|
}
|
Loading…
Reference in New Issue