mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-10 03:37:43 +02:00
processes UI (#8349)
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
<!--
|
||||
// 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 { getCurrentEmployee } from '@hcengineering/contact'
|
||||
import { createQuery } from '@hcengineering/presentation'
|
||||
import { Process } from '@hcengineering/process'
|
||||
import { Separator, deviceOptionsStore as deviceInfo } from '@hcengineering/ui'
|
||||
import { SpecialView } from '@hcengineering/workbench-resources'
|
||||
import { onDestroy } from 'svelte'
|
||||
import plugin from '../plugin'
|
||||
import { Special } from '../types'
|
||||
import Navigator from './Navigator.svelte'
|
||||
import RunProcessCardPopup from './RunProcessCardPopup.svelte'
|
||||
|
||||
export let currentSpace: string
|
||||
|
||||
const query = createQuery()
|
||||
let processes: Process[] = []
|
||||
query.query(plugin.class.Process, {}, (res) => {
|
||||
processes = res
|
||||
})
|
||||
|
||||
$: selectedProcess = processes.find((p) => p._id === currentSpace)
|
||||
|
||||
let replacedPanel: HTMLElement
|
||||
$: $deviceInfo.replacedPanel = replacedPanel
|
||||
onDestroy(() => ($deviceInfo.replacedPanel = undefined))
|
||||
|
||||
const specials: Special[] = [
|
||||
{
|
||||
_id: 'all',
|
||||
label: plugin.string.AllProcesses,
|
||||
baseQuery: {}
|
||||
},
|
||||
{
|
||||
_id: 'my',
|
||||
label: plugin.string.MyProcesses,
|
||||
baseQuery: {
|
||||
assignee: getCurrentEmployee()
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
$: selectedSpecial = specials.find((s) => s._id === currentSpace)
|
||||
$: baseQuery =
|
||||
selectedProcess !== undefined
|
||||
? { process: selectedProcess._id }
|
||||
: selectedSpecial !== undefined
|
||||
? selectedSpecial.baseQuery
|
||||
: {}
|
||||
</script>
|
||||
|
||||
<div class="hulyPanels-container">
|
||||
{#if $deviceInfo.navigator.visible}
|
||||
<Navigator {processes} {currentSpace} {specials} />
|
||||
<Separator
|
||||
name={'workbench'}
|
||||
float={$deviceInfo.navigator.float}
|
||||
index={0}
|
||||
color={'transparent'}
|
||||
separatorSize={0}
|
||||
short
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<div class="hulyComponent" bind:this={replacedPanel}>
|
||||
<SpecialView
|
||||
_class={plugin.class.Execution}
|
||||
label={plugin.string.Processes}
|
||||
icon={plugin.icon.Process}
|
||||
{baseQuery}
|
||||
createLabel={plugin.string.RunProcess}
|
||||
createComponent={plugin.component.RunProcessCardPopup}
|
||||
createComponentProps={{ value: selectedProcess?._id }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,73 @@
|
||||
<!--
|
||||
// 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 { cardId } from '@hcengineering/card'
|
||||
import { Process } from '@hcengineering/process'
|
||||
import { deviceOptionsStore as deviceInfo, NavItem, Scroller } from '@hcengineering/ui'
|
||||
import { NavLink } from '@hcengineering/view-resources'
|
||||
import { NavFooter, NavHeader, SavedView } from '@hcengineering/workbench-resources'
|
||||
import plugin from '../plugin'
|
||||
import { Special } from '../types'
|
||||
|
||||
export let currentSpace: string
|
||||
export let processes: Process[]
|
||||
|
||||
export let specials: Special[]
|
||||
|
||||
let menuSelection: boolean = false
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="antiPanel-navigator {$deviceInfo.navigator.direction === 'horizontal' ? 'portrait' : 'landscape'} border-left"
|
||||
class:fly={$deviceInfo.navigator.float}
|
||||
>
|
||||
<div class="antiPanel-wrap__content hulyNavPanel-container">
|
||||
<NavHeader label={plugin.string.Processes} />
|
||||
{#each specials as special}
|
||||
<NavLink space={special._id}>
|
||||
<NavItem
|
||||
_id={special._id}
|
||||
label={special.label}
|
||||
isFold
|
||||
empty
|
||||
selected={!menuSelection && special._id === currentSpace}
|
||||
/>
|
||||
</NavLink>
|
||||
{/each}
|
||||
|
||||
<SavedView alias={cardId} on:select={(res) => (menuSelection = res.detail)} />
|
||||
|
||||
{#if processes.length > 0}
|
||||
<div class="antiNav-divider line" />
|
||||
<Scroller shrink>
|
||||
{#each processes as process}
|
||||
<NavLink space={process._id}>
|
||||
<NavItem
|
||||
_id={process._id}
|
||||
title={process.name}
|
||||
isFold
|
||||
empty
|
||||
selected={!menuSelection && process._id === currentSpace}
|
||||
/>
|
||||
</NavLink>
|
||||
{/each}
|
||||
</Scroller>
|
||||
{/if}
|
||||
|
||||
<div class="mt-2" />
|
||||
|
||||
<NavFooter split />
|
||||
</div>
|
||||
</div>
|
||||
@@ -29,7 +29,6 @@
|
||||
} from '@hcengineering/ui'
|
||||
import view, { Viewlet, ViewletPreference, ViewOptions } from '@hcengineering/view'
|
||||
import { List, ListSelectionProvider, SelectDirection, ViewletsSettingButton } from '@hcengineering/view-resources'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import process from '../plugin'
|
||||
import RunProcessPopup from './RunProcessPopup.svelte'
|
||||
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
<!--
|
||||
// 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 as CardPopup, getClient } from '@hcengineering/presentation'
|
||||
import plugin from '../plugin'
|
||||
import { Card } from '@hcengineering/card'
|
||||
import { CardSelector } from '@hcengineering/card-resources'
|
||||
import { Dropdown, Label, ListItem, Loading } from '@hcengineering/ui'
|
||||
import { Process } from '@hcengineering/process'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import core, { Ref } from '@hcengineering/core'
|
||||
|
||||
export let value: Ref<Process> | undefined
|
||||
|
||||
const client = getClient()
|
||||
|
||||
let process: Ref<Process> | undefined = value
|
||||
let card: Ref<Card> | undefined
|
||||
|
||||
const processes = client.getModel().findAllSync(plugin.class.Process, {})
|
||||
|
||||
const items: ListItem[] = processes.map((p) => ({ label: p.name, _id: p._id }))
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
async function runProcess (): Promise<void> {
|
||||
if (process === undefined || card === undefined) return
|
||||
await client.createDoc(plugin.class.Execution, core.space.Workspace, {
|
||||
process,
|
||||
currentState: null,
|
||||
card,
|
||||
done: false,
|
||||
rollback: {},
|
||||
currentToDo: null,
|
||||
assignee: null
|
||||
})
|
||||
dispatch('close')
|
||||
}
|
||||
|
||||
$: selectedProcess = processes.find((p) => p._id === process)
|
||||
</script>
|
||||
|
||||
<CardPopup
|
||||
label={plugin.string.RunProcess}
|
||||
canSave={process !== undefined && card !== undefined}
|
||||
okAction={runProcess}
|
||||
width={'menu'}
|
||||
on:close
|
||||
>
|
||||
<div class="mb-4">
|
||||
<Dropdown
|
||||
{items}
|
||||
kind={'regular'}
|
||||
size={'medium'}
|
||||
placeholder={plugin.string.Process}
|
||||
disabled={value !== undefined}
|
||||
selected={items.find((i) => i._id === process)}
|
||||
on:selected={(e) => {
|
||||
process = e.detail._id
|
||||
card = undefined
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{#if selectedProcess !== undefined}
|
||||
<CardSelector kind={'regular'} size={'medium'} bind:value={card} _class={selectedProcess.masterTag} />
|
||||
{/if}
|
||||
</CardPopup>
|
||||
@@ -14,12 +14,12 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Card } from '@hcengineering/card'
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
import process from '../plugin'
|
||||
import { Label, Loading } from '@hcengineering/ui'
|
||||
import { Process } from '@hcengineering/process'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import core, { Ref } from '@hcengineering/core'
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
import { Process } from '@hcengineering/process'
|
||||
import { Label } from '@hcengineering/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import process from '../plugin'
|
||||
|
||||
export let value: Card
|
||||
|
||||
@@ -30,19 +30,8 @@
|
||||
const mixins = h.getDescendants(value._class).filter((p) => h.hasMixin(value, p))
|
||||
const resClasses = [...asc, ...mixins]
|
||||
|
||||
let loading = true
|
||||
let processes: Process[] = []
|
||||
|
||||
void client
|
||||
.findAll(process.class.Process, {})
|
||||
.then((res) => {
|
||||
processes = res.filter((it) => resClasses.includes(it.masterTag))
|
||||
loading = false
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err)
|
||||
loading = false
|
||||
})
|
||||
const res = client.getModel().findAllSync(process.class.Process, {})
|
||||
const processes = res.filter((it) => resClasses.includes(it.masterTag))
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
@@ -63,10 +52,10 @@
|
||||
<div class="antiPopup">
|
||||
<div class="ap-space x2" />
|
||||
<div class="ap-scroll">
|
||||
{#if loading}
|
||||
<Loading />
|
||||
{:else if processes.length === 0}
|
||||
<Label label={process.string.NoProcesses} />
|
||||
{#if processes.length === 0}
|
||||
<div class="flex-row-center p-4">
|
||||
<Label label={process.string.NoProcesses} />
|
||||
</div>
|
||||
{:else}
|
||||
{#each processes as process}
|
||||
<button
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
export let size: IconSize = 'small'
|
||||
|
||||
export let fill: number = -1
|
||||
export let fill: number = 21
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
export let size: IconSize = 'small'
|
||||
|
||||
export let fill: number = -1
|
||||
export let fill: number = 17
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
export let size: IconSize = 'small'
|
||||
|
||||
export let fill: number = -1
|
||||
export let fill: number = 11
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user