diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 1ffe9d36..7a8476c5 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -6,6 +6,32 @@ updates:
interval: "weekly"
target-branch: "development"
open-pull-requests-limit: 10
+ # HELD BACK DELIBERATELY, not out of caution. Each of these is blocked by a
+ # package we do not control, and dependabot cannot see that, so it proposes
+ # them on every run and each one takes `npm ci` or `npm run build` from
+ # green to red with no code change that can fix it.
+ #
+ # typescript 7: typescript-eslint hard-throws on TS >= 7 (a `versionMajor
+ # >= 7` guard in its dist/index.js) and every published
+ # version still peers `typescript: ">=4.8.4 <6.1.0"`.
+ # webpack-cli 7: @nextcloud/webpack-vue-config 7.0.4, the latest, peers
+ # `webpack-cli: ^6.0.1`.
+ # @babel/core 8: the same package peers `@babel/core: ^7.22.9`, and
+ # preset-env 8 requires core 8, so the pair moves together
+ # or not at all.
+ #
+ # Lift each the moment its blocker ships support. These are compatibility
+ # limits, not security ones: `npm audit` reports no advisory against any of
+ # the versions pinned here.
+ ignore:
+ - dependency-name: "typescript"
+ update-types: ["version-update:semver-major"]
+ - dependency-name: "webpack-cli"
+ update-types: ["version-update:semver-major"]
+ - dependency-name: "@babel/core"
+ update-types: ["version-update:semver-major"]
+ - dependency-name: "@babel/preset-env"
+ update-types: ["version-update:semver-major"]
cooldown:
default-days: 1
include:
diff --git a/appinfo/info.xml b/appinfo/info.xml
index e43088f3..aa43d171 100644
--- a/appinfo/info.xml
+++ b/appinfo/info.xml
@@ -52,7 +52,7 @@ Ideaal voor organisaties die consistente, samengestelde dashboards willen voor h
Vrij en open source onder de EUPL-1.2-licentie.
]]>
- 1.0.20
+ 1.0.20-unstable.20260830175557EUPL-1.2ConductionLaunchPad
diff --git a/css/launchpad.css b/css/launchpad.css
index cd0d6de8..1804a21c 100644
--- a/css/launchpad.css
+++ b/css/launchpad.css
@@ -50,3 +50,32 @@
* math and produced double-stacking artefacts. The `c: 1` entry in the
* BREAKPOINTS table already gives every widget the full row at <= 480 px.
*/
+
+/**
+ * Restore the NcSelect dropdown's stacking, which @nextcloud/vue 9.10 broke.
+ *
+ * NcSelect renders its menu with `appendToBody: true` (the default in both
+ * 9.9 and 9.11), so the menu is a child of
, NOT of the select. Its
+ * z-index comes from the `--vs-dropdown-z-index` custom property, which the
+ * menu can only pick up by INHERITANCE.
+ *
+ * 9.9.0 declared it on `body`, which the appended menu inherits:
+ *
+ * body { --vs-dropdown-z-index: 9999 }
+ *
+ * 9.11.0 moved the declaration onto the select root:
+ *
+ * .nc-select.v-select.select { --vs-dropdown-z-index: 9999 }
+ *
+ * The menu is not a descendant of that element, so it inherits nothing and
+ * falls back to vue-select's own default — which sits BELOW Nextcloud's modal
+ * backdrop. The dropdown then renders visibly but cannot be clicked: the
+ * Playwright trace shows the option "visible, enabled and stable" with
+ * `class="modal-mask"` intercepting the pointer, 70 times across 11 tests.
+ *
+ * Re-declaring it on `body` restores exactly what 9.9.0 did, and is harmless
+ * once upstream fixes the scope: the value is identical either way.
+ */
+body {
+ --vs-dropdown-z-index: 9999;
+}
diff --git a/package-lock.json b/package-lock.json
index 33eca57c..9b2e2851 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -16,7 +16,7 @@
"@nextcloud/initial-state": "^2.2.0",
"@nextcloud/l10n": "^3.4.1",
"@nextcloud/router": "^3.1.0",
- "@nextcloud/vue": "~9.9.0",
+ "@nextcloud/vue": "^9.11.0",
"dexie": "^4.4.5",
"dompurify": "^3.4.14",
"gridstack": "^12.2.1",
@@ -4251,9 +4251,9 @@
}
},
"node_modules/@nextcloud/vue": {
- "version": "9.9.0",
- "resolved": "https://registry.npmjs.org/@nextcloud/vue/-/vue-9.9.0.tgz",
- "integrity": "sha512-TmKnBWp6Aiw+cm+WamwX5cMkhkpJqLSUKrTUB5I5Y9RDt2S0TUlwRaTe9vltBIV3qmKParhpZQ3/ewWHgEQlrQ==",
+ "version": "9.11.0",
+ "resolved": "https://registry.npmjs.org/@nextcloud/vue/-/vue-9.11.0.tgz",
+ "integrity": "sha512-LRsyU9Mxs0b2xWqbxygps8O7/i1z4QhNQD9/QDni+VqFY3V0N95mAgmKJm6vfoFuxTAMXERp9bjqFn3UV542gw==",
"license": "AGPL-3.0-or-later",
"dependencies": {
"@ckpack/vue-color": "^1.6.0",
@@ -4270,19 +4270,19 @@
"@nextcloud/sharing": "^0.4.0",
"@nextcloud/vue-select": "^4.1.0",
"@vuepic/vue-datepicker": "^11.0.3",
- "@vueuse/components": "^14.3.0",
- "@vueuse/core": "^14.3.0",
+ "@vueuse/components": "^14.4.0",
+ "@vueuse/core": "^14.4.0",
"blurhash": "^2.0.5",
"clone": "^2.1.2",
"debounce": "^3.0.0",
- "dompurify": "^3.4.12",
+ "dompurify": "^3.4.14",
"emoji-mart-vue-fast": "^15.0.5",
"escape-html": "^1.0.3",
"floating-vue": "^5.2.2",
"focus-trap": "^8.2.2",
"linkifyjs": "^4.3.3",
"mdast-util-to-string": "^4.0.0",
- "p-queue": "^9.3.1",
+ "p-queue": "^9.3.3",
"rehype-external-links": "^3.0.0",
"rehype-highlight": "^7.0.2",
"rehype-react": "^8.0.0",
@@ -4299,7 +4299,7 @@
"unist-builder": "^4.0.0",
"unist-util-visit-parents": "^6.0.2",
"vue": "^3.5.18",
- "vue-router": "^5.1.0"
+ "vue-router": "^5.2.0"
},
"engines": {
"node": "^20.11.0 || ^22 || ^24"
diff --git a/package.json b/package.json
index 03fca29a..2238ec08 100644
--- a/package.json
+++ b/package.json
@@ -41,7 +41,7 @@
"@nextcloud/initial-state": "^2.2.0",
"@nextcloud/l10n": "^3.4.1",
"@nextcloud/router": "^3.1.0",
- "@nextcloud/vue": "~9.9.0",
+ "@nextcloud/vue": "^9.11.0",
"dexie": "^4.4.5",
"dompurify": "^3.4.14",
"gridstack": "^12.2.1",
diff --git a/src/components/Widgets/VisibilityRuleRow.vue b/src/components/Widgets/VisibilityRuleRow.vue
index 246c2c50..b93ad9dd 100644
--- a/src/components/Widgets/VisibilityRuleRow.vue
+++ b/src/components/Widgets/VisibilityRuleRow.vue
@@ -708,4 +708,30 @@ export default {
gap: 8px;
justify-content: flex-end;
}
+
+/*
+ * The open select dropdown must paint ABOVE the row's action buttons.
+ *
+ * The row is a flex column: fields first, actions after. An NcSelect
+ * dropdown opens downward out of the fields block and lands over the
+ * actions, and because the actions are a LATER sibling with no stacking
+ * context of their own, they win and swallow the click.
+ *
+ * @nextcloud/vue 9.10 made this reachable by giving NcSelect a floating
+ * label (#8570), which makes the control taller and pushes the dropdown
+ * further down -- far enough to reach the actions. The Playwright trace
+ * names the interception exactly:
+ *
+ * - locator resolved to
+ * - attempting click action
+ * - element is visible, enabled and stable
+ * -
... intercepts pointer events
+ *
+ * The option was never unstable; it was covered. Giving the fields their
+ * own stacking context puts the dropdown back on top.
+ */
+.visibility-rule-row__fields {
+ position: relative;
+ z-index: 1;
+}
diff --git a/src/modals/DashboardConfigModal.vue b/src/modals/DashboardConfigModal.vue
index 6e084b12..ba6893b9 100644
--- a/src/modals/DashboardConfigModal.vue
+++ b/src/modals/DashboardConfigModal.vue
@@ -136,7 +136,7 @@
class="dashboard-config__panel">
+ class="dashboard-config__field dashboard-config__field--select">
@@ -1151,6 +1151,57 @@ export default {
gap: 6px;
}
+/*
+ * The sharee dropdown must paint ABOVE the fields that follow it.
+ *
+ * The modal body is a column of `__field` blocks. An NcSelect dropdown
+ * opens downward out of its field and lands over the next ones, and
+ * because those are LATER siblings with no stacking context of their own,
+ * they win and swallow the click.
+ *
+ * @nextcloud/vue 9.10 made this reachable by giving NcSelect a floating
+ * label (#8570): the control is taller, so the dropdown reaches further
+ * down. The Playwright trace names the interceptors exactly:
+ *
+ * - locator resolved to
+ * - attempting click action
+ * - element is visible, enabled and stable
+ * -
...
+ * -
Not shared with anyone yet.
...
+ *
+ * The option was never unstable; it was covered. Only the field holding a
+ * select is raised, so nothing else changes.
+ */
+.dashboard-config__field--select {
+ position: relative;
+ z-index: 2;
+}
+
+/*
+ * A field holding an NcSelect must paint ABOVE the fields that follow it.
+ *
+ * The modal is a column of fields. An NcSelect dropdown opens downward out
+ * of its own field and lands over the next one; those are LATER siblings
+ * with no stacking context, so they win and swallow the click.
+ *
+ * @nextcloud/vue 9.10 made this reachable by giving NcSelect a floating
+ * label (#8570), which makes the control taller and pushes the dropdown
+ * far enough down to reach them. The Playwright trace names the
+ * interception rather than leaving it to be guessed:
+ *
+ * - locator resolved to
+ * - attempting click action
+ * - element is visible, enabled and stable
+ * -
Not shared with anyone yet.
+ * ... intercepts pointer events
+ *
+ * The option was never unstable; it was covered.
+ */
+.dashboard-config__field--select {
+ position: relative;
+ z-index: 2;
+}
+
.dashboard-config__label {
font-size: 13px;
font-weight: 600;