@ryuzaki13/react-foundation-ui 1.5.10 → 1.5.11
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.
- package/dist/advanced-search/index.js +182 -148
- package/dist/advanced-search/index.js.map +1 -1
- package/dist/advanced-search/model/useAdvancedSearchSelection.d.ts +1 -1
- package/dist/advanced-search/model/useAdvancedSearchSelection.d.ts.map +1 -1
- package/dist/advanced-search/ui/AdvancedSearchModal.d.ts +12 -3
- package/dist/advanced-search/ui/AdvancedSearchModal.d.ts.map +1 -1
- package/dist/advanced-search/ui/AdvancedSearchModalSession.d.ts +15 -0
- package/dist/advanced-search/ui/AdvancedSearchModalSession.d.ts.map +1 -0
- package/dist/advanced-search/ui/AdvancedSearchSelect.d.ts.map +1 -1
- package/dist/badge/index.js +1 -1
- package/dist/base-table/index.js +1 -1
- package/dist/button/index.js +1 -1
- package/dist/check-box/index.js +1 -1
- package/dist/chunks/{CalendarView-BSshXZAX.js → CalendarView-DqA-PbAU.js} +42 -42
- package/dist/chunks/{CalendarView-BSshXZAX.js.map → CalendarView-DqA-PbAU.js.map} +1 -1
- package/dist/chunks/{ImageViewerRuntime-BMs3BBkV.js → ImageViewerRuntime-HGBWp9NM.js} +18 -18
- package/dist/chunks/{ImageViewerRuntime-BMs3BBkV.js.map → ImageViewerRuntime-HGBWp9NM.js.map} +1 -1
- package/dist/chunks/{TextEditorLexicalClient-CLjpATRu.js → TextEditorLexicalClient-B084kVzu.js} +322 -322
- package/dist/chunks/{TextEditorLexicalClient-CLjpATRu.js.map → TextEditorLexicalClient-B084kVzu.js.map} +1 -1
- package/dist/chunks/{badge-CaooZXYD.js → badge-DMM8cOHd.js} +16 -16
- package/dist/chunks/{badge-CaooZXYD.js.map → badge-DMM8cOHd.js.map} +1 -1
- package/dist/chunks/{base-table-fUJY__6M.js → base-table-CJdKCKhb.js} +125 -125
- package/dist/chunks/{base-table-fUJY__6M.js.map → base-table-CJdKCKhb.js.map} +1 -1
- package/dist/chunks/{button-C--u7uJj.js → button-CzUO5rzq.js} +17 -17
- package/dist/chunks/{button-C--u7uJj.js.map → button-CzUO5rzq.js.map} +1 -1
- package/dist/chunks/{check-box-BZiEBR9c.js → check-box-sfGjYczQ.js} +11 -11
- package/dist/chunks/{check-box-BZiEBR9c.js.map → check-box-sfGjYczQ.js.map} +1 -1
- package/dist/chunks/{context-menu-XZ-e0f6_.js → context-menu-6nJkPmKV.js} +83 -83
- package/dist/chunks/{context-menu-XZ-e0f6_.js.map → context-menu-6nJkPmKV.js.map} +1 -1
- package/dist/chunks/date-input-9T8AoG5U.js +341 -0
- package/dist/chunks/{date-input-Dr5QNVT6.js.map → date-input-9T8AoG5U.js.map} +1 -1
- package/dist/chunks/{input-BNszawm6.js → input-VC8jEoTa.js} +37 -37
- package/dist/chunks/{input-BNszawm6.js.map → input-VC8jEoTa.js.map} +1 -1
- package/dist/chunks/{input-files-DxLVr2PF.js → input-files-CoMjadk7.js} +22 -22
- package/dist/chunks/{input-files-DxLVr2PF.js.map → input-files-CoMjadk7.js.map} +1 -1
- package/dist/chunks/{input-search-C2OOhZlw.js → input-search-Bs_9SxT0.js} +2 -2
- package/dist/chunks/{input-search-C2OOhZlw.js.map → input-search-Bs_9SxT0.js.map} +1 -1
- package/dist/chunks/{misc-Cp_r022Z.js → misc-CkRRma5E.js} +55 -55
- package/dist/chunks/{misc-Cp_r022Z.js.map → misc-CkRRma5E.js.map} +1 -1
- package/dist/chunks/{modal-DK9M7lT5.js → modal-LHkNxBko.js} +38 -38
- package/dist/chunks/{modal-DK9M7lT5.js.map → modal-LHkNxBko.js.map} +1 -1
- package/dist/chunks/{multi-select-CFHaQPot.js → multi-select-BJ6Lst1E.js} +44 -44
- package/dist/chunks/{multi-select-CFHaQPot.js.map → multi-select-BJ6Lst1E.js.map} +1 -1
- package/dist/chunks/{picker-D3Fc15JH.js → picker-DLnfOgZj.js} +34 -34
- package/dist/chunks/{picker-D3Fc15JH.js.map → picker-DLnfOgZj.js.map} +1 -1
- package/dist/chunks/{popover-BTT7zSqx.js → popover-IExDrsF6.js} +67 -67
- package/dist/chunks/{popover-BTT7zSqx.js.map → popover-IExDrsF6.js.map} +1 -1
- package/dist/chunks/{select-BolFlcoY.js → select-CysiIrej.js} +5 -5
- package/dist/chunks/{select-BolFlcoY.js.map → select-CysiIrej.js.map} +1 -1
- package/dist/chunks/{sortable-DcTIAbjD.js → sortable-BKIwlqhI.js} +17 -17
- package/dist/chunks/{sortable-DcTIAbjD.js.map → sortable-BKIwlqhI.js.map} +1 -1
- package/dist/chunks/{table-BChs6bgR.js → table-CIWdAcPY.js} +2 -2
- package/dist/chunks/{table-BChs6bgR.js.map → table-CIWdAcPY.js.map} +1 -1
- package/dist/chunks/{types-CxXyru6U.js → types-D9Wj9wrg.js} +21 -21
- package/dist/chunks/{types-CxXyru6U.js.map → types-D9Wj9wrg.js.map} +1 -1
- package/dist/chunks/{useODataSelectBase-BhCMCzv_.js → useODataSelectBase-Bq36Wp1U.js} +8 -8
- package/dist/chunks/{useODataSelectBase-BhCMCzv_.js.map → useODataSelectBase-Bq36Wp1U.js.map} +1 -1
- package/dist/context-menu/index.js +1 -1
- package/dist/date-input/index.js +2 -2
- package/dist/date-time-input/index.js +32 -32
- package/dist/dialog/index.js +9 -9
- package/dist/disclosure/index.js +10 -10
- package/dist/drop-zone/index.js +8 -8
- package/dist/errors/index.js +8 -8
- package/dist/expandable-action-panel/index.js +16 -16
- package/dist/flex/useFlexClasses.d.ts +1 -1
- package/dist/fullscreen-portal/index.js +7 -7
- package/dist/image/index.js +27 -27
- package/dist/input/index.js +1 -1
- package/dist/input-date-time/index.js +1 -1
- package/dist/input-file/index.js +1 -1
- package/dist/input-files/index.js +1 -1
- package/dist/input-image/index.js +1 -1
- package/dist/input-search/index.js +1 -1
- package/dist/layout-picker/index.js +1 -1
- package/dist/list/index.js +25 -25
- package/dist/listbox/index.js +5 -5
- package/dist/misc/index.js +1 -1
- package/dist/modal/index.js +1 -1
- package/dist/multi-select/index.js +1 -1
- package/dist/notifications/index.js +30 -30
- package/dist/picker/index.js +1 -1
- package/dist/popover/index.js +1 -1
- package/dist/preset-range-date-input/index.js +1 -1
- package/dist/preset-select/index.js +1 -1
- package/dist/radio-button/index.js +10 -10
- package/dist/select/index.js +1 -1
- package/dist/simple-table/index.js +1 -1
- package/dist/slider/index.js +3 -3
- package/dist/sortable/index.js +1 -1
- package/dist/state-select/index.js +1 -1
- package/dist/styles.css +1 -1
- package/dist/switch/index.js +11 -11
- package/dist/table/index.js +1 -1
- package/dist/table-sorting/index.js +13 -13
- package/dist/tabs/index.js +1 -1
- package/dist/tag-input/index.js +55 -55
- package/dist/tag-input/index.js.map +1 -1
- package/dist/text/index.js +1 -1
- package/dist/text-editor/index.js +3 -3
- package/dist/textarea/index.js +1 -1
- package/dist/tree-select/index.js +134 -134
- package/dist/tree-select/index.js.map +1 -1
- package/dist/tree-table/index.js +16 -16
- package/package.json +1 -1
- package/storybook-static/project.json +1 -1
- package/dist/chunks/date-input-Dr5QNVT6.js +0 -341
|
@@ -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/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 */\nexport function useAdvancedSearchSelection<T extends Record<string, string>>(config: SearchConfig<T>) {\n\tconst [selectedItems, setSelectedItems] = useState<T[]>([]);\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 nextSelectionMap = new Map<string, T>();\n\n\t\t\t\tfor (const item of nextItems) {\n\t\t\t\t\tnextSelectionMap.set(String(item[config.leadingKey]), item);\n\t\t\t\t}\n\n\t\t\t\tconst normalizedItems = Array.from(nextSelectionMap.values());\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, useEffect, 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 SearchModalProps<T extends Record<string, string>> {\n\tonClose: () => void;\n\tonItemsSelect: (items: T[]) => void;\n\tinitialSelectedItems?: T[];\n\tconfig: SearchConfig<T>;\n}\n\n/**\n * Модальное окно поиска клиентов\n */\nexport function AdvancedSearchModal<T extends Record<string, string>>({\n\tonClose,\n\tonItemsSelect,\n\tconfig,\n\tinitialSelectedItems = []\n}: SearchModalProps<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);\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\t// До изменения: пустой внешний набор не очищал внутренний выбор.\n\t// После изменения: модальное окно синхронизирует выбор с внешним набором полностью.\n\tuseEffect(() => {\n\t\treplaceSelection(initialSelectedItems);\n\t}, [initialSelectedItems, replaceSelection]);\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// После изменения: таблица управляет multi-selection, а модалка сохраняет скрытые фильтрами элементы.\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\t * Удаляет отдельный элемент из общего выбора.\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// Обработчик подтверждения выбора\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={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} // или query.isFetchingNextPage\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 { 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 } from \"./AdvancedSearchModal\";\nimport { AdvancedSearchSelectUI } from \"./AdvancedSearchSelectUI\";\n\ntype AdvancedSearchSelectProps<T extends Record<string, string>> = UiBaseProps<string[]> & {\n\tconfig: SearchConfig<T>;\n};\n\nexport function AdvancedSearchSelect<T extends Record<string, string>>({\n\tvalue = [],\n\tonChange,\n\tconfig,\n\t...props\n}: AdvancedSearchSelectProps<T>) {\n\tconst [isModalOpen, setIsModalOpen] = useState(false);\n\n\tconst { data: selectedItems } = useAdvancedSearchInitialSelected(config, value);\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\tconfig={config}\n\t\t\t\t\tonClose={handleClose}\n\t\t\t\t\tonItemsSelect={handleSelect}\n\t\t\t\t\tinitialSelectedItems={selectedItems}\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\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\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={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\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\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\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={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\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\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\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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"}
|
|
@@ -2,7 +2,7 @@ import { SearchConfig } from "./types";
|
|
|
2
2
|
/**
|
|
3
3
|
* Хук для управления выбором клиентов
|
|
4
4
|
*/
|
|
5
|
-
export declare function useAdvancedSearchSelection<T extends Record<string, string>>(config: SearchConfig<T
|
|
5
|
+
export declare function useAdvancedSearchSelection<T extends Record<string, string>>(config: SearchConfig<T>, initialSelectedItems?: readonly T[]): {
|
|
6
6
|
selectedItems: T[];
|
|
7
7
|
select: (item: T) => void;
|
|
8
8
|
deselect: (id: string) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAdvancedSearchSelection.d.ts","sourceRoot":"","sources":["../../../src/advanced-search/model/useAdvancedSearchSelection.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"useAdvancedSearchSelection.d.ts","sourceRoot":"","sources":["../../../src/advanced-search/model/useAdvancedSearchSelection.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAiBvC;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC1E,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,EACvB,oBAAoB,GAAE,SAAS,CAAC,EAAO;;mBAmC/B,CAAC;mBAaH,MAAM;kCAxBC,SAAS,CAAC,EAAE;;qBAmCnB,MAAM;EAcZ"}
|
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
import { SearchConfig } from "../model";
|
|
2
|
+
export type AdvancedSearchInitialSelection<T extends Record<string, string>> = {
|
|
3
|
+
status: "loading";
|
|
4
|
+
} | {
|
|
5
|
+
status: "error";
|
|
6
|
+
} | {
|
|
7
|
+
status: "ready";
|
|
8
|
+
items: readonly T[];
|
|
9
|
+
};
|
|
2
10
|
interface SearchModalProps<T extends Record<string, string>> {
|
|
3
11
|
onClose: () => void;
|
|
4
12
|
onItemsSelect: (items: T[]) => void;
|
|
5
|
-
|
|
13
|
+
initialSelection: AdvancedSearchInitialSelection<T>;
|
|
6
14
|
config: SearchConfig<T>;
|
|
7
15
|
}
|
|
8
16
|
/**
|
|
9
|
-
*
|
|
17
|
+
* Query boundary начального выбора. Интерактивная сессия монтируется только после
|
|
18
|
+
* успешной загрузки committed snapshot, поэтому поздний ответ не может стереть draft.
|
|
10
19
|
*/
|
|
11
|
-
export declare function AdvancedSearchModal<T extends Record<string, string>>({ onClose, onItemsSelect,
|
|
20
|
+
export declare function AdvancedSearchModal<T extends Record<string, string>>({ onClose, onItemsSelect, initialSelection, config }: SearchModalProps<T>): import("react").JSX.Element;
|
|
12
21
|
export {};
|
|
13
22
|
//# sourceMappingURL=AdvancedSearchModal.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdvancedSearchModal.d.ts","sourceRoot":"","sources":["../../../src/advanced-search/ui/AdvancedSearchModal.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AdvancedSearchModal.d.ts","sourceRoot":"","sources":["../../../src/advanced-search/ui/AdvancedSearchModal.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAIxC,MAAM,MAAM,8BAA8B,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAC1E;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,SAAS,CAAC,EAAE,CAAA;CAAE,CAAC;AAExF,UAAU,gBAAgB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAC1D,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,aAAa,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC;IACpC,gBAAgB,EAAE,8BAA8B,CAAC,CAAC,CAAC,CAAC;IACpD,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;CACxB;AAeD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,EACrE,OAAO,EACP,aAAa,EACb,gBAAgB,EAChB,MAAM,EACN,EAAE,gBAAgB,CAAC,CAAC,CAAC,+BA4BrB"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SearchConfig } from "../model";
|
|
2
|
+
interface AdvancedSearchModalSessionProps<T extends Record<string, string>> {
|
|
3
|
+
onClose: () => void;
|
|
4
|
+
onItemsSelect: (items: T[]) => void;
|
|
5
|
+
/** Снимок committed-выбора, с которого начинается текущая сессия модалки. */
|
|
6
|
+
initialSelectedItems: readonly T[];
|
|
7
|
+
config: SearchConfig<T>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Интерактивная сессия расширенного поиска с собственным selection draft.
|
|
11
|
+
* Компонент монтируется только после разрешения initial Query snapshot.
|
|
12
|
+
*/
|
|
13
|
+
export declare function AdvancedSearchModalSession<T extends Record<string, string>>({ onClose, onItemsSelect, config, initialSelectedItems }: AdvancedSearchModalSessionProps<T>): import("react").JSX.Element;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=AdvancedSearchModalSession.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AdvancedSearchModalSession.d.ts","sourceRoot":"","sources":["../../../src/advanced-search/ui/AdvancedSearchModalSession.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAE,YAAY,EAAiD,MAAM,UAAU,CAAC;AAEvF,UAAU,+BAA+B,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IACzE,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,aAAa,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC;IACpC,6EAA6E;IAC7E,oBAAoB,EAAE,SAAS,CAAC,EAAE,CAAC;IACnC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,EAC5E,OAAO,EACP,aAAa,EACb,MAAM,EACN,oBAAoB,EACpB,EAAE,+BAA+B,CAAC,CAAC,CAAC,+BAiJpC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdvancedSearchSelect.d.ts","sourceRoot":"","sources":["../../../src/advanced-search/ui/AdvancedSearchSelect.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAoC,MAAM,UAAU,CAAC;AAK1E,KAAK,yBAAyB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC,GAAG;IAC1F,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;CACxB,CAAC;
|
|
1
|
+
{"version":3,"file":"AdvancedSearchSelect.d.ts","sourceRoot":"","sources":["../../../src/advanced-search/ui/AdvancedSearchSelect.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAoC,MAAM,UAAU,CAAC;AAK1E,KAAK,yBAAyB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC,GAAG;IAC1F,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;CACxB,CAAC;AAIF,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,EACtE,KAAU,EACV,QAAQ,EACR,MAAM,EACN,GAAG,KAAK,EACR,EAAE,yBAAyB,CAAC,CAAC,CAAC,+BA4C9B"}
|
package/dist/badge/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as e, t } from "../chunks/badge-
|
|
1
|
+
import { n as e, t } from "../chunks/badge-DMM8cOHd.js";
|
|
2
2
|
export { e as Badge, t as BadgeList };
|
package/dist/base-table/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { n as e, t } from "../chunks/table-column-interactions-DzEvVuXe.js";
|
|
2
|
-
import { a as n, c as r, d as i, f as a, g as o, h as s, i as c, l, m as u, n as d, o as f, p, r as m, s as h, t as g, u as _ } from "../chunks/base-table-
|
|
2
|
+
import { a as n, c as r, d as i, f as a, g as o, h as s, i as c, l, m as u, n as d, o as f, p, r as m, s as h, t as g, u as _ } from "../chunks/base-table-CJdKCKhb.js";
|
|
3
3
|
export { d as BaseTable, g as FormattedTableCell, e as TableColumnResizeHandle, t as TableHeaderInteractionCell, a as buildBaseTableColumnLayout, h as buildBaseTableMergedCellsLayout, r as buildTableFormattingSnapshot, p as getLeftPinnedColumnOffsets, u as getOrderedVisibleLeafColumns, l as hasTableColumnCustomCellRenderer, s as normalizeTableColumnPinning, o as resolveBaseTableColumnWidth, _ as resolveTableFormattingColumnId, i as shouldUseTableFormatting, f as useTableColumnOrder, n as useTableColumnPinning, c as useTableColumnSizing, m as useTableColumnVisibility };
|
package/dist/button/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as e, t } from "../chunks/button-
|
|
1
|
+
import { n as e, t } from "../chunks/button-CzUO5rzq.js";
|
|
2
2
|
export { e as Button, t as ButtonRemove };
|
package/dist/check-box/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as e } from "../chunks/check-box-
|
|
1
|
+
import { t as e } from "../chunks/check-box-sfGjYczQ.js";
|
|
2
2
|
export { e as CheckBox };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { n as e } from "./button-
|
|
1
|
+
import { n as e } from "./button-CzUO5rzq.js";
|
|
2
2
|
import { useState as t } from "react";
|
|
3
3
|
import { cn as n } from "@ryuzaki13/react-foundation-lib/utils";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
5
|
+
import { ChevronLeft as a, ChevronRight as o } from "lucide-react";
|
|
6
6
|
import { addCalendarMonths as s, addCalendarYears as c, createCalendarDate as l, getCalendarPeriod as u, getStartOfDay as d, isCalendarPeriodWithinDateBounds as f, isDateInsideCalendarPeriod as p, isDateRangeTuple as m, isSameCalendarDay as h } from "@ryuzaki13/react-foundation-lib/formatters";
|
|
7
7
|
//#region src/date-input/lib/dateInputCalendar.ts
|
|
8
8
|
var g = [
|
|
@@ -83,19 +83,19 @@ var T = {
|
|
|
83
83
|
year: "numeric",
|
|
84
84
|
month: "long",
|
|
85
85
|
day: "numeric"
|
|
86
|
-
}), O = ({ now: e, currentDate:
|
|
86
|
+
}), O = ({ now: e, currentDate: a, value: o, onChange: s, minDate: c, maxDate: m, selectsRange: g, selectionMode: _ = "day", weekEndDay: v = "sunday" }) => {
|
|
87
87
|
let [y, b] = t(null), x = {
|
|
88
88
|
selectionMode: _,
|
|
89
89
|
weekEndDay: v
|
|
90
90
|
}, S = (() => {
|
|
91
|
-
let e =
|
|
92
|
-
for (let n =
|
|
93
|
-
for (let n = 1; n <=
|
|
91
|
+
let e = a.getFullYear(), t = a.getMonth(), n = l(e, t, 1), r = l(e, t + 1, 0), i = n.getDay() === 0 ? 6 : n.getDay() - 1, o = 42 - (i + r.getDate()), s = [], c = l(e, t, 0).getDate();
|
|
92
|
+
for (let n = i; n > 0; --n) s.push(l(e, t - 1, c - n + 1));
|
|
93
|
+
for (let n = 1; n <= r.getDate(); n += 1) s.push(l(e, t, n));
|
|
94
94
|
for (let n = 1; n <= o; n += 1) s.push(l(e, t + 1, n));
|
|
95
95
|
let u = [];
|
|
96
96
|
for (let e = 0; e < s.length; e += 7) u.push(s.slice(e, e + 7));
|
|
97
97
|
return u;
|
|
98
|
-
})(), C = g && Array.isArray(
|
|
98
|
+
})(), C = g && Array.isArray(o) ? o[0] : null, w = g && Array.isArray(o) ? o[1] : null, O = u(g ? null : o, x), k = u(y, x), A = w ?? (C ? k?.end ?? null : null), j = _ === "week", M = j && (!g || !C), N = (e) => {
|
|
99
99
|
if (!g || !C || !A) return !1;
|
|
100
100
|
let t = d(e).getTime(), n = C.getTime(), r = A.getTime();
|
|
101
101
|
return t >= Math.min(n, r) && t <= Math.max(n, r);
|
|
@@ -105,24 +105,24 @@ var T = {
|
|
|
105
105
|
}), F = (e, t) => {
|
|
106
106
|
t || (j && b(e), !(!g || !C || w) && (j || b(e)));
|
|
107
107
|
};
|
|
108
|
-
return /* @__PURE__ */
|
|
108
|
+
return /* @__PURE__ */ i("div", {
|
|
109
109
|
className: T.dayView,
|
|
110
|
-
children: [/* @__PURE__ */
|
|
110
|
+
children: [/* @__PURE__ */ r("div", {
|
|
111
111
|
className: T.weekdays,
|
|
112
|
-
children: E.map((e) => /* @__PURE__ */
|
|
112
|
+
children: E.map((e) => /* @__PURE__ */ r("div", {
|
|
113
113
|
className: T.weekday,
|
|
114
114
|
children: e
|
|
115
115
|
}, e))
|
|
116
|
-
}), /* @__PURE__ */
|
|
116
|
+
}), /* @__PURE__ */ r("div", {
|
|
117
117
|
className: T.daysGrid,
|
|
118
118
|
onMouseLeave: () => {
|
|
119
119
|
(j || !w) && b(null);
|
|
120
120
|
},
|
|
121
|
-
children: S.map((t, i) => /* @__PURE__ */
|
|
121
|
+
children: S.map((t, i) => /* @__PURE__ */ r("div", {
|
|
122
122
|
className: T.week,
|
|
123
123
|
children: t.map((t, o) => {
|
|
124
|
-
let c = t.getMonth() ===
|
|
125
|
-
return /* @__PURE__ */
|
|
124
|
+
let c = t.getMonth() === a.getMonth(), l = p(t, O), u = M && p(t, k), d = N(t), f = h(t, C), m = h(t, A), g = h(t, e), v = P(t);
|
|
125
|
+
return /* @__PURE__ */ r("button", {
|
|
126
126
|
type: "button",
|
|
127
127
|
onClick: () => !v && s(t),
|
|
128
128
|
onMouseEnter: () => F(t, v),
|
|
@@ -161,11 +161,11 @@ var T = {
|
|
|
161
161
|
}, A = new Intl.DateTimeFormat("ru-RU", { month: "short" }), j = new Intl.DateTimeFormat("ru-RU", {
|
|
162
162
|
month: "long",
|
|
163
163
|
year: "numeric"
|
|
164
|
-
}), M = ({ currentDate: e, value:
|
|
164
|
+
}), M = ({ currentDate: e, value: i, onChange: a, minDate: o, maxDate: s, selectsRange: c, selectsPeriod: d, selectionMode: p = "day", weekEndDay: m = "sunday" }) => {
|
|
165
165
|
let [h, g] = t(null), _ = Array.from({ length: 12 }, (e, t) => t), v = e.getFullYear(), y = {
|
|
166
166
|
selectionMode: p,
|
|
167
167
|
weekEndDay: m
|
|
168
|
-
}, b = c && Array.isArray(
|
|
168
|
+
}, b = c && Array.isArray(i) ? i[0] : null, x = c && Array.isArray(i) ? i[1] : null, S = (e) => A.format(l(v, e, 1)), C = (e) => {
|
|
169
169
|
if (!o && !s) return !1;
|
|
170
170
|
let t = l(v, e, 1), n = l(v, e + 1, 0, 23, 59, 59);
|
|
171
171
|
return d ? !f(u(t, y), {
|
|
@@ -175,9 +175,9 @@ var T = {
|
|
|
175
175
|
}, T = (e, t) => {
|
|
176
176
|
!c || !b || x || t || g(e);
|
|
177
177
|
};
|
|
178
|
-
return /* @__PURE__ */
|
|
178
|
+
return /* @__PURE__ */ r("div", {
|
|
179
179
|
className: k.monthView,
|
|
180
|
-
children: /* @__PURE__ */
|
|
180
|
+
children: /* @__PURE__ */ r("div", {
|
|
181
181
|
className: k.monthsGrid,
|
|
182
182
|
onMouseLeave: () => {
|
|
183
183
|
x || g(null);
|
|
@@ -185,14 +185,14 @@ var T = {
|
|
|
185
185
|
children: _.map((e) => {
|
|
186
186
|
let t = C(e), o = l(v, e, 1), s = w({
|
|
187
187
|
date: o,
|
|
188
|
-
value:
|
|
188
|
+
value: i,
|
|
189
189
|
hoveredDate: h,
|
|
190
190
|
selectsRange: c,
|
|
191
191
|
selectionOptions: y
|
|
192
192
|
});
|
|
193
|
-
return /* @__PURE__ */
|
|
193
|
+
return /* @__PURE__ */ r("button", {
|
|
194
194
|
type: "button",
|
|
195
|
-
onClick: () => !t &&
|
|
195
|
+
onClick: () => !t && a(o),
|
|
196
196
|
onMouseEnter: () => T(o, t),
|
|
197
197
|
disabled: t,
|
|
198
198
|
"data-ui": "calendar-month-button",
|
|
@@ -223,11 +223,11 @@ var T = {
|
|
|
223
223
|
selected: "d1SfcV",
|
|
224
224
|
rangeStart: "Gkui4r",
|
|
225
225
|
rangeEnd: "_0dVZLW"
|
|
226
|
-
}, F = ({ currentDate: e, value:
|
|
226
|
+
}, F = ({ currentDate: e, value: i, onChange: a, minDate: o, maxDate: s, selectsRange: c, selectsPeriod: d, selectionMode: p = "day", weekEndDay: m = "sunday" }) => {
|
|
227
227
|
let [h, g] = t(null), _ = Math.floor(e.getFullYear() / 12) * 12, v = Array.from({ length: 12 }, (e, t) => _ + t), y = {
|
|
228
228
|
selectionMode: p,
|
|
229
229
|
weekEndDay: m
|
|
230
|
-
}, b = c && Array.isArray(
|
|
230
|
+
}, b = c && Array.isArray(i) ? i[0] : null, x = c && Array.isArray(i) ? i[1] : null, S = (e) => {
|
|
231
231
|
if (!o && !s) return !1;
|
|
232
232
|
let t = l(e, 0, 1), n = l(e, 11, 31, 23, 59, 59);
|
|
233
233
|
return d ? !f(u(t, y), {
|
|
@@ -237,9 +237,9 @@ var T = {
|
|
|
237
237
|
}, C = (e, t) => {
|
|
238
238
|
!c || !b || x || t || g(e);
|
|
239
239
|
};
|
|
240
|
-
return /* @__PURE__ */
|
|
240
|
+
return /* @__PURE__ */ r("div", {
|
|
241
241
|
className: P.yearView,
|
|
242
|
-
children: /* @__PURE__ */
|
|
242
|
+
children: /* @__PURE__ */ r("div", {
|
|
243
243
|
className: P.yearsGrid,
|
|
244
244
|
onMouseLeave: () => {
|
|
245
245
|
x || g(null);
|
|
@@ -247,14 +247,14 @@ var T = {
|
|
|
247
247
|
children: v.map((e) => {
|
|
248
248
|
let t = S(e), o = l(e, 0, 1), s = w({
|
|
249
249
|
date: o,
|
|
250
|
-
value:
|
|
250
|
+
value: i,
|
|
251
251
|
hoveredDate: h,
|
|
252
252
|
selectsRange: c,
|
|
253
253
|
selectionOptions: y
|
|
254
254
|
});
|
|
255
|
-
return /* @__PURE__ */
|
|
255
|
+
return /* @__PURE__ */ r("button", {
|
|
256
256
|
type: "button",
|
|
257
|
-
onClick: () => !t &&
|
|
257
|
+
onClick: () => !t && a(o),
|
|
258
258
|
onMouseEnter: () => C(o, t),
|
|
259
259
|
disabled: t,
|
|
260
260
|
"data-ui": "calendar-year-button",
|
|
@@ -314,7 +314,7 @@ function L({ view: n, datePickerLevel: l, selectionMode: p = "day", weekEndDay:
|
|
|
314
314
|
}
|
|
315
315
|
E((e) => c(e, 12));
|
|
316
316
|
};
|
|
317
|
-
return /* @__PURE__ */
|
|
317
|
+
return /* @__PURE__ */ i("div", {
|
|
318
318
|
className: N.calendarView,
|
|
319
319
|
children: [(() => {
|
|
320
320
|
let t = "";
|
|
@@ -327,17 +327,17 @@ function L({ view: n, datePickerLevel: l, selectionMode: p = "day", weekEndDay:
|
|
|
327
327
|
let e = Math.floor(w.getFullYear() / 12) * 12;
|
|
328
328
|
t = `${e} - ${e + 11}`;
|
|
329
329
|
}
|
|
330
|
-
return /* @__PURE__ */
|
|
330
|
+
return /* @__PURE__ */ i("div", {
|
|
331
331
|
className: N.calendarHeader,
|
|
332
332
|
children: [
|
|
333
|
-
/* @__PURE__ */
|
|
334
|
-
icon: /* @__PURE__ */ a
|
|
333
|
+
/* @__PURE__ */ r(e, {
|
|
334
|
+
icon: /* @__PURE__ */ r(a, {}),
|
|
335
335
|
onClick: D,
|
|
336
336
|
variant: "ghost",
|
|
337
337
|
"aria-label": "Предыдущий",
|
|
338
338
|
"data-action": "calendar-previous"
|
|
339
339
|
}),
|
|
340
|
-
/* @__PURE__ */
|
|
340
|
+
/* @__PURE__ */ r(e, {
|
|
341
341
|
onClick: () => {
|
|
342
342
|
n === "day" ? h("month") : n === "month" && h("year");
|
|
343
343
|
},
|
|
@@ -347,8 +347,8 @@ function L({ view: n, datePickerLevel: l, selectionMode: p = "day", weekEndDay:
|
|
|
347
347
|
"data-action": "calendar-switch-view",
|
|
348
348
|
children: t
|
|
349
349
|
}),
|
|
350
|
-
/* @__PURE__ */
|
|
351
|
-
icon: /* @__PURE__ */
|
|
350
|
+
/* @__PURE__ */ r(e, {
|
|
351
|
+
icon: /* @__PURE__ */ r(o, {}),
|
|
352
352
|
onClick: k,
|
|
353
353
|
variant: "ghost",
|
|
354
354
|
"aria-label": "Следующий",
|
|
@@ -387,7 +387,7 @@ function L({ view: n, datePickerLevel: l, selectionMode: p = "day", weekEndDay:
|
|
|
387
387
|
return;
|
|
388
388
|
}
|
|
389
389
|
h("day");
|
|
390
|
-
},
|
|
390
|
+
}, i = (t) => {
|
|
391
391
|
if (E(t), p === "year" || !b("month", l)) {
|
|
392
392
|
e(t);
|
|
393
393
|
return;
|
|
@@ -395,7 +395,7 @@ function L({ view: n, datePickerLevel: l, selectionMode: p = "day", weekEndDay:
|
|
|
395
395
|
h("month");
|
|
396
396
|
};
|
|
397
397
|
switch (n) {
|
|
398
|
-
case "day": return /* @__PURE__ */
|
|
398
|
+
case "day": return /* @__PURE__ */ r(O, {
|
|
399
399
|
now: _,
|
|
400
400
|
currentDate: w,
|
|
401
401
|
value: g.value,
|
|
@@ -406,7 +406,7 @@ function L({ view: n, datePickerLevel: l, selectionMode: p = "day", weekEndDay:
|
|
|
406
406
|
selectionMode: p,
|
|
407
407
|
weekEndDay: m
|
|
408
408
|
});
|
|
409
|
-
case "month": return /* @__PURE__ */
|
|
409
|
+
case "month": return /* @__PURE__ */ r(M, {
|
|
410
410
|
currentDate: w,
|
|
411
411
|
value: g.value,
|
|
412
412
|
onChange: t,
|
|
@@ -417,10 +417,10 @@ function L({ view: n, datePickerLevel: l, selectionMode: p = "day", weekEndDay:
|
|
|
417
417
|
selectionMode: p,
|
|
418
418
|
weekEndDay: m
|
|
419
419
|
});
|
|
420
|
-
case "year": return /* @__PURE__ */
|
|
420
|
+
case "year": return /* @__PURE__ */ r(F, {
|
|
421
421
|
currentDate: w,
|
|
422
422
|
value: g.value,
|
|
423
|
-
onChange:
|
|
423
|
+
onChange: i,
|
|
424
424
|
minDate: g.minDate,
|
|
425
425
|
maxDate: g.maxDate,
|
|
426
426
|
selectsRange: g.selectsRange,
|
|
@@ -436,4 +436,4 @@ function L({ view: n, datePickerLevel: l, selectionMode: p = "day", weekEndDay:
|
|
|
436
436
|
//#endregion
|
|
437
437
|
export { y as a, w as c, g as i, _ as n, b as o, v as r, x as s, L as t };
|
|
438
438
|
|
|
439
|
-
//# sourceMappingURL=CalendarView-
|
|
439
|
+
//# sourceMappingURL=CalendarView-DqA-PbAU.js.map
|