Add parallel execution restriction feature to processes (#8477)

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
Denis Bykhov
2025-04-07 14:28:25 +07:00
committed by GitHub
parent b9c6d337d8
commit e2a2011ad8
18 changed files with 114 additions and 13 deletions
@@ -78,6 +78,12 @@
}
}
async function saveRestriction (e: CustomEvent<boolean>): Promise<void> {
if (value !== undefined) {
await client.update(value, { parallelExecutionForbidden: e.detail })
}
}
async function saveAutoStart (e: CustomEvent<boolean>): Promise<void> {
if (value !== undefined) {
await client.update(value, { autoStart: e.detail })
@@ -167,6 +173,13 @@
<EditBox bind:value={value.name} on:change={saveName} placeholder={process.string.Untitled} />
<ButtonIcon icon={IconDelete} size="small" kind="secondary" on:click={handleDelete} />
</div>
<div>
<ToggleWithLabel
on={value.parallelExecutionForbidden ?? false}
on:change={saveRestriction}
label={process.string.ParallelExecutionForbidden}
/>
</div>
<div>
<ToggleWithLabel
on={value.autoStart ?? false}
@@ -50,6 +50,30 @@
}
$: selectedProcess = processes.find((p) => p._id === process)
let ignoreObjects: Ref<Card>[] = []
$: void filter(process)
async function filter (process: Ref<Process> | undefined): Promise<void> {
if (process === undefined) {
ignoreObjects = []
return
}
const pr = client.getModel().findObject(process)
if (pr === undefined) {
ignoreObjects = []
return
}
if (pr.parallelExecutionForbidden !== true) {
ignoreObjects = []
return
}
const executions = await client.findAll(plugin.class.Execution, { process, done: false }, {})
const cards = new Set(executions.map((it) => it.card))
ignoreObjects = [...cards]
}
</script>
<CardPopup
@@ -74,6 +98,12 @@
/>
</div>
{#if selectedProcess !== undefined}
<CardSelector kind={'regular'} size={'medium'} bind:value={card} _class={selectedProcess.masterTag} />
<CardSelector
kind={'regular'}
size={'medium'}
bind:value={card}
{ignoreObjects}
_class={selectedProcess.masterTag}
/>
{/if}
</CardPopup>
@@ -33,6 +33,31 @@
const res = client.getModel().findAllSync(process.class.Process, {})
const processes = res.filter((it) => resClasses.includes(it.masterTag))
async function filterProcesses (processes: Process[]): Promise<Process[]> {
const res: Process[] = []
const shouldCheck: Process[] = []
for (const val of processes) {
if (val.parallelExecutionForbidden === true) {
shouldCheck.push(val)
} else {
res.push(val)
}
}
if (shouldCheck.length === 0) return res
const executions = await client.findAll(process.class.Execution, {
process: { $in: shouldCheck.map((it) => it._id) },
done: false
})
const notAllowed = new Set(executions.map((it) => it.process))
for (const val of shouldCheck) {
if (!notAllowed.has(val._id)) {
res.push(val)
}
}
return res
}
const dispatch = createEventDispatcher()
async function runProcess (_id: Ref<Process>): Promise<void> {
@@ -57,16 +82,18 @@
<Label label={process.string.NoProcesses} />
</div>
{:else}
{#each processes as process}
<button
class="ap-menuItem flex-row-center withIcon w-full"
on:click|preventDefault|stopPropagation={async () => {
await runProcess(process._id)
}}
>
{process.name}
</button>
{/each}
{#await filterProcesses(processes) then processes}
{#each processes as process}
<button
class="ap-menuItem flex-row-center withIcon w-full"
on:click|preventDefault|stopPropagation={async () => {
await runProcess(process._id)
}}
>
{process.name}
</button>
{/each}
{/await}
{/if}
</div>
<div class="ap-space x2" />