@manta-eu/react 0.1.10 → 0.2.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.
Files changed (100) hide show
  1. package/dist/components/chat-view/ChatTurnErrorNotice.d.ts.map +1 -1
  2. package/dist/components/chat-view/ChatTurnErrorNotice.js +3 -1
  3. package/dist/components/chat-view/ChatTurnErrorNotice.js.map +1 -1
  4. package/dist/components/layouts/ConnectedCustomApp.d.ts +13 -0
  5. package/dist/components/layouts/ConnectedCustomApp.d.ts.map +1 -0
  6. package/dist/components/layouts/ConnectedCustomApp.js +37 -0
  7. package/dist/components/layouts/ConnectedCustomApp.js.map +1 -0
  8. package/dist/components/layouts/Sidebar.d.ts.map +1 -1
  9. package/dist/components/layouts/Sidebar.js +6 -3
  10. package/dist/components/layouts/Sidebar.js.map +1 -1
  11. package/dist/components/table-skeleton/index.d.ts +2 -0
  12. package/dist/components/table-skeleton/index.d.ts.map +1 -1
  13. package/dist/components/table-skeleton/index.js +2 -1
  14. package/dist/components/table-skeleton/index.js.map +1 -1
  15. package/dist/graph/createNodeRouter.js +3 -3
  16. package/dist/graph/createNodeRouter.js.map +1 -1
  17. package/dist/graph/nodes/BrandFontSuggestionView.d.ts +3 -0
  18. package/dist/graph/nodes/BrandFontSuggestionView.d.ts.map +1 -0
  19. package/dist/graph/nodes/{BrandFontFamilyView.js → BrandFontSuggestionView.js} +21 -13
  20. package/dist/graph/nodes/BrandFontSuggestionView.js.map +1 -0
  21. package/dist/graph/nodes/brand-font.d.ts +8 -0
  22. package/dist/graph/nodes/brand-font.d.ts.map +1 -1
  23. package/dist/graph/nodes/brand-font.js +6 -0
  24. package/dist/graph/nodes/brand-font.js.map +1 -1
  25. package/dist/graph/nodes/brand-shared.d.ts +0 -3
  26. package/dist/graph/nodes/brand-shared.d.ts.map +1 -1
  27. package/dist/graph/nodes/brand-shared.js +1 -4
  28. package/dist/graph/nodes/brand-shared.js.map +1 -1
  29. package/dist/hooks/use-connection-problems.d.ts.map +1 -1
  30. package/dist/hooks/useAuth.d.ts +2 -2
  31. package/dist/hooks/useAuth.d.ts.map +1 -1
  32. package/dist/hooks/useAuth.js +2 -2
  33. package/dist/hooks/useAuth.js.map +1 -1
  34. package/dist/hooks/useOnboardingState.js +1 -1
  35. package/dist/hooks/useOnboardingState.js.map +1 -1
  36. package/dist/hooks/useValidateActionPlan.d.ts.map +1 -1
  37. package/dist/lib/datastore-route-table.d.ts +2 -1
  38. package/dist/lib/datastore-route-table.d.ts.map +1 -1
  39. package/dist/lib/datastore-route-table.js +2 -1
  40. package/dist/lib/datastore-route-table.js.map +1 -1
  41. package/dist/providers/AuthContext.d.ts +2 -1
  42. package/dist/providers/AuthContext.d.ts.map +1 -1
  43. package/dist/providers/AuthContext.js.map +1 -1
  44. package/dist/providers/ChatManagerProvider.d.ts.map +1 -1
  45. package/dist/providers/ChatManagerProvider.js +19 -8
  46. package/dist/providers/ChatManagerProvider.js.map +1 -1
  47. package/dist/routes/data-explorer/declared-namespaces.d.ts +3 -0
  48. package/dist/routes/data-explorer/declared-namespaces.d.ts.map +1 -1
  49. package/dist/routes/data-explorer/declared-namespaces.js +21 -13
  50. package/dist/routes/data-explorer/declared-namespaces.js.map +1 -1
  51. package/dist/routes/data-explorer/namespaces.d.ts +1 -0
  52. package/dist/routes/data-explorer/namespaces.d.ts.map +1 -1
  53. package/dist/routes/data-explorer/namespaces.js +7 -6
  54. package/dist/routes/data-explorer/namespaces.js.map +1 -1
  55. package/dist/routes/datastores/components/DeleteDatastoreDialog.d.ts +10 -0
  56. package/dist/routes/datastores/components/DeleteDatastoreDialog.d.ts.map +1 -0
  57. package/dist/routes/datastores/components/DeleteDatastoreDialog.js +20 -0
  58. package/dist/routes/datastores/components/DeleteDatastoreDialog.js.map +1 -0
  59. package/dist/routes/datastores/flatten.d.ts +1 -0
  60. package/dist/routes/datastores/flatten.d.ts.map +1 -1
  61. package/dist/routes/datastores/flatten.js +17 -0
  62. package/dist/routes/datastores/flatten.js.map +1 -1
  63. package/dist/routes/datastores/hooks/useDatastoreColumns.d.ts +3 -1
  64. package/dist/routes/datastores/hooks/useDatastoreColumns.d.ts.map +1 -1
  65. package/dist/routes/datastores/hooks/useDatastoreColumns.js +14 -6
  66. package/dist/routes/datastores/hooks/useDatastoreColumns.js.map +1 -1
  67. package/dist/routes/datastores/index.d.ts.map +1 -1
  68. package/dist/routes/datastores/index.js +31 -5
  69. package/dist/routes/datastores/index.js.map +1 -1
  70. package/dist/routes/integrations/components/ProviderGroup.js +2 -2
  71. package/dist/routes/integrations/components/ProviderGroup.js.map +1 -1
  72. package/package.json +7 -7
  73. package/src/components/chat-view/ChatTurnErrorNotice.tsx +3 -1
  74. package/src/components/layouts/ConnectedCustomApp.tsx +63 -0
  75. package/src/components/layouts/Sidebar.tsx +9 -3
  76. package/src/components/table-skeleton/index.tsx +7 -1
  77. package/src/graph/createNodeRouter.tsx +3 -3
  78. package/src/graph/nodes/{BrandFontFamilyView.tsx → BrandFontSuggestionView.tsx} +39 -31
  79. package/src/graph/nodes/brand-font.ts +17 -0
  80. package/src/graph/nodes/brand-shared.tsx +1 -4
  81. package/src/hooks/useAuth.ts +3 -3
  82. package/src/hooks/useOnboardingState.ts +1 -1
  83. package/src/lib/datastore-route-table.ts +4 -2
  84. package/src/providers/AuthContext.ts +3 -1
  85. package/src/providers/ChatManagerProvider.tsx +16 -8
  86. package/src/routes/data-explorer/declared-namespaces.ts +21 -13
  87. package/src/routes/data-explorer/namespaces.ts +7 -6
  88. package/src/routes/datastores/components/DeleteDatastoreDialog.tsx +78 -0
  89. package/src/routes/datastores/flatten.ts +15 -0
  90. package/src/routes/datastores/hooks/useDatastoreColumns.tsx +88 -49
  91. package/src/routes/datastores/index.tsx +41 -2
  92. package/src/routes/integrations/components/ProviderGroup.tsx +2 -2
  93. package/dist/graph/nodes/BrandFontFamilyView.d.ts +0 -3
  94. package/dist/graph/nodes/BrandFontFamilyView.d.ts.map +0 -1
  95. package/dist/graph/nodes/BrandFontFamilyView.js.map +0 -1
  96. package/dist/graph/nodes/BrandFontUploadButton.d.ts +0 -6
  97. package/dist/graph/nodes/BrandFontUploadButton.d.ts.map +0 -1
  98. package/dist/graph/nodes/BrandFontUploadButton.js +0 -69
  99. package/dist/graph/nodes/BrandFontUploadButton.js.map +0 -1
  100. package/src/graph/nodes/BrandFontUploadButton.tsx +0 -95
@@ -13,6 +13,7 @@ import {
13
13
  Power,
14
14
  RefreshCw,
15
15
  RotateCcw,
16
+ Trash,
16
17
  Trash2,
17
18
  TriangleAlert,
18
19
  Users,
@@ -28,6 +29,7 @@ import { isUnmirroredOrganization, type DatastoreRow } from "../flatten";
28
29
  import { Badge } from "#components/badge/index";
29
30
  import { Button } from "#components/button/index";
30
31
  import { datastoreStatusCategory, isMaterializing, type DatastoreStatus } from "#components/datastore-management/tree";
32
+ import { DisabledActionTooltip } from "#components/disabled-action-tooltip/index";
31
33
  import {
32
34
  Dropdown,
33
35
  DropdownContent,
@@ -99,6 +101,7 @@ type UseDatastoreColumnsArgs = {
99
101
  // Indentation only means something while rows are in hierarchy order; a sort makes it a lie.
100
102
  indented: boolean;
101
103
  matchableRowIds: Set<string>;
104
+ nestedDatastoreNamesByRowId: Map<string, string[]>;
102
105
  suggestedMatchByDatastoreId?: Record<string, DatastoreRow>;
103
106
  onSelect: (row: DatastoreRow) => void;
104
107
  onAddChild: (row: DatastoreRow) => void;
@@ -107,10 +110,11 @@ type UseDatastoreColumnsArgs = {
107
110
  onLinkExisting: (row: DatastoreRow) => void;
108
111
  onRemove: (row: DatastoreRow) => void;
109
112
  onRestore: (row: DatastoreRow) => void;
113
+ onDelete: (row: DatastoreRow) => void;
110
114
  onRename: (row: DatastoreRow) => void;
111
115
  onRegister: (row: DatastoreRow) => void;
112
116
  onManageUsers: (row: DatastoreRow) => void;
113
- onManageExternalApps: (row: DatastoreRow) => void;
117
+ onManageCustomApps: (row: DatastoreRow) => void;
114
118
  onBringOnline: (row: DatastoreRow) => void;
115
119
  isBringingOnline?: boolean;
116
120
  onLinkProvider: (row: DatastoreRow) => void;
@@ -125,6 +129,7 @@ export function useDatastoreColumns(args: UseDatastoreColumnsArgs): ColumnDef<Da
125
129
  isSwitching,
126
130
  indented,
127
131
  matchableRowIds,
132
+ nestedDatastoreNamesByRowId,
128
133
  suggestedMatchByDatastoreId,
129
134
  onSelect,
130
135
  onAddChild,
@@ -133,10 +138,11 @@ export function useDatastoreColumns(args: UseDatastoreColumnsArgs): ColumnDef<Da
133
138
  onLinkExisting,
134
139
  onRemove,
135
140
  onRestore,
141
+ onDelete,
136
142
  onRename,
137
143
  onRegister,
138
144
  onManageUsers,
139
- onManageExternalApps,
145
+ onManageCustomApps,
140
146
  onBringOnline,
141
147
  isBringingOnline,
142
148
  onLinkProvider,
@@ -310,6 +316,11 @@ export function useDatastoreColumns(args: UseDatastoreColumnsArgs): ColumnDef<Da
310
316
  .with({ materializing: true }, () => "Still materializing - this can take a few minutes.")
311
317
  .otherwise(() => undefined);
312
318
  const canSelect = hasDatastore && !reason && !current && !isSwitching;
319
+ const canDelete = hasDatastore && !current;
320
+ const nestedDatastoreNames = nestedDatastoreNamesByRowId.get(datastoreRow.id);
321
+ const deleteBlockedReason = isPresent(nestedDatastoreNames)
322
+ ? `Delete the datastores under it first: ${nestedDatastoreNames.join(", ")}`
323
+ : undefined;
313
324
 
314
325
  return (
315
326
  <div className={cn(columnMinWidths[datastoreColumnIds.actions], "flex items-center justify-end gap-1.5")}>
@@ -376,7 +387,7 @@ export function useDatastoreColumns(args: UseDatastoreColumnsArgs): ColumnDef<Da
376
387
  Select
377
388
  </Button>
378
389
  )}
379
- {isRealmDefault || isUnlinked ? (
390
+ {isRealmDefault || (isUnlinked && !canDelete) ? (
380
391
  // Same-sized spacer keeps Select/Selected aligned with rows that have the ellipsis.
381
392
  <div className="size-6" aria-hidden="true" />
382
393
  ) : (
@@ -391,57 +402,83 @@ export function useDatastoreColumns(args: UseDatastoreColumnsArgs): ColumnDef<Da
391
402
  </button>
392
403
  </DropdownTrigger>
393
404
  <DropdownContent align="end" className="min-w-52">
394
- <DropdownItem icon={<Pencil className="size-4" />} onSelect={() => onRename(datastoreRow)}>
395
- Rename
396
- </DropdownItem>
397
- {isPresent(datastoreRow.organizationAlias) && (
398
- <DropdownItem icon={<Users className="size-4" />} onSelect={() => onManageUsers(datastoreRow)}>
399
- Manage users
400
- </DropdownItem>
401
- )}
402
- {datastoreRow.isOrganization && isPresent(datastoreRow.organizationAlias) && (
403
- <DropdownItem
404
- icon={<Blocks className="size-4" />}
405
- onSelect={() => onManageExternalApps(datastoreRow)}
406
- >
407
- Custom apps
408
- </DropdownItem>
409
- )}
410
- {!hasDatastore &&
411
- (matchableRowIds.has(datastoreRow.id) ? (
412
- <DropdownItem icon={<Link2 className="size-4" />} onSelect={() => onLinkExisting(datastoreRow)}>
413
- Link existing datastore
405
+ {!isUnlinked && (
406
+ <>
407
+ <DropdownItem icon={<Pencil className="size-4" />} onSelect={() => onRename(datastoreRow)}>
408
+ Rename
414
409
  </DropdownItem>
415
- ) : (
416
- <DropdownItem
417
- icon={<DatabaseZap className="size-4" />}
418
- onSelect={() => onProvision(datastoreRow)}
419
- >
420
- Provision datastore
410
+ {isPresent(datastoreRow.organizationAlias) && (
411
+ <DropdownItem
412
+ icon={<Users className="size-4" />}
413
+ onSelect={() => onManageUsers(datastoreRow)}
414
+ >
415
+ Manage users
416
+ </DropdownItem>
417
+ )}
418
+ {datastoreRow.isOrganization && isPresent(datastoreRow.organizationAlias) && (
419
+ <DropdownItem
420
+ icon={<Blocks className="size-4" />}
421
+ onSelect={() => onManageCustomApps(datastoreRow)}
422
+ >
423
+ Custom apps
424
+ </DropdownItem>
425
+ )}
426
+ {!hasDatastore &&
427
+ (matchableRowIds.has(datastoreRow.id) ? (
428
+ <DropdownItem
429
+ icon={<Link2 className="size-4" />}
430
+ onSelect={() => onLinkExisting(datastoreRow)}
431
+ >
432
+ Link existing datastore
433
+ </DropdownItem>
434
+ ) : (
435
+ <DropdownItem
436
+ icon={<DatabaseZap className="size-4" />}
437
+ onSelect={() => onProvision(datastoreRow)}
438
+ >
439
+ Provision datastore
440
+ </DropdownItem>
441
+ ))}
442
+ <DropdownItem icon={<Plus className="size-4" />} onSelect={() => onAddChild(datastoreRow)}>
443
+ Add datastore
421
444
  </DropdownItem>
422
- ))}
423
- <DropdownItem icon={<Plus className="size-4" />} onSelect={() => onAddChild(datastoreRow)}>
424
- Add datastore
425
- </DropdownItem>
426
- {enableDatastoreRemoval && hasDatastore && !removed && (
427
- <>
428
- <DropdownSeparator />
445
+ {enableDatastoreRemoval && hasDatastore && !removed && (
446
+ <>
447
+ <DropdownSeparator />
448
+ <DropdownItem
449
+ className="text-error-foreground"
450
+ icon={<Trash2 className="size-4" />}
451
+ onSelect={() => onRemove(datastoreRow)}
452
+ >
453
+ Remove datastore
454
+ </DropdownItem>
455
+ </>
456
+ )}
457
+ {enableDatastoreRemoval && hasDatastore && removed && (
458
+ <>
459
+ <DropdownSeparator />
460
+ <DropdownItem
461
+ icon={<RotateCcw className="size-4" />}
462
+ onSelect={() => onRestore(datastoreRow)}
463
+ >
464
+ Restore datastore
465
+ </DropdownItem>
466
+ </>
467
+ )}
468
+ {!enableDatastoreRemoval && canDelete && <DropdownSeparator />}
469
+ </>
470
+ )}
471
+ {canDelete && (
472
+ <DisabledActionTooltip reason={deleteBlockedReason}>
429
473
  <DropdownItem
430
474
  className="text-error-foreground"
431
- icon={<Trash2 className="size-4" />}
432
- onSelect={() => onRemove(datastoreRow)}
475
+ icon={<Trash className="size-4" />}
476
+ disabled={isPresent(deleteBlockedReason)}
477
+ onSelect={() => onDelete(datastoreRow)}
433
478
  >
434
- Remove datastore
435
- </DropdownItem>
436
- </>
437
- )}
438
- {enableDatastoreRemoval && hasDatastore && removed && (
439
- <>
440
- <DropdownSeparator />
441
- <DropdownItem icon={<RotateCcw className="size-4" />} onSelect={() => onRestore(datastoreRow)}>
442
- Restore datastore
479
+ Delete permanently
443
480
  </DropdownItem>
444
- </>
481
+ </DisabledActionTooltip>
445
482
  )}
446
483
  </DropdownContent>
447
484
  </Dropdown>
@@ -457,6 +494,7 @@ export function useDatastoreColumns(args: UseDatastoreColumnsArgs): ColumnDef<Da
457
494
  isSwitching,
458
495
  indented,
459
496
  matchableRowIds,
497
+ nestedDatastoreNamesByRowId,
460
498
  suggestedMatchByDatastoreId,
461
499
  onSelect,
462
500
  onAddChild,
@@ -465,10 +503,11 @@ export function useDatastoreColumns(args: UseDatastoreColumnsArgs): ColumnDef<Da
465
503
  onLinkExisting,
466
504
  onRemove,
467
505
  onRestore,
506
+ onDelete,
468
507
  onRegister,
469
508
  onRename,
470
509
  onManageUsers,
471
- onManageExternalApps,
510
+ onManageCustomApps,
472
511
  onBringOnline,
473
512
  isBringingOnline,
474
513
  onLinkProvider,
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  useBringDatastoreOnlineMutation,
3
+ useDeleteDatastoreMutation,
3
4
  useOrganizationLinkingQuery,
4
5
  useLinkOrganizationToProviderMutation,
5
6
  useLinkUnlinkedDatastoreMutation,
@@ -26,6 +27,7 @@ import { toast } from "sonner";
26
27
  import type { DatastoreFormTarget } from "./components/DatastoreFormDialog";
27
28
  import { DatastoresToolbar } from "./components/DatastoresToolbar";
28
29
  import { DatastoreTableSkeleton } from "./components/DatastoreTableSkeleton";
30
+ import { DeleteDatastoreDialog } from "./components/DeleteDatastoreDialog";
29
31
  import { LinkUnlinkedDatastoreDialog, type SuggestedLinkTarget } from "./components/LinkUnlinkedDatastoreDialog";
30
32
  import { ProvisionDatastoreDialog } from "./components/ProvisionDatastoreDialog";
31
33
  import { RenameDatastoreGroupDialog } from "./components/RenameDatastoreGroupDialog";
@@ -34,6 +36,7 @@ import {
34
36
  existingOrganizationNameKeys,
35
37
  hiddenRowCount,
36
38
  matchesProviderFilter,
39
+ nestedDatastoreNamesByRowId,
37
40
  organizationNameKey,
38
41
  organizationNames,
39
42
  realmDefaultRow,
@@ -104,6 +107,7 @@ export function DatastoresRoute() {
104
107
 
105
108
  const [formTarget, setFormTarget] = useState<DatastoreFormTarget | null>(null);
106
109
  const [pendingRemoval, setPendingRemoval] = useState<DatastoreRow | null>(null);
110
+ const [pendingDeletion, setPendingDeletion] = useState<DatastoreRow | null>(null);
107
111
  const [renameTarget, setRenameTarget] = useState<DatastoreRow | null>(null);
108
112
  const [linkDialogTarget, setLinkDialogTarget] = useState<string | null>(null);
109
113
  const [visibility, setVisibility] = useState<DatastoreRowVisibility>({
@@ -197,6 +201,25 @@ export function DatastoresRoute() {
197
201
  },
198
202
  });
199
203
 
204
+ const deleteMutation = useDeleteDatastoreMutation(mantaClient, {
205
+ onSuccess: (result, variables) => {
206
+ void refreshDatastores();
207
+ setPendingDeletion(null);
208
+ const { success, error } = result.deleteDatastore;
209
+ if (!success) {
210
+ toast.error("Couldn't delete the datastore", { description: error ?? undefined });
211
+ return;
212
+ }
213
+
214
+ toast.success(`"${variables.confirmName}" was deleted permanently`);
215
+ },
216
+ onError: (error) => {
217
+ setPendingDeletion(null);
218
+ const info = parseError(error, "Couldn't delete the datastore");
219
+ toast.error(info.message, { description: info.description });
220
+ },
221
+ });
222
+
200
223
  const restoreMutation = useRestoreDatastoreMutation(mantaClient, {
201
224
  onSuccess: (result) => {
202
225
  invalidateTree();
@@ -294,6 +317,7 @@ export function DatastoresRoute() {
294
317
  [unlinkedData],
295
318
  );
296
319
  const allRows = useMemo(() => [...treeRows, ...unlinkedRows], [treeRows, unlinkedRows]);
320
+ const nestedDatastoreNames = useMemo(() => nestedDatastoreNamesByRowId(treeRows), [treeRows]);
297
321
  const rows = useMemo(() => visibleDatastoreRows(treeRows, visibility), [treeRows, visibility]);
298
322
  const unprovisionedCount = useMemo(
299
323
  () => hiddenRowCount(treeRows, visibility, "showUnprovisioned", rows.length),
@@ -462,7 +486,7 @@ export function DatastoresRoute() {
462
486
  [navigate],
463
487
  );
464
488
 
465
- const onManageExternalApps = useCallback(
489
+ const onManageCustomApps = useCallback(
466
490
  (row: DatastoreRow) =>
467
491
  void navigate(`/custom-apps?${new URLSearchParams({ org: row.organizationAlias }).toString()}`),
468
492
  [navigate],
@@ -488,6 +512,7 @@ export function DatastoresRoute() {
488
512
  isSwitching,
489
513
  indented,
490
514
  matchableRowIds,
515
+ nestedDatastoreNamesByRowId: nestedDatastoreNames,
491
516
  suggestedMatchByDatastoreId,
492
517
  onSelect,
493
518
  onAddChild,
@@ -495,11 +520,12 @@ export function DatastoresRoute() {
495
520
  onProvision: provisionExisting,
496
521
  onLinkExisting,
497
522
  onRemove: setPendingRemoval,
523
+ onDelete: setPendingDeletion,
498
524
  onRestore,
499
525
  onRename: setRenameTarget,
500
526
  onRegister,
501
527
  onManageUsers,
502
- onManageExternalApps,
528
+ onManageCustomApps,
503
529
  onBringOnline,
504
530
  isBringingOnline: bringOnlineMutation.isPending,
505
531
  onLinkProvider,
@@ -810,6 +836,19 @@ export function DatastoresRoute() {
810
836
  />
811
837
  )}
812
838
 
839
+ {pendingDeletion && isPresent(pendingDeletion.datastoreId) && (
840
+ <DeleteDatastoreDialog
841
+ target={pendingDeletion}
842
+ isDeleting={deleteMutation.isPending}
843
+ onConfirm={(confirmName) => {
844
+ if (isPresent(pendingDeletion.datastoreId)) {
845
+ deleteMutation.mutate({ datastoreId: pendingDeletion.datastoreId, confirmName });
846
+ }
847
+ }}
848
+ onCancel={() => setPendingDeletion(null)}
849
+ />
850
+ )}
851
+
813
852
  {pendingRemoval && isPresent(pendingRemoval.datastoreId) && (
814
853
  <DeleteConfirmationDialog
815
854
  title="Remove datastore"
@@ -57,7 +57,7 @@ export function ProviderGroup<Id extends string = ProviderId>(props: ProviderGro
57
57
  )}
58
58
  </header>
59
59
 
60
- <div className="flex flex-col gap-2 min-w-0 bg-card py-4 border-b border-muted-border">
60
+ <div className="flex flex-col gap-2 min-w-0 bg-card py-4">
61
61
  {alwaysVisible.map(renderConnection)}
62
62
 
63
63
  {hasOverflow && (
@@ -90,7 +90,7 @@ export function ProviderGroupSkeleton() {
90
90
  </div>
91
91
  <Skeleton className="h-8 w-24 rounded-md" />
92
92
  </header>
93
- <div className="flex flex-col gap-2 bg-card py-4 border-b border-muted-border">
93
+ <div className="flex flex-col gap-2 bg-card py-4">
94
94
  <ConnectionRowSkeleton />
95
95
  <ConnectionRowSkeleton />
96
96
  </div>
@@ -1,3 +0,0 @@
1
- import type { EntityViewProps } from "../types.js";
2
- export declare const BrandFontFamilyView: import("react").NamedExoticComponent<EntityViewProps>;
3
- //# sourceMappingURL=BrandFontFamilyView.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"BrandFontFamilyView.d.ts","sourceRoot":"","sources":["../../../src/graph/nodes/BrandFontFamilyView.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAiEhD,eAAO,MAAM,mBAAmB,uDA6C9B,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"BrandFontFamilyView.js","sourceRoot":"","sources":["../../../src/graph/nodes/BrandFontFamilyView.tsx"],"names":[],"mappings":"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"}
@@ -1,6 +0,0 @@
1
- type BrandFontUploadButtonProps = {
2
- family: string;
3
- };
4
- export declare function BrandFontUploadButton(props: BrandFontUploadButtonProps): import("react/jsx-runtime").JSX.Element;
5
- export {};
6
- //# sourceMappingURL=BrandFontUploadButton.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"BrandFontUploadButton.d.ts","sourceRoot":"","sources":["../../../src/graph/nodes/BrandFontUploadButton.tsx"],"names":[],"mappings":"AAsDA,KAAK,0BAA0B,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAErD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,0BAA0B,2CAsCtE"}
@@ -1,69 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useAbortUploadMutation, useCompleteUploadMutation, useExecuteAgentActionAdditionMutation, useInitiateUploadMutation, } from "@manta-eu/client";
3
- import { namespaces } from "@manta-eu/rdf-lib/namespaces";
4
- import { Upload } from "lucide-react";
5
- import { use, useRef, useState } from "react";
6
- import { toast } from "sonner";
7
- import { Button } from "#components/button/index";
8
- import { buildActionDocument, mintSubjectIri } from "#lib/action-document";
9
- import { uploadFile } from "#lib/upload-client";
10
- import { MantaClientProviderContext } from "#providers/manta-client-context";
11
- const acceptedFontFiles = ".woff2,.woff,.ttf,.otf";
12
- const attachFontFile = `${namespaces.brand}AttachFontFile`;
13
- const attachFontFileShape = `${namespaces.brand}AttachFontFileShape`;
14
- function ignoreProgress() { }
15
- // Graph views sit below the provider barrels, so this reads the client context directly instead of useExecuteAction.
16
- function useAttachFontFile(family) {
17
- const clientContext = use(MantaClientProviderContext);
18
- const mantaClient = clientContext?.mantaClient;
19
- if (!mantaClient)
20
- throw new Error("BrandFontUploadButton must be used within a MantaClientProvider");
21
- const uploadRelay = clientContext?.uploadRelay;
22
- const { mutateAsync: initiateUpload } = useInitiateUploadMutation(mantaClient);
23
- const { mutateAsync: completeUpload } = useCompleteUploadMutation(mantaClient);
24
- const { mutateAsync: abortUpload } = useAbortUploadMutation(mantaClient);
25
- const { mutateAsync: startAddition } = useExecuteAgentActionAdditionMutation(mantaClient);
26
- return async (file) => {
27
- const { fileIri } = await uploadFile({
28
- file,
29
- onFileProgress: ignoreProgress,
30
- initiateUpload,
31
- completeUpload,
32
- abortUpload,
33
- ...(uploadRelay ? { relay: uploadRelay } : {}),
34
- });
35
- const subjectIri = mintSubjectIri(attachFontFile);
36
- const properties = buildActionDocument({ subjectIri, rdfType: attachFontFile }, { [`${namespaces.brand}fontFamily`]: family, [`${namespaces.brand}fontFile`]: { "@id": fileIri } });
37
- const { executeActionAddition } = await startAddition({
38
- input: { subjectIri, rdfType: attachFontFile, actionShape: attachFontFileShape, properties },
39
- });
40
- if (!executeActionAddition.success)
41
- throw new Error(executeActionAddition.error ?? "The font was not attached");
42
- };
43
- }
44
- export function BrandFontUploadButton(props) {
45
- const { family } = props;
46
- const input = useRef(null);
47
- const [isAttaching, setIsAttaching] = useState(false);
48
- const attach = useAttachFontFile(family);
49
- async function attachChosen(file) {
50
- setIsAttaching(true);
51
- try {
52
- await attach(file);
53
- toast.success(`${file.name} is being attached to ${family}`);
54
- }
55
- catch (error) {
56
- toast.error(error instanceof Error ? error.message : `Could not attach ${file.name}`);
57
- }
58
- finally {
59
- setIsAttaching(false);
60
- }
61
- }
62
- return (_jsxs(_Fragment, { children: [_jsx("input", { ref: input, type: "file", accept: acceptedFontFiles, className: "hidden", onChange: (event) => {
63
- const file = event.target.files?.[0];
64
- event.target.value = "";
65
- if (file)
66
- void attachChosen(file);
67
- } }), _jsxs(Button, { variant: "secondary", size: "sm", disabled: isAttaching, onClick: () => input.current?.click(), children: [_jsx(Upload, { size: 12 }), "Upload font"] })] }));
68
- }
69
- //# sourceMappingURL=BrandFontUploadButton.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"BrandFontUploadButton.js","sourceRoot":"","sources":["../../../src/graph/nodes/BrandFontUploadButton.tsx"],"names":[],"mappings":"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"}
@@ -1,95 +0,0 @@
1
- import {
2
- useAbortUploadMutation,
3
- useCompleteUploadMutation,
4
- useExecuteAgentActionAdditionMutation,
5
- useInitiateUploadMutation,
6
- } from "@manta-eu/client";
7
- import { namespaces } from "@manta-eu/rdf-lib/namespaces";
8
- import { Upload } from "lucide-react";
9
- import { use, useRef, useState } from "react";
10
- import { toast } from "sonner";
11
- import { Button } from "#components/button/index";
12
- import { buildActionDocument, mintSubjectIri } from "#lib/action-document";
13
- import { uploadFile } from "#lib/upload-client";
14
- import { MantaClientProviderContext } from "#providers/manta-client-context";
15
-
16
- const acceptedFontFiles = ".woff2,.woff,.ttf,.otf";
17
- const attachFontFile = `${namespaces.brand}AttachFontFile`;
18
- const attachFontFileShape = `${namespaces.brand}AttachFontFileShape`;
19
-
20
- function ignoreProgress() {}
21
-
22
- // Graph views sit below the provider barrels, so this reads the client context directly instead of useExecuteAction.
23
- function useAttachFontFile(family: string) {
24
- const clientContext = use(MantaClientProviderContext);
25
- const mantaClient = clientContext?.mantaClient;
26
- if (!mantaClient) throw new Error("BrandFontUploadButton must be used within a MantaClientProvider");
27
- const uploadRelay = clientContext?.uploadRelay;
28
-
29
- const { mutateAsync: initiateUpload } = useInitiateUploadMutation(mantaClient);
30
- const { mutateAsync: completeUpload } = useCompleteUploadMutation(mantaClient);
31
- const { mutateAsync: abortUpload } = useAbortUploadMutation(mantaClient);
32
- const { mutateAsync: startAddition } = useExecuteAgentActionAdditionMutation(mantaClient);
33
-
34
- return async (file: File) => {
35
- const { fileIri } = await uploadFile({
36
- file,
37
- onFileProgress: ignoreProgress,
38
- initiateUpload,
39
- completeUpload,
40
- abortUpload,
41
- ...(uploadRelay ? { relay: uploadRelay } : {}),
42
- });
43
- const subjectIri = mintSubjectIri(attachFontFile);
44
- const properties = buildActionDocument(
45
- { subjectIri, rdfType: attachFontFile },
46
- { [`${namespaces.brand}fontFamily`]: family, [`${namespaces.brand}fontFile`]: { "@id": fileIri } },
47
- );
48
- const { executeActionAddition } = await startAddition({
49
- input: { subjectIri, rdfType: attachFontFile, actionShape: attachFontFileShape, properties },
50
- });
51
- if (!executeActionAddition.success) throw new Error(executeActionAddition.error ?? "The font was not attached");
52
- };
53
- }
54
-
55
- type BrandFontUploadButtonProps = { family: string };
56
-
57
- export function BrandFontUploadButton(props: BrandFontUploadButtonProps) {
58
- const { family } = props;
59
-
60
- const input = useRef<HTMLInputElement>(null);
61
- const [isAttaching, setIsAttaching] = useState(false);
62
- const attach = useAttachFontFile(family);
63
-
64
- async function attachChosen(file: File) {
65
- setIsAttaching(true);
66
- try {
67
- await attach(file);
68
- toast.success(`${file.name} is being attached to ${family}`);
69
- } catch (error) {
70
- toast.error(error instanceof Error ? error.message : `Could not attach ${file.name}`);
71
- } finally {
72
- setIsAttaching(false);
73
- }
74
- }
75
-
76
- return (
77
- <>
78
- <input
79
- ref={input}
80
- type="file"
81
- accept={acceptedFontFiles}
82
- className="hidden"
83
- onChange={(event) => {
84
- const file = event.target.files?.[0];
85
- event.target.value = "";
86
- if (file) void attachChosen(file);
87
- }}
88
- />
89
- <Button variant="secondary" size="sm" disabled={isAttaching} onClick={() => input.current?.click()}>
90
- <Upload size={12} />
91
- Upload font
92
- </Button>
93
- </>
94
- );
95
- }