@lodashventure/medusa-media-manager 0.2.10 → 0.2.12
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.
|
@@ -2,7 +2,7 @@ import { jsxs, jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState, useMemo, useCallback, useRef, useEffect } from "react";
|
|
3
3
|
import { defineRouteConfig } from "@medusajs/admin-sdk";
|
|
4
4
|
import { SquaresPlus, ListBullet, ArrowPath, CloudArrowUp, Photo, ShieldCheck, DocumentText, PlaySolid, X, CircleArrowUp, ArrowDownTray, SquareTwoStack, Trash } from "@medusajs/icons";
|
|
5
|
-
import { Input, Select, TooltipProvider, Tooltip, IconButton, clx, Button, Badge, Skeleton, Table, StatusBadge, toast, Drawer, FocusModal, Textarea, Container, Heading, Alert } from "@medusajs/ui";
|
|
5
|
+
import { Input, Select, TooltipProvider, Tooltip, IconButton, clx, Button, Badge, Skeleton, Table, StatusBadge, toast, Drawer, FocusModal, Textarea, Prompt, Container, Heading, Alert } from "@medusajs/ui";
|
|
6
6
|
import "@medusajs/admin-shared";
|
|
7
7
|
const ALL_OPTION_VALUE = "all";
|
|
8
8
|
const normalizeSelectValue = (value) => {
|
|
@@ -703,11 +703,13 @@ const MediaAssetDialog = ({
|
|
|
703
703
|
const [visibility, setVisibility] = useState("public");
|
|
704
704
|
const [deletePromptOpen, setDeletePromptOpen] = useState(false);
|
|
705
705
|
const [deleteAttempted, setDeleteAttempted] = useState(false);
|
|
706
|
+
const [isDeleting, setIsDeleting] = useState(false);
|
|
706
707
|
useEffect(() => {
|
|
707
708
|
if (!assetId) {
|
|
708
709
|
setAsset(null);
|
|
709
710
|
setPreviewUrl(null);
|
|
710
711
|
setDeleteAttempted(false);
|
|
712
|
+
setDeletePromptOpen(false);
|
|
711
713
|
return;
|
|
712
714
|
}
|
|
713
715
|
let isMounted = true;
|
|
@@ -801,6 +803,10 @@ const MediaAssetDialog = ({
|
|
|
801
803
|
if (!assetId) {
|
|
802
804
|
return;
|
|
803
805
|
}
|
|
806
|
+
if (isDeleting) {
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
809
|
+
setIsDeleting(true);
|
|
804
810
|
try {
|
|
805
811
|
await deleteMediaAsset(assetId, force);
|
|
806
812
|
toast.success("Asset deleted");
|
|
@@ -813,6 +819,8 @@ const MediaAssetDialog = ({
|
|
|
813
819
|
toast.error("Failed to delete", {
|
|
814
820
|
description: (err == null ? void 0 : err.message) ?? "Unable to delete asset. If it's in use, try forcing deletion."
|
|
815
821
|
});
|
|
822
|
+
} finally {
|
|
823
|
+
setIsDeleting(false);
|
|
816
824
|
}
|
|
817
825
|
};
|
|
818
826
|
const handleVariantCopy = async (preset) => {
|
|
@@ -858,67 +866,239 @@ const MediaAssetDialog = ({
|
|
|
858
866
|
}
|
|
859
867
|
};
|
|
860
868
|
const assetRelations = (asset == null ? void 0 : asset.relations) ?? [];
|
|
861
|
-
return /* @__PURE__ */
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
/* @__PURE__ */
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
/* @__PURE__ */ jsxs("
|
|
873
|
-
/* @__PURE__ */
|
|
874
|
-
"
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
/* @__PURE__ */
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
869
|
+
return /* @__PURE__ */ jsxs(FocusModal, { open: Boolean(assetId), onOpenChange: (open) => !open && onClose(), children: [
|
|
870
|
+
/* @__PURE__ */ jsxs(
|
|
871
|
+
FocusModal.Content,
|
|
872
|
+
{
|
|
873
|
+
ref: modalContentRef,
|
|
874
|
+
className: "flex h-full w-full max-w-3xl flex-col overflow-y-auto p-6",
|
|
875
|
+
children: [
|
|
876
|
+
/* @__PURE__ */ jsxs(FocusModal.Header, { children: [
|
|
877
|
+
/* @__PURE__ */ jsx(FocusModal.Title, { className: "text-lg font-semibold", children: "Asset details" }),
|
|
878
|
+
/* @__PURE__ */ jsx(FocusModal.Description, { children: "Review and update metadata, copy delivery URLs, or replace the original file." })
|
|
879
|
+
] }),
|
|
880
|
+
isLoading ? /* @__PURE__ */ jsx("div", { className: "flex flex-1 items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "text-sm text-ui-fg-subtle", children: "Loading asset..." }) }) : asset ? /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col gap-y-6", children: [
|
|
881
|
+
/* @__PURE__ */ jsxs("section", { className: "flex flex-col gap-y-4", children: [
|
|
882
|
+
/* @__PURE__ */ jsx("div", { className: "aspect-video w-full overflow-hidden rounded-lg border border-ui-border-base bg-ui-bg-subtle", children: previewUrl ? /* @__PURE__ */ jsx(
|
|
883
|
+
"img",
|
|
884
|
+
{
|
|
885
|
+
src: previewUrl,
|
|
886
|
+
alt: asset.original_filename,
|
|
887
|
+
className: "h-full w-full object-contain"
|
|
888
|
+
}
|
|
889
|
+
) : /* @__PURE__ */ jsx("div", { className: "flex h-full w-full items-center justify-center text-ui-fg-muted", children: /* @__PURE__ */ jsx(Photo, { className: "size-8" }) }) }),
|
|
890
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2 text-xs text-ui-fg-subtle", children: [
|
|
891
|
+
/* @__PURE__ */ jsx("span", { children: asset.mime }),
|
|
892
|
+
/* @__PURE__ */ jsx("span", { children: "·" }),
|
|
893
|
+
/* @__PURE__ */ jsx("span", { children: formatFileSize(asset.size_bytes) }),
|
|
894
|
+
/* @__PURE__ */ jsx("span", { children: "·" }),
|
|
895
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
896
|
+
"Updated ",
|
|
897
|
+
formatDateTime(asset.updated_at)
|
|
898
|
+
] }),
|
|
899
|
+
/* @__PURE__ */ jsx(
|
|
900
|
+
StatusBadge,
|
|
901
|
+
{
|
|
902
|
+
size: "small",
|
|
903
|
+
color: STATUS_COLORS[asset.status] ?? "default",
|
|
904
|
+
children: asset.status
|
|
905
|
+
}
|
|
906
|
+
),
|
|
907
|
+
/* @__PURE__ */ jsx(
|
|
908
|
+
Badge,
|
|
909
|
+
{
|
|
910
|
+
size: "small",
|
|
911
|
+
variant: asset.visibility === "public" ? "neutral" : "warning",
|
|
912
|
+
className: "capitalize",
|
|
913
|
+
children: asset.visibility
|
|
914
|
+
}
|
|
915
|
+
)
|
|
916
|
+
] }),
|
|
917
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2", children: [
|
|
918
|
+
/* @__PURE__ */ jsxs(
|
|
919
|
+
Button,
|
|
920
|
+
{
|
|
921
|
+
type: "button",
|
|
922
|
+
variant: "secondary",
|
|
923
|
+
onClick: () => {
|
|
924
|
+
var _a2;
|
|
925
|
+
return (_a2 = fileInputRef.current) == null ? void 0 : _a2.click();
|
|
926
|
+
},
|
|
927
|
+
isLoading: isReplacing,
|
|
928
|
+
children: [
|
|
929
|
+
/* @__PURE__ */ jsx(CircleArrowUp, { className: "mr-1 size-4" }),
|
|
930
|
+
"Replace file"
|
|
931
|
+
]
|
|
932
|
+
}
|
|
933
|
+
),
|
|
934
|
+
/* @__PURE__ */ jsxs(
|
|
935
|
+
Button,
|
|
936
|
+
{
|
|
937
|
+
type: "button",
|
|
938
|
+
variant: "secondary",
|
|
939
|
+
onClick: () => handleVariantCopy("medium"),
|
|
940
|
+
children: [
|
|
941
|
+
/* @__PURE__ */ jsx(ArrowDownTray, { className: "mr-1 size-4" }),
|
|
942
|
+
"Get URL"
|
|
943
|
+
]
|
|
944
|
+
}
|
|
945
|
+
)
|
|
889
946
|
] }),
|
|
890
947
|
/* @__PURE__ */ jsx(
|
|
891
|
-
|
|
948
|
+
"input",
|
|
892
949
|
{
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
950
|
+
type: "file",
|
|
951
|
+
ref: fileInputRef,
|
|
952
|
+
className: "hidden",
|
|
953
|
+
onChange: (event) => {
|
|
954
|
+
var _a2;
|
|
955
|
+
return handleReplace(((_a2 = event.target.files) == null ? void 0 : _a2[0]) ?? null);
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
)
|
|
959
|
+
] }),
|
|
960
|
+
/* @__PURE__ */ jsxs("section", { className: "space-y-4", children: [
|
|
961
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2", children: [
|
|
962
|
+
/* @__PURE__ */ jsx(
|
|
963
|
+
Input,
|
|
964
|
+
{
|
|
965
|
+
label: "Title",
|
|
966
|
+
placeholder: "Hero banner",
|
|
967
|
+
value: title,
|
|
968
|
+
onChange: (event) => setTitle(event.target.value)
|
|
969
|
+
}
|
|
970
|
+
),
|
|
971
|
+
/* @__PURE__ */ jsx(
|
|
972
|
+
Input,
|
|
973
|
+
{
|
|
974
|
+
label: "Alt text",
|
|
975
|
+
placeholder: "Describe the media for accessibility",
|
|
976
|
+
value: altText,
|
|
977
|
+
onChange: (event) => setAltText(event.target.value)
|
|
978
|
+
}
|
|
979
|
+
)
|
|
980
|
+
] }),
|
|
981
|
+
/* @__PURE__ */ jsx(
|
|
982
|
+
Textarea,
|
|
983
|
+
{
|
|
984
|
+
label: "Caption",
|
|
985
|
+
placeholder: "Optional caption or notes",
|
|
986
|
+
value: caption,
|
|
987
|
+
onChange: (event) => setCaption(event.target.value)
|
|
896
988
|
}
|
|
897
989
|
),
|
|
898
990
|
/* @__PURE__ */ jsx(
|
|
899
|
-
|
|
991
|
+
Input,
|
|
900
992
|
{
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
993
|
+
label: "Tags",
|
|
994
|
+
placeholder: "summer, lookbook, hero",
|
|
995
|
+
value: tagsInput,
|
|
996
|
+
onChange: (event) => setTagsInput(event.target.value),
|
|
997
|
+
helperText: "Separate tags with commas"
|
|
905
998
|
}
|
|
906
|
-
)
|
|
999
|
+
),
|
|
1000
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
|
|
1001
|
+
/* @__PURE__ */ jsxs(
|
|
1002
|
+
Select,
|
|
1003
|
+
{
|
|
1004
|
+
value: status,
|
|
1005
|
+
onValueChange: (value) => setStatus(value),
|
|
1006
|
+
children: [
|
|
1007
|
+
/* @__PURE__ */ jsx(Select.Trigger, { children: /* @__PURE__ */ jsx(Select.Value, { placeholder: "Status" }) }),
|
|
1008
|
+
/* @__PURE__ */ jsxs(Select.Content, { children: [
|
|
1009
|
+
/* @__PURE__ */ jsx(Select.Item, { value: "draft", children: "Draft" }),
|
|
1010
|
+
/* @__PURE__ */ jsx(Select.Item, { value: "published", children: "Published" }),
|
|
1011
|
+
/* @__PURE__ */ jsx(Select.Item, { value: "archived", children: "Archived" })
|
|
1012
|
+
] })
|
|
1013
|
+
]
|
|
1014
|
+
}
|
|
1015
|
+
),
|
|
1016
|
+
/* @__PURE__ */ jsxs(
|
|
1017
|
+
Select,
|
|
1018
|
+
{
|
|
1019
|
+
value: visibility,
|
|
1020
|
+
onValueChange: (value) => setVisibility(value),
|
|
1021
|
+
children: [
|
|
1022
|
+
/* @__PURE__ */ jsx(Select.Trigger, { children: /* @__PURE__ */ jsx(Select.Value, { placeholder: "Visibility" }) }),
|
|
1023
|
+
/* @__PURE__ */ jsxs(Select.Content, { children: [
|
|
1024
|
+
/* @__PURE__ */ jsx(Select.Item, { value: "public", children: "Public" }),
|
|
1025
|
+
/* @__PURE__ */ jsx(Select.Item, { value: "private", children: "Private" })
|
|
1026
|
+
] })
|
|
1027
|
+
]
|
|
1028
|
+
}
|
|
1029
|
+
)
|
|
1030
|
+
] })
|
|
907
1031
|
] }),
|
|
908
|
-
/* @__PURE__ */ jsxs("
|
|
1032
|
+
((_a = asset.variants) == null ? void 0 : _a.length) ? /* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
|
|
1033
|
+
/* @__PURE__ */ jsx("h3", { className: "text-sm font-medium", children: "Variants" }),
|
|
1034
|
+
/* @__PURE__ */ jsxs(Table, { children: [
|
|
1035
|
+
/* @__PURE__ */ jsx(Table.Header, { children: /* @__PURE__ */ jsxs(Table.Row, { children: [
|
|
1036
|
+
/* @__PURE__ */ jsx(Table.HeaderCell, { children: "Name" }),
|
|
1037
|
+
/* @__PURE__ */ jsx(Table.HeaderCell, { children: "Format" }),
|
|
1038
|
+
/* @__PURE__ */ jsx(Table.HeaderCell, { children: "Dimensions" }),
|
|
1039
|
+
/* @__PURE__ */ jsx(Table.HeaderCell, { children: "Size" }),
|
|
1040
|
+
/* @__PURE__ */ jsx(Table.HeaderCell, { className: "text-right", children: "Actions" })
|
|
1041
|
+
] }) }),
|
|
1042
|
+
/* @__PURE__ */ jsx(Table.Body, { children: asset.variants.map((variant) => /* @__PURE__ */ jsxs(
|
|
1043
|
+
Table.Row,
|
|
1044
|
+
{
|
|
1045
|
+
children: [
|
|
1046
|
+
/* @__PURE__ */ jsx(Table.Cell, { className: "capitalize", children: variant.preset }),
|
|
1047
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: variant.format }),
|
|
1048
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: variant.width && variant.height ? `${variant.width}×${variant.height}` : "-" }),
|
|
1049
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: formatFileSize(variant.size_bytes) }),
|
|
1050
|
+
/* @__PURE__ */ jsx(Table.Cell, { className: "flex justify-end gap-2", children: /* @__PURE__ */ jsxs(
|
|
1051
|
+
Button,
|
|
1052
|
+
{
|
|
1053
|
+
size: "small",
|
|
1054
|
+
variant: "secondary",
|
|
1055
|
+
onClick: () => handleVariantCopy(variant.preset),
|
|
1056
|
+
children: [
|
|
1057
|
+
/* @__PURE__ */ jsx(SquareTwoStack, { className: "mr-1 size-4" }),
|
|
1058
|
+
" Copy URL"
|
|
1059
|
+
]
|
|
1060
|
+
}
|
|
1061
|
+
) })
|
|
1062
|
+
]
|
|
1063
|
+
},
|
|
1064
|
+
variant.id ?? `${variant.preset}-${variant.format}`
|
|
1065
|
+
)) })
|
|
1066
|
+
] })
|
|
1067
|
+
] }) : null,
|
|
1068
|
+
/* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
|
|
1069
|
+
/* @__PURE__ */ jsx("h3", { className: "text-sm font-medium", children: "Usage" }),
|
|
1070
|
+
assetRelations.length ? /* @__PURE__ */ jsxs(Table, { children: [
|
|
1071
|
+
/* @__PURE__ */ jsx(Table.Header, { children: /* @__PURE__ */ jsxs(Table.Row, { children: [
|
|
1072
|
+
/* @__PURE__ */ jsx(Table.HeaderCell, { children: "Entity" }),
|
|
1073
|
+
/* @__PURE__ */ jsx(Table.HeaderCell, { children: "Reference" }),
|
|
1074
|
+
/* @__PURE__ */ jsx(Table.HeaderCell, { children: "Role" })
|
|
1075
|
+
] }) }),
|
|
1076
|
+
/* @__PURE__ */ jsx(Table.Body, { children: assetRelations.map((relation) => /* @__PURE__ */ jsxs(Table.Row, { children: [
|
|
1077
|
+
/* @__PURE__ */ jsx(Table.Cell, { className: "capitalize", children: relation.entity_type }),
|
|
1078
|
+
/* @__PURE__ */ jsx(Table.Cell, { className: "font-mono text-xs", children: relation.entity_id }),
|
|
1079
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: relation.relation_role })
|
|
1080
|
+
] }, relation.id)) })
|
|
1081
|
+
] }) : /* @__PURE__ */ jsx("p", { className: "text-sm text-ui-fg-subtle", children: "This asset is not linked to any entities." })
|
|
1082
|
+
] })
|
|
1083
|
+
] }) : /* @__PURE__ */ jsx("div", { className: "flex flex-1 items-center justify-center text-sm text-ui-fg-subtle", children: "Select an asset to view details." }),
|
|
1084
|
+
/* @__PURE__ */ jsxs(FocusModal.Footer, { className: "mt-6 flex flex-wrap items-center justify-between gap-3", children: [
|
|
1085
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
909
1086
|
/* @__PURE__ */ jsxs(
|
|
910
1087
|
Button,
|
|
911
1088
|
{
|
|
912
1089
|
type: "button",
|
|
913
|
-
variant: "
|
|
1090
|
+
variant: "danger",
|
|
914
1091
|
onClick: () => {
|
|
915
|
-
|
|
916
|
-
|
|
1092
|
+
if (!asset) {
|
|
1093
|
+
return;
|
|
1094
|
+
}
|
|
1095
|
+
setDeletePromptOpen(true);
|
|
917
1096
|
},
|
|
918
|
-
|
|
1097
|
+
disabled: !asset || isDeleting,
|
|
1098
|
+
isLoading: isDeleting,
|
|
919
1099
|
children: [
|
|
920
|
-
/* @__PURE__ */ jsx(
|
|
921
|
-
"
|
|
1100
|
+
/* @__PURE__ */ jsx(Trash, { className: "mr-1 size-4" }),
|
|
1101
|
+
" Delete"
|
|
922
1102
|
]
|
|
923
1103
|
}
|
|
924
1104
|
),
|
|
@@ -927,227 +1107,82 @@ const MediaAssetDialog = ({
|
|
|
927
1107
|
{
|
|
928
1108
|
type: "button",
|
|
929
1109
|
variant: "secondary",
|
|
930
|
-
onClick: () => handleVariantCopy("medium"),
|
|
1110
|
+
onClick: () => asset && handleVariantCopy("medium"),
|
|
1111
|
+
disabled: !asset,
|
|
931
1112
|
children: [
|
|
932
|
-
/* @__PURE__ */ jsx(
|
|
933
|
-
"
|
|
1113
|
+
/* @__PURE__ */ jsx(ArrowPath, { className: "mr-1 size-4" }),
|
|
1114
|
+
" Copy URL"
|
|
934
1115
|
]
|
|
935
1116
|
}
|
|
936
1117
|
)
|
|
937
1118
|
] }),
|
|
938
|
-
/* @__PURE__ */
|
|
939
|
-
"
|
|
940
|
-
{
|
|
941
|
-
type: "file",
|
|
942
|
-
ref: fileInputRef,
|
|
943
|
-
className: "hidden",
|
|
944
|
-
onChange: (event) => {
|
|
945
|
-
var _a2;
|
|
946
|
-
return handleReplace(((_a2 = event.target.files) == null ? void 0 : _a2[0]) ?? null);
|
|
947
|
-
}
|
|
948
|
-
}
|
|
949
|
-
)
|
|
950
|
-
] }),
|
|
951
|
-
/* @__PURE__ */ jsxs("section", { className: "space-y-4", children: [
|
|
952
|
-
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2", children: [
|
|
953
|
-
/* @__PURE__ */ jsx(
|
|
954
|
-
Input,
|
|
955
|
-
{
|
|
956
|
-
label: "Title",
|
|
957
|
-
placeholder: "Hero banner",
|
|
958
|
-
value: title,
|
|
959
|
-
onChange: (event) => setTitle(event.target.value)
|
|
960
|
-
}
|
|
961
|
-
),
|
|
1119
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
1120
|
+
/* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: onClose, children: "Close" }),
|
|
962
1121
|
/* @__PURE__ */ jsx(
|
|
963
|
-
|
|
964
|
-
{
|
|
965
|
-
label: "Alt text",
|
|
966
|
-
placeholder: "Describe the media for accessibility",
|
|
967
|
-
value: altText,
|
|
968
|
-
onChange: (event) => setAltText(event.target.value)
|
|
969
|
-
}
|
|
970
|
-
)
|
|
971
|
-
] }),
|
|
972
|
-
/* @__PURE__ */ jsx(
|
|
973
|
-
Textarea,
|
|
974
|
-
{
|
|
975
|
-
label: "Caption",
|
|
976
|
-
placeholder: "Optional caption or notes",
|
|
977
|
-
value: caption,
|
|
978
|
-
onChange: (event) => setCaption(event.target.value)
|
|
979
|
-
}
|
|
980
|
-
),
|
|
981
|
-
/* @__PURE__ */ jsx(
|
|
982
|
-
Input,
|
|
983
|
-
{
|
|
984
|
-
label: "Tags",
|
|
985
|
-
placeholder: "summer, lookbook, hero",
|
|
986
|
-
value: tagsInput,
|
|
987
|
-
onChange: (event) => setTagsInput(event.target.value),
|
|
988
|
-
helperText: "Separate tags with commas"
|
|
989
|
-
}
|
|
990
|
-
),
|
|
991
|
-
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
|
|
992
|
-
/* @__PURE__ */ jsxs(
|
|
993
|
-
Select,
|
|
1122
|
+
Button,
|
|
994
1123
|
{
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
/* @__PURE__ */ jsxs(Select.Content, { children: [
|
|
1000
|
-
/* @__PURE__ */ jsx(Select.Item, { value: "draft", children: "Draft" }),
|
|
1001
|
-
/* @__PURE__ */ jsx(Select.Item, { value: "published", children: "Published" }),
|
|
1002
|
-
/* @__PURE__ */ jsx(Select.Item, { value: "archived", children: "Archived" })
|
|
1003
|
-
] })
|
|
1004
|
-
]
|
|
1005
|
-
}
|
|
1006
|
-
),
|
|
1007
|
-
/* @__PURE__ */ jsxs(
|
|
1008
|
-
Select,
|
|
1009
|
-
{
|
|
1010
|
-
value: visibility,
|
|
1011
|
-
onValueChange: (value) => setVisibility(value),
|
|
1012
|
-
children: [
|
|
1013
|
-
/* @__PURE__ */ jsx(Select.Trigger, { children: /* @__PURE__ */ jsx(Select.Value, { placeholder: "Visibility" }) }),
|
|
1014
|
-
/* @__PURE__ */ jsxs(Select.Content, { children: [
|
|
1015
|
-
/* @__PURE__ */ jsx(Select.Item, { value: "public", children: "Public" }),
|
|
1016
|
-
/* @__PURE__ */ jsx(Select.Item, { value: "private", children: "Private" })
|
|
1017
|
-
] })
|
|
1018
|
-
]
|
|
1124
|
+
onClick: handleSave,
|
|
1125
|
+
disabled: !asset || isSaving,
|
|
1126
|
+
isLoading: isSaving,
|
|
1127
|
+
children: "Save changes"
|
|
1019
1128
|
}
|
|
1020
1129
|
)
|
|
1021
1130
|
] })
|
|
1022
1131
|
] }),
|
|
1023
|
-
|
|
1024
|
-
/* @__PURE__ */ jsx("
|
|
1025
|
-
/* @__PURE__ */
|
|
1026
|
-
|
|
1027
|
-
/* @__PURE__ */ jsx(Table.HeaderCell, { children: "Name" }),
|
|
1028
|
-
/* @__PURE__ */ jsx(Table.HeaderCell, { children: "Format" }),
|
|
1029
|
-
/* @__PURE__ */ jsx(Table.HeaderCell, { children: "Dimensions" }),
|
|
1030
|
-
/* @__PURE__ */ jsx(Table.HeaderCell, { children: "Size" }),
|
|
1031
|
-
/* @__PURE__ */ jsx(Table.HeaderCell, { className: "text-right", children: "Actions" })
|
|
1032
|
-
] }) }),
|
|
1033
|
-
/* @__PURE__ */ jsx(Table.Body, { children: asset.variants.map((variant) => /* @__PURE__ */ jsxs(
|
|
1034
|
-
Table.Row,
|
|
1035
|
-
{
|
|
1036
|
-
children: [
|
|
1037
|
-
/* @__PURE__ */ jsx(Table.Cell, { className: "capitalize", children: variant.preset }),
|
|
1038
|
-
/* @__PURE__ */ jsx(Table.Cell, { children: variant.format }),
|
|
1039
|
-
/* @__PURE__ */ jsx(Table.Cell, { children: variant.width && variant.height ? `${variant.width}×${variant.height}` : "-" }),
|
|
1040
|
-
/* @__PURE__ */ jsx(Table.Cell, { children: formatFileSize(variant.size_bytes) }),
|
|
1041
|
-
/* @__PURE__ */ jsx(Table.Cell, { className: "flex justify-end gap-2", children: /* @__PURE__ */ jsxs(
|
|
1042
|
-
Button,
|
|
1043
|
-
{
|
|
1044
|
-
size: "small",
|
|
1045
|
-
variant: "secondary",
|
|
1046
|
-
onClick: () => handleVariantCopy(variant.preset),
|
|
1047
|
-
children: [
|
|
1048
|
-
/* @__PURE__ */ jsx(SquareTwoStack, { className: "mr-1 size-4" }),
|
|
1049
|
-
" Copy URL"
|
|
1050
|
-
]
|
|
1051
|
-
}
|
|
1052
|
-
) })
|
|
1053
|
-
]
|
|
1054
|
-
},
|
|
1055
|
-
variant.id ?? `${variant.preset}-${variant.format}`
|
|
1056
|
-
)) })
|
|
1057
|
-
] })
|
|
1058
|
-
] }) : null,
|
|
1059
|
-
/* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
|
|
1060
|
-
/* @__PURE__ */ jsx("h3", { className: "text-sm font-medium", children: "Usage" }),
|
|
1061
|
-
assetRelations.length ? /* @__PURE__ */ jsxs(Table, { children: [
|
|
1062
|
-
/* @__PURE__ */ jsx(Table.Header, { children: /* @__PURE__ */ jsxs(Table.Row, { children: [
|
|
1063
|
-
/* @__PURE__ */ jsx(Table.HeaderCell, { children: "Entity" }),
|
|
1064
|
-
/* @__PURE__ */ jsx(Table.HeaderCell, { children: "Reference" }),
|
|
1065
|
-
/* @__PURE__ */ jsx(Table.HeaderCell, { children: "Role" })
|
|
1066
|
-
] }) }),
|
|
1067
|
-
/* @__PURE__ */ jsx(Table.Body, { children: assetRelations.map((relation) => /* @__PURE__ */ jsxs(Table.Row, { children: [
|
|
1068
|
-
/* @__PURE__ */ jsx(Table.Cell, { className: "capitalize", children: relation.entity_type }),
|
|
1069
|
-
/* @__PURE__ */ jsx(Table.Cell, { className: "font-mono text-xs", children: relation.entity_id }),
|
|
1070
|
-
/* @__PURE__ */ jsx(Table.Cell, { children: relation.relation_role })
|
|
1071
|
-
] }, relation.id)) })
|
|
1072
|
-
] }) : /* @__PURE__ */ jsx("p", { className: "text-sm text-ui-fg-subtle", children: "This asset is not linked to any entities." })
|
|
1073
|
-
] })
|
|
1074
|
-
] }) : /* @__PURE__ */ jsx("div", { className: "flex flex-1 items-center justify-center text-sm text-ui-fg-subtle", children: "Select an asset to view details." }),
|
|
1075
|
-
/* @__PURE__ */ jsxs(FocusModal.Footer, { className: "mt-6 flex flex-wrap items-center justify-between gap-3", children: [
|
|
1076
|
-
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
1077
|
-
/* @__PURE__ */ jsxs(
|
|
1132
|
+
deleteAttempted && asset && /* @__PURE__ */ 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: [
|
|
1133
|
+
/* @__PURE__ */ jsx("p", { className: "font-medium text-ui-fg-base", children: "Having trouble deleting?" }),
|
|
1134
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1", children: "If the asset is still referenced, remove those relations first or attempt a force delete." }),
|
|
1135
|
+
/* @__PURE__ */ jsx(
|
|
1078
1136
|
Button,
|
|
1079
1137
|
{
|
|
1080
|
-
|
|
1138
|
+
className: "mt-3",
|
|
1081
1139
|
variant: "danger",
|
|
1140
|
+
size: "small",
|
|
1141
|
+
disabled: isDeleting,
|
|
1142
|
+
isLoading: isDeleting,
|
|
1082
1143
|
onClick: () => {
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
}
|
|
1086
|
-
const confirmDelete = window.confirm(
|
|
1087
|
-
"Delete this asset and all generated variants?"
|
|
1144
|
+
const confirmForce = window.confirm(
|
|
1145
|
+
"Force delete will remove the asset even if it is still referenced. Continue?"
|
|
1088
1146
|
);
|
|
1089
|
-
if (
|
|
1090
|
-
handleDelete(
|
|
1147
|
+
if (confirmForce) {
|
|
1148
|
+
handleDelete(true);
|
|
1091
1149
|
}
|
|
1092
1150
|
},
|
|
1093
|
-
|
|
1094
|
-
children: [
|
|
1095
|
-
/* @__PURE__ */ jsx(Trash, { className: "mr-1 size-4" }),
|
|
1096
|
-
" Delete"
|
|
1097
|
-
]
|
|
1098
|
-
}
|
|
1099
|
-
),
|
|
1100
|
-
/* @__PURE__ */ jsxs(
|
|
1101
|
-
Button,
|
|
1102
|
-
{
|
|
1103
|
-
type: "button",
|
|
1104
|
-
variant: "secondary",
|
|
1105
|
-
onClick: () => asset && handleVariantCopy("medium"),
|
|
1106
|
-
disabled: !asset,
|
|
1107
|
-
children: [
|
|
1108
|
-
/* @__PURE__ */ jsx(ArrowPath, { className: "mr-1 size-4" }),
|
|
1109
|
-
" Copy URL"
|
|
1110
|
-
]
|
|
1151
|
+
children: "Force delete"
|
|
1111
1152
|
}
|
|
1112
1153
|
)
|
|
1154
|
+
] })
|
|
1155
|
+
]
|
|
1156
|
+
}
|
|
1157
|
+
),
|
|
1158
|
+
/* @__PURE__ */ jsx(
|
|
1159
|
+
Prompt,
|
|
1160
|
+
{
|
|
1161
|
+
variant: "confirmation",
|
|
1162
|
+
open: Boolean(asset) && deletePromptOpen,
|
|
1163
|
+
onOpenChange: (open) => setDeletePromptOpen(open),
|
|
1164
|
+
children: /* @__PURE__ */ jsxs(Prompt.Content, { children: [
|
|
1165
|
+
/* @__PURE__ */ jsxs(Prompt.Header, { children: [
|
|
1166
|
+
/* @__PURE__ */ jsx(Prompt.Title, { children: "Delete asset" }),
|
|
1167
|
+
/* @__PURE__ */ jsx(Prompt.Description, { children: asset ? `Delete "${asset.original_filename}" and all generated variants? This cannot be undone.` : "Delete this asset and all generated variants? This cannot be undone." })
|
|
1113
1168
|
] }),
|
|
1114
|
-
/* @__PURE__ */ jsxs(
|
|
1115
|
-
/* @__PURE__ */ jsx(
|
|
1116
|
-
/* @__PURE__ */ jsx(
|
|
1169
|
+
/* @__PURE__ */ jsxs(Prompt.Footer, { children: [
|
|
1170
|
+
/* @__PURE__ */ jsx(Prompt.Cancel, { children: "Cancel" }),
|
|
1171
|
+
/* @__PURE__ */ jsx(Prompt.Action, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
1117
1172
|
Button,
|
|
1118
1173
|
{
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1174
|
+
variant: "danger",
|
|
1175
|
+
onClick: () => handleDelete(false),
|
|
1176
|
+
disabled: isDeleting,
|
|
1177
|
+
isLoading: isDeleting,
|
|
1178
|
+
children: "Delete"
|
|
1123
1179
|
}
|
|
1124
|
-
)
|
|
1180
|
+
) })
|
|
1125
1181
|
] })
|
|
1126
|
-
] }),
|
|
1127
|
-
deleteAttempted && asset && /* @__PURE__ */ 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: [
|
|
1128
|
-
/* @__PURE__ */ jsx("p", { className: "font-medium text-ui-fg-base", children: "Having trouble deleting?" }),
|
|
1129
|
-
/* @__PURE__ */ jsx("p", { className: "mt-1", children: "If the asset is still referenced, remove those relations first or attempt a force delete." }),
|
|
1130
|
-
/* @__PURE__ */ jsx(
|
|
1131
|
-
Button,
|
|
1132
|
-
{
|
|
1133
|
-
className: "mt-3",
|
|
1134
|
-
variant: "danger",
|
|
1135
|
-
size: "small",
|
|
1136
|
-
onClick: () => {
|
|
1137
|
-
const confirmForce = window.confirm(
|
|
1138
|
-
"Force delete will remove the asset even if it is still referenced. Continue?"
|
|
1139
|
-
);
|
|
1140
|
-
if (confirmForce) {
|
|
1141
|
-
handleDelete(true);
|
|
1142
|
-
}
|
|
1143
|
-
},
|
|
1144
|
-
children: "Force delete"
|
|
1145
|
-
}
|
|
1146
|
-
)
|
|
1147
1182
|
] })
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1183
|
+
}
|
|
1184
|
+
)
|
|
1185
|
+
] });
|
|
1151
1186
|
};
|
|
1152
1187
|
const MediaAssetDrawer = MediaAssetDialog;
|
|
1153
1188
|
const PAGE_SIZE = 24;
|