feat(category): check if user defined already exists, remove duplicates
This commit is contained in:
parent
f7f8778707
commit
b9d6820405
@ -1,10 +1,11 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import React, { useEffect, useMemo, useState } from 'react'
|
||||
import { createPortal } from 'react-dom'
|
||||
import { Category } from 'types'
|
||||
import {
|
||||
addToUserCategories,
|
||||
capitalizeEachWord,
|
||||
deleteFromUserCategories
|
||||
deleteFromUserCategories,
|
||||
flattenCategories
|
||||
} from 'utils'
|
||||
import { useLocalStorage } from 'hooks'
|
||||
import styles from './CategoryFilterPopup.module.scss'
|
||||
@ -35,6 +36,21 @@ export const CategoryFilterPopup = ({
|
||||
setHierarchies(filterHierarchies)
|
||||
}
|
||||
const [inputValue, setInputValue] = useState<string>('')
|
||||
const userHierarchiesMatching = useMemo(
|
||||
() =>
|
||||
flattenCategories(userHierarchies, []).some((h) =>
|
||||
h.hierarchy.includes(inputValue.toLowerCase())
|
||||
),
|
||||
[inputValue, userHierarchies]
|
||||
)
|
||||
const hierarchiesMatching = useMemo(
|
||||
() =>
|
||||
flattenCategories(categoriesData, []).some((h) =>
|
||||
h.hierarchy.includes(inputValue.toLowerCase())
|
||||
),
|
||||
[inputValue]
|
||||
)
|
||||
|
||||
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setInputValue(e.target.value)
|
||||
}
|
||||
@ -75,13 +91,14 @@ export const CategoryFilterPopup = ({
|
||||
const path = values.join(':')
|
||||
|
||||
// Add new hierarchy to current selection and active selection
|
||||
// Convert through set to remove duplicates
|
||||
setFilterHierarchies((prev) => {
|
||||
prev.push(path)
|
||||
return [...prev]
|
||||
return Array.from(new Set([...prev]))
|
||||
})
|
||||
setHierarchies((prev) => {
|
||||
prev.push(path)
|
||||
return [...prev]
|
||||
return Array.from(new Set([...prev]))
|
||||
})
|
||||
setInputValue('')
|
||||
}
|
||||
@ -149,6 +166,7 @@ export const CategoryFilterPopup = ({
|
||||
overflow: 'auto'
|
||||
}}
|
||||
>
|
||||
{!userHierarchiesMatching && <div>No results.</div>}
|
||||
{userHierarchies
|
||||
.filter((c) => typeof c !== 'string')
|
||||
.map((c, i) => (
|
||||
@ -187,6 +205,15 @@ export const CategoryFilterPopup = ({
|
||||
</>
|
||||
)}
|
||||
<div className='inputLabelWrapperMain'>
|
||||
<div className='inputLabelWrapperMain'>
|
||||
<label
|
||||
className='form-label labelMain'
|
||||
style={{ fontWeight: 'bold' }}
|
||||
>
|
||||
Categories
|
||||
</label>
|
||||
<p className='labelDescriptionMain'>Maybe</p>
|
||||
</div>
|
||||
<div
|
||||
className='inputMain'
|
||||
style={{
|
||||
@ -199,27 +226,31 @@ export const CategoryFilterPopup = ({
|
||||
<div className={`${styles.noResult}`}>
|
||||
<div>No results.</div>
|
||||
<br />
|
||||
<div
|
||||
className='dropdown-item dropdownMainMenuItem'
|
||||
onClick={handleAddNew}
|
||||
>
|
||||
Add and search for "{inputValue}" category
|
||||
<button
|
||||
type='button'
|
||||
className='btn btnMain btnMainInsideField btnMainAdd'
|
||||
title='Add'
|
||||
{userHierarchiesMatching ? (
|
||||
<div>Already defined in your categories</div>
|
||||
) : (
|
||||
<div
|
||||
className='dropdown-item dropdownMainMenuItem'
|
||||
onClick={handleAddNew}
|
||||
>
|
||||
<svg
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
viewBox='-32 0 512 512'
|
||||
width='1em'
|
||||
height='1em'
|
||||
fill='currentColor'
|
||||
Add and search for "{inputValue}" category
|
||||
<button
|
||||
type='button'
|
||||
className='btn btnMain btnMainInsideField btnMainAdd'
|
||||
title='Add'
|
||||
>
|
||||
<path d='M432 256c0 17.69-14.33 32.01-32 32.01H256v144c0 17.69-14.33 31.99-32 31.99s-32-14.3-32-31.99v-144H48c-17.67 0-32-14.32-32-32.01s14.33-31.99 32-31.99H192v-144c0-17.69 14.33-32.01 32-32.01s32 14.32 32 32.01v144h144C417.7 224 432 238.3 432 256z'></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<svg
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
viewBox='-32 0 512 512'
|
||||
width='1em'
|
||||
height='1em'
|
||||
fill='currentColor'
|
||||
>
|
||||
<path d='M432 256c0 17.69-14.33 32.01-32 32.01H256v144c0 17.69-14.33 31.99-32 31.99s-32-14.3-32-31.99v-144H48c-17.67 0-32-14.32-32-32.01s14.33-31.99 32-31.99H192v-144c0-17.69 14.33-32.01 32-32.01s32 14.32 32 32.01v144h144C417.7 224 432 238.3 432 256z'></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{(categoriesData as Category[]).map((category, i) => (
|
||||
<CategoryCheckbox
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Categories, Category } from 'types/category'
|
||||
import categoriesData from './../assets/categories/categories.json'
|
||||
|
||||
const flattenCategories = (
|
||||
export const flattenCategories = (
|
||||
categories: (Category | string)[],
|
||||
parentPath: string[] = []
|
||||
): Categories[] => {
|
||||
@ -26,16 +26,6 @@ export const getCategories = () => {
|
||||
return flattenCategories(categoriesData)
|
||||
}
|
||||
|
||||
export const buildCategories = (input: string[]) => {
|
||||
const categories: (string | Category)[] = []
|
||||
|
||||
input.forEach((cat) => {
|
||||
addToUserCategories(categories, cat)
|
||||
})
|
||||
|
||||
return categories
|
||||
}
|
||||
|
||||
export const addToUserCategories = (
|
||||
categories: (string | Category)[],
|
||||
input: string
|
||||
|
Loading…
x
Reference in New Issue
Block a user