mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-10 19:57:43 +02:00
Merge branch 'develop' of https://github.com/hcengineering/platform into staging-new
Signed-off-by: Artem Savchenko <armisav@gmail.com>
This commit is contained in:
@@ -969,4 +969,6 @@ jobs:
|
||||
run: |
|
||||
REF="${{ github.event.inputs.ref || github.ref }}"
|
||||
VERSION="${REF#refs/tags/v}"
|
||||
node common/scripts/bump.js "$VERSION" --publish
|
||||
VERSION="${VERSION#v}"
|
||||
node common/scripts/bump.js "$VERSION"
|
||||
node common/scripts/safe-publish.js
|
||||
|
||||
@@ -2,6 +2,16 @@
|
||||
|
||||
Changelog.
|
||||
|
||||
## [0.7.375] - 2026-02-23
|
||||
|
||||
* 🚀 FEATURES: · Add activity section in controlled doc ([#10457](https://github.com/hcengineering/platform/issues/10457)) · Add data converter plugin ([#10460](https://github.com/hcengineering/platform/issues/10460)) · *(ui)* Add Turkish language to settings popup ([#10441](https://github.com/hcengineering/platform/issues/10441)) · Turkish language in dev setup ([#10462](https://github.com/hcengineering/platform/issues/10462)) · Add import notifications ([#10464](https://github.com/hcengineering/platform/issues/10464)) · Guest users to upload attachments and use reactions ([#10469](https://github.com/hcengineering/platform/issues/10469)) · Add activity input for controlled docs ([#10470](https://github.com/hcengineering/platform/issues/10470)) · Ability to select multiple docs and to export to pdf ([#10468](https://github.com/hcengineering/platform/issues/10468)) · Headers legibility ([#10473](https://github.com/hcengineering/platform/issues/10473)) · Brazilian Portuguese translation ([#10478](https://github.com/hcengineering/platform/issues/10478)) · Add drive permissions ([#10489](https://github.com/hcengineering/platform/issues/10489)) · Add unlock card and section functionality with UI updates ([#10492](https://github.com/hcengineering/platform/issues/10492)) · To define different viewlet actions ([#10502](https://github.com/hcengineering/platform/issues/10502)) · Add ability to copy all data from cards/docs tables ([#10505](https://github.com/hcengineering/platform/issues/10505)) · Redesign workspace join ([#10507](https://github.com/hcengineering/platform/issues/10507)) · For guests to update notification settings ([#10517](https://github.com/hcengineering/platform/issues/10517)) · Add project breadcrumb ([#10515](https://github.com/hcengineering/platform/issues/10515)) · Implement process import/export functionality, enhance process … ([#10528](https://github.com/hcengineering/platform/issues/10528)) · Implement CancelSubProcess action, fix process execution flow. ([#10530](https://github.com/hcengineering/platform/issues/10530)) · Add ability to group by issues by project ([#10531](https://github.com/hcengineering/platform/issues/10531))
|
||||
* 🐛 BUG FIXES: · Okit.graphql is not a function ([#10442](https://github.com/hcengineering/platform/issues/10442)) · Custom attributes in markdown table ([#10445](https://github.com/hcengineering/platform/issues/10445)) · Relationship table diff/refresh ([#10446](https://github.com/hcengineering/platform/issues/10446)) · Handle youtu.be links ([#10458](https://github.com/hcengineering/platform/issues/10458)) · Calendar timezone day-shift bug ([#7048](https://github.com/hcengineering/platform/issues/7048)) ([#10459](https://github.com/hcengineering/platform/issues/10459)) · Mute account unauthorized error ([#10461](https://github.com/hcengineering/platform/issues/10461)) · Do not write analytics event when no token ([#10463](https://github.com/hcengineering/platform/issues/10463)) · Documents space export ([#10465](https://github.com/hcengineering/platform/issues/10465)) · Print layout ([#10472](https://github.com/hcengineering/platform/issues/10472)) · Use the error logging level for expected situations ([#10474](https://github.com/hcengineering/platform/issues/10474)) · Allow to open mermaid diagram in fullscreen ([#10477](https://github.com/hcengineering/platform/issues/10477)) · Rows order in relationsheep table compare ([#10479](https://github.com/hcengineering/platform/issues/10479)) · Custom attributes display in original view ([#10480](https://github.com/hcengineering/platform/issues/10480)) · Card formatting in markdown ([#10475](https://github.com/hcengineering/platform/issues/10475)) · Proper mermaid diagram size ([#10487](https://github.com/hcengineering/platform/issues/10487)) · Embed pdf via direct link ([#10491](https://github.com/hcengineering/platform/issues/10491)) · Secure blobs ([#10490](https://github.com/hcengineering/platform/issues/10490)) · Relationship table refresh ([#10494](https://github.com/hcengineering/platform/issues/10494)) · Issues layout ([#10498](https://github.com/hcengineering/platform/issues/10498)) · Exception during github issue id reading ([#10500](https://github.com/hcengineering/platform/issues/10500)) · Email notifications for export ([#10506](https://github.com/hcengineering/platform/issues/10506)) · Prevent datalake from error flood ([#10521](https://github.com/hcengineering/platform/issues/10521)) · Brazilian Portuguese translation ([#10522](https://github.com/hcengineering/platform/issues/10522)) · Datalake in dev setup does not support secure mode ([#10525](https://github.com/hcengineering/platform/issues/10525)) · Date formatting in md table ([#10523](https://github.com/hcengineering/platform/issues/10523)) · Bump with foundation packages ([#10536](https://github.com/hcengineering/platform/issues/10536)) · Process ([#10543](https://github.com/hcengineering/platform/issues/10543))
|
||||
* 🚜 REFACTOR: · One metadata interface ([#10444](https://github.com/hcengineering/platform/issues/10444))
|
||||
* ⚙️ MISCELLANEOUS TASKS: · Changelog · Changelog ([#10439](https://github.com/hcengineering/platform/issues/10439)) · Mail URL from export pod ([#10476](https://github.com/hcengineering/platform/issues/10476)) · Etc/hosts path for Windows ([#10482](https://github.com/hcengineering/platform/issues/10482)) · Space security and permissions ([#10529](https://github.com/hcengineering/platform/issues/10529)) · Kvs and pulse versions ([#10539](https://github.com/hcengineering/platform/issues/10539)) · And publish npm packages for v tags ([#10542](https://github.com/hcengineering/platform/issues/10542))
|
||||
* FIX: · Images not rendering on GitHub side of GitHub integration ([#10520](https://github.com/hcengineering/platform/issues/10520)) · Show print actions for individual documents ([#10484](https://github.com/hcengineering/platform/issues/10484)) · Password signup crashes with JSON parse error when MAIL_URL is configured ([#10519](https://github.com/hcengineering/platform/issues/10519))
|
||||
* QFIX: · Allow notifications for guests with collab security ([#10510](https://github.com/hcengineering/platform/issues/10510))
|
||||
* QFIX: · Remove unused ui dependencies ([#10511](https://github.com/hcengineering/platform/issues/10511))
|
||||
|
||||
## [0.7.353] - 2026-01-24
|
||||
|
||||
* 🚀 FEATURES: · Link preview service ([#10424](https://github.com/hcengineering/platform/issues/10424)) · Add confirmation modal for table refresh ([#10428](https://github.com/hcengineering/platform/issues/10428)) · Guest update profile (avatar, name etc) ([#10429](https://github.com/hcengineering/platform/issues/10429))
|
||||
|
||||
@@ -43,8 +43,24 @@ function checkPackageExists(packageName, version) {
|
||||
*/
|
||||
function getPublishablePackages(includePattern) {
|
||||
try {
|
||||
const output = execSync('rush list -p --json', { encoding: 'utf-8' })
|
||||
const config = JSON.parse(output)
|
||||
const repoRoot = execSync('git rev-parse --show-toplevel', { encoding: 'utf-8' }).trim()
|
||||
const output = execSync('node common/scripts/install-run-rush.js list -p --json', {
|
||||
encoding: 'utf-8',
|
||||
cwd: repoRoot
|
||||
})
|
||||
const lines = output.split('\n')
|
||||
let jsonStart = -1
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
if (lines[i].trim().startsWith('{')) {
|
||||
jsonStart = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if (jsonStart === -1) {
|
||||
console.error('Could not find JSON output from rush list')
|
||||
return []
|
||||
}
|
||||
const config = JSON.parse(lines.slice(jsonStart).join('\n'))
|
||||
|
||||
return config.projects.filter((project) => {
|
||||
// Check if package should be published according to rush.json
|
||||
|
||||
@@ -436,7 +436,10 @@ export abstract class TxProcessor implements WithTx {
|
||||
}
|
||||
|
||||
static txHasUpdate<T extends Doc>(tx: TxUpdateDoc<T>, attribute: string): boolean {
|
||||
const ops = tx.operations
|
||||
return TxProcessor.hasUpdate(tx.operations, attribute)
|
||||
}
|
||||
|
||||
static hasUpdate<T extends Doc>(ops: DocumentUpdate<T>, attribute: string): boolean {
|
||||
if ((ops as any)[attribute] !== undefined) return true
|
||||
for (const op in ops) {
|
||||
if (op.startsWith('$')) {
|
||||
|
||||
@@ -103,6 +103,9 @@ export class TProcess extends TDoc implements Process {
|
||||
@Prop(TypeBoolean(), process.string.StartAutomatically)
|
||||
autoStart: boolean | undefined
|
||||
|
||||
@Prop(TypeBoolean(), process.string.AutomationOnly)
|
||||
automationOnly: boolean | undefined
|
||||
|
||||
context!: Record<ContextId, ProcessContext>
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
<!--
|
||||
// Copyright © 2026 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 { onDestroy } from 'svelte'
|
||||
import EmbeddedPDF from './EmbeddedPDF.svelte'
|
||||
import Loading from './Loading.svelte'
|
||||
|
||||
export let src: string
|
||||
export let name: string
|
||||
export let fit: boolean = false
|
||||
export let css: string | undefined = undefined
|
||||
|
||||
let iframeSrc: string | undefined
|
||||
|
||||
async function loadFile (src: string): Promise<void> {
|
||||
if (iframeSrc !== undefined) {
|
||||
URL.revokeObjectURL(iframeSrc)
|
||||
iframeSrc = undefined
|
||||
}
|
||||
|
||||
const response = await fetch(src)
|
||||
const blob = await response.blob()
|
||||
iframeSrc = URL.createObjectURL(blob)
|
||||
}
|
||||
|
||||
$: void loadFile(src)
|
||||
|
||||
onDestroy(() => {
|
||||
if (iframeSrc !== undefined) {
|
||||
URL.revokeObjectURL(iframeSrc)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
{#if iframeSrc}
|
||||
<EmbeddedPDF src={iframeSrc} {name} {fit} {css} />
|
||||
{:else}
|
||||
<Loading />
|
||||
{/if}
|
||||
@@ -284,6 +284,7 @@ export { default as CodeForm } from './components/CodeForm.svelte'
|
||||
export { default as CodeInput } from './components/CodeInput.svelte'
|
||||
export { default as TimeLeft } from './components/TimeLeft.svelte'
|
||||
export { default as SectionEmpty } from './components/SectionEmpty.svelte'
|
||||
export { default as EmbeddedHTML } from './components/EmbeddedHTML.svelte'
|
||||
export { default as EmbeddedPDF } from './components/EmbeddedPDF.svelte'
|
||||
export { default as NestedMenu } from './components/NestedMenu.svelte'
|
||||
export { default as NestedDropdown } from './components/NestedDropdown.svelte'
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
import { getMetadata } from '@hcengineering/platform'
|
||||
import presentation, { getFileUrl } from '@hcengineering/presentation'
|
||||
import { convertToHTML } from '@hcengineering/print'
|
||||
import { EmbeddedPDF, Spinner, themeStore } from '@hcengineering/ui'
|
||||
import { EmbeddedHTML, Spinner, themeStore } from '@hcengineering/ui'
|
||||
|
||||
export let value: Ref<Blob>
|
||||
export let name: string
|
||||
@@ -270,7 +270,7 @@
|
||||
<Spinner size="medium" />
|
||||
</div>
|
||||
{:else}
|
||||
<EmbeddedPDF {src} {name} {css} />
|
||||
<EmbeddedHTML {src} {name} {css} />
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
"Required": "Povinné",
|
||||
"ParallelExecutionForbidden": "Nedovoluj paralelní spuštění",
|
||||
"StartAutomatically": "Spustit automaticky",
|
||||
"AutomationOnly": "Pouze automatizace",
|
||||
"Error": "Chyba",
|
||||
"Continue": "Pokračovat",
|
||||
"RequestFromUser": "Požádat uživatele",
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
"Required": "Erforderlich",
|
||||
"ParallelExecutionForbidden": "Parallele Ausführung verboten",
|
||||
"StartAutomatically": "Automatisch starten",
|
||||
"AutomationOnly": "Nur Automatisierung",
|
||||
"Error": "Fehler",
|
||||
"Continue": "Fortsetzen",
|
||||
"RequestFromUser": "Anfrage von Benutzer",
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
"Required": "Required",
|
||||
"ParallelExecutionForbidden": "Parallel execution forbidden",
|
||||
"StartAutomatically": "Start automatically",
|
||||
"AutomationOnly": "Automation only",
|
||||
"Error": "Error",
|
||||
"Continue": "Continue",
|
||||
"RequestFromUser": "Request from user",
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
"Required": "Requerido",
|
||||
"ParallelExecutionForbidden": "Ejecución paralela prohibida",
|
||||
"StartAutomatically": "Iniciar automáticamente",
|
||||
"AutomationOnly": "Solo automatización",
|
||||
"Error": "Error",
|
||||
"Continue": "Continuar",
|
||||
"RequestFromUser": "Solicitar desde el usuario",
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
"Required": "Requis",
|
||||
"ParallelExecutionForbidden": "Exécution parallèle interdite",
|
||||
"StartAutomatically": "Démarrer automatiquement",
|
||||
"AutomationOnly": "Automatisation uniquement",
|
||||
"Error": "Erreur",
|
||||
"Continue": "Continuer",
|
||||
"RequestFromUser": "Demander à partir de l'utilisateur",
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
"Required": "Obbligatorio",
|
||||
"ParallelExecutionForbidden": "Esecuzione parallela vietata",
|
||||
"StartAutomatically": "Avvia automaticamente",
|
||||
"AutomationOnly": "Solo automazione",
|
||||
"Error": "Errore",
|
||||
"Continue": "Continua",
|
||||
"RequestFromUser": "Richiedi da utente",
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
"Required": "必須",
|
||||
"ParallelExecutionForbidden": "並列実行は禁止されています",
|
||||
"StartAutomatically": "自動的に開始",
|
||||
"AutomationOnly": "自動化のみ",
|
||||
"Error": "エラー",
|
||||
"Continue": "続行",
|
||||
"RequestFromUser": "ユーザーからのリクエスト",
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
"Required": "Obrigatório",
|
||||
"ParallelExecutionForbidden": "Execução Paralela Proibida",
|
||||
"StartAutomatically": "Iniciar automaticamente",
|
||||
"AutomationOnly": "Apenas automação",
|
||||
"Error": "Erro",
|
||||
"Continue": "Continuar",
|
||||
"RequestFromUser": "Solicitar do usuário",
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
"Required": "Obrigatório",
|
||||
"ParallelExecutionForbidden": "Execução Paralela Proibida",
|
||||
"StartAutomatically": "Iniciar automaticamente",
|
||||
"AutomationOnly": "Apenas automação",
|
||||
"Error": "Erro",
|
||||
"Continue": "Continuar",
|
||||
"RequestFromUser": "Solicitar do usuário",
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
"Required": "Обязательно",
|
||||
"ParallelExecutionForbidden": "Одновременное выполнение запрещено",
|
||||
"StartAutomatically": "Запускать автоматически",
|
||||
"AutomationOnly": "Только автоматизация",
|
||||
"Error": "Ошибка",
|
||||
"Continue": "Продолжить",
|
||||
"RequestFromUser": "Запросить у пользователя",
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
"Required": "Gerekli",
|
||||
"ParallelExecutionForbidden": "Paralel yürütme yasak",
|
||||
"StartAutomatically": "Otomatik başlat",
|
||||
"AutomationOnly": "Sadece otomasyon",
|
||||
"Error": "Hata",
|
||||
"Continue": "Devam et",
|
||||
"RequestFromUser": "Kullanıcıdan talep et",
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
"Required": "必需",
|
||||
"ParallelExecutionForbidden": "禁止并行执行",
|
||||
"StartAutomatically": "自动启动",
|
||||
"AutomationOnly": "仅限自动化",
|
||||
"Error": "错误",
|
||||
"Continue": "继续",
|
||||
"RequestFromUser": "从用户请求",
|
||||
|
||||
@@ -30,7 +30,10 @@
|
||||
let process: Ref<Process> | undefined = value
|
||||
let card: Card | undefined
|
||||
|
||||
const processes = client.getModel().findAllSync(plugin.class.Process, {})
|
||||
const processes = client
|
||||
.getModel()
|
||||
.findAllSync(plugin.class.Process, {})
|
||||
.filter((p) => p.automationOnly !== true)
|
||||
|
||||
const items: ListItem[] = processes.map((p) => ({ label: p.name, _id: p._id }))
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
const resClasses = getPossibleClasses()
|
||||
|
||||
const res = client.getModel().findAllSync(process.class.Process, {})
|
||||
const processes = res.filter((it) => resClasses.includes(it.masterTag))
|
||||
const processes = res.filter((it) => resClasses.includes(it.masterTag) && it.automationOnly !== true)
|
||||
|
||||
function getCardPossibleClasses (card: Card): Ref<Class<Doc>>[] {
|
||||
const asc = h.getAncestors(card._class)
|
||||
|
||||
@@ -35,6 +35,12 @@
|
||||
await client.update(value, { autoStart: e.detail })
|
||||
}
|
||||
}
|
||||
|
||||
async function saveAutomationOnly (e: CustomEvent<boolean>): Promise<void> {
|
||||
if (value !== undefined) {
|
||||
await client.update(value, { automationOnly: e.detail })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<Card
|
||||
@@ -54,5 +60,16 @@
|
||||
label={process.string.ParallelExecutionForbidden}
|
||||
/>
|
||||
</div>
|
||||
<ToggleWithLabel on={value.autoStart ?? false} on:change={saveAutoStart} label={process.string.StartAutomatically} />
|
||||
<div class="mb-2">
|
||||
<ToggleWithLabel
|
||||
on={value.autoStart ?? false}
|
||||
on:change={saveAutoStart}
|
||||
label={process.string.StartAutomatically}
|
||||
/>
|
||||
</div>
|
||||
<ToggleWithLabel
|
||||
on={value.automationOnly ?? false}
|
||||
on:change={saveAutomationOnly}
|
||||
label={process.string.AutomationOnly}
|
||||
/>
|
||||
</Card>
|
||||
|
||||
@@ -1,21 +1,37 @@
|
||||
import { type MasterTag } from '@hcengineering/card'
|
||||
import core, { type Doc, type Ref, type Class, generateId } from '@hcengineering/core'
|
||||
import card from '@hcengineering/card'
|
||||
import core, {
|
||||
type Doc,
|
||||
type Ref,
|
||||
type Class,
|
||||
generateId,
|
||||
type EnumOf,
|
||||
type RefTo,
|
||||
type ArrOf,
|
||||
type ModelDb,
|
||||
type Hierarchy
|
||||
} from '@hcengineering/core'
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
import process from './plugin'
|
||||
import { type Process, type Transition } from '@hcengineering/process'
|
||||
import processPlugin from './plugin'
|
||||
|
||||
export function exportProcesses (_id: Ref<MasterTag>): {
|
||||
docs: Doc[]
|
||||
required: Array<Ref<Class<Doc>>>
|
||||
} {
|
||||
const docs: Doc[] = []
|
||||
const required: Array<Ref<Class<Doc>>> = []
|
||||
const client = getClient()
|
||||
const m = client.getModel()
|
||||
const processes = m.findAllSync(process.class.Process, { masterTag: _id })
|
||||
const processes = m.findAllSync(processPlugin.class.Process, { masterTag: _id })
|
||||
for (const proc of processes) {
|
||||
const res = exportProcess(proc)
|
||||
docs.push(...res.docs)
|
||||
for (const req of res.required) {
|
||||
if (!required.includes(req)) required.push(req)
|
||||
}
|
||||
}
|
||||
return { docs, required: [] }
|
||||
return { docs, required }
|
||||
}
|
||||
|
||||
export function exportProcess (proc: Doc): {
|
||||
@@ -23,13 +39,84 @@ export function exportProcess (proc: Doc): {
|
||||
required: Array<Ref<Class<Doc>>>
|
||||
} {
|
||||
const docs: Doc[] = [proc]
|
||||
const required: Array<Ref<Class<Doc>>> = []
|
||||
const client = getClient()
|
||||
const m = client.getModel()
|
||||
const h = client.getHierarchy()
|
||||
|
||||
docs.push(...m.findAllSync(process.class.State, { process: proc._id as any }))
|
||||
docs.push(...m.findAllSync(process.class.Transition, { process: proc._id as any }))
|
||||
docs.push(...m.findAllSync(processPlugin.class.State, { process: proc._id as any }))
|
||||
const transitions = m.findAllSync(processPlugin.class.Transition, { process: proc._id as any }) as Transition[]
|
||||
docs.push(...transitions)
|
||||
|
||||
return { docs, required: [] }
|
||||
const processDoc = proc as Process
|
||||
|
||||
for (const tr of transitions) {
|
||||
processParams(tr.triggerParams, processDoc.masterTag, docs, required, m, h)
|
||||
for (const action of tr.actions) {
|
||||
processParams(action.params, processDoc.masterTag, docs, required, m, h)
|
||||
}
|
||||
}
|
||||
|
||||
return { docs, required }
|
||||
}
|
||||
|
||||
function processParams (
|
||||
params: Record<string, any> | undefined,
|
||||
masterTag: Ref<MasterTag>,
|
||||
docs: Doc[],
|
||||
required: Array<Ref<Class<Doc>>>,
|
||||
m: ModelDb,
|
||||
h: Hierarchy
|
||||
): void {
|
||||
if (params === undefined) return
|
||||
for (const key in params) {
|
||||
if (key.startsWith('$')) {
|
||||
const val = params[key]
|
||||
if (Array.isArray(val)) {
|
||||
for (const item of val) {
|
||||
if (typeof item === 'object' && item !== null) {
|
||||
processParams(item, masterTag, docs, required, m, h)
|
||||
}
|
||||
}
|
||||
} else if (typeof val === 'object' && val !== null) {
|
||||
processParams(val, masterTag, docs, required, m, h)
|
||||
}
|
||||
continue
|
||||
}
|
||||
const attr = h.findAttribute(masterTag, key)
|
||||
if (attr !== undefined) {
|
||||
const type = attr.type
|
||||
if (type._class === core.class.EnumOf) {
|
||||
const enumRef = (type as EnumOf).of
|
||||
const enumDoc = m.findObject(enumRef)
|
||||
if (enumDoc !== undefined && !docs.some((d) => d._id === enumDoc._id)) {
|
||||
docs.push(enumDoc)
|
||||
}
|
||||
}
|
||||
if (type._class === core.class.RefTo) {
|
||||
const to = (type as RefTo<Doc>).to
|
||||
if (h.isDerived(to, card.class.Card) && !required.includes(to)) {
|
||||
required.push(to)
|
||||
}
|
||||
}
|
||||
if (type._class === core.class.ArrOf) {
|
||||
const of = (type as ArrOf<Doc>).of
|
||||
if (of._class === core.class.EnumOf) {
|
||||
const enumRef = (of as EnumOf).of
|
||||
const enumDoc = m.findObject(enumRef)
|
||||
if (enumDoc !== undefined && !docs.some((d) => d._id === enumDoc._id)) {
|
||||
docs.push(enumDoc)
|
||||
}
|
||||
}
|
||||
if (of._class === core.class.RefTo) {
|
||||
const to = (of as RefTo<Doc>).to
|
||||
if (h.isDerived(to, card.class.Card) && !required.includes(to)) {
|
||||
required.push(to)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function importProcess (masterTag: Ref<MasterTag>, json: string): Promise<void> {
|
||||
|
||||
@@ -181,6 +181,7 @@ export default mergeIds(processId, process, {
|
||||
Required: '' as IntlString,
|
||||
ParallelExecutionForbidden: '' as IntlString,
|
||||
StartAutomatically: '' as IntlString,
|
||||
AutomationOnly: '' as IntlString,
|
||||
Continue: '' as IntlString,
|
||||
RequestFromUser: '' as IntlString,
|
||||
EnterValue: '' as IntlString,
|
||||
|
||||
@@ -20,12 +20,14 @@ import core, {
|
||||
type Client,
|
||||
type Doc,
|
||||
type DocumentQuery,
|
||||
type DocumentUpdate,
|
||||
generateId,
|
||||
matchQuery,
|
||||
type Ref,
|
||||
type RefTo,
|
||||
type Space,
|
||||
type TxOperations,
|
||||
TxProcessor,
|
||||
type Type
|
||||
} from '@hcengineering/core'
|
||||
import { getResource, type IntlString, PlatformError, Severity, Status } from '@hcengineering/platform'
|
||||
@@ -207,9 +209,9 @@ export function getContext (
|
||||
}
|
||||
}
|
||||
const allRelations = client.getModel().findAllSync(core.class.Association, {})
|
||||
const descendants = new Set(client.getHierarchy().getDescendants(process.masterTag))
|
||||
const ancestors = new Set(client.getHierarchy().getAncestors(process.masterTag))
|
||||
|
||||
const relationsA = allRelations.filter((it) => descendants.has(it.classA))
|
||||
const relationsA = allRelations.filter((it) => ancestors.has(it.classA))
|
||||
for (const rel of relationsA) {
|
||||
if (['object', 'array'].includes(category) && client.getHierarchy().isDerived(rel.classB, target)) {
|
||||
relations[rel.nameB] = {
|
||||
@@ -231,7 +233,7 @@ export function getContext (
|
||||
}
|
||||
}
|
||||
|
||||
const relationsB = allRelations.filter((it) => descendants.has(it.classB))
|
||||
const relationsB = allRelations.filter((it) => ancestors.has(it.classB))
|
||||
for (const rel of relationsB) {
|
||||
if (['object', 'array'].includes(category) && client.getHierarchy().isDerived(rel.classA, target)) {
|
||||
relations[rel.nameA] = {
|
||||
@@ -683,8 +685,9 @@ export function fieldChangesCheck (
|
||||
): boolean {
|
||||
const doc = context.card
|
||||
if (doc === undefined) return false
|
||||
const param = Object.keys(params)[0]
|
||||
if (!Object.keys(context.operations ?? {}).includes(param)) return false
|
||||
const operations = (context.operations ?? {}) as DocumentUpdate<Doc>
|
||||
const target = Object.keys(params)[0]
|
||||
if (!TxProcessor.hasUpdate(operations, target)) return false
|
||||
const res = matchQuery([doc], params, doc._class, client.getHierarchy(), true)
|
||||
return res.length > 0
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ export interface Process extends Doc {
|
||||
description: string
|
||||
parallelExecutionForbidden?: boolean
|
||||
autoStart?: boolean
|
||||
automationOnly?: boolean
|
||||
context: Record<ContextId, ProcessContext>
|
||||
resultType?: Type<any>
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import core, {
|
||||
Class,
|
||||
Data,
|
||||
Doc,
|
||||
DocumentUpdate,
|
||||
fillDefaults,
|
||||
findProperty,
|
||||
generateId,
|
||||
@@ -169,9 +170,9 @@ export function FieldChangedCheck (
|
||||
const process = control.client.getModel().findObject(execution.process)
|
||||
if (process === undefined) return false
|
||||
if (context.operations === undefined) return false
|
||||
const changedFields = Object.keys(context.operations)
|
||||
const operations = context.operations as DocumentUpdate<Doc>
|
||||
const target = Object.keys(params)[0]
|
||||
if (!changedFields.includes(target)) return false
|
||||
if (!TxProcessor.hasUpdate(operations, target)) return false
|
||||
const res = matchQuery([context.card], params, process.masterTag, control.client.getHierarchy(), true)
|
||||
return res.length > 0
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user