diff --git a/apps/comments/src/comments-activity-tab.ts b/apps/comments/src/comments-activity-tab.ts index eda9fe7d55f..b738242cf57 100644 --- a/apps/comments/src/comments-activity-tab.ts +++ b/apps/comments/src/comments-activity-tab.ts @@ -4,7 +4,7 @@ */ import type { INode } from '@nextcloud/files' -import type { ComponentPublicInstance } from 'vue' +import type { App } from 'vue' import { createPinia } from 'pinia' import { createApp } from 'vue' @@ -15,7 +15,7 @@ import { getComments } from './services/GetComments.ts' * Register the comments plugins for the Activity sidebar */ export function registerCommentsPlugins() { - let app + let app: App window.OCA.Activity.registerSidebarAction({ mount: async (el: HTMLElement, { node, reload }: { node: INode, reload: () => void }) => { @@ -53,12 +53,12 @@ export function registerCommentsPlugins() { const { default: CommentView } = await import('./views/ActivityCommentEntry.vue') return comments.map((comment) => ({ - _CommentsViewInstance: undefined as ComponentPublicInstance | undefined, + _CommentsViewInstance: undefined as App | undefined, timestamp: Date.parse(comment.props?.creationDateTime as string | undefined ?? ''), mount(element: HTMLElement, { reload }) { - this._CommentsViewInstance = createApp( + const app = createApp( CommentView, { comment, @@ -66,7 +66,8 @@ export function registerCommentsPlugins() { reloadCallback: reload, }, ) - this._CommentsViewInstance.mount(el) + app.mount(element) + this._CommentsViewInstance = app }, unmount() { this._CommentsViewInstance?.unmount() diff --git a/apps/comments/src/services/CommentsInstance.ts b/apps/comments/src/services/CommentsInstance.ts index 32a8ed3eeae..c1307704776 100644 --- a/apps/comments/src/services/CommentsInstance.ts +++ b/apps/comments/src/services/CommentsInstance.ts @@ -1,34 +1,49 @@ -/** +/*! * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ +import type { App, ComponentPublicInstance } from 'vue' + import { n, t } from '@nextcloud/l10n' import { createPinia } from 'pinia' import { createApp } from 'vue' -import CommentsApp from '../views/Comments.vue' +import CommentsApp from '../views/CommentsApp.vue' import logger from '../logger.ts' +export interface CommentsInstanceOptions { + el?: HTMLElement + + props?: Record + + /** @deprecated use `props` instead */ + propsData?: Record +} + export default class CommentInstance { + private app: App + private instance: ComponentPublicInstance | undefined + /** * Initialize a new Comments instance for the desired type * - * @param {string} resourceType the comments endpoint type - * @param {object} options the vue options (propsData, parent, el...) + * @param resourceType - The comments endpoint type + * @param options - The vue options (props, parent, el...) */ - constructor(resourceType = 'files', options = {}) { + constructor(resourceType = 'files', options: CommentsInstanceOptions = {}) { const pinia = createPinia() - const app = createApp( + this.app = createApp( CommentsApp, { ...(options.propsData ?? {}), + ...(options.props ?? {}), resourceType, }, ) // Add translates functions - app.mixin({ + this.app.mixin({ data() { return { logger, @@ -40,8 +55,40 @@ export default class CommentInstance { }, }) - app.use(pinia) - // app.mount(options.el) - return app + this.app.use(pinia) + if (options.el) { + this.instance = this.app.mount(options.el) + } + } + + /** + * Mount the Comments instance to a new element. + * + * @param el - The element to mount the instance on + */ + $mount(el: HTMLElement | string) { + if (this.instance) { + this.app.unmount() + } + this.instance = this.app.mount(el) + } + + /** + * Unmount the Comments instance from the DOM and destroy it. + */ + $unmount() { + this.app.unmount() + this.instance = undefined + } + + /** + * Update the current resource id. + * + * @param id - The new resource id to load the comments for + */ + update(id: string | number) { + if (this.instance) { + this.instance.update(id) + } } }