feat(manifest): quick-filter tabs + "link" widget + built-in date formatters + readOnly + pages[].permission (closes #224)#226
Merged
Conversation
…matters + readOnly shorthand + pages[].permission §1–7 of the `manifest-index-page-followups` opsx change — a tight bundle of small additions surfaced by the fleet conversion wave (pipelinq #351, procest #436, scholiq #71, zaakafhandelapp #203, softwarecatalog #231, decidesk #197). - **Quick-filter tabs** (REQ-MIPFU-1): `type:"index"` pages gain `config.quickFilters: [{label, filter, default?, icon?}]`. CnIndexPage renders the new `CnQuickFilterBar` above the table; the active tab's `filter` is merged into the useListView fetch AFTER `config.filter` (so the tab wins) and BEFORE the user's `activeFilters` (which still narrow within the active tab). `@route.<name>` resolution parity with `config.filter`. Closes procest's filter-tabs gap (Voorstellen tabs were dropped in the conversion — `config.filter` is fixed, not switchable). - **Built-in `widget:"link"`** (REQ-MIPFU-2): `CnCellRenderer` resolves `widget:"link"` to a `<router-link>` (when `widgetProps.route` is a manifest page id; default `id` param from the new `rowKey` prop; override via `widgetProps.params: {routeParam: "rowField"}`) / external `<a target="_blank">` (when `widgetProps.href` is set, with `{key}` placeholder substitution from the row) / plain-text fallback + once-per-session `console.warn` (silence with `widgetProps.fallback:"silent"`). Consumer-registered `link` still wins. Resolves decidesk's `Decisions.title widget:"link"` no-op. - **Built-in `"date"` / `"datetime"` / `"relative-time"` formatters** (REQ-MIPFU-3): `CnAppRoot` provides `cnFormatters` as `{...BUILT_IN_FORMATTERS, ...props.formatters}` so consumer overrides win. All three are safe against null/empty/non-parseable inputs (`Intl.DateTimeFormat` / `Intl.RelativeTimeFormat`; return '' or original value, no throw). Resolves decidesk's `Decisions.decisionDate formatter:"date"` no-op. - **`config.readOnly:true` shorthand** (REQ-MIPFU-4): `CnPageRenderer` expands `config.readOnly:true` on a `type:"index"` page to `selectable:false, showAdd:false, showFormDialog:false, showEditAction:false, showCopyAction:false, showDeleteAction:false, showMassImport:false, showMassCopy:false, showMassDelete:false` — merged UNDER explicit `config.*` props so an explicit `config.showAdd:true` still wins. Replaces the 9-line CRUD-off boilerplate scholiq#71 had to spell out for its read-only pages. - **`pages[].permission`** (REQ-MIPFU-5): the page schema's $defs.page (additionalProperties:false) now allows an optional `permission: <string>`. Schema-only — no runtime gating (consumers filter the manifest themselves if they want enforcement). Resolves procest's WmsLayers* / LhsMatrices* validation errors. - **`handler:"emit"`** (REQ-MIPFU-6): verified the existing `CnIndexPage.mergedActions` already strips the `handler` key for `"emit"` so the page emits `@action` only. No code change — spec scenario updated to match the existing payload shape (`{action: <label>, row: <item>}`). Verification: 91 suites / 1294 tests green (27 new); npm run lint — 0 errors (was 2; fixed); npm run build ✓; npm run check:docs — 89/89 components; openspec validate passes.
Contributor
|
🎉 This PR is included in version 1.0.0-beta.42 🎉 The release is available on:
Your semantic-release bot 📦🚀 |
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.
What
§1–7 of the
manifest-index-page-followupsopsx change — closes #224. A tight bundle of small additions surfaced by the fleet conversion wave (pipelinq #351, procest #436, scholiq #71, zaakafhandelapp #203, softwarecatalog #231, decidesk #197).1. Quick-filter tabs (
config.quickFilters) — REQ-MIPFU-1type:"index"pages gainconfig.quickFilters: [{label, filter, default?, icon?}].CnIndexPagerenders the newCnQuickFilterBarabove the table; the active tab'sfilteris merged into theuseListViewfetch afterconfig.filter(so the tab wins on a colliding key) and before the user'sactiveFilters(which still narrow within the active tab).@route.<name>resolution parity withconfig.filter. Closes procest's filter-tabs gap (Voorstellen's Concept/InBehandeling/Afgerond tabs were dropped in the conversion —config.filteris fixed, not switchable; this is the missing piece).2. Built-in
widget:"link"— REQ-MIPFU-2CnCellRendererresolveswidget:"link"to:<router-link>whenwidgetProps.routeis set (a manifest page id; default{id: row[rowKey]}param map; override viawidgetProps.params: {routeParam: "rowField"})<a target="_blank" rel="noopener">whenwidgetProps.hrefis set (with{key}placeholder substitution from the row)console.warn(silence withwidgetProps.fallback:"silent")Consumer-registered
linkstill wins. Resolves decidesk'sDecisions.title widget:"link"no-op.3. Built-in
"date"/"datetime"/"relative-time"formatters — REQ-MIPFU-3CnAppRootprovidescnFormattersas{...BUILT_IN_FORMATTERS, ...props.formatters}so consumer overrides win. All three are safe against null / empty / non-parseable inputs (Intl.DateTimeFormat/Intl.RelativeTimeFormat; return''or the original value, no throw). Resolves decidesk'sDecisions.decisionDate formatter:"date"no-op.4.
config.readOnly:trueshorthand — REQ-MIPFU-4CnPageRendererexpandsconfig.readOnly:trueon atype:"index"page toselectable:false, showAdd:false, showFormDialog:false, showEditAction:false, showCopyAction:false, showDeleteAction:false, showMassImport:false, showMassCopy:false, showMassDelete:false— merged under explicitconfig.*props so an explicitconfig.showAdd:truestill wins. Replaces the 9-line CRUD-off boilerplate scholiq #71 had to spell out for its read-only AssessmentResults / LearningPlanEvaluations / Signatures pages.5.
pages[].permission— REQ-MIPFU-5$defs.page(additionalProperties:false) now allows an optionalpermission: <string>. Schema-only — no runtime gating (consumers filter the manifest themselves if they want enforcement). Resolves procest'sWmsLayers*/LhsMatrices*validation errors.6.
handler:"emit"— REQ-MIPFU-6Verified the existing
CnIndexPage.mergedActionsalready strips thehandlerkey for"emit"(and unknown / non-resolvable handlers) →CnRowActionsdoesn't see a function → page emits@actiononly. No code change needed; spec scenario updated to match the existing{action: <label>, row: <item>}payload shape.Verification
npm test— 91 suites / 1294 tests green (no regression; +27 new — formatters 12, CnPageRenderer readOnly 3, CnCellRenderer link 5, CnIndexPage quickFilters 7)npm run lint— 0 errors (was 2 from the new<a>attribute wrap; fixed). 306 warnings are all pre-existing.npm run build— ✓ (dist/nextcloud-vue.esm.js+dist/nextcloud-vue.cjs.jscreated)npm run check:docs— 89/89 component docs cover their props and slots (addedCnQuickFilterBar;rowKey+quickFiltersprops documented)openspec validate manifest-index-page-followups— validopsx
openspec/changes/manifest-index-page-followups/— proposal, design, specs (REQ-MIPFU-1…6), tasks all included.Closes #224.
🤖 Generated with Claude Code