sanity-plugin-media 4.3.6 → 5.0.1
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/package.json +8 -17
- package/dist/index.cjs +0 -4721
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -239
- package/dist/index.d.cts.map +0 -1
- package/sanity.json +0 -8
- package/src/__tests__/fixtures/createEpicTestStore.ts +0 -28
- package/src/__tests__/fixtures/listenMock.ts +0 -9
- package/src/__tests__/fixtures/mockSanityClient.ts +0 -84
- package/src/__tests__/fixtures/renderWithProviders.tsx +0 -55
- package/src/__tests__/fixtures/rootState.ts +0 -27
- package/src/__tests__/fixtures/withinDialog.ts +0 -28
- package/src/components/AssetGridVirtualized/index.tsx +0 -94
- package/src/components/AssetMetadata/index.tsx +0 -122
- package/src/components/AssetTableVirtualized/index.tsx +0 -73
- package/src/components/AutoTagInputWrapper/index.tsx +0 -85
- package/src/components/Browser/Browser.test.tsx +0 -45
- package/src/components/Browser/index.tsx +0 -90
- package/src/components/Browser/useBrowserInit.ts +0 -126
- package/src/components/ButtonAssetCopy/index.tsx +0 -65
- package/src/components/ButtonViewGroup/index.tsx +0 -39
- package/src/components/CardAsset/CardAsset.test.tsx +0 -323
- package/src/components/CardAsset/index.tsx +0 -290
- package/src/components/CardUpload/index.tsx +0 -161
- package/src/components/Controls/index.tsx +0 -136
- package/src/components/DebugControls/index.tsx +0 -80
- package/src/components/Dialog/index.tsx +0 -11
- package/src/components/DialogAssetEdit/Details.tsx +0 -181
- package/src/components/DialogAssetEdit/DialogAssetEdit.test.tsx +0 -216
- package/src/components/DialogAssetEdit/index.tsx +0 -493
- package/src/components/DialogConfirm/index.tsx +0 -90
- package/src/components/DialogSearchFacets/index.tsx +0 -42
- package/src/components/DialogTagCreate/DialogTagCreate.test.tsx +0 -121
- package/src/components/DialogTagCreate/index.tsx +0 -111
- package/src/components/DialogTagEdit/DialogTagEdit.test.tsx +0 -165
- package/src/components/DialogTagEdit/index.tsx +0 -201
- package/src/components/DialogTags/index.tsx +0 -45
- package/src/components/Dialogs/index.tsx +0 -76
- package/src/components/DocumentList/index.tsx +0 -62
- package/src/components/FileAssetPreview/index.tsx +0 -37
- package/src/components/FileIcon/index.tsx +0 -43
- package/src/components/FormBuilderTool/FormBuilderTool.test.tsx +0 -63
- package/src/components/FormBuilderTool/index.tsx +0 -69
- package/src/components/FormFieldInputLabel/index.tsx +0 -66
- package/src/components/FormFieldInputTags/index.tsx +0 -98
- package/src/components/FormFieldInputText/index.tsx +0 -41
- package/src/components/FormFieldInputTextarea/index.tsx +0 -43
- package/src/components/FormSubmitButton/index.tsx +0 -59
- package/src/components/Header/index.tsx +0 -80
- package/src/components/Image/index.tsx +0 -41
- package/src/components/Items/index.tsx +0 -68
- package/src/components/Notifications/index.tsx +0 -24
- package/src/components/OrderSelect/index.tsx +0 -66
- package/src/components/PickedBar/index.tsx +0 -77
- package/src/components/Progress/index.tsx +0 -38
- package/src/components/ReduxProvider/index.tsx +0 -96
- package/src/components/SearchFacet/index.tsx +0 -66
- package/src/components/SearchFacetNumber/index.tsx +0 -133
- package/src/components/SearchFacetSelect/index.tsx +0 -110
- package/src/components/SearchFacetString/index.tsx +0 -88
- package/src/components/SearchFacetTags/index.tsx +0 -121
- package/src/components/SearchFacets/index.tsx +0 -72
- package/src/components/SearchFacetsControl/index.tsx +0 -140
- package/src/components/TableHeader/index.tsx +0 -110
- package/src/components/TableHeaderItem/index.tsx +0 -61
- package/src/components/TableRowAsset/index.tsx +0 -419
- package/src/components/TableRowUpload/index.tsx +0 -164
- package/src/components/Tag/index.tsx +0 -200
- package/src/components/TagIcon/index.tsx +0 -22
- package/src/components/TagView/index.tsx +0 -39
- package/src/components/TagViewHeader/index.tsx +0 -70
- package/src/components/TagsPanel/index.tsx +0 -40
- package/src/components/TagsVirtualized/index.tsx +0 -160
- package/src/components/TextInputNumber/index.tsx +0 -32
- package/src/components/TextInputSearch/index.tsx +0 -60
- package/src/components/Tool/index.tsx +0 -13
- package/src/components/UploadDropzone/UploadDropzone.test.tsx +0 -40
- package/src/components/UploadDropzone/index.tsx +0 -173
- package/src/config/orders.ts +0 -28
- package/src/config/searchFacets.ts +0 -312
- package/src/constants.ts +0 -87
- package/src/contexts/AssetSourceDispatchContext.tsx +0 -38
- package/src/contexts/DropzoneDispatchContext.tsx +0 -32
- package/src/contexts/ToolOptionsContext.tsx +0 -66
- package/src/formSchema/index.test.ts +0 -56
- package/src/formSchema/index.ts +0 -39
- package/src/hooks/useBreakpointIndex.ts +0 -50
- package/src/hooks/useKeyPress.ts +0 -39
- package/src/hooks/usePortalPopoverProps.ts +0 -13
- package/src/hooks/useTypedSelector.ts +0 -7
- package/src/hooks/useVersionedClient.ts +0 -6
- package/src/index.ts +0 -5
- package/src/modules/assets/actions.ts +0 -42
- package/src/modules/assets/deleteAndUpdateEpics.test.ts +0 -87
- package/src/modules/assets/fetchEpic.test.ts +0 -73
- package/src/modules/assets/index.ts +0 -782
- package/src/modules/assets/reducer.test.ts +0 -91
- package/src/modules/assets/tagsAndListenerEpics.test.ts +0 -206
- package/src/modules/debug/index.ts +0 -28
- package/src/modules/dialog/actions.ts +0 -10
- package/src/modules/dialog/epics.test.ts +0 -168
- package/src/modules/dialog/index.ts +0 -238
- package/src/modules/dialog/reducer.test.ts +0 -185
- package/src/modules/index.ts +0 -117
- package/src/modules/notifications/epics.test.ts +0 -374
- package/src/modules/notifications/index.ts +0 -199
- package/src/modules/notifications/reducer.test.ts +0 -54
- package/src/modules/search/index.test.ts +0 -36
- package/src/modules/search/index.ts +0 -167
- package/src/modules/selected/index.ts +0 -22
- package/src/modules/selectors.test.ts +0 -21
- package/src/modules/selectors.ts +0 -17
- package/src/modules/tags/epics.test.ts +0 -96
- package/src/modules/tags/index.test.ts +0 -42
- package/src/modules/tags/index.ts +0 -540
- package/src/modules/types.ts +0 -3
- package/src/modules/uploads/actions.ts +0 -13
- package/src/modules/uploads/epics.test.ts +0 -109
- package/src/modules/uploads/index.test.ts +0 -59
- package/src/modules/uploads/index.ts +0 -272
- package/src/operators/checkTagName.test.ts +0 -29
- package/src/operators/checkTagName.ts +0 -33
- package/src/operators/debugThrottle.ts +0 -25
- package/src/plugin.tsx +0 -54
- package/src/schemas/tag.ts +0 -28
- package/src/styled/GlobalStyles/index.tsx +0 -40
- package/src/styled/react-select/creatable.tsx +0 -184
- package/src/styled/react-select/single.tsx +0 -184
- package/src/types/index.ts +0 -346
- package/src/types/sanity-ui.d.ts +0 -5
- package/src/utils/applyMediaTags.ts +0 -87
- package/src/utils/blocksToText.test.ts +0 -43
- package/src/utils/blocksToText.ts +0 -27
- package/src/utils/constructFilter.test.ts +0 -120
- package/src/utils/constructFilter.ts +0 -98
- package/src/utils/generatePreviewBlobUrl.test.ts +0 -68
- package/src/utils/generatePreviewBlobUrl.ts +0 -53
- package/src/utils/getAssetResolution.test.ts +0 -13
- package/src/utils/getAssetResolution.ts +0 -7
- package/src/utils/getDocumentAssetIds.test.ts +0 -50
- package/src/utils/getDocumentAssetIds.ts +0 -35
- package/src/utils/getSchemeColor.test.ts +0 -12
- package/src/utils/getSchemeColor.ts +0 -43
- package/src/utils/getTagSelectOptions.test.ts +0 -44
- package/src/utils/getTagSelectOptions.ts +0 -16
- package/src/utils/getUniqueDocuments.test.ts +0 -26
- package/src/utils/getUniqueDocuments.ts +0 -15
- package/src/utils/imageDprUrl.test.ts +0 -46
- package/src/utils/imageDprUrl.ts +0 -27
- package/src/utils/isSupportedAssetType.test.ts +0 -16
- package/src/utils/isSupportedAssetType.ts +0 -15
- package/src/utils/mediaField.ts +0 -73
- package/src/utils/sanitizeFormData.test.ts +0 -59
- package/src/utils/sanitizeFormData.ts +0 -26
- package/src/utils/typeGuards.test.ts +0 -18
- package/src/utils/typeGuards.ts +0 -9
- package/src/utils/uploadSanityAsset.test.ts +0 -29
- package/src/utils/uploadSanityAsset.ts +0 -97
- package/src/utils/withMaxConcurrency.test.ts +0 -43
- package/src/utils/withMaxConcurrency.ts +0 -55
- package/src/utils/zodFormResolver.ts +0 -17
- package/v2-incompatible.js +0 -11
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
import {CloseIcon} from '@sanity/icons'
|
|
2
|
-
import {Box, Button, Flex, Text} from '@sanity/ui'
|
|
3
|
-
import filesize from 'filesize'
|
|
4
|
-
import {useDispatch} from 'react-redux'
|
|
5
|
-
import {useColorSchemeValue} from 'sanity'
|
|
6
|
-
import {styled} from 'styled-components'
|
|
7
|
-
|
|
8
|
-
import {PANEL_HEIGHT} from '../../constants'
|
|
9
|
-
import useTypedSelector from '../../hooks/useTypedSelector'
|
|
10
|
-
import {selectUploadById, uploadsActions} from '../../modules/uploads'
|
|
11
|
-
import {getSchemeColor} from '../../utils/getSchemeColor'
|
|
12
|
-
import FileIcon from '../FileIcon'
|
|
13
|
-
import Image from '../Image'
|
|
14
|
-
|
|
15
|
-
type Props = {
|
|
16
|
-
id: string
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const CardWrapper = styled(Flex)`
|
|
20
|
-
box-sizing: border-box;
|
|
21
|
-
height: 100%;
|
|
22
|
-
overflow: hidden;
|
|
23
|
-
position: relative;
|
|
24
|
-
width: 100%;
|
|
25
|
-
`
|
|
26
|
-
|
|
27
|
-
const CardUpload = (props: Props) => {
|
|
28
|
-
const {id} = props
|
|
29
|
-
|
|
30
|
-
const scheme = useColorSchemeValue()
|
|
31
|
-
|
|
32
|
-
// Redux
|
|
33
|
-
const dispatch = useDispatch()
|
|
34
|
-
const item = useTypedSelector((state) => selectUploadById(state, id))
|
|
35
|
-
|
|
36
|
-
if (!item) {
|
|
37
|
-
return null
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const fileSize = filesize(item.size, {base: 10, round: 0})
|
|
41
|
-
const percentLoaded = Math.round(item.percent || 0) // (0 - 100)
|
|
42
|
-
|
|
43
|
-
const isComplete = item.status === 'complete'
|
|
44
|
-
const isUploading = item.status === 'uploading'
|
|
45
|
-
const isQueued = item.status === 'queued'
|
|
46
|
-
|
|
47
|
-
let status
|
|
48
|
-
if (isComplete) {
|
|
49
|
-
status = 'Verifying'
|
|
50
|
-
}
|
|
51
|
-
if (isUploading) {
|
|
52
|
-
status = `${percentLoaded}%`
|
|
53
|
-
}
|
|
54
|
-
if (isQueued) {
|
|
55
|
-
status = 'Queued'
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Callbacks
|
|
59
|
-
const handleCancelUpload = () => {
|
|
60
|
-
dispatch(uploadsActions.uploadCancel({hash: item.hash}))
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return (
|
|
64
|
-
<CardWrapper padding={1}>
|
|
65
|
-
<Flex
|
|
66
|
-
direction="column"
|
|
67
|
-
flex={1}
|
|
68
|
-
style={{
|
|
69
|
-
background: getSchemeColor(scheme, 'bg'),
|
|
70
|
-
border: '1px solid transparent',
|
|
71
|
-
height: '100%',
|
|
72
|
-
position: 'relative',
|
|
73
|
-
}}
|
|
74
|
-
>
|
|
75
|
-
{/* Progress bar */}
|
|
76
|
-
<div
|
|
77
|
-
style={{
|
|
78
|
-
background: 'var(--card-fg-color)',
|
|
79
|
-
bottom: 0,
|
|
80
|
-
height: '1px',
|
|
81
|
-
left: 0,
|
|
82
|
-
position: 'absolute',
|
|
83
|
-
width: '100%',
|
|
84
|
-
transform: `scaleX(${percentLoaded * 0.01})`,
|
|
85
|
-
transformOrigin: 'bottom left',
|
|
86
|
-
transition: 'all 1000ms ease-out',
|
|
87
|
-
}}
|
|
88
|
-
/>
|
|
89
|
-
|
|
90
|
-
<Box flex={1} style={{position: 'relative'}}>
|
|
91
|
-
{item.assetType === 'image' && item?.objectUrl && (
|
|
92
|
-
<Image
|
|
93
|
-
draggable={false}
|
|
94
|
-
$scheme={scheme}
|
|
95
|
-
src={item.objectUrl}
|
|
96
|
-
style={{
|
|
97
|
-
opacity: 0.4,
|
|
98
|
-
}}
|
|
99
|
-
/>
|
|
100
|
-
)}
|
|
101
|
-
|
|
102
|
-
{item.assetType === 'file' && (
|
|
103
|
-
<div style={{height: '100%', opacity: 0.1}}>
|
|
104
|
-
<FileIcon width="80px" />
|
|
105
|
-
</div>
|
|
106
|
-
)}
|
|
107
|
-
|
|
108
|
-
{/*
|
|
109
|
-
Cancel upload button.
|
|
110
|
-
Assets will only have a `complete` status _after_ it has been created on your dataset.
|
|
111
|
-
As such, we also hide the cancel button when `percentLoaded === 100`, as cancelling when the asset
|
|
112
|
-
has been fully uploaded (even with a status of `progress`) won't stop the asset from being created.
|
|
113
|
-
*/}
|
|
114
|
-
{!isComplete && percentLoaded !== 100 && (
|
|
115
|
-
<Flex
|
|
116
|
-
align="center"
|
|
117
|
-
direction="column"
|
|
118
|
-
justify="center"
|
|
119
|
-
style={{
|
|
120
|
-
height: '100%',
|
|
121
|
-
left: 0,
|
|
122
|
-
position: 'absolute',
|
|
123
|
-
top: 0,
|
|
124
|
-
width: '100%',
|
|
125
|
-
}}
|
|
126
|
-
>
|
|
127
|
-
<Button
|
|
128
|
-
fontSize={4}
|
|
129
|
-
icon={CloseIcon}
|
|
130
|
-
mode="bleed"
|
|
131
|
-
onClick={handleCancelUpload}
|
|
132
|
-
padding={2}
|
|
133
|
-
style={{background: 'none', boxShadow: 'none'}}
|
|
134
|
-
tone="critical"
|
|
135
|
-
/>
|
|
136
|
-
</Flex>
|
|
137
|
-
)}
|
|
138
|
-
</Box>
|
|
139
|
-
|
|
140
|
-
{/* Footer */}
|
|
141
|
-
<Flex
|
|
142
|
-
align="center"
|
|
143
|
-
justify="space-between"
|
|
144
|
-
paddingX={2}
|
|
145
|
-
style={{height: `${PANEL_HEIGHT}px`}}
|
|
146
|
-
>
|
|
147
|
-
<Box flex={1} marginRight={1}>
|
|
148
|
-
<Text size={0} textOverflow="ellipsis">
|
|
149
|
-
{item.name} ({fileSize})
|
|
150
|
-
</Text>
|
|
151
|
-
</Box>
|
|
152
|
-
<Text size={0} style={{flexShrink: 0}} weight="semibold">
|
|
153
|
-
{status}
|
|
154
|
-
</Text>
|
|
155
|
-
</Flex>
|
|
156
|
-
</Flex>
|
|
157
|
-
</CardWrapper>
|
|
158
|
-
)
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export default CardUpload
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
import {Box, Button, Flex, Inline, useMediaIndex} from '@sanity/ui'
|
|
2
|
-
import {useDispatch} from 'react-redux'
|
|
3
|
-
|
|
4
|
-
import useTypedSelector from '../../hooks/useTypedSelector'
|
|
5
|
-
import {dialogActions} from '../../modules/dialog'
|
|
6
|
-
import {tagsActions} from '../../modules/tags'
|
|
7
|
-
import ButtonViewGroup from '../ButtonViewGroup'
|
|
8
|
-
import OrderSelect from '../OrderSelect'
|
|
9
|
-
import Progress from '../Progress'
|
|
10
|
-
import SearchFacets from '../SearchFacets'
|
|
11
|
-
import SearchFacetsControl from '../SearchFacetsControl'
|
|
12
|
-
import TagIcon from '../TagIcon'
|
|
13
|
-
import TextInputSearch from '../TextInputSearch'
|
|
14
|
-
|
|
15
|
-
const Controls = () => {
|
|
16
|
-
// Redux
|
|
17
|
-
const dispatch = useDispatch()
|
|
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)
|
|
22
|
-
|
|
23
|
-
const mediaIndex = useMediaIndex()
|
|
24
|
-
|
|
25
|
-
// Callbacks
|
|
26
|
-
const handleShowSearchFacetDialog = () => {
|
|
27
|
-
dispatch(dialogActions.showSearchFacets())
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const handleShowTagsDialog = () => {
|
|
31
|
-
dispatch(dialogActions.showTags())
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const toggleTagsPanelToggle = () => {
|
|
35
|
-
dispatch(tagsActions.panelVisibleSet({panelVisible: !tagsPanelVisible}))
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return (
|
|
39
|
-
<Box
|
|
40
|
-
paddingY={2}
|
|
41
|
-
style={{
|
|
42
|
-
borderBottom: '1px solid var(--card-border-color)',
|
|
43
|
-
zIndex: 2,
|
|
44
|
-
}}
|
|
45
|
-
>
|
|
46
|
-
{/* Rows: search / filters / orders */}
|
|
47
|
-
<Box marginBottom={2}>
|
|
48
|
-
<Flex
|
|
49
|
-
align="flex-start"
|
|
50
|
-
direction={['column', 'column', 'column', 'column', 'row']}
|
|
51
|
-
justify="space-between"
|
|
52
|
-
>
|
|
53
|
-
{/* Search + Filters */}
|
|
54
|
-
<Flex
|
|
55
|
-
flex={1}
|
|
56
|
-
style={{
|
|
57
|
-
alignItems: 'flex-start',
|
|
58
|
-
flex: 1,
|
|
59
|
-
height: '100%',
|
|
60
|
-
justifyContent: mediaIndex < 2 ? 'space-between' : 'flex-start',
|
|
61
|
-
position: 'relative',
|
|
62
|
-
width: '100%',
|
|
63
|
-
}}
|
|
64
|
-
>
|
|
65
|
-
<Box marginX={2} style={{minWidth: '200px'}}>
|
|
66
|
-
{/* Search */}
|
|
67
|
-
<TextInputSearch />
|
|
68
|
-
</Box>
|
|
69
|
-
|
|
70
|
-
<Box display={['none', 'none', 'block']}>
|
|
71
|
-
<SearchFacets />
|
|
72
|
-
|
|
73
|
-
{/* Search Facets Control (add / clear) */}
|
|
74
|
-
<SearchFacetsControl />
|
|
75
|
-
</Box>
|
|
76
|
-
|
|
77
|
-
<Box display={['block', 'block', 'none']} marginX={2}>
|
|
78
|
-
<Inline space={2} style={{whiteSpace: 'nowrap'}}>
|
|
79
|
-
{/* Filters button (small) */}
|
|
80
|
-
<Button
|
|
81
|
-
fontSize={1}
|
|
82
|
-
mode="ghost"
|
|
83
|
-
onClick={handleShowSearchFacetDialog}
|
|
84
|
-
text={`Filters${searchFacets.length > 0 ? ` (${searchFacets.length})` : ''}`}
|
|
85
|
-
tone="primary"
|
|
86
|
-
/>
|
|
87
|
-
|
|
88
|
-
{/* Tags button (small) */}
|
|
89
|
-
<Button
|
|
90
|
-
fontSize={1}
|
|
91
|
-
mode="ghost"
|
|
92
|
-
onClick={handleShowTagsDialog}
|
|
93
|
-
text={`Tags`}
|
|
94
|
-
tone="primary"
|
|
95
|
-
/>
|
|
96
|
-
</Inline>
|
|
97
|
-
</Box>
|
|
98
|
-
</Flex>
|
|
99
|
-
</Flex>
|
|
100
|
-
</Box>
|
|
101
|
-
|
|
102
|
-
<Box>
|
|
103
|
-
<Flex align="center" justify={['space-between']}>
|
|
104
|
-
{/* Views */}
|
|
105
|
-
<Box marginX={2}>
|
|
106
|
-
<ButtonViewGroup />
|
|
107
|
-
</Box>
|
|
108
|
-
|
|
109
|
-
<Flex marginX={2}>
|
|
110
|
-
{/* Orders */}
|
|
111
|
-
<OrderSelect />
|
|
112
|
-
{/* Tags panel toggle */}
|
|
113
|
-
<Box display={['none', 'none', 'block']} marginLeft={2}>
|
|
114
|
-
<Button
|
|
115
|
-
fontSize={1}
|
|
116
|
-
icon={
|
|
117
|
-
<Box style={{transform: 'scale(0.75)'}}>
|
|
118
|
-
<TagIcon />
|
|
119
|
-
</Box>
|
|
120
|
-
}
|
|
121
|
-
onClick={toggleTagsPanelToggle}
|
|
122
|
-
mode={tagsPanelVisible ? 'default' : 'ghost'}
|
|
123
|
-
text={tagsPanelVisible ? 'Tags' : ''}
|
|
124
|
-
/>
|
|
125
|
-
</Box>
|
|
126
|
-
</Flex>
|
|
127
|
-
</Flex>
|
|
128
|
-
</Box>
|
|
129
|
-
|
|
130
|
-
{/* Progress bar */}
|
|
131
|
-
<Progress key={pageIndex} loading={fetching} />
|
|
132
|
-
</Box>
|
|
133
|
-
)
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
export default Controls
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import {PlugIcon} from '@sanity/icons'
|
|
2
|
-
import {Box, Flex, Switch, Text, Tooltip} from '@sanity/ui'
|
|
3
|
-
import {type ChangeEvent} from 'react'
|
|
4
|
-
import {useDispatch} from 'react-redux'
|
|
5
|
-
|
|
6
|
-
import useKeyPress from '../../hooks/useKeyPress'
|
|
7
|
-
import useTypedSelector from '../../hooks/useTypedSelector'
|
|
8
|
-
import {debugActions} from '../../modules/debug'
|
|
9
|
-
|
|
10
|
-
const DebugControls = () => {
|
|
11
|
-
// Redux
|
|
12
|
-
const dispatch = useDispatch()
|
|
13
|
-
const badConnection = useTypedSelector((state) => state.debug.badConnection)
|
|
14
|
-
const debugEnabled = useTypedSelector((state) => state.debug.enabled)
|
|
15
|
-
|
|
16
|
-
// Callbacks
|
|
17
|
-
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
|
|
18
|
-
const checked = e.target.checked
|
|
19
|
-
|
|
20
|
-
dispatch(debugActions.setBadConnection(checked))
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const handleToggleControls = () => {
|
|
24
|
-
dispatch(debugActions.toggleEnabled())
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// Close on escape key press
|
|
28
|
-
useKeyPress('alt+ctrl+shift+/', handleToggleControls)
|
|
29
|
-
|
|
30
|
-
if (!debugEnabled) {
|
|
31
|
-
return null
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return (
|
|
35
|
-
<Box
|
|
36
|
-
padding={4}
|
|
37
|
-
style={{
|
|
38
|
-
bottom: 0,
|
|
39
|
-
left: 0,
|
|
40
|
-
pointerEvents: 'none',
|
|
41
|
-
position: 'fixed',
|
|
42
|
-
width: '100%',
|
|
43
|
-
}}
|
|
44
|
-
>
|
|
45
|
-
{/* Bad connection toggle */}
|
|
46
|
-
<Flex align="center">
|
|
47
|
-
<Box marginRight={3}>
|
|
48
|
-
<Text muted size={1}>
|
|
49
|
-
<PlugIcon />
|
|
50
|
-
</Text>
|
|
51
|
-
</Box>
|
|
52
|
-
<Tooltip
|
|
53
|
-
animate
|
|
54
|
-
content={
|
|
55
|
-
<Box padding={2}>
|
|
56
|
-
<Text muted size={1}>
|
|
57
|
-
{badConnection
|
|
58
|
-
? 'Bad connection: +3000ms & 50% chance to fail'
|
|
59
|
-
: 'No connection throttling'}
|
|
60
|
-
</Text>
|
|
61
|
-
</Box>
|
|
62
|
-
}
|
|
63
|
-
fallbackPlacements={['right', 'left']}
|
|
64
|
-
placement="bottom"
|
|
65
|
-
portal
|
|
66
|
-
>
|
|
67
|
-
<Switch
|
|
68
|
-
checked={badConnection}
|
|
69
|
-
onChange={handleChange}
|
|
70
|
-
style={{
|
|
71
|
-
pointerEvents: 'auto',
|
|
72
|
-
}}
|
|
73
|
-
/>
|
|
74
|
-
</Tooltip>
|
|
75
|
-
</Flex>
|
|
76
|
-
</Box>
|
|
77
|
-
)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export default DebugControls
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import {Dialog as SanityDialog} from '@sanity/ui'
|
|
2
|
-
import {type ComponentProps} from 'react'
|
|
3
|
-
|
|
4
|
-
const Dialog = (props: ComponentProps<typeof SanityDialog>) => {
|
|
5
|
-
// HACK: Temporarily force fixed positioning on all @sanity/ui <Dialog /> components.
|
|
6
|
-
// The studio is currently setting absolute positioning on all root-level dialogs on the mobile breakpoint,
|
|
7
|
-
// causing unwanted scroll behaviour.
|
|
8
|
-
return <SanityDialog {...props} style={{position: 'fixed'}} />
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export default Dialog
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
import {Card, Stack, Tab, TabList, TabPanel} from '@sanity/ui'
|
|
2
|
-
import {useState} from 'react'
|
|
3
|
-
import {type Control, type FieldErrors, type UseFormRegister} from 'react-hook-form'
|
|
4
|
-
|
|
5
|
-
import type {Asset, AssetFormData, Locale, TagSelectOption} from '../../types'
|
|
6
|
-
import FormFieldInputTags from '../FormFieldInputTags'
|
|
7
|
-
import FormFieldInputText from '../FormFieldInputText'
|
|
8
|
-
import FormFieldInputTextarea from '../FormFieldInputTextarea'
|
|
9
|
-
|
|
10
|
-
type LocalizedErrors = Record<string, {message?: string} | undefined>
|
|
11
|
-
|
|
12
|
-
// When locales are not configured, extract a plain string from a potentially localized field
|
|
13
|
-
function toStringField(value: unknown): string | undefined {
|
|
14
|
-
if (typeof value === 'string') return value
|
|
15
|
-
if (typeof value === 'object' && value !== null) {
|
|
16
|
-
const found = Object.values(value as Record<string, string>).find((v) => v)
|
|
17
|
-
return found || undefined
|
|
18
|
-
}
|
|
19
|
-
return undefined
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export type DetailsProps = {
|
|
23
|
-
formUpdating: boolean
|
|
24
|
-
handleCreateTag: (title: string) => void
|
|
25
|
-
control: Control<AssetFormData>
|
|
26
|
-
errors: FieldErrors<AssetFormData>
|
|
27
|
-
register: UseFormRegister<AssetFormData>
|
|
28
|
-
allTagOptions: TagSelectOption[]
|
|
29
|
-
assetTagOptions: TagSelectOption[] | null
|
|
30
|
-
currentAsset: Asset
|
|
31
|
-
creditLine?: {
|
|
32
|
-
enabled: boolean
|
|
33
|
-
excludeSources?: string | string[] | undefined
|
|
34
|
-
}
|
|
35
|
-
locales?: Locale[]
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export default function Details({
|
|
39
|
-
formUpdating,
|
|
40
|
-
handleCreateTag,
|
|
41
|
-
control,
|
|
42
|
-
errors,
|
|
43
|
-
register,
|
|
44
|
-
allTagOptions,
|
|
45
|
-
assetTagOptions,
|
|
46
|
-
currentAsset,
|
|
47
|
-
creditLine,
|
|
48
|
-
locales,
|
|
49
|
-
}: DetailsProps) {
|
|
50
|
-
const hasLocales = locales && locales.length > 0
|
|
51
|
-
const [activeLocaleTab, setActiveLocaleTab] = useState(0)
|
|
52
|
-
return (
|
|
53
|
-
<Stack space={3}>
|
|
54
|
-
{/* Tags */}
|
|
55
|
-
<FormFieldInputTags
|
|
56
|
-
control={control}
|
|
57
|
-
disabled={formUpdating}
|
|
58
|
-
error={errors?.opt?.media?.tags?.message}
|
|
59
|
-
label="Tags"
|
|
60
|
-
name="opt.media.tags"
|
|
61
|
-
onCreateTag={handleCreateTag}
|
|
62
|
-
options={allTagOptions}
|
|
63
|
-
placeholder="Select or create..."
|
|
64
|
-
value={assetTagOptions}
|
|
65
|
-
/>
|
|
66
|
-
{/* Filename */}
|
|
67
|
-
<FormFieldInputText
|
|
68
|
-
{...register('originalFilename')}
|
|
69
|
-
disabled={formUpdating}
|
|
70
|
-
error={errors?.originalFilename?.message}
|
|
71
|
-
label="Filename"
|
|
72
|
-
name="originalFilename"
|
|
73
|
-
value={currentAsset?.originalFilename}
|
|
74
|
-
/>
|
|
75
|
-
{/* Localized fields grouped by language */}
|
|
76
|
-
{hasLocales ? (
|
|
77
|
-
<Card marginTop={2} shadow={1} padding={3} radius={1}>
|
|
78
|
-
<Stack space={2}>
|
|
79
|
-
<TabList space={2}>
|
|
80
|
-
{locales.map((locale, idx) => (
|
|
81
|
-
<Tab
|
|
82
|
-
key={locale.id}
|
|
83
|
-
id={`locale-tab-${locale.id}`}
|
|
84
|
-
aria-controls={`locale-panel-${locale.id}`}
|
|
85
|
-
selected={activeLocaleTab === idx}
|
|
86
|
-
onClick={() => setActiveLocaleTab(idx)}
|
|
87
|
-
label={locale.title}
|
|
88
|
-
/>
|
|
89
|
-
))}
|
|
90
|
-
</TabList>
|
|
91
|
-
{locales.map((locale, idx) => (
|
|
92
|
-
<TabPanel
|
|
93
|
-
key={locale.id}
|
|
94
|
-
id={`locale-panel-${locale.id}`}
|
|
95
|
-
aria-labelledby={`locale-tab-${locale.id}`}
|
|
96
|
-
hidden={activeLocaleTab !== idx}
|
|
97
|
-
>
|
|
98
|
-
<Stack space={3}>
|
|
99
|
-
<FormFieldInputText
|
|
100
|
-
{...register(`title.${locale.id}` as const)}
|
|
101
|
-
disabled={formUpdating}
|
|
102
|
-
error={(errors?.title as LocalizedErrors)?.[locale.id]?.message}
|
|
103
|
-
label="Title"
|
|
104
|
-
name={`title.${locale.id}`}
|
|
105
|
-
/>
|
|
106
|
-
<FormFieldInputText
|
|
107
|
-
{...register(`altText.${locale.id}` as const)}
|
|
108
|
-
disabled={formUpdating}
|
|
109
|
-
error={(errors?.altText as LocalizedErrors)?.[locale.id]?.message}
|
|
110
|
-
label="Alt Text"
|
|
111
|
-
name={`altText.${locale.id}`}
|
|
112
|
-
/>
|
|
113
|
-
<FormFieldInputTextarea
|
|
114
|
-
{...register(`description.${locale.id}` as const)}
|
|
115
|
-
disabled={formUpdating}
|
|
116
|
-
error={(errors?.description as LocalizedErrors)?.[locale.id]?.message}
|
|
117
|
-
label="Description"
|
|
118
|
-
name={`description.${locale.id}`}
|
|
119
|
-
rows={5}
|
|
120
|
-
/>
|
|
121
|
-
{creditLine?.enabled && (
|
|
122
|
-
<FormFieldInputText
|
|
123
|
-
{...register(`creditLine.${locale.id}` as const)}
|
|
124
|
-
error={(errors?.creditLine as LocalizedErrors)?.[locale.id]?.message}
|
|
125
|
-
label="Credit"
|
|
126
|
-
name={`creditLine.${locale.id}`}
|
|
127
|
-
disabled={
|
|
128
|
-
formUpdating ||
|
|
129
|
-
creditLine?.excludeSources?.includes(currentAsset?.['source']?.name)
|
|
130
|
-
}
|
|
131
|
-
/>
|
|
132
|
-
)}
|
|
133
|
-
</Stack>
|
|
134
|
-
</TabPanel>
|
|
135
|
-
))}
|
|
136
|
-
</Stack>
|
|
137
|
-
</Card>
|
|
138
|
-
) : (
|
|
139
|
-
<>
|
|
140
|
-
<FormFieldInputText
|
|
141
|
-
{...register('title')}
|
|
142
|
-
disabled={formUpdating}
|
|
143
|
-
error={errors?.title?.message}
|
|
144
|
-
label="Title"
|
|
145
|
-
name="title"
|
|
146
|
-
value={toStringField(currentAsset?.title)}
|
|
147
|
-
/>
|
|
148
|
-
<FormFieldInputText
|
|
149
|
-
{...register('altText')}
|
|
150
|
-
disabled={formUpdating}
|
|
151
|
-
error={errors?.altText?.message}
|
|
152
|
-
label="Alt Text"
|
|
153
|
-
name="altText"
|
|
154
|
-
value={toStringField(currentAsset?.altText)}
|
|
155
|
-
/>
|
|
156
|
-
<FormFieldInputTextarea
|
|
157
|
-
{...register('description')}
|
|
158
|
-
disabled={formUpdating}
|
|
159
|
-
error={errors?.description?.message}
|
|
160
|
-
label="Description"
|
|
161
|
-
name="description"
|
|
162
|
-
rows={5}
|
|
163
|
-
value={toStringField(currentAsset?.description)}
|
|
164
|
-
/>
|
|
165
|
-
{creditLine?.enabled && (
|
|
166
|
-
<FormFieldInputText
|
|
167
|
-
{...register('creditLine')}
|
|
168
|
-
error={errors?.creditLine?.message}
|
|
169
|
-
label="Credit"
|
|
170
|
-
name="creditLine"
|
|
171
|
-
value={toStringField(currentAsset?.creditLine)}
|
|
172
|
-
disabled={
|
|
173
|
-
formUpdating || creditLine?.excludeSources?.includes(currentAsset?.['source']?.name)
|
|
174
|
-
}
|
|
175
|
-
/>
|
|
176
|
-
)}
|
|
177
|
-
</>
|
|
178
|
-
)}
|
|
179
|
-
</Stack>
|
|
180
|
-
)
|
|
181
|
-
}
|