@pramen/cms-editor 0.0.60 → 0.0.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -3
- package/dist/editor.css +1 -1
- package/dist/editor.js +155 -155
- package/package.json +3 -2
- package/src/api.ts +23 -6
- package/src/app-context.tsx +4 -0
- package/src/app.css +48 -0
- package/src/breadcrumb.tsx +48 -0
- package/src/chrome.ts +27 -0
- package/src/components.tsx +624 -183
- package/src/cover.tsx +163 -0
- package/src/furniture.tsx +121 -27
- package/src/icons.tsx +97 -0
- package/src/nav.ts +149 -15
- package/src/page-header.tsx +128 -0
- package/src/preview.ts +65 -0
- package/src/routes/_layout.tsx +511 -93
- package/src/routes/page.tsx +4 -0
- package/src/types.ts +62 -0
package/src/routes/page.tsx
CHANGED
|
@@ -73,6 +73,10 @@ export default createPage()
|
|
|
73
73
|
tab={tab}
|
|
74
74
|
onTab={setTab}
|
|
75
75
|
onBack={backToList}
|
|
76
|
+
// Named for where it actually goes. On a per-type deployment `backToList` lands in
|
|
77
|
+
// this page's OWN type list, and a button labelled "Pages" then named a pooled list
|
|
78
|
+
// that deployment does not have.
|
|
79
|
+
backLabel={splitsByType(contentTypes, cms) && ownType ? ownType.name : "Pages"}
|
|
76
80
|
onChange={setPage}
|
|
77
81
|
registerGuard={setNavGuard}
|
|
78
82
|
/>
|
package/src/types.ts
CHANGED
|
@@ -209,6 +209,11 @@ export interface CmsCapabilities {
|
|
|
209
209
|
* configured. Without it a reviewer-only session gets the authoring nav and every screen
|
|
210
210
|
* 403s on its first save. */
|
|
211
211
|
canEdit: boolean;
|
|
212
|
+
/** The server has `listMediaTerms`/`setMediaTerms`, and `listMedia` understands `term`.
|
|
213
|
+
* Declared like `siteFurniture`: on an older server the detail panel's Tags section would
|
|
214
|
+
* 404 the moment a file is opened, and the library's tag filter would send an argument
|
|
215
|
+
* that is silently ignored — a control that visibly does nothing. */
|
|
216
|
+
mediaTerms: boolean;
|
|
212
217
|
}
|
|
213
218
|
|
|
214
219
|
/**
|
|
@@ -244,6 +249,7 @@ export const DEFAULT_CAPABILITIES: CmsCapabilities = {
|
|
|
244
249
|
pagesByType: false,
|
|
245
250
|
siteFurniture: false,
|
|
246
251
|
codeDefinedTypes: false,
|
|
252
|
+
mediaTerms: false,
|
|
247
253
|
// Fails OPEN, unlike its neighbours. An older server sends no `canEdit`, and hiding
|
|
248
254
|
// every authoring control from a real editor is unrecoverable from inside the editor;
|
|
249
255
|
// showing one that 403s is a legible error with a way forward. The server is the
|
|
@@ -371,8 +377,25 @@ export interface Taxonomy {
|
|
|
371
377
|
pluralLabel?: string | null;
|
|
372
378
|
description?: string | null;
|
|
373
379
|
hierarchical?: boolean;
|
|
380
|
+
/** What this vocabulary classifies. `null`/absent means EVERYTHING — a vocabulary that was
|
|
381
|
+
* never narrowed, and the reading for a row written before the column existed. */
|
|
382
|
+
appliesTo?: TaxonomyTarget[] | null;
|
|
374
383
|
}
|
|
375
384
|
|
|
385
|
+
/** Mirror of @pramen/cms `TAXONOMY_TARGETS` — the object types a vocabulary can classify.
|
|
386
|
+
* Mirrored rather than imported for the reason at the top of this file: the editor is a
|
|
387
|
+
* standalone browser app with no server-package dependency. The server is the authority; an
|
|
388
|
+
* unknown value here would just render an unchecked box it refuses to save. */
|
|
389
|
+
export const TAXONOMY_TARGETS = ["page", "media"] as const;
|
|
390
|
+
export type TaxonomyTarget = (typeof TAXONOMY_TARGETS)[number];
|
|
391
|
+
|
|
392
|
+
/** What each target is called on screen — plural, because each names the SET of things the
|
|
393
|
+
* vocabulary would classify. */
|
|
394
|
+
export const TAXONOMY_TARGET_LABELS = {
|
|
395
|
+
page: "Pages",
|
|
396
|
+
media: "Media",
|
|
397
|
+
} satisfies Record<TaxonomyTarget, string>;
|
|
398
|
+
|
|
376
399
|
export interface Term {
|
|
377
400
|
id: string;
|
|
378
401
|
taxonomyId: string;
|
|
@@ -459,3 +482,42 @@ export interface AdminPageMeta {
|
|
|
459
482
|
icon?: string;
|
|
460
483
|
navOrder?: number;
|
|
461
484
|
}
|
|
485
|
+
|
|
486
|
+
// --- media sorting and filtering -----------------------------------------------------------
|
|
487
|
+
//
|
|
488
|
+
// Mirrors of the vocabularies `listMedia` accepts in @pramen/cms. Mirrored rather than
|
|
489
|
+
// imported for the reason at the top of this file — the editor is a standalone browser app
|
|
490
|
+
// with no server-package dependency — and checked against the originals in
|
|
491
|
+
// `test/cms-editor-mirrors.test.ts`, because a duplicate nobody verifies is a latent bug with
|
|
492
|
+
// a comment on it.
|
|
493
|
+
//
|
|
494
|
+
// The server treats an unrecognised value as absent, so a drift here degrades to the default
|
|
495
|
+
// order rather than to an error. That is the failure worth having, and it is still a failure:
|
|
496
|
+
// a sort the editor offers and the server drops is a control that silently does nothing.
|
|
497
|
+
|
|
498
|
+
/** How the media library may be ordered. */
|
|
499
|
+
export const MEDIA_SORTS = ["newest", "oldest", "name", "name_desc", "largest", "smallest"] as const;
|
|
500
|
+
export type MediaSort = (typeof MEDIA_SORTS)[number];
|
|
501
|
+
|
|
502
|
+
/** What each sort is called on screen. */
|
|
503
|
+
export const MEDIA_SORT_LABELS = {
|
|
504
|
+
newest: "Newest first",
|
|
505
|
+
oldest: "Oldest first",
|
|
506
|
+
name: "Name A–Z",
|
|
507
|
+
name_desc: "Name Z–A",
|
|
508
|
+
largest: "Largest first",
|
|
509
|
+
smallest: "Smallest first",
|
|
510
|
+
} satisfies Record<MediaSort, string>;
|
|
511
|
+
|
|
512
|
+
/** The coarse type buckets the library filters by. */
|
|
513
|
+
export const MEDIA_KINDS = ["image", "video", "audio", "document", "other"] as const;
|
|
514
|
+
export type MediaKind = (typeof MEDIA_KINDS)[number];
|
|
515
|
+
|
|
516
|
+
/** …and their labels. Plural, because each names a SET the filter narrows to. */
|
|
517
|
+
export const MEDIA_KIND_LABELS = {
|
|
518
|
+
image: "Images",
|
|
519
|
+
video: "Video",
|
|
520
|
+
audio: "Audio",
|
|
521
|
+
document: "Documents",
|
|
522
|
+
other: "Other",
|
|
523
|
+
} satisfies Record<MediaKind, string>;
|