diff --git a/models/process/src/index.ts b/models/process/src/index.ts index 4a362c3a48..60c8aa6f78 100644 --- a/models/process/src/index.ts +++ b/models/process/src/index.ts @@ -248,6 +248,8 @@ export class TUpdateCriteriaComponent extends TDoc implements UpdateCriteriaComp editor!: AnyComponent of!: Ref>> + + props!: Record } export * from './migration' @@ -1180,50 +1182,83 @@ export function createModel (builder: Builder): void { builder.createDoc(process.class.UpdateCriteriaComponent, core.space.Model, { category: 'attribute', - editor: process.criteriaEditor.StringCriteria, - of: core.class.TypeString + editor: process.criteriaEditor.BaseCriteria, + of: core.class.TypeString, + props: { + modes: ['Equal', 'StringContains', 'Exists'] + } }) builder.createDoc(process.class.UpdateCriteriaComponent, core.space.Model, { category: 'attribute', - editor: process.criteriaEditor.StringCriteria, - of: core.class.TypeHyperlink + editor: process.criteriaEditor.BaseCriteria, + of: core.class.TypeHyperlink, + props: { + modes: ['Equal', 'StringContains', 'Exists'] + } }) builder.createDoc(process.class.UpdateCriteriaComponent, core.space.Model, { category: 'attribute', - editor: process.criteriaEditor.NumberCriteria, - of: core.class.TypeNumber + editor: process.criteriaEditor.BaseCriteria, + of: core.class.TypeNumber, + props: { + modes: ['Equal', 'GT', 'LT', 'Between', 'Exists'] + } }) builder.createDoc(process.class.UpdateCriteriaComponent, core.space.Model, { category: 'attribute', - editor: process.criteriaEditor.DateCriteria, - of: core.class.TypeDate + editor: process.criteriaEditor.BaseCriteria, + of: core.class.TypeDate, + props: { + modes: ['Equal', 'GT', 'LT', 'Between', 'Exists'] + } }) builder.createDoc(process.class.UpdateCriteriaComponent, core.space.Model, { category: 'attribute', - editor: process.criteriaEditor.BooleanCriteria, - of: core.class.TypeBoolean + editor: process.criteriaEditor.BaseCriteria, + of: core.class.TypeBoolean, + props: { + modes: ['Equal', 'NotEqual', 'Exists'] + } }) builder.createDoc(process.class.UpdateCriteriaComponent, core.space.Model, { category: 'array', - editor: process.criteriaEditor.ArrayCriteria, - of: core.class.ArrOf + editor: process.criteriaEditor.BaseCriteria, + of: core.class.ArrOf, + props: { + modes: [ + 'ArrayAll', + 'ArrayAny', + 'ArrayNotIncludes', + 'ArraySizeEquals', + 'ArraySizeGt', + 'ArraySizeGte', + 'ArraySizeLt', + 'ArraySizeLte' + ] + } }) builder.createDoc(process.class.UpdateCriteriaComponent, core.space.Model, { category: 'attribute', - editor: process.criteriaEditor.EnumCriteria, - of: core.class.EnumOf + editor: process.criteriaEditor.BaseCriteria, + of: core.class.EnumOf, + props: { + modes: ['Equal', 'NotEqual', 'Exists'] + } }) builder.createDoc(process.class.UpdateCriteriaComponent, core.space.Model, { category: 'object', - editor: process.criteriaEditor.RefCriteria, - of: core.class.RefTo + editor: process.criteriaEditor.BaseCriteria, + of: core.class.RefTo, + props: { + modes: ['Equal', 'NotEqual', 'Exists'] + } }) } diff --git a/plugins/process-resources/src/components/criterias/ArrayCriteria.svelte b/plugins/process-resources/src/components/criterias/ArrayCriteria.svelte deleted file mode 100644 index 6a7b5dce37..0000000000 --- a/plugins/process-resources/src/components/criterias/ArrayCriteria.svelte +++ /dev/null @@ -1,231 +0,0 @@ - - - - -
- { - mode = e.detail - if ((isSize(mode) && !isSize(selectedMode.id)) || (!isSize(mode) && isSize(selectedMode.id))) { - val = undefined - contextValue = undefined - } - selectedMode = modes.find((m) => m.id === mode) ?? modes[0] - changeResult(val, true) - }} - /> - -
- {#if !isSize(mode)} - {#if contextValue} - { - onSelect(e.detail) - }} - /> - {:else} -
- {#if baseEditor} - - {/if} -
- {/if} - {:else if contextValue} - { - onSelect(e.detail) - }} - /> - {:else if !Number.isNaN(val)} -
- -
- {/if} -
-
-
-
- - diff --git a/plugins/process-resources/src/components/criterias/ArraySizeCriteria.svelte b/plugins/process-resources/src/components/criterias/ArraySizeCriteria.svelte new file mode 100644 index 0000000000..062defcca7 --- /dev/null +++ b/plugins/process-resources/src/components/criterias/ArraySizeCriteria.svelte @@ -0,0 +1,137 @@ + + + + +
+ {#if contextValue} + { + onSelect(e.detail) + }} + /> + {:else} +
+ +
+ {/if} +
+
+
+ + diff --git a/plugins/process-resources/src/components/criterias/AttributeCriteria.svelte b/plugins/process-resources/src/components/criterias/AttributeCriteria.svelte index 688845bc5f..6241641ab2 100644 --- a/plugins/process-resources/src/components/criterias/AttributeCriteria.svelte +++ b/plugins/process-resources/src/components/criterias/AttributeCriteria.svelte @@ -15,7 +15,7 @@ + +
+ {#if contextValue} + { + onSelect(e.detail) + }} + /> + {:else} +
+ {#if baseEditor} + + {/if} +
+ {/if} +
+
+
+ + diff --git a/plugins/process-resources/src/components/criterias/BooleanCriteria.svelte b/plugins/process-resources/src/components/criterias/BooleanCriteria.svelte deleted file mode 100644 index 538ef8d874..0000000000 --- a/plugins/process-resources/src/components/criterias/BooleanCriteria.svelte +++ /dev/null @@ -1,33 +0,0 @@ - - - - - diff --git a/plugins/process-resources/src/components/criterias/DateCriteria.svelte b/plugins/process-resources/src/components/criterias/DateCriteria.svelte deleted file mode 100644 index 35ddfb8f21..0000000000 --- a/plugins/process-resources/src/components/criterias/DateCriteria.svelte +++ /dev/null @@ -1,33 +0,0 @@ - - - - - diff --git a/plugins/process-resources/src/components/criterias/EnumCriteria.svelte b/plugins/process-resources/src/components/criterias/EnumCriteria.svelte deleted file mode 100644 index 538ef8d874..0000000000 --- a/plugins/process-resources/src/components/criterias/EnumCriteria.svelte +++ /dev/null @@ -1,33 +0,0 @@ - - - - - diff --git a/plugins/process-resources/src/components/criterias/NumberCriteria.svelte b/plugins/process-resources/src/components/criterias/NumberCriteria.svelte deleted file mode 100644 index 35ddfb8f21..0000000000 --- a/plugins/process-resources/src/components/criterias/NumberCriteria.svelte +++ /dev/null @@ -1,33 +0,0 @@ - - - - - diff --git a/plugins/process-resources/src/components/criterias/RangeCriteria.svelte b/plugins/process-resources/src/components/criterias/RangeCriteria.svelte new file mode 100644 index 0000000000..c4faea5b68 --- /dev/null +++ b/plugins/process-resources/src/components/criterias/RangeCriteria.svelte @@ -0,0 +1,211 @@ + + + + +
+
+
+ {#if firstContextValue} + { + onSelect(e.detail, 0) + }} + /> + {:else} +
+ {#if baseEditor} + + {/if} +
+ {/if} +
+
+
+
+ {#if secondContextValue} + { + onSelect(e.detail, 1) + }} + /> + {:else} +
+ {#if baseEditor} + + {/if} +
+ {/if} +
+
+
+
+
+ + diff --git a/plugins/process-resources/src/components/criterias/RefCriteria.svelte b/plugins/process-resources/src/components/criterias/RefCriteria.svelte deleted file mode 100644 index 538ef8d874..0000000000 --- a/plugins/process-resources/src/components/criterias/RefCriteria.svelte +++ /dev/null @@ -1,33 +0,0 @@ - - - - - diff --git a/plugins/process-resources/src/components/criterias/StringCriteria.svelte b/plugins/process-resources/src/components/criterias/StringCriteria.svelte deleted file mode 100644 index 9791c454cc..0000000000 --- a/plugins/process-resources/src/components/criterias/StringCriteria.svelte +++ /dev/null @@ -1,33 +0,0 @@ - - - - - diff --git a/plugins/process-resources/src/components/settings/CardUpdateEditor.svelte b/plugins/process-resources/src/components/settings/CardUpdateEditor.svelte index 7e78111514..5959278366 100644 --- a/plugins/process-resources/src/components/settings/CardUpdateEditor.svelte +++ b/plugins/process-resources/src/components/settings/CardUpdateEditor.svelte @@ -46,7 +46,8 @@ if (attr.hidden === true) continue if (ignoreKeys.includes(key)) continue const presenterClass = getAttributePresenterClass(hierarchy, attr.type) - const editor = getCirteriaEditor(presenterClass.attrClass, presenterClass.category) + const updateCriteria = getCirteriaEditor(presenterClass.attrClass, presenterClass.category) + const editor = updateCriteria?.editor if (editor == null) continue res.push(attr) } diff --git a/plugins/process-resources/src/index.ts b/plugins/process-resources/src/index.ts index 1bcf1c3c0d..a34cd7b3e2 100644 --- a/plugins/process-resources/src/index.ts +++ b/plugins/process-resources/src/index.ts @@ -48,13 +48,9 @@ import MultiArrayElementEditor from './components/transformEditors/MultiArrayEle import DateOffsetEditor from './components/transformEditors/DateOffsetEditor.svelte' import NumberEditor from './components/transformEditors/NumberEditor.svelte' -import ArrayCriteria from './components/criterias/ArrayCriteria.svelte' -import BooleanCriteria from './components/criterias/BooleanCriteria.svelte' -import DateCriteria from './components/criterias/DateCriteria.svelte' -import EnumCriteria from './components/criterias/EnumCriteria.svelte' -import NumberCriteria from './components/criterias/NumberCriteria.svelte' -import RefCriteria from './components/criterias/RefCriteria.svelte' -import StringCriteria from './components/criterias/StringCriteria.svelte' +import ArraySizeCriteria from './components/criterias/ArraySizeCriteria.svelte' +import BaseCriteria from './components/criterias/BaseCriteria.svelte' +import RangeCriteria from './components/criterias/RangeCriteria.svelte' import LogActionPresenter from './components/LogActionPresenter.svelte' import NotifierExtension from './components/NotifierExtension.svelte' import AddRelationPresenter from './components/presenters/AddRelationPresenter.svelte' @@ -139,13 +135,9 @@ export default async (): Promise => ({ ExecutionMyToDos }, criteriaEditor: { - DateCriteria, - StringCriteria, - BooleanCriteria, - NumberCriteria, - RefCriteria, - EnumCriteria, - ArrayCriteria + BaseCriteria, + ArraySizeCriteria, + RangeCriteria }, transformPresenter: { NumberPresenter, diff --git a/plugins/process-resources/src/plugin.ts b/plugins/process-resources/src/plugin.ts index 5570152def..91d29bad7f 100644 --- a/plugins/process-resources/src/plugin.ts +++ b/plugins/process-resources/src/plugin.ts @@ -72,13 +72,9 @@ export default mergeIds(processId, process, { AddTagPresenter: '' as AnyComponent }, criteriaEditor: { - StringCriteria: '' as AnyComponent, - NumberCriteria: '' as AnyComponent, - DateCriteria: '' as AnyComponent, - BooleanCriteria: '' as AnyComponent, - ArrayCriteria: '' as AnyComponent, - EnumCriteria: '' as AnyComponent, - RefCriteria: '' as AnyComponent + BaseCriteria: '' as AnyComponent, + RangeCriteria: '' as AnyComponent, + ArraySizeCriteria: '' as AnyComponent }, transformEditor: { MultiArrayElementEditor: '' as AnyComponent, diff --git a/plugins/process-resources/src/query.ts b/plugins/process-resources/src/query.ts index d93249d62e..f83d6be38b 100644 --- a/plugins/process-resources/src/query.ts +++ b/plugins/process-resources/src/query.ts @@ -13,7 +13,9 @@ import { type QuerySelector } from '@hcengineering/core' import { getEmbeddedLabel, type IntlString } from '@hcengineering/platform' +import { type AnyComponent } from '@hcengineering/ui' import view from '@hcengineering/view-resources/src/plugin' +import plugin from './plugin' export interface Mode { id: string @@ -21,6 +23,7 @@ export interface Mode { query: QuerySelector | string parse?: (value: any) => any withoutEditor?: boolean + editor?: AnyComponent } const Equal: Mode = { @@ -47,6 +50,17 @@ const LT: Mode = { query: { $lt: '$val' as any } } +const Between: Mode = { + id: 'between', + label: view.string.Between, + query: { $gte: '$val[0]' as any, $lte: '$val[1]' as any }, + parse: (value: any): any => { + if (!Array.isArray(value) || value.length !== 2) return value + return value + }, + editor: plugin.criteriaEditor.RangeCriteria +} + const Exists: Mode = { id: 'exists', label: view.string.ValueIsSet, @@ -85,40 +99,46 @@ const ArrayNotIncludes: Mode = { const ArraySizeEquals: Mode = { id: 'sizeEquals', label: getEmbeddedLabel('='), - query: { $size: '$val' as any } + query: { $size: '$val' as any }, + editor: plugin.criteriaEditor.ArraySizeCriteria } const ArraySizeGt: Mode = { id: 'sizeGt', label: getEmbeddedLabel('>'), - query: { $size: { $gt: '$val' as any } } + query: { $size: { $gt: '$val' as any } }, + editor: plugin.criteriaEditor.ArraySizeCriteria } const ArraySizeGte: Mode = { id: 'sizeGte', label: getEmbeddedLabel('≥'), - query: { $size: { $gte: '$val' as any } } + query: { $size: { $gte: '$val' as any } }, + editor: plugin.criteriaEditor.ArraySizeCriteria } const ArraySizeLt: Mode = { id: 'sizeLt', label: getEmbeddedLabel('<'), - query: { $size: { $lt: '$val' as any } } + query: { $size: { $lt: '$val' as any } }, + editor: plugin.criteriaEditor.ArraySizeCriteria } const ArraySizeLte: Mode = { id: 'sizeLte', label: getEmbeddedLabel('≤'), - query: { $size: { $lte: '$val' as any } } + query: { $size: { $lte: '$val' as any } }, + editor: plugin.criteriaEditor.ArraySizeCriteria } -export const Modes: Record = { +export const Modes = { Exists, Equal, NotEqual, StringContains, GT, LT, + Between, ArrayAll, ArrayAny, ArrayNotIncludes, @@ -129,6 +149,8 @@ export const Modes: Record = { ArraySizeLte } as const +export type ModeId = keyof typeof Modes + export function parseValue (modes: Mode[], value: any): [any, Mode] { if (value == null) { return [value, modes[0]] @@ -163,24 +185,20 @@ export function buildResult (mode: Mode, value: any): any { if (typeof q !== 'object') return value const result: any = {} let res = result - while (true) { - if (typeof q === 'object') { - const key = Object.keys(q)[0] - const v: any = (q as any)[key] - if (typeof v !== 'object') { - if (typeof value === 'string' && typeof v === 'string') { - res[key] = v.replace('$val', value) - } else { - res[key] = mode.withoutEditor === true ? v : value ?? v - } - return result + while (typeof q === 'object') { + const key = Object.keys(q)[0] + const v: any = (q as any)[key] + if (typeof v !== 'object') { + if (typeof value === 'string' && typeof v === 'string') { + res[key] = v.replace('$val', value) + } else { + res[key] = mode.withoutEditor === true ? v : value ?? v } - q = v - res[key] = {} - res = res[key] - } else { - break + return result } + q = v + res[key] = {} + res = res[key] } return result } diff --git a/plugins/process-resources/src/utils.ts b/plugins/process-resources/src/utils.ts index 0c274f9559..cbea58cc6d 100644 --- a/plugins/process-resources/src/utils.ts +++ b/plugins/process-resources/src/utils.ts @@ -50,9 +50,10 @@ import { type Step, type StepId, type Transition, + type UpdateCriteriaComponent, type UserResult } from '@hcengineering/process' -import { type AnyComponent, showPopup } from '@hcengineering/ui' +import { showPopup } from '@hcengineering/ui' import { type AttributeCategory } from '@hcengineering/view' import process from './plugin' @@ -638,17 +639,20 @@ export async function subProcessesDoneCheck ( return res === undefined } -export function getCirteriaEditor (of: Ref>, category: AttributeCategory): AnyComponent | undefined { +export function getCirteriaEditor ( + of: Ref>, + category: AttributeCategory +): UpdateCriteriaComponent | undefined { const client = getClient() if (category !== 'attribute') { const res = client.getModel().findAllSync(process.class.UpdateCriteriaComponent, { category })[0] - return res?.editor + return res } const res = client.getModel().findAllSync(process.class.UpdateCriteriaComponent, { category, of })[0] - return res?.editor + return res } diff --git a/plugins/process/src/index.ts b/plugins/process/src/index.ts index 0b2d45d20c..93018c79a5 100644 --- a/plugins/process/src/index.ts +++ b/plugins/process/src/index.ts @@ -188,6 +188,7 @@ export interface UpdateCriteriaComponent extends Doc { category: AttributeCategory editor: AnyComponent of: Ref> + props: Record } export * from './errors'