Allow generating screens from the data section

This commit is contained in:
Andrew Kingston 2024-08-23 11:19:56 +01:00
parent a29cd7fefc
commit 495c01c1a2
No known key found for this signature in database
6 changed files with 103 additions and 41 deletions

View File

@ -1,15 +1,24 @@
<script>
import { ActionButton, Menu, MenuItem, notifications } from "@budibase/bbui"
import { getContext } from "svelte"
import { automationStore, tables, builderStore } from "stores/builder"
import {
automationStore,
tables,
builderStore,
viewsV2,
} from "stores/builder"
import { TriggerStepID } from "constants/backend/automations"
import { goto } from "@roxi/routify"
import DetailPopover from "components/common/DetailPopover.svelte"
import MagicWand from "./magic-wand.svg"
import { AutoScreenTypes } from "constants"
import CreateScreenModal from "pages/builder/app/[application]/design/_components/NewScreen/CreateScreenModal.svelte"
const { datasource } = getContext("grid")
let popover
let createScreenModal
let isCreatingScreen
$: triggers = $automationStore.blockDefinitions.CREATABLE_TRIGGER
$: table = $tables.list.find(table => table._id === $datasource.tableId)
@ -57,6 +66,17 @@
notifications.error("Error creating automation")
}
}
const startScreenWizard = autoScreenType => {
popover.hide()
let preSelected
if ($datasource.type === "table") {
preSelected = $tables.list.find(x => x._id === $datasource.tableId)
} else {
preSelected = $viewsV2.list.find(x => x.id === $datasource.id)
}
createScreenModal.show(autoScreenType, preSelected)
}
</script>
<DetailPopover title="Generate" bind:this={popover}>
@ -88,10 +108,30 @@
>
Automation: when row is updated
</MenuItem>
<MenuItem
icon="WebPage"
on:click={() => {
open = false
startScreenWizard(AutoScreenTypes.TABLE)
}}
>
CRUD app
</MenuItem>
<MenuItem
icon="WebPage"
on:click={() => {
open = false
startScreenWizard(AutoScreenTypes.FORM)
}}
>
Form
</MenuItem>
</Menu>
</div>
</DetailPopover>
<CreateScreenModal bind:this={createScreenModal} />
<style>
.menu {
margin: 0 calc(-1 * var(--spacing-xl));

View File

@ -72,3 +72,9 @@ export const PlanModel = {
}
export const ChangelogURL = "https://docs.budibase.com/changelog"
export const AutoScreenTypes = {
BLANK: "blank",
TABLE: "table",
FORM: "form",
}

View File

@ -10,12 +10,16 @@
navigationStore,
permissions as permissionsStore,
builderStore,
datasources,
appStore,
} from "stores/builder"
import { auth } from "stores/portal"
import { goto } from "@roxi/routify"
import { TOUR_KEYS } from "components/portal/onboarding/tours.js"
import * as screenTemplating from "templates/screenTemplating"
import { Roles } from "constants/backend"
import { AutoScreenTypes } from "constants"
import { makeTableOption, makeViewOption } from "./utils"
let mode
@ -23,20 +27,33 @@
let datasourceModal
let formTypeModal
let tableTypeModal
let selectedTablesAndViews = []
let permissions = {}
let hasPreselectedDatasource = false
$: screens = $screenStore.screens
export const show = newMode => {
export const show = (newMode, preselectedDatasource) => {
mode = newMode
selectedTablesAndViews = []
permissions = {}
hasPreselectedDatasource = preselectedDatasource != null
if (mode === "table" || mode === "form") {
if (mode === AutoScreenTypes.TABLE || mode === AutoScreenTypes.FORM) {
if (preselectedDatasource) {
// If preselecting a datasource, skip a step
const isTable = preselectedDatasource.type === "table"
const tableOrView = isTable
? makeTableOption(preselectedDatasource, $datasources.list)
: makeViewOption(preselectedDatasource)
fetchPermission(tableOrView.id)
selectedTablesAndViews.push(tableOrView)
onSelectDatasources()
} else {
// Otherwise choose a datasource
datasourceModal.show()
} else if (mode === "blank") {
}
} else if (mode === AutoScreenTypes.BLANK) {
screenDetailsModal.show()
} else {
throw new Error("Invalid mode provided")
@ -77,9 +94,9 @@
}
const onSelectDatasources = async () => {
if (mode === "form") {
if (mode === AutoScreenTypes.FORM) {
formTypeModal.show()
} else if (mode === "table") {
} else if (mode === AutoScreenTypes.TABLE) {
tableTypeModal.show()
}
}
@ -136,9 +153,11 @@
if (screen?.props?._children.length) {
// Focus on the main component for the screen type
const mainComponent = screen?.props?._children?.[0]._id
$goto(`./${screen._id}/${mainComponent}`)
$goto(
`/builder/app/${$appStore.appId}/design/${screen._id}/${mainComponent}`
)
} else {
$goto(`./${screen._id}`)
$goto(`/builder/app/${$appStore.appId}/design/${screen._id}`)
}
screenStore.select(screen._id)
@ -214,6 +233,7 @@
tableTypeModal.hide()
datasourceModal.show()
}}
showCancelButton={!hasPreselectedDatasource}
/>
</Modal>
@ -230,5 +250,6 @@
formTypeModal.hide()
datasourceModal.show()
}}
showCancelButton={!hasPreselectedDatasource}
/>
</Modal>

View File

@ -1,11 +1,11 @@
<script>
import { Body, ModalContent, Layout, notifications } from "@budibase/bbui"
import { Body, ModalContent, Layout } from "@budibase/bbui"
import { datasources as datasourcesStore } from "stores/builder"
import ICONS from "components/backend/DatasourceNavigator/icons"
import { IntegrationNames } from "constants"
import { createEventDispatcher, onMount } from "svelte"
import { createEventDispatcher } from "svelte"
import TableOrViewOption from "./TableOrViewOption.svelte"
import * as format from "helpers/data/format"
import { makeTableOption, makeViewOption } from "./utils"
export let onConfirm
export let selectedTablesAndViews
@ -16,17 +16,10 @@
const views = Object.values(table.views || {}).filter(
view => view.version === 2
)
return views.map(view => ({
icon: "Remove",
name: view.name,
id: view.id,
tableSelectFormat: format.tableSelect.viewV2(view),
datasourceSelectFormat: format.datasourceSelect.viewV2(view),
}))
return views.map(makeViewOption)
}
const getTablesAndViews = datasource => {
const getTablesAndViews = (datasource, datasources) => {
let tablesAndViews = []
const tables = Array.isArray(datasource.entities)
? datasource.entities
@ -37,16 +30,7 @@
continue
}
const formattedTable = {
icon: "Table",
name: table.name,
id: table._id,
tableSelectFormat: format.tableSelect.table(table),
datasourceSelectFormat: format.datasourceSelect.table(
table,
$datasourcesStore.list
),
}
const formattedTable = makeTableOption(table, datasources)
tablesAndViews = tablesAndViews.concat([
formattedTable,
@ -71,7 +55,7 @@
const datasource = {
name: rawDatasource.name,
iconComponent: ICONS[rawDatasource.source],
tablesAndViews: getTablesAndViews(rawDatasource),
tablesAndViews: getTablesAndViews(rawDatasource, rawDatasources),
}
datasources.push(datasource)
@ -85,14 +69,6 @@
const toggleSelection = tableOrView => {
dispatch("toggle", tableOrView)
}
onMount(async () => {
try {
await datasourcesStore.fetch()
} catch (error) {
notifications.error("Error fetching datasources")
}
})
</script>
<ModalContent

View File

@ -7,6 +7,7 @@
export let types
export let onCancel = () => {}
export let onConfirm = () => {}
export let showCancelButton = true
</script>
<ModalContent
@ -17,6 +18,7 @@
{onCancel}
disabled={!selectedType}
size="L"
{showCancelButton}
>
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions -->

View File

@ -0,0 +1,17 @@
import * as format from "helpers/data/format"
export const makeViewOption = view => ({
icon: "Remove",
name: view.name,
id: view.id,
tableSelectFormat: format.tableSelect.viewV2(view),
datasourceSelectFormat: format.datasourceSelect.viewV2(view),
})
export const makeTableOption = (table, datasources) => ({
icon: "Table",
name: table.name,
id: table._id,
tableSelectFormat: format.tableSelect.table(table),
datasourceSelectFormat: format.datasourceSelect.table(table, datasources),
})