CI runs in Forgejo Actions on the Forgejo-hosted repository.
Opsdash is an independent third-party app that turns Nextcloud Calendar data into a practical operations dashboard: what happened, what is on target, and where your time is drifting.
Opsdash is not affiliated with, endorsed by, sponsored by, or officially maintained by Nextcloud GmbH or the Nextcloud project.
- 📅 Dashboard – KPIs for week/month, busiest days, averages, weekend share, top categories, longest events, and multi-tab layouts.
- 🎯 Targets & pacing – per-calendar and per-category goals, pace hints, trend context, forecast signals, and over-target progress beyond 200%.
- ⏱️ Current period done vs planned – active week/month separates elapsed hours from future hours so “done” metrics stop at now and upcoming time stays clearly labeled.
- ⚖️ Balance – share cards, stacked bars, relations/ratios, heatmaps, lookback trends, and daypart toggles.
- 🧠 Notes – edit “This week/month”, view “Last week/month”, and optionally surface notes in cards.
- 🧩 Shared overlays – onboarding, profiles, and the in-app
What's newwindow now share one large overlay shell and interaction model. - ✨ Release notes in-app – new versions can auto-open a
What's newview with short highlights, preview images, a clickable version history, and remembered dismissal per app version. - 🗓️ Activity & schedule – event and active-day KPIs plus “Days off” trend heatmaps.
- 🔐 Runs inside Nextcloud – same session, same permissions, CSRF-protected writes, no external API calls.
- 🗂️ Deck widgets – a management-focused
Deck cardswidget plus a compactDeck statswidget, both with per-widget board/stack/tag filters and range-aware Deck summaries. - 📨 Reporting & recap mail – configure separate weekly/monthly recap modes, trigger a live test send from the UI, and render goal-type-aware mails inside the native Nextcloud email shell.
- 📐 Widget sizing controls – per-widget width/height plus scale/dense options for layout tuning.
| Widgets (Light) | Widgets (Dark) |
|---|---|
![]() |
![]() |
| Onboarding (Light) | Onboarding (Dark) |
|---|---|
![]() |
![]() |
| What's New Overlay |
|---|
![]() |
| Calendar Table (Light) | Calendar Table (Dark) |
|---|---|
![]() |
![]() |
Opsdash supports Nextcloud installations, but it is an independent third-party app and not an official Nextcloud app.
| Branch | Nextcloud | App version |
|---|---|---|
master |
30-33 | 0.8.1 |
release/0.5.x |
30-33 | Store-ready line |
Install from the Nextcloud App Store as a third-party app (when published) or place opsdash in custom_apps/ and enable it:
occ app:enable opsdashmake start
cd opsdash
npm ci
composer install
npm run build
npm run test:unit
composer run test:unit
PLAYWRIGHT_BASE_URL=http://localhost:8093 npm run test:e2emake startstarts the local Nextcloud 33 dev container onhttp://localhost:8093.make start33starts the same Nextcloud 33 stack explicitly.make start32starts the Nextcloud 32 container onhttp://localhost:8092.make start31starts the Nextcloud 31 container onhttp://localhost:8088.- The checked-out app is mounted into the dev container from
./opsdashby default. Override withAPP_SOURCE_DIR=/abs/path/to/opsdashif you need a different source path. make status/make logshelp confirm the stack is up before testing.- The
ghcr.io/juliusknorr/nextcloud-dev-php83:latestimage bootstraps the server on first start. Afterdocker compose up -d, Apache may answer on the mapped port before Nextcloud is ready. - On a fresh volume, wait until
docker exec <container> bash -lc 'cd /var/www/html && php occ status'reportsinstalled: true. This can take roughly 4 minutes on first bootstrap. - Do not run
php occ maintenance:installagainst these dev-image containers during normal startup. Use the image's built-in bootstrap flow and only intervene manually when you intentionally reset a dedicated test volume.
For SMTP testing with a local mail catcher:
docker compose -f docker-compose33-mail.yml up -d
docker exec nc33-mailguard bash -lc 'cd /var/www/html && php occ status'docker-compose33-mail.ymlstarts a dedicated Nextcloud 33 test instance onhttp://localhost:8094.- It also starts Mailpit with SMTP on
localhost:1026and the web inbox onhttp://localhost:8026. - The same bootstrap rule applies here: wait for
occ statusto showinstalled: truebefore setting SMTP, users, or app config. - Test-send paths:
- UI:
POST /overview/report/test-send - CLI payload:
php occ opsdash:report --user=<uid> --range=week --offset=0 --format=json
- UI:
- Report mails are goal-type-driven:
Single GoalCalendar GoalsCalendar + Category Goals
- Dashboard presets/layout variants stay in the UI, but they do not affect report rendering.
- Automatic recap delivery is integrated through the Nextcloud background job system, not an app-managed Unix cron path.
- Scheduler semantics:
final= complete previous week/month after the period closescheckpoint_final= midpoint checkpoint plus final closed-period recapsendTimeLocal= user-local Nextcloud time, not raw server time
- Current defaults:
- weekly enabled:
finalat06:00 - monthly disabled:
checkpoint_finalat18:00
- weekly enabled:
- Release builds intentionally expose only one Opsdash
occcommand:php occ opsdash:report.
Quick smoke check:
make smokemake release VERSION=0.8.1One-step release helper:
- bumps
appinfo/info.xml,package.json,package-lock.json,opsdash/VERSION, andSECURITY.md - runs the packaged app build
- creates
build/dist/opsdash-<version>.tar.gz
Manual packaging only:
make appstore VERSION=0.8.1Produces build/dist/opsdash-<version>.tar.gz (unsigned).
Sign separately with:
make sign VERSION=0.8.1 SIGN_PRIVATE_KEY_FILE=/secure/path/privkey.pem SIGN_CERT_FILE=/secure/path/cert.crt SIGN_CONTAINER=nc33-devUpload the signed tarball with:
FORGEJO_TOKEN=<token> make upload VERSION=0.8.1 RELEASE_TAG=v0.8.1Push to the Nextcloud App Store with:
APPSTORE_TOKEN=<token> SIGN_PRIVATE_KEY_FILE=/secure/path/privkey.pem DOWNLOAD_URL=https://public-host/opsdash-0.8.1.tar.gz make appstore-push VERSION=0.8.1Long-form internal release and runbook documentation now lives in the separate opsdash-docs and opsdash-ops workspace repos. Keep this repo focused on the app, its generic release commands, and contributor-facing basics.
- Keep PRs focused.
- Update docs and fixtures when payloads change.
- Run unit tests before opening a PR.







