feat: add web-based admin interface for resource and room management- #224 - #299
Merged
Conversation
hamza221
marked this pull request as ready for review
August 11, 2026 10:48
GVodyanov
approved these changes
Aug 20, 2026
GVodyanov
left a comment
There was a problem hiding this comment.
Tested and looked thru the frontend code, looks really clean and nice.
Signed-off-by: Hamza <hamzamahjoubi221@gmail.com> Add Vue 3 Web Interface for Calendar Resource Management - Added complete Vue 3 frontend with Vite build system - Implemented admin UI for Buildings, Stories, Rooms, and Resources - Fixed Vue reactivity issues with dropdown selections (buildingOptions/storyOptions as data properties) - Added professional CSS styling with Nextcloud theme integration - Implemented cache invalidation via IRoomManager/IResourceManager - Fixed getAllRooms() and getAllResources() to return actual data - Added AdminController with optional manager dependencies - Cleaned up excessive debug logging for production - Added routes for REST API endpoints - Created AdminSettings integration Signed-off-by: Hamza <hamzamahjoubi221@gmail.com> Add optional room properties: capacity, contact person, room number, and equipment flags (phone, video, TV, projector, whiteboard, wheelchair accessible) Signed-off-by: Hamza <hamzamahjoubi221@gmail.com> Add admin delegation support and fix autoloader issue Signed-off-by: Hamza <hamzamahjoubi221@gmail.com> Fix validation UX - remove required attributes, add programmatic validation - Removed HTML5 required attributes from all form fields (Gebäude, Stockwerke, Räume, Ressourcen) - Added placeholder='Pflichtfeld' for visual indication of required fields - Implemented programmatic validation in addBuilding(), addStory(), addRoom(), addResource() - Prevents red border issue on input fields after successful form submission - Provides clear German error messages via alert() dialogs Signed-off-by: Hamza <hamzamahjoubi221@gmail.com> Add multilanguage support (DE/EN) with Nextcloud l10n - Implemented translation system following Nextcloud standards (like integration_mattermost) - Created l10n files: de_DE.js, de_DE.json, en.js, en.json - Wrapped t() and n() functions with auto-injection of app name in adminSettings.js - All UI strings now translatable (50+ translation keys) - Removed hardcoded German strings from Vue template - Fixed UTF-8 encoding issues for German umlauts - Supports automatic language detection based on Nextcloud user settings - German translations: Gebäude, Stockwerke, Räume, Ressourcen, etc. - English translations: Buildings, Stories, Rooms, Resources, etc. Signed-off-by: Hamza <hamzamahjoubi221@gmail.com> chore: add SPDX license headers to frontend files Add SPDX-FileCopyrightText and SPDX-License-Identifier headers to all frontend source files according to Nextcloud contribution guidelines. Files updated: - src/CalendarResourceAdmin.vue - src/adminSettings.js - l10n/de_DE.js All files use AGPL-3.0-or-later license to match the project license. Signed-off-by: Marcel Meyer <meyerm@strato.de> Signed-off-by: Hamza <hamzamahjoubi221@gmail.com> fix: add missing SPDX headers and strict_types declarations Addresses code review feedback from @kesselb in #224: - Add SPDX-FileCopyrightText and SPDX-License-Identifier to: * lib/Controller/AdminController.php * lib/Settings/AdminSection.php * lib/Settings/AdminSettings.php - Add declare(strict_types=1) to all PHP files - Rename package.json name to 'calendar-resource-management' References: #58 Signed-off-by: Marcel Meyer <meyerm@strato.de> Signed-off-by: Hamza <hamzamahjoubi221@gmail.com> fix: ensure REUSE compliance and fix coding style This commit addresses all CI failures in #224: 1. REUSE Compliance: - Add Apache-2.0 license file to LICENSES/ - Add SPDX headers to: routes.php, vite.config.mjs, css file - Add .license files for JSON and lock files - Add license field to package.json 2. XML Schema Compliance: - Move <icon> element before <category> in info.xml 3. PHP Coding Style: - Run composer cs:fix on all PHP files - Apply PSR-12 formatting standards All files now comply with Nextcloud contribution requirements. Signed-off-by: Marcel Meyer <meyerm@strato.de> Signed-off-by: Hamza <hamzamahjoubi221@gmail.com> fix: address all PR #224 review feedback - Translate all comments to English - Update SPDX copyright to Nextcloud GmbH and Nextcloud contributors - Remove CSS file, inject styles via JS bundle (inlineCSS) - Replace calendar icon with meeting room icon - Remove l10n files (handled by Transifex) - Extract API calls into src/services/adminService.js - Use @nextcloud/axios instead of fetch() - Use @nextcloud/router instead of OC.generateUrl() - Replace alert() with showError() from @nextcloud/dialogs - Replace confirm() with NcDialog component - Remove console.log statements - Remove commit_msg.txt and package-lock.json.license - Remove LICENSES/Apache-2.0.txt (not needed) - Remove <javascript> tag from info.xml - Add npm scripts (build, dev, watch, lint, stylelint) - Use createAppConfig() from @nextcloud/vite-config - Remove manual registerService() calls (auto DI) - Hide table headers when no data (v-if) - Use strict equality (===) for comparisons - Rename appName to appId to avoid createAppConfig collision Signed-off-by: Hamza <hamzamahjoubi221@gmail.com> build: add eslint and stylelint config and declare frontend dependencies `npm run lint` could not run: the scripts used the removed `--ext` flag and the app shipped no eslint or stylelint config, so both linters only worked by accident when the app was checked out inside a server tree. - add eslint.config.mjs using @nextcloud/eslint-config v9 flat config (recommendedJavascript: Vue 3 with JavaScript script blocks) and stylelint.config.js extending @nextcloud/stylelint-config - declare eslint, stylelint and the stylelint peer configs instead of relying on transitive installs - add the browserslist and engines fields - annotate package.json and package-lock.json in REUSE.toml, they cannot carry a license header themselves Assisted-by: ClaudeCode:claude-opus-5 Signed-off-by: Hamza <hamzamahjoubi221@gmail.com> refactor(settings): split admin settings into per-entity components The admin settings were a single 671 line component that violated the coding style (spaces, semicolons, console logging) and swallowed API errors. - split into per-entity section components, each an NcSettingsSection, with data loading, error reporting and delete confirmation in the parent - report every failed request via @nextcloud/logger and showError and check the `success` flag of create and delete responses - translate via `translate as t` from @nextcloud/l10n instead of a global t/n mixin - replace the emoji equipment column with a translated list and label the delete buttons for screen readers - replace the hand rolled number input with NcTextField and use design system variables, logical properties and scrollable tables Fixes two defects found on the way: - NcButton in @nextcloud/vue 9 has no `type` prop, so `type="primary"` and `type="error"` rendered unstyled buttons with an invalid HTML type attribute; use `variant` - room creation sent hasVideoConferencing and isWheelchairAccessible, but the endpoint reads hasVideo and wheelchairAccessible, so both switches were silently discarded Assisted-by: ClaudeCode:claude-opus-5 Signed-off-by: Hamza <hamzamahjoubi221@gmail.com> fix: make info.xml schema valid and add the Apache-2.0 license text The appstore info.xsd has no `icon` element, so `<icon>img/app.svg</icon>` failed schema validation. The app icon is picked up from img/app.svg by convention and AdminSection already resolves it, so the element is not needed. img/app.svg is annotated as Apache-2.0 in REUSE.toml but the matching license text was missing from LICENSES, which made the reuse lint fail once the file was added. Assisted-by: ClaudeCode:claude-opus-5 Signed-off-by: Hamza <hamzamahjoubi221@gmail.com> fix: drop the out-of-scope calendar backend changes getAllRooms() and getAllResources() have returned an empty array since the initial commit and nothing calls them: the sync job in OC\Calendar\ResourcesRoomsUpdater reads through listAllRooms()/getRoom() and listAllResources()/getResource(). Implementing them with a plain findAll() would also have bypassed the visibility filtering that listAllRooms() gained with findAllVisibleUIDs(), handing out restricted rooms and resources. Unrelated to the admin settings anyway, so leave them as they are. Assisted-by: ClaudeCode:claude-opus-5 Signed-off-by: Hamza <hamzamahjoubi221@gmail.com> fix(settings): authorize delegated admins and harden the admin API The endpoints were reachable by admins only despite AdminSettings implementing IDelegatedSettings, accepted any parent ID, and returned raw exception messages to the client. - add #[AuthorizedAdminSetting] to every endpoint. It has to be per method because MiddlewareUtils::getAuthorizedAdminSettingClasses() only reads method attributes - validate that the story or building exists before inserting, like the create commands do, and drop the storyId/buildingId fallback of 1 - log unexpected failures with the exception and answer with a fixed message and Http::STATUS_* instead of $e->getMessage(); missing input is a 400, an unknown entity a 404 - move building and story persistence into BuildingService and a new StoryService instead of using the mappers from the controller - replace appinfo/routes.php with #[FrontpageRoute]; the generated URLs are unchanged, so the frontend keeps working - use constructor promotion, return types and camelCase method names, inject the room and resource managers non-nullable (IManager::update() exists since 30.0.0 and the app requires 31) and generate UIDs with ISecureRandom - drop the deprecated IInitialStateService and the initial state that no code read The error messages are deliberately untranslated, the frontend shows its own translated message and only logs the response. Assisted-by: ClaudeCode:claude-opus-5 Signed-off-by: Hamza <hamzamahjoubi221@gmail.com> test: cover the admin API and the resource services Adds unit tests for the input validation, the parent ID checks, the error mapping and the calendar backend updates of AdminController, and for BuildingService, StoryService, RoomService and ResourceService. Assisted-by: ClaudeCode:claude-opus-5 Signed-off-by: Hamza <hamzamahjoubi221@gmail.com> fix(design): design review - one shared max width for all form fields, selects and submit buttons, only the room table is allowed to be wider because of its column count - tables lead each section, get rounded corners and a --color-border-dark border, and their cells leave 4px around the row actions - delete buttons are tertiary icon buttons, labelled for screen readers - add buttons are wide, carry a plus icon and name what they add - the add buttons show a spinner and refuse further clicks while the create request runs, which made it possible to add an entry twice - the contact person is picked from an account dropdown instead of typing a user id, backed by a new endpoint that searches accounts server side - capacity drops the "(persons)" hint - the interface calls stories floors, which is the more common wording. The entity keeps its name because the database, the commands and the public IRoomMetadata::BUILDING_STORY key cannot be renamed Assisted-by: ClaudeCode:claude-opus-5 Signed-off-by: Hamza <hamzamahjoubi221@gmail.com> refactor: use typescript Signed-off-by: Hamza <hamzamahjoubi221@gmail.com> fix: use json serialize Signed-off-by: Hamza <hamzamahjoubi221@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Continuing #224
Closes #58.
🤖 AI (if applicable)