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.20260830175557 EUPL-1.2 Conduction LaunchPad 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;