sanity-plugin-media 4.3.5 → 5.0.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.
Files changed (166) hide show
  1. package/dist/index.d.ts +190 -413
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +2532 -3564
  4. package/dist/index.js.map +1 -1
  5. package/package.json +29 -35
  6. package/dist/index.cjs +0 -5753
  7. package/dist/index.cjs.map +0 -1
  8. package/dist/index.d.cts +0 -462
  9. package/sanity.json +0 -8
  10. package/src/__tests__/fixtures/createEpicTestStore.ts +0 -28
  11. package/src/__tests__/fixtures/listenMock.ts +0 -9
  12. package/src/__tests__/fixtures/mockSanityClient.ts +0 -84
  13. package/src/__tests__/fixtures/renderWithProviders.tsx +0 -55
  14. package/src/__tests__/fixtures/rootState.ts +0 -27
  15. package/src/__tests__/fixtures/withinDialog.ts +0 -28
  16. package/src/components/AssetGridVirtualized/index.tsx +0 -94
  17. package/src/components/AssetMetadata/index.tsx +0 -122
  18. package/src/components/AssetTableVirtualized/index.tsx +0 -73
  19. package/src/components/AutoTagInputWrapper/index.tsx +0 -87
  20. package/src/components/Browser/Browser.test.tsx +0 -45
  21. package/src/components/Browser/index.tsx +0 -90
  22. package/src/components/Browser/useBrowserInit.ts +0 -126
  23. package/src/components/ButtonAssetCopy/index.tsx +0 -65
  24. package/src/components/ButtonViewGroup/index.tsx +0 -39
  25. package/src/components/CardAsset/CardAsset.test.tsx +0 -323
  26. package/src/components/CardAsset/index.tsx +0 -290
  27. package/src/components/CardUpload/index.tsx +0 -161
  28. package/src/components/Controls/index.tsx +0 -136
  29. package/src/components/DebugControls/index.tsx +0 -80
  30. package/src/components/Dialog/index.tsx +0 -11
  31. package/src/components/DialogAssetEdit/Details.tsx +0 -181
  32. package/src/components/DialogAssetEdit/DialogAssetEdit.test.tsx +0 -216
  33. package/src/components/DialogAssetEdit/index.tsx +0 -492
  34. package/src/components/DialogConfirm/index.tsx +0 -88
  35. package/src/components/DialogSearchFacets/index.tsx +0 -42
  36. package/src/components/DialogTagCreate/DialogTagCreate.test.tsx +0 -121
  37. package/src/components/DialogTagCreate/index.tsx +0 -103
  38. package/src/components/DialogTagEdit/DialogTagEdit.test.tsx +0 -165
  39. package/src/components/DialogTagEdit/index.tsx +0 -190
  40. package/src/components/DialogTags/index.tsx +0 -45
  41. package/src/components/Dialogs/index.tsx +0 -76
  42. package/src/components/DocumentList/index.tsx +0 -62
  43. package/src/components/FileAssetPreview/index.tsx +0 -37
  44. package/src/components/FileIcon/index.tsx +0 -43
  45. package/src/components/FormBuilderTool/FormBuilderTool.test.tsx +0 -63
  46. package/src/components/FormBuilderTool/index.tsx +0 -69
  47. package/src/components/FormFieldInputLabel/index.tsx +0 -66
  48. package/src/components/FormFieldInputTags/index.tsx +0 -98
  49. package/src/components/FormFieldInputText/index.tsx +0 -41
  50. package/src/components/FormFieldInputTextarea/index.tsx +0 -43
  51. package/src/components/FormSubmitButton/index.tsx +0 -59
  52. package/src/components/Header/index.tsx +0 -80
  53. package/src/components/Image/index.tsx +0 -41
  54. package/src/components/Items/index.tsx +0 -68
  55. package/src/components/Notifications/index.tsx +0 -24
  56. package/src/components/OrderSelect/index.tsx +0 -66
  57. package/src/components/PickedBar/index.tsx +0 -77
  58. package/src/components/Progress/index.tsx +0 -38
  59. package/src/components/ReduxProvider/index.tsx +0 -96
  60. package/src/components/SearchFacet/index.tsx +0 -66
  61. package/src/components/SearchFacetNumber/index.tsx +0 -133
  62. package/src/components/SearchFacetSelect/index.tsx +0 -110
  63. package/src/components/SearchFacetString/index.tsx +0 -88
  64. package/src/components/SearchFacetTags/index.tsx +0 -121
  65. package/src/components/SearchFacets/index.tsx +0 -72
  66. package/src/components/SearchFacetsControl/index.tsx +0 -140
  67. package/src/components/TableHeader/index.tsx +0 -110
  68. package/src/components/TableHeaderItem/index.tsx +0 -61
  69. package/src/components/TableRowAsset/index.tsx +0 -420
  70. package/src/components/TableRowUpload/index.tsx +0 -164
  71. package/src/components/Tag/index.tsx +0 -200
  72. package/src/components/TagIcon/index.tsx +0 -22
  73. package/src/components/TagView/index.tsx +0 -39
  74. package/src/components/TagViewHeader/index.tsx +0 -70
  75. package/src/components/TagsPanel/index.tsx +0 -40
  76. package/src/components/TagsVirtualized/index.tsx +0 -160
  77. package/src/components/TextInputNumber/index.tsx +0 -32
  78. package/src/components/TextInputSearch/index.tsx +0 -60
  79. package/src/components/Tool/index.tsx +0 -13
  80. package/src/components/UploadDropzone/UploadDropzone.test.tsx +0 -40
  81. package/src/components/UploadDropzone/index.tsx +0 -173
  82. package/src/config/orders.ts +0 -28
  83. package/src/config/searchFacets.ts +0 -312
  84. package/src/constants.ts +0 -87
  85. package/src/contexts/AssetSourceDispatchContext.tsx +0 -37
  86. package/src/contexts/DropzoneDispatchContext.tsx +0 -34
  87. package/src/contexts/ToolOptionsContext.tsx +0 -65
  88. package/src/formSchema/index.test.ts +0 -56
  89. package/src/formSchema/index.ts +0 -39
  90. package/src/hooks/useBreakpointIndex.ts +0 -49
  91. package/src/hooks/useKeyPress.ts +0 -39
  92. package/src/hooks/useOnScreen.ts +0 -34
  93. package/src/hooks/usePortalPopoverProps.ts +0 -13
  94. package/src/hooks/useTypedSelector.ts +0 -7
  95. package/src/hooks/useVersionedClient.ts +0 -6
  96. package/src/index.ts +0 -5
  97. package/src/modules/assets/actions.ts +0 -42
  98. package/src/modules/assets/deleteAndUpdateEpics.test.ts +0 -87
  99. package/src/modules/assets/fetchEpic.test.ts +0 -73
  100. package/src/modules/assets/index.ts +0 -825
  101. package/src/modules/assets/reducer.test.ts +0 -91
  102. package/src/modules/assets/tagsAndListenerEpics.test.ts +0 -206
  103. package/src/modules/debug/index.ts +0 -28
  104. package/src/modules/dialog/actions.ts +0 -10
  105. package/src/modules/dialog/epics.test.ts +0 -168
  106. package/src/modules/dialog/index.ts +0 -238
  107. package/src/modules/dialog/reducer.test.ts +0 -185
  108. package/src/modules/index.ts +0 -124
  109. package/src/modules/notifications/epics.test.ts +0 -374
  110. package/src/modules/notifications/index.ts +0 -199
  111. package/src/modules/notifications/reducer.test.ts +0 -54
  112. package/src/modules/search/index.test.ts +0 -36
  113. package/src/modules/search/index.ts +0 -167
  114. package/src/modules/selected/index.ts +0 -22
  115. package/src/modules/selectors.test.ts +0 -21
  116. package/src/modules/selectors.ts +0 -17
  117. package/src/modules/tags/epics.test.ts +0 -96
  118. package/src/modules/tags/index.test.ts +0 -42
  119. package/src/modules/tags/index.ts +0 -540
  120. package/src/modules/types.ts +0 -3
  121. package/src/modules/uploads/actions.ts +0 -13
  122. package/src/modules/uploads/epics.test.ts +0 -109
  123. package/src/modules/uploads/index.test.ts +0 -59
  124. package/src/modules/uploads/index.ts +0 -282
  125. package/src/operators/checkTagName.test.ts +0 -29
  126. package/src/operators/checkTagName.ts +0 -33
  127. package/src/operators/debugThrottle.ts +0 -25
  128. package/src/plugin.tsx +0 -54
  129. package/src/schemas/tag.ts +0 -28
  130. package/src/styled/GlobalStyles/index.tsx +0 -40
  131. package/src/styled/react-select/creatable.tsx +0 -184
  132. package/src/styled/react-select/single.tsx +0 -184
  133. package/src/types/index.ts +0 -379
  134. package/src/types/sanity-ui.d.ts +0 -6
  135. package/src/utils/applyMediaTags.ts +0 -87
  136. package/src/utils/blocksToText.test.ts +0 -43
  137. package/src/utils/blocksToText.ts +0 -27
  138. package/src/utils/constructFilter.test.ts +0 -120
  139. package/src/utils/constructFilter.ts +0 -98
  140. package/src/utils/generatePreviewBlobUrl.test.ts +0 -70
  141. package/src/utils/generatePreviewBlobUrl.ts +0 -53
  142. package/src/utils/getAssetResolution.test.ts +0 -13
  143. package/src/utils/getAssetResolution.ts +0 -7
  144. package/src/utils/getDocumentAssetIds.test.ts +0 -50
  145. package/src/utils/getDocumentAssetIds.ts +0 -35
  146. package/src/utils/getSchemeColor.test.ts +0 -12
  147. package/src/utils/getSchemeColor.ts +0 -43
  148. package/src/utils/getTagSelectOptions.test.ts +0 -44
  149. package/src/utils/getTagSelectOptions.ts +0 -16
  150. package/src/utils/getUniqueDocuments.test.ts +0 -26
  151. package/src/utils/getUniqueDocuments.ts +0 -15
  152. package/src/utils/imageDprUrl.test.ts +0 -46
  153. package/src/utils/imageDprUrl.ts +0 -27
  154. package/src/utils/isSupportedAssetType.test.ts +0 -16
  155. package/src/utils/isSupportedAssetType.ts +0 -15
  156. package/src/utils/mediaField.ts +0 -73
  157. package/src/utils/sanitizeFormData.test.ts +0 -59
  158. package/src/utils/sanitizeFormData.ts +0 -26
  159. package/src/utils/typeGuards.test.ts +0 -18
  160. package/src/utils/typeGuards.ts +0 -9
  161. package/src/utils/uploadSanityAsset.test.ts +0 -29
  162. package/src/utils/uploadSanityAsset.ts +0 -97
  163. package/src/utils/withMaxConcurrency.test.ts +0 -43
  164. package/src/utils/withMaxConcurrency.ts +0 -55
  165. package/src/utils/zodFormResolver.ts +0 -17
  166. package/v2-incompatible.js +0 -11
@@ -1,110 +0,0 @@
1
- import {SelectIcon} from '@sanity/icons'
2
- import {Box, Button, Menu, MenuButton, MenuDivider, MenuItem} from '@sanity/ui'
3
- import {useDispatch} from 'react-redux'
4
-
5
- import {operators} from '../../config/searchFacets'
6
- import {usePortalPopoverProps} from '../../hooks/usePortalPopoverProps'
7
- import {searchActions} from '../../modules/search'
8
- import type {
9
- SearchFacetInputSelectListItemProps,
10
- SearchFacetInputSelectProps,
11
- SearchFacetOperatorType,
12
- WithId,
13
- } from '../../types'
14
- import SearchFacet from '../SearchFacet'
15
-
16
- type Props = {
17
- facet: WithId<SearchFacetInputSelectProps>
18
- }
19
-
20
- const SearchFacetSelect = ({facet}: Props) => {
21
- // Redux
22
- const dispatch = useDispatch()
23
-
24
- const popoverProps = usePortalPopoverProps()
25
-
26
- const options = facet?.options
27
-
28
- const selectedItem = options?.find((v) => v.name === facet?.value)
29
-
30
- const handleListItemClick = (option: SearchFacetInputSelectListItemProps) => {
31
- dispatch(searchActions.facetsUpdate({name: facet.name, value: option.name}))
32
- }
33
-
34
- const handleOperatorItemClick = (operatorType: SearchFacetOperatorType) => {
35
- dispatch(searchActions.facetsUpdate({name: facet.name, operatorType}))
36
- }
37
-
38
- const selectedOperatorType: SearchFacetOperatorType = facet?.operatorType ?? 'is'
39
-
40
- return (
41
- <SearchFacet facet={facet}>
42
- {/* Optional operators */}
43
- {facet?.operatorTypes && (
44
- <MenuButton
45
- button={
46
- <Box marginRight={1}>
47
- <Button
48
- fontSize={1}
49
- iconRight={SelectIcon}
50
- padding={2}
51
- text={operators[selectedOperatorType].label}
52
- />
53
- </Box>
54
- }
55
- id="operators"
56
- menu={
57
- <Menu>
58
- {facet.operatorTypes.map((operatorType, index) => {
59
- if (operatorType) {
60
- const selected = operatorType === selectedOperatorType
61
- return (
62
- <MenuItem
63
- disabled={selected}
64
- fontSize={1}
65
- key={operatorType}
66
- onClick={() => handleOperatorItemClick(operatorType)}
67
- padding={2}
68
- text={operators[operatorType].label}
69
- />
70
- )
71
- }
72
-
73
- return <MenuDivider key={index} />
74
- })}
75
- </Menu>
76
- }
77
- popover={popoverProps}
78
- />
79
- )}
80
-
81
- {/* List */}
82
- <MenuButton
83
- button={
84
- <Button fontSize={1} iconRight={SelectIcon} padding={2} text={selectedItem?.title} />
85
- }
86
- id="list"
87
- menu={
88
- <Menu>
89
- {options?.map((item, index) => {
90
- const selected = item.name === selectedItem?.name
91
- return (
92
- <MenuItem
93
- disabled={selected}
94
- fontSize={1}
95
- key={item.name}
96
- onClick={() => handleListItemClick(options[index])}
97
- padding={2}
98
- text={item.title}
99
- />
100
- )
101
- })}
102
- </Menu>
103
- }
104
- popover={popoverProps}
105
- />
106
- </SearchFacet>
107
- )
108
- }
109
-
110
- export default SearchFacetSelect
@@ -1,88 +0,0 @@
1
- import {SelectIcon} from '@sanity/icons'
2
- import {Box, Button, Menu, MenuButton, MenuDivider, MenuItem, TextInput} from '@sanity/ui'
3
- import {type ChangeEvent} from 'react'
4
- import {useDispatch} from 'react-redux'
5
-
6
- import {operators} from '../../config/searchFacets'
7
- import {usePortalPopoverProps} from '../../hooks/usePortalPopoverProps'
8
- import {searchActions} from '../../modules/search'
9
- import type {SearchFacetInputStringProps, SearchFacetOperatorType, WithId} from '../../types'
10
- import SearchFacet from '../SearchFacet'
11
-
12
- type Props = {
13
- facet: WithId<SearchFacetInputStringProps>
14
- }
15
-
16
- const SearchFacetString = ({facet}: Props) => {
17
- // Redux
18
- const dispatch = useDispatch()
19
-
20
- const popoverProps = usePortalPopoverProps()
21
-
22
- const handleOperatorItemClick = (operatorType: SearchFacetOperatorType) => {
23
- dispatch(searchActions.facetsUpdateById({id: facet.id, operatorType}))
24
- }
25
-
26
- const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
27
- dispatch(searchActions.facetsUpdateById({id: facet.id, value: e.target.value}))
28
- }
29
-
30
- const selectedOperatorType: SearchFacetOperatorType = facet.operatorType
31
-
32
- return (
33
- <SearchFacet facet={facet}>
34
- {/* Optional operators */}
35
- {facet?.operatorTypes && (
36
- <MenuButton
37
- button={
38
- <Button
39
- fontSize={1}
40
- iconRight={SelectIcon}
41
- padding={2}
42
- text={operators[selectedOperatorType].label}
43
- />
44
- }
45
- id="operators"
46
- menu={
47
- <Menu>
48
- {facet.operatorTypes.map((operatorType, index) => {
49
- if (operatorType) {
50
- const selected = operatorType === selectedOperatorType
51
- return (
52
- <MenuItem
53
- disabled={selected}
54
- fontSize={1}
55
- key={operatorType}
56
- onClick={() => handleOperatorItemClick(operatorType)}
57
- padding={2}
58
- text={operators[operatorType].label}
59
- />
60
- )
61
- }
62
-
63
- return <MenuDivider key={index} />
64
- })}
65
- </Menu>
66
- }
67
- popover={popoverProps}
68
- />
69
- )}
70
-
71
- {/* Value */}
72
- {!operators[selectedOperatorType].hideInput && (
73
- <Box marginLeft={1} style={{maxWidth: '125px'}}>
74
- <TextInput
75
- fontSize={1}
76
- onChange={handleChange}
77
- padding={2}
78
- radius={2}
79
- width={2}
80
- value={facet?.value}
81
- />
82
- </Box>
83
- )}
84
- </SearchFacet>
85
- )
86
- }
87
-
88
- export default SearchFacetString
@@ -1,121 +0,0 @@
1
- import {SelectIcon} from '@sanity/icons'
2
- import {Box, Button, Menu, MenuButton, MenuDivider, MenuItem} from '@sanity/ui'
3
- import {useDispatch} from 'react-redux'
4
- import Select from 'react-select'
5
- import {useColorSchemeValue} from 'sanity'
6
-
7
- import {operators} from '../../config/searchFacets'
8
- import {usePortalPopoverProps} from '../../hooks/usePortalPopoverProps'
9
- import useTypedSelector from '../../hooks/useTypedSelector'
10
- import {searchActions} from '../../modules/search'
11
- import {selectTags} from '../../modules/tags'
12
- import {reactSelectComponents, reactSelectStyles} from '../../styled/react-select/single'
13
- import type {
14
- TagSelectOption,
15
- SearchFacetInputSearchableProps,
16
- SearchFacetOperatorType,
17
- WithId,
18
- } from '../../types'
19
- import getTagSelectOptions from '../../utils/getTagSelectOptions'
20
- import SearchFacet from '../SearchFacet'
21
-
22
- type Props = {
23
- facet: WithId<SearchFacetInputSearchableProps>
24
- }
25
-
26
- const SearchFacetTags = ({facet}: Props) => {
27
- const scheme = useColorSchemeValue()
28
-
29
- // Redux
30
- const dispatch = useDispatch()
31
- const tags = useTypedSelector((state) => selectTags(state))
32
- const tagsFetching = useTypedSelector((state) => state.tags.fetching)
33
- const allTagOptions = getTagSelectOptions(tags)
34
-
35
- const popoverProps = usePortalPopoverProps()
36
-
37
- const handleChange = (option: TagSelectOption) => {
38
- dispatch(
39
- searchActions.facetsUpdateById({
40
- id: facet.id,
41
- value: option,
42
- }),
43
- )
44
- }
45
-
46
- const handleOperatorItemClick = (operatorType: SearchFacetOperatorType) => {
47
- dispatch(
48
- searchActions.facetsUpdateById({
49
- id: facet.id,
50
- operatorType,
51
- }),
52
- )
53
- }
54
-
55
- const selectedOperatorType: SearchFacetOperatorType = facet.operatorType
56
-
57
- return (
58
- <SearchFacet facet={facet}>
59
- {/* Optional operators */}
60
- {facet?.operatorTypes && (
61
- <MenuButton
62
- button={
63
- <Button
64
- fontSize={1}
65
- iconRight={SelectIcon}
66
- padding={2}
67
- text={operators[selectedOperatorType].label}
68
- />
69
- }
70
- id="operators"
71
- menu={
72
- <Menu>
73
- {facet.operatorTypes.map((operatorType, index) => {
74
- if (operatorType) {
75
- const selected = operatorType === selectedOperatorType
76
- return (
77
- <MenuItem
78
- disabled={selected}
79
- fontSize={1}
80
- key={operatorType}
81
- onClick={() => handleOperatorItemClick(operatorType)}
82
- padding={2}
83
- space={4}
84
- style={{minWidth: '150px'}}
85
- text={operators[operatorType].label}
86
- />
87
- )
88
- }
89
-
90
- return <MenuDivider key={index} />
91
- })}
92
- </Menu>
93
- }
94
- popover={popoverProps}
95
- />
96
- )}
97
-
98
- {/* Value */}
99
- {!operators[selectedOperatorType].hideInput && (
100
- <Box marginX={1} style={{width: '160px'}}>
101
- <Select
102
- components={reactSelectComponents}
103
- instanceId="facet-searchable"
104
- isClearable
105
- isDisabled={tagsFetching}
106
- isSearchable
107
- name="tags"
108
- noOptionsMessage={() => 'No tags'}
109
- onChange={(value: any) => handleChange(value as TagSelectOption)}
110
- options={allTagOptions}
111
- placeholder={tagsFetching ? 'Loading...' : 'Select...'}
112
- styles={reactSelectStyles(scheme)}
113
- value={facet?.value}
114
- />
115
- </Box>
116
- )}
117
- </SearchFacet>
118
- )
119
- }
120
-
121
- export default SearchFacetTags
@@ -1,72 +0,0 @@
1
- import {Box, Flex, Inline, rem, type Theme} from '@sanity/ui'
2
- import {styled, css} from 'styled-components'
3
-
4
- import useTypedSelector from '../../hooks/useTypedSelector'
5
- import SearchFacetNumber from '../SearchFacetNumber'
6
- import SearchFacetSelect from '../SearchFacetSelect'
7
- import SearchFacetString from '../SearchFacetString'
8
- import SearchFacetTags from '../SearchFacetTags'
9
-
10
- type Props = {
11
- layout?: 'inline' | 'stack'
12
- }
13
-
14
- const StackContainer = styled(Flex)(({theme}: {theme: Theme}) => {
15
- return css`
16
- > * {
17
- margin-bottom: ${rem(theme.sanity.space[2])};
18
- }
19
- `
20
- })
21
-
22
- const SearchFacets = (props: Props) => {
23
- const {layout = 'inline'} = props
24
-
25
- // Redux
26
- const searchFacets = useTypedSelector((state) => state.search.facets)
27
-
28
- const Items = searchFacets.map((facet) => {
29
- const key = facet.id
30
- if (facet.type === 'number') {
31
- return <SearchFacetNumber facet={facet} key={key} />
32
- }
33
-
34
- if (facet.type === 'searchable') {
35
- return <SearchFacetTags facet={facet} key={key} />
36
- }
37
-
38
- if (facet.type === 'select') {
39
- return <SearchFacetSelect facet={facet} key={key} />
40
- }
41
-
42
- if (facet.type === 'string') {
43
- return <SearchFacetString facet={facet} key={key} />
44
- }
45
-
46
- return null
47
- })
48
-
49
- if (layout === 'inline') {
50
- if (searchFacets.length === 0) {
51
- return null
52
- }
53
-
54
- return (
55
- <Box marginBottom={2}>
56
- <Inline space={2}>{Items}</Inline>
57
- </Box>
58
- )
59
- }
60
-
61
- if (layout === 'stack') {
62
- return (
63
- <StackContainer align="flex-start" direction="column">
64
- {Items}
65
- </StackContainer>
66
- )
67
- }
68
-
69
- throw Error('Invalid layout')
70
- }
71
-
72
- export default SearchFacets
@@ -1,140 +0,0 @@
1
- import {AddIcon} from '@sanity/icons'
2
- import {Button, Flex, Menu, MenuButton, MenuDivider, MenuGroup, MenuItem} from '@sanity/ui'
3
- import {useDispatch} from 'react-redux'
4
-
5
- import {FACETS} from '../../constants'
6
- import {useToolOptions} from '../../contexts/ToolOptionsContext'
7
- import {usePortalPopoverProps} from '../../hooks/usePortalPopoverProps'
8
- import useTypedSelector from '../../hooks/useTypedSelector'
9
- import {searchActions} from '../../modules/search'
10
- import type {SearchFacetDivider, SearchFacetGroup, SearchFacetInputProps} from '../../types'
11
-
12
- const SearchFacetsControl = () => {
13
- // Redux
14
- const dispatch = useDispatch()
15
- const assetTypes = useTypedSelector((state) => state.assets.assetTypes)
16
- const searchFacets = useTypedSelector((state) => state.search.facets)
17
- const selectedDocument = useTypedSelector((state) => state.selected.document)
18
-
19
- const popoverProps = usePortalPopoverProps()
20
-
21
- const {creditLine} = useToolOptions()
22
-
23
- const isTool = !selectedDocument
24
-
25
- const filteredFacets = FACETS
26
- // Filter facets based on current context, whether it's invoked as a tool, or via selection through via custom asset source.
27
- .filter((facet) => {
28
- // Remove credit line filter if it's not enabled
29
- if (!creditLine?.enabled && facet?.type === 'string' && facet?.name === 'creditLine') {
30
- return false
31
- }
32
-
33
- if (facet.type === 'group' || facet.type === 'divider') {
34
- return true
35
- }
36
-
37
- if (isTool) {
38
- return !facet?.selectOnly
39
- }
40
-
41
- const matchingAssetTypes = facet.assetTypes.filter((assetType) =>
42
- assetTypes.includes(assetType),
43
- )
44
- return matchingAssetTypes.length > 0
45
- })
46
- // Remove adjacent and leading / trailing dividers
47
- .filter((facet, index, facets) => {
48
- const previousFacet = facets[index - 1]
49
- // Ignore leading + trailing dividers
50
- if (facet.type === 'divider' && (index === 0 || index === facets.length - 1)) {
51
- return false
52
- }
53
- // Ignore adjacent dividers
54
- if (facet.type === 'divider' && previousFacet?.type === 'divider') {
55
- return false
56
- }
57
- return true
58
- })
59
-
60
- const hasSearchFacets = filteredFacets.length > 0
61
-
62
- const renderMenuFacets = (
63
- facets: (SearchFacetDivider | SearchFacetGroup | SearchFacetInputProps)[],
64
- level: number = 0,
65
- ) => {
66
- return (
67
- <>
68
- {facets?.map((facet, index) => {
69
- if (facet.type === 'divider') {
70
- return <MenuDivider key={index} />
71
- }
72
-
73
- // Recursively render menu facets
74
- if (facet.type === 'group') {
75
- return (
76
- <MenuGroup key={`group-${level}-${index}`} text={facet.title} title={facet.title}>
77
- {renderMenuFacets(facet.facets, level + 1)}
78
- </MenuGroup>
79
- )
80
- }
81
-
82
- if (facet) {
83
- const disabled =
84
- !facet.operatorTypes && !!searchFacets.find((v) => v.name === facet.name)
85
-
86
- return (
87
- <MenuItem
88
- disabled={disabled}
89
- fontSize={1}
90
- key={facet.name}
91
- onClick={() => dispatch(searchActions.facetsAdd({facet}))}
92
- padding={2}
93
- text={facet.title}
94
- />
95
- )
96
- }
97
-
98
- return null
99
- })}
100
- </>
101
- )
102
- }
103
-
104
- return (
105
- <Flex>
106
- {/* Add filter button */}
107
- <MenuButton
108
- button={
109
- <Button
110
- disabled={!hasSearchFacets}
111
- fontSize={1}
112
- icon={AddIcon}
113
- mode="bleed"
114
- space={2}
115
- text="Add filter"
116
- tone="primary"
117
- />
118
- }
119
- id="facets"
120
- menu={<Menu>{renderMenuFacets(filteredFacets)}</Menu>}
121
- popover={{
122
- ...popoverProps,
123
- placement: 'right-start',
124
- }}
125
- />
126
-
127
- {/* Clear facets button */}
128
- {searchFacets.length > 0 && (
129
- <Button
130
- fontSize={1}
131
- mode="bleed"
132
- onClick={() => dispatch(searchActions.facetsClear())}
133
- text="Clear"
134
- />
135
- )}
136
- </Flex>
137
- )
138
- }
139
-
140
- export default SearchFacetsControl
@@ -1,110 +0,0 @@
1
- import {Checkbox, Flex, Grid, type ThemeColorSchemeKey, useMediaIndex} from '@sanity/ui'
2
- import {type MouseEvent} from 'react'
3
- import {useDispatch} from 'react-redux'
4
- import {useColorSchemeValue} from 'sanity'
5
- import {styled, css} from 'styled-components'
6
-
7
- import {GRID_TEMPLATE_COLUMNS, PANEL_HEIGHT} from '../../constants'
8
- import {useAssetSourceActions} from '../../contexts/AssetSourceDispatchContext'
9
- import useTypedSelector from '../../hooks/useTypedSelector'
10
- import {assetsActions, selectAssetsLength, selectAssetsPickedLength} from '../../modules/assets'
11
- import {getSchemeColor} from '../../utils/getSchemeColor'
12
- import TableHeaderItem from '../TableHeaderItem'
13
-
14
- // TODO: DRY
15
- const ContextActionContainer = styled<typeof Flex, {$scheme: ThemeColorSchemeKey}>(Flex)(({
16
- $scheme,
17
- }) => {
18
- return css`
19
- cursor: pointer;
20
- @media (hover: hover) and (pointer: fine) {
21
- &:hover {
22
- background: ${getSchemeColor($scheme, 'bg')};
23
- }
24
- }
25
- `
26
- })
27
-
28
- const TableHeader = () => {
29
- const scheme = useColorSchemeValue()
30
-
31
- // Redux
32
- const dispatch = useDispatch()
33
- const fetching = useTypedSelector((state) => state.assets.fetching)
34
- const itemsLength = useTypedSelector(selectAssetsLength)
35
- const numPickedAssets = useTypedSelector(selectAssetsPickedLength)
36
-
37
- const mediaIndex = useMediaIndex()
38
- const {onSelect} = useAssetSourceActions()
39
-
40
- const allSelected = numPickedAssets === itemsLength
41
-
42
- // Callbacks
43
- const handleContextActionClick = (e: MouseEvent) => {
44
- e.stopPropagation()
45
-
46
- if (allSelected) {
47
- dispatch(assetsActions.pickClear())
48
- } else {
49
- dispatch(assetsActions.pickAll())
50
- }
51
- }
52
-
53
- // Note that even though we hide the table header on smaller breakpoints, we never set it to
54
- // `display: none`, as doing so causes issues with react-virtuoso.
55
- // Instead, we give it 0 height and hide it with `visibility: hidden`.
56
- return (
57
- <Grid
58
- style={{
59
- alignItems: 'center',
60
- background: 'var(--card-bg-color)',
61
- borderBottom: '1px solid var(--card-border-color)',
62
- gridColumnGap: mediaIndex < 3 ? 0 : '16px',
63
- gridTemplateColumns: GRID_TEMPLATE_COLUMNS.LARGE,
64
- height: mediaIndex < 3 ? 0 : `${PANEL_HEIGHT}px`,
65
- letterSpacing: '0.025em',
66
- position: 'sticky',
67
- textTransform: 'uppercase',
68
- top: 0,
69
- visibility: mediaIndex < 3 ? 'hidden' : 'visible',
70
- width: '100%',
71
- zIndex: 1, // force stacking context
72
- }}
73
- >
74
- {onSelect ? (
75
- <TableHeaderItem />
76
- ) : (
77
- <ContextActionContainer
78
- align="center"
79
- justify="center"
80
- onClick={handleContextActionClick}
81
- $scheme={scheme}
82
- style={{
83
- height: '100%',
84
- position: 'relative',
85
- }}
86
- >
87
- <Checkbox
88
- checked={!fetching && allSelected}
89
- readOnly
90
- style={{
91
- pointerEvents: 'none', // TODO: consider alternative for usability
92
- transform: 'scale(0.8)',
93
- }}
94
- />
95
- </ContextActionContainer>
96
- )}
97
-
98
- <TableHeaderItem />
99
- <TableHeaderItem field="originalFilename" title="Filename" />
100
- <TableHeaderItem title="Resolution" />
101
- <TableHeaderItem field="mimeType" title="MIME type" />
102
- <TableHeaderItem field="size" title="Size" />
103
- <TableHeaderItem field="_updatedAt" title="Last updated" />
104
- <TableHeaderItem title="References" />
105
- <TableHeaderItem />
106
- </Grid>
107
- )
108
- }
109
-
110
- export default TableHeader
@@ -1,61 +0,0 @@
1
- import {ChevronDownIcon, ChevronUpIcon} from '@sanity/icons'
2
- import {Box, Label} from '@sanity/ui'
3
- import {useDispatch} from 'react-redux'
4
-
5
- import useTypedSelector from '../../hooks/useTypedSelector'
6
- import {assetsActions} from '../../modules/assets'
7
-
8
- type Props = {
9
- field?: string
10
- title?: string
11
- }
12
-
13
- const TableHeaderItem = (props: Props) => {
14
- const {field, title} = props
15
-
16
- // Redux
17
- const dispatch = useDispatch()
18
- const order = useTypedSelector((state) => state.assets.order)
19
-
20
- const isActive = order.field === field
21
-
22
- // Callbacks
23
- const handleClick = () => {
24
- if (!field || !title) {
25
- return
26
- }
27
-
28
- if (isActive) {
29
- const direction = order.direction === 'asc' ? 'desc' : 'asc'
30
- dispatch(assetsActions.orderSet({order: {field, direction}}))
31
- } else {
32
- dispatch(assetsActions.orderSet({order: {field, direction: 'asc'}}))
33
- }
34
- }
35
-
36
- return (
37
- <Label muted={!field} size={0}>
38
- <Box
39
- onClick={field ? handleClick : undefined}
40
- style={{
41
- cursor: field ? 'pointer' : 'default',
42
- display: 'inline',
43
- whiteSpace: 'nowrap',
44
- }}
45
- >
46
- <span
47
- style={{
48
- marginRight: '0.4em',
49
- }}
50
- >
51
- {title}
52
- </span>
53
-
54
- {isActive && order?.direction === 'asc' && <ChevronUpIcon />}
55
- {isActive && order?.direction === 'desc' && <ChevronDownIcon />}
56
- </Box>
57
- </Label>
58
- )
59
- }
60
-
61
- export default TableHeaderItem