@ryuzaki13/react-foundation-ui 1.6.12 → 1.6.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -344,7 +344,7 @@ var G = ({ label: t, description: n, disabled: r, size: i, placeholder: o = "В
|
|
|
344
344
|
className: e.uiToggleButtonContainer,
|
|
345
345
|
children: [
|
|
346
346
|
/* @__PURE__ */ j("div", {
|
|
347
|
-
className: "flexEllipsis",
|
|
347
|
+
className: "flexEllipsis fontSizeSm fontLight",
|
|
348
348
|
style: { maxWidth: "100%" },
|
|
349
349
|
children: s
|
|
350
350
|
}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/advanced-search/lib/searchParts.ts","../../src/advanced-search/model/useAdvancedSearch.ts","../../src/advanced-search/model/useAdvancedSearchInitialSelected.ts","../../src/advanced-search/model/useAdvancedSearchSelection.ts","../../src/advanced-search/ui/AdvancedSearchModalSession.tsx","../../src/advanced-search/ui/AdvancedSearchModal.tsx","../../src/advanced-search/ui/AdvancedSearchSelectUI.tsx","../../src/advanced-search/ui/AdvancedSearchSelect.tsx"],"sourcesContent":["export function buildSearchParts(searchTerm: string) {\n\tconst term = searchTerm.trim();\n\tif (!term) {\n\t\treturn [];\n\t}\n\n\tconst searchParts = term\n\t\t.split(\"*\")\n\t\t.map((part) => part.trim())\n\t\t.filter((part) => part.length);\n\n\treturn searchParts;\n\n\t// const filterConditions = searchKeys.map((key) => {\n\t// \treturn searchParts.map((part) => `substringof('${part}',${String(key)})`).join(\" and \");\n\t// });\n\n\t// return `(${filterConditions.join(\" or \")})`;\n}\n\nexport function filterBySearchParts<T extends Record<string, string>>(items: T[], searchParts: string[], searchKeys: (keyof T)[]) {\n\tconst lowerSearchParts = searchParts.map((part) => part.toLowerCase());\n\n\treturn items.filter((item) => {\n\t\tfor (const key of searchKeys) {\n\t\t\tconst value = String(item[key] || \"\").toLowerCase();\n\n\t\t\tlet lastIndex = 0;\n\t\t\tlet allPartsFound = true;\n\n\t\t\t// Ищем каждую часть строго после предыдущей\n\t\t\tfor (const part of lowerSearchParts) {\n\t\t\t\tconst index = value.indexOf(part, lastIndex);\n\t\t\t\tif (index === -1) {\n\t\t\t\t\tallPartsFound = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tlastIndex = index + part.length; // следующая часть после найденной\n\t\t\t}\n\n\t\t\tif (allPartsFound) return true;\n\t\t}\n\t\treturn false;\n\t});\n\n\t// С регуляркой медленнее в 2-3 раза\n\n\t// // Паттерн: первая часть, затем любое количество символов, затем вторая часть\n\t// const searchPattern = searchParts.join(\".*?\");\n\t// const regExp = new RegExp(searchPattern, \"i\");\n\n\t// return items.filter((item) => {\n\t// \tfor (const key of searchKeys) {\n\t// \t\tif (regExp.test(item[key])) {\n\t// \t\t\treturn true;\n\t// \t\t}\n\t// \t}\n\t// \treturn false;\n\t// });\n}\n","import { useCallback, useMemo, useState } from \"react\";\n\nimport { odataQueryFn } from \"@ryuzaki13/react-foundation-api/odata\";\nimport { createFilterContains, createFilterEqual } from \"@ryuzaki13/react-foundation-lib/odata-service\";\nimport { useInfiniteQuery } from \"@tanstack/react-query\";\n\nimport { buildSearchParts, filterBySearchParts } from \"../lib\";\n\nimport { SearchConfig } from \"./types\";\n\nconst PAGE_SIZE = 50;\n\nexport function useAdvancedSearch<T extends Record<string, string>>(config: SearchConfig<T>) {\n\tconst [term, setTerm] = useState(\"\");\n\tconst [filters, setFilters] = useState<Record<string, string[]>>(() =>\n\t\tObject.keys(config.segments ?? {}).reduce(\n\t\t\t(acc, key) => {\n\t\t\t\tacc[key] = [];\n\t\t\t\treturn acc;\n\t\t\t},\n\t\t\t{} as Record<string, string[]>\n\t\t)\n\t);\n\n\tconst searchParts = buildSearchParts(term);\n\tconst isComplexSearch = searchParts.length > 1;\n\n\tconst top = isComplexSearch ? 5000 : PAGE_SIZE;\n\n\tconst query = useInfiniteQuery({\n\t\tqueryKey: [\"search\", config.odata.service, config.odata.target, filters, term],\n\t\tqueryFn: async ({ pageParam = 0, signal, client }) => {\n\t\t\tconst columnKeys = config.columns.map((col) => col.key);\n\n\t\t\tconst result = await odataQueryFn<T>({\n\t\t\t\todata: {\n\t\t\t\t\tservice: config.odata.service,\n\t\t\t\t\ttarget: config.odata.target\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\ttop: top,\n\t\t\t\t\tskip: pageParam,\n\t\t\t\t\tselect: columnKeys,\n\t\t\t\t\texpression: {\n\t\t\t\t\t\tand: true,\n\t\t\t\t\t\tfilters: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfilters: searchParts\n\t\t\t\t\t\t\t\t\t? config.searchKeys.map((key) => ({\n\t\t\t\t\t\t\t\t\t\t\tfilters: searchParts.map((part) => createFilterContains(key, part))\n\t\t\t\t\t\t\t\t\t\t}))\n\t\t\t\t\t\t\t\t\t: []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tand: true,\n\t\t\t\t\t\t\t\tfilters: Object.keys(filters).map((key) => createFilterEqual(key, filters[key]))\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\tsorts: [{ key: config.leadingKey }]\n\t\t\t\t}\n\t\t\t})({ signal, client });\n\n\t\t\tif (isComplexSearch) {\n\t\t\t\treturn filterBySearchParts(result.data, searchParts, config.searchKeys);\n\t\t\t}\n\n\t\t\treturn result.data;\n\t\t},\n\t\tgetNextPageParam: (lastPage, allPages) => {\n\t\t\tif (lastPage.length < top) return undefined;\n\t\t\treturn allPages.length * top;\n\t\t},\n\t\tinitialPageParam: 0\n\t});\n\n\tconst search = useCallback((term: string) => {\n\t\tsetTerm(term);\n\t}, []);\n\n\tconst clearSearch = useCallback(() => {\n\t\tsetTerm(\"\");\n\t}, []);\n\n\tconst items = useMemo(() => {\n\t\treturn query.data?.pages.flatMap((page) => page) ?? [];\n\t}, [query.data?.pages]);\n\n\treturn {\n\t\tquery,\n\t\titems,\n\t\tsearchTerm: term,\n\t\tsetSearch: search,\n\t\tclearSearch,\n\t\tfilters,\n\t\tsetFilters\n\t};\n}\n","import { odataQueryFn } from \"@ryuzaki13/react-foundation-api/odata\";\nimport { createFilterEqual, unwrapODataQueryResult } from \"@ryuzaki13/react-foundation-lib/odata-service\";\nimport { useQuery } from \"@tanstack/react-query\";\n\nimport { SearchConfig } from \"./types\";\n\n/**\n * Хук для поиска клиентов с поддержкой бесконечной прокрутки через OData\n */\nexport function useAdvancedSearchInitialSelected<T extends Record<string, string>>(\n\tconfig: SearchConfig<T>,\n\tinitialSelectedKeys: string[] = []\n) {\n\tconst query = useQuery({\n\t\tqueryKey: [\"searchSelected\", config.odata.service, config.odata.target, initialSelectedKeys],\n\t\tqueryFn: async ({ client, signal }) => {\n\t\t\tif (initialSelectedKeys.length === 0) {\n\t\t\t\treturn { data: [] as T[], totalCount: undefined };\n\t\t\t}\n\n\t\t\t// Получаем ключи колонок для select параметра\n\t\t\tconst columnKeys = config.columns.map((col) => col.key);\n\n\t\t\t// Выполняем OData запрос\n\t\t\treturn await odataQueryFn<T>({\n\t\t\t\todata: { service: config.odata.service, target: config.odata.target },\n\t\t\t\toptions: {\n\t\t\t\t\tselect: columnKeys,\n\t\t\t\t\texpression: {\n\t\t\t\t\t\tfilters: initialSelectedKeys.map((key) => createFilterEqual(config.leadingKey, key))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})({ client, signal });\n\t\t},\n\t\tenabled: initialSelectedKeys.length > 0\n\t});\n\n\treturn unwrapODataQueryResult(query);\n}\n","import { useCallback, useState } from \"react\";\n\nimport { SearchConfig } from \"./types\";\n\n/**\n * Создаёт независимый набор выбора и сохраняет последнюю строку для каждого ведущего ключа.\n * Это единая структурная граница как для initial snapshot модалки, так и для дальнейших\n * обновлений выбора из таблицы.\n */\nfunction buildAdvancedSearchSelection<T extends Record<string, string>>(items: readonly T[], leadingKey: keyof T): T[] {\n\tconst selectionById = new Map<string, T>();\n\n\tfor (const item of items) {\n\t\tselectionById.set(String(item[leadingKey]), item);\n\t}\n\n\treturn Array.from(selectionById.values());\n}\n\n/**\n * Хук для управления выбором клиентов\n */\nexport function useAdvancedSearchSelection<T extends Record<string, string>>(\n\tconfig: SearchConfig<T>,\n\tinitialSelectedItems: readonly T[] = []\n) {\n\tconst [selectedItems, setSelectedItems] = useState<T[]>(() => buildAdvancedSearchSelection(initialSelectedItems, config.leadingKey));\n\n\t/**\n\t * Сравнивает наборы выбранных элементов по ведущему ключу без учёта порядка.\n\t */\n\tconst areSelectionsEqual = useCallback(\n\t\t(left: readonly T[], right: readonly T[]) => {\n\t\t\tif (left.length !== right.length) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst rightIds = new Set(right.map((item) => String(item[config.leadingKey])));\n\n\t\t\treturn left.every((item) => rightIds.has(String(item[config.leadingKey])));\n\t\t},\n\t\t[config.leadingKey]\n\t);\n\n\t/**\n\t * Нормализует новый набор выбора и удаляет дубликаты по ведущему ключу.\n\t */\n\tconst replaceSelection = useCallback(\n\t\t(nextItems: readonly T[]) => {\n\t\t\tsetSelectedItems((prev) => {\n\t\t\t\tconst normalizedItems = buildAdvancedSearchSelection(nextItems, config.leadingKey);\n\n\t\t\t\treturn areSelectionsEqual(prev, normalizedItems) ? prev : normalizedItems;\n\t\t\t});\n\t\t},\n\t\t[areSelectionsEqual, config.leadingKey]\n\t);\n\n\tconst select = useCallback(\n\t\t(item: T) => {\n\t\t\tsetSelectedItems((prev) => {\n\t\t\t\t// Проверяем, не выбран ли уже этот клиент\n\t\t\t\tif (prev.some((c) => c[config.leadingKey] === item[config.leadingKey])) {\n\t\t\t\t\treturn prev;\n\t\t\t\t}\n\t\t\t\treturn [...prev, item];\n\t\t\t});\n\t\t},\n\t\t[config.leadingKey]\n\t);\n\n\tconst deselect = useCallback(\n\t\t(id: string) => {\n\t\t\tsetSelectedItems((prev) => prev.filter((item) => item[config.leadingKey] !== id));\n\t\t},\n\t\t[config.leadingKey]\n\t);\n\n\tconst clearSelection = useCallback(() => {\n\t\tsetSelectedItems([]);\n\t}, []);\n\n\tconst isSelected = useCallback(\n\t\t(id: string) => {\n\t\t\treturn selectedItems.some((item) => item[config.leadingKey] === id);\n\t\t},\n\t\t[config.leadingKey, selectedItems]\n\t);\n\n\treturn {\n\t\tselectedItems,\n\t\tselect,\n\t\tdeselect,\n\t\treplaceSelection,\n\t\tclearSelection,\n\t\tisSelected\n\t};\n}\n","import { useCallback, useMemo } from \"react\";\n\nimport { useODataTableColumns } from \"@ryuzaki13/react-foundation-api/odata\";\nimport { type TableColumnDef } from \"@ryuzaki13/react-foundation-lib/table\";\n\nimport { Badge, BadgeList } from \"../../badge\";\nimport { Button } from \"../../button\";\nimport { FlexContainer } from \"../../flex\";\nimport { GridContainer } from \"../../grid\";\nimport { InputSearch } from \"../../input-search\";\nimport { Scrollable } from \"../../misc\";\nimport { Modal, ModalContent, ModalFooter, ModalToolbar } from \"../../modal\";\nimport { ODataDependentMultiSelect } from \"../../multi-select\";\nimport { Table } from \"../../table\";\nimport { SearchConfig, useAdvancedSearch, useAdvancedSearchSelection } from \"../model\";\n\ninterface AdvancedSearchModalSessionProps<T extends Record<string, string>> {\n\tonClose: () => void;\n\tonItemsSelect: (items: T[]) => void;\n\t/** Снимок committed-выбора, с которого начинается текущая сессия модалки. */\n\tinitialSelectedItems: readonly T[];\n\ttitle?: string;\n\tconfig: SearchConfig<T>;\n}\n\n/**\n * Интерактивная сессия расширенного поиска с собственным selection draft.\n * Компонент монтируется только после разрешения initial Query snapshot.\n */\nexport function AdvancedSearchModalSession<T extends Record<string, string>>({\n\tonClose,\n\tonItemsSelect,\n\ttitle,\n\tconfig,\n\tinitialSelectedItems\n}: AdvancedSearchModalSessionProps<T>) {\n\tconst tableColumns: TableColumnDef<T>[] = useMemo(\n\t\t() =>\n\t\t\tconfig.columns.map(\n\t\t\t\t(col) =>\n\t\t\t\t\t({\n\t\t\t\t\t\tid: col.key as keyof T,\n\t\t\t\t\t\taccessorKey: col.key as keyof T,\n\t\t\t\t\t\theader: col.label,\n\t\t\t\t\t\tmeta: {\n\t\t\t\t\t\t\twidth: col.width || \"auto\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}) as TableColumnDef<T>\n\t\t\t),\n\t\t[config.columns]\n\t);\n\n\tconst { columns, isLoading } = useODataTableColumns<T>({\n\t\tservice: config.odata.service,\n\t\ttarget: config.odata.target,\n\t\tmode: \"enrich\",\n\t\tcolumns: tableColumns\n\t});\n\n\tconst { query, items, searchTerm, setSearch, clearSearch, filters, setFilters } = useAdvancedSearch(config);\n\tconst { selectedItems, deselect, replaceSelection } = useAdvancedSearchSelection(config, initialSelectedItems);\n\tconst getRowId = useCallback((item: T) => String(item[config.leadingKey]), [config.leadingKey]);\n\tconst selectedRowIds = useMemo(() => selectedItems.map((item) => String(item[config.leadingKey])), [selectedItems, config.leadingKey]);\n\tconst visibleItemIds = useMemo(() => new Set(items.map((item) => String(item[config.leadingKey]))), [items, config.leadingKey]);\n\n\tconst handleReachEnd = useCallback(() => {\n\t\tif (query.hasNextPage && !query.isFetchingNextPage) {\n\t\t\tquery.fetchNextPage();\n\t\t}\n\t}, [query]);\n\n\t/**\n\t * При изменении видимого выбора сохраняет элементы, которые временно скрыты\n\t * поиском или сегментными фильтрами.\n\t */\n\tconst handleSelect = useCallback(\n\t\t(selectedVisibleItems: T[]) => {\n\t\t\tconst selectedVisibleIds = new Set(selectedVisibleItems.map((item) => String(item[config.leadingKey])));\n\t\t\tconst hiddenSelectedItems = selectedItems.filter((item) => !visibleItemIds.has(String(item[config.leadingKey])));\n\t\t\tconst nextVisibleSelectedItems = items.filter((item) => selectedVisibleIds.has(String(item[config.leadingKey])));\n\n\t\t\treplaceSelection([...hiddenSelectedItems, ...nextVisibleSelectedItems]);\n\t\t},\n\t\t[config.leadingKey, items, replaceSelection, selectedItems, visibleItemIds]\n\t);\n\n\t/** Удаляет отдельный элемент из общего выбора. */\n\tconst handleRemoveSelectedItem = useCallback(\n\t\t(item: T) => {\n\t\t\tdeselect(String(item[config.leadingKey]));\n\t\t},\n\t\t[config.leadingKey, deselect]\n\t);\n\n\t/** Передаёт committed-значение владельцу поля только по явному подтверждению. */\n\tconst handleConfirmSelection = useCallback(() => {\n\t\tonItemsSelect(selectedItems);\n\t\tonClose();\n\t}, [selectedItems, onItemsSelect, onClose]);\n\n\tconst filterConfig = useMemo(() => {\n\t\tif (\"segments\" in config && config.segments) {\n\t\t\tconst limitedKeys = Object.keys(config.segments);\n\t\t\tif (limitedKeys.length) {\n\t\t\t\treturn {\n\t\t\t\t\todata: { ...config.odata, limitedKeys },\n\t\t\t\t\tsegments: config.segments,\n\t\t\t\t\tmodel: config.model\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}, [config]);\n\n\treturn (\n\t\t<Modal isOpen onClose={onClose} title={title || config.title} size=\"lg\" height=\"min(50em, 80dvh)\">\n\t\t\t<ModalToolbar>\n\t\t\t\t<FlexContainer gap=\"sm\">\n\t\t\t\t\t{filterConfig && (\n\t\t\t\t\t\t<ODataDependentMultiSelect\n\t\t\t\t\t\t\todata={filterConfig.odata}\n\t\t\t\t\t\t\tsegments={filterConfig.segments}\n\t\t\t\t\t\t\tmodel={filterConfig.model}\n\t\t\t\t\t\t\tvalues={filters}\n\t\t\t\t\t\t\tonChange={setFilters}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\n\t\t\t\t\t<InputSearch\n\t\t\t\t\t\tsize=\"md\"\n\t\t\t\t\t\tplaceholder={config.searchLabel ?? \"Введите поисковый запрос\"}\n\t\t\t\t\t\tvalue={searchTerm}\n\t\t\t\t\t\tonChange={setSearch}\n\t\t\t\t\t\tonClear={clearSearch}\n\t\t\t\t\t\tclassName=\"flexGrow\"\n\t\t\t\t\t/>\n\t\t\t\t</FlexContainer>\n\t\t\t</ModalToolbar>\n\n\t\t\t<ModalContent>\n\t\t\t\t<GridContainer gap=\"md\" templateRows=\"1fr auto\" className=\"h100\">\n\t\t\t\t\t<Table\n\t\t\t\t\t\tcolumns={columns}\n\t\t\t\t\t\tdata={items}\n\t\t\t\t\t\tselectionMode=\"multi\"\n\t\t\t\t\t\tselectedRowIds={selectedRowIds}\n\t\t\t\t\t\tgetRowId={getRowId}\n\t\t\t\t\t\tisLoading={query.isLoading || isLoading}\n\t\t\t\t\t\tisFetching={query.isFetching}\n\t\t\t\t\t\tonRowSelectionChange={handleSelect}\n\t\t\t\t\t\tonReachEnd={handleReachEnd}\n\t\t\t\t\t\tclassName=\"w100\"\n\t\t\t\t\t/>\n\n\t\t\t\t\t<div className=\"marginBlockMd border\">\n\t\t\t\t\t\t<Scrollable className=\"paddingSm\" height=\"6em\">\n\t\t\t\t\t\t\t<BadgeList>\n\t\t\t\t\t\t\t\t{selectedItems.map((item) => (\n\t\t\t\t\t\t\t\t\t<Badge\n\t\t\t\t\t\t\t\t\t\tkey={item[config.leadingKey]}\n\t\t\t\t\t\t\t\t\t\tsize=\"md\"\n\t\t\t\t\t\t\t\t\t\ttone=\"info\"\n\t\t\t\t\t\t\t\t\t\tappearance=\"outline\"\n\t\t\t\t\t\t\t\t\t\tonRemove={() => handleRemoveSelectedItem(item)}>\n\t\t\t\t\t\t\t\t\t\t{config.leadingText ? item[config.leadingText] || item[config.leadingKey] : item[config.leadingKey]}\n\t\t\t\t\t\t\t\t\t</Badge>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</BadgeList>\n\t\t\t\t\t\t</Scrollable>\n\t\t\t\t\t</div>\n\t\t\t\t</GridContainer>\n\t\t\t</ModalContent>\n\n\t\t\t<ModalFooter>\n\t\t\t\t<Button onClick={onClose}>Отмена</Button>\n\t\t\t\t<Button variant=\"successOutline\" onClick={handleConfirmSelection}>\n\t\t\t\t\tВыбрать\n\t\t\t\t</Button>\n\t\t\t</ModalFooter>\n\t\t</Modal>\n\t);\n}\n","import { stableStringify } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { Button } from \"../../button\";\nimport { LoadingMessage, Message } from \"../../misc\";\nimport { Modal, ModalContent, ModalFooter } from \"../../modal\";\nimport { SearchConfig } from \"../model\";\n\nimport { AdvancedSearchModalSession } from \"./AdvancedSearchModalSession\";\n\nexport type AdvancedSearchInitialSelection<T extends Record<string, string>> =\n\t{ status: \"loading\" } | { status: \"error\" } | { status: \"ready\"; items: readonly T[] };\n\ninterface SearchModalProps<T extends Record<string, string>> {\n\tonClose: () => void;\n\tonItemsSelect: (items: T[]) => void;\n\tinitialSelection: AdvancedSearchInitialSelection<T>;\n\ttitle?: string;\n\tconfig: SearchConfig<T>;\n}\n\n/**\n * Создаёт стабильную identity modal-session по владельцу данных и внешним ключам.\n * Новый Query object с теми же строками не должен пересоздавать пользовательский draft.\n */\nfunction buildAdvancedSearchModalSessionKey<T extends Record<string, string>>(config: SearchConfig<T>, items: readonly T[]) {\n\treturn stableStringify({\n\t\tleadingKey: String(config.leadingKey),\n\t\tservice: config.odata.service,\n\t\ttarget: config.odata.target,\n\t\tselectedIds: items.map((item) => String(item[config.leadingKey])).sort()\n\t});\n}\n\n/**\n * Query boundary начального выбора. Интерактивная сессия монтируется только после\n * успешной загрузки committed snapshot, поэтому поздний ответ не может стереть draft.\n */\nexport function AdvancedSearchModal<T extends Record<string, string>>({\n\tonClose,\n\tonItemsSelect,\n\tinitialSelection,\n\ttitle,\n\tconfig\n}: SearchModalProps<T>) {\n\tif (initialSelection.status === \"ready\") {\n\t\treturn (\n\t\t\t<AdvancedSearchModalSession\n\t\t\t\tkey={buildAdvancedSearchModalSessionKey(config, initialSelection.items)}\n\t\t\t\ttitle={title}\n\t\t\t\tconfig={config}\n\t\t\t\tonClose={onClose}\n\t\t\t\tonItemsSelect={onItemsSelect}\n\t\t\t\tinitialSelectedItems={initialSelection.items}\n\t\t\t/>\n\t\t);\n\t}\n\n\treturn (\n\t\t<Modal isOpen onClose={onClose} title={title || config.title} size=\"lg\" height=\"min(50em, 80dvh)\">\n\t\t\t<ModalContent>\n\t\t\t\t{initialSelection.status === \"loading\" ? (\n\t\t\t\t\t<LoadingMessage text=\"Загружаем выбранные элементы...\" />\n\t\t\t\t) : (\n\t\t\t\t\t<Message color=\"error\">Не удалось загрузить выбранные элементы</Message>\n\t\t\t\t)}\n\t\t\t</ModalContent>\n\n\t\t\t<ModalFooter>\n\t\t\t\t<Button onClick={onClose}>Закрыть</Button>\n\t\t\t</ModalFooter>\n\t\t</Modal>\n\t);\n}\n","import { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { ChevronRightIcon, XIcon } from \"lucide-react\";\n\nimport { FlexContainer } from \"../../flex\";\nimport { useInputFieldIds } from \"../../input\";\nimport inputStyles from \"../../input/Input.module.scss\";\nimport { UiBaseProps } from \"../../types\";\nimport uiStyles from \"../../ui.module.scss\";\n\ninterface AdvancedSearchSelectUIProps extends Omit<UiBaseProps<string[]>, \"value\" | \"onChange\"> {\n\ttoken: string | undefined;\n\tonOpen: () => void;\n\tonClear: () => void;\n}\n\nexport const AdvancedSearchSelectUI = ({\n\tlabel,\n\tdescription,\n\tdisabled,\n\tsize,\n\tplaceholder = \"Выбрать\",\n\ttoken,\n\tonOpen,\n\tonClear\n}: AdvancedSearchSelectUIProps) => {\n\tconst { controlId, labelId, descriptionId } = useInputFieldIds({\n\t\thasLabel: label !== undefined && label !== null,\n\t\thasDescription: !!description\n\t});\n\tconst hasToken = Boolean(token);\n\n\treturn (\n\t\t<div aria-disabled={disabled || undefined} className={cn(uiStyles.uiElement, uiStyles.uiSizable, size && uiStyles[size])}>\n\t\t\t{label && (\n\t\t\t\t<label id={labelId} htmlFor={controlId} className={uiStyles.uiLabel}>\n\t\t\t\t\t{label}\n\t\t\t\t</label>\n\t\t\t)}\n\t\t\t{description && (\n\t\t\t\t<p id={descriptionId} className={uiStyles.uiDescription}>\n\t\t\t\t\t{description}\n\t\t\t\t</p>\n\t\t\t)}\n\n\t\t\t<div className={uiStyles.uiInputContainer}>\n\t\t\t\t<div className={uiStyles.uiInputWithToggle}>\n\t\t\t\t\t{!hasToken && (\n\t\t\t\t\t\t<FlexContainer align=\"center\" className=\"h100\">\n\t\t\t\t\t\t\t<div className={uiStyles.uiPlaceholder}>{placeholder}</div>\n\t\t\t\t\t\t</FlexContainer>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\n\t\t\t\t<div className={inputStyles.controlEndAdornment}>\n\t\t\t\t\t<div className={uiStyles.uiToggleButtonContainer}>\n\t\t\t\t\t\t<div className=\"flexEllipsis\" style={{ maxWidth: \"100%\" }}>\n\t\t\t\t\t\t\t{token}\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tdisabled={!token}\n\t\t\t\t\t\t\tclassName={uiStyles.uiClearButton}\n\t\t\t\t\t\t\tonClick={onClear}\n\t\t\t\t\t\t\taria-label=\"Очистить все\">\n\t\t\t\t\t\t\t<XIcon />\n\t\t\t\t\t\t</button>\n\n\t\t\t\t\t\t<div className={uiStyles.uiButtonSeparator} />\n\n\t\t\t\t\t\t<button type=\"button\" onClick={onOpen} className={uiStyles.uiToggleButton}>\n\t\t\t\t\t\t\t<ChevronRightIcon className={uiStyles.uiToggleIcon} />\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n","import { useCallback, useState } from \"react\";\n\nimport { UiBaseProps } from \"../../types\";\nimport { SearchConfig, useAdvancedSearchInitialSelected } from \"../model\";\n\nimport { AdvancedSearchModal, type AdvancedSearchInitialSelection } from \"./AdvancedSearchModal\";\nimport { AdvancedSearchSelectUI } from \"./AdvancedSearchSelectUI\";\n\ntype AdvancedSearchSelectProps<T extends Record<string, string>> = UiBaseProps<string[]> & {\n\ttitle?: string;\n\tconfig: SearchConfig<T>;\n};\n\nconst EMPTY_INITIAL_SELECTION: readonly never[] = [];\n\nexport function AdvancedSearchSelect<T extends Record<string, string>>({\n\tvalue = [],\n\tonChange,\n\ttitle,\n\tconfig,\n\t...props\n}: AdvancedSearchSelectProps<T>) {\n\tconst [isModalOpen, setIsModalOpen] = useState(false);\n\n\tconst initialSelectionQuery = useAdvancedSearchInitialSelected(config, value);\n\tconst selectedItems = initialSelectionQuery.data;\n\tconst initialSelection: AdvancedSearchInitialSelection<T> =\n\t\tvalue.length === 0\n\t\t\t? { status: \"ready\", items: EMPTY_INITIAL_SELECTION }\n\t\t\t: selectedItems !== undefined\n\t\t\t\t? { status: \"ready\", items: selectedItems }\n\t\t\t\t: initialSelectionQuery.isError\n\t\t\t\t\t? { status: \"error\" }\n\t\t\t\t\t: { status: \"loading\" };\n\n\tconst handleOpen = useCallback(() => setIsModalOpen(true), []);\n\tconst handleClose = useCallback(() => setIsModalOpen(false), []);\n\tconst handleRemove = useCallback(() => onChange([]), [onChange]);\n\tconst handleSelect = useCallback(\n\t\t(items: T[]) => onChange(items.map((item) => String(item[config.leadingKey]))),\n\t\t[config.leadingKey, onChange]\n\t);\n\tconst getDisplayText = useCallback(\n\t\t(items: T[] | undefined) => {\n\t\t\tif (!items?.length) return;\n\t\t\tif (items.length > 1) return `Выбрано ${items.length} элем.`;\n\t\t\treturn `${(config.leadingText && items[0][config.leadingText]) || items[0][config.leadingKey]}`;\n\t\t},\n\t\t[config.leadingKey, config.leadingText]\n\t);\n\n\treturn (\n\t\t<>\n\t\t\t<AdvancedSearchSelectUI {...props} token={getDisplayText(selectedItems)} onOpen={handleOpen} onClear={handleRemove} />\n\n\t\t\t{isModalOpen && (\n\t\t\t\t<AdvancedSearchModal\n\t\t\t\t\ttitle={title}\n\t\t\t\t\tconfig={config}\n\t\t\t\t\tonClose={handleClose}\n\t\t\t\t\tonItemsSelect={handleSelect}\n\t\t\t\t\tinitialSelection={initialSelection}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</>\n\t);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/advanced-search/lib/searchParts.ts","../../src/advanced-search/model/useAdvancedSearch.ts","../../src/advanced-search/model/useAdvancedSearchInitialSelected.ts","../../src/advanced-search/model/useAdvancedSearchSelection.ts","../../src/advanced-search/ui/AdvancedSearchModalSession.tsx","../../src/advanced-search/ui/AdvancedSearchModal.tsx","../../src/advanced-search/ui/AdvancedSearchSelectUI.tsx","../../src/advanced-search/ui/AdvancedSearchSelect.tsx"],"sourcesContent":["export function buildSearchParts(searchTerm: string) {\n\tconst term = searchTerm.trim();\n\tif (!term) {\n\t\treturn [];\n\t}\n\n\tconst searchParts = term\n\t\t.split(\"*\")\n\t\t.map((part) => part.trim())\n\t\t.filter((part) => part.length);\n\n\treturn searchParts;\n\n\t// const filterConditions = searchKeys.map((key) => {\n\t// \treturn searchParts.map((part) => `substringof('${part}',${String(key)})`).join(\" and \");\n\t// });\n\n\t// return `(${filterConditions.join(\" or \")})`;\n}\n\nexport function filterBySearchParts<T extends Record<string, string>>(items: T[], searchParts: string[], searchKeys: (keyof T)[]) {\n\tconst lowerSearchParts = searchParts.map((part) => part.toLowerCase());\n\n\treturn items.filter((item) => {\n\t\tfor (const key of searchKeys) {\n\t\t\tconst value = String(item[key] || \"\").toLowerCase();\n\n\t\t\tlet lastIndex = 0;\n\t\t\tlet allPartsFound = true;\n\n\t\t\t// Ищем каждую часть строго после предыдущей\n\t\t\tfor (const part of lowerSearchParts) {\n\t\t\t\tconst index = value.indexOf(part, lastIndex);\n\t\t\t\tif (index === -1) {\n\t\t\t\t\tallPartsFound = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tlastIndex = index + part.length; // следующая часть после найденной\n\t\t\t}\n\n\t\t\tif (allPartsFound) return true;\n\t\t}\n\t\treturn false;\n\t});\n\n\t// С регуляркой медленнее в 2-3 раза\n\n\t// // Паттерн: первая часть, затем любое количество символов, затем вторая часть\n\t// const searchPattern = searchParts.join(\".*?\");\n\t// const regExp = new RegExp(searchPattern, \"i\");\n\n\t// return items.filter((item) => {\n\t// \tfor (const key of searchKeys) {\n\t// \t\tif (regExp.test(item[key])) {\n\t// \t\t\treturn true;\n\t// \t\t}\n\t// \t}\n\t// \treturn false;\n\t// });\n}\n","import { useCallback, useMemo, useState } from \"react\";\n\nimport { odataQueryFn } from \"@ryuzaki13/react-foundation-api/odata\";\nimport { createFilterContains, createFilterEqual } from \"@ryuzaki13/react-foundation-lib/odata-service\";\nimport { useInfiniteQuery } from \"@tanstack/react-query\";\n\nimport { buildSearchParts, filterBySearchParts } from \"../lib\";\n\nimport { SearchConfig } from \"./types\";\n\nconst PAGE_SIZE = 50;\n\nexport function useAdvancedSearch<T extends Record<string, string>>(config: SearchConfig<T>) {\n\tconst [term, setTerm] = useState(\"\");\n\tconst [filters, setFilters] = useState<Record<string, string[]>>(() =>\n\t\tObject.keys(config.segments ?? {}).reduce(\n\t\t\t(acc, key) => {\n\t\t\t\tacc[key] = [];\n\t\t\t\treturn acc;\n\t\t\t},\n\t\t\t{} as Record<string, string[]>\n\t\t)\n\t);\n\n\tconst searchParts = buildSearchParts(term);\n\tconst isComplexSearch = searchParts.length > 1;\n\n\tconst top = isComplexSearch ? 5000 : PAGE_SIZE;\n\n\tconst query = useInfiniteQuery({\n\t\tqueryKey: [\"search\", config.odata.service, config.odata.target, filters, term],\n\t\tqueryFn: async ({ pageParam = 0, signal, client }) => {\n\t\t\tconst columnKeys = config.columns.map((col) => col.key);\n\n\t\t\tconst result = await odataQueryFn<T>({\n\t\t\t\todata: {\n\t\t\t\t\tservice: config.odata.service,\n\t\t\t\t\ttarget: config.odata.target\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\ttop: top,\n\t\t\t\t\tskip: pageParam,\n\t\t\t\t\tselect: columnKeys,\n\t\t\t\t\texpression: {\n\t\t\t\t\t\tand: true,\n\t\t\t\t\t\tfilters: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfilters: searchParts\n\t\t\t\t\t\t\t\t\t? config.searchKeys.map((key) => ({\n\t\t\t\t\t\t\t\t\t\t\tfilters: searchParts.map((part) => createFilterContains(key, part))\n\t\t\t\t\t\t\t\t\t\t}))\n\t\t\t\t\t\t\t\t\t: []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tand: true,\n\t\t\t\t\t\t\t\tfilters: Object.keys(filters).map((key) => createFilterEqual(key, filters[key]))\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\tsorts: [{ key: config.leadingKey }]\n\t\t\t\t}\n\t\t\t})({ signal, client });\n\n\t\t\tif (isComplexSearch) {\n\t\t\t\treturn filterBySearchParts(result.data, searchParts, config.searchKeys);\n\t\t\t}\n\n\t\t\treturn result.data;\n\t\t},\n\t\tgetNextPageParam: (lastPage, allPages) => {\n\t\t\tif (lastPage.length < top) return undefined;\n\t\t\treturn allPages.length * top;\n\t\t},\n\t\tinitialPageParam: 0\n\t});\n\n\tconst search = useCallback((term: string) => {\n\t\tsetTerm(term);\n\t}, []);\n\n\tconst clearSearch = useCallback(() => {\n\t\tsetTerm(\"\");\n\t}, []);\n\n\tconst items = useMemo(() => {\n\t\treturn query.data?.pages.flatMap((page) => page) ?? [];\n\t}, [query.data?.pages]);\n\n\treturn {\n\t\tquery,\n\t\titems,\n\t\tsearchTerm: term,\n\t\tsetSearch: search,\n\t\tclearSearch,\n\t\tfilters,\n\t\tsetFilters\n\t};\n}\n","import { odataQueryFn } from \"@ryuzaki13/react-foundation-api/odata\";\nimport { createFilterEqual, unwrapODataQueryResult } from \"@ryuzaki13/react-foundation-lib/odata-service\";\nimport { useQuery } from \"@tanstack/react-query\";\n\nimport { SearchConfig } from \"./types\";\n\n/**\n * Хук для поиска клиентов с поддержкой бесконечной прокрутки через OData\n */\nexport function useAdvancedSearchInitialSelected<T extends Record<string, string>>(\n\tconfig: SearchConfig<T>,\n\tinitialSelectedKeys: string[] = []\n) {\n\tconst query = useQuery({\n\t\tqueryKey: [\"searchSelected\", config.odata.service, config.odata.target, initialSelectedKeys],\n\t\tqueryFn: async ({ client, signal }) => {\n\t\t\tif (initialSelectedKeys.length === 0) {\n\t\t\t\treturn { data: [] as T[], totalCount: undefined };\n\t\t\t}\n\n\t\t\t// Получаем ключи колонок для select параметра\n\t\t\tconst columnKeys = config.columns.map((col) => col.key);\n\n\t\t\t// Выполняем OData запрос\n\t\t\treturn await odataQueryFn<T>({\n\t\t\t\todata: { service: config.odata.service, target: config.odata.target },\n\t\t\t\toptions: {\n\t\t\t\t\tselect: columnKeys,\n\t\t\t\t\texpression: {\n\t\t\t\t\t\tfilters: initialSelectedKeys.map((key) => createFilterEqual(config.leadingKey, key))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})({ client, signal });\n\t\t},\n\t\tenabled: initialSelectedKeys.length > 0\n\t});\n\n\treturn unwrapODataQueryResult(query);\n}\n","import { useCallback, useState } from \"react\";\n\nimport { SearchConfig } from \"./types\";\n\n/**\n * Создаёт независимый набор выбора и сохраняет последнюю строку для каждого ведущего ключа.\n * Это единая структурная граница как для initial snapshot модалки, так и для дальнейших\n * обновлений выбора из таблицы.\n */\nfunction buildAdvancedSearchSelection<T extends Record<string, string>>(items: readonly T[], leadingKey: keyof T): T[] {\n\tconst selectionById = new Map<string, T>();\n\n\tfor (const item of items) {\n\t\tselectionById.set(String(item[leadingKey]), item);\n\t}\n\n\treturn Array.from(selectionById.values());\n}\n\n/**\n * Хук для управления выбором клиентов\n */\nexport function useAdvancedSearchSelection<T extends Record<string, string>>(\n\tconfig: SearchConfig<T>,\n\tinitialSelectedItems: readonly T[] = []\n) {\n\tconst [selectedItems, setSelectedItems] = useState<T[]>(() => buildAdvancedSearchSelection(initialSelectedItems, config.leadingKey));\n\n\t/**\n\t * Сравнивает наборы выбранных элементов по ведущему ключу без учёта порядка.\n\t */\n\tconst areSelectionsEqual = useCallback(\n\t\t(left: readonly T[], right: readonly T[]) => {\n\t\t\tif (left.length !== right.length) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst rightIds = new Set(right.map((item) => String(item[config.leadingKey])));\n\n\t\t\treturn left.every((item) => rightIds.has(String(item[config.leadingKey])));\n\t\t},\n\t\t[config.leadingKey]\n\t);\n\n\t/**\n\t * Нормализует новый набор выбора и удаляет дубликаты по ведущему ключу.\n\t */\n\tconst replaceSelection = useCallback(\n\t\t(nextItems: readonly T[]) => {\n\t\t\tsetSelectedItems((prev) => {\n\t\t\t\tconst normalizedItems = buildAdvancedSearchSelection(nextItems, config.leadingKey);\n\n\t\t\t\treturn areSelectionsEqual(prev, normalizedItems) ? prev : normalizedItems;\n\t\t\t});\n\t\t},\n\t\t[areSelectionsEqual, config.leadingKey]\n\t);\n\n\tconst select = useCallback(\n\t\t(item: T) => {\n\t\t\tsetSelectedItems((prev) => {\n\t\t\t\t// Проверяем, не выбран ли уже этот клиент\n\t\t\t\tif (prev.some((c) => c[config.leadingKey] === item[config.leadingKey])) {\n\t\t\t\t\treturn prev;\n\t\t\t\t}\n\t\t\t\treturn [...prev, item];\n\t\t\t});\n\t\t},\n\t\t[config.leadingKey]\n\t);\n\n\tconst deselect = useCallback(\n\t\t(id: string) => {\n\t\t\tsetSelectedItems((prev) => prev.filter((item) => item[config.leadingKey] !== id));\n\t\t},\n\t\t[config.leadingKey]\n\t);\n\n\tconst clearSelection = useCallback(() => {\n\t\tsetSelectedItems([]);\n\t}, []);\n\n\tconst isSelected = useCallback(\n\t\t(id: string) => {\n\t\t\treturn selectedItems.some((item) => item[config.leadingKey] === id);\n\t\t},\n\t\t[config.leadingKey, selectedItems]\n\t);\n\n\treturn {\n\t\tselectedItems,\n\t\tselect,\n\t\tdeselect,\n\t\treplaceSelection,\n\t\tclearSelection,\n\t\tisSelected\n\t};\n}\n","import { useCallback, useMemo } from \"react\";\n\nimport { useODataTableColumns } from \"@ryuzaki13/react-foundation-api/odata\";\nimport { type TableColumnDef } from \"@ryuzaki13/react-foundation-lib/table\";\n\nimport { Badge, BadgeList } from \"../../badge\";\nimport { Button } from \"../../button\";\nimport { FlexContainer } from \"../../flex\";\nimport { GridContainer } from \"../../grid\";\nimport { InputSearch } from \"../../input-search\";\nimport { Scrollable } from \"../../misc\";\nimport { Modal, ModalContent, ModalFooter, ModalToolbar } from \"../../modal\";\nimport { ODataDependentMultiSelect } from \"../../multi-select\";\nimport { Table } from \"../../table\";\nimport { SearchConfig, useAdvancedSearch, useAdvancedSearchSelection } from \"../model\";\n\ninterface AdvancedSearchModalSessionProps<T extends Record<string, string>> {\n\tonClose: () => void;\n\tonItemsSelect: (items: T[]) => void;\n\t/** Снимок committed-выбора, с которого начинается текущая сессия модалки. */\n\tinitialSelectedItems: readonly T[];\n\ttitle?: string;\n\tconfig: SearchConfig<T>;\n}\n\n/**\n * Интерактивная сессия расширенного поиска с собственным selection draft.\n * Компонент монтируется только после разрешения initial Query snapshot.\n */\nexport function AdvancedSearchModalSession<T extends Record<string, string>>({\n\tonClose,\n\tonItemsSelect,\n\ttitle,\n\tconfig,\n\tinitialSelectedItems\n}: AdvancedSearchModalSessionProps<T>) {\n\tconst tableColumns: TableColumnDef<T>[] = useMemo(\n\t\t() =>\n\t\t\tconfig.columns.map(\n\t\t\t\t(col) =>\n\t\t\t\t\t({\n\t\t\t\t\t\tid: col.key as keyof T,\n\t\t\t\t\t\taccessorKey: col.key as keyof T,\n\t\t\t\t\t\theader: col.label,\n\t\t\t\t\t\tmeta: {\n\t\t\t\t\t\t\twidth: col.width || \"auto\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}) as TableColumnDef<T>\n\t\t\t),\n\t\t[config.columns]\n\t);\n\n\tconst { columns, isLoading } = useODataTableColumns<T>({\n\t\tservice: config.odata.service,\n\t\ttarget: config.odata.target,\n\t\tmode: \"enrich\",\n\t\tcolumns: tableColumns\n\t});\n\n\tconst { query, items, searchTerm, setSearch, clearSearch, filters, setFilters } = useAdvancedSearch(config);\n\tconst { selectedItems, deselect, replaceSelection } = useAdvancedSearchSelection(config, initialSelectedItems);\n\tconst getRowId = useCallback((item: T) => String(item[config.leadingKey]), [config.leadingKey]);\n\tconst selectedRowIds = useMemo(() => selectedItems.map((item) => String(item[config.leadingKey])), [selectedItems, config.leadingKey]);\n\tconst visibleItemIds = useMemo(() => new Set(items.map((item) => String(item[config.leadingKey]))), [items, config.leadingKey]);\n\n\tconst handleReachEnd = useCallback(() => {\n\t\tif (query.hasNextPage && !query.isFetchingNextPage) {\n\t\t\tquery.fetchNextPage();\n\t\t}\n\t}, [query]);\n\n\t/**\n\t * При изменении видимого выбора сохраняет элементы, которые временно скрыты\n\t * поиском или сегментными фильтрами.\n\t */\n\tconst handleSelect = useCallback(\n\t\t(selectedVisibleItems: T[]) => {\n\t\t\tconst selectedVisibleIds = new Set(selectedVisibleItems.map((item) => String(item[config.leadingKey])));\n\t\t\tconst hiddenSelectedItems = selectedItems.filter((item) => !visibleItemIds.has(String(item[config.leadingKey])));\n\t\t\tconst nextVisibleSelectedItems = items.filter((item) => selectedVisibleIds.has(String(item[config.leadingKey])));\n\n\t\t\treplaceSelection([...hiddenSelectedItems, ...nextVisibleSelectedItems]);\n\t\t},\n\t\t[config.leadingKey, items, replaceSelection, selectedItems, visibleItemIds]\n\t);\n\n\t/** Удаляет отдельный элемент из общего выбора. */\n\tconst handleRemoveSelectedItem = useCallback(\n\t\t(item: T) => {\n\t\t\tdeselect(String(item[config.leadingKey]));\n\t\t},\n\t\t[config.leadingKey, deselect]\n\t);\n\n\t/** Передаёт committed-значение владельцу поля только по явному подтверждению. */\n\tconst handleConfirmSelection = useCallback(() => {\n\t\tonItemsSelect(selectedItems);\n\t\tonClose();\n\t}, [selectedItems, onItemsSelect, onClose]);\n\n\tconst filterConfig = useMemo(() => {\n\t\tif (\"segments\" in config && config.segments) {\n\t\t\tconst limitedKeys = Object.keys(config.segments);\n\t\t\tif (limitedKeys.length) {\n\t\t\t\treturn {\n\t\t\t\t\todata: { ...config.odata, limitedKeys },\n\t\t\t\t\tsegments: config.segments,\n\t\t\t\t\tmodel: config.model\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}, [config]);\n\n\treturn (\n\t\t<Modal isOpen onClose={onClose} title={title || config.title} size=\"lg\" height=\"min(50em, 80dvh)\">\n\t\t\t<ModalToolbar>\n\t\t\t\t<FlexContainer gap=\"sm\">\n\t\t\t\t\t{filterConfig && (\n\t\t\t\t\t\t<ODataDependentMultiSelect\n\t\t\t\t\t\t\todata={filterConfig.odata}\n\t\t\t\t\t\t\tsegments={filterConfig.segments}\n\t\t\t\t\t\t\tmodel={filterConfig.model}\n\t\t\t\t\t\t\tvalues={filters}\n\t\t\t\t\t\t\tonChange={setFilters}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\n\t\t\t\t\t<InputSearch\n\t\t\t\t\t\tsize=\"md\"\n\t\t\t\t\t\tplaceholder={config.searchLabel ?? \"Введите поисковый запрос\"}\n\t\t\t\t\t\tvalue={searchTerm}\n\t\t\t\t\t\tonChange={setSearch}\n\t\t\t\t\t\tonClear={clearSearch}\n\t\t\t\t\t\tclassName=\"flexGrow\"\n\t\t\t\t\t/>\n\t\t\t\t</FlexContainer>\n\t\t\t</ModalToolbar>\n\n\t\t\t<ModalContent>\n\t\t\t\t<GridContainer gap=\"md\" templateRows=\"1fr auto\" className=\"h100\">\n\t\t\t\t\t<Table\n\t\t\t\t\t\tcolumns={columns}\n\t\t\t\t\t\tdata={items}\n\t\t\t\t\t\tselectionMode=\"multi\"\n\t\t\t\t\t\tselectedRowIds={selectedRowIds}\n\t\t\t\t\t\tgetRowId={getRowId}\n\t\t\t\t\t\tisLoading={query.isLoading || isLoading}\n\t\t\t\t\t\tisFetching={query.isFetching}\n\t\t\t\t\t\tonRowSelectionChange={handleSelect}\n\t\t\t\t\t\tonReachEnd={handleReachEnd}\n\t\t\t\t\t\tclassName=\"w100\"\n\t\t\t\t\t/>\n\n\t\t\t\t\t<div className=\"marginBlockMd border\">\n\t\t\t\t\t\t<Scrollable className=\"paddingSm\" height=\"6em\">\n\t\t\t\t\t\t\t<BadgeList>\n\t\t\t\t\t\t\t\t{selectedItems.map((item) => (\n\t\t\t\t\t\t\t\t\t<Badge\n\t\t\t\t\t\t\t\t\t\tkey={item[config.leadingKey]}\n\t\t\t\t\t\t\t\t\t\tsize=\"md\"\n\t\t\t\t\t\t\t\t\t\ttone=\"info\"\n\t\t\t\t\t\t\t\t\t\tappearance=\"outline\"\n\t\t\t\t\t\t\t\t\t\tonRemove={() => handleRemoveSelectedItem(item)}>\n\t\t\t\t\t\t\t\t\t\t{config.leadingText ? item[config.leadingText] || item[config.leadingKey] : item[config.leadingKey]}\n\t\t\t\t\t\t\t\t\t</Badge>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</BadgeList>\n\t\t\t\t\t\t</Scrollable>\n\t\t\t\t\t</div>\n\t\t\t\t</GridContainer>\n\t\t\t</ModalContent>\n\n\t\t\t<ModalFooter>\n\t\t\t\t<Button onClick={onClose}>Отмена</Button>\n\t\t\t\t<Button variant=\"successOutline\" onClick={handleConfirmSelection}>\n\t\t\t\t\tВыбрать\n\t\t\t\t</Button>\n\t\t\t</ModalFooter>\n\t\t</Modal>\n\t);\n}\n","import { stableStringify } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { Button } from \"../../button\";\nimport { LoadingMessage, Message } from \"../../misc\";\nimport { Modal, ModalContent, ModalFooter } from \"../../modal\";\nimport { SearchConfig } from \"../model\";\n\nimport { AdvancedSearchModalSession } from \"./AdvancedSearchModalSession\";\n\nexport type AdvancedSearchInitialSelection<T extends Record<string, string>> =\n\t{ status: \"loading\" } | { status: \"error\" } | { status: \"ready\"; items: readonly T[] };\n\ninterface SearchModalProps<T extends Record<string, string>> {\n\tonClose: () => void;\n\tonItemsSelect: (items: T[]) => void;\n\tinitialSelection: AdvancedSearchInitialSelection<T>;\n\ttitle?: string;\n\tconfig: SearchConfig<T>;\n}\n\n/**\n * Создаёт стабильную identity modal-session по владельцу данных и внешним ключам.\n * Новый Query object с теми же строками не должен пересоздавать пользовательский draft.\n */\nfunction buildAdvancedSearchModalSessionKey<T extends Record<string, string>>(config: SearchConfig<T>, items: readonly T[]) {\n\treturn stableStringify({\n\t\tleadingKey: String(config.leadingKey),\n\t\tservice: config.odata.service,\n\t\ttarget: config.odata.target,\n\t\tselectedIds: items.map((item) => String(item[config.leadingKey])).sort()\n\t});\n}\n\n/**\n * Query boundary начального выбора. Интерактивная сессия монтируется только после\n * успешной загрузки committed snapshot, поэтому поздний ответ не может стереть draft.\n */\nexport function AdvancedSearchModal<T extends Record<string, string>>({\n\tonClose,\n\tonItemsSelect,\n\tinitialSelection,\n\ttitle,\n\tconfig\n}: SearchModalProps<T>) {\n\tif (initialSelection.status === \"ready\") {\n\t\treturn (\n\t\t\t<AdvancedSearchModalSession\n\t\t\t\tkey={buildAdvancedSearchModalSessionKey(config, initialSelection.items)}\n\t\t\t\ttitle={title}\n\t\t\t\tconfig={config}\n\t\t\t\tonClose={onClose}\n\t\t\t\tonItemsSelect={onItemsSelect}\n\t\t\t\tinitialSelectedItems={initialSelection.items}\n\t\t\t/>\n\t\t);\n\t}\n\n\treturn (\n\t\t<Modal isOpen onClose={onClose} title={title || config.title} size=\"lg\" height=\"min(50em, 80dvh)\">\n\t\t\t<ModalContent>\n\t\t\t\t{initialSelection.status === \"loading\" ? (\n\t\t\t\t\t<LoadingMessage text=\"Загружаем выбранные элементы...\" />\n\t\t\t\t) : (\n\t\t\t\t\t<Message color=\"error\">Не удалось загрузить выбранные элементы</Message>\n\t\t\t\t)}\n\t\t\t</ModalContent>\n\n\t\t\t<ModalFooter>\n\t\t\t\t<Button onClick={onClose}>Закрыть</Button>\n\t\t\t</ModalFooter>\n\t\t</Modal>\n\t);\n}\n","import { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { ChevronRightIcon, XIcon } from \"lucide-react\";\n\nimport { FlexContainer } from \"../../flex\";\nimport { useInputFieldIds } from \"../../input\";\nimport inputStyles from \"../../input/Input.module.scss\";\nimport { UiBaseProps } from \"../../types\";\nimport uiStyles from \"../../ui.module.scss\";\n\ninterface AdvancedSearchSelectUIProps extends Omit<UiBaseProps<string[]>, \"value\" | \"onChange\"> {\n\ttoken: string | undefined;\n\tonOpen: () => void;\n\tonClear: () => void;\n}\n\nexport const AdvancedSearchSelectUI = ({\n\tlabel,\n\tdescription,\n\tdisabled,\n\tsize,\n\tplaceholder = \"Выбрать\",\n\ttoken,\n\tonOpen,\n\tonClear\n}: AdvancedSearchSelectUIProps) => {\n\tconst { controlId, labelId, descriptionId } = useInputFieldIds({\n\t\thasLabel: label !== undefined && label !== null,\n\t\thasDescription: !!description\n\t});\n\tconst hasToken = Boolean(token);\n\n\treturn (\n\t\t<div aria-disabled={disabled || undefined} className={cn(uiStyles.uiElement, uiStyles.uiSizable, size && uiStyles[size])}>\n\t\t\t{label && (\n\t\t\t\t<label id={labelId} htmlFor={controlId} className={uiStyles.uiLabel}>\n\t\t\t\t\t{label}\n\t\t\t\t</label>\n\t\t\t)}\n\t\t\t{description && (\n\t\t\t\t<p id={descriptionId} className={uiStyles.uiDescription}>\n\t\t\t\t\t{description}\n\t\t\t\t</p>\n\t\t\t)}\n\n\t\t\t<div className={uiStyles.uiInputContainer}>\n\t\t\t\t<div className={uiStyles.uiInputWithToggle}>\n\t\t\t\t\t{!hasToken && (\n\t\t\t\t\t\t<FlexContainer align=\"center\" className=\"h100\">\n\t\t\t\t\t\t\t<div className={uiStyles.uiPlaceholder}>{placeholder}</div>\n\t\t\t\t\t\t</FlexContainer>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\n\t\t\t\t<div className={inputStyles.controlEndAdornment}>\n\t\t\t\t\t<div className={uiStyles.uiToggleButtonContainer}>\n\t\t\t\t\t\t<div className=\"flexEllipsis fontSizeSm fontLight\" style={{ maxWidth: \"100%\" }}>\n\t\t\t\t\t\t\t{token}\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tdisabled={!token}\n\t\t\t\t\t\t\tclassName={uiStyles.uiClearButton}\n\t\t\t\t\t\t\tonClick={onClear}\n\t\t\t\t\t\t\taria-label=\"Очистить все\">\n\t\t\t\t\t\t\t<XIcon />\n\t\t\t\t\t\t</button>\n\n\t\t\t\t\t\t<div className={uiStyles.uiButtonSeparator} />\n\n\t\t\t\t\t\t<button type=\"button\" onClick={onOpen} className={uiStyles.uiToggleButton}>\n\t\t\t\t\t\t\t<ChevronRightIcon className={uiStyles.uiToggleIcon} />\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n","import { useCallback, useState } from \"react\";\n\nimport { UiBaseProps } from \"../../types\";\nimport { SearchConfig, useAdvancedSearchInitialSelected } from \"../model\";\n\nimport { AdvancedSearchModal, type AdvancedSearchInitialSelection } from \"./AdvancedSearchModal\";\nimport { AdvancedSearchSelectUI } from \"./AdvancedSearchSelectUI\";\n\ntype AdvancedSearchSelectProps<T extends Record<string, string>> = UiBaseProps<string[]> & {\n\ttitle?: string;\n\tconfig: SearchConfig<T>;\n};\n\nconst EMPTY_INITIAL_SELECTION: readonly never[] = [];\n\nexport function AdvancedSearchSelect<T extends Record<string, string>>({\n\tvalue = [],\n\tonChange,\n\ttitle,\n\tconfig,\n\t...props\n}: AdvancedSearchSelectProps<T>) {\n\tconst [isModalOpen, setIsModalOpen] = useState(false);\n\n\tconst initialSelectionQuery = useAdvancedSearchInitialSelected(config, value);\n\tconst selectedItems = initialSelectionQuery.data;\n\tconst initialSelection: AdvancedSearchInitialSelection<T> =\n\t\tvalue.length === 0\n\t\t\t? { status: \"ready\", items: EMPTY_INITIAL_SELECTION }\n\t\t\t: selectedItems !== undefined\n\t\t\t\t? { status: \"ready\", items: selectedItems }\n\t\t\t\t: initialSelectionQuery.isError\n\t\t\t\t\t? { status: \"error\" }\n\t\t\t\t\t: { status: \"loading\" };\n\n\tconst handleOpen = useCallback(() => setIsModalOpen(true), []);\n\tconst handleClose = useCallback(() => setIsModalOpen(false), []);\n\tconst handleRemove = useCallback(() => onChange([]), [onChange]);\n\tconst handleSelect = useCallback(\n\t\t(items: T[]) => onChange(items.map((item) => String(item[config.leadingKey]))),\n\t\t[config.leadingKey, onChange]\n\t);\n\tconst getDisplayText = useCallback(\n\t\t(items: T[] | undefined) => {\n\t\t\tif (!items?.length) return;\n\t\t\tif (items.length > 1) return `Выбрано ${items.length} элем.`;\n\t\t\treturn `${(config.leadingText && items[0][config.leadingText]) || items[0][config.leadingKey]}`;\n\t\t},\n\t\t[config.leadingKey, config.leadingText]\n\t);\n\n\treturn (\n\t\t<>\n\t\t\t<AdvancedSearchSelectUI {...props} token={getDisplayText(selectedItems)} onOpen={handleOpen} onClear={handleRemove} />\n\n\t\t\t{isModalOpen && (\n\t\t\t\t<AdvancedSearchModal\n\t\t\t\t\ttitle={title}\n\t\t\t\t\tconfig={config}\n\t\t\t\t\tonClose={handleClose}\n\t\t\t\t\tonItemsSelect={handleSelect}\n\t\t\t\t\tinitialSelection={initialSelection}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</>\n\t);\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"generatedAt":
|
|
1
|
+
{"generatedAt":1785935579508,"hasCustomBabel":false,"hasCustomWebpack":false,"hasStaticDirs":false,"hasStorybookEslint":false,"refCount":0,"metaFramework":{"name":"tanstack-react","packageName":"@tanstack/react-router","version":"1.170.18"},"knownPackages":{"testPackages":{"@chromatic-com/storybook":"5.2.1","@storybook/addon-vitest":"10.5.5","@testing-library/dom":"10.4.1","@testing-library/react":"16.3.2","@testing-library/user-event":"^14.6.1","@vitest/browser":"4.1.10","playwright":"1.62.1","vitest":"4.1.10"},"stateManagementPackages":{"zustand":"5.0.0"},"dataFetchingPackages":{"@tanstack/react-query":"5.101.1"},"routerPackages":{"@tanstack/react-router":"1.170.0"}},"hasRouterPackage":false,"packageManager":{"type":"npm","version":"11.7.0","agent":"npm","nodeLinker":"node_modules"},"preview":{"usesGlobals":false},"framework":{"name":"@storybook/react-vite","options":{}},"builder":"@storybook/builder-vite","renderer":"@storybook/react","portableStoriesFileCount":1,"applicationFileCount":9,"storybookVersion":"10.5.5","storybookVersionSpecifier":"^10.5.5","language":"typescript","storybookPackages":{"@storybook/react-vite":{"version":"10.5.5"},"storybook":{}},"addons":{"@chromatic-com/storybook":{"version":"5.2.1"},"@storybook/addon-docs":{"version":"10.5.5"},"@storybook/addon-a11y":{"version":"10.5.5"},"@storybook/addon-vitest":{"version":"10.5.5"}},"packageJsonType":"module"}
|