From 49a2edf19ed7f6fc5576ff100ae8cec4702be9e6 Mon Sep 17 00:00:00 2001 From: Artyom Savchenko Date: Mon, 20 Apr 2026 13:06:57 +0700 Subject: [PATCH 1/3] Fix tracker project actions (#10786) * Fix tracker project actions Signed-off-by: Artem Savchenko * Revert "Fix tracker project actions" This reverts commit 586c6562bd50674d3fb49bdbbbc95ada0311cf11. * Convert docs for all actions Signed-off-by: Artem Savchenko * Clean up Signed-off-by: Artem Savchenko * Clean up Signed-off-by: Artem Savchenko --------- Signed-off-by: Artem Savchenko --- plugins/view-resources/src/actions.ts | 16 ++++++++++++++-- .../src/components/ActionsPopup.svelte | 4 ++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/plugins/view-resources/src/actions.ts b/plugins/view-resources/src/actions.ts index 3c0cbc5d1e..6a7d291573 100644 --- a/plugins/view-resources/src/actions.ts +++ b/plugins/view-resources/src/actions.ts @@ -41,6 +41,18 @@ import view from './plugin' import { type FocusSelection, type SelectionStore } from './selection' import { restrictionStore } from './utils' +/** + * Collapses a single-element array to the element, otherwise returns the original value. + * + * @public + */ +export function normalizeActionContext (doc: T | T[] | undefined): T | T[] | undefined { + if (Array.isArray(doc) && doc.length === 1) { + return doc[0] + } + return doc +} + /** * @public */ @@ -114,7 +126,7 @@ export async function filterAvailableActions ( } else { const visibilityTester = await getResource(action.visibilityTester) - if (await visibilityTester(doc)) { + if (await visibilityTester(normalizeActionContext(doc))) { result.push(action) } } @@ -132,7 +144,7 @@ export async function invokeAction ( ): Promise { const impl = await getResource(action.action) Analytics.handleEvent(action.analyticsEvent ?? action._id) - await impl(Array.isArray(object) && object.length === 1 ? object[0] : object, evt, { + await impl(normalizeActionContext(object), evt, { ...action.actionProps, ...props }) diff --git a/plugins/view-resources/src/components/ActionsPopup.svelte b/plugins/view-resources/src/components/ActionsPopup.svelte index 8719fa8206..0b11ffed81 100644 --- a/plugins/view-resources/src/components/ActionsPopup.svelte +++ b/plugins/view-resources/src/components/ActionsPopup.svelte @@ -51,7 +51,7 @@ } from '@hcengineering/ui' import { Action, ActionCategory, ViewContext } from '@hcengineering/view' import { createEventDispatcher, onMount, tick } from 'svelte' - import { filterActions, getSelection } from '../actions' + import { filterActions, getSelection, normalizeActionContext } from '../actions' import view from '../plugin' import { focusStore, selectionStore } from '../selection' import { openDoc } from '../utils' @@ -99,7 +99,7 @@ } else { const visibilityTester = await getResource(action.visibilityTester) - if (await visibilityTester(docs)) { + if (await visibilityTester(normalizeActionContext(docs))) { resultActions.push(action) } } From 99eafbf8bb7ac5da6f15f674aed1c27afc6f20c9 Mon Sep 17 00:00:00 2001 From: Artyom Savchenko Date: Mon, 20 Apr 2026 13:07:25 +0700 Subject: [PATCH 2/3] Fix training question actions (#10780) * Fix training actions Signed-off-by: Artem Savchenko * Formatting Signed-off-by: Artem Savchenko --------- Signed-off-by: Artem Savchenko --- common/config/rush/pnpm-lock.yaml | 3 ++ models/all/src/index.ts | 4 +-- models/questions/package.json | 1 + models/questions/src/index.ts | 11 +++++- models/view/src/index.ts | 36 ++++++++++--------- .../src/components/QuestionsItemEditor.svelte | 7 ---- plugins/view/src/index.ts | 3 +- 7 files changed, 38 insertions(+), 27 deletions(-) diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 9fa0051bfd..5f1981eebd 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -9666,6 +9666,9 @@ importers: '@hcengineering/model-core': specifier: workspace:^0.7.0 version: link:../core + '@hcengineering/model-print': + specifier: workspace:^0.7.0 + version: link:../print '@hcengineering/model-tracker': specifier: workspace:^0.7.0 version: link:../tracker diff --git a/models/all/src/index.ts b/models/all/src/index.ts index 47cb2ed9fa..e41b28a9da 100644 --- a/models/all/src/index.ts +++ b/models/all/src/index.ts @@ -428,9 +428,9 @@ export default function buildModel (): Builder { questionsId, { label: setting.string.Configure, - enabled: false, + enabled: true, beta: false, - hidden: true, + hidden: false, classFilter: defaultFilter } ], diff --git a/models/questions/package.json b/models/questions/package.json index 26b4f9af82..4f6c6e3882 100644 --- a/models/questions/package.json +++ b/models/questions/package.json @@ -44,6 +44,7 @@ "@hcengineering/model-core": "workspace:^0.7.0", "@hcengineering/model-tracker": "workspace:^0.7.0", "@hcengineering/model-view": "workspace:^0.7.0", + "@hcengineering/model-print": "workspace:^0.7.0", "@hcengineering/platform": "workspace:^0.7.20", "@hcengineering/view": "workspace:^0.7.0" } diff --git a/models/questions/src/index.ts b/models/questions/src/index.ts index 77f04ecd59..7baefe38b3 100644 --- a/models/questions/src/index.ts +++ b/models/questions/src/index.ts @@ -24,6 +24,7 @@ import { type Builder } from '@hcengineering/model' import core from '@hcengineering/model-core' import tracker from '@hcengineering/model-tracker' import view, { createAction } from '@hcengineering/model-view' +import print from '@hcengineering/model-print' import { TAnswer, TAssessment, @@ -215,7 +216,15 @@ function defineActions (builder: Builder): void { ) builder.mixin(questions.class.Question, core.class.Class, view.mixin.IgnoreActions, { - actions: [view.action.Open, view.action.OpenInNewTab, view.action.Delete, tracker.action.NewRelatedIssue] + actions: [ + view.action.Open, + view.action.OpenInNewTab, + view.action.Delete, + tracker.action.NewRelatedIssue, + view.action.CopyLink, + view.action.AddRelation, + print.action.Print + ] }) createAction( diff --git a/models/view/src/index.ts b/models/view/src/index.ts index d0afec43fc..d8670ffb18 100644 --- a/models/view/src/index.ts +++ b/models/view/src/index.ts @@ -890,24 +890,28 @@ export function createModel (builder: Builder): void { view.action.Join ) - createAction(builder, { - action: view.actionImpl.ShowPopup, - actionProps: { - component: view.component.AddRelationPopup, - fillProps: { - _objects: 'value' + createAction( + builder, + { + action: view.actionImpl.ShowPopup as ViewAction>, + actionProps: { + component: view.component.AddRelationPopup, + fillProps: { + _objects: 'value' + } + }, + label: core.string.AddRelation, + input: 'any', + icon: view.icon.CopyLink, + category: view.category.Editor, + target: core.class.Doc, + context: { + mode: ['context', 'browser'], + group: 'associate' } }, - label: core.string.AddRelation, - input: 'any', - icon: view.icon.CopyLink, - category: view.category.Editor, - target: core.class.Doc, - context: { - mode: ['context', 'browser'], - group: 'associate' - } - }) + view.action.AddRelation + ) createAction( builder, diff --git a/plugins/questions-resources/src/components/QuestionsItemEditor.svelte b/plugins/questions-resources/src/components/QuestionsItemEditor.svelte index e08a69c951..5d7d7205af 100644 --- a/plugins/questions-resources/src/components/QuestionsItemEditor.svelte +++ b/plugins/questions-resources/src/components/QuestionsItemEditor.svelte @@ -134,10 +134,3 @@ {/await} {/if} - - diff --git a/plugins/view/src/index.ts b/plugins/view/src/index.ts index efb4a29923..d6fd373e20 100644 --- a/plugins/view/src/index.ts +++ b/plugins/view/src/index.ts @@ -163,7 +163,8 @@ const view = plugin(viewId, { RemoveRelation: '' as Ref, CopyLink: '' as Ref>, - CopyDocumentMarkdown: '' as Ref> + CopyDocumentMarkdown: '' as Ref>, + AddRelation: '' as Ref> }, viewlet: { Table: '' as Ref, From f885bf90e0e3cbaf66ef431469e6331c0c79663b Mon Sep 17 00:00:00 2001 From: Artyom Savchenko Date: Mon, 20 Apr 2026 13:07:40 +0700 Subject: [PATCH 3/3] Fix UI freeze on controlled doc update view (#10778) * Fix UI freeze on controlled doc update view Signed-off-by: Artem Savchenko * Fix translation Signed-off-by: Artem Savchenko --------- Signed-off-by: Artem Savchenko --- .../text/src/markup/__tests__/utils.test.ts | 27 ++++++ .../src/components/MarkupDiffViewer.svelte | 94 ++++++++++++++----- 2 files changed, 96 insertions(+), 25 deletions(-) diff --git a/foundations/core/packages/text/src/markup/__tests__/utils.test.ts b/foundations/core/packages/text/src/markup/__tests__/utils.test.ts index 2bff4dc275..1fb1554f17 100644 --- a/foundations/core/packages/text/src/markup/__tests__/utils.test.ts +++ b/foundations/core/packages/text/src/markup/__tests__/utils.test.ts @@ -22,6 +22,7 @@ import { isEmptyMarkup, isEmptyNode, jsonToMarkup, + type MarkupMark, MarkupMarkType, MarkupNode, MarkupNodeType, @@ -300,6 +301,32 @@ describe('jsonToPmNode', () => { expect(node.content.child(0).type.name).toEqual('text') expect(node.content.child(0).text).toEqual('Hello, world!') }) + + it('ServerKit schema includes node-uuid mark and parses text carrying it (QMS anchors)', () => { + const schema = getSchema(extensions) + expect(schema.marks['node-uuid']).toBeDefined() + const json: MarkupNode = { + type: MarkupNodeType.doc, + content: [ + { + type: MarkupNodeType.paragraph, + attrs: { textAlign: null as any }, + content: [ + { + type: MarkupNodeType.text, + text: 'hello', + marks: [{ type: 'node-uuid' } as unknown as MarkupMark] + } + ] + } + ] + } + const node = jsonToPmNode(json, schema) + expect(node.type.name).toEqual('doc') + const para = node.content.child(0) + const text = para.content.child(0) + expect(text.marks.some((m) => m.type.name === 'node-uuid')).toBeTruthy() + }) }) describe('htmlToMarkup', () => { diff --git a/plugins/text-editor-resources/src/components/MarkupDiffViewer.svelte b/plugins/text-editor-resources/src/components/MarkupDiffViewer.svelte index 44131bdba6..490e29fcd9 100644 --- a/plugins/text-editor-resources/src/components/MarkupDiffViewer.svelte +++ b/plugins/text-editor-resources/src/components/MarkupDiffViewer.svelte @@ -15,8 +15,11 @@ // -->
-
+ + +