From 1d64fbac00a9982810f12661c8871c576976514a Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Wed, 15 Apr 2026 09:31:49 +0200 Subject: [PATCH 1/2] fix: align webpack config and sidebar with shared patterns - Extend base webpack config instead of replacing resolve/module - Add NodePolyfillPlugin for process polyfill compatibility - Add CnObjectSidebar + objectSidebarState for proper sidebar positioning - Follows ADR-017 (component composition) and ADR-018 (header actions) --- src/App.vue | 30 +++++++++++++++++++++-- webpack.config.js | 62 +++++++++++++++++++++++------------------------ 2 files changed, 59 insertions(+), 33 deletions(-) diff --git a/src/App.vue b/src/App.vue index 2f6a7877..fef030ba 100644 --- a/src/App.vue +++ b/src/App.vue @@ -27,7 +27,7 @@ + + + + @@ -55,7 +68,7 @@ import Vue from 'vue' import { NcContent, NcAppContent, NcButton, NcEmptyContent, NcLoadingIcon } from '@nextcloud/vue' -import { CnIndexSidebar } from '@conduction/nextcloud-vue' +import { CnObjectSidebar, CnIndexSidebar } from '@conduction/nextcloud-vue' import { generateUrl, imagePath } from '@nextcloud/router' import MainMenu from './navigation/MainMenu.vue' import Modals from './modals/Modals.vue' @@ -71,6 +84,7 @@ export default { NcButton, NcEmptyContent, NcLoadingIcon, + CnObjectSidebar, CnIndexSidebar, MainMenu, Modals, @@ -80,6 +94,7 @@ export default { provide() { return { + objectSidebarState: this.objectSidebarState, sidebarState: this.sidebarState, } }, @@ -87,6 +102,17 @@ export default { data() { return { storesReady: false, + objectSidebarState: { + active: false, + open: true, + objectType: '', + objectId: '', + title: '', + subtitle: '', + register: '', + schema: '', + hiddenTabs: [], + }, sidebarState: Vue.observable({ active: false, open: true, diff --git a/webpack.config.js b/webpack.config.js index 71e3ba4e..7ec70a82 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -2,6 +2,7 @@ const path = require('path') const fs = require('fs') const webpackConfig = require('@nextcloud/webpack-vue-config') const { VueLoaderPlugin } = require('vue-loader') +const NodePolyfillPlugin = require('node-polyfill-webpack-plugin') const buildMode = process.env.NODE_ENV const isDev = buildMode === 'development' @@ -28,41 +29,40 @@ webpackConfig.entry = { const localLib = path.resolve(__dirname, '../nextcloud-vue/src') const useLocalLib = fs.existsSync(localLib) -webpackConfig.resolve = { - extensions: ['.ts', '.tsx', '.vue', '.js'], - alias: { - '@': path.resolve(__dirname, 'src'), - ...(useLocalLib ? { '@conduction/nextcloud-vue': localLib } : {}), - // Deduplicate shared packages so the aliased library source uses - // the same instances as the app (prevents dual-Pinia / dual-Vue bugs). - 'vue$': path.resolve(__dirname, 'node_modules/vue'), - 'pinia$': path.resolve(__dirname, 'node_modules/pinia'), - '@nextcloud/vue$': path.resolve(__dirname, 'node_modules/@nextcloud/vue'), - }, +webpackConfig.resolve = webpackConfig.resolve || {} +webpackConfig.resolve.modules = [path.resolve(__dirname, 'node_modules'), 'node_modules'] +webpackConfig.resolve.alias = { + ...(webpackConfig.resolve.alias || {}), + '@': path.resolve(__dirname, 'src'), + ...(useLocalLib ? { '@conduction/nextcloud-vue': localLib } : {}), + // Deduplicate shared packages so the aliased library source uses + // the same instances as the app (prevents dual-Pinia / dual-Vue bugs). + 'vue$': path.resolve(__dirname, 'node_modules/vue'), + 'pinia$': path.resolve(__dirname, 'node_modules/pinia'), + '@nextcloud/vue$': path.resolve(__dirname, 'node_modules/@nextcloud/vue'), } -webpackConfig.module = { - rules: [ - { - test: /\.vue$/, - loader: 'vue-loader', - }, - { - test: /\.ts$/, - loader: 'ts-loader', - exclude: /node_modules/, - options: { appendTsSuffixTo: [/\.vue$/] }, - }, - { - test: /\.css$/, - use: ['style-loader', 'css-loader'], - }, - ], -} +webpackConfig.module.rules.push( + { + test: /\.vue$/, + loader: 'vue-loader', + }, + { + test: /\.ts$/, + loader: 'ts-loader', + exclude: /node_modules/, + options: { appendTsSuffixTo: [/\.vue$/] }, + }, + { + test: /\.css$/, + use: ['style-loader', 'css-loader'], + }, +) -webpackConfig.plugins = [ +webpackConfig.plugins.push( new VueLoaderPlugin(), -] + new NodePolyfillPlugin({ additionalAliases: ['process'] }), +) // Force @nextcloud/dialogs to resolve from this app's node_modules, // preventing the nextcloud-vue submodule's nested deps (Vue 3) from leaking in. From 9887f7f5c3c00f7df8ebdd00baa33de39ecb6748 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Thu, 16 Apr 2026 09:47:47 +0200 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20settings=20pattern=20=E2=80=94=20use?= =?UTF-8?q?=20NcAppSettingsDialog=20modal=20(ADR-004)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Settings link in gear foldout now opens NcAppSettingsDialog modal instead of routing to /settings page. Matches ADR-004 pattern. --- src/App.vue | 6 +++++- src/navigation/MainMenu.vue | 16 ++++++++++++++++ src/views/settings/UserSettings.vue | 22 ++++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 src/views/settings/UserSettings.vue diff --git a/src/App.vue b/src/App.vue index fef030ba..fdf50acc 100644 --- a/src/App.vue +++ b/src/App.vue @@ -24,7 +24,8 @@