fix: add compatibility layer for apps expecting Vue 2 API

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
This commit is contained in:
Ferdinand Thiessen 2026-04-01 02:14:42 +02:00
parent e26588d78c
commit 324ebd144c
2 changed files with 63 additions and 15 deletions

View file

@ -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()

View file

@ -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<string, unknown>
/** @deprecated use `props` instead */
propsData?: Record<string, unknown>
}
export default class CommentInstance {
private app: App
private instance: ComponentPublicInstance<typeof CommentsApp> | 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)
}
}
}