mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-12 12:47:45 +02:00
Process roles (#8654)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
@@ -29,7 +29,9 @@
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import ContextSelectorPopup from './attributeEditors/ContextSelectorPopup.svelte'
|
||||
import ContextValue from './attributeEditors/ContextValue.svelte'
|
||||
import { MasterTag, Tag } from '@hcengineering/card'
|
||||
|
||||
export let masterTag: Ref<MasterTag | Tag>
|
||||
export let value: any
|
||||
export let context: Context
|
||||
export let presenterClass: {
|
||||
@@ -52,6 +54,7 @@
|
||||
showPopup(
|
||||
ContextSelectorPopup,
|
||||
{
|
||||
masterTag,
|
||||
context,
|
||||
attribute,
|
||||
onSelect
|
||||
@@ -78,6 +81,7 @@
|
||||
<div class="text-input" class:context={contextValue}>
|
||||
{#if contextValue}
|
||||
<ContextValue
|
||||
{masterTag}
|
||||
{contextValue}
|
||||
{context}
|
||||
{attribute}
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
{attribute}
|
||||
{presenterClass}
|
||||
{value}
|
||||
masterTag={process.masterTag}
|
||||
{allowRemove}
|
||||
on:remove
|
||||
on:change={(e) => {
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import core, { generateId, Ref } from '@hcengineering/core'
|
||||
import core, { Ref } from '@hcengineering/core'
|
||||
import { translate } from '@hcengineering/platform'
|
||||
import { createQuery, getClient, MessageBox } from '@hcengineering/presentation'
|
||||
import { Process, SelectedUserRequest, State } from '@hcengineering/process'
|
||||
import { Process, State } from '@hcengineering/process'
|
||||
import { settingsStore } from '@hcengineering/setting-resources'
|
||||
import {
|
||||
Button,
|
||||
@@ -29,21 +29,20 @@
|
||||
IconDescription,
|
||||
navigate,
|
||||
NavItem,
|
||||
ToggleWithLabel,
|
||||
Scroller,
|
||||
secondNavSeparators,
|
||||
Separator,
|
||||
showPopup
|
||||
showPopup,
|
||||
ToggleWithLabel
|
||||
} from '@hcengineering/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import process from '../plugin'
|
||||
import { getToDoEndAction } from '../utils'
|
||||
import Aside from './Aside.svelte'
|
||||
import ArrowEnd from './icons/ArrowEnd.svelte'
|
||||
import ArrowStart from './icons/ArrowStart.svelte'
|
||||
import StateEditor from './StateEditor.svelte'
|
||||
import TransitionEditor from './TransitionEditor.svelte'
|
||||
import { getToDoEndAction } from '../utils'
|
||||
import ExecutionResultEditor from './ExecutionResultEditor.svelte'
|
||||
|
||||
export let _id: Ref<Process>
|
||||
export let visibleSecondNav: boolean = true
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { AnyAttribute, Class, Doc, Ref } from '@hcengineering/core'
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
import { Context, Func, ProcessFunction, SelectedContext } from '@hcengineering/process'
|
||||
import {
|
||||
ButtonIcon,
|
||||
CheckBox,
|
||||
@@ -26,14 +29,13 @@
|
||||
showPopup,
|
||||
Submenu
|
||||
} from '@hcengineering/ui'
|
||||
import { AttributeCategory } from '@hcengineering/view'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import plugin from '../../plugin'
|
||||
import core, { AnyAttribute, Class, Doc, Ref } from '@hcengineering/core'
|
||||
import { Context, Func, ProcessFunction, SelectedContext } from '@hcengineering/process'
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
import { AttributeCategory } from '@hcengineering/view'
|
||||
import FallbackEditor from '../contextEditors/FallbackEditor.svelte'
|
||||
import { MasterTag, Tag } from '@hcengineering/card'
|
||||
|
||||
export let masterTag: Ref<MasterTag | Tag>
|
||||
export let contextValue: SelectedContext
|
||||
export let context: Context
|
||||
export let attribute: AnyAttribute
|
||||
@@ -63,7 +65,7 @@
|
||||
|
||||
const reduceFuncs = client
|
||||
.getModel()
|
||||
.findAllSync(plugin.class.ProcessFunction, { of: core.class.ArrOf })
|
||||
.findAllSync(plugin.class.ProcessFunction, { type: 'reduce' })
|
||||
.map((it) => it._id)
|
||||
|
||||
$: availableFunctions = getAvailableFunctions(context, contextValue.functions, attrClass, category)
|
||||
@@ -77,7 +79,9 @@
|
||||
category: AttributeCategory
|
||||
): Ref<ProcessFunction>[] {
|
||||
const result: Ref<ProcessFunction>[] = []
|
||||
const allFunctions = client.getModel().findAllSync(plugin.class.ProcessFunction, { of: attrClass, category })
|
||||
const allFunctions = client
|
||||
.getModel()
|
||||
.findAllSync(plugin.class.ProcessFunction, { of: attrClass, category, type: 'transform' })
|
||||
for (const f of allFunctions) {
|
||||
if (functions === undefined || f.allowMany === true || functions.findIndex((p) => p.func === f._id) === -1) {
|
||||
result.push(f._id)
|
||||
@@ -179,6 +183,7 @@
|
||||
func.editor,
|
||||
{
|
||||
func,
|
||||
masterTag,
|
||||
context,
|
||||
attribute,
|
||||
props: val?.props ?? {}
|
||||
@@ -192,7 +197,6 @@
|
||||
func.props = res
|
||||
contextValue.functions[pos] = func
|
||||
contextValue.functions = contextValue.functions
|
||||
console.log(contextValue.functions)
|
||||
onChange(contextValue)
|
||||
}
|
||||
}
|
||||
@@ -309,8 +313,8 @@
|
||||
/>
|
||||
<!-- <div class="menu-separator" /> -->
|
||||
{/if}
|
||||
<div class="menu-separator" />
|
||||
{/if}
|
||||
<div class="menu-separator" />
|
||||
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
|
||||
<button
|
||||
bind:this={elements[functionButtonIndex + 1]}
|
||||
|
||||
+52
-21
@@ -13,13 +13,16 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { AnyAttribute, generateId } from '@hcengineering/core'
|
||||
import { Context, SelectedContext } from '@hcengineering/process'
|
||||
import { AnyAttribute, generateId, Ref } from '@hcengineering/core'
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
import { Context, ProcessFunction, SelectedContext } from '@hcengineering/process'
|
||||
import { Label, resizeObserver, Scroller, Submenu } from '@hcengineering/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import plugin from '../../plugin'
|
||||
import { getValueReduceFunc } from '../../utils'
|
||||
import { MasterTag, Tag } from '@hcengineering/card'
|
||||
|
||||
export let masterTag: Ref<MasterTag | Tag>
|
||||
export let context: Context
|
||||
export let attribute: AnyAttribute
|
||||
export let onSelect: (val: SelectedContext | null) => void
|
||||
@@ -58,20 +61,20 @@
|
||||
dispatch('close')
|
||||
}
|
||||
|
||||
function getIndex (ownIndex: number, kind: 'attribute' | 'relation' | 'nested' | 'total'): number {
|
||||
if (kind === 'attribute') {
|
||||
return ownIndex + 1
|
||||
}
|
||||
if (kind === 'nested') {
|
||||
return ownIndex + context.attributes.length + 1
|
||||
}
|
||||
if (kind === 'relation') {
|
||||
return ownIndex + context.attributes.length + nested.length + 1
|
||||
}
|
||||
if (kind === 'total') {
|
||||
return ownIndex + context.attributes.length + relations.length + nested.length + 1
|
||||
}
|
||||
return ownIndex
|
||||
function onFunc (func: Ref<ProcessFunction>): void {
|
||||
onSelect({
|
||||
type: 'function',
|
||||
key: attribute.name,
|
||||
func,
|
||||
props: {}
|
||||
})
|
||||
dispatch('close')
|
||||
}
|
||||
|
||||
function getFunc (func: Ref<ProcessFunction>): ProcessFunction {
|
||||
const client = getClient()
|
||||
const f = client.getModel().getObject(func)
|
||||
return f
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -89,8 +92,38 @@
|
||||
</span>
|
||||
</button>
|
||||
<div class="menu-separator" />
|
||||
{#if context.functions.length > 0}
|
||||
{#each context.functions as f}
|
||||
{@const func = getFunc(f)}
|
||||
{#if func.editor !== undefined}
|
||||
<Submenu
|
||||
label={func.label}
|
||||
props={{
|
||||
masterTag,
|
||||
context: func,
|
||||
target: attribute,
|
||||
onSelect: onClick
|
||||
}}
|
||||
options={{ component: func.editor }}
|
||||
withHover
|
||||
/>
|
||||
{:else}
|
||||
<button
|
||||
on:click={() => {
|
||||
onFunc(func._id)
|
||||
}}
|
||||
class="menu-item"
|
||||
>
|
||||
<span class="overflow-label pr-1">
|
||||
<Label label={func.label} />
|
||||
</span>
|
||||
</button>
|
||||
{/if}
|
||||
{/each}
|
||||
<div class="menu-separator" />
|
||||
{/if}
|
||||
{#if context.attributes.length > 0}
|
||||
{#each context.attributes as attr, i}
|
||||
{#each context.attributes as attr}
|
||||
<button
|
||||
on:click={() => {
|
||||
onAttribute(attr)
|
||||
@@ -105,8 +138,7 @@
|
||||
<div class="menu-separator" />
|
||||
{/if}
|
||||
{#if nested.length > 0}
|
||||
{#each nested as object, i}
|
||||
{@const index = getIndex(i, 'nested')}
|
||||
{#each nested as object}
|
||||
<Submenu
|
||||
label={object.attribute.label}
|
||||
props={{
|
||||
@@ -121,8 +153,7 @@
|
||||
<div class="menu-separator" />
|
||||
{/if}
|
||||
{#if relations.length > 0}
|
||||
{#each relations as object, i}
|
||||
{@const index = getIndex(i, 'relation')}
|
||||
{#each relations as object}
|
||||
<Submenu
|
||||
text={object[0]}
|
||||
props={{
|
||||
|
||||
@@ -20,7 +20,9 @@
|
||||
import ContextValuePresenter from './ContextValuePresenter.svelte'
|
||||
import { AttributeCategory } from '@hcengineering/view'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { MasterTag, Tag } from '@hcengineering/card'
|
||||
|
||||
export let masterTag: Ref<MasterTag | Tag>
|
||||
export let contextValue: SelectedContext
|
||||
export let context: Context
|
||||
export let attribute: AnyAttribute
|
||||
@@ -46,7 +48,7 @@
|
||||
}
|
||||
showPopup(
|
||||
ConfigurePopup,
|
||||
{ contextValue, attrClass, category, attribute, context, onChange },
|
||||
{ contextValue, attrClass, masterTag, category, attribute, context, onChange },
|
||||
eventToHTMLElement(e)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
import AttrContextPresenter from './AttrContextPresenter.svelte'
|
||||
import NestedContextPresenter from './NestedContextPresenter.svelte'
|
||||
import RelContextPresenter from './RelContextPresenter.svelte'
|
||||
import FunctionContextPresenter from './FunctionContextPresenter.svelte'
|
||||
|
||||
export let contextValue: SelectedContext
|
||||
export let context: Context
|
||||
@@ -33,6 +34,8 @@
|
||||
<NestedContextPresenter {contextValue} {context} />
|
||||
{:else if contextValue.type === 'userRequest'}
|
||||
<Label label={plugin.string.RequestFromUser} />
|
||||
{:else if contextValue.type === 'function'}
|
||||
<FunctionContextPresenter {contextValue} {context} />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
<!--
|
||||
// Copyright © 2025 Hardcore Engineering Inc.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
import { Context, SelectedContextFunc } from '@hcengineering/process'
|
||||
import { Label } from '@hcengineering/ui'
|
||||
|
||||
export let contextValue: SelectedContextFunc
|
||||
export let context: Context
|
||||
|
||||
const client = getClient()
|
||||
const func = client.getModel().findObject(contextValue.func)
|
||||
</script>
|
||||
|
||||
{#if func !== undefined}
|
||||
<Label label={func.label} />
|
||||
{/if}
|
||||
@@ -13,7 +13,8 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import core, { AnyAttribute } from '@hcengineering/core'
|
||||
import { MasterTag, Tag } from '@hcengineering/card'
|
||||
import core, { AnyAttribute, Ref } from '@hcengineering/core'
|
||||
import { getResource } from '@hcengineering/platform'
|
||||
import presentation, { Card, getClient } from '@hcengineering/presentation'
|
||||
import { Context, ProcessFunction } from '@hcengineering/process'
|
||||
@@ -23,6 +24,7 @@
|
||||
import ProcessAttribute from '../ProcessAttribute.svelte'
|
||||
|
||||
export let func: ProcessFunction
|
||||
export let masterTag: Ref<MasterTag | Tag>
|
||||
export let context: Context
|
||||
export let attribute: AnyAttribute
|
||||
export let props: Record<string, any> = {}
|
||||
@@ -59,6 +61,7 @@
|
||||
|
||||
<Card on:close width={'menu'} label={func.label} canSave okAction={save} okLabel={presentation.string.Save}>
|
||||
<ProcessAttribute
|
||||
{masterTag}
|
||||
{context}
|
||||
{attribute}
|
||||
presenterClass={{
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
<!--
|
||||
// Copyright © 2025 Hardcore Engineering Inc.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import card, { MasterTag, Role, Tag } from '@hcengineering/card'
|
||||
import { AnyAttribute, Ref } from '@hcengineering/core'
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
import { ProcessFunction, SelectedContext } from '@hcengineering/process'
|
||||
import { resizeObserver, Scroller } from '@hcengineering/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { getContextFunctionReduce } from '../../utils'
|
||||
|
||||
export let context: ProcessFunction
|
||||
export let masterTag: Ref<MasterTag | Tag>
|
||||
export let target: AnyAttribute
|
||||
export let onSelect: (val: SelectedContext) => void
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const client = getClient()
|
||||
|
||||
const elements: HTMLButtonElement[] = []
|
||||
|
||||
const keyDown = (event: KeyboardEvent, index: number): void => {
|
||||
if (event.key === 'ArrowDown') {
|
||||
elements[(index + 1) % elements.length].focus()
|
||||
}
|
||||
|
||||
if (event.key === 'ArrowUp') {
|
||||
elements[(elements.length + index - 1) % elements.length].focus()
|
||||
}
|
||||
|
||||
if (event.key === 'ArrowLeft') {
|
||||
dispatch('close')
|
||||
}
|
||||
}
|
||||
|
||||
function onValue (role: Ref<Role>): void {
|
||||
const pathReduce = getContextFunctionReduce(context, target)
|
||||
onSelect({
|
||||
type: 'function',
|
||||
func: context._id,
|
||||
key: target.name,
|
||||
functions: [],
|
||||
sourceFunction: pathReduce,
|
||||
props: {
|
||||
target: role
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const ancestors = client.getHierarchy().getAncestors(masterTag)
|
||||
const roles = client.getModel().findAllSync(card.class.Role, { attachedTo: { $in: ancestors } })
|
||||
</script>
|
||||
|
||||
<div class="selectPopup" use:resizeObserver={() => dispatch('changeContent')}>
|
||||
<div class="menu-space" />
|
||||
<Scroller>
|
||||
{#each roles as role, i}
|
||||
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
|
||||
<button
|
||||
bind:this={elements[i]}
|
||||
on:keydown={(event) => {
|
||||
keyDown(event, i)
|
||||
}}
|
||||
on:mouseover={() => {
|
||||
elements[i]?.focus()
|
||||
}}
|
||||
on:click={() => {
|
||||
onValue(role._id)
|
||||
}}
|
||||
class="menu-item"
|
||||
>
|
||||
<span class="overflow-label pr-1">
|
||||
{role.name}
|
||||
</span>
|
||||
</button>
|
||||
{/each}
|
||||
</Scroller>
|
||||
<div class="menu-space" />
|
||||
</div>
|
||||
Reference in New Issue
Block a user