Skip to content

feat(resources): Visual room browser with building grouping and filters#7996

Draft
Rikdekker wants to merge 12 commits intonextcloud:mainfrom
Rikdekker:feature/visual-room-browser
Draft

feat(resources): Visual room browser with building grouping and filters#7996
Rikdekker wants to merge 12 commits intonextcloud:mainfrom
Rikdekker:feature/visual-room-browser

Conversation

@Rikdekker
Copy link
Copy Markdown

Summary

Replace the minimal resource picker (search-only, max 3 suggestions) with a comprehensive visual room browser that shows all available rooms at once, grouped by building.

  • All rooms visible — loads all room principals upfront instead of requiring a search query
  • Building grouping — rooms grouped by building with collapsible sections showing available/total counts
  • Real-time availability — each room shows Available (green) / Unavailable (red) / Reserved (blue) status
  • Client-side filtering — text search across name, building, address, floor; available-only toggle; minimum capacity filter
  • Dynamic filter chips — building chips and facility chips generated from actual room data (no hardcoded list)
  • Room cards — compact cards showing name, status badge, capacity, floor/location, room type, and add/remove button
Feature Before After
All rooms visible No (search or max 3 suggestions) Yes, all rooms at once
Building grouping No Yes, expand/collapse per group
Availability status Only in search results Per room, real-time
Text search Name only via DAV roundtrip Client-side on name, building, address, floor
Available-only filter Checkbox in search Toggle that filters entire list
Min. capacity filter In search form Inline filter
Building filter No Dynamic chips, multi-select
Facility filter 3 hardcoded checkboxes Dynamic chips based on actual room features

Screenshots

Room browser with filters and building grouping

Room selected and reserved

Context

This room browser was developed as part of RoomVox, a CalDAV-based room booking backend for Nextcloud. Full documentation of the patch and its data flow is available at calendar-patch.md.

Changes

  • ResourceList.vue — full rewrite: loads all room principals, checks availability via free/busy, groups by building, client-side filtering with text/capacity/building/facility filters
  • ResourceRoomCard.vue — new component: compact card with availability badge, capacity, floor, room type, add/remove button
  • principal.js — extract room-specific DAV properties (seating capacity, room type, features, building address, room number) and derive a structured LOCATION string
  • resourceProps.js — add formatFacility() helper and extend getAllRoomTypes() with additional room types (board room, conference room, rehearsal room, studio, outdoor area)

Test plan

  • Open an event editor with a room backend registered (e.g. RoomVox)
  • Verify all rooms are displayed grouped by building
  • Verify availability status updates when changing event time
  • Test text search filtering across room name, building, address
  • Test available-only toggle
  • Test minimum capacity filter
  • Test building chip filter (multi-select)
  • Test facility chip filter
  • Add a room and verify it shows as "Reserved" with blue styling
  • Remove a room and verify it returns to normal state
  • Verify the event LOCATION field is populated when adding a room
  • Verify read-only mode hides add/remove buttons
  • Verify non-organizer view hides action buttons

🤖 Generated with Claude Code

…ilters

Replace the minimal resource picker with a comprehensive room browser
that loads all room principals upfront and provides real-time
availability checking, client-side filtering, and building-based
grouping.

Changes:
- ResourceList.vue: full rewrite with search, available-only toggle,
  min capacity filter, dynamic building and facility chips, collapsible
  building groups, and room cards with availability status
- ResourceRoomCard.vue: new component showing room name, availability
  badge, capacity, floor, room type, and add/remove action
- principal.js: extract room-specific DAV properties (seating capacity,
  room type, features, building address, room number) and derive a
  structured location string for the LOCATION field
- resourceProps.js: add formatFacility() helper and extend
  getAllRoomTypes() with additional room types

Signed-off-by: Rik Dekker <rik@shalution.nl>
Replace directional CSS properties with logical equivalents:
- margin-right → margin-inline-end
- text-align: left → text-align: start
- padding-left → padding-inline-start
- border-left → border-inline-start

Signed-off-by: Rik Dekker <rik@shalution.nl>
Add room property fields (roomSeatingCapacity, roomType, roomAddress,
roomFeatures, roomBuildingName, roomBuildingAddress, roomNumber) to all
existing principal test expectations. Add a new test case for a room
principal with actual room DAV properties to verify the building name
derivation and address formatting logic.

Signed-off-by: Rik Dekker <rik@shalution.nl>
…mCard

ResourceList.vue:
- Replace deprecated :value with v-model on NcTextField
- Use camelCase for component attributes and event names
- Fix import ordering (perfectionist/sort-imports)
- Add curly braces to all if/else blocks
- Replace deprecated Vue.set with direct property assignment
- Split multi-statement forEach bodies to separate lines
- Remove self-closing slash from void <input> element
- Fix function-paren-newline style

ResourceRoomCard.vue:
- Replace deprecated :type with :variant on NcButton
- Add emits option declaring removeRoom and addRoom
- Use camelCase for emitted event names
- Add required newlines between multi-line props

Signed-off-by: Rik Dekker <rik@shalution.nl>
@Rikdekker Rikdekker force-pushed the feature/visual-room-browser branch from 4aa6f97 to f92802f Compare February 19, 2026 16:45
Move debounce and pinia (external group) before @nextcloud/vue/components
and vue-material-design-icons (vue group). Remove blank lines between
import groups as required by newlinesBetween: 0.

Signed-off-by: Rik Dekker <rik@shalution.nl>
@Rikdekker Rikdekker force-pushed the feature/visual-room-browser branch from e13919c to 5f1ab97 Compare February 19, 2026 16:59
…st mocks

Move FACILITY_LABELS from a module-level constant to a lazily-evaluated
function. The module-level t() calls were executed at import time, before
Vitest test mocks were active, which polluted the @nextcloud/l10n mock
state and caused 54 unrelated tests to fail.

This follows the same pattern as getAllRoomTypes() which also evaluates
t() inside a function body rather than at module scope.

Signed-off-by: Rik Dekker <rik@shalution.nl>
@SebastianKrupinski SebastianKrupinski added 2. developing Work in progress enhancement New feature request labels Feb 19, 2026
Comment thread src/components/Editor/Resources/ResourceList.vue
Comment thread src/components/Editor/Resources/ResourceList.vue
Comment thread src/components/Editor/Resources/ResourceRoomCard.vue
@@ -0,0 +1,204 @@
<!--
- SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are in 2026

…bility

The vmForks pool has a known issue with Vitest v4 where vi.mock()
hoisting breaks when V8 coverage instrumentation is active
(vitest-dev/vitest#8861). This causes 54 tests to fail under
`vitest --run --coverage` while passing under `vitest --run`.

Switch to vmThreads which provides the same VM isolation and CSS
transformation support without the coverage mock hoisting bug.

Signed-off-by: Rik Dekker <rik@shalution.nl>
@SebastianKrupinski
Copy link
Copy Markdown
Contributor

Hi @Rikdekker

I had a quick look at the changes you are suggesting. I am not sure if packing all that information in to that corner of the editor is a good idea, I think maybe adding a room selection modal might be a better approache

Lets see what design thinks? @nextcloud/designers @nimishavijay

@Rikdekker
Copy link
Copy Markdown
Author

Hi @Rikdekker

I had a quick look at the changes you are suggesting. I am not sure if packing all that information in to that corner of the editor is a good idea, I think maybe adding a room selection modal might be a better approache

Lets see what design thinks? @nextcloud/designers @nimishavijay

Agreed! We can also give some ideas about reorganizing the page

@codecov
Copy link
Copy Markdown

codecov bot commented Feb 19, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Rikdekker and others added 4 commits February 19, 2026 19:35
Address PR review feedback:
- Convert ResourceRoomCard.vue and ResourceList.vue to TypeScript with
  Composition API and <script setup> syntax
- Delete unused ResourceListItem.vue and ResourceListSearch.vue
- Fix SPDX copyright year to 2026
- Fix ESLint issues in vitest.config.js (import order, trailing comma,
  semicolon)

Signed-off-by: Rik Dekker <rik@shalution.nl>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The vmThreads/vmForks pools have a non-deterministic issue with
vi.mock() hoisting when V8 coverage is active (vitest-dev/vitest#8861).
Switch to the standard forks pool which uses real Node.js child
processes and handles mock hoisting reliably.

Signed-off-by: Rik Dekker <rik@shalution.nl>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The forks pool cannot transform CSS files from @nextcloud/vue, causing
"Unknown file extension .css" errors. Switch back to vmThreads (which
handles CSS via the Vite pipeline) but disable fileParallelism to
prevent the non-deterministic vi.mock() hoisting failures when V8
coverage is active (vitest-dev/vitest#8861).

Signed-off-by: Rik Dekker <rik@shalution.nl>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use vmForks pool (required for CSS transformation) with singleFork
option to serialize test execution in a single VM fork, preventing
the non-deterministic vi.mock() hoisting failures when V8 coverage
is active (vitest-dev/vitest#8861).

Signed-off-by: Rik Dekker <rik@shalution.nl>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rikdekker added a commit to Rikdekker/calendar that referenced this pull request Feb 24, 2026
Prevent loading room data for non-organizers by checking
isViewedByOrganizer before calling loadAllRooms().

Addresses review feedback from SebastianKrupinski on PR nextcloud#7996.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Prevent loading room data for non-organizers by checking
isViewedByOrganizer before calling loadAllRooms().

Addresses review feedback from SebastianKrupinski on PR nextcloud#7996.

Signed-off-by: Rikdekker <Rikdekker@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Rikdekker Rikdekker force-pushed the feature/visual-room-browser branch from 6fdc817 to 27c347b Compare February 24, 2026 17:13
@Rikdekker
Copy link
Copy Markdown
Author

Friendly ping @nextcloud/designers @nimishavijay — would love your input on the modal vs inline approach so we can move forward. Happy to prepare mockups for either direction.

In the meantime I've addressed the code review feedback from @SebastianKrupinski:

  • ✅ Restored isViewedByOrganizer guard in onMounted
  • ✅ Removed unused ResourceListSearch.vue
  • ✅ Fixed copyright year
  • ✅ Converted to TypeScript with Composition API and <script setup>

Copy link
Copy Markdown
Member

@jancborchardt jancborchardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is indeed very very busy. Could we follow the MS Outlook calendar approach, to the right sidebar? It’s much more organized by using select elements:

Event modal

Image

Sidebar detail

Image

Building select

Image

Features

Image

@ChristophWurst ChristophWurst marked this pull request as draft February 25, 2026 11:59
@Rikdekker
Copy link
Copy Markdown
Author

@jancborchardt thanks for the feedback. What do you think of this design proposal?
RoomVox-bookrooms

Copy link
Copy Markdown
Member

@jancborchardt jancborchardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The interaction is good, but the layout was nice as before with attendees 2/3 (left column) and the room selector 1/3 (right column). That will also help people switching over from MS to adjust quicker.

@Rikdekker
Copy link
Copy Markdown
Author

@jancborchardt What do you think about this? We think it is quite busy to have all the information at the same time on one screen.
RoomVox-bookrooms-sidepanel

Copy link
Copy Markdown
Member

@jancborchardt jancborchardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Rikdekker right, that's a valid concern. The approach with a (nonstandard) sidebar on top of a modal is a bit strange though.

Instead what do you think about having a button "Room finder" (note we use sentence case) in the right column, same level as the sharing input, which then expands that info.

Interaction-wise it works similar to your proposal, but is a bit more integrated.

@Rikdekker
Copy link
Copy Markdown
Author

@jancborchardt Here's a demo of a new proposal for the calendar event modal including room finder interaction (filtering, availability, selecting a room):

Room finder demo

Documentation

I've written up detailed documentation for this feature:

Looking forward to you feedback!

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 6, 2026

Hello there,
Thank you so much for taking the time and effort to create a pull request to our Nextcloud project.

We hope that the review process is going smooth and is helpful for you. We want to ensure your pull request is reviewed to your satisfaction. If you have a moment, our community management team would very much appreciate your feedback on your experience with this PR review process.

Your feedback is valuable to us as we continuously strive to improve our community developer experience. Please take a moment to complete our short survey by clicking on the following link: https://cloud.nextcloud.com/apps/forms/s/i9Ago4EQRZ7TWxjfmeEpPkf6

Thank you for contributing to Nextcloud and we hope to hear from you soon!

(If you believe you should not receive this message, you can add yourself to the blocklist.)

@Rikdekker
Copy link
Copy Markdown
Author

@jancborchardt can you give an update of the status of this PR?

@Rikdekker
Copy link
Copy Markdown
Author

@jancborchardt Friendly reminder — this has been waiting on design feedback for about 7 weeks now. I'd love to move this forward.

I've iterated on the design based on your earlier input and posted a working demo with documentation on March 2nd. I'm happy with the current approach — it balances usability and information density well without overloading the modal.

Could you take another look and share any remaining concerns? If there are specific things you'd like adjusted I'm happy to discuss, but I'd like to avoid the PR going stale. Thanks!

@nimishavijay
Copy link
Copy Markdown
Member

Hello! Thank you for taking the time to contribute :) From your latest screencast I see that there are many different updates that go beyond the scope of just room management, and the result of the room management UI is quite different from what @jancborchardt had suggested as well. Please update the UI with the feedback in mind (we do want to be rather similar to Outlook, but with Nextcloud's design language, and good alignment of text and icons), and let's keep the scope of this to just room management so it is easier for the developers to review :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

2. developing Work in progress enhancement New feature request feedback-requested

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants