perf: load single order group by id in detail view instead of all 430 groups

- add fetchOrderGroupById (single .eq(id).single() query)
- useOrderGroups gains groupId mode: fetches one group, not full 2.6MB list
- GroupDetailPage passes groupId — fixes 30-40s card open on slow connections
This commit is contained in:
Hermes 2026-08-19 11:02:23 +02:00
parent 5ca9bd7ebf
commit 8131e26c77
3 changed files with 50 additions and 4 deletions

View File

@ -1,5 +1,5 @@
import React from "react"; import React from "react";
import { assignDriverToOrderGroup, fetchOrderGroups, saveShipmentData, updateDeliveryStatus, updateOrderGroupDeliveryChoice } from "../services/supabase/orderGroupRepository"; import { assignDriverToOrderGroup, fetchOrderGroupById, fetchOrderGroups, saveShipmentData, updateDeliveryStatus, updateOrderGroupDeliveryChoice } from "../services/supabase/orderGroupRepository";
import { import {
buildOrderGroupBuckets, buildOrderGroupBuckets,
filterOrderGroups, filterOrderGroups,
@ -9,7 +9,7 @@ import {
} from "../services/orderGroupViews"; } from "../services/orderGroupViews";
import { getErrorMessage } from "../utils/deliveryUtils"; import { getErrorMessage } from "../utils/deliveryUtils";
export const useOrderGroups = ({ enabled = true, details = false } = {}) => { export const useOrderGroups = ({ enabled = true, details = false, groupId = null } = {}) => {
const [orderGroups, setOrderGroups] = React.useState(() => []); const [orderGroups, setOrderGroups] = React.useState(() => []);
const FILTERS_STORAGE_KEY = "supersam_order_filters"; const FILTERS_STORAGE_KEY = "supersam_order_filters";
const [filters, setFilters] = React.useState(() => { const [filters, setFilters] = React.useState(() => {
@ -41,6 +41,24 @@ export const useOrderGroups = ({ enabled = true, details = false } = {}) => {
if (!enabled) { setOrderGroups([]); setIsLoading(false); return; } if (!enabled) { setOrderGroups([]); setIsLoading(false); return; }
// Single-group mode: load only the requested group (avoids pulling all
// 430 groups with their full source_orders JSON — 2.6MB — for a detail view).
if (groupId) {
const singleResult = await fetchOrderGroupById(groupId);
if (!singleResult) {
return;
}
if (singleResult.error) {
setLoadError(singleResult.error?.message || "Не удалось загрузить группу доставки");
setOrderGroups([]);
setIsLoading(false);
return;
}
setOrderGroups(singleResult.data ? [singleResult.data] : []);
setIsLoading(false);
return;
}
const groupsResult = await fetchOrderGroups({ details }); const groupsResult = await fetchOrderGroups({ details });
if (!groupsResult) { if (!groupsResult) {
@ -56,7 +74,7 @@ export const useOrderGroups = ({ enabled = true, details = false } = {}) => {
setOrderGroups(groupsResult.data || []); setOrderGroups(groupsResult.data || []);
setIsLoading(false); setIsLoading(false);
}, [enabled, details]); }, [enabled, details, groupId]);
// Initial load // Initial load
React.useEffect(() => { React.useEffect(() => {

View File

@ -38,7 +38,7 @@ export const GroupDetailPage = () => {
saveShipmentData, saveShipmentData,
isLoading, isLoading,
refetch, refetch,
} = useOrderGroups({ details: true }); } = useOrderGroups({ details: true, groupId });
// ── Drivers ──────────────────────────────────────────────────────────────── // ── Drivers ────────────────────────────────────────────────────────────────
const [drivers, setDrivers] = React.useState([]); const [drivers, setDrivers] = React.useState([]);

View File

@ -594,3 +594,31 @@ export const fetchOrderGroups = async ({ details = true } = {}) => {
}).filter(Boolean); }).filter(Boolean);
}, "Ошибка загрузки групп доставки"); }, "Ошибка загрузки групп доставки");
}; };
export const fetchOrderGroupById = async (orderGroupId) => {
return safeSupabaseCall(async () => {
const client = requireSupabase();
const { data, error } = await client
.from("order_groups")
.select(ORDER_GROUP_SELECT_FIELDS)
.eq("id", orderGroupId)
.single();
if (error) {
throw error;
}
const group = mapOrderGroupRowToDeliveryGroup(data);
if (group && group.assignedDriverId && !group.assignedDriverName) {
const { data: drivers, error: driversError } = await client.rpc("get_drivers");
if (!driversError && drivers) {
const driver = drivers.find((d) => d.id === group.assignedDriverId);
if (driver) {
group.assignedDriverName = driver.name || driver.email;
}
}
}
return group;
}, "Ошибка загрузки группы доставки");
};