Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ name: Documentation

on:
push:
branches: [documentation]
branches: [development]
pull_request:
branches: [documentation]
branches: [development]

jobs:
deploy:
uses: ConductionNL/.github/.github/workflows/documentation.yml@main
with:
cname: app-template.app
cname: app-template.conduction.nl
14 changes: 14 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,20 @@ docker/dolphin/models/
/docusaurus/node_modules/
/docusaurus/build/
/docusaurus/.docusaurus/

# Docusaurus documentation site (docs/) — build artefacts only; sources are tracked
/docs/node_modules/
/docs/build/
/docs/.docusaurus/
/docs/.cache-loader/
/docs/i18n/nl/

# Playwright (tests/e2e/) — reports, traces, and captured outputs are not committed
/tests/e2e/playwright-report/
/tests/e2e/test-results/
/test-results/
/playwright-report/

# Test screenshots — images generated by browser test commands (test-app, run-test-scenario)
# Only images are ignored; markdown reports and scenario files are kept in git.
test-results/**/*.png
Expand Down
31 changes: 29 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,13 @@ A starting point for building Nextcloud apps following ConductionNL conventions.

## Screenshots

_Add screenshots here once the app has a UI._
Screenshots are captured automatically from the tutorial flows, not pasted in by hand. The journeydoc scaffold (hydra ADR-030) ships two tutorial stories under [`docs/tutorials/`](docs/tutorials/) — a user "first launch" walkthrough (the Dashboard) and an admin "manage settings" walkthrough (Admin Settings) — and a Playwright `docs-capture` project that turns each documented step into a PNG under `docs/static/screenshots/tutorials/`.

- Add a tutorial story: `/journeydoc-add-story`
- Add stable `data-testid` hooks to a Vue component: `/journeydoc-instrument`
- (Re)capture screenshots against a running Nextcloud: `NEXTCLOUD_URL=http://localhost:8080 npx playwright test --project docs-capture`

See the [Documentation](#documentation) section below for how the docs site itself is built and deployed.

## Features

Expand Down Expand Up @@ -90,12 +96,20 @@ app-template/
│ ├── architecture/ # App-specific Architectural Decision Records
│ ├── ROADMAP.md # Product roadmap
│ └── changes/ # OpenSpec change directories (created on first change)
├── docs/ # Docusaurus documentation site (@conduction/docusaurus-preset)
│ ├── docusaurus.config.js # Site config — title, url, navbar, brand theme
│ ├── intro.md # Docs landing page
│ ├── src/pages/index.js # Marketing landing page (brand <DetailHero> / <WidgetShelf>)
│ ├── tutorials/ # journeydoc tutorial stories — user/ + admin/ tracks (ADR-030)
│ └── static/screenshots/ # Captured tutorial screenshots (populated by docs-capture)
├── tests/ # Unit and integration tests
│ ├── e2e/docs-screenshots.spec.ts # journeydoc screenshot capture suite (Playwright docs-capture project)
│ ├── validate-manifest.js # Ajv schema validator for src/manifest.json (nc-vue manifest schema)
│ ├── validate-register.js # Structural validator for lib/Settings/*_register.json (slugs, lifecycle requires→PHP, clobber heuristic)
│ └── validate-json-strict.js # Strict JSON parse — rejects duplicate keys + appendOnly nested in x-openregister
├── playwright.config.ts # Playwright config — `chromium` (regression) + `docs-capture` (screenshots) projects
├── l10n/ # Translations (en, en_US, nl)
├── .github/workflows/ # CI/CD pipelines
├── .github/workflows/ # CI/CD pipelines (incl. documentation.yml — deploys docs/ from `development`)
├── Makefile # Dev helpers (make dev-link)
└── img/ # App icons and screenshots
```
Expand Down Expand Up @@ -302,6 +316,19 @@ docker exec nextcloud php occ app:enable app-template

## Documentation

The user-facing documentation site lives in [`docs/`](docs/) — a Docusaurus site built on [`@conduction/docusaurus-preset`](https://www.npmjs.com/package/@conduction/docusaurus-preset) with the brand `<DetailHero>` / `<WidgetShelf>` landing page, the journeydoc tutorial scaffold ([`docs/tutorials/`](docs/tutorials/) — user "first launch" + admin "manage settings"), and the Playwright `docs-capture` project for screenshots (hydra ADR-030).

`.github/workflows/documentation.yml` deploys the site on every push to `development`: it runs `cd docs && npm ci && npm run build` and publishes to `<slug>.conduction.nl` (the template's placeholder slug is `app-template`, so `app-template.conduction.nl` — `docs/static/CNAME` carries this and is rewritten by the renaming pass). Build the site locally with:

```bash
cd docs
npm ci --legacy-peer-deps
npm run build # → build/ ([SUCCESS] Generated static files)
npm run start # local dev server with hot reload
```

Project / spec documentation:

| Resource | Description |
|----------|-------------|
| [`openspec/app-config.json`](openspec/app-config.json) | App identity, goals, dependencies, and CI configuration |
Expand Down
147 changes: 147 additions & 0 deletions docs/docusaurus.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
// @ts-check

/**
* Nextcloud App Template documentation site.
*
* Built on @conduction/docusaurus-preset for brand defaults (tokens,
* theme swizzles for Navbar / Footer, i18n scaffolding, KvK / BTW
* copyright). Site-specific overrides — locale (en only), sidebar
* path, mermaid theme, custom prism themes, navbar items — are passed
* through createConfig() opts.
*
* This is the *default* docs site every new Conduction app inherits
* from the template (ADR-030 / journeydoc). When you scaffold a new
* app, the renaming pass swaps `app-template` / `Nextcloud App
* Template` for your slug / title throughout this file — review the
* title, tagline, url, projectName, editUrl, and the navbar GitHub
* link, then commit.
*/

const { createConfig, baseFooterLinks } = require('@conduction/docusaurus-preset');

/* createConfig replaces themes wholesale when `themes:` is passed, so
we re-include the brand theme plugin alongside @docusaurus/theme-mermaid.
Without the brand theme entry the Navbar/Footer swizzles and
brand.css auto-load would silently drop. */
const BRAND_THEME = require.resolve('@conduction/docusaurus-preset/theme');

const config = createConfig({
title: 'Nextcloud App Template',
tagline: 'A template for creating new Nextcloud apps — manifest-first Vue 2 frontend, OpenRegister data layer, and the full Conduction quality pipeline',
url: 'https://app-template.conduction.nl',
baseUrl: '/',

organizationName: 'ConductionNL',
projectName: 'app-template',

/* English-only for now (ADR-030). The brand preset ships a
multi-locale i18n block (nl/en/de/fr), but enabling locales
without translated markdown breaks SSR on doc pages — stale
locale metadata trips `Cannot read properties of undefined`.
Re-enable 'nl' once a Dutch translation pass has shipped the
`i18n/nl/docusaurus-plugin-content-docs/current/` markdown. */
i18n: {
defaultLocale: 'en',
locales: ['en'],
localeConfigs: {
en: { label: 'English' },
},
},

/* The docs source lives at the repo root of `docs/` rather than
under a `docs/` subfolder, so we override the preset's default
`presets:` block to point `docs.path` at './' and disable the
blog plugin. customCss carries app-specific CSS only — brand
tokens and the theme swizzles are auto-loaded by the brand theme
entry in `themes:` below. */
presets: [
[
'classic',
{
docs: {
path: './',
/* docs.path: './' makes plugin-content-docs scan every file
in docs/, which collides with plugin-content-pages's own
scan of docs/src/pages/. Exclude src/ (pages live there)
plus the standard node_modules bucket. */
exclude: ['**/node_modules/**', 'src/**'],
sidebarPath: require.resolve('./sidebars.js'),
editUrl: 'https://github.com/ConductionNL/nextcloud-app-template/tree/development/docs/',
},
blog: false,
theme: {
customCss: require.resolve('./src/css/custom.css'),
},
},
],
],

themes: [BRAND_THEME, '@docusaurus/theme-mermaid'],

/* Brand navbar provides locale dropdown + GitHub by default; we
replace items[] with the app's own (Documentation sidebar link,
GitHub link, locale dropdown). Object.assign in createConfig is
shallow, so items: replaces wholesale. */
navbar: {
items: [
{
type: 'docSidebar',
sidebarId: 'tutorialSidebar',
position: 'left',
label: 'Documentation',
},
{
href: 'https://github.com/ConductionNL/nextcloud-app-template',
label: 'GitHub',
position: 'right',
},
{ type: 'localeDropdown', position: 'right' },
],
},

/* Per-property footer override (preset 1.2.0+): we pass `links` only,
so the brand `style: 'dark'` and the brand KvK/BTW/IBAN/address
copyright string both inherit unchanged. */
footer: {
links: [
...baseFooterLinks().filter((column) => column.title === 'Conduction'),
],
},

/* Drop the canal-footer mini-games on this product-page footer
(preset 1.3.0+). The static skyline + canal decoration are kept;
the interactive layer goes away. */
minigames: false,

/* themeConfig is shallow-merged into the preset's defaults
(colorMode + navbar + footer). prism + mermaid land alongside. */
themeConfig: {
prism: {
theme: require('prism-react-renderer/themes/github'),
darkTheme: require('prism-react-renderer/themes/dracula'),
},
mermaid: {
theme: { light: 'default', dark: 'dark' },
},
},
});

/* createConfig doesn't pass-through arbitrary top-level fields; assign
markdown + onBrokenAnchors directly so they make it into the final
Docusaurus config. trailingSlash is left at the preset's default. */
config.onBrokenAnchors = 'warn';
config.markdown = {
mermaid: true,
/* Tutorial pages reference screenshots populated by
`tests/e2e/docs-screenshots.spec.ts`. The Playwright capture run
is separate from the docs build, so the build needs to succeed
even when a fresh checkout doesn't have every PNG yet. Warn
instead of failing — the absence is visible at preview time and
the capture spec brings everything back on demand. Flip to
'throw' once screenshots are committed. */
hooks: {
onBrokenMarkdownImages: 'warn',
},
};

module.exports = config;
59 changes: 59 additions & 0 deletions docs/intro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
sidebar_position: 1
---

# Nextcloud App Template

A starting point for building Nextcloud apps following ConductionNL
conventions — a manifest-first Vue 2 frontend rendered by CnAppRoot, an
OpenRegister data layer, a Dashboard widget, an admin settings panel, an
AI Chat Companion tool provider, and the full PHP + frontend quality
pipeline.

## What is this?

This is the **template every new Conduction app is scaffolded from**. It
ships:

- **A manifest-driven UI** — pages, navigation, and dependencies are
declared in `src/manifest.json`; the shell (CnAppRoot) reads the
manifest at boot and renders index / detail / dashboard / settings
pages without per-page Vue files.
- **A Dashboard widget** — a working `ExampleWidget` (PHP `IWidget`
class + webpack entry + `NcDashboardWidget` renderer) you copy and
rename.
- **Admin settings** — a settings panel wired through
`NcAppSettingsDialog`, backed by an OpenRegister settings register.
- **An MCP tool provider** — `ExampleToolProvider` exposes the app's
capabilities to the in-app AI Chat Companion over MCP.
- **OpenRegister integration** — `manifest.dependencies` lists
`openregister`, so the dependency-check phase ensures it is installed
before the UI mounts. Remove the entry if your app does not need it.
- **The quality pipeline** — PHPCS, PHPMD, Psalm, PHPStan, ESLint,
Stylelint, plus manifest/register/JSON-strict validators.
- **This documentation site** — Docusaurus on `@conduction/docusaurus-preset`,
the journeydoc tutorial scaffold, and a Playwright `docs-capture`
project for screenshots (ADR-030).

## Getting started

Clone the template, rename `app-template` to your slug, and build:

```bash
cd /var/www/html/custom_apps
git clone https://github.com/ConductionNL/nextcloud-app-template.git app-template
cd app-template
npm install && npm run build
php occ app:enable app-template
```

> OpenRegister must be installed first unless you remove the dependency
> from `src/manifest.json`, `appinfo/info.xml`, and `openspec/app-config.json`.

- New here? Start with the **[User guide](/docs/category/user-guide)** — open
the app for the first time.
- Setting things up? See the **[Admin guide](/docs/category/admin-guide)** —
manage the app's settings.

Free and open source under the EUPL-1.2 license. For support, contact
support@conduction.nl.
Loading
Loading