diff --git a/app/package-lock.json b/app/package-lock.json index 1c776b8..c19cfb4 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -14,7 +14,8 @@ "emdash": "^0.10.0" }, "devDependencies": { - "@astrojs/check": "^0.9.7" + "@astrojs/check": "^0.9.7", + "@types/node": "^22" } }, "node_modules/@astrojs/check": { @@ -3607,13 +3608,12 @@ } }, "node_modules/@types/node": { - "version": "25.9.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.1.tgz", - "integrity": "sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==", + "version": "22.19.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.19.tgz", + "integrity": "sha512-dyh/xO2Fh5bYrfWaaqGrRQQGkNdmYw6AmaAUvYeUMNTWQtvb796ikLdmTchRmOlOiIJ1TDXfWgVx1QkUlQ6Hew==", "license": "MIT", - "optional": true, "dependencies": { - "undici-types": ">=7.24.0 <7.24.7" + "undici-types": "~6.21.0" } }, "node_modules/@types/react": { @@ -9505,11 +9505,10 @@ "license": "MIT" }, "node_modules/undici-types": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", - "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==", - "license": "MIT", - "optional": true + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "license": "MIT" }, "node_modules/unified": { "version": "11.0.5", diff --git a/app/package.json b/app/package.json index 528be6d..ad81a12 100644 --- a/app/package.json +++ b/app/package.json @@ -22,6 +22,7 @@ "emdash": "^0.10.0" }, "devDependencies": { - "@astrojs/check": "^0.9.7" + "@astrojs/check": "^0.9.7", + "@types/node": "^22" } } diff --git a/app/seed/seed.json b/app/seed/seed.json index ab16a1e..7dfbb0f 100644 --- a/app/seed/seed.json +++ b/app/seed/seed.json @@ -47,13 +47,13 @@ "defaultValue": "proposed", "searchable": true, "options": [ - { "value": "port", "label": "Port — reimplement on target" }, - { "value": "built-in", "label": "Built-in — covered by target core" }, - { "value": "saas", "label": "SaaS — replaced by external service" }, - { "value": "drop", "label": "Drop — not needed" }, - { "value": "gated", "label": "Gated — pending decision" }, - { "value": "done", "label": "Done — ported and shipped" }, - { "value": "proposed", "label": "Proposed — newly submitted" } + { "value": "port", "label": "Port" }, + { "value": "built-in", "label": "Built-in" }, + { "value": "saas", "label": "SaaS" }, + { "value": "drop", "label": "Drop" }, + { "value": "gated", "label": "Gated" }, + { "value": "done", "label": "Done" }, + { "value": "proposed", "label": "Proposed" } ] }, { "slug": "source_repo_url", "label": "Source repo URL", "type": "string" }, diff --git a/app/src/components/PluginCard.astro b/app/src/components/PluginCard.astro index 3ff81be..3193a54 100644 --- a/app/src/components/PluginCard.astro +++ b/app/src/components/PluginCard.astro @@ -20,7 +20,7 @@ const d = entry.data;

{d.title}

- {d.source_cms && {d.source_cms} → {d.target_cms ?? "—"}} + {d.source_cms && {d.source_cms}{d.target_cms ? ` → ${d.target_cms}` : ""}}
{d.purpose &&

{d.purpose}

} diff --git a/app/src/components/StatusBadge.astro b/app/src/components/StatusBadge.astro index e26c833..5affb4c 100644 --- a/app/src/components/StatusBadge.astro +++ b/app/src/components/StatusBadge.astro @@ -8,4 +8,4 @@ const value = (status ?? "proposed").toLowerCase(); const label = STATUS_LABELS[value] ?? value; const desc = STATUSES.find((s) => s.value === value)?.desc; --- -Status: {label} +Status: {label}{desc ? ` — ${desc}` : ""}. {label} diff --git a/app/src/components/StatusLegend.astro b/app/src/components/StatusLegend.astro index d6860da..46371ec 100644 --- a/app/src/components/StatusLegend.astro +++ b/app/src/components/StatusLegend.astro @@ -1,9 +1,13 @@ --- import StatusBadge from "./StatusBadge.astro"; import { STATUSES } from "../lib/statuses"; +interface Props { + items?: typeof STATUSES; +} +const { items = STATUSES } = Astro.props; ---
- {STATUSES.map((i) => ( + {items.map((i) => ( {i.desc} ))}
diff --git a/app/src/lib/statuses.ts b/app/src/lib/statuses.ts index 7f70f16..b5c0008 100644 --- a/app/src/lib/statuses.ts +++ b/app/src/lib/statuses.ts @@ -1,3 +1,5 @@ +export const PLUGIN_FETCH_CAP = 10000; + export interface StatusDef { value: string; label: string; @@ -5,13 +7,13 @@ export interface StatusDef { } export const STATUSES: StatusDef[] = [ - { value: "port", label: "Port", desc: "must be reimplemented on the target CMS" }, - { value: "built-in", label: "Built-in", desc: "covered by target CMS core / framework" }, - { value: "saas", label: "SaaS", desc: "replaced by an external service" }, - { value: "drop", label: "Drop", desc: "not needed on the target CMS" }, - { value: "gated", label: "Gated", desc: "fate depends on an unresolved decision" }, - { value: "done", label: "Done", desc: "ported and shipped" }, - { value: "proposed", label: "Proposed", desc: "submitted for cataloging" }, + { value: "port", label: "Port", desc: "Reimplemented as a new Emdash plugin" }, + { value: "built-in", label: "Built-in", desc: "Already covered by Emdash core" }, + { value: "saas", label: "SaaS", desc: "Replaced by an external hosted service" }, + { value: "drop", label: "Drop", desc: "Not needed after migration" }, + { value: "gated", label: "Gated", desc: "Blocked on an open decision" }, + { value: "done", label: "Done", desc: "Ported and shipped" }, + { value: "proposed", label: "Proposed", desc: "Newly added, not yet classified" }, ]; export const STATUS_LABELS: Record = Object.fromEntries( diff --git a/app/src/pages/cms/[slug].astro b/app/src/pages/cms/[slug].astro index 516530f..f736eee 100644 --- a/app/src/pages/cms/[slug].astro +++ b/app/src/pages/cms/[slug].astro @@ -2,6 +2,7 @@ import { getEmDashCollection, getEmDashEntry, decodeSlug } from "emdash"; import Base from "../../layouts/Base.astro"; import PluginCard from "../../components/PluginCard.astro"; +import { PLUGIN_FETCH_CAP } from "../../lib/statuses"; export const prerender = false; @@ -14,7 +15,6 @@ if (!slug || !cms) { } if (cacheHint) Astro.cache.set(cacheHint); -const PLUGIN_FETCH_CAP = 10000; const { entries: all } = cms ? await getEmDashCollection("plugins", { orderBy: { title: "asc" }, limit: PLUGIN_FETCH_CAP }) : { entries: [] }; @@ -36,6 +36,7 @@ const targetingHere = all.filter((p) => p.data.target_cms === cmsName); {cms.data.description &&

{cms.data.description}

}

Plugins from this CMS ({fromHere.length})

+

Filter these in the catalog

{fromHere.length === 0 ? (

No plugins cataloged for this CMS yet.

) : ( diff --git a/app/src/pages/cms/index.astro b/app/src/pages/cms/index.astro index 3654ebd..ec01823 100644 --- a/app/src/pages/cms/index.astro +++ b/app/src/pages/cms/index.astro @@ -1,6 +1,7 @@ --- import { getEmDashCollection } from "emdash"; import Base from "../../layouts/Base.astro"; +import { PLUGIN_FETCH_CAP } from "../../lib/statuses"; export const prerender = false; @@ -9,7 +10,6 @@ const { entries: cmses, cacheHint } = await getEmDashCollection("cmses", { }); Astro.cache.set(cacheHint); -const PLUGIN_FETCH_CAP = 10000; const { entries: plugins } = await getEmDashCollection("plugins", { limit: PLUGIN_FETCH_CAP }); if (plugins.length >= PLUGIN_FETCH_CAP) console.warn("[cms] plugin fetch hit cap", PLUGIN_FETCH_CAP, "- counts/lists may be truncated"); const countBySource = new Map(); @@ -23,11 +23,12 @@ for (const p of plugins) { ---

By CMS

+

CMSes