@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.
@@ -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>;