Skip to content

Commit

Permalink
Merge pull request #11573 from Budibase/views-v2-frontend
Browse files Browse the repository at this point in the history
Views V2
  • Loading branch information
aptkingston authored Aug 31, 2023
2 parents 98ab51d + d089da5 commit 9ef3313
Show file tree
Hide file tree
Showing 123 changed files with 2,460 additions and 1,258 deletions.
4 changes: 4 additions & 0 deletions packages/bbui/src/Modal/Modal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
export let fixed = false
export let inline = false
export let disableCancel = false
export let autoFocus = true
const dispatch = createEventDispatcher()
let visible = fixed || inline
Expand Down Expand Up @@ -53,6 +54,9 @@
}
async function focusModal(node) {
if (!autoFocus) {
return
}
await tick()
// Try to focus first input
Expand Down
2 changes: 0 additions & 2 deletions packages/bbui/src/Tabs/Tabs.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,8 @@
function calculateIndicatorLength() {
if (!vertical) {
width = $tab.info?.width + "px"
height = $tab.info?.height
} else {
height = $tab.info?.height + 4 + "px"
width = $tab.info?.width
}
}
Expand Down
53 changes: 40 additions & 13 deletions packages/builder/src/builderStore/dataBinding.js
Original file line number Diff line number Diff line change
Expand Up @@ -351,12 +351,19 @@ const getProviderContextBindings = (asset, dataProviders) => {
schema = info.schema
table = info.table

// For JSON arrays, use the array name as the readable prefix.
// Otherwise use the table name
// Determine what to prefix bindings with
if (datasource.type === "jsonarray") {
// For JSON arrays, use the array name as the readable prefix
const split = datasource.label.split(".")
readablePrefix = split[split.length - 1]
} else if (datasource.type === "viewV2") {
// For views, use the view name
const view = Object.values(table?.views || {}).find(
view => view.id === datasource.id
)
readablePrefix = view?.name
} else {
// Otherwise use the table name
readablePrefix = info.table?.name
}
}
Expand Down Expand Up @@ -464,7 +471,7 @@ const getComponentBindingCategory = (component, context, def) => {
*/
export const getUserBindings = () => {
let bindings = []
const { schema } = getSchemaForTable(TableNames.USERS)
const { schema } = getSchemaForDatasourcePlus(TableNames.USERS)
const keys = Object.keys(schema).sort()
const safeUser = makePropSafe("user")

Expand Down Expand Up @@ -714,17 +721,25 @@ export const getActionBindings = (actions, actionId) => {
}

/**
* Gets the schema for a certain table ID.
* Gets the schema for a certain datasource plus.
* The options which can be passed in are:
* formSchema: whether the schema is for a form
* searchableSchema: whether to generate a searchable schema, which may have
* fewer fields than a readable schema
* @param tableId the table ID to get the schema for
* @param resourceId the DS+ resource ID
* @param options options for generating the schema
* @return {{schema: Object, table: Object}}
*/
export const getSchemaForTable = (tableId, options) => {
return getSchemaForDatasource(null, { type: "table", tableId }, options)
export const getSchemaForDatasourcePlus = (resourceId, options) => {
const isViewV2 = resourceId?.includes("view_")
const datasource = isViewV2
? {
type: "viewV2",
id: resourceId,
tableId: resourceId.split("_").slice(1, 3).join("_"),
}
: { type: "table", tableId: resourceId }
return getSchemaForDatasource(null, datasource, options)
}

/**
Expand Down Expand Up @@ -801,9 +816,21 @@ export const getSchemaForDatasource = (asset, datasource, options) => {
// Determine the schema from the backing entity if not already determined
if (table && !schema) {
if (type === "view") {
// For views, the schema is pulled from the `views` property of the
// table
// Old views
schema = cloneDeep(table.views?.[datasource.name]?.schema)
} else if (type === "viewV2") {
// New views which are DS+
const view = Object.values(table.views || {}).find(
view => view.id === datasource.id
)
schema = cloneDeep(view?.schema)

// Strip hidden fields
Object.keys(schema || {}).forEach(field => {
if (!schema[field].visible) {
delete schema[field]
}
})
} else if (
type === "query" &&
(options.formSchema || options.searchableSchema)
Expand Down Expand Up @@ -849,12 +876,12 @@ export const getSchemaForDatasource = (asset, datasource, options) => {

// Determine if we should add ID and rev to the schema
const isInternal = table && !table.sql
const isTable = ["table", "link"].includes(datasource.type)
const isDSPlus = ["table", "link", "viewV2"].includes(datasource.type)

// ID is part of the readable schema for all tables
// Rev is part of the readable schema for internal tables only
let addId = isTable
let addRev = isTable && isInternal
let addId = isDSPlus
let addRev = isDSPlus && isInternal

// Don't add ID or rev for form schemas
if (options.formSchema) {
Expand All @@ -864,7 +891,7 @@ export const getSchemaForDatasource = (asset, datasource, options) => {

// ID is only searchable for internal tables
else if (options.searchableSchema) {
addId = isTable && isInternal
addId = isDSPlus && isInternal
}

// Add schema properties if required
Expand Down
11 changes: 5 additions & 6 deletions packages/builder/src/builderStore/store/screenTemplates/index.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
import rowListScreen from "./rowListScreen"
import createFromScratchScreen from "./createFromScratchScreen"

const allTemplates = tables => [...rowListScreen(tables)]
const allTemplates = datasources => [...rowListScreen(datasources)]

// Allows us to apply common behaviour to all create() functions
const createTemplateOverride = (frontendState, template) => () => {
const createTemplateOverride = template => () => {
const screen = template.create()
screen.name = screen.props._id
screen.routing.route = screen.routing.route.toLowerCase()
screen.template = template.id
return screen
}

export default (frontendState, tables) => {
export default datasources => {
const enrichTemplate = template => ({
...template,
create: createTemplateOverride(frontendState, template),
create: createTemplateOverride(template),
})

const fromScratch = enrichTemplate(createFromScratchScreen)
const tableTemplates = allTemplates(tables).map(enrichTemplate)
const tableTemplates = allTemplates(datasources).map(enrichTemplate)
return [
fromScratch,
...tableTemplates.sort((templateA, templateB) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,26 @@ import sanitizeUrl from "./utils/sanitizeUrl"
import { Screen } from "./utils/Screen"
import { Component } from "./utils/Component"

export default function (tables) {
return tables.map(table => {
export default function (datasources) {
return datasources.map(datasource => {
return {
name: `${table.name} - List`,
create: () => createScreen(table),
name: `${datasource.name} - List`,
create: () => createScreen(datasource),
id: ROW_LIST_TEMPLATE,
table: table._id,
resourceId: datasource.resourceId,
}
})
}

export const ROW_LIST_TEMPLATE = "ROW_LIST_TEMPLATE"
export const rowListUrl = table => sanitizeUrl(`/${table.name}`)
export const rowListUrl = datasource => sanitizeUrl(`/${datasource.name}`)

const generateTableBlock = table => {
const generateTableBlock = datasource => {
const tableBlock = new Component("@budibase/standard-components/tableblock")
tableBlock
.customProps({
title: table.name,
dataSource: {
label: table.name,
name: table._id,
tableId: table._id,
type: "table",
},
title: datasource.name,
dataSource: datasource,
sortOrder: "Ascending",
size: "spectrum--medium",
paginate: true,
Expand All @@ -36,14 +31,14 @@ const generateTableBlock = table => {
titleButtonText: "Create row",
titleButtonClickBehaviour: "new",
})
.instanceName(`${table.name} - Table block`)
.instanceName(`${datasource.name} - Table block`)
return tableBlock
}

const createScreen = table => {
const createScreen = datasource => {
return new Screen()
.route(rowListUrl(table))
.instanceName(`${table.name} - List`)
.addChild(generateTableBlock(table))
.route(rowListUrl(datasource))
.instanceName(`${datasource.name} - List`)
.addChild(generateTableBlock(datasource))
.json()
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
import FilterDrawer from "components/design/settings/controls/FilterEditor/FilterDrawer.svelte"
import { LuceneUtils } from "@budibase/frontend-core"
import {
getSchemaForTable,
getSchemaForDatasourcePlus,
getEnvironmentBindings,
} from "builderStore/dataBinding"
import { Utils } from "@budibase/frontend-core"
Expand Down Expand Up @@ -67,7 +67,9 @@
$: table = tableId
? $tables.list.find(table => table._id === inputData.tableId)
: { schema: {} }
$: schema = getSchemaForTable(tableId, { searchableSchema: true }).schema
$: schema = getSchemaForDatasourcePlus(tableId, {
searchableSchema: true,
}).schema
$: schemaFields = Object.values(schema || {})
$: queryLimit = tableId?.includes("datasource") ? "" : "1000"
$: isTrigger = block?.type === "TRIGGER"
Expand Down Expand Up @@ -158,7 +160,7 @@
// instead fetch the schema in the backend at runtime.
let schema
if (e.detail?.tableId) {
schema = getSchemaForTable(e.detail.tableId, {
schema = getSchemaForDatasourcePlus(e.detail.tableId, {
searchableSchema: true,
}).schema
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@
$: id = $tables.selected?._id
$: isUsersTable = id === TableNames.USERS
$: isInternal = $tables.selected?.type !== "external"
$: datasource = $datasources.list.find(datasource => {
$: gridDatasource = {
type: "table",
tableId: id,
}
$: tableDatasource = $datasources.list.find(datasource => {
return datasource._id === $tables.selected?.sourceId
})
$: relationshipsEnabled = relationshipSupport(datasource)
$: relationshipsEnabled = relationshipSupport(tableDatasource)
const relationshipSupport = datasource => {
const integration = $integrations[datasource?.source]
Expand All @@ -54,12 +56,12 @@
<div class="wrapper">
<Grid
{API}
tableId={id}
allowAddRows={!isUsersTable}
allowDeleteRows={!isUsersTable}
datasource={gridDatasource}
canAddRows={!isUsersTable}
canDeleteRows={!isUsersTable}
schemaOverrides={isUsersTable ? userSchemaOverrides : null}
showAvatars={false}
on:updatetable={handleGridTableUpdate}
on:updatedatasource={handleGridTableUpdate}
>
<svelte:fragment slot="filter">
<GridFilterButton />
Expand All @@ -72,9 +74,7 @@
</svelte:fragment>
<svelte:fragment slot="controls">
{#if isInternal}
<GridCreateViewButton />
{/if}
<GridCreateViewButton />
<GridManageAccessButton />
{#if relationshipsEnabled}
<GridRelationshipButton />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<script>
import { viewsV2 } from "stores/backend"
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>
<div class="wrapper">
<Grid
{API}
{datasource}
allowAddRows
allowDeleteRows
showAvatars={false}
on:updatedatasource={handleGridViewUpdate}
>
<svelte:fragment slot="filter">
<GridFilterButton />
</svelte:fragment>
<svelte:fragment slot="controls">
<GridCreateEditRowModal />
<GridManageAccessButton />
</svelte:fragment>
</Grid>
</div>
<style>
.wrapper {
flex: 1 1 auto;
margin: -28px -40px -40px -40px;
display: flex;
flex-direction: column;
background: var(--background);
overflow: hidden;
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
export let resourceId
export let disabled = false
export let requiresLicence
let modal
let resourcePermissions
Expand All @@ -21,6 +22,7 @@
<Modal bind:this={modal}>
<ManageAccessModal
{resourceId}
{requiresLicence}
levels={$permissions}
permissions={resourcePermissions}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,15 @@
$: tempValue = filters || []
$: schemaFields = Object.values(schema || {})
$: text = getText(filters)
$: selected = tempValue.filter(x => !x.onEmptyFilter)?.length > 0
const getText = filters => {
const count = filters?.filter(filter => filter.field)?.length
return count ? `Filter (${count})` : "Filter"
}
</script>
<ActionButton
icon="Filter"
quiet
{disabled}
on:click={modal.show}
selected={tempValue?.length > 0}
>
<ActionButton icon="Filter" quiet {disabled} on:click={modal.show} {selected}>
{text}
</ActionButton>
<Modal bind:this={modal}>
Expand Down
Loading

0 comments on commit 9ef3313

Please sign in to comment.