mirror of
https://github.com/hcengineering/platform.git
synced 2025-06-09 09:20:54 +00:00
Fix processes
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
parent
ee97398277
commit
2e6a9411ec
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@ -97,7 +97,7 @@
|
||||
"MODEL_JSON": "${workspaceRoot}/models/all/bundle/model.json",
|
||||
// "SERVER_PROVIDER":"uweb"
|
||||
"SERVER_PROVIDER": "ws",
|
||||
"MODEL_VERSION": "0.7.75",
|
||||
"MODEL_VERSION": "0.7.110",
|
||||
// "VERSION": "0.6.289",
|
||||
"ELASTIC_INDEX_NAME": "local_storage_index",
|
||||
"UPLOAD_URL": "/files",
|
||||
|
@ -1,9 +1,25 @@
|
||||
<script lang="ts">
|
||||
import { Doc } from '@hcengineering/core'
|
||||
import presentation, { getClient } from '@hcengineering/presentation'
|
||||
import { Process, Transition } from '@hcengineering/process'
|
||||
import { Process, Step, StepId, Transition } from '@hcengineering/process'
|
||||
import { clearSettingsStore } from '@hcengineering/setting-resources'
|
||||
import { ButtonIcon, Component, IconDelete, Label, Modal } from '@hcengineering/ui'
|
||||
import {
|
||||
Button,
|
||||
ButtonIcon,
|
||||
Component,
|
||||
DropdownIntlItem,
|
||||
DropdownLabelsPopupIntl,
|
||||
getEventPositionElement,
|
||||
IconAdd,
|
||||
IconDelete,
|
||||
Label,
|
||||
Modal,
|
||||
showPopup
|
||||
} from '@hcengineering/ui'
|
||||
import plugin from '../../plugin'
|
||||
import { initState } from '../../utils'
|
||||
import ActionPresenter from './ActionPresenter.svelte'
|
||||
import StepEditor from './StepEditor.svelte'
|
||||
import TransitionPresenter from './TransitionPresenter.svelte'
|
||||
|
||||
export let readonly: boolean
|
||||
@ -14,11 +30,8 @@
|
||||
|
||||
const client = getClient()
|
||||
|
||||
const from = client.getModel().findObject(transition.from)
|
||||
const to = transition.to === null ? null : client.getModel().findObject(transition.to)
|
||||
|
||||
async function save (): Promise<void> {
|
||||
await client.update(transition, { triggerParams: params })
|
||||
await client.update(transition, { triggerParams: params, actions: transition.actions })
|
||||
clearSettingsStore()
|
||||
}
|
||||
|
||||
@ -31,7 +44,28 @@
|
||||
params = e.detail
|
||||
}
|
||||
|
||||
function addAction (e: MouseEvent): void {
|
||||
const items: DropdownIntlItem[] = client
|
||||
.getModel()
|
||||
.findAllSync(plugin.class.Method, {})
|
||||
.map((x) => ({
|
||||
id: x._id,
|
||||
label: x.label
|
||||
}))
|
||||
|
||||
showPopup(DropdownLabelsPopupIntl, { items }, getEventPositionElement(e), async (res) => {
|
||||
if (res !== undefined) {
|
||||
const step = await initState(res)
|
||||
transition.actions.push(step)
|
||||
transition.actions = transition.actions
|
||||
await client.update(transition, { actions: transition.actions })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
$: trigger = client.getModel().findObject(transition.trigger)
|
||||
|
||||
let expanded = new Set<StepId>()
|
||||
</script>
|
||||
|
||||
<Modal
|
||||
@ -48,19 +82,47 @@
|
||||
<ButtonIcon icon={IconDelete} size={'small'} kind={'tertiary'} on:click={remove} />
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
{#if trigger !== undefined}
|
||||
<div class="content clear-mins">
|
||||
<div class="header">
|
||||
<div class="fs-title title text-xl">
|
||||
<Label label={trigger.label} />
|
||||
</div>
|
||||
<div class="content clear-mins">
|
||||
<div class="header">
|
||||
<div class="fs-title title text-xl">
|
||||
<TransitionPresenter {transition} />
|
||||
</div>
|
||||
</div>
|
||||
{#if trigger !== undefined}
|
||||
<div class="flex-col-center text-lg">
|
||||
<Label label={trigger.label} />
|
||||
</div>
|
||||
{#if trigger.editor !== undefined}
|
||||
<Component is={trigger.editor} props={{ process, params, readonly }} on:change={change} />
|
||||
{/if}
|
||||
{/if}
|
||||
<div class="divider" />
|
||||
<div class="flex-col flex-gap-2">
|
||||
{#each transition.actions as action}
|
||||
<Button
|
||||
justify="left"
|
||||
size="large"
|
||||
kind="regular"
|
||||
width="100%"
|
||||
on:click={() => {
|
||||
if (readonly) return
|
||||
expanded.has(action._id) ? expanded.delete(action._id) : expanded.add(action._id)
|
||||
expanded = expanded
|
||||
}}
|
||||
>
|
||||
<svelte:fragment slot="content">
|
||||
<ActionPresenter {action} {process} {readonly} />
|
||||
</svelte:fragment>
|
||||
</Button>
|
||||
{#if expanded.has(action._id)}
|
||||
<StepEditor bind:step={action} {process} withoutHeader />
|
||||
{/if}
|
||||
{/each}
|
||||
{#if !readonly}
|
||||
<Button kind={'ghost'} width={'100%'} icon={IconAdd} label={plugin.string.AddAction} on:click={addAction} />
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<style lang="scss">
|
||||
@ -71,4 +133,9 @@
|
||||
.title {
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.divider {
|
||||
border-bottom: 1px solid var(--theme-divider-color);
|
||||
margin: 1rem 0;
|
||||
}
|
||||
</style>
|
||||
|
@ -46,7 +46,7 @@
|
||||
{key}
|
||||
{allowRemove}
|
||||
object={params}
|
||||
on:update={(e) => {
|
||||
on:change={(e) => {
|
||||
change(e, key)
|
||||
}}
|
||||
on:remove
|
||||
|
@ -19,6 +19,7 @@
|
||||
import { AnySvelteComponent } from '@hcengineering/ui'
|
||||
import { getContext } from '../../utils'
|
||||
import ProcessAttribute from '../ProcessAttribute.svelte'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
|
||||
export let process: Process
|
||||
export let _class: Ref<Class<Doc>>
|
||||
@ -28,6 +29,7 @@
|
||||
|
||||
const client = getClient()
|
||||
const hierarchy = client.getHierarchy()
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
function onChange (value: any | undefined): void {
|
||||
if (value === undefined) {
|
||||
@ -36,6 +38,7 @@
|
||||
} else {
|
||||
;(object as any)[key] = value
|
||||
}
|
||||
dispatch('change', { value })
|
||||
}
|
||||
|
||||
$: value = object[key]
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
export let step: Step<Doc>
|
||||
export let process: Process
|
||||
export let withoutHeader: boolean = false
|
||||
|
||||
const client = getClient()
|
||||
const dispatch = createEventDispatcher()
|
||||
@ -44,16 +45,18 @@
|
||||
|
||||
{#if method !== undefined}
|
||||
<div class="content clear-mins">
|
||||
<div class="header">
|
||||
<div class="fs-title title text-xl">
|
||||
<Label label={method.label} />
|
||||
</div>
|
||||
{#if method.description}
|
||||
<div class="descr">
|
||||
<Label label={method.description} />
|
||||
{#if !withoutHeader}
|
||||
<div class="header">
|
||||
<div class="fs-title title text-xl">
|
||||
<Label label={method.label} />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{#if method.description}
|
||||
<div class="descr">
|
||||
<Label label={method.description} />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
{#if method.editor !== undefined}
|
||||
<Component is={method.editor} props={{ step, process }} on:change={change} />
|
||||
{/if}
|
||||
|
@ -13,31 +13,14 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { createQuery, getClient, MessageBox } from '@hcengineering/presentation'
|
||||
import { Process, Step, Transition } from '@hcengineering/process'
|
||||
import {
|
||||
Button,
|
||||
ButtonIcon,
|
||||
DropdownIntlItem,
|
||||
DropdownLabelsPopupIntl,
|
||||
eventToHTMLElement,
|
||||
Icon,
|
||||
IconAdd,
|
||||
IconMoreV,
|
||||
Label,
|
||||
Menu,
|
||||
showPopup
|
||||
} from '@hcengineering/ui'
|
||||
import view from '@hcengineering/view'
|
||||
import plugin from '../../plugin'
|
||||
import { initState } from '../../utils'
|
||||
import ActionPresenter from './ActionPresenter.svelte'
|
||||
import TriggerPresenter from './TriggerPresenter.svelte'
|
||||
import AsideStepEditor from './AsideStepEditor.svelte'
|
||||
import { Doc } from '@hcengineering/core'
|
||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||
import { Process, Transition } from '@hcengineering/process'
|
||||
import { settingsStore } from '@hcengineering/setting-resources'
|
||||
import { Button, Icon } from '@hcengineering/ui'
|
||||
import plugin from '../../plugin'
|
||||
import AsideTransitionEditor from './AsideTransitionEditor.svelte'
|
||||
import TransitionPresenter from './TransitionPresenter.svelte'
|
||||
import TriggerPresenter from './TriggerPresenter.svelte'
|
||||
|
||||
export let transition: Transition
|
||||
export let process: Process
|
||||
@ -46,8 +29,6 @@
|
||||
|
||||
const client = getClient()
|
||||
|
||||
let collapsed: boolean = true
|
||||
|
||||
let from = client.getModel().findObject(transition.from)
|
||||
let to = transition.to === null ? null : client.getModel().findObject(transition.to)
|
||||
|
||||
@ -57,64 +38,13 @@
|
||||
to = transition.to === null ? null : client.getModel().findObject(transition.to)
|
||||
})
|
||||
|
||||
function editAction (step: Step<Doc>): void {
|
||||
$settingsStore = {
|
||||
id: transition._id,
|
||||
component: AsideStepEditor,
|
||||
props: { readonly, process, step, _id: transition._id }
|
||||
}
|
||||
}
|
||||
|
||||
let hovered: boolean = false
|
||||
|
||||
async function onMenuClick (ev: MouseEvent): Promise<void> {
|
||||
const actions = [
|
||||
{
|
||||
label: view.string.Delete,
|
||||
icon: view.icon.Delete,
|
||||
action: async () => {
|
||||
showPopup(MessageBox, {
|
||||
label: plugin.string.DeleteTransition,
|
||||
message: plugin.string.DeleteTransitionConfirm,
|
||||
action: async () => {
|
||||
await client.remove(transition)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
]
|
||||
hovered = true
|
||||
showPopup(Menu, { actions }, eventToHTMLElement(ev), () => {
|
||||
hovered = false
|
||||
})
|
||||
}
|
||||
|
||||
function add (e: MouseEvent): void {
|
||||
const items: DropdownIntlItem[] = client
|
||||
.getModel()
|
||||
.findAllSync(plugin.class.Method, {})
|
||||
.map((x) => ({
|
||||
id: x._id,
|
||||
label: x.label
|
||||
}))
|
||||
|
||||
showPopup(DropdownLabelsPopupIntl, { items }, eventToHTMLElement(e), async (res) => {
|
||||
if (res !== undefined) {
|
||||
const step = await initState(res)
|
||||
const length = transition.actions.push(step)
|
||||
await client.update(transition, { actions: transition.actions })
|
||||
editAction(step)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function edit (): void {
|
||||
$settingsStore = { id: transition._id, component: AsideTransitionEditor, props: { readonly, process, transition } }
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="w-full container" class:hovered>
|
||||
<div class:expand={!collapsed} class="innerContainer">
|
||||
<div class="w-full container">
|
||||
<div class="innerContainer">
|
||||
<Button on:click={edit} kind="ghost" width={'100%'} padding={'0'} size="small">
|
||||
<div class="flex-between w-full" slot="content">
|
||||
<div class="flex-row-center flex-gap-2">
|
||||
@ -122,49 +52,13 @@
|
||||
<TransitionPresenter {transition} {direction} />
|
||||
</div>
|
||||
<div class="flex-row-center">
|
||||
{#if !readonly}
|
||||
<div class="tool">
|
||||
<ButtonIcon kind="tertiary" icon={IconMoreV} size={'min'} on:click={onMenuClick} />
|
||||
</div>
|
||||
{/if}
|
||||
{#if transition.to !== null}
|
||||
<Button
|
||||
on:click={() => {
|
||||
collapsed = !collapsed
|
||||
}}
|
||||
padding={'0.25rem'}
|
||||
kind="ghost"
|
||||
size="small"
|
||||
>
|
||||
<div class="flex-row-center" slot="content">
|
||||
<Icon icon={plugin.icon.Process} size="small" />
|
||||
{transition.actions.length}
|
||||
</div>
|
||||
</Button>
|
||||
<Icon icon={plugin.icon.Process} size="small" />
|
||||
{transition.actions.length}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</Button>
|
||||
{#if !collapsed}
|
||||
{#each transition.actions as action}
|
||||
<Button
|
||||
justify="left"
|
||||
kind="ghost"
|
||||
width="100%"
|
||||
on:click={() => {
|
||||
if (readonly) return
|
||||
editAction(action)
|
||||
}}
|
||||
>
|
||||
<svelte:fragment slot="content">
|
||||
<ActionPresenter {action} {process} {readonly} />
|
||||
</svelte:fragment>
|
||||
</Button>
|
||||
{/each}
|
||||
{#if !readonly}
|
||||
<Button label={plugin.string.AddAction} icon={IconAdd} kind={'ghost'} width={'100%'} on:click={add} />
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -318,13 +318,17 @@ export function showDoneQuery (value: any, query: DocumentQuery<Doc>): DocumentQ
|
||||
|
||||
export async function continueExecution (value: Execution): Promise<void> {
|
||||
if (value.error == null) return
|
||||
const transition = value.error[0].transition
|
||||
if (transition == null) return
|
||||
const client = getClient()
|
||||
const _transition = client.getModel().findObject(transition)
|
||||
if (_transition === undefined) return
|
||||
const targetState = _transition.to
|
||||
const context = targetState == null ? value.context : await getNextStateUserInput(value, targetState, value.context)
|
||||
let context = value.context
|
||||
const transition = value.error[0].transition
|
||||
if (transition == null) {
|
||||
context = await newExecutionUserInput(value.process, context)
|
||||
} else {
|
||||
const _transition = client.getModel().findObject(transition)
|
||||
if (_transition === undefined) return
|
||||
const targetState = _transition.to
|
||||
context = targetState == null ? value.context : await getNextStateUserInput(value, targetState, value.context)
|
||||
}
|
||||
await client.update(value, { status: ExecutionStatus.Active, context })
|
||||
}
|
||||
|
||||
|
@ -17,5 +17,5 @@ import { ExecutionError } from '@hcengineering/process'
|
||||
import { ExecuteResult } from '@hcengineering/server-process'
|
||||
|
||||
export function isError (value: ExecuteResult | any): value is ExecutionError {
|
||||
return (value as ExecutionError).error !== undefined
|
||||
return (value as ExecutionError)?.error !== undefined
|
||||
}
|
||||
|
@ -559,7 +559,7 @@ export async function CreateToDo (
|
||||
execution: Execution,
|
||||
control: TriggerControl
|
||||
): Promise<ExecuteResult | undefined> {
|
||||
if (params.user === undefined || params.state === undefined || params.title === undefined) return
|
||||
if (params.user === undefined || params.title === undefined) return
|
||||
const res: Tx[] = []
|
||||
const rollback: Tx[] = []
|
||||
const id = generateId<ProcessToDo>()
|
||||
@ -573,7 +573,7 @@ export async function CreateToDo (
|
||||
collection: 'todos',
|
||||
workslots: 0,
|
||||
execution: execution._id,
|
||||
state: params.state,
|
||||
state: execution.currentState,
|
||||
title: params.title,
|
||||
user: params.user,
|
||||
description: params.description ?? '',
|
||||
|
Loading…
Reference in New Issue
Block a user