Bump the contract for the new gate, and close the ways it could read as open
CI / full-gate (push) Successful in 2m45s
CI / full-gate (push) Successful in 2m45s
This commit is contained in:
@@ -26,10 +26,6 @@ What it demonstrates:
|
||||
The plugin holds **no state** — data lives upstream (README → *Stateless*). Handlers are thin and
|
||||
`fetch` is injectable, so they unit-test as pure functions (`shifts.test.ts`).
|
||||
|
||||
The shifts list and "My shifts" repeat a little view-model and markup rather than sharing a
|
||||
parameterised one: an example is read far more often than it is changed, and each page is meant to be
|
||||
followed top to bottom on its own.
|
||||
|
||||
## Upstream
|
||||
|
||||
Set `PLUGIN_SETTING_SCHEDULING_UPSTREAM` to your backend's base URL. The dev compose points it at a tiny in-memory
|
||||
|
||||
@@ -12,7 +12,7 @@ let upstreamUrl = "";
|
||||
const upstream = createUpstream(() => upstreamUrl);
|
||||
|
||||
export default definePlugin({
|
||||
apiVersion: "0.3.0", // the host contract this was built against — a literal, never HOST_API_VERSION
|
||||
apiVersion: "0.4.0", // the host contract this was built against — a literal, never HOST_API_VERSION
|
||||
|
||||
// onBoot runs after discovery, before the server listens — where a plugin receives its resolved
|
||||
// settings. A malformed URL already failed the boot by then; the host validated the declared type.
|
||||
@@ -39,8 +39,6 @@ export default definePlugin({
|
||||
{ description: "Create and edit shifts", name: WRITE },
|
||||
],
|
||||
|
||||
// Mounted under /scheduling; `permission` gates before the handler runs. The overview is `public`
|
||||
// (anyone may reach /scheduling, signed in or not); the rest need a permission.
|
||||
routes: [
|
||||
{ handler: overview(), method: "GET", path: "/", public: true },
|
||||
{ handler: myShifts(upstream), method: "GET", path: "/mine", session: true },
|
||||
|
||||
@@ -218,7 +218,8 @@ export function buildMineModel(opts: { chrome: PageChrome; email: string; error?
|
||||
table: {
|
||||
caption: t("scheduling.mine.title"),
|
||||
columns: [{ label: t("scheduling.table.shift") }, { label: t("scheduling.table.start") }, { label: t("scheduling.table.end") }],
|
||||
emptyText: t("scheduling.mine.empty", { email: opts.email }),
|
||||
// Only when the upstream answered: a failed read knows nothing about what is assigned.
|
||||
...(opts.error === undefined ? { emptyText: t("scheduling.mine.empty", { email: opts.email }) } : {}),
|
||||
rows: opts.shifts.map((s) => ({ cells: [{ rowHeader: { text: s.title } }, s.start, s.end], name: s.title })),
|
||||
},
|
||||
title: t("scheduling.mine.title"),
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<%#
|
||||
Scheduling · the visitor's own shifts (reference plugin). Reached behind `session: true`, so
|
||||
ctx.user is always set by the time this renders.
|
||||
Scheduling · the visitor's own shifts (reference plugin).
|
||||
Data: chrome, title, breadcrumbs, count, table, error?
|
||||
%><%
|
||||
const navHtml = include("partials/nav-tree", { nodes: chrome.nav });
|
||||
|
||||
Reference in New Issue
Block a user