From a3f48685b6e3eed4c9d2b1520680d605e9b68991 Mon Sep 17 00:00:00 2001 From: Lixian Zhou Date: Thu, 19 Mar 2026 12:39:56 -0400 Subject: [PATCH] fix --- client/src/shared/components/Export.js | 34 ++++-- client/src/shared/components/ManageTable.js | 116 +++++++++++++++++++- 2 files changed, 139 insertions(+), 11 deletions(-) diff --git a/client/src/shared/components/Export.js b/client/src/shared/components/Export.js index 3f87786..53bfedf 100644 --- a/client/src/shared/components/Export.js +++ b/client/src/shared/components/Export.js @@ -43,6 +43,17 @@ const Export = ({ columns, data, filename = "export", customActions = [], show, }); }; + const handleSelectAll = () => { + scrollTopRef.current = scrollContainerRef.current?.scrollTop || 0; + const updatedColumns = exportColumns.map((col) => ({ ...col, show: true })); + setExportColumns(updatedColumns); + requestAnimationFrame(() => { + if (scrollContainerRef.current) { + scrollContainerRef.current.scrollTop = scrollTopRef.current; + } + }); + }; + const generateCSV = () => { const visibleColumns = exportColumns.filter(col => col.show); const headers = visibleColumns.map(col => col.label).join(','); @@ -158,13 +169,22 @@ const Export = ({ columns, data, filename = "export", customActions = [], show,
Select Columns:
- +
+ + +
{exportColumns.map((column) => (
diff --git a/client/src/shared/components/ManageTable.js b/client/src/shared/components/ManageTable.js index 5114892..185c670 100644 --- a/client/src/shared/components/ManageTable.js +++ b/client/src/shared/components/ManageTable.js @@ -2,7 +2,59 @@ import React, { useRef, useState } from "react"; import { Dropdown } from "react-bootstrap"; import { Columns } from "react-bootstrap-icons"; -const ManageTable = ({ columns, onColumnsChange, show, onToggle }) => { +const getSessionStorageValue = (key) => { + try { + return window.sessionStorage.getItem(key); + } catch (_e) { + return null; + } +}; + +const setSessionStorageValue = (key, value) => { + try { + window.sessionStorage.setItem(key, value); + return true; + } catch (_e) { + return false; + } +}; + +const getCookieNameFromKey = (key) => `manage_table_${`${key}`.replace(/[^a-zA-Z0-9_-]/g, "_")}`; + +const getCookieValue = (name) => { + if (typeof document === "undefined") return null; + const cookie = document.cookie + .split("; ") + .find((row) => row.startsWith(`${name}=`)); + if (!cookie) return null; + return decodeURIComponent(cookie.split("=")[1] || ""); +}; + +const setCookieValue = (name, value) => { + if (typeof document === "undefined") return; + document.cookie = `${name}=${encodeURIComponent(value)}; path=/; SameSite=Lax`; +}; + +const toVisibilityMap = (columnList = []) => ( + columnList.reduce((acc, col) => { + acc[col.key] = !!col.show; + return acc; + }, {}) +); + +const applyVisibilityMap = (columnList = [], visibilityMap = {}) => ( + columnList.map((col) => ( + Object.prototype.hasOwnProperty.call(visibilityMap, col.key) + ? { ...col, show: !!visibilityMap[col.key] } + : col + )) +); + +const hasVisibilityDiff = (left = [], right = []) => ( + left.length !== right.length || left.some((col, idx) => col.key !== right[idx]?.key || !!col.show !== !!right[idx]?.show) +); + +const ManageTable = ({ columns, onColumnsChange, show, onToggle, storageKey }) => { const [internalShow, setInternalShow] = useState(false); const [tempColumns, setTempColumns] = useState(columns); const scrollContainerRef = useRef(null); @@ -11,10 +63,41 @@ const ManageTable = ({ columns, onColumnsChange, show, onToggle }) => { // Use external control if provided, otherwise use internal state const showManageTableDropdown = show !== undefined ? show : internalShow; const handleToggle = onToggle || (() => setInternalShow(!internalShow)); + const resolvedStorageKey = React.useMemo(() => { + if (storageKey) return storageKey; + const path = window?.location?.pathname || "default"; + let userKey = "guest"; + try { + const user = JSON.parse(localStorage.getItem("user") || "{}"); + userKey = user?.id || user?._id || user?.name || "guest"; + } catch (_e) { + userKey = "guest"; + } + return `manage-table:${path}:${userKey}`; + }, [storageKey]); React.useEffect(() => { - setTempColumns(columns); - }, [columns]); + const rawSessionValue = getSessionStorageValue(resolvedStorageKey); + const cookieName = getCookieNameFromKey(resolvedStorageKey); + const rawCookieValue = getCookieValue(cookieName); + const rawValue = rawSessionValue || rawCookieValue; + + if (!rawValue) { + setTempColumns(columns); + return; + } + + try { + const parsedVisibilityMap = JSON.parse(rawValue); + const mergedColumns = applyVisibilityMap(columns, parsedVisibilityMap); + setTempColumns(mergedColumns); + if (hasVisibilityDiff(columns, mergedColumns)) { + onColumnsChange(mergedColumns); + } + } catch (_e) { + setTempColumns(columns); + } + }, [columns, onColumnsChange, resolvedStorageKey]); const handleColumnToggle = (columnKey) => { scrollTopRef.current = scrollContainerRef.current?.scrollTop || 0; @@ -30,6 +113,13 @@ const ManageTable = ({ columns, onColumnsChange, show, onToggle }) => { }; const handleDone = () => { + const visibilityMapString = JSON.stringify(toVisibilityMap(tempColumns)); + const wroteToSession = setSessionStorageValue(resolvedStorageKey, visibilityMapString); + if (!wroteToSession) { + setCookieValue(getCookieNameFromKey(resolvedStorageKey), visibilityMapString); + } else { + setCookieValue(getCookieNameFromKey(resolvedStorageKey), visibilityMapString); + } onColumnsChange(tempColumns); if (onToggle) { onToggle(false); @@ -58,6 +148,17 @@ const ManageTable = ({ columns, onColumnsChange, show, onToggle }) => { }); }; + const handleSelectAll = () => { + scrollTopRef.current = scrollContainerRef.current?.scrollTop || 0; + const updatedColumns = tempColumns.map((col) => ({ ...col, show: true })); + setTempColumns(updatedColumns); + requestAnimationFrame(() => { + if (scrollContainerRef.current) { + scrollContainerRef.current.scrollTop = scrollTopRef.current; + } + }); + }; + const customManageTableMenu = React.forwardRef( ({ children, style, className, 'aria-labelledby': labeledBy }, ref) => { return ( @@ -68,7 +169,14 @@ const ManageTable = ({ columns, onColumnsChange, show, onToggle }) => { aria-labelledby={labeledBy} >
Manage Table Columns
-
+
+