@knkcs/mediahub-ui 0.2.0 → 0.3.0

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/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ import { JSX } from 'react';
3
3
  import { PersistOptions } from 'zustand/middleware';
4
4
  import { QueryClient } from '@tanstack/react-query';
5
5
  import { ReactNode } from 'react';
6
+ import { Schema } from '@knkcs/fieldkit/schema';
6
7
  import { StatusInfo } from '@knkcs/statushub-ui';
7
8
  import { StoreApi } from 'zustand';
8
9
  import { TFunction } from 'i18next';
@@ -365,6 +366,97 @@ export declare interface AssetTypeClient {
365
366
  delete(id: string): Promise<void>;
366
367
  }
367
368
 
369
+ /**
370
+ * Create an asset type. The screen the package owns, replacing the
371
+ * standalone's create dialog and core's create page (knkCS/mediahub#137/#140).
372
+ *
373
+ * The slug follows the name until it is edited by hand and then stops — the
374
+ * unconditional overwrite the standalone had silently discarded a slug someone
375
+ * typed on purpose. The server's rule (lowercase alphanumeric with hyphens, at
376
+ * least two characters) is stated on the form and enforced before submit,
377
+ * because without both a name like `Bild Anhang` produced a bare 400
378
+ * (knkcms/core#861).
379
+ */
380
+ export declare function AssetTypeCreate({ assetTypesPath, onCreated, onCancel, }: AssetTypeCreateProps): default_2.JSX.Element;
381
+
382
+ export declare namespace AssetTypeCreate {
383
+ var displayName: string;
384
+ }
385
+
386
+ export declare interface AssetTypeCreateProps {
387
+ /**
388
+ * The host's asset-type index path — used as the breadcrumb's target. A
389
+ * path, not a route: the screen never navigates, it only says where the
390
+ * list it belongs to lives (core's `docs/service-integration.md`).
391
+ */
392
+ assetTypesPath: string;
393
+ /** Called with the created asset type; the host decides where to go. */
394
+ onCreated?: (assetType: AssetTypeInfo) => void;
395
+ /** Called when the administrator abandons the form. */
396
+ onCancel?: () => void;
397
+ }
398
+
399
+ /**
400
+ * The packaged asset-type detail screen: view, edit and delete one asset type,
401
+ * with its fieldkit metadata schema on a second tab.
402
+ *
403
+ * **Correct against the wire, not against the declared type.** Connect omits
404
+ * empty repeated fields and empty strings from its JSON, and a host client that
405
+ * returns the wire object unmapped therefore delivers `undefined` where
406
+ * `AssetTypeInfo` promises `string` or `string[]`. Reading one of those
407
+ * unguarded is what took core's detail page down (knkcms/core#862, #863).
408
+ * Every field below is defaulted at the one place it is read, so an absent
409
+ * value renders as empty rather than throwing — and never flips a controlled
410
+ * input to uncontrolled, which is the quieter version of the same bug.
411
+ */
412
+ export declare function AssetTypeDetail({ typeId, assetTypesPath, onBack, onDeleted, }: AssetTypeDetailProps): default_2.JSX.Element;
413
+
414
+ export declare namespace AssetTypeDetail {
415
+ var displayName: string;
416
+ }
417
+
418
+ export declare interface AssetTypeDetailProps {
419
+ /** The asset type to show. */
420
+ typeId: string;
421
+ /**
422
+ * Typed path of the host's asset-type index, used for the breadcrumb back
423
+ * link. The screen never routes itself — the host owns its URLs
424
+ * (core's `docs/service-integration.md`).
425
+ */
426
+ assetTypesPath?: string;
427
+ /**
428
+ * Navigate back to the asset-type index. Given one, the screen renders a
429
+ * back affordance that confirms before discarding unsaved edits — the
430
+ * breadcrumb link above is the host's own navigation and the screen cannot
431
+ * intercept it.
432
+ */
433
+ onBack?: () => void;
434
+ /** Called after a successful delete; the host decides where to go next. */
435
+ onDeleted?: () => void;
436
+ }
437
+
438
+ /**
439
+ * The workspace's asset types, listed. The package owns the screen; both hosts
440
+ * compose it and keep their own routing to themselves (#142, parent #138).
441
+ */
442
+ export declare function AssetTypeIndex(props: AssetTypeIndexProps): React.JSX.Element;
443
+
444
+ export declare namespace AssetTypeIndex {
445
+ var displayName: string;
446
+ }
447
+
448
+ export declare interface AssetTypeIndexProps {
449
+ /**
450
+ * An asset type was opened. The host decides what that means — it receives
451
+ * the id and nothing else, because this package must not know either host's
452
+ * URL structure (core's `docs/service-integration.md`; spec #138). Screens,
453
+ * not routes: nothing here navigates and nothing here builds a path.
454
+ */
455
+ onOpen?: (assetTypeId: string) => void;
456
+ /** The reader asked for a new asset type. Same contract as `onOpen`. */
457
+ onCreate?: () => void;
458
+ }
459
+
368
460
  export declare interface AssetTypeInfo {
369
461
  id: string;
370
462
  workspaceId: string;
@@ -840,6 +932,19 @@ declare interface FolderTreeProps {
840
932
  onFolderSelect: (folderId: string) => void;
841
933
  }
842
934
 
935
+ /**
936
+ * Takes `string[] | undefined` although `AssetTypeInfo.allowedMimeTypes` is
937
+ * declared `string[]`, because a host client may return the wire object
938
+ * unmapped under that type. Connect omits an empty repeated field from the
939
+ * JSON, so an asset type with no MIME types arrives without the key at all and
940
+ * the declared type is a lie. The package's own client maps through
941
+ * `mapAssetType`, which defaults it; core's did not, and the detail page went
942
+ * down on "Cannot read properties of undefined (reading 'join')"
943
+ * (knkcms/core#863). Tolerating the absent list here is the fix, kept in one
944
+ * place for every host.
945
+ */
946
+ export declare const formatMimeTypeList: (value: string[] | undefined) => string;
947
+
843
948
  export declare interface GetUploadUrlParams {
844
949
  assetId: string;
845
950
  filename: string;
@@ -945,6 +1050,38 @@ export declare const i18nResources: {
945
1050
  unknownValue: string;
946
1051
  };
947
1052
  };
1053
+ assetTypeDetail: {
1054
+ breadcrumbAssetTypes: string;
1055
+ notFound: string;
1056
+ untitled: string;
1057
+ backButtonAria: string;
1058
+ generalTab: string;
1059
+ metadataTab: string;
1060
+ nameLabel: string;
1061
+ nameRequired: string;
1062
+ slugLabel: string;
1063
+ descriptionLabel: string;
1064
+ descriptionPlaceholder: string;
1065
+ allowedMimeTypesLabel: string;
1066
+ allowedMimeTypesDescription: string;
1067
+ activeLabel: string;
1068
+ save: string;
1069
+ delete: string;
1070
+ saveSuccessToast: string;
1071
+ saveFailedToast: string;
1072
+ schemaSavedToast: string;
1073
+ deleteConfirmTitle: string;
1074
+ deleteConfirmMessage: string;
1075
+ deleteConfirmLabel: string;
1076
+ deleteSuccessToast: string;
1077
+ deleteFailedToast: string;
1078
+ discardSchemaConfirmTitle: string;
1079
+ discardSchemaConfirmMessage: string;
1080
+ discardSchemaConfirmLabel: string;
1081
+ discardConfirmTitle: string;
1082
+ discardConfirmMessage: string;
1083
+ discardConfirmLabel: string;
1084
+ };
948
1085
  assetLibrary: {
949
1086
  pageTitle: string;
950
1087
  uploadButton: string;
@@ -1176,6 +1313,52 @@ export declare const i18nResources: {
1176
1313
  closeLabel: string;
1177
1314
  resolveHint: string;
1178
1315
  };
1316
+ assetTypeCreate: {
1317
+ title: string;
1318
+ breadcrumbAssetTypes: string;
1319
+ nameLabel: string;
1320
+ namePlaceholder: string;
1321
+ nameRequired: string;
1322
+ slugLabel: string;
1323
+ slugHint: string;
1324
+ slugInvalid: string;
1325
+ descriptionLabel: string;
1326
+ descriptionPlaceholder: string;
1327
+ allowedMimeTypesLabel: string;
1328
+ allowedMimeTypesHint: string;
1329
+ allowedMimeTypesPlaceholder: string;
1330
+ metadataSchemaLabel: string;
1331
+ metadataSchemaHint: string;
1332
+ submit: string;
1333
+ cancel: string;
1334
+ createdToast: string;
1335
+ createFailedToast: string;
1336
+ };
1337
+ assetTypeIndex: {
1338
+ pageTitle: string;
1339
+ pageSubtitle: string;
1340
+ newButton: string;
1341
+ searchPlaceholder: string;
1342
+ typesCount: string;
1343
+ columnName: string;
1344
+ columnSlug: string;
1345
+ columnMimeTypes: string;
1346
+ columnFields: string;
1347
+ columnStatus: string;
1348
+ statusActive: string;
1349
+ statusInactive: string;
1350
+ actionDelete: string;
1351
+ deleteConfirmTitle: string;
1352
+ deleteConfirmMessage: string;
1353
+ deleteConfirmLabel: string;
1354
+ deleteSuccessToast: string;
1355
+ deleteFailedToast: string;
1356
+ noAssetTypesHeader: string;
1357
+ noAssetTypesDescription: string;
1358
+ noMatchesHeader: string;
1359
+ noMatchesDescription: string;
1360
+ loadFailedHeader: string;
1361
+ };
1179
1362
  };
1180
1363
  };
1181
1364
  de: {
@@ -1238,6 +1421,38 @@ export declare const i18nResources: {
1238
1421
  unknownValue: string;
1239
1422
  };
1240
1423
  };
1424
+ assetTypeDetail: {
1425
+ breadcrumbAssetTypes: string;
1426
+ notFound: string;
1427
+ untitled: string;
1428
+ backButtonAria: string;
1429
+ generalTab: string;
1430
+ metadataTab: string;
1431
+ nameLabel: string;
1432
+ nameRequired: string;
1433
+ slugLabel: string;
1434
+ descriptionLabel: string;
1435
+ descriptionPlaceholder: string;
1436
+ allowedMimeTypesLabel: string;
1437
+ allowedMimeTypesDescription: string;
1438
+ activeLabel: string;
1439
+ save: string;
1440
+ delete: string;
1441
+ saveSuccessToast: string;
1442
+ saveFailedToast: string;
1443
+ schemaSavedToast: string;
1444
+ deleteConfirmTitle: string;
1445
+ deleteConfirmMessage: string;
1446
+ deleteConfirmLabel: string;
1447
+ deleteSuccessToast: string;
1448
+ deleteFailedToast: string;
1449
+ discardSchemaConfirmTitle: string;
1450
+ discardSchemaConfirmMessage: string;
1451
+ discardSchemaConfirmLabel: string;
1452
+ discardConfirmTitle: string;
1453
+ discardConfirmMessage: string;
1454
+ discardConfirmLabel: string;
1455
+ };
1241
1456
  assetLibrary: {
1242
1457
  pageTitle: string;
1243
1458
  uploadButton: string;
@@ -1469,6 +1684,52 @@ export declare const i18nResources: {
1469
1684
  closeLabel: string;
1470
1685
  resolveHint: string;
1471
1686
  };
1687
+ assetTypeCreate: {
1688
+ title: string;
1689
+ breadcrumbAssetTypes: string;
1690
+ nameLabel: string;
1691
+ namePlaceholder: string;
1692
+ nameRequired: string;
1693
+ slugLabel: string;
1694
+ slugHint: string;
1695
+ slugInvalid: string;
1696
+ descriptionLabel: string;
1697
+ descriptionPlaceholder: string;
1698
+ allowedMimeTypesLabel: string;
1699
+ allowedMimeTypesHint: string;
1700
+ allowedMimeTypesPlaceholder: string;
1701
+ metadataSchemaLabel: string;
1702
+ metadataSchemaHint: string;
1703
+ submit: string;
1704
+ cancel: string;
1705
+ createdToast: string;
1706
+ createFailedToast: string;
1707
+ };
1708
+ assetTypeIndex: {
1709
+ pageTitle: string;
1710
+ pageSubtitle: string;
1711
+ newButton: string;
1712
+ searchPlaceholder: string;
1713
+ typesCount: string;
1714
+ columnName: string;
1715
+ columnSlug: string;
1716
+ columnMimeTypes: string;
1717
+ columnFields: string;
1718
+ columnStatus: string;
1719
+ statusActive: string;
1720
+ statusInactive: string;
1721
+ actionDelete: string;
1722
+ deleteConfirmTitle: string;
1723
+ deleteConfirmMessage: string;
1724
+ deleteConfirmLabel: string;
1725
+ deleteSuccessToast: string;
1726
+ deleteFailedToast: string;
1727
+ noAssetTypesHeader: string;
1728
+ noAssetTypesDescription: string;
1729
+ noMatchesHeader: string;
1730
+ noMatchesDescription: string;
1731
+ loadFailedHeader: string;
1732
+ };
1472
1733
  };
1473
1734
  };
1474
1735
  };
@@ -1623,6 +1884,23 @@ export declare interface MediahubProviderProps {
1623
1884
  children: ReactNode;
1624
1885
  }
1625
1886
 
1887
+ /**
1888
+ * The asset type's fieldkit metadata schema, edited on a page with room for it
1889
+ * (spec knkCS/mediahub#138, story 7) rather than as a JSON textarea.
1890
+ */
1891
+ export declare const MetadataSchemaEditor: default_2.FC<MetadataSchemaEditorProps>;
1892
+
1893
+ export declare interface MetadataSchemaEditorProps {
1894
+ typeId: string;
1895
+ /**
1896
+ * The committed schema — SpecEditor's baseline. Content-equal re-parses on
1897
+ * background refetches are ignored by the editor's stability contract.
1898
+ */
1899
+ initialSchema: Schema;
1900
+ /** Wire into the screen's unsaved-changes tab guard. */
1901
+ onDirtyChange?: (dirty: boolean) => void;
1902
+ }
1903
+
1626
1904
  /**
1627
1905
  * Destination folder picker for moving a folder or an asset. Destinations
1628
1906
  * that would trip the server's leak guard (moving exposed content into a
@@ -1662,6 +1940,14 @@ export declare interface Page<T> {
1662
1940
  totalPages: number;
1663
1941
  }
1664
1942
 
1943
+ /**
1944
+ * A comma-separated MIME type field, both directions: the asset-type create and
1945
+ * detail screens edit `AssetTypeInfo.allowedMimeTypes` (a `string[]`) as one
1946
+ * plain-text input, so both parse the same way back into the array the mutation
1947
+ * sends.
1948
+ */
1949
+ export declare const parseMimeTypeList: (value: string) => string[];
1950
+
1665
1951
  declare interface PreferencesActions {
1666
1952
  toggleSidebar: () => void;
1667
1953
  setViewMode: (mode: "list" | "grid") => void;
@@ -1749,6 +2035,19 @@ declare type SelectionStore = SelectionState & SelectionActions;
1749
2035
  */
1750
2036
  export declare function showRpcErrorToast(err: unknown, fallbackTitle: string): void;
1751
2037
 
2038
+ /**
2039
+ * Convert a display name into a slug mediahub accepts: lowercase alphanumeric
2040
+ * with hyphens.
2041
+ *
2042
+ * Non-ASCII is a separator, not transliterated — "Bürgerdaten" becomes
2043
+ * "b-rgerdaten" — because the server's rule is the ASCII one and a
2044
+ * transliteration would produce a slug the user never saw derived.
2045
+ *
2046
+ * Both hosts carried their own copy of this (knkCS/mediahub#137); the package
2047
+ * owns it now so the asset-type screens share one derivation.
2048
+ */
2049
+ export declare function slugify(name: string): string;
2050
+
1752
2051
  export declare interface StatusCountInfo {
1753
2052
  statusSlug: string;
1754
2053
  name: string;