Add complete generation popover with both automation and screen generation
This commit is contained in:
parent
495c01c1a2
commit
bf998f6e6c
|
@ -6,11 +6,18 @@
|
||||||
export let title = null
|
export let title = null
|
||||||
export let subtitle = null
|
export let subtitle = null
|
||||||
export let url = null
|
export let url = null
|
||||||
|
export let hoverable = false
|
||||||
|
export let showArrow = false
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<!-- 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">
|
<div class="left">
|
||||||
{#if icon}
|
{#if icon}
|
||||||
<Icon name={icon} color={iconColor} />
|
<Icon name={icon} color={iconColor} />
|
||||||
|
@ -30,7 +37,9 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<slot name="right" />
|
<slot name="right" />
|
||||||
|
{#if showArrow}
|
||||||
<Icon name="ChevronRight" />
|
<Icon name="ChevronRight" />
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
const generateAutomation = () => {
|
const generateAutomation = () => {
|
||||||
popover?.hide()
|
popover?.hide()
|
||||||
dispatch("generate-automation")
|
dispatch("request-generate")
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -62,6 +62,7 @@
|
||||||
: "var(--spectrum-global-color-green-600)"}
|
: "var(--spectrum-global-color-green-600)"}
|
||||||
title={automation.name}
|
title={automation.name}
|
||||||
url={`/builder/app/${$appStore.appId}/automation/${automation._id}`}
|
url={`/builder/app/${$appStore.appId}/automation/${automation._id}`}
|
||||||
|
showArrow
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
</List>
|
</List>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { ActionButton, Menu, MenuItem, notifications } from "@budibase/bbui"
|
import { ActionButton, ListItem, notifications } from "@budibase/bbui"
|
||||||
import { getContext } from "svelte"
|
import { getContext } from "svelte"
|
||||||
import {
|
import {
|
||||||
automationStore,
|
automationStore,
|
||||||
|
@ -13,12 +13,12 @@
|
||||||
import MagicWand from "./magic-wand.svg"
|
import MagicWand from "./magic-wand.svg"
|
||||||
import { AutoScreenTypes } from "constants"
|
import { AutoScreenTypes } from "constants"
|
||||||
import CreateScreenModal from "pages/builder/app/[application]/design/_components/NewScreen/CreateScreenModal.svelte"
|
import CreateScreenModal from "pages/builder/app/[application]/design/_components/NewScreen/CreateScreenModal.svelte"
|
||||||
|
import { getSequentialName } from "helpers/duplicate"
|
||||||
|
|
||||||
const { datasource } = getContext("grid")
|
const { datasource } = getContext("grid")
|
||||||
|
|
||||||
let popover
|
let popover
|
||||||
let createScreenModal
|
let createScreenModal
|
||||||
let isCreatingScreen
|
|
||||||
|
|
||||||
$: triggers = $automationStore.blockDefinitions.CREATABLE_TRIGGER
|
$: triggers = $automationStore.blockDefinitions.CREATABLE_TRIGGER
|
||||||
$: table = $tables.list.find(table => table._id === $datasource.tableId)
|
$: table = $tables.list.find(table => table._id === $datasource.tableId)
|
||||||
|
@ -39,9 +39,19 @@
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const automationName = `${table.name} : Row ${
|
const suffixMap = {
|
||||||
type === TriggerStepID.ROW_SAVED ? "created" : "updated"
|
[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(
|
const triggerBlock = automationStore.actions.constructBlock(
|
||||||
"TRIGGER",
|
"TRIGGER",
|
||||||
triggerType.stepId,
|
triggerType.stepId,
|
||||||
|
@ -59,10 +69,10 @@
|
||||||
"/builder/app/:application/data",
|
"/builder/app/:application/data",
|
||||||
window.location.pathname
|
window.location.pathname
|
||||||
)
|
)
|
||||||
$goto(`/builder/app/${response.appId}/automation/${response.id}`)
|
$goto(`/builder/app/${response.appId}/automation/${response._id}`)
|
||||||
notifications.success(`Automation created`)
|
notifications.success(`Automation created successfully`)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Error creating automation", e)
|
console.error(e)
|
||||||
notifications.error("Error creating automation")
|
notifications.error("Error creating automation")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +89,7 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<DetailPopover title="Generate" bind:this={popover}>
|
<DetailPopover title="Generate" bind:this={popover} minWidth={400}>
|
||||||
<svelte:fragment slot="anchor" let:open>
|
<svelte:fragment slot="anchor" let:open>
|
||||||
<ActionButton selected={open}>
|
<ActionButton selected={open}>
|
||||||
<div class="center">
|
<div class="center">
|
||||||
|
@ -88,60 +98,94 @@
|
||||||
</div>
|
</div>
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
<div class="menu">
|
|
||||||
<Menu>
|
{#if $datasource.type === "table"}
|
||||||
<MenuItem
|
Generate a new app screen or automation from this data.
|
||||||
icon="ShareAndroid"
|
{:else}
|
||||||
on:click={() => {
|
Generate a new app screen from this data.
|
||||||
open = false
|
{/if}
|
||||||
createAutomation(TriggerStepID.ROW_SAVED)
|
|
||||||
}}
|
<div class="generate-section">
|
||||||
>
|
<div class="generate-section__title">App screens</div>
|
||||||
Automation: when row is created
|
<div class="generate-section__options">
|
||||||
</MenuItem>
|
<div>
|
||||||
<MenuItem
|
<ListItem
|
||||||
icon="ShareAndroid"
|
title="CRUD app"
|
||||||
on:click={() => {
|
icon="TableEdit"
|
||||||
open = false
|
hoverable
|
||||||
createAutomation(TriggerStepID.ROW_UPDATED)
|
on:click={() => startScreenWizard(AutoScreenTypes.TABLE)}
|
||||||
}}
|
iconColor="var(--spectrum-global-color-gray-600)"
|
||||||
>
|
/>
|
||||||
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>
|
</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>
|
</DetailPopover>
|
||||||
|
|
||||||
<CreateScreenModal bind:this={createScreenModal} />
|
<CreateScreenModal bind:this={createScreenModal} />
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.menu {
|
|
||||||
margin: 0 calc(-1 * var(--spacing-xl));
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: stretch;
|
|
||||||
}
|
|
||||||
.center {
|
.center {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
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>
|
</style>
|
||||||
|
|
|
@ -83,7 +83,7 @@
|
||||||
{:else}
|
{:else}
|
||||||
<List>
|
<List>
|
||||||
{#each rowActions as action}
|
{#each rowActions as action}
|
||||||
<ListItem title={action.name} url={$rowActionUrl(action)}>
|
<ListItem title={action.name} url={$rowActionUrl(action)} showArrow>
|
||||||
<svelte:fragment slot="right">
|
<svelte:fragment slot="right">
|
||||||
{#if isView}
|
{#if isView}
|
||||||
<span>
|
<span>
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
<script>
|
<script>
|
||||||
import { ActionButton, List, ListItem } from "@budibase/bbui"
|
import { ActionButton, List, ListItem, Button } from "@budibase/bbui"
|
||||||
import DetailPopover from "components/common/DetailPopover.svelte"
|
import DetailPopover from "components/common/DetailPopover.svelte"
|
||||||
import { screenStore, appStore } from "stores/builder"
|
import { screenStore, appStore } from "stores/builder"
|
||||||
import { getContext } from "svelte"
|
import { getContext, createEventDispatcher } from "svelte"
|
||||||
|
|
||||||
const { datasource } = getContext("grid")
|
const { datasource } = getContext("grid")
|
||||||
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
|
let popover
|
||||||
|
|
||||||
$: ds = $datasource
|
$: ds = $datasource
|
||||||
$: resourceId = ds?.type === "table" ? ds.tableId : ds?.id
|
$: resourceId = ds?.type === "table" ? ds.tableId : ds?.id
|
||||||
|
@ -16,9 +19,14 @@
|
||||||
return JSON.stringify(screen).includes(`"${resourceId}"`)
|
return JSON.stringify(screen).includes(`"${resourceId}"`)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const generateScreen = () => {
|
||||||
|
popover?.hide()
|
||||||
|
dispatch("request-generate")
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<DetailPopover title="Screens" minWidth={400}>
|
<DetailPopover title="Screens" minWidth={400} bind:this={popover}>
|
||||||
<svelte:fragment slot="anchor" let:open>
|
<svelte:fragment slot="anchor" let:open>
|
||||||
<ActionButton
|
<ActionButton
|
||||||
icon="WebPage"
|
icon="WebPage"
|
||||||
|
@ -38,8 +46,14 @@
|
||||||
<ListItem
|
<ListItem
|
||||||
title={screen.routing.route}
|
title={screen.routing.route}
|
||||||
url={`/builder/app/${$appStore.appId}/design/${screen._id}`}
|
url={`/builder/app/${$appStore.appId}/design/${screen._id}`}
|
||||||
|
showArrow
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
</List>
|
</List>
|
||||||
{/if}
|
{/if}
|
||||||
|
<div>
|
||||||
|
<Button secondary icon="WebPage" on:click={generateScreen}>
|
||||||
|
Generate app screen
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</DetailPopover>
|
</DetailPopover>
|
||||||
|
|
|
@ -12,7 +12,8 @@
|
||||||
import GridGenerateButton from "components/backend/DataTable/buttons/grid/GridGenerateButton.svelte"
|
import GridGenerateButton from "components/backend/DataTable/buttons/grid/GridGenerateButton.svelte"
|
||||||
import GridScreensButton from "components/backend/DataTable/buttons/grid/GridScreensButton.svelte"
|
import GridScreensButton from "components/backend/DataTable/buttons/grid/GridScreensButton.svelte"
|
||||||
import GridRowActionsButton from "components/backend/DataTable/buttons/grid/GridRowActionsButton.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
|
$: id = $viewsV2.selected?.id
|
||||||
$: datasource = {
|
$: datasource = {
|
||||||
|
@ -43,10 +44,10 @@
|
||||||
<GridColumnsSettingButton />
|
<GridColumnsSettingButton />
|
||||||
<GridManageAccessButton />
|
<GridManageAccessButton />
|
||||||
<GridRowActionsButton />
|
<GridRowActionsButton />
|
||||||
<GridScreensButton />
|
<GridScreensButton on:request-generate={() => generateButton?.show()} />
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
<svelte:fragment slot="controls-right">
|
<svelte:fragment slot="controls-right">
|
||||||
<GridGenerateButton />
|
<GridGenerateButton bind:this={generateButton} />
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
<GridCreateEditRowModal />
|
<GridCreateEditRowModal />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
|
@ -120,9 +120,9 @@
|
||||||
<GridRowActionsButton />
|
<GridRowActionsButton />
|
||||||
{/if}
|
{/if}
|
||||||
<GridAutomationsButton
|
<GridAutomationsButton
|
||||||
on:generate-automation={() => generateButton?.show()}
|
on:request-generate={() => generateButton?.show()}
|
||||||
/>
|
/>
|
||||||
<GridScreensButton />
|
<GridScreensButton on:request-generate={() => generateButton?.show()} />
|
||||||
{#if !isUsersTable}
|
{#if !isUsersTable}
|
||||||
<GridImportButton />
|
<GridImportButton />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
Loading…
Reference in New Issue