1
0
Fork 0
mirror of synced 2024-06-28 02:50:50 +12:00

Shifting the title of the flow item header into separate component so that it can be used by the run history flow as well.

This commit is contained in:
mike12345567 2022-05-12 18:14:38 +01:00
parent da1d53e6ab
commit a7631bbad9
9 changed files with 314 additions and 1043 deletions

View file

@ -13,6 +13,7 @@
export let size = "M"
export let active = false
export let fullWidth = false
export let noPadding = false
function longPress(element) {
if (!longPressable) return
@ -41,6 +42,7 @@
class:spectrum-ActionButton--quiet={quiet}
class:spectrum-ActionButton--emphasized={emphasized}
class:is-selected={selected}
class:noPadding
class:fullWidth
class="spectrum-ActionButton spectrum-ActionButton--size{size}"
class:active
@ -80,4 +82,8 @@
.active svg {
color: var(--spectrum-global-color-blue-600);
}
.noPadding {
padding: 0;
min-width: 0;
}
</style>

View file

@ -20,6 +20,17 @@ export const getAutomationStore = () => {
}
const automationActions = store => ({
definitions: async () => {
const response = await API.getAutomationDefinitions()
store.update(state => {
state.blockDefinitions = {
TRIGGER: response.trigger,
ACTION: response.action,
}
return state
})
return response
},
fetch: async () => {
const responses = await Promise.all([
API.getAutomations(),

View file

@ -4,27 +4,23 @@
Icon,
Divider,
Layout,
Body,
Detail,
Modal,
Button,
StatusLight,
Select,
ActionButton,
notifications,
} from "@budibase/bbui"
import AutomationBlockSetup from "../../SetupPanel/AutomationBlockSetup.svelte"
import CreateWebhookModal from "components/automation/Shared/CreateWebhookModal.svelte"
import ResultsModal from "./ResultsModal.svelte"
import ActionModal from "./ActionModal.svelte"
import { externalActions } from "./ExternalActions"
import FlowItemHeader from "./FlowItemHeader.svelte"
export let block
export let testDataModal
let selected
let webhookModal
let actionModal
let resultsModal
let blockComplete
let showLooping = false
@ -182,63 +178,12 @@
{/if}
{/if}
<div class="blockSection">
<div
on:click={() => {
blockComplete = !blockComplete
}}
class="splitHeader"
>
<div class="center-items">
{#if externalActions[block.stepId]}
<img
alt={externalActions[block.stepId].name}
width="28px"
height="28px"
src={externalActions[block.stepId].icon}
/>
{:else}
<svg
width="28px"
height="28px"
class="spectrum-Icon"
style="color:grey;"
focusable="false"
>
<use xlink:href="#spectrum-icon-18-{block.icon}" />
</svg>
{/if}
<div class="iconAlign">
{#if isTrigger}
<Body size="XS">When this happens:</Body>
{:else}
<Body size="XS">Do this:</Body>
{/if}
<Detail size="S">{block?.name?.toUpperCase() || ""}</Detail>
</div>
</div>
<div class="blockTitle">
{#if testResult && testResult[0]}
<div style="float: right;" on:click={() => resultsModal.show()}>
<StatusLight
positive={isTrigger || testResult[0].outputs?.success}
negative={!testResult[0].outputs?.success}
><Body size="XS">View response</Body></StatusLight
>
</div>
{/if}
<div
style="margin-left: 10px;"
on:click={() => {
onSelect(block)
}}
>
<Icon name={blockComplete ? "ChevronDown" : "ChevronUp"} />
</div>
</div>
</div>
</div>
<FlowItemHeader
{onSelect}
{block}
bind:results={testResult}
bind:open={blockComplete}
/>
{#if !blockComplete}
<Divider noMargin />
<div class="blockSection">
@ -283,10 +228,6 @@
</div>
{/if}
<Modal bind:this={resultsModal} width="30%">
<ResultsModal {isTrigger} {testResult} />
</Modal>
<Modal bind:this={actionModal} width="30%">
<ActionModal {blockIdx} bind:blockComplete />
</Modal>

View file

@ -0,0 +1,110 @@
<script>
import { Detail, Icon, Body, StatusLight, Modal } from "@budibase/bbui"
import { externalActions } from "./ExternalActions"
import ResultsModal from "./ResultsModal.svelte"
export let onSelect
export let block
export let results
export let useResultsModal = true
export let open
$: isTrigger = block?.type === "TRIGGER"
let resultsModal
</script>
<div class="blockSection">
<div
on:click={() => {
open = !open
}}
class="splitHeader"
>
<div class="center-items">
{#if externalActions[block.stepId]}
<img
alt={externalActions[block.stepId].name}
width="28px"
height="28px"
src={externalActions[block.stepId].icon}
/>
{:else}
<svg
width="28px"
height="28px"
class="spectrum-Icon"
style="color:grey;"
focusable="false"
>
<use xlink:href="#spectrum-icon-18-{block.icon}" />
</svg>
{/if}
<div class="iconAlign">
{#if isTrigger}
<Body size="XS">When this happens:</Body>
{:else}
<Body size="XS">Do this:</Body>
{/if}
<Detail size="S">{block?.name?.toUpperCase() || ""}</Detail>
</div>
</div>
<div class="blockTitle">
{#if useResultsModal}
{#if results && results[0]}
<div style="float: right;" on:click={() => resultsModal.show()}>
<StatusLight
positive={isTrigger || results[0].outputs?.success}
negative={!results[0].outputs?.success}
><Body size="XS">View response</Body></StatusLight
>
</div>
{/if}
{:else}
<slot />
{/if}
<div
style="margin-left: 10px;"
on:click={() => {
onSelect(block)
}}
>
<Icon name={open ? "ChevronDown" : "ChevronUp"} />
</div>
</div>
</div>
</div>
{#if useResultsModal}
<Modal bind:this={resultsModal} width="30%">
<ResultsModal {isTrigger} bind:testResult={results} />
</Modal>
{/if}
<style>
.center-items {
display: flex;
align-items: center;
}
.splitHeader {
display: flex;
justify-content: space-between;
align-items: center;
}
.iconAlign {
padding: 0 0 0 var(--spacing-m);
display: inline-block;
}
.blockSection {
padding: var(--spacing-xl);
}
.blockTitle {
display: flex;
align-items: center;
}
</style>

View file

@ -1,19 +1,51 @@
<script>
import { Body, Layout, Icon, ActionButton } from "@budibase/bbui"
import { Body, Layout, Icon, ActionButton, Heading } from "@budibase/bbui"
import { capitalise } from "helpers"
import StatusRenderer from "components/portal/history/StatusRenderer.svelte"
import DateTimeRenderer from "components/common/renderers/DateTimeRenderer.svelte"
import FlowItemHeader from "components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte"
export let history
export let close
$: console.log(history)
</script>
<div class="body">
<Layout>
{#if history}
<div class="body">
<div class="top">
<Icon name="Clock" />
<Body>Run log details</Body>
<ActionButton size="S" icon="Close" quiet on:click={close} />
<div class="controls">
<Icon name="Clock" />
<Body>Run log details</Body>
<ActionButton noPadding size="S" icon="Close" quiet on:click={close} />
</div>
</div>
</Layout>
</div>
<Layout paddingX="XL" gap="S">
<Heading>{capitalise(history.appName || "")}</Heading>
<StatusRenderer value={history.status} />
<div class="icon">
<Icon name="Clock" />
<DateTimeRenderer value={history.timestamp} />
</div>
<div class="icon">
<Icon name="JourneyVoyager" />
<Body>{history.name}</Body>
</div>
<div>
<ActionButton icon="Edit" fullWidth={false}
>Edit automation</ActionButton
>
</div>
</Layout>
<div class="bottom">
{#each history.steps as step}
<FlowItemHeader useResultsModal={false} block={step} />
{/each}
</div>
</div>
{:else}
<Body>No details found</Body>
{/if}
<style>
.body {
@ -24,10 +56,24 @@
}
.top {
padding: var(--spacing-l) 0 var(--spacing-l) 0;
border-bottom: var(--border-light);
}
.bottom {
margin-top: var(--spacing-m);
border-top: var(--border-light);
}
.icon {
display: flex;
gap: var(--spacing-m);
}
.controls {
padding: 0 var(--spacing-l) 0 var(--spacing-l);
display: grid;
grid-template-columns: auto 1fr auto;
gap: var(--spacing-s);
padding: var(--spacing-s) 0 var(--spacing-l) var(--spacing-s);
border-bottom: var(--border-light);
}
</style>

View file

@ -0,0 +1,25 @@
<script>
import { Icon, Body } from "@budibase/bbui"
export let value
$: isError = value === "Error"
</script>
<div class="cell">
<Icon
color={isError
? "var(--spectrum-semantic-negative-color-background)"
: "var(--green)"}
name={isError ? "Alert" : "CheckmarkCircle"}
/>
<Body>{value}</Body>
</div>
<style>
.cell {
color: var(--spectrum-semantic-negative-color-background);
display: flex;
flex-direction: row;
gap: var(--spacing-m);
}
</style>

View file

@ -9,39 +9,95 @@
Input,
} from "@budibase/bbui"
import DateTimeRenderer from "components/common/renderers/DateTimeRenderer.svelte"
import StatusRenderer from "components/portal/history/StatusRenderer.svelte"
import HistoryDetailsPanel from "components/portal/history/HistoryDetailsPanel.svelte"
import { automationStore } from "builderStore"
import { onMount } from "svelte"
let showPanel = false
let selectedHistory = null
let runHistory = []
const runHistorySchema = {
status: "",
time: "",
app: "",
automation: "",
status: { displayName: "Status" },
timestamp: { displayName: "Time" },
appName: { displayName: "App" },
name: { displayName: "Automation" },
}
const customRenderers = [{ column: "time", component: DateTimeRenderer }]
let runHistory = [
{
status: "Error",
time: "2022-05-11T16:06:14.438Z",
app: "App name",
automation: "automation name",
},
{
status: "Success",
time: "2022-05-11T16:03:14.438Z",
app: "App name",
automation: "automation name",
},
const customRenderers = [
{ column: "time", component: DateTimeRenderer },
{ column: "status", component: StatusRenderer },
]
function enrichHistory(definitions, runHistory) {
const finalHistory = []
for (let history of runHistory) {
if (!history.steps) {
continue
}
let notFound = false
for (let step of history.steps) {
const trigger = definitions.trigger[step.stepId],
action = definitions.action[step.stepId]
if (!trigger && !action) {
notFound = true
break
}
step.icon = trigger ? trigger.icon : action.icon
step.name = trigger ? trigger.name : action.name
}
if (!notFound) {
finalHistory.push(history)
}
}
return finalHistory
}
function viewDetails({ detail }) {
selectedHistory = detail
showPanel = true
}
onMount(async () => {
let definitions = await automationStore.actions.definitions()
runHistory = enrichHistory(definitions, [
{
status: "Error",
timestamp: "2022-05-11T16:06:14.438Z",
appName: "App name",
name: "automation name",
steps: [
{
stepId: "ROW_SAVED",
outputs: {},
},
{
stepId: "SEND_EMAIL_SMTP",
inputs: {},
outputs: {},
},
],
},
{
status: "Success",
timestamp: "2022-05-11T16:03:14.438Z",
appName: "App name",
name: "automation name",
steps: [
{
stepId: "ROW_SAVED",
outputs: {},
},
{
stepId: "SEND_EMAIL_SMTP",
inputs: {},
outputs: {},
},
],
},
])
})
</script>
<div class="root" class:panelOpen={showPanel}>
@ -65,15 +121,17 @@
<Input placeholder="Search" />
</div>
</div>
<Table
on:click={viewDetails}
schema={runHistorySchema}
allowSelectRows={false}
allowEditColumns={false}
allowEditRows={false}
data={runHistory}
{customRenderers}
/>
{#if runHistory}
<Table
on:click={viewDetails}
schema={runHistorySchema}
allowSelectRows={false}
allowEditColumns={false}
allowEditRows={false}
data={runHistory}
{customRenderers}
/>
{/if}
</Layout>
</Page>
<div class="panel" class:panelShow={showPanel}>
@ -94,7 +152,7 @@
}
.panelOpen {
grid-template-columns: 1fr 390px;
grid-template-columns: 1fr 360px;
}
.search {

File diff suppressed because it is too large Load diff

View file

@ -65,6 +65,7 @@ async function getLinksForRows(rows) {
// return duplicates, could be querying for both tables in a relation
return getUniqueByProp(
responses
.filter(el => el != null)
// create a unique ID which we can use for getting only unique ones
.map(el => ({ ...el, unique: el.id + el.thisId + el.fieldName })),
"unique"