From 98564ba10a119304efcff716582c7b45caaa98b6 Mon Sep 17 00:00:00 2001 From: Oleg Solodkov <94829167+sol-0@users.noreply.github.com> Date: Fri, 20 Oct 2023 11:35:02 +0400 Subject: [PATCH] [EZQMS-287] Added generic menu items and collaborator utils (#3837) * [EZQMS-287] Added generic menu items and collaborator utils Signed-off-by: Oleg Solodkov * Added copyright Signed-off-by: Oleg Solodkov * [EZQMS-287] Formatting and component fixes Signed-off-by: Oleg Solodkov * Fixed menu popups Signed-off-by: Oleg Solodkov * Addressed review comments Signed-off-by: Oleg Solodkov * Formatting Signed-off-by: Oleg Solodkov * Changed temp provider disposal Signed-off-by: Oleg Solodkov * Formatting Signed-off-by: Oleg Solodkov --------- Signed-off-by: Oleg Solodkov --- .../src/components/CollaboratorEditor.svelte | 7 +- packages/text-editor/src/index.ts | 1 + packages/text-editor/src/provider.ts | 8 ++ packages/text-editor/src/utils.ts | 78 +++++++++++++++++++ .../src/components/sidebar/TreeElement.svelte | 3 +- 5 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 packages/text-editor/src/utils.ts diff --git a/packages/text-editor/src/components/CollaboratorEditor.svelte b/packages/text-editor/src/components/CollaboratorEditor.svelte index e617f12ea2..61edcbf8fe 100644 --- a/packages/text-editor/src/components/CollaboratorEditor.svelte +++ b/packages/text-editor/src/components/CollaboratorEditor.svelte @@ -39,6 +39,7 @@ import textEditorPlugin from '../plugin' import { TiptapCollabProvider } from '../provider' import { CollaborationIds, TextFormatCategory, TextNodeAction } from '../types' + import { copyDocumentContent, copyDocumentField } from '../utils' import { calculateDecorations } from './diff/decorations' import { noSelectionRender } from './editor/collaboration' @@ -150,7 +151,11 @@ } export function takeSnapshot (snapshotId: string) { - provider.copyContent(documentId, snapshotId) + copyDocumentContent(documentId, snapshotId, { provider }, initialContentId) + } + + export function copyField (srcFieldId: string, dstFieldId: string) { + copyDocumentField(documentId, srcFieldId, dstFieldId, { provider }, initialContentId) } export function unregisterPlugin (nameOrPluginKey: string | PluginKey) { diff --git a/packages/text-editor/src/index.ts b/packages/text-editor/src/index.ts index 5926964a11..25b04e4956 100644 --- a/packages/text-editor/src/index.ts +++ b/packages/text-editor/src/index.ts @@ -31,6 +31,7 @@ export { default as TextEditorStyleToolbar } from './components/TextEditorStyleT export { default as AttachIcon } from './components/icons/Attach.svelte' export { default } from './plugin' export * from './types' +export * from './utils' export { IsEmptyContentExtension, diff --git a/packages/text-editor/src/provider.ts b/packages/text-editor/src/provider.ts index b80a893c57..24ec65c202 100644 --- a/packages/text-editor/src/provider.ts +++ b/packages/text-editor/src/provider.ts @@ -31,6 +31,14 @@ export class TiptapCollabProvider extends HocuspocusProvider { this.sendStateless(JSON.stringify(payload)) } + copyField (documentId: string, srcFieldId: string, dstFieldId: string): void { + const payload = { + action: 'document.field.copy', + params: { documentId, srcFieldId, dstFieldId } + } + this.sendStateless(JSON.stringify(payload)) + } + destroy (): void { this.configuration.websocketProvider.disconnect() super.destroy() diff --git a/packages/text-editor/src/utils.ts b/packages/text-editor/src/utils.ts new file mode 100644 index 0000000000..8e213a2f5c --- /dev/null +++ b/packages/text-editor/src/utils.ts @@ -0,0 +1,78 @@ +// +// Copyright © 2023 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. +// + +import { onStatelessParameters } from '@hocuspocus/provider' +import * as Y from 'yjs' + +import { TiptapCollabProvider } from './provider' + +type ProviderData = ( + | { + provider: TiptapCollabProvider + } + | { + collaboratorURL: string + token: string + } +) & { ydoc?: Y.Doc } + +function getProvider (documentId: string, providerData: ProviderData, initialContentId?: string): TiptapCollabProvider { + if (!('provider' in providerData)) { + const provider = new TiptapCollabProvider({ + url: providerData.collaboratorURL, + name: documentId, + document: providerData.ydoc ?? new Y.Doc(), + token: providerData.token, + parameters: { + initialContentId: initialContentId ?? '' + }, + onStateless (data: onStatelessParameters) { + try { + const payload = JSON.parse(data.payload) + if ('status' in payload && payload.status === 'completed') { + provider.destroy() + } + } catch (e) { + console.error('Failed to check provider operation status', e) + } + } + }) + + return provider + } else { + return providerData.provider + } +} + +export function copyDocumentField ( + documentId: string, + srcFieldId: string, + dstFieldId: string, + providerData: ProviderData, + initialContentId?: string +): void { + const provider = getProvider(documentId, providerData, initialContentId) + provider.copyField(documentId, srcFieldId, dstFieldId) +} + +export function copyDocumentContent ( + documentId: string, + snapshotId: string, + providerData: ProviderData, + initialContentId?: string +): void { + const provider = getProvider(documentId, providerData, initialContentId) + provider.copyContent(documentId, snapshotId) +} diff --git a/plugins/hr-resources/src/components/sidebar/TreeElement.svelte b/plugins/hr-resources/src/components/sidebar/TreeElement.svelte index 5c95620e9e..cad0250c70 100644 --- a/plugins/hr-resources/src/components/sidebar/TreeElement.svelte +++ b/plugins/hr-resources/src/components/sidebar/TreeElement.svelte @@ -16,9 +16,8 @@ import { createEventDispatcher } from 'svelte' import { Doc, Ref } from '@hcengineering/core' import type { Asset, IntlString } from '@hcengineering/platform' - import type { AnySvelteComponent } from '@hcengineering/ui' + import type { AnySvelteComponent, Action } from '@hcengineering/ui' import { Icon, IconChevronDown, IconMoreH, Label, Menu, showPopup } from '@hcengineering/ui' - import { Action } from '@hcengineering/view' export let _id: Ref | undefined = undefined export let icon: Asset | AnySvelteComponent | undefined = undefined