@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
|
|
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.
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
"
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
className: "
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
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.
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
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: "
|
|
899
|
-
/* @__PURE__ */ jsxRuntime.
|
|
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
|
-
|
|
903
|
-
variant: "
|
|
1134
|
+
className: "mt-3",
|
|
1135
|
+
variant: "danger",
|
|
1136
|
+
size: "small",
|
|
904
1137
|
onClick: () => {
|
|
905
|
-
|
|
906
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1014
|
-
|
|
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("");
|