@lodashventure/medusa-media-manager 0.2.5 → 0.2.8

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.
@@ -681,7 +681,7 @@ const STATUS_COLORS = {
681
681
  archived: "warning"
682
682
  };
683
683
  const DEFAULT_LOCALE = "default";
684
- const MediaAssetDrawer = ({
684
+ const MediaAssetDialog = ({
685
685
  assetId,
686
686
  onClose,
687
687
  onUpdated,
@@ -689,6 +689,7 @@ const MediaAssetDrawer = ({
689
689
  }) => {
690
690
  var _a;
691
691
  const fileInputRef = react.useRef(null);
692
+ const modalContentRef = react.useRef(null);
692
693
  const [asset, setAsset] = react.useState(null);
693
694
  const [isLoading, setIsLoading] = react.useState(false);
694
695
  const [isSaving, setIsSaving] = react.useState(false);
@@ -765,6 +766,11 @@ const MediaAssetDrawer = ({
765
766
  isMounted = false;
766
767
  };
767
768
  }, [assetId]);
769
+ react.useEffect(() => {
770
+ if (modalContentRef.current) {
771
+ modalContentRef.current.scrollTop = 0;
772
+ }
773
+ }, [assetId]);
768
774
  const tags = react.useMemo(() => parseTags(tagsInput), [tagsInput]);
769
775
  const handleSave = async () => {
770
776
  if (!asset || !assetId) {
@@ -853,290 +859,298 @@ const MediaAssetDrawer = ({
853
859
  }
854
860
  };
855
861
  const assetRelations = (asset == null ? void 0 : asset.relations) ?? [];
856
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Drawer, { open: Boolean(assetId), onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Drawer.Content, { className: "flex h-full w-full max-w-3xl flex-col overflow-y-auto p-6", children: [
857
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Drawer.Header, { children: [
858
- /* @__PURE__ */ jsxRuntime.jsx(ui.Drawer.Title, { className: "text-lg font-semibold", children: "Asset details" }),
859
- /* @__PURE__ */ jsxRuntime.jsx(ui.Drawer.Description, { children: "Review and update metadata, copy delivery URLs, or replace the original file." })
860
- ] }),
861
- isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-ui-fg-subtle", children: "Loading asset..." }) }) : asset ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col gap-y-6", children: [
862
- /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "flex flex-col gap-y-4", children: [
863
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-video w-full overflow-hidden rounded-lg border border-ui-border-base bg-ui-bg-subtle", children: previewUrl ? /* @__PURE__ */ jsxRuntime.jsx(
864
- "img",
865
- {
866
- src: previewUrl,
867
- alt: asset.original_filename,
868
- className: "h-full w-full object-contain"
869
- }
870
- ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full w-full items-center justify-center text-ui-fg-muted", children: /* @__PURE__ */ jsxRuntime.jsx(icons.Photo, { className: "size-8" }) }) }),
871
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2 text-xs text-ui-fg-subtle", children: [
872
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: asset.mime }),
873
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "·" }),
874
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatFileSize(asset.size_bytes) }),
875
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "·" }),
876
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
877
- "Updated ",
878
- formatDateTime(asset.updated_at)
862
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.FocusModal, { open: Boolean(assetId), onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(
863
+ ui.FocusModal.Content,
864
+ {
865
+ ref: modalContentRef,
866
+ className: "flex h-full w-full max-w-3xl flex-col overflow-y-auto p-6",
867
+ children: [
868
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.FocusModal.Header, { children: [
869
+ /* @__PURE__ */ jsxRuntime.jsx(ui.FocusModal.Title, { className: "text-lg font-semibold", children: "Asset details" }),
870
+ /* @__PURE__ */ jsxRuntime.jsx(ui.FocusModal.Description, { children: "Review and update metadata, copy delivery URLs, or replace the original file." })
871
+ ] }),
872
+ isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-ui-fg-subtle", children: "Loading asset..." }) }) : asset ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col gap-y-6", children: [
873
+ /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "flex flex-col gap-y-4", children: [
874
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-video w-full overflow-hidden rounded-lg border border-ui-border-base bg-ui-bg-subtle", children: previewUrl ? /* @__PURE__ */ jsxRuntime.jsx(
875
+ "img",
876
+ {
877
+ src: previewUrl,
878
+ alt: asset.original_filename,
879
+ className: "h-full w-full object-contain"
880
+ }
881
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full w-full items-center justify-center text-ui-fg-muted", children: /* @__PURE__ */ jsxRuntime.jsx(icons.Photo, { className: "size-8" }) }) }),
882
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2 text-xs text-ui-fg-subtle", children: [
883
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: asset.mime }),
884
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "·" }),
885
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatFileSize(asset.size_bytes) }),
886
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "·" }),
887
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
888
+ "Updated ",
889
+ formatDateTime(asset.updated_at)
890
+ ] }),
891
+ /* @__PURE__ */ jsxRuntime.jsx(
892
+ ui.StatusBadge,
893
+ {
894
+ size: "small",
895
+ color: STATUS_COLORS[asset.status] ?? "default",
896
+ children: asset.status
897
+ }
898
+ ),
899
+ /* @__PURE__ */ jsxRuntime.jsx(
900
+ ui.Badge,
901
+ {
902
+ size: "small",
903
+ variant: asset.visibility === "public" ? "neutral" : "warning",
904
+ className: "capitalize",
905
+ children: asset.visibility
906
+ }
907
+ )
908
+ ] }),
909
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [
910
+ /* @__PURE__ */ jsxRuntime.jsxs(
911
+ ui.Button,
912
+ {
913
+ type: "button",
914
+ variant: "secondary",
915
+ onClick: () => {
916
+ var _a2;
917
+ return (_a2 = fileInputRef.current) == null ? void 0 : _a2.click();
918
+ },
919
+ isLoading: isReplacing,
920
+ children: [
921
+ /* @__PURE__ */ jsxRuntime.jsx(icons.CircleArrowUp, { className: "mr-1 size-4" }),
922
+ "Replace file"
923
+ ]
924
+ }
925
+ ),
926
+ /* @__PURE__ */ jsxRuntime.jsxs(
927
+ ui.Button,
928
+ {
929
+ type: "button",
930
+ variant: "secondary",
931
+ onClick: () => handleVariantCopy("medium"),
932
+ children: [
933
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownTray, { className: "mr-1 size-4" }),
934
+ "Get URL"
935
+ ]
936
+ }
937
+ )
938
+ ] }),
939
+ /* @__PURE__ */ jsxRuntime.jsx(
940
+ "input",
941
+ {
942
+ type: "file",
943
+ ref: fileInputRef,
944
+ className: "hidden",
945
+ onChange: (event) => {
946
+ var _a2;
947
+ return handleReplace(((_a2 = event.target.files) == null ? void 0 : _a2[0]) ?? null);
948
+ }
949
+ }
950
+ )
879
951
  ] }),
880
- /* @__PURE__ */ jsxRuntime.jsx(
881
- ui.StatusBadge,
882
- {
883
- size: "small",
884
- color: STATUS_COLORS[asset.status] ?? "default",
885
- children: asset.status
886
- }
887
- ),
888
- /* @__PURE__ */ jsxRuntime.jsx(
889
- ui.Badge,
890
- {
891
- size: "small",
892
- variant: asset.visibility === "public" ? "neutral" : "warning",
893
- className: "capitalize",
894
- children: asset.visibility
895
- }
896
- )
952
+ /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-4", children: [
953
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2", children: [
954
+ /* @__PURE__ */ jsxRuntime.jsx(
955
+ ui.Input,
956
+ {
957
+ label: "Title",
958
+ placeholder: "Hero banner",
959
+ value: title,
960
+ onChange: (event) => setTitle(event.target.value)
961
+ }
962
+ ),
963
+ /* @__PURE__ */ jsxRuntime.jsx(
964
+ ui.Input,
965
+ {
966
+ label: "Alt text",
967
+ placeholder: "Describe the media for accessibility",
968
+ value: altText,
969
+ onChange: (event) => setAltText(event.target.value)
970
+ }
971
+ )
972
+ ] }),
973
+ /* @__PURE__ */ jsxRuntime.jsx(
974
+ ui.Textarea,
975
+ {
976
+ label: "Caption",
977
+ placeholder: "Optional caption or notes",
978
+ value: caption,
979
+ onChange: (event) => setCaption(event.target.value)
980
+ }
981
+ ),
982
+ /* @__PURE__ */ jsxRuntime.jsx(
983
+ ui.Input,
984
+ {
985
+ label: "Tags",
986
+ placeholder: "summer, lookbook, hero",
987
+ value: tagsInput,
988
+ onChange: (event) => setTagsInput(event.target.value),
989
+ helperText: "Separate tags with commas"
990
+ }
991
+ ),
992
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
993
+ /* @__PURE__ */ jsxRuntime.jsxs(
994
+ ui.Select,
995
+ {
996
+ value: status,
997
+ onValueChange: (value) => setStatus(value),
998
+ children: [
999
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Trigger, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Value, { placeholder: "Status" }) }),
1000
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Select.Content, { children: [
1001
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: "draft", children: "Draft" }),
1002
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: "published", children: "Published" }),
1003
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: "archived", children: "Archived" })
1004
+ ] })
1005
+ ]
1006
+ }
1007
+ ),
1008
+ /* @__PURE__ */ jsxRuntime.jsxs(
1009
+ ui.Select,
1010
+ {
1011
+ value: visibility,
1012
+ onValueChange: (value) => setVisibility(value),
1013
+ children: [
1014
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Trigger, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Value, { placeholder: "Visibility" }) }),
1015
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Select.Content, { children: [
1016
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: "public", children: "Public" }),
1017
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: "private", children: "Private" })
1018
+ ] })
1019
+ ]
1020
+ }
1021
+ )
1022
+ ] })
1023
+ ] }),
1024
+ ((_a = asset.variants) == null ? void 0 : _a.length) ? /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-3", children: [
1025
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-medium", children: "Variants" }),
1026
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Table, { children: [
1027
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Header, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Row, { children: [
1028
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Name" }),
1029
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Format" }),
1030
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Dimensions" }),
1031
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Size" }),
1032
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { className: "text-right", children: "Actions" })
1033
+ ] }) }),
1034
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Body, { children: asset.variants.map((variant) => /* @__PURE__ */ jsxRuntime.jsxs(
1035
+ ui.Table.Row,
1036
+ {
1037
+ children: [
1038
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { className: "capitalize", children: variant.preset }),
1039
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: variant.format }),
1040
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: variant.width && variant.height ? `${variant.width}×${variant.height}` : "-" }),
1041
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: formatFileSize(variant.size_bytes) }),
1042
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { className: "flex justify-end gap-2", children: /* @__PURE__ */ jsxRuntime.jsxs(
1043
+ ui.Button,
1044
+ {
1045
+ size: "small",
1046
+ variant: "secondary",
1047
+ onClick: () => handleVariantCopy(variant.preset),
1048
+ children: [
1049
+ /* @__PURE__ */ jsxRuntime.jsx(icons.SquareTwoStack, { className: "mr-1 size-4" }),
1050
+ " Copy URL"
1051
+ ]
1052
+ }
1053
+ ) })
1054
+ ]
1055
+ },
1056
+ variant.id ?? `${variant.preset}-${variant.format}`
1057
+ )) })
1058
+ ] })
1059
+ ] }) : null,
1060
+ /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-3", children: [
1061
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-medium", children: "Usage" }),
1062
+ assetRelations.length ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Table, { children: [
1063
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Header, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Row, { children: [
1064
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Entity" }),
1065
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Reference" }),
1066
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Role" })
1067
+ ] }) }),
1068
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Body, { children: assetRelations.map((relation) => /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Row, { children: [
1069
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { className: "capitalize", children: relation.entity_type }),
1070
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { className: "font-mono text-xs", children: relation.entity_id }),
1071
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: relation.relation_role })
1072
+ ] }, relation.id)) })
1073
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-ui-fg-subtle", children: "This asset is not linked to any entities." })
1074
+ ] })
1075
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 items-center justify-center text-sm text-ui-fg-subtle", children: "Select an asset to view details." }),
1076
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.FocusModal.Footer, { className: "mt-6 flex flex-wrap items-center justify-between gap-3", children: [
1077
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
1078
+ /* @__PURE__ */ jsxRuntime.jsxs(
1079
+ ui.Button,
1080
+ {
1081
+ type: "button",
1082
+ variant: "danger",
1083
+ onClick: () => {
1084
+ if (!asset) {
1085
+ return;
1086
+ }
1087
+ const confirmDelete = window.confirm(
1088
+ "Delete this asset and all generated variants?"
1089
+ );
1090
+ if (confirmDelete) {
1091
+ handleDelete(false);
1092
+ }
1093
+ },
1094
+ disabled: !asset,
1095
+ children: [
1096
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "mr-1 size-4" }),
1097
+ " Delete"
1098
+ ]
1099
+ }
1100
+ ),
1101
+ /* @__PURE__ */ jsxRuntime.jsxs(
1102
+ ui.Button,
1103
+ {
1104
+ type: "button",
1105
+ variant: "secondary",
1106
+ onClick: () => asset && handleVariantCopy("medium"),
1107
+ disabled: !asset,
1108
+ children: [
1109
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowPath, { className: "mr-1 size-4" }),
1110
+ " Copy URL"
1111
+ ]
1112
+ }
1113
+ )
1114
+ ] }),
1115
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
1116
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: onClose, children: "Close" }),
1117
+ /* @__PURE__ */ jsxRuntime.jsx(
1118
+ ui.Button,
1119
+ {
1120
+ onClick: handleSave,
1121
+ disabled: !asset || isSaving,
1122
+ isLoading: isSaving,
1123
+ children: "Save changes"
1124
+ }
1125
+ )
1126
+ ] })
897
1127
  ] }),
898
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [
899
- /* @__PURE__ */ jsxRuntime.jsxs(
1128
+ deleteAttempted && asset && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-4 rounded-md border border-ui-border-base bg-ui-bg-subtle p-4 text-sm text-ui-fg-subtle", children: [
1129
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium text-ui-fg-base", children: "Having trouble deleting?" }),
1130
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1", children: "If the asset is still referenced, remove those relations first or attempt a force delete." }),
1131
+ /* @__PURE__ */ jsxRuntime.jsx(
900
1132
  ui.Button,
901
1133
  {
902
- type: "button",
903
- variant: "secondary",
1134
+ className: "mt-3",
1135
+ variant: "danger",
1136
+ size: "small",
904
1137
  onClick: () => {
905
- var _a2;
906
- return (_a2 = fileInputRef.current) == null ? void 0 : _a2.click();
1138
+ const confirmForce = window.confirm(
1139
+ "Force delete will remove the asset even if it is still referenced. Continue?"
1140
+ );
1141
+ if (confirmForce) {
1142
+ handleDelete(true);
1143
+ }
907
1144
  },
908
- isLoading: isReplacing,
909
- children: [
910
- /* @__PURE__ */ jsxRuntime.jsx(icons.CircleArrowUp, { className: "mr-1 size-4" }),
911
- "Replace file"
912
- ]
913
- }
914
- ),
915
- /* @__PURE__ */ jsxRuntime.jsxs(
916
- ui.Button,
917
- {
918
- type: "button",
919
- variant: "secondary",
920
- onClick: () => handleVariantCopy("medium"),
921
- children: [
922
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownTray, { className: "mr-1 size-4" }),
923
- "Get URL"
924
- ]
925
- }
926
- )
927
- ] }),
928
- /* @__PURE__ */ jsxRuntime.jsx(
929
- "input",
930
- {
931
- type: "file",
932
- ref: fileInputRef,
933
- className: "hidden",
934
- onChange: (event) => {
935
- var _a2;
936
- return handleReplace(((_a2 = event.target.files) == null ? void 0 : _a2[0]) ?? null);
937
- }
938
- }
939
- )
940
- ] }),
941
- /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-4", children: [
942
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2", children: [
943
- /* @__PURE__ */ jsxRuntime.jsx(
944
- ui.Input,
945
- {
946
- label: "Title",
947
- placeholder: "Hero banner",
948
- value: title,
949
- onChange: (event) => setTitle(event.target.value)
950
- }
951
- ),
952
- /* @__PURE__ */ jsxRuntime.jsx(
953
- ui.Input,
954
- {
955
- label: "Alt text",
956
- placeholder: "Describe the media for accessibility",
957
- value: altText,
958
- onChange: (event) => setAltText(event.target.value)
959
- }
960
- )
961
- ] }),
962
- /* @__PURE__ */ jsxRuntime.jsx(
963
- ui.Textarea,
964
- {
965
- label: "Caption",
966
- placeholder: "Optional caption or notes",
967
- value: caption,
968
- onChange: (event) => setCaption(event.target.value)
969
- }
970
- ),
971
- /* @__PURE__ */ jsxRuntime.jsx(
972
- ui.Input,
973
- {
974
- label: "Tags",
975
- placeholder: "summer, lookbook, hero",
976
- value: tagsInput,
977
- onChange: (event) => setTagsInput(event.target.value),
978
- helperText: "Separate tags with commas"
979
- }
980
- ),
981
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
982
- /* @__PURE__ */ jsxRuntime.jsxs(
983
- ui.Select,
984
- {
985
- value: status,
986
- onValueChange: (value) => setStatus(value),
987
- children: [
988
- /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Trigger, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Value, { placeholder: "Status" }) }),
989
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Select.Content, { children: [
990
- /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: "draft", children: "Draft" }),
991
- /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: "published", children: "Published" }),
992
- /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: "archived", children: "Archived" })
993
- ] })
994
- ]
995
- }
996
- ),
997
- /* @__PURE__ */ jsxRuntime.jsxs(
998
- ui.Select,
999
- {
1000
- value: visibility,
1001
- onValueChange: (value) => setVisibility(value),
1002
- children: [
1003
- /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Trigger, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Value, { placeholder: "Visibility" }) }),
1004
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Select.Content, { children: [
1005
- /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: "public", children: "Public" }),
1006
- /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: "private", children: "Private" })
1007
- ] })
1008
- ]
1145
+ children: "Force delete"
1009
1146
  }
1010
1147
  )
1011
1148
  ] })
1012
- ] }),
1013
- ((_a = asset.variants) == null ? void 0 : _a.length) ? /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-3", children: [
1014
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-medium", children: "Variants" }),
1015
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Table, { children: [
1016
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Header, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Row, { children: [
1017
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Name" }),
1018
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Format" }),
1019
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Dimensions" }),
1020
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Size" }),
1021
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { className: "text-right", children: "Actions" })
1022
- ] }) }),
1023
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Body, { children: asset.variants.map((variant) => /* @__PURE__ */ jsxRuntime.jsxs(
1024
- ui.Table.Row,
1025
- {
1026
- children: [
1027
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { className: "capitalize", children: variant.preset }),
1028
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: variant.format }),
1029
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: variant.width && variant.height ? `${variant.width}×${variant.height}` : "-" }),
1030
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: formatFileSize(variant.size_bytes) }),
1031
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { className: "flex justify-end gap-2", children: /* @__PURE__ */ jsxRuntime.jsxs(
1032
- ui.Button,
1033
- {
1034
- size: "small",
1035
- variant: "secondary",
1036
- onClick: () => handleVariantCopy(variant.preset),
1037
- children: [
1038
- /* @__PURE__ */ jsxRuntime.jsx(icons.SquareTwoStack, { className: "mr-1 size-4" }),
1039
- " Copy URL"
1040
- ]
1041
- }
1042
- ) })
1043
- ]
1044
- },
1045
- variant.id ?? `${variant.preset}-${variant.format}`
1046
- )) })
1047
- ] })
1048
- ] }) : null,
1049
- /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-3", children: [
1050
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-medium", children: "Usage" }),
1051
- assetRelations.length ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Table, { children: [
1052
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Header, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Row, { children: [
1053
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Entity" }),
1054
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Reference" }),
1055
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Role" })
1056
- ] }) }),
1057
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Body, { children: assetRelations.map((relation) => /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Row, { children: [
1058
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { className: "capitalize", children: relation.entity_type }),
1059
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { className: "font-mono text-xs", children: relation.entity_id }),
1060
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: relation.relation_role })
1061
- ] }, relation.id)) })
1062
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-ui-fg-subtle", children: "This asset is not linked to any entities." })
1063
- ] })
1064
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 items-center justify-center text-sm text-ui-fg-subtle", children: "Select an asset to view details." }),
1065
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Drawer.Footer, { className: "mt-6 flex flex-wrap items-center justify-between gap-3", children: [
1066
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
1067
- /* @__PURE__ */ jsxRuntime.jsxs(
1068
- ui.Button,
1069
- {
1070
- type: "button",
1071
- variant: "danger",
1072
- onClick: () => {
1073
- if (!asset) {
1074
- return;
1075
- }
1076
- const confirmDelete = window.confirm(
1077
- "Delete this asset and all generated variants?"
1078
- );
1079
- if (confirmDelete) {
1080
- handleDelete(false);
1081
- }
1082
- },
1083
- disabled: !asset,
1084
- children: [
1085
- /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "mr-1 size-4" }),
1086
- " Delete"
1087
- ]
1088
- }
1089
- ),
1090
- /* @__PURE__ */ jsxRuntime.jsxs(
1091
- ui.Button,
1092
- {
1093
- type: "button",
1094
- variant: "secondary",
1095
- onClick: () => asset && handleVariantCopy("medium"),
1096
- disabled: !asset,
1097
- children: [
1098
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowPath, { className: "mr-1 size-4" }),
1099
- " Copy URL"
1100
- ]
1101
- }
1102
- )
1103
- ] }),
1104
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
1105
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: onClose, children: "Close" }),
1106
- /* @__PURE__ */ jsxRuntime.jsx(
1107
- ui.Button,
1108
- {
1109
- onClick: handleSave,
1110
- disabled: !asset || isSaving,
1111
- isLoading: isSaving,
1112
- children: "Save changes"
1113
- }
1114
- )
1115
- ] })
1116
- ] }),
1117
- deleteAttempted && asset && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-4 rounded-md border border-ui-border-base bg-ui-bg-subtle p-4 text-sm text-ui-fg-subtle", children: [
1118
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium text-ui-fg-base", children: "Having trouble deleting?" }),
1119
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1", children: "If the asset is still referenced, remove those relations first or attempt a force delete." }),
1120
- /* @__PURE__ */ jsxRuntime.jsx(
1121
- ui.Button,
1122
- {
1123
- className: "mt-3",
1124
- variant: "danger",
1125
- size: "small",
1126
- onClick: () => {
1127
- const confirmForce = window.confirm(
1128
- "Force delete will remove the asset even if it is still referenced. Continue?"
1129
- );
1130
- if (confirmForce) {
1131
- handleDelete(true);
1132
- }
1133
- },
1134
- children: "Force delete"
1135
- }
1136
- )
1137
- ] })
1138
- ] }) });
1149
+ ]
1150
+ }
1151
+ ) });
1139
1152
  };
1153
+ const MediaAssetDrawer = MediaAssetDialog;
1140
1154
  const PAGE_SIZE = 24;
1141
1155
  const MediaLibraryPage = () => {
1142
1156
  const [search, setSearch] = react.useState("");