Skip to content

Commit

Permalink
feat: add support for multiple tags
Browse files Browse the repository at this point in the history
Co-authored-by: Noah Gentile <[email protected]>
  • Loading branch information
robinpyon and nkgentile committed Jul 3, 2023
1 parent cb7983c commit 5f5bea8
Show file tree
Hide file tree
Showing 13 changed files with 118 additions and 75 deletions.
13 changes: 4 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"@reduxjs/toolkit": "^1.9.0",
"@sanity/incompatible-plugin": "^1.0.4",
"@sanity/ui": "^1.7.0",
"@sanity/uuid": "^3.0.1",
"@tanem/react-nprogress": "^5.0.0",
"copy-to-clipboard": "^3.3.1",
"date-fns": "^2.27.0",
Expand Down
6 changes: 3 additions & 3 deletions src/components/SearchFacet/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import {CloseIcon} from '@sanity/icons'
import {Box, Flex, Label, Text} from '@sanity/ui'
import {SearchFacetInputProps} from '@types'
import {SearchFacetInputProps, WithId} from '@types'
import React, {ReactNode} from 'react'
import {useDispatch} from 'react-redux'
import styled from 'styled-components'
import {searchActions} from '../../modules/search'

type Props = {
children: ReactNode
facet: SearchFacetInputProps
facet: WithId<SearchFacetInputProps>
}

const Container = styled(Box)`
Expand All @@ -23,7 +23,7 @@ const SearchFacet = (props: Props) => {
const dispatch = useDispatch()

const handleClose = () => {
dispatch(searchActions.facetsRemove({facetName: facet.name}))
dispatch(searchActions.facetsRemoveById({facetId: facet.id}))
}

return (
Expand Down
11 changes: 6 additions & 5 deletions src/components/SearchFacetNumber/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import {Box, Button, Menu, MenuButton, MenuDivider, MenuItem} from '@sanity/ui'
import {
SearchFacetInputNumberModifier,
SearchFacetInputNumberProps,
SearchFacetOperatorType
SearchFacetOperatorType,
WithId
} from '@types'
import React from 'react'
import {useDispatch} from 'react-redux'
Expand All @@ -14,7 +15,7 @@ import SearchFacet from '../SearchFacet'
import TextInputNumber from '../TextInputNumber'

type Props = {
facet: SearchFacetInputNumberProps
facet: WithId<SearchFacetInputNumberProps>
}

const SearchFacetNumber = ({facet}: Props) => {
Expand All @@ -29,15 +30,15 @@ const SearchFacetNumber = ({facet}: Props) => {
: modifiers?.[0]

const handleOperatorItemClick = (operatorType: SearchFacetOperatorType) => {
dispatch(searchActions.facetsUpdate({name: facet.name, operatorType}))
dispatch(searchActions.facetsUpdateById({id: facet.id, operatorType}))
}

const handleModifierClick = (modifier: SearchFacetInputNumberModifier) => {
dispatch(searchActions.facetsUpdate({name: facet.name, modifier: modifier.name}))
dispatch(searchActions.facetsUpdateById({id: facet.id, modifier: modifier.name}))
}

const handleValueChange = (value: number) => {
dispatch(searchActions.facetsUpdate({name: facet.name, value}))
dispatch(searchActions.facetsUpdateById({id: facet.id, value}))
}

const selectedOperatorType: SearchFacetOperatorType = facet.operatorType ?? 'greaterThan'
Expand Down
5 changes: 3 additions & 2 deletions src/components/SearchFacetSelect/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import {Button, Menu, MenuButton, MenuDivider, MenuItem} from '@sanity/ui'
import {
SearchFacetInputSelectListItemProps,
SearchFacetInputSelectProps,
SearchFacetOperatorType
SearchFacetOperatorType,
WithId
} from '@types'
import React from 'react'
import {useDispatch} from 'react-redux'
Expand All @@ -14,7 +15,7 @@ import SearchFacet from '../SearchFacet'
import {usePortalPopoverProps} from '../../hooks/usePortalPopoverProps'

type Props = {
facet: SearchFacetInputSelectProps
facet: WithId<SearchFacetInputSelectProps>
}

const SearchFacetSelect = ({facet}: Props) => {
Expand Down
8 changes: 4 additions & 4 deletions src/components/SearchFacetString/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {SelectIcon} from '@sanity/icons'
import {Box, Button, Menu, MenuButton, MenuDivider, MenuItem, TextInput} from '@sanity/ui'
import {SearchFacetInputStringProps, SearchFacetOperatorType} from '@types'
import {SearchFacetInputStringProps, SearchFacetOperatorType, WithId} from '@types'
import React, {ChangeEvent} from 'react'
import {useDispatch} from 'react-redux'

Expand All @@ -10,7 +10,7 @@ import {searchActions} from '../../modules/search'
import SearchFacet from '../SearchFacet'

type Props = {
facet: SearchFacetInputStringProps
facet: WithId<SearchFacetInputStringProps>
}

const SearchFacetString = ({facet}: Props) => {
Expand All @@ -20,11 +20,11 @@ const SearchFacetString = ({facet}: Props) => {
const popoverProps = usePortalPopoverProps()

const handleOperatorItemClick = (operatorType: SearchFacetOperatorType) => {
dispatch(searchActions.facetsUpdate({name: facet.name, operatorType}))
dispatch(searchActions.facetsUpdateById({id: facet.id, operatorType}))
}

const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
dispatch(searchActions.facetsUpdate({name: facet.name, value: e.target.value}))
dispatch(searchActions.facetsUpdateById({id: facet.id, value: e.target.value}))
}

const selectedOperatorType: SearchFacetOperatorType = facet.operatorType
Expand Down
17 changes: 11 additions & 6 deletions src/components/SearchFacetTags/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import {SelectIcon} from '@sanity/icons'
import {Box, Button, Menu, MenuButton, MenuDivider, MenuItem} from '@sanity/ui'
import {ReactSelectOption, SearchFacetInputSearchableProps, SearchFacetOperatorType} from '@types'
import {
ReactSelectOption,
SearchFacetInputSearchableProps,
SearchFacetOperatorType,
WithId
} from '@types'
import React from 'react'
import {useDispatch} from 'react-redux'
import Select from 'react-select'
Expand All @@ -14,7 +19,7 @@ import getTagSelectOptions from '../../utils/getTagSelectOptions'
import SearchFacet from '../SearchFacet'

type Props = {
facet: SearchFacetInputSearchableProps
facet: WithId<SearchFacetInputSearchableProps>
}

const SearchFacetTags = ({facet}: Props) => {
Expand All @@ -28,17 +33,17 @@ const SearchFacetTags = ({facet}: Props) => {

const handleChange = (option: ReactSelectOption) => {
dispatch(
searchActions.facetsUpdate({
name: facet.name,
searchActions.facetsUpdateById({
id: facet.id,
value: option
})
)
}

const handleOperatorItemClick = (operatorType: SearchFacetOperatorType) => {
dispatch(
searchActions.facetsUpdate({
name: facet.name,
searchActions.facetsUpdateById({
id: facet.id,
operatorType
})
)
Expand Down
9 changes: 5 additions & 4 deletions src/components/SearchFacets/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,21 @@ const SearchFacets = (props: Props) => {
const searchFacets = useTypedSelector(state => state.search.facets)

const Items = searchFacets.map(facet => {
const key = facet.id
if (facet.type === 'number') {
return <SearchFacetNumber facet={facet} key={facet.name} />
return <SearchFacetNumber facet={facet} key={key} />
}

if (facet.type === 'searchable') {
return <SearchFacetTags facet={facet} key={facet.name} />
return <SearchFacetTags facet={facet} key={key} />
}

if (facet.type === 'select') {
return <SearchFacetSelect facet={facet} key={facet.name} />
return <SearchFacetSelect facet={facet} key={key} />
}

if (facet.type === 'string') {
return <SearchFacetString facet={facet} key={facet.name} />
return <SearchFacetString facet={facet} key={key} />
}

return null
Expand Down
11 changes: 4 additions & 7 deletions src/components/SearchFacetsControl/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,7 @@ const SearchFacetsControl = () => {
return true
})

// Determine if there are any remaining un-selected facets
// (This operates under the assumption that only one of each facet can be active at any given time)
const hasRemainingSearchFacets =
filteredFacets.filter(facet => facet).length - searchFacets.length > 0
const hasSearchFacets = filteredFacets.length > 0

const renderMenuFacets = (
facets: (SearchFacetDivider | SearchFacetGroup | SearchFacetInputProps)[],
Expand All @@ -75,11 +72,11 @@ const SearchFacetsControl = () => {
}

if (facet) {
const isPresent = !!searchFacets.find(v => v.name === facet.name)
const disabled = !facet.operatorTypes && !!searchFacets.find(v => v.name === facet.name)

return (
<MenuItem
disabled={isPresent}
disabled={disabled}
fontSize={1}
key={facet.name}
onClick={() => dispatch(searchActions.facetsAdd({facet}))}
Expand All @@ -101,7 +98,7 @@ const SearchFacetsControl = () => {
<MenuButton
button={
<Button
disabled={!hasRemainingSearchFacets}
disabled={!hasSearchFacets}
fontSize={1}
icon={AddCircleIcon}
mode="bleed"
Expand Down
7 changes: 3 additions & 4 deletions src/components/Tag/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import useTypedSelector from '../../hooks/useTypedSelector'
import {selectAssetsPicked} from '../../modules/assets'
import {dialogActions} from '../../modules/dialog'
import {DIALOG_ACTIONS} from '../../modules/dialog/actions'
import {searchActions, selectHasSearchFacetTag, selectIsSearchFacetTag} from '../../modules/search'
import {searchActions, selectIsSearchFacetTag} from '../../modules/search'

type Props = {
actions?: TagActions[]
Expand Down Expand Up @@ -77,12 +77,11 @@ const Tag = (props: Props) => {
// Redux
const dispatch = useDispatch()
const assetsPicked = useTypedSelector(selectAssetsPicked)
const hasSearchFacetTag = useTypedSelector(selectHasSearchFacetTag)
const isSearchFacetTag = useTypedSelector(state => selectIsSearchFacetTag(state, tag?.tag?._id))

// Callbacks
const handleSearchFacetTagRemove = () => {
dispatch(searchActions.facetsRemove({facetName: 'tag'}))
dispatch(searchActions.facetsRemoveByTag({tagId: tag.tag._id}))
}

const handleShowAddTagToAssetsDialog = () => {
Expand Down Expand Up @@ -110,7 +109,7 @@ const Tag = (props: Props) => {
}
} as SearchFacetInputSearchableProps

if (hasSearchFacetTag) {
if (isSearchFacetTag) {
dispatch(
searchActions.facetsUpdate({
name: 'tag',
Expand Down
10 changes: 8 additions & 2 deletions src/modules/assets/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -575,8 +575,11 @@ export const assetsSearchEpic: MyEpic = action$ =>
ofType(
searchActions.facetsAdd.type,
searchActions.facetsClear.type,
searchActions.facetsRemove.type,
searchActions.facetsRemoveById.type,
searchActions.facetsRemoveByName.type,
searchActions.facetsRemoveByTag.type,
searchActions.facetsUpdate.type,
searchActions.facetsUpdateById.type,
searchActions.querySet.type
),
debounceTime(400),
Expand Down Expand Up @@ -723,8 +726,11 @@ export const assetsUnpickEpic: MyEpic = action$ =>
assetsActions.viewSet.type,
searchActions.facetsAdd.type,
searchActions.facetsClear.type,
searchActions.facetsRemove.type,
searchActions.facetsRemoveById.type,
searchActions.facetsRemoveByName.type,
searchActions.facetsRemoveByTag.type,
searchActions.facetsUpdate.type,
searchActions.facetsUpdateById.type,
searchActions.querySet.type
),
mergeMap(() => {
Expand Down
Loading

0 comments on commit 5f5bea8

Please sign in to comment.