import { Messenger } from '@estruyf/vscode/dist/client'; import { ExclamationTriangleIcon, PlusIcon, TagIcon } from '@heroicons/react/24/outline'; import * as React from 'react'; import { useMemo } from 'react'; import { useRecoilValue } from 'recoil'; import { TaxonomyData } from '../../../models'; import { DashboardMessage } from '../../DashboardMessage'; import { Page } from '../../models'; import { SettingsSelector } from '../../state'; import { getTaxonomyField } from '../../../helpers/getTaxonomyField'; import { TaxonomyActions } from './TaxonomyActions'; import { TaxonomyLookup } from './TaxonomyLookup'; import * as l10n from '@vscode/l10n'; import { LocalizationKey } from '../../../localization'; import { FilterInput } from './FilterInput'; import { useDebounce } from '../../../hooks/useDebounce'; import { usePrevious } from '../../../panelWebView/hooks/usePrevious'; export interface ITaxonomyManagerProps { data: TaxonomyData | undefined; taxonomy: string | null; pages: Page[]; onContentTagging: (value: string) => void; } export const TaxonomyManager: React.FunctionComponent = ({ data, taxonomy, pages, onContentTagging }: React.PropsWithChildren) => { const settings = useRecoilValue(SettingsSelector); const [filterValue, setFilterValue] = React.useState(''); const debounceFilterValue = useDebounce(filterValue, 500); const prevTaxonomy = usePrevious(taxonomy); const onCreate = () => { Messenger.send(DashboardMessage.createTaxonomy, { type: taxonomy }); }; const items = useMemo(() => { if (data && taxonomy) { let crntItems: string[] = []; if (taxonomy === 'tags' || taxonomy === 'categories') { crntItems = data[taxonomy]; } else { crntItems = data.customTaxonomy.find((c) => c.id === taxonomy)?.options || []; } // Only allow string values crntItems = crntItems.filter((i) => typeof i === 'string'); // Alphabetically sort the items crntItems = Object.assign([], crntItems).sort((a: string, b: string) => { a = a || ''; b = b || ''; if (a.toLowerCase() < b.toLowerCase()) { return -1; } if (a.toLowerCase() > b.toLowerCase()) { return 1; } return 0; }); if (debounceFilterValue) { crntItems = crntItems.filter((i) => i.toLowerCase().includes(debounceFilterValue.toLowerCase())); } return crntItems.filter(i => i); } return []; }, [data, taxonomy, debounceFilterValue]); const unmappedItems = useMemo(() => { let unmapped: string[] = []; if (!pages || !settings?.contentTypes || !taxonomy) { return unmapped; } for (const page of pages) { let values: string[] = []; if (taxonomy === 'tags') { values = page.fmTags || []; } else if (taxonomy === 'categories') { values = page.fmCategories || []; } else { const contentType = settings.contentTypes.find((ct) => ct.name === page.fmContentType); if (!contentType) { return false; } let fieldName = getTaxonomyField(taxonomy, contentType); if (fieldName && page[fieldName]) { values = page[fieldName]; } } if (typeof values === 'string') { values = [values]; } for (const value of values) { if (!items.includes(value)) { unmapped.push(value); } } } const unmappedItems = [...new Set(unmapped)].filter(i => i); if (debounceFilterValue) { return unmappedItems.filter((i) => i.toLowerCase().includes(debounceFilterValue.toLowerCase())); } return unmappedItems; }, [items, taxonomy, pages, settings?.contentTypes, debounceFilterValue]); React.useEffect(() => { if (prevTaxonomy !== taxonomy) { setFilterValue(''); } }, [prevTaxonomy, taxonomy]) if (!taxonomy) { return null; } return (

{taxonomy}

{l10n.t(LocalizationKey.dashboardTaxonomyViewTaxonomyManagerDescription, taxonomy)}

setFilterValue(value)} onReset={() => setFilterValue('')} />
{items && items.length > 0 ? items.map((item, index) => ( )) : !unmappedItems || (unmappedItems.length === 0 && ( ))} {unmappedItems && unmappedItems.length > 0 && unmappedItems.map((item, index) => ( ))}
{l10n.t(LocalizationKey.dashboardTaxonomyViewTaxonomyManagerTableHeadingName)} {l10n.t(LocalizationKey.dashboardTaxonomyViewTaxonomyManagerTableHeadingCount)} {l10n.t(LocalizationKey.dashboardTaxonomyViewTaxonomyManagerTableHeadingAction)}
{item}
{l10n.t(LocalizationKey.dashboardTaxonomyViewTaxonomyManagerTableRowEmpty, taxonomy)}
{item}
); };