sanity-plugin-media 4.3.1 → 4.3.2
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 +4 -4
- package/README.md +12 -12
- package/dist/index.d.mts +263 -195
- package/dist/index.d.ts +263 -195
- package/dist/index.js +83 -203
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +84 -203
- package/dist/index.mjs.map +1 -1
- package/package.json +41 -63
- package/src/__tests__/fixtures/createEpicTestStore.ts +5 -4
- package/src/__tests__/fixtures/mockSanityClient.ts +8 -8
- package/src/__tests__/fixtures/renderWithProviders.tsx +8 -7
- package/src/__tests__/fixtures/rootState.ts +4 -4
- package/src/components/AssetGridVirtualized/index.tsx +8 -7
- package/src/components/AssetMetadata/index.tsx +6 -5
- package/src/components/AssetTableVirtualized/index.tsx +7 -6
- package/src/components/AutoTagInputWrapper/index.tsx +9 -4
- package/src/components/Browser/Browser.test.tsx +9 -8
- package/src/components/Browser/index.tsx +2 -1
- package/src/components/Browser/useBrowserInit.ts +9 -9
- package/src/components/ButtonAssetCopy/index.tsx +1 -0
- package/src/components/ButtonViewGroup/index.tsx +4 -3
- package/src/components/CardAsset/CardAsset.test.tsx +53 -52
- package/src/components/CardAsset/index.tsx +52 -49
- package/src/components/CardUpload/index.tsx +7 -6
- package/src/components/Controls/index.tsx +7 -6
- package/src/components/DebugControls/index.tsx +5 -4
- package/src/components/DialogAssetEdit/Details.tsx +3 -2
- package/src/components/DialogAssetEdit/DialogAssetEdit.test.tsx +28 -27
- package/src/components/DialogAssetEdit/index.tsx +37 -37
- package/src/components/DialogConfirm/index.tsx +2 -1
- package/src/components/DialogSearchFacets/index.tsx +3 -2
- package/src/components/DialogTagCreate/DialogTagCreate.test.tsx +16 -15
- package/src/components/DialogTagCreate/index.tsx +11 -10
- package/src/components/DialogTagEdit/DialogTagEdit.test.tsx +28 -27
- package/src/components/DialogTagEdit/index.tsx +17 -16
- package/src/components/DialogTags/index.tsx +4 -3
- package/src/components/Dialogs/index.tsx +2 -3
- package/src/components/DocumentList/index.tsx +2 -3
- package/src/components/FileAssetPreview/index.tsx +2 -2
- package/src/components/FormBuilderTool/FormBuilderTool.test.tsx +12 -11
- package/src/components/FormBuilderTool/index.tsx +2 -1
- package/src/components/FormFieldInputLabel/index.tsx +1 -2
- package/src/components/FormFieldInputTags/index.tsx +4 -3
- package/src/components/FormSubmitButton/index.tsx +1 -1
- package/src/components/Header/index.tsx +3 -3
- package/src/components/Image/index.tsx +10 -4
- package/src/components/Items/index.tsx +5 -4
- package/src/components/Notifications/index.tsx +3 -2
- package/src/components/OrderSelect/index.tsx +4 -3
- package/src/components/PickedBar/index.tsx +2 -1
- package/src/components/Progress/index.tsx +3 -3
- package/src/components/ReduxProvider/index.tsx +15 -12
- package/src/components/SearchFacet/index.tsx +3 -2
- package/src/components/SearchFacetNumber/index.tsx +8 -8
- package/src/components/SearchFacetSelect/index.tsx +7 -8
- package/src/components/SearchFacetString/index.tsx +1 -1
- package/src/components/SearchFacetTags/index.tsx +13 -12
- package/src/components/SearchFacets/index.tsx +2 -3
- package/src/components/SearchFacetsControl/index.tsx +13 -12
- package/src/components/TableHeader/index.tsx +18 -17
- package/src/components/TableHeaderItem/index.tsx +4 -4
- package/src/components/TableRowAsset/index.tsx +37 -36
- package/src/components/TableRowUpload/index.tsx +7 -6
- package/src/components/Tag/index.tsx +8 -7
- package/src/components/TagView/index.tsx +2 -2
- package/src/components/TagViewHeader/index.tsx +5 -4
- package/src/components/TagsPanel/index.tsx +3 -3
- package/src/components/TagsVirtualized/index.tsx +25 -24
- package/src/components/TextInputSearch/index.tsx +3 -2
- package/src/components/UploadDropzone/UploadDropzone.test.tsx +8 -7
- package/src/components/UploadDropzone/index.tsx +14 -13
- package/src/config/orders.ts +6 -6
- package/src/config/searchFacets.ts +56 -55
- package/src/constants.ts +15 -14
- package/src/contexts/AssetSourceDispatchContext.tsx +1 -1
- package/src/contexts/ToolOptionsContext.tsx +6 -5
- package/src/formSchema/index.test.ts +6 -5
- package/src/formSchema/index.ts +5 -5
- package/src/hooks/useBreakpointIndex.ts +6 -6
- package/src/hooks/useKeyPress.ts +2 -2
- package/src/hooks/usePortalPopoverProps.ts +1 -1
- package/src/modules/assets/actions.ts +8 -7
- package/src/modules/assets/deleteAndUpdateEpics.test.ts +18 -17
- package/src/modules/assets/fetchEpic.test.ts +12 -11
- package/src/modules/assets/index.ts +134 -133
- package/src/modules/assets/reducer.test.ts +9 -8
- package/src/modules/assets/tagsAndListenerEpics.test.ts +36 -35
- package/src/modules/debug/index.ts +3 -3
- package/src/modules/dialog/actions.ts +2 -2
- package/src/modules/dialog/epics.test.ts +29 -28
- package/src/modules/dialog/index.ts +36 -35
- package/src/modules/dialog/reducer.test.ts +31 -30
- package/src/modules/index.ts +9 -9
- package/src/modules/notifications/epics.test.ts +71 -70
- package/src/modules/notifications/index.ts +50 -49
- package/src/modules/notifications/reducer.test.ts +8 -7
- package/src/modules/search/index.test.ts +2 -1
- package/src/modules/search/index.ts +22 -22
- package/src/modules/selected/index.ts +2 -2
- package/src/modules/selectors.test.ts +4 -3
- package/src/modules/selectors.ts +5 -5
- package/src/modules/tags/epics.test.ts +16 -15
- package/src/modules/tags/index.test.ts +2 -1
- package/src/modules/tags/index.ts +82 -81
- package/src/modules/uploads/actions.ts +3 -3
- package/src/modules/uploads/epics.test.ts +13 -12
- package/src/modules/uploads/index.test.ts +8 -7
- package/src/modules/uploads/index.ts +48 -47
- package/src/operators/checkTagName.test.ts +7 -6
- package/src/operators/checkTagName.ts +6 -5
- package/src/operators/debugThrottle.ts +4 -4
- package/src/plugin.tsx +18 -18
- package/src/schemas/tag.ts +7 -7
- package/src/styled/react-select/creatable.tsx +40 -39
- package/src/styled/react-select/single.tsx +39 -38
- package/src/types/index.ts +4 -3
- package/src/utils/applyMediaTags.ts +11 -10
- package/src/utils/blocksToText.test.ts +5 -4
- package/src/utils/blocksToText.ts +2 -2
- package/src/utils/constructFilter.test.ts +15 -14
- package/src/utils/constructFilter.ts +7 -7
- package/src/utils/generatePreviewBlobUrl.test.ts +6 -5
- package/src/utils/generatePreviewBlobUrl.ts +2 -2
- package/src/utils/getAssetResolution.test.ts +3 -2
- package/src/utils/getDocumentAssetIds.test.ts +7 -6
- package/src/utils/getDocumentAssetIds.ts +2 -2
- package/src/utils/getSchemeColor.test.ts +1 -0
- package/src/utils/getSchemeColor.ts +9 -9
- package/src/utils/getTagSelectOptions.test.ts +6 -5
- package/src/utils/getTagSelectOptions.ts +1 -1
- package/src/utils/getUniqueDocuments.test.ts +4 -3
- package/src/utils/getUniqueDocuments.ts +2 -2
- package/src/utils/imageDprUrl.test.ts +4 -3
- package/src/utils/imageDprUrl.ts +1 -1
- package/src/utils/isSupportedAssetType.test.ts +1 -0
- package/src/utils/mediaField.ts +4 -3
- package/src/utils/sanitizeFormData.test.ts +14 -13
- package/src/utils/typeGuards.test.ts +2 -1
- package/src/utils/uploadSanityAsset.test.ts +5 -4
- package/src/utils/uploadSanityAsset.ts +17 -16
- package/src/utils/withMaxConcurrency.test.ts +5 -4
- package/src/utils/withMaxConcurrency.ts +4 -4
- package/src/utils/zodFormResolver.ts +17 -0
- package/v2-incompatible.js +2 -2
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import type {RefObject} from 'react'
|
|
2
|
-
import userEvent from '@testing-library/user-event'
|
|
3
1
|
import {screen} from '@testing-library/react'
|
|
2
|
+
import userEvent from '@testing-library/user-event'
|
|
3
|
+
import type {RefObject} from 'react'
|
|
4
4
|
import {beforeEach, describe, expect, it, vi} from 'vitest'
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
import {renderWithProviders} from '../../__tests__/fixtures/renderWithProviders'
|
|
7
7
|
import {initialState as assetsInitialState} from '../../modules/assets'
|
|
8
8
|
import type {AssetItem, AssetType, FileAsset, ImageAsset} from '../../types'
|
|
9
|
+
import CardAsset from './index'
|
|
9
10
|
|
|
10
11
|
const SHIFT_FLAG = '__CARD_ASSET_TEST_SHIFT__'
|
|
11
12
|
|
|
@@ -23,25 +24,25 @@ vi.mock('../../hooks/useKeyPress', () => ({
|
|
|
23
24
|
({
|
|
24
25
|
get current() {
|
|
25
26
|
return Boolean((globalThis as unknown as Record<string, unknown>)[SHIFT_FLAG])
|
|
26
|
-
}
|
|
27
|
-
} as RefObject<boolean
|
|
27
|
+
},
|
|
28
|
+
}) as RefObject<boolean>,
|
|
28
29
|
}))
|
|
29
30
|
|
|
30
31
|
vi.mock('../Image', () => ({
|
|
31
|
-
default: () => <div data-testid="card-image"
|
|
32
|
+
default: () => <div data-testid="card-image" />,
|
|
32
33
|
}))
|
|
33
34
|
|
|
34
35
|
vi.mock('../FileIcon', () => ({
|
|
35
36
|
default: ({extension}: {extension?: string}) => (
|
|
36
37
|
<div data-testid="card-file-icon" data-extension={extension ?? ''} />
|
|
37
|
-
)
|
|
38
|
+
),
|
|
38
39
|
}))
|
|
39
40
|
|
|
40
|
-
vi.mock('sanity', async importOriginal => {
|
|
41
|
+
vi.mock('sanity', async (importOriginal) => {
|
|
41
42
|
const actual = await importOriginal<typeof import('sanity')>()
|
|
42
43
|
return {
|
|
43
44
|
...actual,
|
|
44
|
-
useColorSchemeValue: () => 'light'
|
|
45
|
+
useColorSchemeValue: () => 'light',
|
|
45
46
|
}
|
|
46
47
|
})
|
|
47
48
|
|
|
@@ -55,7 +56,7 @@ const imageAsset = {
|
|
|
55
56
|
size: 1,
|
|
56
57
|
mimeType: 'image/png',
|
|
57
58
|
url: 'https://example.com/photo.png',
|
|
58
|
-
metadata: {dimensions: {width: 100, height: 100}, isOpaque: true}
|
|
59
|
+
metadata: {dimensions: {width: 100, height: 100}, isOpaque: true},
|
|
59
60
|
} as ImageAsset
|
|
60
61
|
|
|
61
62
|
const fileAsset = {
|
|
@@ -68,7 +69,7 @@ const fileAsset = {
|
|
|
68
69
|
extension: 'pdf',
|
|
69
70
|
size: 1,
|
|
70
71
|
mimeType: 'application/pdf',
|
|
71
|
-
url: 'https://example.com/doc.pdf'
|
|
72
|
+
url: 'https://example.com/doc.pdf',
|
|
72
73
|
} as FileAsset
|
|
73
74
|
|
|
74
75
|
function assetItem(asset: ImageAsset | FileAsset, partial?: Partial<AssetItem>): AssetItem {
|
|
@@ -77,7 +78,7 @@ function assetItem(asset: ImageAsset | FileAsset, partial?: Partial<AssetItem>):
|
|
|
77
78
|
asset,
|
|
78
79
|
picked: false,
|
|
79
80
|
updating: false,
|
|
80
|
-
...partial
|
|
81
|
+
...partial,
|
|
81
82
|
}
|
|
82
83
|
}
|
|
83
84
|
|
|
@@ -87,7 +88,7 @@ function assetsState(byIds: Record<string, AssetItem>, extra?: Partial<typeof as
|
|
|
87
88
|
assetTypes: ['file', 'image'] as AssetType[],
|
|
88
89
|
allIds: Object.keys(byIds),
|
|
89
90
|
byIds,
|
|
90
|
-
...extra
|
|
91
|
+
...extra,
|
|
91
92
|
}
|
|
92
93
|
}
|
|
93
94
|
|
|
@@ -121,8 +122,8 @@ describe('CardAsset', () => {
|
|
|
121
122
|
it('renders nothing when the asset id is not in the store', () => {
|
|
122
123
|
renderWithProviders(<CardAsset id="missing" selected={false} />, {
|
|
123
124
|
preloaded: {
|
|
124
|
-
assets: assetsState({})
|
|
125
|
-
}
|
|
125
|
+
assets: assetsState({}),
|
|
126
|
+
},
|
|
126
127
|
})
|
|
127
128
|
expect(screen.queryAllByTestId('card-image')).toHaveLength(0)
|
|
128
129
|
expect(screen.queryAllByTestId('card-file-icon')).toHaveLength(0)
|
|
@@ -131,8 +132,8 @@ describe('CardAsset', () => {
|
|
|
131
132
|
it('renders image preview and original filename for an image asset', () => {
|
|
132
133
|
renderWithProviders(<CardAsset id="img-1" selected={false} />, {
|
|
133
134
|
preloaded: {
|
|
134
|
-
assets: assetsState({'img-1': assetItem(imageAsset)})
|
|
135
|
-
}
|
|
135
|
+
assets: assetsState({'img-1': assetItem(imageAsset)}),
|
|
136
|
+
},
|
|
136
137
|
})
|
|
137
138
|
expect(screen.getAllByTestId('card-image').length).toBeGreaterThan(0)
|
|
138
139
|
expect(screen.getAllByText('photo.png').length).toBeGreaterThan(0)
|
|
@@ -141,8 +142,8 @@ describe('CardAsset', () => {
|
|
|
141
142
|
it('renders file icon with extension for a file asset', () => {
|
|
142
143
|
renderWithProviders(<CardAsset id="file-1" selected={false} />, {
|
|
143
144
|
preloaded: {
|
|
144
|
-
assets: assetsState({'file-1': assetItem(fileAsset)})
|
|
145
|
-
}
|
|
145
|
+
assets: assetsState({'file-1': assetItem(fileAsset)}),
|
|
146
|
+
},
|
|
146
147
|
})
|
|
147
148
|
const icon = screen.getAllByTestId('card-file-icon').at(-1)!
|
|
148
149
|
expect(icon).toHaveAttribute('data-extension', 'pdf')
|
|
@@ -153,14 +154,14 @@ describe('CardAsset', () => {
|
|
|
153
154
|
const user = userEvent.setup()
|
|
154
155
|
const {store} = renderWithProviders(<CardAsset id="img-1" selected={false} />, {
|
|
155
156
|
preloaded: {
|
|
156
|
-
assets: assetsState({'img-1': assetItem(imageAsset)})
|
|
157
|
-
}
|
|
157
|
+
assets: assetsState({'img-1': assetItem(imageAsset)}),
|
|
158
|
+
},
|
|
158
159
|
})
|
|
159
160
|
|
|
160
161
|
await user.click(clickPreview())
|
|
161
162
|
|
|
162
163
|
expect(
|
|
163
|
-
store.getState().dialog.items.some(d => d.type === 'assetEdit' && d.assetId === 'img-1')
|
|
164
|
+
store.getState().dialog.items.some((d) => d.type === 'assetEdit' && d.assetId === 'img-1'),
|
|
164
165
|
).toBe(true)
|
|
165
166
|
})
|
|
166
167
|
|
|
@@ -170,8 +171,8 @@ describe('CardAsset', () => {
|
|
|
170
171
|
renderWithProviders(<CardAsset id="img-1" selected={false} />, {
|
|
171
172
|
onSelect,
|
|
172
173
|
preloaded: {
|
|
173
|
-
assets: assetsState({'img-1': assetItem(imageAsset)})
|
|
174
|
-
}
|
|
174
|
+
assets: assetsState({'img-1': assetItem(imageAsset)}),
|
|
175
|
+
},
|
|
175
176
|
})
|
|
176
177
|
|
|
177
178
|
await user.click(clickPreview())
|
|
@@ -179,8 +180,8 @@ describe('CardAsset', () => {
|
|
|
179
180
|
expect(onSelect).toHaveBeenCalledWith([
|
|
180
181
|
{
|
|
181
182
|
kind: 'assetDocumentId',
|
|
182
|
-
value: 'img-1'
|
|
183
|
-
}
|
|
183
|
+
value: 'img-1',
|
|
184
|
+
},
|
|
184
185
|
])
|
|
185
186
|
})
|
|
186
187
|
|
|
@@ -188,8 +189,8 @@ describe('CardAsset', () => {
|
|
|
188
189
|
const user = userEvent.setup()
|
|
189
190
|
const {store} = renderWithProviders(<CardAsset id="img-1" selected={false} />, {
|
|
190
191
|
preloaded: {
|
|
191
|
-
assets: assetsState({'img-1': assetItem(imageAsset, {picked: false})})
|
|
192
|
-
}
|
|
192
|
+
assets: assetsState({'img-1': assetItem(imageAsset, {picked: false})}),
|
|
193
|
+
},
|
|
193
194
|
})
|
|
194
195
|
|
|
195
196
|
await user.click(clickFooterFilename('photo.png'))
|
|
@@ -203,15 +204,15 @@ describe('CardAsset', () => {
|
|
|
203
204
|
const {store} = renderWithProviders(<CardAsset id="img-1" selected={false} />, {
|
|
204
205
|
onSelect,
|
|
205
206
|
preloaded: {
|
|
206
|
-
assets: assetsState({'img-1': assetItem(imageAsset)})
|
|
207
|
-
}
|
|
207
|
+
assets: assetsState({'img-1': assetItem(imageAsset)}),
|
|
208
|
+
},
|
|
208
209
|
})
|
|
209
210
|
|
|
210
211
|
await user.click(clickFooterFilename('photo.png'))
|
|
211
212
|
|
|
212
213
|
expect(onSelect).not.toHaveBeenCalled()
|
|
213
214
|
expect(
|
|
214
|
-
store.getState().dialog.items.some(d => d.type === 'assetEdit' && d.assetId === 'img-1')
|
|
215
|
+
store.getState().dialog.items.some((d) => d.type === 'assetEdit' && d.assetId === 'img-1'),
|
|
215
216
|
).toBe(true)
|
|
216
217
|
})
|
|
217
218
|
|
|
@@ -219,8 +220,8 @@ describe('CardAsset', () => {
|
|
|
219
220
|
const user = userEvent.setup()
|
|
220
221
|
const {store} = renderWithProviders(<CardAsset id="img-1" selected={false} />, {
|
|
221
222
|
preloaded: {
|
|
222
|
-
assets: assetsState({'img-1': assetItem(imageAsset, {picked: true})})
|
|
223
|
-
}
|
|
223
|
+
assets: assetsState({'img-1': assetItem(imageAsset, {picked: true})}),
|
|
224
|
+
},
|
|
224
225
|
})
|
|
225
226
|
|
|
226
227
|
setShiftPressed(true)
|
|
@@ -238,11 +239,11 @@ describe('CardAsset', () => {
|
|
|
238
239
|
assets: assetsState(
|
|
239
240
|
{
|
|
240
241
|
'prev-1': assetItem(prevAsset),
|
|
241
|
-
'img-1': assetItem(imageAsset, {picked: false})
|
|
242
|
+
'img-1': assetItem(imageAsset, {picked: false}),
|
|
242
243
|
},
|
|
243
|
-
{lastPicked: 'prev-1'}
|
|
244
|
-
)
|
|
245
|
-
}
|
|
244
|
+
{lastPicked: 'prev-1'},
|
|
245
|
+
),
|
|
246
|
+
},
|
|
246
247
|
})
|
|
247
248
|
|
|
248
249
|
setShiftPressed(true)
|
|
@@ -258,18 +259,18 @@ describe('CardAsset', () => {
|
|
|
258
259
|
const anchorAsset = {
|
|
259
260
|
...imageAsset,
|
|
260
261
|
_id: 'anchor-9',
|
|
261
|
-
originalFilename: 'anchor.png'
|
|
262
|
+
originalFilename: 'anchor.png',
|
|
262
263
|
} as ImageAsset
|
|
263
264
|
const {store} = renderWithProviders(<CardAsset id="img-1" selected={false} />, {
|
|
264
265
|
preloaded: {
|
|
265
266
|
assets: assetsState(
|
|
266
267
|
{
|
|
267
268
|
'anchor-9': assetItem(anchorAsset),
|
|
268
|
-
'img-1': assetItem(imageAsset, {picked: false})
|
|
269
|
+
'img-1': assetItem(imageAsset, {picked: false}),
|
|
269
270
|
},
|
|
270
|
-
{lastPicked: 'anchor-9'}
|
|
271
|
-
)
|
|
272
|
-
}
|
|
271
|
+
{lastPicked: 'anchor-9'},
|
|
272
|
+
),
|
|
273
|
+
},
|
|
273
274
|
})
|
|
274
275
|
|
|
275
276
|
setShiftPressed(true)
|
|
@@ -283,19 +284,19 @@ describe('CardAsset', () => {
|
|
|
283
284
|
it('shows the selection checkmark when selected and not updating', () => {
|
|
284
285
|
const {container} = renderWithProviders(<CardAsset id="img-1" selected />, {
|
|
285
286
|
preloaded: {
|
|
286
|
-
assets: assetsState({'img-1': assetItem(imageAsset, {updating: false})})
|
|
287
|
-
}
|
|
287
|
+
assets: assetsState({'img-1': assetItem(imageAsset, {updating: false})}),
|
|
288
|
+
},
|
|
288
289
|
})
|
|
289
290
|
expect(
|
|
290
|
-
container.querySelectorAll('[data-sanity-icon="checkmark-circle"]').length
|
|
291
|
+
container.querySelectorAll('[data-sanity-icon="checkmark-circle"]').length,
|
|
291
292
|
).toBeGreaterThan(0)
|
|
292
293
|
})
|
|
293
294
|
|
|
294
295
|
it('does not show the checkmark overlay while updating even if selected', () => {
|
|
295
296
|
const {container} = renderWithProviders(<CardAsset id="img-1" selected />, {
|
|
296
297
|
preloaded: {
|
|
297
|
-
assets: assetsState({'img-1': assetItem(imageAsset, {updating: true})})
|
|
298
|
-
}
|
|
298
|
+
assets: assetsState({'img-1': assetItem(imageAsset, {updating: true})}),
|
|
299
|
+
},
|
|
299
300
|
})
|
|
300
301
|
expect(container.querySelectorAll('[data-sanity-icon="checkmark-circle"]')).toHaveLength(0)
|
|
301
302
|
})
|
|
@@ -303,8 +304,8 @@ describe('CardAsset', () => {
|
|
|
303
304
|
it('shows a spinner while updating', () => {
|
|
304
305
|
renderWithProviders(<CardAsset id="img-1" selected={false} />, {
|
|
305
306
|
preloaded: {
|
|
306
|
-
assets: assetsState({'img-1': assetItem(imageAsset, {updating: true})})
|
|
307
|
-
}
|
|
307
|
+
assets: assetsState({'img-1': assetItem(imageAsset, {updating: true})}),
|
|
308
|
+
},
|
|
308
309
|
})
|
|
309
310
|
expect(document.body.querySelectorAll('[data-ui="Spinner"]').length).toBeGreaterThan(0)
|
|
310
311
|
})
|
|
@@ -312,11 +313,11 @@ describe('CardAsset', () => {
|
|
|
312
313
|
it('shows a warning icon when the asset item has an error', () => {
|
|
313
314
|
const {container} = renderWithProviders(<CardAsset id="img-1" selected={false} />, {
|
|
314
315
|
preloaded: {
|
|
315
|
-
assets: assetsState({'img-1': assetItem(imageAsset, {error: 'Upload failed'})})
|
|
316
|
-
}
|
|
316
|
+
assets: assetsState({'img-1': assetItem(imageAsset, {error: 'Upload failed'})}),
|
|
317
|
+
},
|
|
317
318
|
})
|
|
318
319
|
expect(
|
|
319
|
-
container.querySelectorAll('[data-sanity-icon="warning-filled"]').length
|
|
320
|
+
container.querySelectorAll('[data-sanity-icon="warning-filled"]').length,
|
|
320
321
|
).toBeGreaterThan(0)
|
|
321
322
|
})
|
|
322
323
|
})
|
|
@@ -8,23 +8,24 @@ import {
|
|
|
8
8
|
Text,
|
|
9
9
|
type Theme,
|
|
10
10
|
type ThemeColorSchemeKey,
|
|
11
|
-
Tooltip
|
|
11
|
+
Tooltip,
|
|
12
12
|
} from '@sanity/ui'
|
|
13
13
|
import {memo, type MouseEvent, type RefObject} from 'react'
|
|
14
14
|
import {useDispatch} from 'react-redux'
|
|
15
15
|
import {useColorSchemeValue} from 'sanity'
|
|
16
16
|
import {styled, css} from 'styled-components'
|
|
17
|
+
|
|
17
18
|
import {PANEL_HEIGHT} from '../../constants'
|
|
18
19
|
import {useAssetSourceActions} from '../../contexts/AssetSourceDispatchContext'
|
|
19
20
|
import useKeyPress from '../../hooks/useKeyPress'
|
|
20
21
|
import useTypedSelector from '../../hooks/useTypedSelector'
|
|
21
22
|
import {assetsActions, selectAssetById} from '../../modules/assets'
|
|
22
23
|
import {dialogActions} from '../../modules/dialog'
|
|
24
|
+
import {getSchemeColor} from '../../utils/getSchemeColor'
|
|
23
25
|
import imageDprUrl from '../../utils/imageDprUrl'
|
|
24
26
|
import {isFileAsset, isImageAsset} from '../../utils/typeGuards'
|
|
25
27
|
import FileIcon from '../FileIcon'
|
|
26
28
|
import Image from '../Image'
|
|
27
|
-
import {getSchemeColor} from '../../utils/getSchemeColor'
|
|
28
29
|
|
|
29
30
|
type Props = {
|
|
30
31
|
id: string
|
|
@@ -39,51 +40,53 @@ const CardWrapper = styled(Flex)`
|
|
|
39
40
|
width: 100%;
|
|
40
41
|
`
|
|
41
42
|
|
|
42
|
-
const CardContainer = styled(Flex)<{$picked?: boolean; theme: Theme; $updating?: boolean}>(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
43
|
+
const CardContainer = styled(Flex)<{$picked?: boolean; theme: Theme; $updating?: boolean}>(({
|
|
44
|
+
$picked,
|
|
45
|
+
theme,
|
|
46
|
+
$updating,
|
|
47
|
+
}) => {
|
|
48
|
+
return css`
|
|
49
|
+
border: 1px solid transparent;
|
|
50
|
+
height: 100%;
|
|
51
|
+
pointer-events: ${$updating ? 'none' : 'auto'};
|
|
52
|
+
position: relative;
|
|
53
|
+
transition: all 300ms;
|
|
54
|
+
user-select: none;
|
|
55
|
+
width: 100%;
|
|
52
56
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
57
|
+
border: ${$picked
|
|
58
|
+
? `1px solid ${theme.sanity.color.spot.orange} !important`
|
|
59
|
+
: '1px solid inherit'};
|
|
56
60
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
@media (hover: hover) and (pointer: fine) {
|
|
60
|
-
&:hover {
|
|
61
|
-
border: 1px solid var(--card-border-color);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
`}
|
|
65
|
-
`
|
|
66
|
-
}
|
|
67
|
-
)
|
|
68
|
-
|
|
69
|
-
const ContextActionContainer = styled<typeof Flex, {$scheme: ThemeColorSchemeKey}>(Flex)(
|
|
70
|
-
({$scheme}) => {
|
|
71
|
-
return css`
|
|
72
|
-
cursor: pointer;
|
|
73
|
-
height: ${PANEL_HEIGHT}px;
|
|
74
|
-
transition: all 300ms;
|
|
61
|
+
${!$updating &&
|
|
62
|
+
css`
|
|
75
63
|
@media (hover: hover) and (pointer: fine) {
|
|
76
64
|
&:hover {
|
|
77
|
-
|
|
65
|
+
border: 1px solid var(--card-border-color);
|
|
78
66
|
}
|
|
79
67
|
}
|
|
80
|
-
`
|
|
81
|
-
|
|
82
|
-
)
|
|
68
|
+
`}
|
|
69
|
+
`
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
const ContextActionContainer = styled<typeof Flex, {$scheme: ThemeColorSchemeKey}>(Flex)(({
|
|
73
|
+
$scheme,
|
|
74
|
+
}) => {
|
|
75
|
+
return css`
|
|
76
|
+
cursor: pointer;
|
|
77
|
+
height: ${PANEL_HEIGHT}px;
|
|
78
|
+
transition: all 300ms;
|
|
79
|
+
@media (hover: hover) and (pointer: fine) {
|
|
80
|
+
&:hover {
|
|
81
|
+
background: ${getSchemeColor($scheme, 'bg')};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
`
|
|
85
|
+
})
|
|
83
86
|
|
|
84
87
|
const StyledWarningOutlineIcon = styled(WarningFilledIcon)(({theme}) => {
|
|
85
88
|
return {
|
|
86
|
-
color: theme.sanity.color.spot.red
|
|
89
|
+
color: theme.sanity.color.spot.red,
|
|
87
90
|
}
|
|
88
91
|
})
|
|
89
92
|
|
|
@@ -97,8 +100,8 @@ const CardAsset = (props: Props) => {
|
|
|
97
100
|
|
|
98
101
|
// Redux
|
|
99
102
|
const dispatch = useDispatch()
|
|
100
|
-
const lastPicked = useTypedSelector(state => state.assets.lastPicked)
|
|
101
|
-
const item = useTypedSelector(state => selectAssetById(state, id))
|
|
103
|
+
const lastPicked = useTypedSelector((state) => state.assets.lastPicked)
|
|
104
|
+
const item = useTypedSelector((state) => selectAssetById(state, id))
|
|
102
105
|
|
|
103
106
|
const asset = item?.asset
|
|
104
107
|
const error = item?.error
|
|
@@ -121,8 +124,8 @@ const CardAsset = (props: Props) => {
|
|
|
121
124
|
onSelect([
|
|
122
125
|
{
|
|
123
126
|
kind: 'assetDocumentId',
|
|
124
|
-
value: asset._id
|
|
125
|
-
}
|
|
127
|
+
value: asset._id,
|
|
128
|
+
},
|
|
126
129
|
])
|
|
127
130
|
} else if (shiftPressed.current) {
|
|
128
131
|
if (picked) {
|
|
@@ -158,7 +161,7 @@ const CardAsset = (props: Props) => {
|
|
|
158
161
|
flex={1}
|
|
159
162
|
style={{
|
|
160
163
|
cursor: selected ? 'default' : 'pointer',
|
|
161
|
-
position: 'relative'
|
|
164
|
+
position: 'relative',
|
|
162
165
|
}}
|
|
163
166
|
>
|
|
164
167
|
<div onClick={handleAssetClick} style={{height: '100%', opacity: opacityPreview}}>
|
|
@@ -174,7 +177,7 @@ const CardAsset = (props: Props) => {
|
|
|
174
177
|
src={imageDprUrl(asset, {height: 250, width: 250})}
|
|
175
178
|
style={{
|
|
176
179
|
draggable: false,
|
|
177
|
-
transition: 'opacity 1000ms'
|
|
180
|
+
transition: 'opacity 1000ms',
|
|
178
181
|
}}
|
|
179
182
|
/>
|
|
180
183
|
)}
|
|
@@ -191,7 +194,7 @@ const CardAsset = (props: Props) => {
|
|
|
191
194
|
opacity: opacityContainer,
|
|
192
195
|
position: 'absolute',
|
|
193
196
|
top: 0,
|
|
194
|
-
width: '100%'
|
|
197
|
+
width: '100%',
|
|
195
198
|
}}
|
|
196
199
|
>
|
|
197
200
|
<Text size={2}>
|
|
@@ -210,7 +213,7 @@ const CardAsset = (props: Props) => {
|
|
|
210
213
|
left: 0,
|
|
211
214
|
position: 'absolute',
|
|
212
215
|
top: 0,
|
|
213
|
-
width: '100%'
|
|
216
|
+
width: '100%',
|
|
214
217
|
}}
|
|
215
218
|
>
|
|
216
219
|
<Spinner />
|
|
@@ -230,7 +233,7 @@ const CardAsset = (props: Props) => {
|
|
|
230
233
|
<EditIcon
|
|
231
234
|
style={{
|
|
232
235
|
flexShrink: 0,
|
|
233
|
-
opacity: 0.5
|
|
236
|
+
opacity: 0.5,
|
|
234
237
|
}}
|
|
235
238
|
/>
|
|
236
239
|
) : (
|
|
@@ -240,7 +243,7 @@ const CardAsset = (props: Props) => {
|
|
|
240
243
|
style={{
|
|
241
244
|
flexShrink: 0,
|
|
242
245
|
pointerEvents: 'none',
|
|
243
|
-
transform: 'scale(0.8)'
|
|
246
|
+
transform: 'scale(0.8)',
|
|
244
247
|
}}
|
|
245
248
|
/>
|
|
246
249
|
)}
|
|
@@ -260,7 +263,7 @@ const CardAsset = (props: Props) => {
|
|
|
260
263
|
style={{
|
|
261
264
|
position: 'absolute',
|
|
262
265
|
right: 0,
|
|
263
|
-
top: 0
|
|
266
|
+
top: 0,
|
|
264
267
|
}}
|
|
265
268
|
>
|
|
266
269
|
<Tooltip
|
|
@@ -4,12 +4,13 @@ import filesize from 'filesize'
|
|
|
4
4
|
import {useDispatch} from 'react-redux'
|
|
5
5
|
import {useColorSchemeValue} from 'sanity'
|
|
6
6
|
import {styled} from 'styled-components'
|
|
7
|
+
|
|
7
8
|
import {PANEL_HEIGHT} from '../../constants'
|
|
8
9
|
import useTypedSelector from '../../hooks/useTypedSelector'
|
|
9
10
|
import {selectUploadById, uploadsActions} from '../../modules/uploads'
|
|
11
|
+
import {getSchemeColor} from '../../utils/getSchemeColor'
|
|
10
12
|
import FileIcon from '../FileIcon'
|
|
11
13
|
import Image from '../Image'
|
|
12
|
-
import {getSchemeColor} from '../../utils/getSchemeColor'
|
|
13
14
|
|
|
14
15
|
type Props = {
|
|
15
16
|
id: string
|
|
@@ -30,7 +31,7 @@ const CardUpload = (props: Props) => {
|
|
|
30
31
|
|
|
31
32
|
// Redux
|
|
32
33
|
const dispatch = useDispatch()
|
|
33
|
-
const item = useTypedSelector(state => selectUploadById(state, id))
|
|
34
|
+
const item = useTypedSelector((state) => selectUploadById(state, id))
|
|
34
35
|
|
|
35
36
|
if (!item) {
|
|
36
37
|
return null
|
|
@@ -68,7 +69,7 @@ const CardUpload = (props: Props) => {
|
|
|
68
69
|
background: getSchemeColor(scheme, 'bg'),
|
|
69
70
|
border: '1px solid transparent',
|
|
70
71
|
height: '100%',
|
|
71
|
-
position: 'relative'
|
|
72
|
+
position: 'relative',
|
|
72
73
|
}}
|
|
73
74
|
>
|
|
74
75
|
{/* Progress bar */}
|
|
@@ -82,7 +83,7 @@ const CardUpload = (props: Props) => {
|
|
|
82
83
|
width: '100%',
|
|
83
84
|
transform: `scaleX(${percentLoaded * 0.01})`,
|
|
84
85
|
transformOrigin: 'bottom left',
|
|
85
|
-
transition: 'all 1000ms ease-out'
|
|
86
|
+
transition: 'all 1000ms ease-out',
|
|
86
87
|
}}
|
|
87
88
|
/>
|
|
88
89
|
|
|
@@ -93,7 +94,7 @@ const CardUpload = (props: Props) => {
|
|
|
93
94
|
$scheme={scheme}
|
|
94
95
|
src={item.objectUrl}
|
|
95
96
|
style={{
|
|
96
|
-
opacity: 0.4
|
|
97
|
+
opacity: 0.4,
|
|
97
98
|
}}
|
|
98
99
|
/>
|
|
99
100
|
)}
|
|
@@ -120,7 +121,7 @@ const CardUpload = (props: Props) => {
|
|
|
120
121
|
left: 0,
|
|
121
122
|
position: 'absolute',
|
|
122
123
|
top: 0,
|
|
123
|
-
width: '100%'
|
|
124
|
+
width: '100%',
|
|
124
125
|
}}
|
|
125
126
|
>
|
|
126
127
|
<Button
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {Box, Button, Flex, Inline, useMediaIndex} from '@sanity/ui'
|
|
2
2
|
import {useDispatch} from 'react-redux'
|
|
3
|
+
|
|
3
4
|
import useTypedSelector from '../../hooks/useTypedSelector'
|
|
4
5
|
import {dialogActions} from '../../modules/dialog'
|
|
5
6
|
import {tagsActions} from '../../modules/tags'
|
|
@@ -14,10 +15,10 @@ import TextInputSearch from '../TextInputSearch'
|
|
|
14
15
|
const Controls = () => {
|
|
15
16
|
// Redux
|
|
16
17
|
const dispatch = useDispatch()
|
|
17
|
-
const fetching = useTypedSelector(state => state.assets.fetching)
|
|
18
|
-
const pageIndex = useTypedSelector(state => state.assets.pageIndex)
|
|
19
|
-
const searchFacets = useTypedSelector(state => state.search.facets)
|
|
20
|
-
const tagsPanelVisible = useTypedSelector(state => state.tags.panelVisible)
|
|
18
|
+
const fetching = useTypedSelector((state) => state.assets.fetching)
|
|
19
|
+
const pageIndex = useTypedSelector((state) => state.assets.pageIndex)
|
|
20
|
+
const searchFacets = useTypedSelector((state) => state.search.facets)
|
|
21
|
+
const tagsPanelVisible = useTypedSelector((state) => state.tags.panelVisible)
|
|
21
22
|
|
|
22
23
|
const mediaIndex = useMediaIndex()
|
|
23
24
|
|
|
@@ -39,7 +40,7 @@ const Controls = () => {
|
|
|
39
40
|
paddingY={2}
|
|
40
41
|
style={{
|
|
41
42
|
borderBottom: '1px solid var(--card-border-color)',
|
|
42
|
-
zIndex: 2
|
|
43
|
+
zIndex: 2,
|
|
43
44
|
}}
|
|
44
45
|
>
|
|
45
46
|
{/* Rows: search / filters / orders */}
|
|
@@ -58,7 +59,7 @@ const Controls = () => {
|
|
|
58
59
|
height: '100%',
|
|
59
60
|
justifyContent: mediaIndex < 2 ? 'space-between' : 'flex-start',
|
|
60
61
|
position: 'relative',
|
|
61
|
-
width: '100%'
|
|
62
|
+
width: '100%',
|
|
62
63
|
}}
|
|
63
64
|
>
|
|
64
65
|
<Box marginX={2} style={{minWidth: '200px'}}>
|
|
@@ -2,6 +2,7 @@ import {PlugIcon} from '@sanity/icons'
|
|
|
2
2
|
import {Box, Flex, Switch, Text, Tooltip} from '@sanity/ui'
|
|
3
3
|
import {type ChangeEvent} from 'react'
|
|
4
4
|
import {useDispatch} from 'react-redux'
|
|
5
|
+
|
|
5
6
|
import useKeyPress from '../../hooks/useKeyPress'
|
|
6
7
|
import useTypedSelector from '../../hooks/useTypedSelector'
|
|
7
8
|
import {debugActions} from '../../modules/debug'
|
|
@@ -9,8 +10,8 @@ import {debugActions} from '../../modules/debug'
|
|
|
9
10
|
const DebugControls = () => {
|
|
10
11
|
// Redux
|
|
11
12
|
const dispatch = useDispatch()
|
|
12
|
-
const badConnection = useTypedSelector(state => state.debug.badConnection)
|
|
13
|
-
const debugEnabled = useTypedSelector(state => state.debug.enabled)
|
|
13
|
+
const badConnection = useTypedSelector((state) => state.debug.badConnection)
|
|
14
|
+
const debugEnabled = useTypedSelector((state) => state.debug.enabled)
|
|
14
15
|
|
|
15
16
|
// Callbacks
|
|
16
17
|
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
|
|
@@ -38,7 +39,7 @@ const DebugControls = () => {
|
|
|
38
39
|
left: 0,
|
|
39
40
|
pointerEvents: 'none',
|
|
40
41
|
position: 'fixed',
|
|
41
|
-
width: '100%'
|
|
42
|
+
width: '100%',
|
|
42
43
|
}}
|
|
43
44
|
>
|
|
44
45
|
{/* Bad connection toggle */}
|
|
@@ -67,7 +68,7 @@ const DebugControls = () => {
|
|
|
67
68
|
checked={badConnection}
|
|
68
69
|
onChange={handleChange}
|
|
69
70
|
style={{
|
|
70
|
-
pointerEvents: 'auto'
|
|
71
|
+
pointerEvents: 'auto',
|
|
71
72
|
}}
|
|
72
73
|
/>
|
|
73
74
|
</Tooltip>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {Card, Stack, Tab, TabList, TabPanel} from '@sanity/ui'
|
|
2
2
|
import {useState} from 'react'
|
|
3
3
|
import {type Control, type FieldErrors, type UseFormRegister} from 'react-hook-form'
|
|
4
|
+
|
|
4
5
|
import type {Asset, AssetFormData, Locale, TagSelectOption} from '../../types'
|
|
5
6
|
import FormFieldInputTags from '../FormFieldInputTags'
|
|
6
7
|
import FormFieldInputText from '../FormFieldInputText'
|
|
@@ -12,7 +13,7 @@ type LocalizedErrors = Record<string, {message?: string} | undefined>
|
|
|
12
13
|
function toStringField(value: unknown): string | undefined {
|
|
13
14
|
if (typeof value === 'string') return value
|
|
14
15
|
if (typeof value === 'object' && value !== null) {
|
|
15
|
-
const found = Object.values(value as Record<string, string>).find(v => v)
|
|
16
|
+
const found = Object.values(value as Record<string, string>).find((v) => v)
|
|
16
17
|
return found || undefined
|
|
17
18
|
}
|
|
18
19
|
return undefined
|
|
@@ -44,7 +45,7 @@ export default function Details({
|
|
|
44
45
|
assetTagOptions,
|
|
45
46
|
currentAsset,
|
|
46
47
|
creditLine,
|
|
47
|
-
locales
|
|
48
|
+
locales,
|
|
48
49
|
}: DetailsProps) {
|
|
49
50
|
const hasLocales = locales && locales.length > 0
|
|
50
51
|
const [activeLocaleTab, setActiveLocaleTab] = useState(0)
|