diff --git a/apps/comments/lib/Listener/LoadSidebarScripts.php b/apps/comments/lib/Listener/LoadSidebarScripts.php index 906fe40fed250..5235de9c0a094 100644 --- a/apps/comments/lib/Listener/LoadSidebarScripts.php +++ b/apps/comments/lib/Listener/LoadSidebarScripts.php @@ -34,7 +34,8 @@ public function handle(Event $event): void { $this->commentsManager->load(); $this->initialState->provideInitialState('activityEnabled', $this->appManager->isEnabledForUser('activity')); - // Add comments sidebar tab script + // Add comments sidebar tab script/style + Util::addStyle(Application::APP_ID, 'comments-tab', 'files'); Util::addScript(Application::APP_ID, 'comments-tab', 'files'); } } diff --git a/apps/comments/src/actions/inlineUnreadCommentsAction.spec.ts b/apps/comments/src/actions/inlineUnreadCommentsAction.spec.ts index 699c53f849d48..2cd2e9d16a066 100644 --- a/apps/comments/src/actions/inlineUnreadCommentsAction.spec.ts +++ b/apps/comments/src/actions/inlineUnreadCommentsAction.spec.ts @@ -7,7 +7,7 @@ import type { IFolder, IView } from '@nextcloud/files' import { File, Permission } from '@nextcloud/files' import { describe, expect, test, vi } from 'vitest' -import logger from '../logger.js' +import logger from '../logger.ts' import { action } from './inlineUnreadCommentsAction.ts' const view = { diff --git a/apps/comments/src/actions/inlineUnreadCommentsAction.ts b/apps/comments/src/actions/inlineUnreadCommentsAction.ts index 4f77a66244c2c..c871a1d474660 100644 --- a/apps/comments/src/actions/inlineUnreadCommentsAction.ts +++ b/apps/comments/src/actions/inlineUnreadCommentsAction.ts @@ -8,8 +8,8 @@ import type { IFileAction } from '@nextcloud/files' import CommentProcessingSvg from '@mdi/svg/svg/comment-processing.svg?raw' import { getSidebar } from '@nextcloud/files' import { n, t } from '@nextcloud/l10n' -import logger from '../logger.js' -import { isUsingActivityIntegration } from '../utils/activity.js' +import logger from '../logger.ts' +import { isUsingActivityIntegration } from '../utils/activity.ts' export const action: IFileAction = { id: 'comments-unread', diff --git a/apps/comments/src/comments-activity-tab.ts b/apps/comments/src/comments-activity-tab.ts index c368236052f86..1f17409252c01 100644 --- a/apps/comments/src/comments-activity-tab.ts +++ b/apps/comments/src/comments-activity-tab.ts @@ -6,44 +6,38 @@ import type { INode } from '@nextcloud/files' import moment from '@nextcloud/moment' -import { createPinia, PiniaVuePlugin } from 'pinia' -import Vue, { type ComponentPublicInstance } from 'vue' -import logger from './logger.js' -import { getComments } from './services/GetComments.js' - -Vue.use(PiniaVuePlugin) - -let ActivityTabPluginView -let ActivityTabPluginInstance +import { createPinia } from 'pinia' +import { createApp, type ComponentPublicInstance } from 'vue' +import logger from './logger.ts' +import { getComments } from './services/GetComments.ts' /** * Register the comments plugins for the Activity sidebar */ export function registerCommentsPlugins() { + let app + window.OCA.Activity.registerSidebarAction({ mount: async (el: HTMLElement, { node, reload }: { node: INode, reload: () => void }) => { const pinia = createPinia() - if (!ActivityTabPluginView) { + if (!app) { const { default: ActivityCommentAction } = await import('./views/ActivityCommentAction.vue') - // @ts-expect-error Types are broken for Vue2 - ActivityTabPluginView = Vue.extend(ActivityCommentAction) + app = createApp( + ActivityCommentAction, + { + reloadCallback: reload, + resourceId: node.fileid, + }, + ) } - ActivityTabPluginInstance = new ActivityTabPluginView({ - el, - pinia, - propsData: { - reloadCallback: reload, - resourceId: node.fileid, - }, - }) + app.use(pinia) + app.mount(el) logger.info('Comments plugin mounted in Activity sidebar action', { node }) }, unmount: () => { // destroy previous instance if available - if (ActivityTabPluginInstance) { - ActivityTabPluginInstance.$destroy() - } + app?.unmount() }, }) @@ -57,8 +51,6 @@ export function registerCommentsPlugins() { ) logger.debug('Loaded comments', { node, comments }) const { default: CommentView } = await import('./views/ActivityCommentEntry.vue') - // @ts-expect-error Types are broken for Vue2 - const CommentsViewObject = Vue.extend(CommentView) return comments.map((comment) => ({ _CommentsViewInstance: undefined as ComponentPublicInstance | undefined, @@ -66,17 +58,18 @@ export function registerCommentsPlugins() { timestamp: moment(comment.props?.creationDateTime).toDate().getTime(), mount(element: HTMLElement, { reload }) { - this._CommentsViewInstance = new CommentsViewObject({ - el: element, - propsData: { + this._CommentsViewInstance = createApp( + CommentView, + { comment, resourceId: node.fileid, reloadCallback: reload, }, - }) + ) + this._CommentsViewInstance.mount(el) }, unmount() { - this._CommentsViewInstance?.$destroy() + this._CommentsViewInstance?.unmount() }, })) }) diff --git a/apps/comments/src/comments-app.js b/apps/comments/src/comments-app.ts similarity index 79% rename from apps/comments/src/comments-app.js rename to apps/comments/src/comments-app.ts index ea99517e2807c..4b4fd54c55a65 100644 --- a/apps/comments/src/comments-app.js +++ b/apps/comments/src/comments-app.ts @@ -3,8 +3,8 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ -import logger from './logger.js' -import CommentsInstance from './services/CommentsInstance.js' +import logger from './logger.ts' +import CommentsInstance from './services/CommentsInstance.ts' // Init Comments if (window.OCA && !window.OCA.Comments) { diff --git a/apps/comments/src/components/Comment.vue b/apps/comments/src/components/Comment.vue index 9e700fbf919d6..7b7fc4cdd4643 100644 --- a/apps/comments/src/components/Comment.vue +++ b/apps/comments/src/components/Comment.vue @@ -75,7 +75,7 @@ :model-value="localMessage" :user-data="userData" aria-describedby="tab-comments__editor-description" - @update:value="updateLocalMessage" + @update:model-value="updateLocalMessage" @submit="onSubmit" />
+ @click="onExpand" />
@@ -125,8 +125,8 @@ import IconArrowRight from 'vue-material-design-icons/ArrowRight.vue' import IconClose from 'vue-material-design-icons/Close.vue' import IconPencilOutline from 'vue-material-design-icons/PencilOutline.vue' import IconTrashCanOutline from 'vue-material-design-icons/TrashCanOutline.vue' -import CommentMixin from '../mixins/CommentMixin.js' -import { useDeletedCommentLimbo } from '../store/deletedCommentLimbo.js' +import CommentMixin from '../mixins/CommentMixin.ts' +import { useDeletedCommentLimbo } from '../store/deletedCommentLimbo.ts' // Dynamic loading const NcRichContenteditable = () => import('@nextcloud/vue/components/NcRichContenteditable') diff --git a/apps/comments/src/files-sidebar.ts b/apps/comments/src/files-sidebar.ts index 1a39291c48d42..f96c69583ccc1 100644 --- a/apps/comments/src/files-sidebar.ts +++ b/apps/comments/src/files-sidebar.ts @@ -7,9 +7,9 @@ import MessageReplyText from '@mdi/svg/svg/message-reply-text.svg?raw' import { getCSPNonce } from '@nextcloud/auth' import { registerSidebarTab } from '@nextcloud/files' import { t } from '@nextcloud/l10n' -import wrap from '@vue/web-component-wrapper' -import { createPinia, PiniaVuePlugin } from 'pinia' -import Vue from 'vue' +import { createPinia } from 'pinia' +import { defineCustomElement, h, createApp, getCurrentInstance } from 'vue' +import { createWebComponent } from 'vue-web-component-wrapper' import { registerCommentsPlugins } from './comments-activity-tab.ts' import { isUsingActivityIntegration } from './utils/activity.ts' @@ -32,17 +32,28 @@ if (isUsingActivityIntegration()) { async onInit() { const { default: FilesSidebarTab } = await import('./views/FilesSidebarTab.vue') - Vue.use(PiniaVuePlugin) - Vue.mixin({ pinia: createPinia() }) - const webComponent = wrap(Vue, FilesSidebarTab) - // In Vue 2, wrap doesn't support disabling shadow. Disable with a hack - Object.defineProperty(webComponent.prototype, 'attachShadow', { - value() { return this }, - }) - Object.defineProperty(webComponent.prototype, 'shadowRoot', { - get() { return this }, + const pluginsWrapper = { + install(GivenVue: any) { + const Vue = GivenVue + + Vue.mixin({ pinia: createPinia() }) + }, + } + + createWebComponent({ + rootComponent: FilesSidebarTab, + elementName: tagName, + plugins: pluginsWrapper, + cssFrameworkStyles: null, + defineCustomElement, + h, + createApp, + getCurrentInstance, + disableStyleRemoval: false, + disableShadowDOM: true, + replaceRootWithHostInCssFramework: false, + nonce: __webpack_nonce__, }) - window.customElements.define(tagName, webComponent) }, }) } diff --git a/apps/comments/src/logger.js b/apps/comments/src/logger.ts similarity index 100% rename from apps/comments/src/logger.js rename to apps/comments/src/logger.ts diff --git a/apps/comments/src/mixins/CommentMixin.js b/apps/comments/src/mixins/CommentMixin.ts similarity index 93% rename from apps/comments/src/mixins/CommentMixin.js rename to apps/comments/src/mixins/CommentMixin.ts index 92fd3b17acf9b..36e79eb429706 100644 --- a/apps/comments/src/mixins/CommentMixin.js +++ b/apps/comments/src/mixins/CommentMixin.ts @@ -5,11 +5,11 @@ import { showError, showUndo, TOAST_UNDO_TIMEOUT } from '@nextcloud/dialogs' import { mapStores } from 'pinia' -import logger from '../logger.js' -import DeleteComment from '../services/DeleteComment.js' -import EditComment from '../services/EditComment.js' -import NewComment from '../services/NewComment.js' -import { useDeletedCommentLimbo } from '../store/deletedCommentLimbo.js' +import logger from '../logger.ts' +import DeleteComment from '../services/DeleteComment.ts' +import EditComment from '../services/EditComment.ts' +import NewComment from '../services/NewComment.ts' +import { useDeletedCommentLimbo } from '../store/deletedCommentLimbo.ts' export default { props: { diff --git a/apps/comments/src/services/CommentsInstance.js b/apps/comments/src/services/CommentsInstance.ts similarity index 54% rename from apps/comments/src/services/CommentsInstance.js rename to apps/comments/src/services/CommentsInstance.ts index a768da1c652a2..6a51248a8c930 100644 --- a/apps/comments/src/services/CommentsInstance.js +++ b/apps/comments/src/services/CommentsInstance.ts @@ -5,49 +5,46 @@ import { getCSPNonce } from '@nextcloud/auth' import { n, t } from '@nextcloud/l10n' -import { createPinia, PiniaVuePlugin } from 'pinia' -import Vue from 'vue' +import { createPinia } from 'pinia' +import { createApp } from 'vue' import CommentsApp from '../views/Comments.vue' -import logger from '../logger.js' - -Vue.use(PiniaVuePlugin) +import logger from '../logger.ts' __webpack_nonce__ = getCSPNonce() -// Add translates functions -Vue.mixin({ - data() { - return { - logger, - } - }, - methods: { - t, - n, - }, -}) - export default class CommentInstance { /** * 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 {object} options the vue options (propsData, parent, el...) */ constructor(resourceType = 'files', options = {}) { const pinia = createPinia() - // Merge options and set `resourceType` property - options = { - ...options, - propsData: { + const app = createApp( + CommentsApp, + { ...(options.propsData ?? {}), resourceType, }, - pinia, - } - // Init Comments component - const View = Vue.extend(CommentsApp) - return new View(options) + ) + + // Add translates functions + app.mixin({ + data() { + return { + logger, + } + }, + methods: { + t, + n, + }, + }) + + app.use(pinia) + // app.mount(options.el) + return app } } diff --git a/apps/comments/src/services/DavClient.js b/apps/comments/src/services/DavClient.ts similarity index 93% rename from apps/comments/src/services/DavClient.js rename to apps/comments/src/services/DavClient.ts index 6287b47cf309f..b1832b0f715ab 100644 --- a/apps/comments/src/services/DavClient.js +++ b/apps/comments/src/services/DavClient.ts @@ -5,7 +5,7 @@ import { getRequestToken, onRequestTokenUpdate } from '@nextcloud/auth' import { createClient } from 'webdav' -import { getRootPath } from '../utils/davUtils.js' +import { getRootPath } from '../utils/davUtils.ts' // init webdav client const client = createClient(getRootPath()) diff --git a/apps/comments/src/services/DeleteComment.js b/apps/comments/src/services/DeleteComment.ts similarity index 93% rename from apps/comments/src/services/DeleteComment.js rename to apps/comments/src/services/DeleteComment.ts index 1ed63d7836a54..46f46a483ffb1 100644 --- a/apps/comments/src/services/DeleteComment.js +++ b/apps/comments/src/services/DeleteComment.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ -import client from './DavClient.js' +import client from './DavClient.ts' /** * Delete a comment diff --git a/apps/comments/src/services/EditComment.js b/apps/comments/src/services/EditComment.ts similarity index 95% rename from apps/comments/src/services/EditComment.js rename to apps/comments/src/services/EditComment.ts index cd8e5a977047a..c5f7679013b7f 100644 --- a/apps/comments/src/services/EditComment.js +++ b/apps/comments/src/services/EditComment.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ -import client from './DavClient.js' +import client from './DavClient.ts' /** * Edit an existing comment diff --git a/apps/comments/src/services/GetComments.ts b/apps/comments/src/services/GetComments.ts index 07c22bef4293c..884b66b77d25c 100644 --- a/apps/comments/src/services/GetComments.ts +++ b/apps/comments/src/services/GetComments.ts @@ -8,7 +8,7 @@ import type { DAVResult, FileStat, ResponseDataDetailed } from 'webdav' import { parseXML } from 'webdav' import { processResponsePayload } from 'webdav/dist/node/response.js' import { prepareFileFromProps } from 'webdav/dist/node/tools/dav.js' -import client from './DavClient.js' +import client from './DavClient.ts' export const DEFAULT_LIMIT = 20 diff --git a/apps/comments/src/services/NewComment.js b/apps/comments/src/services/NewComment.ts similarity index 94% rename from apps/comments/src/services/NewComment.js rename to apps/comments/src/services/NewComment.ts index a283b2068307f..32e452e2c20f0 100644 --- a/apps/comments/src/services/NewComment.js +++ b/apps/comments/src/services/NewComment.ts @@ -5,9 +5,9 @@ import { getCurrentUser } from '@nextcloud/auth' import axios from '@nextcloud/axios' -import { getRootPath } from '../utils/davUtils.js' -import { decodeHtmlEntities } from '../utils/decodeHtmlEntities.js' -import client from './DavClient.js' +import { getRootPath } from '../utils/davUtils.ts' +import { decodeHtmlEntities } from '../utils/decodeHtmlEntities.ts' +import client from './DavClient.ts' /** * Retrieve the comments list diff --git a/apps/comments/src/services/ReadComments.ts b/apps/comments/src/services/ReadComments.ts index 69bf72bb22f2c..873b186700d59 100644 --- a/apps/comments/src/services/ReadComments.ts +++ b/apps/comments/src/services/ReadComments.ts @@ -5,7 +5,7 @@ import type { Response } from 'webdav' -import client from './DavClient.js' +import client from './DavClient.ts' /** * Mark comments older than the date timestamp as read diff --git a/apps/comments/src/store/deletedCommentLimbo.js b/apps/comments/src/store/deletedCommentLimbo.ts similarity index 100% rename from apps/comments/src/store/deletedCommentLimbo.js rename to apps/comments/src/store/deletedCommentLimbo.ts diff --git a/apps/comments/src/utils/cancelableRequest.js b/apps/comments/src/utils/cancelableRequest.ts similarity index 100% rename from apps/comments/src/utils/cancelableRequest.js rename to apps/comments/src/utils/cancelableRequest.ts diff --git a/apps/comments/src/utils/davUtils.js b/apps/comments/src/utils/davUtils.ts similarity index 100% rename from apps/comments/src/utils/davUtils.js rename to apps/comments/src/utils/davUtils.ts diff --git a/apps/comments/src/utils/decodeHtmlEntities.js b/apps/comments/src/utils/decodeHtmlEntities.ts similarity index 100% rename from apps/comments/src/utils/decodeHtmlEntities.js rename to apps/comments/src/utils/decodeHtmlEntities.ts diff --git a/apps/comments/src/views/ActivityCommentAction.vue b/apps/comments/src/views/ActivityCommentAction.vue index e715a231b56a0..c2e21142008cf 100644 --- a/apps/comments/src/views/ActivityCommentAction.vue +++ b/apps/comments/src/views/ActivityCommentAction.vue @@ -20,8 +20,8 @@ import { showError } from '@nextcloud/dialogs' import { t } from '@nextcloud/l10n' import { defineComponent } from 'vue' import Comment from '../components/Comment.vue' -import logger from '../logger.js' -import CommentView from '../mixins/CommentView.js' +import logger from '../logger.ts' +import CommentView from '../mixins/CommentView.ts' export default defineComponent({ components: { diff --git a/apps/comments/src/views/Comments.vue b/apps/comments/src/views/Comments.vue index 456dedf81d8ef..4b5bf5816e4fb 100644 --- a/apps/comments/src/views/Comments.vue +++ b/apps/comments/src/views/Comments.vue @@ -79,11 +79,11 @@ import IconAlertCircleOutline from 'vue-material-design-icons/AlertCircleOutline import IconMessageReplyTextOutline from 'vue-material-design-icons/MessageReplyTextOutline.vue' import IconRefresh from 'vue-material-design-icons/Refresh.vue' import Comment from '../components/Comment.vue' -import logger from '../logger.js' +import logger from '../logger.ts' import CommentView from '../mixins/CommentView.ts' import { DEFAULT_LIMIT, getComments } from '../services/GetComments.ts' import { markCommentsAsRead } from '../services/ReadComments.ts' -import cancelableRequest from '../utils/cancelableRequest.js' +import cancelableRequest from '../utils/cancelableRequest.ts' export default { /* eslint vue/multi-word-component-names: "warn" */ diff --git a/build/frontend-legacy/webpack.modules.cjs b/build/frontend-legacy/webpack.modules.cjs index 29369519fdaa8..3d40933db0c09 100644 --- a/build/frontend-legacy/webpack.modules.cjs +++ b/build/frontend-legacy/webpack.modules.cjs @@ -5,11 +5,6 @@ const path = require('path') module.exports = { - comments: { - 'comments-app': path.join(__dirname, 'apps/comments/src', 'comments-app.js'), - 'comments-tab': path.join(__dirname, 'apps/comments/src', 'files-sidebar.ts'), - init: path.join(__dirname, 'apps/comments/src', 'init.ts'), - }, core: { 'ajax-cron': path.join(__dirname, 'core/src', 'ajax-cron.ts'), files_client: path.join(__dirname, 'core/src', 'files/client.js'), diff --git a/build/frontend-legacy/apps/comments b/build/frontend/apps/comments similarity index 100% rename from build/frontend-legacy/apps/comments rename to build/frontend/apps/comments diff --git a/build/frontend/vite.config.ts b/build/frontend/vite.config.ts index 2532f31419f3e..43b09776efa60 100644 --- a/build/frontend/vite.config.ts +++ b/build/frontend/vite.config.ts @@ -7,6 +7,11 @@ import { createAppConfig } from '@nextcloud/vite-config' import { resolve } from 'node:path' const modules = { + comments: { + 'comments-app': resolve(import.meta.dirname, 'apps/comments/src', 'comments-app.ts'), + 'comments-tab': resolve(import.meta.dirname, 'apps/comments/src', 'files-sidebar.ts'), + init: resolve(import.meta.dirname, 'apps/comments/src', 'init.ts'), + }, dav: { 'settings-admin-caldav': resolve(import.meta.dirname, 'apps/dav/src', 'settings-admin.ts'), 'settings-admin-example-content': resolve(import.meta.dirname, 'apps/dav/src', 'settings-admin-example-content.ts'), diff --git a/package-lock.json b/package-lock.json index f898b3b845d4b..03f4e20bb30f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,7 @@ "@nextcloud/initial-state": "^3.0.0", "@nextcloud/l10n": "^3.4.1", "@nextcloud/logger": "^3.0.3", + "@nextcloud/moment": "^1.3.5", "@nextcloud/password-confirmation": "^6.0.2", "@nextcloud/paths": "^3.0.0", "@nextcloud/router": "^3.1.0", @@ -34,6 +35,7 @@ "pinia": "^3.0.4", "sortablejs": "^1.15.7", "vue": "^3.5.27", + "vue-web-component-wrapper": "^1.7.7", "vuex": "^4.1.0", "webdav": "^5.9.0" }, @@ -228,6 +230,7 @@ "integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", @@ -538,6 +541,7 @@ "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@keyv/serialize": "^1.1.1" } @@ -667,6 +671,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=20.19.0" }, @@ -707,6 +712,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=20.19.0" } @@ -2490,6 +2496,7 @@ "resolved": "https://registry.npmjs.org/@nextcloud/l10n/-/l10n-3.4.1.tgz", "integrity": "sha512-aTFinTcKiK2gEXwLgutXekpZZ8/v/4QiC8C3QCLH5m0o+WtxsBC+fqV142ebC/rfDnzCLhY4ZtswSu8bFbZocg==", "license": "GPL-3.0-or-later", + "peer": true, "dependencies": { "@nextcloud/router": "^3.0.1", "@nextcloud/typings": "^1.9.1", @@ -2513,6 +2520,20 @@ "node": "^20.0.0 || ^22.0.0 || ^24.0.0" } }, + "node_modules/@nextcloud/moment": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@nextcloud/moment/-/moment-1.3.5.tgz", + "integrity": "sha512-sQjQ/D40sdedtq4ywuANSxqG0VhIB/i+QtZ6Voz3nyZWhkyyqGxdj9rQu9AyEvas3/Jlspdom5chc+a8jOmHxQ==", + "license": "GPL-3.0-or-later", + "dependencies": { + "@nextcloud/l10n": "^3.4.0", + "moment": "^2.30.1" + }, + "engines": { + "node": "^20.0.0", + "npm": "^10.0.0" + } + }, "node_modules/@nextcloud/password-confirmation": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/@nextcloud/password-confirmation/-/password-confirmation-6.0.2.tgz", @@ -2632,6 +2653,7 @@ "resolved": "https://registry.npmjs.org/@nextcloud/vue/-/vue-9.5.0.tgz", "integrity": "sha512-CQxBfHhF+Q+2r7RXd+l/eSjttJU8A2JFUyq5VpvjfpIql355kejc8bbNnM1pKgGRGSBuW9qw5Ohx0puzHge10w==", "license": "AGPL-3.0-or-later", + "peer": true, "dependencies": { "@ckpack/vue-color": "^1.6.0", "@floating-ui/dom": "^1.7.5", @@ -3608,6 +3630,7 @@ "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", @@ -3800,6 +3823,7 @@ "integrity": "sha512-zjTUwIsEfT+k9BmXwq1QEFYsb4afBlsI1AXFyWQBgggMzwBFOuu92pGrE5OFx90IOjNl+lUbQoTG7f8S0PkOdg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/types": "^8.53.1", @@ -4216,6 +4240,7 @@ "integrity": "sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.54.0", "@typescript-eslint/types": "8.54.0", @@ -5083,6 +5108,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -5890,6 +5916,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.9", "caniuse-lite": "^1.0.30001746", @@ -6921,6 +6948,7 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "peer": true, "dependencies": { "@cypress/request": "^3.0.10", "@cypress/xvfb": "^1.2.4", @@ -7623,7 +7651,6 @@ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", @@ -7639,7 +7666,6 @@ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "engines": { "node": ">=0.12" }, @@ -7671,8 +7697,7 @@ "url": "https://github.com/sponsors/fb55" } ], - "license": "BSD-2-Clause", - "peer": true + "license": "BSD-2-Clause" }, "node_modules/domhandler": { "version": "5.0.3", @@ -7680,7 +7705,6 @@ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "domelementtype": "^2.3.0" }, @@ -7706,7 +7730,6 @@ "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", @@ -7893,6 +7916,7 @@ "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "ansi-colors": "^4.1.1", "strip-ansi": "^6.0.1" @@ -8112,6 +8136,7 @@ "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -8976,17 +9001,6 @@ "@floating-ui/core": "^1.1.0" } }, - "node_modules/focus-trap": { - "version": "7.6.6", - "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.6.6.tgz", - "integrity": "sha512-v/Z8bvMCajtx4mEXmOo7QEsIzlIOqRXTIwgUfsFOF9gEsespdbD0AkPIka1bSXZ8Y8oZ+2IVDQZePkTfEHZl7Q==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "tabbable": "^6.3.0" - } - }, "node_modules/follow-redirects": { "version": "1.15.11", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", @@ -9808,7 +9822,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", @@ -9822,7 +9835,6 @@ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "engines": { "node": ">=0.12" }, @@ -12426,7 +12438,6 @@ "version": "2.30.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", - "dev": true, "license": "MIT", "engines": { "node": "*" @@ -13313,6 +13324,7 @@ "resolved": "https://registry.npmjs.org/pinia/-/pinia-3.0.4.tgz", "integrity": "sha512-l7pqLUFTI/+ESXn6k3nu30ZIzW5E2WZF/LaHJEpoq6ElcLD+wduZoB2kBN19du6K/4FDpPMazY2wJr+IndBtQw==", "license": "MIT", + "peer": true, "dependencies": { "@vue/devtools-api": "^7.7.7" }, @@ -13401,6 +13413,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -13416,7 +13429,6 @@ "integrity": "sha512-5mMeb1TgLWoRKxZ0Xh9RZDfwUUIqRrcxO2uXO+Ezl1N5lqpCiSU5Gk6+1kZediBfBHFtPCdopr2UZ2SgUsKcgQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "htmlparser2": "^8.0.0", "js-tokens": "^9.0.0", @@ -13432,24 +13444,21 @@ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/postcss-media-query-parser": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/postcss-resolve-nested-selector": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.6.tgz", "integrity": "sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/postcss-safe-parser": { "version": "6.0.0", @@ -13457,7 +13466,6 @@ "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12.0" }, @@ -13489,7 +13497,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=12.0" }, @@ -13503,6 +13510,7 @@ "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -14295,6 +14303,7 @@ "integrity": "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -14499,6 +14508,7 @@ "integrity": "sha512-fDz1zJpd5GycprAbu4Q2PV/RprsRtKC/0z82z0JLgdytmcq0+ujJbJ/09bPGDxCLkKY3Np5cRAOcWiVkLXJURg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "chokidar": "^4.0.0", "immutable": "^5.0.2", @@ -14925,7 +14935,8 @@ "version": "1.15.7", "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.7.tgz", "integrity": "sha512-Kk8wLQPlS+yi1ZEf48a4+fzHa4yxjC30M/Sr2AnQu+f/MPwvvX9XjZ6OWejiz8crBsLwSq8GHqaxaET7u6ux0A==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/source-map": { "version": "0.6.1", @@ -15479,6 +15490,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "@csstools/css-calc": "^3.1.1", "@csstools/css-parser-algorithms": "^4.0.0", @@ -15533,7 +15545,6 @@ "integrity": "sha512-IZv4IVESjKLumUGi+HWeb7skgO6/g4VMuAYrJdlqQFndgbj6WJAXPhaysvBiXefX79upBdQVumgYcdd17gCpjQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": "^12 || >=14" }, @@ -15561,7 +15572,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=20.19.0" }, @@ -15623,7 +15633,6 @@ "integrity": "sha512-H88kCC+6Vtzj76NsC8rv6x/LW8slBzIbyeSjsKVlS+4qaEJoDrcJR4L+8JdrR2ORdTscrBzYWiiT2jq6leYR1Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "css-tree": "^3.0.1", "is-plain-object": "^5.0.0", @@ -15646,8 +15655,7 @@ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.26.0.tgz", "integrity": "sha512-ZqI0qjKWHMPcGUfLmlr80NPNVHIOjPMHtIOe1qXYFGS0YBZ1YKAzo9yk8W+gGrLCN0Xdv/RKxqdIsqPakEfmow==", "dev": true, - "license": "CC0-1.0", - "peer": true + "license": "CC0-1.0" }, "node_modules/stylelint-use-logical": { "version": "2.1.3", @@ -16561,6 +16569,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "devOptional": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -16977,6 +16986,7 @@ "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", @@ -17590,6 +17600,7 @@ "integrity": "sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@vitest/expect": "4.0.18", "@vitest/mocker": "4.0.18", @@ -17681,6 +17692,7 @@ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.28.tgz", "integrity": "sha512-BRdrNfeoccSoIZeIhyPBfvWSLFP4q8J3u8Ju8Ug5vu3LdD+yTM13Sg4sKtljxozbnuMu1NB1X5HBHRYUzFocKg==", "license": "MIT", + "peer": true, "dependencies": { "@vue/compiler-dom": "3.5.28", "@vue/compiler-sfc": "3.5.28", @@ -17865,6 +17877,12 @@ "vue": "3.x" } }, + "node_modules/vue-web-component-wrapper": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/vue-web-component-wrapper/-/vue-web-component-wrapper-1.7.7.tgz", + "integrity": "sha512-2uy6VdN8AwSzCeqc9tV4ZK2HKtgZ/NWL1rvdgOsddF1UFtszBZHKyQT9sDBUc4BpyXmP7f8tmI1rI0n/A6Qptw==", + "license": "MIT" + }, "node_modules/vuex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/vuex/-/vuex-4.1.0.tgz", diff --git a/package.json b/package.json index 3bf056dd126dc..f51507d0e9b00 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "@nextcloud/initial-state": "^3.0.0", "@nextcloud/l10n": "^3.4.1", "@nextcloud/logger": "^3.0.3", + "@nextcloud/moment": "^1.3.5", "@nextcloud/password-confirmation": "^6.0.2", "@nextcloud/paths": "^3.0.0", "@nextcloud/router": "^3.1.0", @@ -63,6 +64,7 @@ "pinia": "^3.0.4", "sortablejs": "^1.15.7", "vue": "^3.5.27", + "vue-web-component-wrapper": "^1.7.7", "vuex": "^4.1.0", "webdav": "^5.9.0" },