UNPKG

sccoreui

Version:

ui-sccore

154 lines (153 loc) 10.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const jsx_runtime_1 = require("react/jsx-runtime"); const React = tslib_1.__importStar(require("react")); const react_virtual_1 = require("@tanstack/react-virtual"); const inputtext_1 = require("primereact/inputtext"); const svg_component_1 = tslib_1.__importDefault(require("../../directives/svg-component")); const hooks_1 = require("primereact/hooks"); const skeleton_1 = require("primereact/skeleton"); function RowVirtualizerDynamic(props) { var _a, _b; const { optionTemplate, optionLabel, filterPlaceholder, matchKey = "id", values, multiple = false, onSelectionChange, fetchData, emptyMessage, emptyFilterMessage, refetchKey, } = props; const parentRef = React.useRef(null); const fetchDataRef = React.useRef(fetchData); fetchDataRef.current = fetchData; const loadingRef = React.useRef(false); const allCount = React.useRef(null); const totalRecordsCount = React.useRef(null); const initialFetch = { pageIndex: 0, pageSize: 100, searchTerm: "", }; const [loading, setLoading] = React.useState(true); const pageIndex = React.useRef(0); const [inputValue, debouncedValue, setInputValue] = (0, hooks_1.useDebounce)("", 500); const [enabled] = React.useState(true); const [data, setData] = React.useState([]); const virtualizer = (0, react_virtual_1.useVirtualizer)({ count: data.length, getScrollElement: () => parentRef.current, estimateSize: () => 45, enabled, }); // Scroll handler const handleScroll = () => { const el = parentRef.current; if (!el) return; const scrollOffset = el.scrollTop + el.clientHeight; const threshold = el.scrollHeight - 100; const checCount = allCount.current != null ? allCount.current > totalRecordsCount.current : true; if (el.scrollHeight > el.clientHeight && scrollOffset >= threshold && !loadingRef.current && checCount) { loadingRef.current = true; fetchMoreData(Object.assign(Object.assign({}, initialFetch), { pageIndex: pageIndex.current })); } }; const lastSearchTerm = React.useRef(''); const fetchMoreData = (props) => tslib_1.__awaiter(this, void 0, void 0, function* () { var _c; try { const object = yield fetchDataRef.current(props); if (object) { loadingRef.current = false; if (lastSearchTerm.current && !(props === null || props === void 0 ? void 0 : props.searchTerm)) { // Search just cleared — reset data setData(object.data); } else if ((props === null || props === void 0 ? void 0 : props.searchTerm) && (props === null || props === void 0 ? void 0 : props.searchTerm) !== "") { totalRecordsCount.current = (_c = object === null || object === void 0 ? void 0 : object.data) === null || _c === void 0 ? void 0 : _c.length; setData(object === null || object === void 0 ? void 0 : object.data); } else { setData((prev) => { const totalData = [...prev, ...object === null || object === void 0 ? void 0 : object.data]; totalRecordsCount.current = totalData.length; return totalData; }); } setLoading(false); allCount.current = object === null || object === void 0 ? void 0 : object.totalRecords; pageIndex.current = pageIndex.current + 1; lastSearchTerm.current = props === null || props === void 0 ? void 0 : props.searchTerm; } } catch (error) { console.error("Error fetching data:", error); loadingRef.current = false; setLoading(false); } }); React.useEffect(() => { loadingRef.current = true; setLoading(true); fetchMoreData(Object.assign(Object.assign({}, initialFetch), { searchTerm: debouncedValue })); }, [debouncedValue]); const isFirstRender = React.useRef(true); React.useEffect(() => { if (isFirstRender.current) { isFirstRender.current = false; return; } if (refetchKey !== undefined) { pageIndex.current = 0; setData([]); loadingRef.current = true; setLoading(true); fetchMoreData(Object.assign(Object.assign({}, initialFetch), { searchTerm: debouncedValue })); } }, [refetchKey]); React.useEffect(() => { const el = parentRef.current; el && el.addEventListener("scroll", handleScroll); return () => el === null || el === void 0 ? void 0 : el.removeEventListener("scroll", handleScroll); }, []); const items = virtualizer.getVirtualItems(); const handleSelect = (item) => { const isSelected = values.some((x) => (x === null || x === void 0 ? void 0 : x[matchKey]) === (item === null || item === void 0 ? void 0 : item[matchKey])); let newSelection; if (!multiple) { newSelection = isSelected ? [] : (item === null || item === void 0 ? void 0 : item[matchKey]) ? [item] : []; } else { newSelection = isSelected ? values.filter((val) => (val === null || val === void 0 ? void 0 : val[matchKey]) !== (item === null || item === void 0 ? void 0 : item[matchKey])) : [...values, item]; } onSelectionChange && onSelectionChange(newSelection); }; // Render Skeletons const renderSkeletons = () => { return Array.from({ length: 10 }).map((_, index) => ((0, jsx_runtime_1.jsx)("li", Object.assign({ className: "p-listbox-item cursor-pointer" }, { children: (0, jsx_runtime_1.jsx)(skeleton_1.Skeleton, { height: "30px", width: "100%" }) }), index))); }; return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ className: "p-listbox" }, { children: [(0, jsx_runtime_1.jsx)("div", Object.assign({ className: "p-listbox-header", "data-pc-section": "header" }, { children: (0, jsx_runtime_1.jsx)("div", Object.assign({ className: "p-listbox-filter-container", "data-pc-section": "filtercontainer" }, { children: (0, jsx_runtime_1.jsxs)("span", Object.assign({ className: "p-input-icon-right flex-order-1" }, { children: [inputValue === "" ? ((0, jsx_runtime_1.jsx)("span", Object.assign({ className: "p-input-suffix cursor-pointer" }, { children: (0, jsx_runtime_1.jsx)(svg_component_1.default, { icon: "search-md", size: 12 }) }))) : ((0, jsx_runtime_1.jsx)("span", Object.assign({ className: "p-input-suffix cursor-pointer", onClick: (e) => { e.stopPropagation(); setInputValue(""); } }, { children: (0, jsx_runtime_1.jsx)(svg_component_1.default, { icon: "x-close", size: 12 }) }))), (0, jsx_runtime_1.jsx)(inputtext_1.InputText, { value: inputValue, onChange: (e) => setInputValue(e.target.value), placeholder: filterPlaceholder, className: "w-full" })] })) })) })), (0, jsx_runtime_1.jsx)("div", Object.assign({ ref: parentRef, className: "List virtual-box w-full bg-gray shadow-3", style: { height: 400, overflowY: "auto", contain: "strict", } }, { children: (0, jsx_runtime_1.jsx)("div", Object.assign({ style: { height: virtualizer.getTotalSize(), width: "100%", position: "relative", }, className: `${data.length === 0 ? "flex-column flex justify-content-around align-items-center h-full w-full" : ""}` }, { children: loading && (data === null || data === void 0 ? void 0 : data.length) === 0 ? ((0, jsx_runtime_1.jsx)("ul", Object.assign({ className: "p-listbox-list w-full h-full" }, { children: renderSkeletons() }))) : (data === null || data === void 0 ? void 0 : data.length) === 0 ? (debouncedValue && debouncedValue !== "" ? ((0, jsx_runtime_1.jsx)("span", { children: emptyFilterMessage })) : ((0, jsx_runtime_1.jsx)("span", { children: emptyMessage }))) : ((0, jsx_runtime_1.jsx)("ul", Object.assign({ className: "p-listbox-list", style: { position: "absolute", top: 0, left: 0, width: "100%", transform: `translateY(${(_b = (_a = items[0]) === null || _a === void 0 ? void 0 : _a.start) !== null && _b !== void 0 ? _b : 0}px)`, } }, { children: items.map((virtualRow) => { var _a; return ((0, jsx_runtime_1.jsx)("li", Object.assign({ "data-index": virtualRow.index, ref: virtualizer.measureElement, onClick: () => handleSelect(data[virtualRow.index]), className: `p-listbox-item ${virtualRow.index % 2 ? "ListItemOdd" : "ListItemEven"} ${values.some((y) => { var _a; return (y === null || y === void 0 ? void 0 : y[matchKey]) === ((_a = data[virtualRow.index]) === null || _a === void 0 ? void 0 : _a[matchKey]); }) ? "p-highlight" : ""} cursor-pointer` }, { children: loading ? ((0, jsx_runtime_1.jsx)(skeleton_1.Skeleton, { height: "30px", width: "100%" })) : optionTemplate ? (optionTemplate(data[virtualRow.index])) : ((0, jsx_runtime_1.jsx)("div", { children: (_a = data[virtualRow.index]) === null || _a === void 0 ? void 0 : _a[optionLabel] })) }), virtualRow.key)); }) }))) })) }))] }))); } exports.default = RowVirtualizerDynamic;