A Nextcloud app that provides a dedicated hub for office documents. Users can browse, filter, search, and create Documents, Spreadsheets, Presentations, and Diagrams from a single page β without going through the Files app.
- Overview page at
/apps/officeβ categorised file list with sidebar navigation - Filters β All / Mine / Shared with me
- Search β within the active category, with an "Open in Files" escape hatch
- View toggle β Grid (thumbnail previews) or List, persisted per user
- Template creator β create new files from editor-provided templates
- Editor integration β opens files directly in the configured office editor
- nextcloud-docker-dev
- NC β₯ 33
- Node 24 / npm 11
Add to nextcloud-docker-dev/docker-compose.override.yml:
services:
nextcloud:
volumes:
- /path/to/office:/var/www/html/apps-extra/officeRestart the container after saving.
docker exec -u www-data nextcloud-docker-dev-nextcloud-1 \
php occ app:enable officenpm ci
npm run build # one-off build
npm run watch # rebuild on file changesAlways build with npm ci (not npm install) so your local bundle matches
the committed package-lock.json. npm install can pull newer transitive
deps and make a trivial change churn unrelated @nextcloud/vue CSS.
nvm use # pins Node 24 β Node 25's native localStorage global
# silently breaks jsdom under Vitest
npm run test:unit # one-off run
npm run test:unit:watch # watch modeVitest + @vue/test-utils + jsdom, configured in vitest.config.ts
(standalone from vite.config.ts β no shared build config to keep in
sync). vitest.setup.ts provides shared mocks for the Nextcloud globals
every component needs outside a running NC page
(@nextcloud/l10n/auth/initial-state/router) plus a ResizeObserver
stub. src/test-utils/fixtures.ts has makeNode()/makeCreator() factories
for building test data. CI runs the suite on PRs via test-unit.yml.
Commit source only (src/, lib/, β¦) β do not commit the built
js/+css/ bundle. npm run build/watch regenerates those locally for
testing; leave them uncommitted (git add src/β¦, then git restore js css
when you're done). A pre-commit hook (.githooks/pre-commit, wired via the
prepare npm script β run npm install/npm ci at least once to activate
it) blocks staged js//css/ changes locally as a safety net.
CI (npm-build) will fail your PR with "Please recompile and commit the
assets" β that's expected for a source-only PR. A maintainer then comments
/compile on the PR and the nextcloud-command bot builds and pushes the
recompiled assets as a chore(assets): Recompile assets commit.
The overview opens files via NC's file shortlink (/f/{fileid}), which
redirects to the Files app and triggers the default file action for the
installed office editor.
To inject a custom editor URL, a backend component can call
provideInitialState('office', 'editor-url', $url) before the page renders.
The frontend reads this via loadState('office', 'editor-url', null) and, when
present, navigates directly to that URL instead of /f/{fileid}.
/apps/office
βββ PageController::index() Renders the SPA shell
βββ App.vue
βββ OfficeOverview.vue Rendering states + wiring (the "launchpad")
βββ TemplateSection.vue Template picker, scrollable card list
βββ FileCard.vue Grid-view file card
βββ officeFiles.ts WebDAV file listing via @nextcloud/files
βββ templates.ts Template discovery and file creation
βββ config.ts User preference persistence (grid/list view)
βββ utils/
βββ fileFilters.ts Mine/shared/all + search + sort (pure)
βββ fileCategories.ts Mime β category mapping (pure)
βββ validateFilename.ts