1
0
Fork 0
mirror of synced 2024-07-04 14:01:27 +12:00

Merge pull request #12827 from Budibase/feat/configure-automation-chaining

Configure automation chaining
This commit is contained in:
Peter Clement 2024-01-23 14:53:54 +00:00 committed by GitHub
commit f6b229e7eb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 76 additions and 20 deletions

View file

@ -15,9 +15,9 @@
<Content showMobileNav>
<SideNav slot="side-nav">
<SideNavItem
text="Automation History"
url={$url("./automation-history")}
active={$isActive("./automation-history")}
text="Automations"
url={$url("./automations")}
active={$isActive("./automations")}
/>
<SideNavItem
text="Backups"

View file

@ -8,6 +8,8 @@
Body,
Heading,
Divider,
Toggle,
notifications,
} from "@budibase/bbui"
import DateTimeRenderer from "components/common/renderers/DateTimeRenderer.svelte"
import StatusRenderer from "./_components/StatusRenderer.svelte"
@ -16,7 +18,7 @@
import { createPaginationStore } from "helpers/pagination"
import { getContext, onDestroy, onMount } from "svelte"
import dayjs from "dayjs"
import { auth, licensing, admin } from "stores/portal"
import { auth, licensing, admin, apps } from "stores/portal"
import { Constants } from "@budibase/frontend-core"
import Portal from "svelte-portal"
@ -35,9 +37,13 @@
let timeRange = null
let loaded = false
$: app = $apps.find(app => app.devId === $store.appId?.includes(app.appId))
$: licensePlan = $auth.user?.license?.plan
$: page = $pageInfo.page
$: fetchLogs(automationId, status, page, timeRange)
$: isCloud = $admin.cloud
$: chainAutomations = app?.automations?.chainAutomations ?? !isCloud
const timeOptions = [
{ value: "90-d", label: "Past 90 days" },
@ -124,6 +130,18 @@
sidePanel.open()
}
async function save({ detail }) {
try {
await apps.update($store.appId, {
automations: {
chainAutomations: detail,
},
})
} catch (error) {
notifications.error("Error updating automation chaining setting")
}
}
onMount(async () => {
await automationStore.actions.fetch()
const params = new URLSearchParams(window.location.search)
@ -150,11 +168,30 @@
<Layout noPadding>
<Layout gap="XS" noPadding>
<Heading>Automation History</Heading>
<Body>View the automations your app has executed</Body>
<Heading>Automations</Heading>
<Body size="S">See your automation history and edit advanced settings</Body>
</Layout>
<Divider />
<Layout gap="XS" noPadding>
<Heading size="XS">Chain automations</Heading>
<Body size="S">Allow automations to trigger from other automations</Body>
<div class="setting-spacing">
<Toggle
text={"Enable chaining"}
on:change={e => {
save(e)
}}
value={chainAutomations}
/>
</div>
</Layout>
<Divider />
<Layout gap="XS" noPadding>
<Heading size="XS">History</Heading>
<Body size="S">Free plan stores up to 1 day of automation history</Body>
</Layout>
<div class="controls">
<div class="search">
<div class="select">
@ -237,6 +274,9 @@
{/if}
<style>
.setting-spacing {
padding-top: var(--spacing-s);
}
.controls {
display: flex;
flex-direction: row;

View file

@ -1,5 +1,5 @@
<script>
import { redirect } from "@roxi/routify"
$redirect("../settings/automation-history")
$redirect("../settings/automations")
</script>

View file

@ -1,18 +1,11 @@
import { rowEmission, tableEmission } from "./utils"
import mainEmitter from "./index"
import env from "../environment"
import { Table, Row } from "@budibase/types"
import { Table, Row, DocumentType, App } from "@budibase/types"
import { context } from "@budibase/backend-core"
// max number of automations that can chain on top of each other
// TODO: in future make this configurable at the automation level
const MAX_AUTOMATION_CHAIN = env.SELF_HOSTED ? 5 : 0
const MAX_AUTOMATIONS_ALLOWED = 5
/**
* Special emitter which takes the count of automation runs which have occurred and blocks an
* automation from running if it has reached the maximum number of chained automations runs.
* This essentially "fakes" the normal emitter to add some functionality in-between to stop automations
* from getting stuck endlessly chaining.
*/
class AutomationEmitter {
chainCount: number
metadata: { automationChainCount: number }
@ -24,7 +17,23 @@ class AutomationEmitter {
}
}
emitRow(eventName: string, appId: string, row: Row, table?: Table) {
async getMaxAutomationChain() {
const db = context.getAppDB()
const appMetadata = await db.get<App>(DocumentType.APP_METADATA)
let chainAutomations = appMetadata?.automations?.chainAutomations
if (chainAutomations === true) {
return MAX_AUTOMATIONS_ALLOWED
} else if (chainAutomations === undefined && env.SELF_HOSTED) {
return MAX_AUTOMATIONS_ALLOWED
} else {
return 0
}
}
async emitRow(eventName: string, appId: string, row: Row, table?: Table) {
let MAX_AUTOMATION_CHAIN = await this.getMaxAutomationChain()
// don't emit even if we've reached max automation chain
if (this.chainCount >= MAX_AUTOMATION_CHAIN) {
return
@ -39,9 +48,11 @@ class AutomationEmitter {
})
}
emitTable(eventName: string, appId: string, table?: Table) {
async emitTable(eventName: string, appId: string, table?: Table) {
let MAX_AUTOMATION_CHAIN = await this.getMaxAutomationChain()
// don't emit even if we've reached max automation chain
if (this.chainCount > MAX_AUTOMATION_CHAIN) {
if (this.chainCount >= MAX_AUTOMATION_CHAIN) {
return
}

View file

@ -23,6 +23,7 @@ export interface App extends Document {
automationErrors?: AppMetadataErrors
icon?: AppIcon
features?: AppFeatures
automations?: AutomationSettings
}
export interface AppInstance {
@ -68,3 +69,7 @@ export interface AppFeatures {
componentValidation?: boolean
disableUserMetadata?: boolean
}
export interface AutomationSettings {
chainAutomations?: boolean
}