The fifth plugin out, and the cheapest so far — offscale's shape rather than
music's or vault's. Nothing stayed behind and nothing had to be redesigned,
for three structural reasons recorded in PLUGIN.md:
• No reverse dependency. Nothing in src/ imported anything of photos'.
• Configuration was already right. The URL and API key live in photos_config,
a per-user registry encrypted at rest and driven from the app. Vault had to
move VAULTWARDEN_URL out of .env and invent a settings panel; here the
sidecar already read the database, and its own comment already said why
nothing reads process.env.
• The frontend was already panels. The screen was a WorkspaceView around
exactly photos-nav and photos-view, so web/panels.ts and web/layout.ts are
the screen's contents with the wrapper removed.
The router's prefix is now derived from mountPrefix rather than the literal
'/api/photos', which was correct only by coincidence — a third-party publisher
mounts at /api/p/<publisher>/photos and the literal would forward the wrong
path to the sidecar.
Palette debt paid down as the runbook requires: 6 classes (it says 47; someone
had already done most of it), all of them state colours wearing palette
numbers, now `success` and `warning` from the closed tone set so they follow
the theme.
Immich itself is still provisioned by the app store rather than by this plugin
— the `provisioned` half of its old catalogue entry has no home until Docker
provisioning for plugins exists. Point it at an instance you already run.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
23 lines
948 B
TypeScript
23 lines
948 B
TypeScript
import type { AppRegistryMeta } from 'officerdev';
|
|
import { PanelLeft, LayoutGrid } from 'lucide-react';
|
|
import { PhotosNav } from './PhotosNav';
|
|
import { PhotosView } from './PhotosView';
|
|
import { PhotosViewHeader } from './PhotosViewHeader';
|
|
|
|
// `panels.ts`, not `.tsx` — discovery checks for that exact name. Two panels: a section nav on the left
|
|
// and the view on the right, both reading `:section` from the URL rather than being told by each other.
|
|
//
|
|
// `availableOnPanel: false` on both, because the screen renders the workspace `locked` — these are not
|
|
// swappable, and offering them in a picker would be a lie.
|
|
export const appRegistryMetas: AppRegistryMeta[] = [
|
|
{ key: 'photos-nav', name: 'Photos', icon: PanelLeft, component: PhotosNav, availableOnPanel: false },
|
|
{
|
|
key: 'photos-view',
|
|
name: 'Photos',
|
|
icon: LayoutGrid,
|
|
component: PhotosView,
|
|
header: PhotosViewHeader,
|
|
availableOnPanel: false,
|
|
},
|
|
];
|