Skip to content

Add frontend-extensibility probes to RedHerb#781

Merged
JeroenDeDauw merged 5 commits intofrontend-extensibilityfrom
redherb-sidebar-panel
Apr 28, 2026
Merged

Add frontend-extensibility probes to RedHerb#781
JeroenDeDauw merged 5 commits intofrontend-extensibilityfrom
redherb-sidebar-panel

Conversation

@malberts
Copy link
Copy Markdown
Collaborator

@malberts malberts commented Apr 26, 2026

Result of extensive back-and-forth with @malberts.
Context: the NeoWiki codebase and live browser verification of every integration point.
Written by Claude Code, Opus 4.7 (1M context)

Follows-up to #754

Adds three RedHerb sidebar entries that act as permanent integration probes for the JavaScript extension surface introduced by #754. RedHerb (tests/RedHerb/) is NeoWiki's in-tree extension whose purpose is to be a working example of how to consume NeoWiki's extension points; everything in it lives alongside the codebase as ongoing validation. The entries are deliberately contrived — they are not user-facing features and a real extension would build a different UI on top of the same primitives — but they exercise concrete pieces of the public-API barrel end-to-end.

What the probes do

  • Find a subject is always present. Routes to a new Special:RedHerbSubjectFinder page where a panel lets the user pick a subject by schema and label, then renders the selected subject using NeoWiki's Infobox view component.
  • Create child Company is shown on every existing wiki page. Opens a RedHerb-owned dialog pinning the Company schema and reusing NeoWiki's SubjectEditor. On save it calls subjectStore.createChildSubject through the shared Pinia, persisting the new child via the SubjectRepository REST path.
  • Edit main subject is shown only on pages that already have a main subject — the sidebar hook calls NeoWikiExtension::newViewHtmlBuilder()->pageHasMainSubject() to decide (RedHerb's first PHP-side runtime API consumption). Click opens a RedHerb-owned dialog wrapping SubjectEditor pre-populated with the existing main subject's statements. On save it calls subjectStore.updateSubject, and NeoWiki's existing Infobox on the same page reactively re-renders without a reload.

Integration points exercised through the public-API barrel

Surface Used here
Shared Pinia owned by NeoWikiExtension Cross-boundary mutation observed empirically (creator dialog opens; child subject persists; main-subject edits flow back into NeoWiki's Infobox without reload)
Reactive view sync across the boundary RedHerb mutates a Subject via subjectStore.updateSubject; NeoWiki's Infobox on the same page re-renders live, proving the shared store drives reactivity end-to-end
REST repositories RestSubjectLabelSearch via the embedded SubjectLookup; RestSubjectRepository via subjectStore.createChildSubject (POST) and subjectStore.updateSubject (PATCH) and StoreStateLoader. The other repos in the barrel use the same import chain and HttpClient, so exercising more is more of the same coverage.
Application services SubjectLabelSearch, PropertyTypeRegistry, SubjectAuthorizer (transitively via SubjectEditor/Infobox)
Pinia stores useSubjectStore (read + create + update), useSchemaStore
Vue components SubjectLookup, Infobox, SubjectEditor
Vue.createMwApp from RedHerb Three RedHerb-owned mounts, each with app.use( ext.getPinia() ) and NeoWikiServices.registerServices( app )
PHP-side runtime API NeoWikiExtension::newViewHtmlBuilder()->pageHasMainSubject() consumed by RedHerbSidebarHook to gate the conditional Edit link
MW SidebarBeforeOutput hook New RedHerbSidebarHook
MW NeoWikiGetFrontendModules hook New RedHerbFrontendModulesHook adds the global RedHerb modules on every NeoWiki page
MW SpecialPage registration New Special:RedHerbSubjectFinder

Cross-boundary Pinia sharing recipe

  1. Visit any content page that has a main subject (e.g. ACME Inc).
  2. Click Create child Company in the RedHerb sidebar section.
  3. Fill in the dialog (Label, optional Status etc.) and submit.
  4. The dialog closes and the new child appears on ?action=subjects for the same page.

The dialog and subjectStore.createChildSubject are owned by separate Vue apps mounted by RedHerb and by NeoWiki respectively. They observe the same store because they share a Pinia instance owned by NeoWikiExtension (the singleton routing was added to #754).

Screenshots

  • Sidebar links:
redherb-sidebar-three-entries * Sidebar entries on a content page, dialog open showing `SubjectEditor` for Company: redherb-create-child-dialog * Subjects action page showing the persisted child after save: redherb-create-child-success * `Special:RedHerbSubjectFinder` lookup with `Infobox` rendering of the selected subject: redherb-special-page-final

@malberts malberts changed the title Add RedHerb sidebar with subject finder and Create-child-Company action Add RedHerb sidebar integration probes Apr 26, 2026
@malberts malberts changed the title Add RedHerb sidebar integration probes Add frontend-extensibility probes to RedHerb Apr 26, 2026
@malberts malberts marked this pull request as ready for review April 26, 2026 21:56
@malberts malberts force-pushed the redherb-sidebar-panel branch from 65d5e4a to af16370 Compare April 27, 2026 09:22
malberts and others added 4 commits April 27, 2026 11:56
Adds a SidebarBeforeOutput hook handler contributing a "RedHerb"
sidebar section with a "Find a subject" link to a new
Special:RedHerbSubjectFinder. The special page mounts a RedHerb-owned
Vue panel via Vue.createMwApp that lets the user pick a subject by
schema and label, then renders the selected subject using NeoWiki's
Infobox component.

Exercises several integration points through the public-API barrel
introduced by #754: RestSubjectLabelSearch (REST repository) via the
embedded SubjectLookup component, the SubjectLabelSearch service via
NeoWiki's service injection, the StoreStateLoader for bulk-loading
subjects and schemas, the Infobox view component, and the shared
Pinia owned by NeoWikiExtension.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a second sidebar entry that opens a RedHerb-owned dialog on the
current page, pinning the Company schema and reusing NeoWiki's
SubjectEditor and stores via the public-API barrel. On save it calls
subjectStore.createChildSubject through the shared Pinia, which hits
the SubjectRepository REST path to persist the new child subject.

A small global RedHerb ResourceLoader module attaches itself to every
NeoWiki content page through a NeoWikiGetFrontendModules hook, listens
for clicks on the sidebar trigger, and mounts the dialog on first use.
The CdxTooltip directive is registered on RedHerb's Vue mounts so the
SubjectEditor inputs do not emit "directive: tooltip" warnings.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a third RedHerb sidebar entry that is only present when the
current page has a main subject. Click opens a RedHerb-owned dialog
wrapping NeoWiki's SubjectEditor, pre-populated with the main
subject's existing statements. On save it calls subjectStore action,
which both persists via the SubjectRepository PATCH path and updates
the shared Pinia. NeoWiki's Infobox on the same page reactively
re-renders without a page reload — the empirical proof of
cross-boundary store sync.

Adds the first PHP-side runtime API consumption from RedHerb: the
sidebar hook calls NeoWikiExtension::newViewHtmlBuilder()::
pageHasMainSubject() to gate the conditional link.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous implementation hid the link on pages without a main
subject and showed an mw.notify warning when clicked. That was
overly restrictive: NeoWiki's data model lets a page hold child
subjects without a main, and there is no API gate. The link now
appears on every existing wiki page; pages without a main subject
keep the Find-a-subject link only when the title cannot exist.

Repurpose the now-misnamed redherb-create-child-not-eligible key as
redherb-create-child-error: the catch in CreateChildDialog renders
it after any save failure, which is what it actually means.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@malberts malberts force-pushed the redherb-sidebar-panel branch from af16370 to 058fac0 Compare April 27, 2026 10:13
@malberts malberts marked this pull request as draft April 27, 2026 12:03
Each RedHerb dialog had a tiny Pinia store (one boolean, occasionally
plus a subject id) for its own open/close state. That was the wrong
tool: those stores are not shared across the boundary, have one
consumer each, and pretend to be cross-cutting state when they are
not. Pinia is meant for genuinely shared stores (which RedHerb
already gets via NeoWikiExtension's singleton — that part stays).

Replace the local stores with a Vue ref/reactive object owned by
each module's init.js and handed to the dialog SFC via app.provide()
+ vue.inject(). Same reactivity, no extra files, and the remaining
Pinia usage in RedHerb correctly signals "we are talking to NeoWiki's
stores".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants