sanity-plugin-media 4.1.1 → 4.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.
- package/LICENSE +1 -1
- package/README.md +56 -4
- package/dist/index.d.mts +131 -57
- package/dist/index.d.ts +131 -57
- package/dist/index.js +259 -98
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +259 -98
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -2
- package/src/__tests__/fixtures/createEpicTestStore.ts +27 -0
- package/src/__tests__/fixtures/listenMock.ts +9 -0
- package/src/__tests__/fixtures/mockSanityClient.ts +84 -0
- package/src/__tests__/fixtures/renderWithProviders.tsx +54 -0
- package/src/__tests__/fixtures/rootState.ts +27 -0
- package/src/__tests__/fixtures/withinDialog.ts +28 -0
- package/src/components/Browser/Browser.test.tsx +44 -0
- package/src/components/CardAsset/CardAsset.test.tsx +322 -0
- package/src/components/DialogAssetEdit/Details.tsx +123 -44
- package/src/components/DialogAssetEdit/DialogAssetEdit.test.tsx +215 -0
- package/src/components/DialogAssetEdit/index.tsx +138 -30
- package/src/components/DialogTagCreate/DialogTagCreate.test.tsx +120 -0
- package/src/components/DialogTagEdit/DialogTagEdit.test.tsx +164 -0
- package/src/components/FormBuilderTool/FormBuilderTool.test.tsx +62 -0
- package/src/components/UploadDropzone/UploadDropzone.test.tsx +39 -0
- package/src/contexts/ToolOptionsContext.tsx +6 -3
- package/src/formSchema/index.test.ts +55 -0
- package/src/formSchema/index.ts +28 -12
- package/src/hooks/useVersionedClient.ts +1 -1
- package/src/modules/assets/deleteAndUpdateEpics.test.ts +86 -0
- package/src/modules/assets/fetchEpic.test.ts +72 -0
- package/src/modules/assets/reducer.test.ts +90 -0
- package/src/modules/assets/tagsAndListenerEpics.test.ts +205 -0
- package/src/modules/dialog/epics.test.ts +167 -0
- package/src/modules/dialog/reducer.test.ts +184 -0
- package/src/modules/notifications/epics.test.ts +373 -0
- package/src/modules/notifications/index.ts +24 -4
- package/src/modules/notifications/reducer.test.ts +53 -0
- package/src/modules/search/index.test.ts +35 -0
- package/src/modules/selectors.test.ts +20 -0
- package/src/modules/tags/epics.test.ts +95 -0
- package/src/modules/tags/index.test.ts +41 -0
- package/src/modules/uploads/epics.test.ts +108 -0
- package/src/modules/uploads/index.test.ts +58 -0
- package/src/operators/checkTagName.test.ts +28 -0
- package/src/types/index.ts +20 -7
- package/src/utils/blocksToText.test.ts +42 -0
- package/src/utils/constructFilter.test.ts +119 -0
- package/src/utils/generatePreviewBlobUrl.test.ts +69 -0
- package/src/utils/getAssetResolution.test.ts +12 -0
- package/src/utils/getDocumentAssetIds.test.ts +49 -0
- package/src/utils/getSchemeColor.test.ts +11 -0
- package/src/utils/getTagSelectOptions.test.ts +43 -0
- package/src/utils/getUniqueDocuments.test.ts +25 -0
- package/src/utils/imageDprUrl.test.ts +45 -0
- package/src/utils/isSupportedAssetType.test.ts +15 -0
- package/src/utils/sanitizeFormData.test.ts +58 -0
- package/src/utils/typeGuards.test.ts +17 -0
- package/src/utils/uploadSanityAsset.test.ts +28 -0
- package/src/utils/withMaxConcurrency.test.ts +42 -0
package/dist/index.js
CHANGED
|
@@ -542,7 +542,7 @@ const useKeyPress = (hotkey, onPress) => {
|
|
|
542
542
|
if (context === void 0)
|
|
543
543
|
throw new Error("useAssetSourceActions must be used within an AssetSourceDispatchProvider");
|
|
544
544
|
return context;
|
|
545
|
-
}, useVersionedClient = () => sanity.useClient({ apiVersion: "
|
|
545
|
+
}, useVersionedClient = () => sanity.useClient({ apiVersion: "2025-10-02" }), ORDER_DICTIONARY = {
|
|
546
546
|
_createdAt: {
|
|
547
547
|
asc: "Last created: Oldest first",
|
|
548
548
|
desc: "Last created: Newest first"
|
|
@@ -2365,14 +2365,16 @@ const Container$1 = styledComponents.styled(ui.Box)(({ $scheme, theme }) => styl
|
|
|
2365
2365
|
enabled: options?.creditLine?.enabled || !1,
|
|
2366
2366
|
excludeSources: creditLineExcludeSources
|
|
2367
2367
|
},
|
|
2368
|
-
directUploads: options?.directUploads ?? !0
|
|
2368
|
+
directUploads: options?.directUploads ?? !0,
|
|
2369
|
+
locales: options?.locales
|
|
2369
2370
|
};
|
|
2370
2371
|
}, [
|
|
2371
2372
|
options?.creditLine?.enabled,
|
|
2372
2373
|
options?.components,
|
|
2373
2374
|
options?.creditLine?.excludeSources,
|
|
2374
2375
|
options?.maximumUploadSize,
|
|
2375
|
-
options?.directUploads
|
|
2376
|
+
options?.directUploads,
|
|
2377
|
+
options?.locales
|
|
2376
2378
|
]);
|
|
2377
2379
|
return /* @__PURE__ */ jsxRuntime.jsx(ToolOptionsContext.Provider, { value, children });
|
|
2378
2380
|
}, useToolOptions = () => {
|
|
@@ -2651,21 +2653,35 @@ const DebugControls = () => {
|
|
|
2651
2653
|
] })
|
|
2652
2654
|
}
|
|
2653
2655
|
) : null;
|
|
2654
|
-
}
|
|
2656
|
+
};
|
|
2657
|
+
function localizedStringSchema(locales) {
|
|
2658
|
+
if (!locales || locales.length === 0)
|
|
2659
|
+
return z__namespace.string().trim().optional();
|
|
2660
|
+
const shape = {};
|
|
2661
|
+
for (const locale of locales)
|
|
2662
|
+
shape[locale.id] = z__namespace.string().trim().optional();
|
|
2663
|
+
return z__namespace.object(shape).passthrough();
|
|
2664
|
+
}
|
|
2665
|
+
const tagOptionSchema = z__namespace.object({
|
|
2655
2666
|
label: z__namespace.string().trim().min(1, { message: "Label cannot be empty" }),
|
|
2656
2667
|
value: z__namespace.string().trim().min(1, { message: "Value cannot be empty" })
|
|
2657
|
-
})
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2668
|
+
});
|
|
2669
|
+
function getAssetFormSchema(locales) {
|
|
2670
|
+
return z__namespace.object({
|
|
2671
|
+
altText: localizedStringSchema(locales),
|
|
2672
|
+
creditLine: localizedStringSchema(locales),
|
|
2673
|
+
description: localizedStringSchema(locales),
|
|
2674
|
+
opt: z__namespace.object({
|
|
2675
|
+
media: z__namespace.object({
|
|
2676
|
+
tags: z__namespace.array(tagOptionSchema).nullable()
|
|
2677
|
+
})
|
|
2678
|
+
}),
|
|
2679
|
+
originalFilename: z__namespace.string().trim().min(1, { message: "Filename cannot be empty" }),
|
|
2680
|
+
title: localizedStringSchema(locales)
|
|
2681
|
+
});
|
|
2682
|
+
}
|
|
2683
|
+
getAssetFormSchema();
|
|
2684
|
+
const tagFormSchema = z__namespace.object({
|
|
2669
2685
|
name: z__namespace.string().min(1, { message: "Name cannot be empty" })
|
|
2670
2686
|
});
|
|
2671
2687
|
function getUniqueDocuments(documents) {
|
|
@@ -3100,6 +3116,11 @@ const imageDprUrl = (asset, options) => {
|
|
|
3100
3116
|
)
|
|
3101
3117
|
] });
|
|
3102
3118
|
});
|
|
3119
|
+
function toStringField(value) {
|
|
3120
|
+
if (typeof value == "string") return value;
|
|
3121
|
+
if (typeof value == "object" && value !== null)
|
|
3122
|
+
return Object.values(value).find((v) => v) || void 0;
|
|
3123
|
+
}
|
|
3103
3124
|
function Details({
|
|
3104
3125
|
formUpdating,
|
|
3105
3126
|
handleCreateTag,
|
|
@@ -3109,8 +3130,10 @@ function Details({
|
|
|
3109
3130
|
allTagOptions,
|
|
3110
3131
|
assetTagOptions,
|
|
3111
3132
|
currentAsset,
|
|
3112
|
-
creditLine
|
|
3133
|
+
creditLine,
|
|
3134
|
+
locales
|
|
3113
3135
|
}) {
|
|
3136
|
+
const hasLocales = locales && locales.length > 0, [activeLocaleTab, setActiveLocaleTab] = react.useState(0);
|
|
3114
3137
|
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
|
|
3115
3138
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3116
3139
|
FormFieldInputTags,
|
|
@@ -3137,51 +3160,117 @@ function Details({
|
|
|
3137
3160
|
value: currentAsset?.originalFilename
|
|
3138
3161
|
}
|
|
3139
3162
|
),
|
|
3140
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3163
|
+
hasLocales ? /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { marginTop: 2, shadow: 1, padding: 3, radius: 1, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 2, children: [
|
|
3164
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.TabList, { space: 2, children: locales.map((locale, idx) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
3165
|
+
ui.Tab,
|
|
3166
|
+
{
|
|
3167
|
+
id: `locale-tab-${locale.id}`,
|
|
3168
|
+
"aria-controls": `locale-panel-${locale.id}`,
|
|
3169
|
+
selected: activeLocaleTab === idx,
|
|
3170
|
+
onClick: () => setActiveLocaleTab(idx),
|
|
3171
|
+
label: locale.title
|
|
3172
|
+
},
|
|
3173
|
+
locale.id
|
|
3174
|
+
)) }),
|
|
3175
|
+
locales.map((locale, idx) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
3176
|
+
ui.TabPanel,
|
|
3177
|
+
{
|
|
3178
|
+
id: `locale-panel-${locale.id}`,
|
|
3179
|
+
"aria-labelledby": `locale-tab-${locale.id}`,
|
|
3180
|
+
hidden: activeLocaleTab !== idx,
|
|
3181
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
|
|
3182
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3183
|
+
FormFieldInputText,
|
|
3184
|
+
{
|
|
3185
|
+
...register(`title.${locale.id}`),
|
|
3186
|
+
disabled: formUpdating,
|
|
3187
|
+
error: errors?.title?.[locale.id]?.message,
|
|
3188
|
+
label: "Title",
|
|
3189
|
+
name: `title.${locale.id}`
|
|
3190
|
+
}
|
|
3191
|
+
),
|
|
3192
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3193
|
+
FormFieldInputText,
|
|
3194
|
+
{
|
|
3195
|
+
...register(`altText.${locale.id}`),
|
|
3196
|
+
disabled: formUpdating,
|
|
3197
|
+
error: errors?.altText?.[locale.id]?.message,
|
|
3198
|
+
label: "Alt Text",
|
|
3199
|
+
name: `altText.${locale.id}`
|
|
3200
|
+
}
|
|
3201
|
+
),
|
|
3202
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3203
|
+
FormFieldInputTextarea,
|
|
3204
|
+
{
|
|
3205
|
+
...register(`description.${locale.id}`),
|
|
3206
|
+
disabled: formUpdating,
|
|
3207
|
+
error: errors?.description?.[locale.id]?.message,
|
|
3208
|
+
label: "Description",
|
|
3209
|
+
name: `description.${locale.id}`,
|
|
3210
|
+
rows: 5
|
|
3211
|
+
}
|
|
3212
|
+
),
|
|
3213
|
+
creditLine?.enabled && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3214
|
+
FormFieldInputText,
|
|
3215
|
+
{
|
|
3216
|
+
...register(`creditLine.${locale.id}`),
|
|
3217
|
+
error: errors?.creditLine?.[locale.id]?.message,
|
|
3218
|
+
label: "Credit",
|
|
3219
|
+
name: `creditLine.${locale.id}`,
|
|
3220
|
+
disabled: formUpdating || creditLine?.excludeSources?.includes(currentAsset?.source?.name)
|
|
3221
|
+
}
|
|
3222
|
+
)
|
|
3223
|
+
] })
|
|
3224
|
+
},
|
|
3225
|
+
locale.id
|
|
3226
|
+
))
|
|
3227
|
+
] }) }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3228
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3229
|
+
FormFieldInputText,
|
|
3230
|
+
{
|
|
3231
|
+
...register("title"),
|
|
3232
|
+
disabled: formUpdating,
|
|
3233
|
+
error: errors?.title?.message,
|
|
3234
|
+
label: "Title",
|
|
3235
|
+
name: "title",
|
|
3236
|
+
value: toStringField(currentAsset?.title)
|
|
3237
|
+
}
|
|
3238
|
+
),
|
|
3239
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3240
|
+
FormFieldInputText,
|
|
3241
|
+
{
|
|
3242
|
+
...register("altText"),
|
|
3243
|
+
disabled: formUpdating,
|
|
3244
|
+
error: errors?.altText?.message,
|
|
3245
|
+
label: "Alt Text",
|
|
3246
|
+
name: "altText",
|
|
3247
|
+
value: toStringField(currentAsset?.altText)
|
|
3248
|
+
}
|
|
3249
|
+
),
|
|
3250
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3251
|
+
FormFieldInputTextarea,
|
|
3252
|
+
{
|
|
3253
|
+
...register("description"),
|
|
3254
|
+
disabled: formUpdating,
|
|
3255
|
+
error: errors?.description?.message,
|
|
3256
|
+
label: "Description",
|
|
3257
|
+
name: "description",
|
|
3258
|
+
rows: 5,
|
|
3259
|
+
value: toStringField(currentAsset?.description)
|
|
3260
|
+
}
|
|
3261
|
+
),
|
|
3262
|
+
creditLine?.enabled && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3263
|
+
FormFieldInputText,
|
|
3264
|
+
{
|
|
3265
|
+
...register("creditLine"),
|
|
3266
|
+
error: errors?.creditLine?.message,
|
|
3267
|
+
label: "Credit",
|
|
3268
|
+
name: "creditLine",
|
|
3269
|
+
value: toStringField(currentAsset?.creditLine),
|
|
3270
|
+
disabled: formUpdating || creditLine?.excludeSources?.includes(currentAsset?.source?.name)
|
|
3271
|
+
}
|
|
3272
|
+
)
|
|
3273
|
+
] })
|
|
3185
3274
|
] });
|
|
3186
3275
|
}
|
|
3187
3276
|
function renderDefaultDetails(props) {
|
|
@@ -3191,16 +3280,37 @@ const DialogAssetEdit = (props) => {
|
|
|
3191
3280
|
const {
|
|
3192
3281
|
children,
|
|
3193
3282
|
dialog: { assetId, id, lastCreatedTag, lastRemovedTagIds }
|
|
3194
|
-
} = props, client = useVersionedClient(), scheme = sanity.useColorSchemeValue(), documentStore = sanity.useDocumentStore(), dispatch = reactRedux.useDispatch(), assetItem = useTypedSelector((state) => selectAssetById(state, String(assetId))), tags = useTypedSelector(selectTags), assetUpdatedPrev = react.useRef(void 0), [assetSnapshot, setAssetSnapshot] = react.useState(assetItem?.asset), [tabSection, setTabSection] = react.useState("details"), currentAsset = assetItem ? assetItem?.asset : assetSnapshot, allTagOptions = getTagSelectOptions(tags), assetTagOptions = useTypedSelector(selectTagSelectOptions(currentAsset)), { creditLine, components: { details: CustomDetails } = {} } = useToolOptions(), generateDefaultValues = react.useCallback(
|
|
3195
|
-
(asset) =>
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3283
|
+
} = props, client = useVersionedClient(), scheme = sanity.useColorSchemeValue(), documentStore = sanity.useDocumentStore(), dispatch = reactRedux.useDispatch(), assetItem = useTypedSelector((state) => selectAssetById(state, String(assetId))), tags = useTypedSelector(selectTags), assetUpdatedPrev = react.useRef(void 0), [assetSnapshot, setAssetSnapshot] = react.useState(assetItem?.asset), [tabSection, setTabSection] = react.useState("details"), currentAsset = assetItem ? assetItem?.asset : assetSnapshot, allTagOptions = getTagSelectOptions(tags), assetTagOptions = useTypedSelector(selectTagSelectOptions(currentAsset)), { creditLine, components: { details: CustomDetails } = {}, locales } = useToolOptions(), generateDefaultValues = react.useCallback(
|
|
3284
|
+
(asset) => {
|
|
3285
|
+
if (locales && locales.length > 0) {
|
|
3286
|
+
const makeLocaleObj = (field) => {
|
|
3287
|
+
const obj = {};
|
|
3288
|
+
for (let i = 0; i < locales.length; i++) {
|
|
3289
|
+
const locale = locales[i];
|
|
3290
|
+
typeof field == "object" && field && field[locale.id] ? obj[locale.id] = field[locale.id] : typeof field == "string" ? obj[locale.id] = i === 0 ? field : "" : obj[locale.id] = "";
|
|
3291
|
+
}
|
|
3292
|
+
return obj;
|
|
3293
|
+
};
|
|
3294
|
+
return {
|
|
3295
|
+
altText: makeLocaleObj(asset?.altText),
|
|
3296
|
+
creditLine: makeLocaleObj(asset?.creditLine),
|
|
3297
|
+
description: makeLocaleObj(asset?.description),
|
|
3298
|
+
originalFilename: asset?.originalFilename || "",
|
|
3299
|
+
opt: { media: { tags: assetTagOptions } },
|
|
3300
|
+
title: makeLocaleObj(asset?.title)
|
|
3301
|
+
};
|
|
3302
|
+
}
|
|
3303
|
+
const flattenField = (field) => typeof field == "string" ? field : typeof field == "object" && field !== null && Object.values(field).find((v) => v) || "";
|
|
3304
|
+
return {
|
|
3305
|
+
altText: flattenField(asset?.altText),
|
|
3306
|
+
creditLine: flattenField(asset?.creditLine),
|
|
3307
|
+
description: flattenField(asset?.description),
|
|
3308
|
+
originalFilename: asset?.originalFilename || "",
|
|
3309
|
+
opt: { media: { tags: assetTagOptions } },
|
|
3310
|
+
title: flattenField(asset?.title)
|
|
3311
|
+
};
|
|
3312
|
+
},
|
|
3313
|
+
[assetTagOptions, locales]
|
|
3204
3314
|
), {
|
|
3205
3315
|
control,
|
|
3206
3316
|
// Read the formState before render to subscribe the form state through Proxy
|
|
@@ -3213,7 +3323,7 @@ const DialogAssetEdit = (props) => {
|
|
|
3213
3323
|
} = reactHookForm.useForm({
|
|
3214
3324
|
defaultValues: generateDefaultValues(assetItem?.asset),
|
|
3215
3325
|
mode: "onChange",
|
|
3216
|
-
resolver: zod.zodResolver(
|
|
3326
|
+
resolver: zod.zodResolver(getAssetFormSchema(locales))
|
|
3217
3327
|
}), formUpdating = !assetItem || assetItem?.updating, handleClose = react.useCallback(() => {
|
|
3218
3328
|
dispatch(dialogActions.remove({ id }));
|
|
3219
3329
|
}, [dispatch, id]), handleDelete = react.useCallback(() => {
|
|
@@ -3236,7 +3346,39 @@ const DialogAssetEdit = (props) => {
|
|
|
3236
3346
|
);
|
|
3237
3347
|
},
|
|
3238
3348
|
[currentAsset?._id, dispatch]
|
|
3239
|
-
),
|
|
3349
|
+
), hasOrphanedLocales = react.useMemo(() => {
|
|
3350
|
+
if (!currentAsset) return !1;
|
|
3351
|
+
const isLocaleObj = (v) => typeof v == "object" && v !== null && !Array.isArray(v), fields = [
|
|
3352
|
+
currentAsset.title,
|
|
3353
|
+
currentAsset.altText,
|
|
3354
|
+
currentAsset.description,
|
|
3355
|
+
...currentAsset._type === "sanity.imageAsset" ? [currentAsset.creditLine] : []
|
|
3356
|
+
];
|
|
3357
|
+
if (!fields.some((f) => isLocaleObj(f))) return !1;
|
|
3358
|
+
if (!locales || locales.length === 0) return !0;
|
|
3359
|
+
const configuredIds = new Set(locales.map((l) => l.id));
|
|
3360
|
+
return fields.some((f) => isLocaleObj(f) ? Object.keys(f).some((k) => !configuredIds.has(k)) : !1);
|
|
3361
|
+
}, [currentAsset, locales]), handleCleanupLocales = react.useCallback(async () => {
|
|
3362
|
+
if (!currentAsset) return;
|
|
3363
|
+
const cleanField = (field) => {
|
|
3364
|
+
if (typeof field != "object" || field === null || Array.isArray(field)) return field;
|
|
3365
|
+
const obj = field;
|
|
3366
|
+
if (!locales || locales.length === 0)
|
|
3367
|
+
return Object.keys(obj).sort().map((k) => obj[k]).find((v) => v) || "";
|
|
3368
|
+
const configuredIds = new Set(locales.map((l) => l.id)), cleaned = {};
|
|
3369
|
+
for (const [key, val] of Object.entries(obj))
|
|
3370
|
+
configuredIds.has(key) && (cleaned[key] = val);
|
|
3371
|
+
return cleaned;
|
|
3372
|
+
};
|
|
3373
|
+
await client.patch(currentAsset._id).set({
|
|
3374
|
+
title: cleanField(currentAsset.title),
|
|
3375
|
+
altText: cleanField(currentAsset.altText),
|
|
3376
|
+
description: cleanField(currentAsset.description),
|
|
3377
|
+
...currentAsset._type === "sanity.imageAsset" && {
|
|
3378
|
+
creditLine: cleanField(currentAsset.creditLine)
|
|
3379
|
+
}
|
|
3380
|
+
}).commit();
|
|
3381
|
+
}, [client, currentAsset, locales]), onSubmit = react.useCallback(
|
|
3240
3382
|
(formData) => {
|
|
3241
3383
|
if (!assetItem?.asset)
|
|
3242
3384
|
return;
|
|
@@ -3284,27 +3426,42 @@ const DialogAssetEdit = (props) => {
|
|
|
3284
3426
|
}, [getValues, lastRemovedTagIds, setValue]), react.useEffect(() => {
|
|
3285
3427
|
assetUpdatedPrev.current !== assetItem?.asset._updatedAt && reset(generateDefaultValues(assetItem?.asset)), assetUpdatedPrev.current = assetItem?.asset._updatedAt;
|
|
3286
3428
|
}, [assetItem?.asset, generateDefaultValues, reset]);
|
|
3287
|
-
const Footer = () => /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { padding: 3, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.
|
|
3288
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3289
|
-
ui.
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3429
|
+
const Footer = () => /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { padding: 3, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
|
|
3430
|
+
hasOrphanedLocales && /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { padding: 3, radius: 2, shadow: 1, tone: "caution", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { align: "center", justify: "space-between", gap: 3, children: [
|
|
3431
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 1, children: "This asset has localized fields that are no longer configured. Clean them up to avoid validation errors." }),
|
|
3432
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3433
|
+
ui.Button,
|
|
3434
|
+
{
|
|
3435
|
+
fontSize: 1,
|
|
3436
|
+
mode: "ghost",
|
|
3437
|
+
onClick: handleCleanupLocales,
|
|
3438
|
+
text: "Cleanup localized fields",
|
|
3439
|
+
tone: "caution"
|
|
3440
|
+
}
|
|
3441
|
+
)
|
|
3442
|
+
] }) }),
|
|
3443
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "space-between", children: [
|
|
3444
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3445
|
+
ui.Button,
|
|
3446
|
+
{
|
|
3447
|
+
disabled: formUpdating,
|
|
3448
|
+
fontSize: 1,
|
|
3449
|
+
mode: "bleed",
|
|
3450
|
+
onClick: handleDelete,
|
|
3451
|
+
text: "Delete",
|
|
3452
|
+
tone: "critical"
|
|
3453
|
+
}
|
|
3454
|
+
),
|
|
3455
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3456
|
+
FormSubmitButton,
|
|
3457
|
+
{
|
|
3458
|
+
disabled: formUpdating || !isDirty || !isValid || hasOrphanedLocales,
|
|
3459
|
+
isValid,
|
|
3460
|
+
lastUpdated: currentAsset?._updatedAt,
|
|
3461
|
+
onClick: handleSubmit(onSubmit)
|
|
3462
|
+
}
|
|
3463
|
+
)
|
|
3464
|
+
] })
|
|
3308
3465
|
] }) });
|
|
3309
3466
|
if (!currentAsset)
|
|
3310
3467
|
return null;
|
|
@@ -3318,7 +3475,8 @@ const DialogAssetEdit = (props) => {
|
|
|
3318
3475
|
allTagOptions,
|
|
3319
3476
|
handleCreateTag,
|
|
3320
3477
|
currentAsset,
|
|
3321
|
-
creditLine
|
|
3478
|
+
creditLine,
|
|
3479
|
+
locales
|
|
3322
3480
|
};
|
|
3323
3481
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3324
3482
|
Dialog,
|
|
@@ -5104,6 +5262,9 @@ const TableRowUpload = (props) => {
|
|
|
5104
5262
|
reducers: {}
|
|
5105
5263
|
});
|
|
5106
5264
|
var selectedReducer = selectedSlice.reducer;
|
|
5265
|
+
function messageFromGenericErrorPayload(payload) {
|
|
5266
|
+
return !payload || typeof payload != "object" ? "Unknown error" : "error" in payload && payload.error && typeof payload.error == "object" && payload.error !== null && "message" in payload.error ? String(payload.error.message) : "message" in payload && typeof payload.message == "string" ? String(payload.message) : "Unknown error";
|
|
5267
|
+
}
|
|
5107
5268
|
const initialState = {
|
|
5108
5269
|
items: []
|
|
5109
5270
|
}, notificationsSlice = toolkit.createSlice({
|
|
@@ -5190,11 +5351,11 @@ const initialState = {
|
|
|
5190
5351
|
uploadsActions.uploadError.type
|
|
5191
5352
|
),
|
|
5192
5353
|
operators$1.mergeMap((action) => {
|
|
5193
|
-
const
|
|
5354
|
+
const title = `An error occurred: ${messageFromGenericErrorPayload(action.payload)}`;
|
|
5194
5355
|
return rxjs.of(
|
|
5195
5356
|
notificationsSlice.actions.add({
|
|
5196
5357
|
status: "error",
|
|
5197
|
-
title
|
|
5358
|
+
title
|
|
5198
5359
|
})
|
|
5199
5360
|
);
|
|
5200
5361
|
})
|