diff --git a/src/features/resources/hooks/useResourcePages.js b/src/features/resources/hooks/useResourcePages.js index 5087af9..7deff02 100644 --- a/src/features/resources/hooks/useResourcePages.js +++ b/src/features/resources/hooks/useResourcePages.js @@ -400,6 +400,8 @@ export function useResourceListPage() { const [form, setForm] = useState(emptyResourceForm); const [selectedResource, setSelectedResource] = useState(null); const [loadingAction, setLoadingAction] = useState(""); + const [resourceRowPatches, setResourceRowPatches] = useState({}); + const [hiddenResourceIds, setHiddenResourceIds] = useState([]); const filters = useMemo( () => ({ keyword: query, @@ -416,6 +418,53 @@ export function useResourceListPage() { pageSize, queryKey: ["resources", filters, page], }); + const hiddenResourceIdSet = useMemo(() => new Set(hiddenResourceIds), [hiddenResourceIds]); + const resourceData = useMemo(() => { + const source = result.data || emptyData; + const sourceItems = Array.isArray(source.items) ? source.items : []; + const patchedItems = sourceItems + .map((item) => ({ + ...item, + ...(resourceRowPatches[item.resourceId] || {}), + })) + .filter((item) => !hiddenResourceIdSet.has(item.resourceId)); + return { + ...source, + items: patchedItems, + }; + }, [hiddenResourceIdSet, resourceRowPatches, result.data]); + + useEffect(() => { + setResourceRowPatches({}); + setHiddenResourceIds([]); + }, [filters]); + + const patchResourceRow = (resourceId, patch) => { + if (!resourceId) { + return; + } + setHiddenResourceIds((current) => current.filter((hiddenId) => hiddenId !== resourceId)); + setResourceRowPatches((current) => ({ + ...current, + [resourceId]: { + ...(current[resourceId] || {}), + ...patch, + }, + })); + }; + + const hideResourceRow = (resourceId) => { + if (!resourceId) { + return; + } + setHiddenResourceIds((current) => (current.includes(resourceId) ? current : [...current, resourceId])); + }; + + const reloadResources = async () => { + setResourceRowPatches({}); + setHiddenResourceIds([]); + return result.reload(); + }; const openCreateResource = () => { setForm(emptyResourceForm()); @@ -469,12 +518,21 @@ export function useResourceListPage() { `resource-status-${resource.resourceId}`, nextEnabled ? "资源已启用" : "资源已禁用", async () => { + let updatedResource; if (nextStatus === "active") { - await enableResource(resource.resourceId); + updatedResource = await enableResource(resource.resourceId); } else { - await disableResource(resource.resourceId); + updatedResource = await disableResource(resource.resourceId); + } + if (status && nextStatus !== status) { + hideResourceRow(resource.resourceId); + } else { + patchResourceRow(resource.resourceId, { + ...(updatedResource || {}), + status: updatedResource?.status || nextStatus, + updatedAtMs: updatedResource?.updatedAtMs ?? Date.now(), + }); } - await result.reload(); }, ); }; @@ -494,8 +552,12 @@ export function useResourceListPage() { ...emptyResourceForm(resource), managerGrantEnabled: nextEnabled, }); - await updateResource(resource.resourceId, buildResourcePayload(formValue)); - await result.reload(); + const updatedResource = await updateResource(resource.resourceId, buildResourcePayload(formValue)); + patchResourceRow(resource.resourceId, { + ...(updatedResource || {}), + managerGrantEnabled: updatedResource?.managerGrantEnabled ?? nextEnabled, + updatedAtMs: updatedResource?.updatedAtMs ?? Date.now(), + }); }, ); }; @@ -520,7 +582,7 @@ export function useResourceListPage() { }; return { - ...sharedPageState({ page, query, result, setPage, setQuery }), + ...sharedPageState({ data: resourceData, page, query, reload: reloadResources, result, setPage, setQuery }), abilities, activeAction, changeResourceType: resetSetter(setResourceType, setPage), @@ -1883,14 +1945,14 @@ export function useResourceGrantListPage() { }; } -function sharedPageState({ page, query, result, setPage, setQuery }) { +function sharedPageState({ data, page, query, reload, result, setPage, setQuery }) { return { - data: result.data || emptyData, + data: data || result.data || emptyData, error: result.error, loading: result.loading, page, query, - reload: result.reload, + reload: reload || result.reload, setPage, changeQuery: resetSetter(setQuery, setPage), };