Enabled collaboration behaviour in the automation section

This commit is contained in:
Dean 2023-07-10 09:30:15 +01:00
parent f176d9d9fa
commit db501fb10a
9 changed files with 79 additions and 6 deletions

View File

@ -3,6 +3,7 @@ import { API } from "api"
import { cloneDeep } from "lodash/fp" import { cloneDeep } from "lodash/fp"
import { generate } from "shortid" import { generate } from "shortid"
import { selectedAutomation } from "builderStore" import { selectedAutomation } from "builderStore"
import { automationStore } from "builderStore"
const initialAutomationState = { const initialAutomationState = {
automations: [], automations: [],
@ -248,4 +249,39 @@ const automationActions = store => ({
} }
await store.actions.save(newAutomation) await store.actions.save(newAutomation)
}, },
replace: async (automationId, automation) => {
if (!automationId) {
return
}
if (!automation) {
store.update(state => {
// Remove the automation
state.automations = state.automations.filter(
x => x._id !== automationId
)
// Select a new automation if required
if (automationId === state.selectedAutomationId) {
store.actions.select(state.automations[0]?._id)
}
return state
})
} else {
const index = get(store).automations.findIndex(
x => x._id === automation._id
)
if (index === -1) {
// Automation addition
store.update(state => ({
...state,
automations: [...state.automations, automation],
}))
} else {
// Automation update
store.update(state => {
state.automations[index] = automation
return state
})
}
}
},
}) })

View File

@ -1,5 +1,10 @@
import { createWebsocket } from "@budibase/frontend-core" import { createWebsocket } from "@budibase/frontend-core"
import { userStore, store, deploymentStore } from "builderStore" import {
userStore,
store,
deploymentStore,
automationStore,
} from "builderStore"
import { datasources, tables } from "stores/backend" import { datasources, tables } from "stores/backend"
import { get } from "svelte/store" import { get } from "svelte/store"
import { auth } from "stores/portal" import { auth } from "stores/portal"
@ -67,5 +72,10 @@ export const createBuilderWebsocket = appId => {
} }
) )
// Automations
socket.onOther(BuilderSocketEvent.AutomationChange, ({ id, automation }) => {
automationStore.actions.replace(id, automation)
})
return socket return socket
} }

View File

@ -1,6 +1,10 @@
<script> <script>
import { onMount } from "svelte" import { onMount } from "svelte"
import { automationStore, selectedAutomation } from "builderStore" import {
automationStore,
selectedAutomation,
userSelectedResourceMap,
} from "builderStore"
import NavItem from "components/common/NavItem.svelte" import NavItem from "components/common/NavItem.svelte"
import EditAutomationPopover from "./EditAutomationPopover.svelte" import EditAutomationPopover from "./EditAutomationPopover.svelte"
import { notifications } from "@budibase/bbui" import { notifications } from "@budibase/bbui"
@ -23,11 +27,11 @@
<div class="automations-list"> <div class="automations-list">
{#each $automationStore.automations.sort(aut => aut.name) as automation, idx} {#each $automationStore.automations.sort(aut => aut.name) as automation, idx}
<NavItem <NavItem
border={idx > 0}
icon="ShareAndroid" icon="ShareAndroid"
text={automation.name} text={automation.name}
selected={automation._id === selectedAutomationId} selected={automation._id === selectedAutomationId}
on:click={() => selectAutomation(automation._id)} on:click={() => selectAutomation(automation._id)}
selectedBy={$userSelectedResourceMap[automation._id]}
> >
<EditAutomationPopover {automation} /> <EditAutomationPopover {automation} />
</NavItem> </NavItem>
@ -40,6 +44,5 @@
flex-direction: column; flex-direction: column;
justify-content: flex-start; justify-content: flex-start;
align-items: stretch; align-items: stretch;
margin: 0 calc(-1 * var(--spacing-xl));
} }
</style> </style>

View File

@ -11,8 +11,8 @@
<Panel title="Automations" borderRight> <Panel title="Automations" borderRight>
<Layout paddingX="L" paddingY="XL" gap="S"> <Layout paddingX="L" paddingY="XL" gap="S">
<Button cta on:click={modal.show}>Add automation</Button> <Button cta on:click={modal.show}>Add automation</Button>
<AutomationList />
</Layout> </Layout>
<AutomationList />
</Panel> </Panel>
<Modal bind:this={modal}> <Modal bind:this={modal}>

View File

@ -228,7 +228,7 @@
.top-nav { .top-nav {
flex: 0 0 60px; flex: 0 0 60px;
background: var(--background); background: var(--background);
padding: 0 var(--spacing-xl); padding-left: var(--spacing-xl);
display: grid; display: grid;
grid-template-columns: 1fr auto 1fr; grid-template-columns: 1fr auto 1fr;
flex-direction: row; flex-direction: row;

View File

@ -8,6 +8,10 @@
import { onDestroy, onMount } from "svelte" import { onDestroy, onMount } from "svelte"
import { syncURLToState } from "helpers/urlStateSync" import { syncURLToState } from "helpers/urlStateSync"
import * as routify from "@roxi/routify" import * as routify from "@roxi/routify"
import { store } from "builderStore"
$: automationId = $selectedAutomation?._id
$: store.actions.websocket.selectResource(automationId)
// Keep URL and state in sync for selected screen ID // Keep URL and state in sync for selected screen ID
const stopSyncing = syncURLToState({ const stopSyncing = syncURLToState({

View File

@ -24,6 +24,7 @@ import {
import { getActionDefinitions as actionDefs } from "../../automations/actions" import { getActionDefinitions as actionDefs } from "../../automations/actions"
import sdk from "../../sdk" import sdk from "../../sdk"
import { db as dbCore } from "@budibase/backend-core" import { db as dbCore } from "@budibase/backend-core"
import { builderSocket } from "../../websockets"
async function getActionDefinitions() { async function getActionDefinitions() {
return removeDeprecated(await actionDefs()) return removeDeprecated(await actionDefs())
@ -107,6 +108,7 @@ export async function create(ctx: BBContext) {
...response, ...response,
}, },
} }
builderSocket?.emitAutomationUpdate(ctx, automation)
} }
export function getNewSteps(oldAutomation: Automation, automation: Automation) { export function getNewSteps(oldAutomation: Automation, automation: Automation) {
@ -187,6 +189,7 @@ export async function update(ctx: BBContext) {
_id: response.id, _id: response.id,
}, },
} }
builderSocket?.emitAutomationUpdate(ctx, automation)
} }
export async function fetch(ctx: BBContext) { export async function fetch(ctx: BBContext) {
@ -215,6 +218,7 @@ export async function destroy(ctx: BBContext) {
await cleanupAutomationMetadata(automationId) await cleanupAutomationMetadata(automationId)
ctx.body = await db.remove(automationId, ctx.params.rev) ctx.body = await db.remove(automationId, ctx.params.rev)
await events.automation.deleted(oldAutomation) await events.automation.deleted(oldAutomation)
builderSocket?.emitAutomationDeletion(ctx, automationId)
} }
export async function logSearch(ctx: BBContext) { export async function logSearch(ctx: BBContext) {

View File

@ -10,6 +10,7 @@ import {
ContextUser, ContextUser,
Screen, Screen,
App, App,
Automation,
} from "@budibase/types" } from "@budibase/types"
import { gridSocket } from "./index" import { gridSocket } from "./index"
import { clearLock, updateLock } from "../utilities/redis" import { clearLock, updateLock } from "../utilities/redis"
@ -156,4 +157,18 @@ export default class BuilderSocket extends BaseSocket {
user: ctx.user, user: ctx.user,
}) })
} }
emitAutomationUpdate(ctx: any, automation: Automation) {
this.emitToRoom(ctx, ctx.appId, BuilderSocketEvent.AutomationChange, {
id: automation._id,
automation,
})
}
emitAutomationDeletion(ctx: any, id: string) {
this.emitToRoom(ctx, ctx.appId, BuilderSocketEvent.AutomationChange, {
id,
automation: null,
})
}
} }

View File

@ -90,6 +90,7 @@ export enum BuilderSocketEvent {
AppMetadataChange = "AppMetadataChange", AppMetadataChange = "AppMetadataChange",
SelectResource = "SelectResource", SelectResource = "SelectResource",
AppPublishChange = "AppPublishChange", AppPublishChange = "AppPublishChange",
AutomationChange = "AutomationChange",
} }
export const SocketSessionTTL = 60 export const SocketSessionTTL = 60