feat:分组下个性化数据独立
This commit is contained in:
@@ -161,131 +161,160 @@ export default function PcFundTable({
|
||||
}
|
||||
setActiveId(null);
|
||||
};
|
||||
const getStoredColumnSizing = () => {
|
||||
const groupKey = currentTab ?? 'all';
|
||||
|
||||
const getCustomSettingsWithMigration = () => {
|
||||
if (typeof window === 'undefined') return {};
|
||||
try {
|
||||
const raw = window.localStorage.getItem('customSettings');
|
||||
if (!raw) return {};
|
||||
const parsed = JSON.parse(raw);
|
||||
const sizing = parsed?.pcTableColumns;
|
||||
if (!sizing || typeof sizing !== 'object') return {};
|
||||
return Object.fromEntries(
|
||||
Object.entries(sizing).filter(([, value]) => Number.isFinite(value)),
|
||||
);
|
||||
const parsed = raw ? JSON.parse(raw) : {};
|
||||
if (!parsed || typeof parsed !== 'object') return {};
|
||||
if (parsed.pcTableColumnOrder != null || parsed.pcTableColumnVisibility != null || parsed.pcTableColumns != null || parsed.mobileTableColumnOrder != null || parsed.mobileTableColumnVisibility != null) {
|
||||
const all = {
|
||||
...(parsed.all && typeof parsed.all === 'object' ? parsed.all : {}),
|
||||
pcTableColumnOrder: parsed.pcTableColumnOrder,
|
||||
pcTableColumnVisibility: parsed.pcTableColumnVisibility,
|
||||
pcTableColumns: parsed.pcTableColumns,
|
||||
mobileTableColumnOrder: parsed.mobileTableColumnOrder,
|
||||
mobileTableColumnVisibility: parsed.mobileTableColumnVisibility,
|
||||
};
|
||||
delete parsed.pcTableColumnOrder;
|
||||
delete parsed.pcTableColumnVisibility;
|
||||
delete parsed.pcTableColumns;
|
||||
delete parsed.mobileTableColumnOrder;
|
||||
delete parsed.mobileTableColumnVisibility;
|
||||
parsed.all = all;
|
||||
window.localStorage.setItem('customSettings', JSON.stringify(parsed));
|
||||
}
|
||||
return parsed;
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
const persistColumnSizing = (nextSizing) => {
|
||||
if (typeof window === 'undefined') return;
|
||||
try {
|
||||
const raw = window.localStorage.getItem('customSettings');
|
||||
const parsed = raw ? JSON.parse(raw) : {};
|
||||
const nextSettings =
|
||||
parsed && typeof parsed === 'object'
|
||||
? { ...parsed, pcTableColumns: nextSizing }
|
||||
: { pcTableColumns: nextSizing };
|
||||
window.localStorage.setItem('customSettings', JSON.stringify(nextSettings));
|
||||
onCustomSettingsChange?.();
|
||||
} catch { }
|
||||
};
|
||||
|
||||
const getStoredColumnOrder = () => {
|
||||
if (typeof window === 'undefined') return null;
|
||||
try {
|
||||
const raw = window.localStorage.getItem('customSettings');
|
||||
if (!raw) return null;
|
||||
const parsed = JSON.parse(raw);
|
||||
const order = parsed?.pcTableColumnOrder;
|
||||
if (!Array.isArray(order) || order.length === 0) return null;
|
||||
const valid = order.filter((id) => NON_FROZEN_COLUMN_IDS.includes(id));
|
||||
const missing = NON_FROZEN_COLUMN_IDS.filter((id) => !valid.includes(id));
|
||||
return [...valid, ...missing];
|
||||
} catch {
|
||||
return null;
|
||||
const buildPcConfigFromGroup = (group) => {
|
||||
if (!group || typeof group !== 'object') return null;
|
||||
const sizing = group.pcTableColumns;
|
||||
const sizingObj = sizing && typeof sizing === 'object'
|
||||
? Object.fromEntries(Object.entries(sizing).filter(([, v]) => Number.isFinite(v)))
|
||||
: {};
|
||||
if (sizingObj.actions) {
|
||||
const { actions, ...rest } = sizingObj;
|
||||
Object.assign(sizingObj, rest);
|
||||
delete sizingObj.actions;
|
||||
}
|
||||
const order = Array.isArray(group.pcTableColumnOrder) && group.pcTableColumnOrder.length > 0
|
||||
? group.pcTableColumnOrder
|
||||
: null;
|
||||
const visibility = group.pcTableColumnVisibility && typeof group.pcTableColumnVisibility === 'object'
|
||||
? group.pcTableColumnVisibility
|
||||
: null;
|
||||
return { sizing: sizingObj, order, visibility };
|
||||
};
|
||||
|
||||
const persistColumnOrder = (nextOrder) => {
|
||||
if (typeof window === 'undefined') return;
|
||||
try {
|
||||
const raw = window.localStorage.getItem('customSettings');
|
||||
const parsed = raw ? JSON.parse(raw) : {};
|
||||
const nextSettings =
|
||||
parsed && typeof parsed === 'object'
|
||||
? { ...parsed, pcTableColumnOrder: nextOrder }
|
||||
: { pcTableColumnOrder: nextOrder };
|
||||
window.localStorage.setItem('customSettings', JSON.stringify(nextSettings));
|
||||
onCustomSettingsChange?.();
|
||||
} catch { }
|
||||
};
|
||||
|
||||
const getStoredColumnVisibility = () => {
|
||||
if (typeof window === 'undefined') return null;
|
||||
try {
|
||||
const raw = window.localStorage.getItem('customSettings');
|
||||
if (!raw) return null;
|
||||
const parsed = JSON.parse(raw);
|
||||
const visibility = parsed?.pcTableColumnVisibility;
|
||||
if (!visibility || typeof visibility !== 'object') return null;
|
||||
const normalized = {};
|
||||
NON_FROZEN_COLUMN_IDS.forEach((id) => {
|
||||
const value = visibility[id];
|
||||
if (typeof value === 'boolean') {
|
||||
normalized[id] = value;
|
||||
}
|
||||
});
|
||||
return Object.keys(normalized).length ? normalized : null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const persistColumnVisibility = (nextVisibility) => {
|
||||
if (typeof window === 'undefined') return;
|
||||
try {
|
||||
const raw = window.localStorage.getItem('customSettings');
|
||||
const parsed = raw ? JSON.parse(raw) : {};
|
||||
const nextSettings =
|
||||
parsed && typeof parsed === 'object'
|
||||
? { ...parsed, pcTableColumnVisibility: nextVisibility }
|
||||
: { pcTableColumnVisibility: nextVisibility };
|
||||
window.localStorage.setItem('customSettings', JSON.stringify(nextSettings));
|
||||
onCustomSettingsChange?.();
|
||||
} catch { }
|
||||
};
|
||||
|
||||
const [columnSizing, setColumnSizing] = useState(() => {
|
||||
const stored = getStoredColumnSizing();
|
||||
if (stored.actions) {
|
||||
const { actions, ...rest } = stored;
|
||||
return rest;
|
||||
}
|
||||
return stored;
|
||||
const getDefaultPcGroupConfig = () => ({
|
||||
order: [...NON_FROZEN_COLUMN_IDS],
|
||||
visibility: null,
|
||||
sizing: {},
|
||||
});
|
||||
const [columnOrder, setColumnOrder] = useState(() => getStoredColumnOrder() ?? [...NON_FROZEN_COLUMN_IDS]);
|
||||
const [columnVisibility, setColumnVisibility] = useState(() => {
|
||||
const stored = getStoredColumnVisibility();
|
||||
if (stored) return stored;
|
||||
const allVisible = {};
|
||||
NON_FROZEN_COLUMN_IDS.forEach((id) => {
|
||||
allVisible[id] = true;
|
||||
|
||||
const getInitialConfigByGroup = () => {
|
||||
const parsed = getCustomSettingsWithMigration();
|
||||
const byGroup = {};
|
||||
Object.keys(parsed).forEach((k) => {
|
||||
if (k === 'pcContainerWidth') return;
|
||||
const group = parsed[k];
|
||||
const pc = buildPcConfigFromGroup(group);
|
||||
if (pc) {
|
||||
byGroup[k] = {
|
||||
pcTableColumnOrder: pc.order ? (() => {
|
||||
const valid = pc.order.filter((id) => NON_FROZEN_COLUMN_IDS.includes(id));
|
||||
const missing = NON_FROZEN_COLUMN_IDS.filter((id) => !valid.includes(id));
|
||||
return [...valid, ...missing];
|
||||
})() : null,
|
||||
pcTableColumnVisibility: pc.visibility,
|
||||
pcTableColumns: Object.keys(pc.sizing).length ? pc.sizing : null,
|
||||
};
|
||||
}
|
||||
});
|
||||
return byGroup;
|
||||
};
|
||||
|
||||
const [configByGroup, setConfigByGroup] = useState(getInitialConfigByGroup);
|
||||
|
||||
const currentGroupPc = configByGroup[groupKey];
|
||||
const defaultPc = getDefaultPcGroupConfig();
|
||||
const columnOrder = (() => {
|
||||
const order = currentGroupPc?.pcTableColumnOrder ?? defaultPc.order;
|
||||
if (!Array.isArray(order) || order.length === 0) return [...NON_FROZEN_COLUMN_IDS];
|
||||
const valid = order.filter((id) => NON_FROZEN_COLUMN_IDS.includes(id));
|
||||
const missing = NON_FROZEN_COLUMN_IDS.filter((id) => !valid.includes(id));
|
||||
return [...valid, ...missing];
|
||||
})();
|
||||
const columnVisibility = (() => {
|
||||
const vis = currentGroupPc?.pcTableColumnVisibility ?? null;
|
||||
if (vis && typeof vis === 'object' && Object.keys(vis).length > 0) return vis;
|
||||
const allVisible = {};
|
||||
NON_FROZEN_COLUMN_IDS.forEach((id) => { allVisible[id] = true; });
|
||||
return allVisible;
|
||||
});
|
||||
})();
|
||||
const columnSizing = (() => {
|
||||
const s = currentGroupPc?.pcTableColumns;
|
||||
if (s && typeof s === 'object') {
|
||||
const out = Object.fromEntries(Object.entries(s).filter(([, v]) => Number.isFinite(v)));
|
||||
if (out.actions) {
|
||||
const { actions, ...rest } = out;
|
||||
return rest;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
return {};
|
||||
})();
|
||||
|
||||
const persistPcGroupConfig = (updates) => {
|
||||
if (typeof window === 'undefined') return;
|
||||
try {
|
||||
const raw = window.localStorage.getItem('customSettings');
|
||||
const parsed = raw ? JSON.parse(raw) : {};
|
||||
const group = parsed[groupKey] && typeof parsed[groupKey] === 'object' ? { ...parsed[groupKey] } : {};
|
||||
if (updates.pcTableColumnOrder !== undefined) group.pcTableColumnOrder = updates.pcTableColumnOrder;
|
||||
if (updates.pcTableColumnVisibility !== undefined) group.pcTableColumnVisibility = updates.pcTableColumnVisibility;
|
||||
if (updates.pcTableColumns !== undefined) group.pcTableColumns = updates.pcTableColumns;
|
||||
parsed[groupKey] = group;
|
||||
window.localStorage.setItem('customSettings', JSON.stringify(parsed));
|
||||
setConfigByGroup((prev) => ({ ...prev, [groupKey]: { ...prev[groupKey], ...updates } }));
|
||||
onCustomSettingsChange?.();
|
||||
} catch { }
|
||||
};
|
||||
|
||||
const setColumnOrder = (nextOrderOrUpdater) => {
|
||||
const next = typeof nextOrderOrUpdater === 'function'
|
||||
? nextOrderOrUpdater(columnOrder)
|
||||
: nextOrderOrUpdater;
|
||||
persistPcGroupConfig({ pcTableColumnOrder: next });
|
||||
};
|
||||
const setColumnVisibility = (nextOrUpdater) => {
|
||||
const next = typeof nextOrUpdater === 'function'
|
||||
? nextOrUpdater(columnVisibility)
|
||||
: nextOrUpdater;
|
||||
persistPcGroupConfig({ pcTableColumnVisibility: next });
|
||||
};
|
||||
const setColumnSizing = (nextOrUpdater) => {
|
||||
const next = typeof nextOrUpdater === 'function'
|
||||
? nextOrUpdater(columnSizing)
|
||||
: nextOrUpdater;
|
||||
const { actions, ...rest } = next || {};
|
||||
persistPcGroupConfig({ pcTableColumns: rest || {} });
|
||||
};
|
||||
const [settingModalOpen, setSettingModalOpen] = useState(false);
|
||||
const [resetConfirmOpen, setResetConfirmOpen] = useState(false);
|
||||
const handleResetSizing = () => {
|
||||
setColumnSizing({});
|
||||
persistColumnSizing({});
|
||||
setResetConfirmOpen(false);
|
||||
};
|
||||
|
||||
const handleResetColumnOrder = () => {
|
||||
const defaultOrder = [...NON_FROZEN_COLUMN_IDS];
|
||||
setColumnOrder(defaultOrder);
|
||||
persistColumnOrder(defaultOrder);
|
||||
setColumnOrder([...NON_FROZEN_COLUMN_IDS]);
|
||||
};
|
||||
|
||||
const handleResetColumnVisibility = () => {
|
||||
@@ -294,14 +323,9 @@ export default function PcFundTable({
|
||||
allVisible[id] = true;
|
||||
});
|
||||
setColumnVisibility(allVisible);
|
||||
persistColumnVisibility(allVisible);
|
||||
};
|
||||
const handleToggleColumnVisibility = (columnId, visible) => {
|
||||
setColumnVisibility((prev = {}) => {
|
||||
const next = { ...prev, [columnId]: visible };
|
||||
persistColumnVisibility(next);
|
||||
return next;
|
||||
});
|
||||
setColumnVisibility((prev = {}) => ({ ...prev, [columnId]: visible }));
|
||||
};
|
||||
const onRemoveFundRef = useRef(onRemoveFund);
|
||||
const onToggleFavoriteRef = useRef(onToggleFavorite);
|
||||
@@ -350,6 +374,7 @@ export default function PcFundTable({
|
||||
onRemoveFromGroupRef.current?.(original);
|
||||
}}
|
||||
title="从小分组移除"
|
||||
style={{ backgroundColor: 'transparent'}}
|
||||
>
|
||||
<ExitIcon width="18" height="18" style={{ transform: 'rotate(180deg)' }} />
|
||||
</button>
|
||||
@@ -676,7 +701,6 @@ export default function PcFundTable({
|
||||
setColumnSizing((prev) => {
|
||||
const next = typeof updater === 'function' ? updater(prev) : updater;
|
||||
const { actions, ...rest } = next || {};
|
||||
persistColumnSizing(rest || {});
|
||||
return rest || {};
|
||||
});
|
||||
},
|
||||
@@ -686,18 +710,10 @@ export default function PcFundTable({
|
||||
columnVisibility,
|
||||
},
|
||||
onColumnOrderChange: (updater) => {
|
||||
setColumnOrder((prev) => {
|
||||
const next = typeof updater === 'function' ? updater(prev) : prev;
|
||||
persistColumnOrder(next);
|
||||
return next;
|
||||
});
|
||||
setColumnOrder(updater);
|
||||
},
|
||||
onColumnVisibilityChange: (updater) => {
|
||||
setColumnVisibility((prev = {}) => {
|
||||
const next = typeof updater === 'function' ? updater(prev) : (updater || {});
|
||||
persistColumnVisibility(next);
|
||||
return next;
|
||||
});
|
||||
setColumnVisibility(updater);
|
||||
},
|
||||
initialState: {
|
||||
columnPinning: {
|
||||
@@ -927,7 +943,6 @@ export default function PcFundTable({
|
||||
columns={columnOrder.map((id) => ({ id, header: COLUMN_HEADERS[id] ?? id }))}
|
||||
onColumnReorder={(newOrder) => {
|
||||
setColumnOrder(newOrder);
|
||||
persistColumnOrder(newOrder);
|
||||
}}
|
||||
columnVisibility={columnVisibility}
|
||||
onToggleColumnVisibility={handleToggleColumnVisibility}
|
||||
|
||||
Reference in New Issue
Block a user