diff --git a/src/renderer/features/shared/components/list-config-menu.tsx b/src/renderer/features/shared/components/list-config-menu.tsx index 2264a501d..89dfe25fa 100644 --- a/src/renderer/features/shared/components/list-config-menu.tsx +++ b/src/renderer/features/shared/components/list-config-menu.tsx @@ -152,7 +152,7 @@ export const ListConfigTable = ({ {options.map((option) => ( {option.label} - {option.component} + {option.component} ))} diff --git a/src/renderer/features/shared/components/table-config.module.css b/src/renderer/features/shared/components/table-config.module.css index cbb5e5552..fdae7c68c 100644 --- a/src/renderer/features/shared/components/table-config.module.css +++ b/src/renderer/features/shared/components/table-config.module.css @@ -15,4 +15,12 @@ align-items: center; justify-content: space-between; width: 100%; + padding: var(--theme-spacing-xs); + border-radius: var(--theme-radius-sm); + transition: outline 0.2s ease; +} + +.item.matched { + outline: 2px solid var(--theme-colors-primary); + outline-offset: 2px; } diff --git a/src/renderer/features/shared/components/table-config.tsx b/src/renderer/features/shared/components/table-config.tsx index f3301751a..637a02510 100644 --- a/src/renderer/features/shared/components/table-config.tsx +++ b/src/renderer/features/shared/components/table-config.tsx @@ -1,4 +1,6 @@ +import { useDebouncedState } from '@mantine/hooks'; import clsx from 'clsx'; +import Fuse from 'fuse.js'; import { motion } from 'motion/react'; import { useCallback, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; @@ -14,11 +16,14 @@ import { DataListProps, useSettingsStore, useSettingsStoreActions } from '/@/ren import { ActionIcon, ActionIconGroup } from '/@/shared/components/action-icon/action-icon'; import { Badge } from '/@/shared/components/badge/badge'; import { Checkbox } from '/@/shared/components/checkbox/checkbox'; +import { Divider } from '/@/shared/components/divider/divider'; import { Group } from '/@/shared/components/group/group'; import { NumberInput } from '/@/shared/components/number-input/number-input'; import { SegmentedControl } from '/@/shared/components/segmented-control/segmented-control'; import { Slider } from '/@/shared/components/slider/slider'; import { Stack } from '/@/shared/components/stack/stack'; +import { TextInput } from '/@/shared/components/text-input/text-input'; +import { Text } from '/@/shared/components/text/text'; import { Tooltip } from '/@/shared/components/tooltip/tooltip'; import { ItemListKey, ListPaginationType } from '/@/shared/types/types'; @@ -48,13 +53,13 @@ export const TableConfig = ({ extraOptions, listKey, tableColumnsData }: TableCo label: t('table.config.general.pagination_infinite', { postProcess: 'sentenceCase', }), - value: 'infinite', + value: ListPaginationType.INFINITE, }, { label: t('table.config.general.pagination_paginate', { postProcess: 'sentenceCase', }), - value: 'paginate', + value: ListPaginationType.PAGINATED, }, ]} onChange={(value) => @@ -201,6 +206,7 @@ export const TableConfig = ({ extraOptions, listKey, tableColumnsData }: TableCo return ( <> + { + return new Fuse(value, { + getFn: (obj) => { + return labelMap[obj.id] || ''; + }, + includeMatches: true, + includeScore: true, + keys: ['id', 'label'], + threshold: 0.3, + }); + }, [value, labelMap]); + + const filteredColumns = useMemo(() => { + if (!searchColumns.trim()) { + return value.map((item) => ({ item, matches: null })); + } + + const results = fuse.search(searchColumns); + const resultMap = new Map(results.map((result) => [result.item.id, result.matches])); + + return value.map((item) => ({ + item, + matches: resultMap.get(item.id) || null, + })); + }, [value, searchColumns, fuse]); + return ( - {value.map((item) => ( - + + {t('common.tableColumns', { postProcess: 'sentenceCase' })} + setSearchColumns(e.currentTarget.value)} + placeholder={t('common.search', { + postProcess: 'sentenceCase', + })} + size="xs" + /> + + {filteredColumns.map(({ item, matches }) => ( + 0, + })} + key={item.id} + layout + >