Add complete generation popover with both automation and screen generation

This commit is contained in:
Andrew Kingston 2024-08-23 12:00:19 +01:00
parent 495c01c1a2
commit bf998f6e6c
No known key found for this signature in database
7 changed files with 135 additions and 66 deletions

View File

@ -6,11 +6,18 @@
export let title = null
export let subtitle = null
export let url = null
export let hoverable = false
export let showArrow = false
</script>
<!-- svelte-ignore a11y-no-static-element-interactions -->
<!-- svelte-ignore a11y-click-events-have-key-events -->
<a href={url} class="list-item" class:hoverable={url != null} on:click>
<a
href={url}
class="list-item"
class:hoverable={hoverable || url != null}
on:click
>
<div class="left">
{#if icon}
<Icon name={icon} color={iconColor} />
@ -30,7 +37,9 @@
</div>
<div class="right">
<slot name="right" />
{#if showArrow}
<Icon name="ChevronRight" />
{/if}
</div>
</a>

View File

@ -34,7 +34,7 @@
const generateAutomation = () => {
popover?.hide()
dispatch("generate-automation")
dispatch("request-generate")
}
</script>
@ -62,6 +62,7 @@
: "var(--spectrum-global-color-green-600)"}
title={automation.name}
url={`/builder/app/${$appStore.appId}/automation/${automation._id}`}
showArrow
/>
{/each}
</List>

View File

@ -1,5 +1,5 @@
<script>
import { ActionButton, Menu, MenuItem, notifications } from "@budibase/bbui"
import { ActionButton, ListItem, notifications } from "@budibase/bbui"
import { getContext } from "svelte"
import {
automationStore,
@ -13,12 +13,12 @@
import MagicWand from "./magic-wand.svg"
import { AutoScreenTypes } from "constants"
import CreateScreenModal from "pages/builder/app/[application]/design/_components/NewScreen/CreateScreenModal.svelte"
import { getSequentialName } from "helpers/duplicate"
const { datasource } = getContext("grid")
let popover
let createScreenModal
let isCreatingScreen
$: triggers = $automationStore.blockDefinitions.CREATABLE_TRIGGER
$: table = $tables.list.find(table => table._id === $datasource.tableId)
@ -39,9 +39,19 @@
return
}
const automationName = `${table.name} : Row ${
type === TriggerStepID.ROW_SAVED ? "created" : "updated"
}`
const suffixMap = {
[TriggerStepID.ROW_SAVED]: "created",
[TriggerStepID.ROW_UPDATED]: "updated",
[TriggerStepID.ROW_DELETED]: "deleted",
}
const namePrefix = `Row ${suffixMap[type]} `
const automationName = getSequentialName(
$automationStore.automations,
namePrefix,
{
getName: x => x.name,
}
)
const triggerBlock = automationStore.actions.constructBlock(
"TRIGGER",
triggerType.stepId,
@ -59,10 +69,10 @@
"/builder/app/:application/data",
window.location.pathname
)
$goto(`/builder/app/${response.appId}/automation/${response.id}`)
notifications.success(`Automation created`)
$goto(`/builder/app/${response.appId}/automation/${response._id}`)
notifications.success(`Automation created successfully`)
} catch (e) {
console.error("Error creating automation", e)
console.error(e)
notifications.error("Error creating automation")
}
}
@ -79,7 +89,7 @@
}
</script>
<DetailPopover title="Generate" bind:this={popover}>
<DetailPopover title="Generate" bind:this={popover} minWidth={400}>
<svelte:fragment slot="anchor" let:open>
<ActionButton selected={open}>
<div class="center">
@ -88,60 +98,94 @@
</div>
</ActionButton>
</svelte:fragment>
<div class="menu">
<Menu>
<MenuItem
icon="ShareAndroid"
on:click={() => {
open = false
createAutomation(TriggerStepID.ROW_SAVED)
}}
>
Automation: when row is created
</MenuItem>
<MenuItem
icon="ShareAndroid"
on:click={() => {
open = false
createAutomation(TriggerStepID.ROW_UPDATED)
}}
>
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>
{#if $datasource.type === "table"}
Generate a new app screen or automation from this data.
{:else}
Generate a new app screen from this data.
{/if}
<div class="generate-section">
<div class="generate-section__title">App screens</div>
<div class="generate-section__options">
<div>
<ListItem
title="CRUD app"
icon="TableEdit"
hoverable
on:click={() => startScreenWizard(AutoScreenTypes.TABLE)}
iconColor="var(--spectrum-global-color-gray-600)"
/>
</div>
<div>
<ListItem
title="Form"
icon="Form"
hoverable
on:click={() => startScreenWizard(AutoScreenTypes.FORM)}
iconColor="var(--spectrum-global-color-gray-600)"
/>
</div>
</div>
</div>
{#if $datasource.type === "table"}
<div class="generate-section">
<div class="generate-section__title">Automation triggers (When a...)</div>
<div class="generate-section__options">
<div>
<ListItem
title="Row is created"
icon="TableRowAddBottom"
hoverable
on:click={() => createAutomation(TriggerStepID.ROW_SAVED)}
iconColor="var(--spectrum-global-color-gray-600)"
/>
</div>
<div>
<ListItem
title="Row is updated"
icon="Refresh"
hoverable
on:click={() => createAutomation(TriggerStepID.ROW_UPDATED)}
iconColor="var(--spectrum-global-color-gray-600)"
/>
</div>
<div>
<ListItem
title="Row is deleted"
icon="TableRowRemoveCenter"
hoverable
on:click={() => createAutomation(TriggerStepID.ROW_DELETED)}
iconColor="var(--spectrum-global-color-gray-600)"
/>
</div>
</div>
</div>
{/if}
</DetailPopover>
<CreateScreenModal bind:this={createScreenModal} />
<style>
.menu {
margin: 0 calc(-1 * var(--spacing-xl));
display: flex;
flex-direction: column;
align-items: stretch;
}
.center {
display: flex;
align-items: center;
gap: 8px;
}
.generate-section {
display: flex;
flex-direction: column;
gap: 8px;
}
.generate-section__title {
color: var(--spectrum-global-color-gray-600);
}
.generate-section__options {
display: grid;
grid-template-columns: 1fr 1fr;
grid-column-gap: 16px;
grid-row-gap: 8px;
}
</style>

View File

@ -83,7 +83,7 @@
{:else}
<List>
{#each rowActions as action}
<ListItem title={action.name} url={$rowActionUrl(action)}>
<ListItem title={action.name} url={$rowActionUrl(action)} showArrow>
<svelte:fragment slot="right">
{#if isView}
<span>

View File

@ -1,10 +1,13 @@
<script>
import { ActionButton, List, ListItem } from "@budibase/bbui"
import { ActionButton, List, ListItem, Button } from "@budibase/bbui"
import DetailPopover from "components/common/DetailPopover.svelte"
import { screenStore, appStore } from "stores/builder"
import { getContext } from "svelte"
import { getContext, createEventDispatcher } from "svelte"
const { datasource } = getContext("grid")
const dispatch = createEventDispatcher()
let popover
$: ds = $datasource
$: resourceId = ds?.type === "table" ? ds.tableId : ds?.id
@ -16,9 +19,14 @@
return JSON.stringify(screen).includes(`"${resourceId}"`)
})
}
const generateScreen = () => {
popover?.hide()
dispatch("request-generate")
}
</script>
<DetailPopover title="Screens" minWidth={400}>
<DetailPopover title="Screens" minWidth={400} bind:this={popover}>
<svelte:fragment slot="anchor" let:open>
<ActionButton
icon="WebPage"
@ -38,8 +46,14 @@
<ListItem
title={screen.routing.route}
url={`/builder/app/${$appStore.appId}/design/${screen._id}`}
showArrow
/>
{/each}
</List>
{/if}
<div>
<Button secondary icon="WebPage" on:click={generateScreen}>
Generate app screen
</Button>
</div>
</DetailPopover>

View File

@ -12,7 +12,8 @@
import GridGenerateButton from "components/backend/DataTable/buttons/grid/GridGenerateButton.svelte"
import GridScreensButton from "components/backend/DataTable/buttons/grid/GridScreensButton.svelte"
import GridRowActionsButton from "components/backend/DataTable/buttons/grid/GridRowActionsButton.svelte"
import GridAutomationsButton from "components/backend/DataTable/buttons/grid/GridAutomationsButton.svelte"
let generateButton
$: id = $viewsV2.selected?.id
$: datasource = {
@ -43,10 +44,10 @@
<GridColumnsSettingButton />
<GridManageAccessButton />
<GridRowActionsButton />
<GridScreensButton />
<GridScreensButton on:request-generate={() => generateButton?.show()} />
</svelte:fragment>
<svelte:fragment slot="controls-right">
<GridGenerateButton />
<GridGenerateButton bind:this={generateButton} />
</svelte:fragment>
<GridCreateEditRowModal />
</Grid>

View File

@ -120,9 +120,9 @@
<GridRowActionsButton />
{/if}
<GridAutomationsButton
on:generate-automation={() => generateButton?.show()}
on:request-generate={() => generateButton?.show()}
/>
<GridScreensButton />
<GridScreensButton on:request-generate={() => generateButton?.show()} />
{#if !isUsersTable}
<GridImportButton />
{/if}