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/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/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/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 @@ // -->
-
+ + + 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) } } 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,