2023-11-28 13:18:25 +00:00
|
|
|
import type { Topic } from '../../../graphql/schema/core.gen'
|
2023-11-14 15:10:00 +00:00
|
|
|
|
2023-03-23 17:15:50 +00:00
|
|
|
import { createOptions, Select } from '@thisbeyond/solid-select'
|
2023-11-14 15:10:00 +00:00
|
|
|
import { clsx } from 'clsx'
|
|
|
|
import { createSignal } from 'solid-js'
|
|
|
|
|
2023-03-23 17:15:50 +00:00
|
|
|
import { useLocalize } from '../../../context/localize'
|
2023-11-14 15:10:00 +00:00
|
|
|
import { clone } from '../../../utils/clone'
|
|
|
|
import { slugify } from '../../../utils/slugify'
|
|
|
|
|
2023-03-23 17:15:50 +00:00
|
|
|
import '@thisbeyond/solid-select/style.css'
|
2023-03-23 17:47:36 +00:00
|
|
|
import './TopicSelect.scss'
|
2023-11-14 15:10:00 +00:00
|
|
|
|
2023-05-10 20:20:53 +00:00
|
|
|
import styles from './TopicSelect.module.scss'
|
2023-03-23 17:15:50 +00:00
|
|
|
|
|
|
|
type TopicSelectProps = {
|
|
|
|
topics: Topic[]
|
2023-03-23 17:47:36 +00:00
|
|
|
selectedTopics: Topic[]
|
2023-03-23 17:15:50 +00:00
|
|
|
onChange: (selectedTopics: Topic[]) => void
|
2023-05-10 20:20:53 +00:00
|
|
|
mainTopic?: Topic
|
|
|
|
onMainTopicChange: (mainTopic: Topic) => void
|
2023-03-23 17:15:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export const TopicSelect = (props: TopicSelectProps) => {
|
|
|
|
const { t } = useLocalize()
|
|
|
|
|
2023-05-10 20:20:53 +00:00
|
|
|
const [isDisabled, setIsDisabled] = createSignal(false)
|
|
|
|
|
|
|
|
const createValue = (title): Topic => {
|
|
|
|
const minId = Math.min(...props.selectedTopics.map((topic) => topic.id))
|
|
|
|
const id = minId < 0 ? minId - 1 : -2
|
|
|
|
return { id, title, slug: slugify(title) }
|
|
|
|
}
|
|
|
|
|
2023-03-23 17:47:36 +00:00
|
|
|
const selectProps = createOptions(props.topics, {
|
|
|
|
key: 'title',
|
|
|
|
disable: (topic) => {
|
2023-03-24 13:39:52 +00:00
|
|
|
return props.selectedTopics.some((selectedTopic) => selectedTopic.slug === topic.slug)
|
2023-05-10 20:20:53 +00:00
|
|
|
},
|
2023-11-14 15:10:00 +00:00
|
|
|
createable: createValue,
|
2023-03-23 17:47:36 +00:00
|
|
|
})
|
2023-03-23 17:15:50 +00:00
|
|
|
|
|
|
|
const handleChange = (selectedTopics: Topic[]) => {
|
|
|
|
props.onChange(selectedTopics)
|
|
|
|
}
|
|
|
|
|
2023-05-10 20:20:53 +00:00
|
|
|
const handleSelectedItemClick = (topic: Topic) => {
|
|
|
|
setIsDisabled(true)
|
|
|
|
props.onMainTopicChange(topic)
|
|
|
|
setIsDisabled(false)
|
|
|
|
}
|
|
|
|
|
|
|
|
const format = (item, type) => {
|
|
|
|
if (type === 'option') {
|
2023-05-11 18:34:04 +00:00
|
|
|
// eslint-disable-next-line solid/components-return-once
|
2023-05-10 20:20:53 +00:00
|
|
|
return item.label
|
|
|
|
}
|
|
|
|
|
2024-01-23 19:01:41 +00:00
|
|
|
const isMainTopic = item.id === props.mainTopic?.id
|
2023-05-10 20:20:53 +00:00
|
|
|
|
|
|
|
return (
|
|
|
|
<div
|
|
|
|
class={clsx(styles.selectedItem, {
|
2023-11-14 15:10:00 +00:00
|
|
|
[styles.mainTopic]: isMainTopic,
|
2023-05-10 20:20:53 +00:00
|
|
|
})}
|
|
|
|
onClick={() => handleSelectedItemClick(item)}
|
|
|
|
>
|
|
|
|
{item.title}
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2023-05-11 11:06:29 +00:00
|
|
|
const initialValue = clone(props.selectedTopics)
|
|
|
|
|
2023-03-23 17:47:36 +00:00
|
|
|
return (
|
|
|
|
<Select
|
|
|
|
multiple={true}
|
2023-05-10 20:20:53 +00:00
|
|
|
disabled={isDisabled()}
|
2023-05-11 11:06:29 +00:00
|
|
|
initialValue={initialValue}
|
2023-03-23 17:47:36 +00:00
|
|
|
{...selectProps}
|
2023-05-10 20:20:53 +00:00
|
|
|
format={format}
|
2023-03-23 17:47:36 +00:00
|
|
|
placeholder={t('Topics')}
|
|
|
|
class="TopicSelect"
|
|
|
|
onChange={handleChange}
|
|
|
|
/>
|
|
|
|
)
|
2023-03-23 17:15:50 +00:00
|
|
|
}
|