feat: persist hydrogen order pages
This commit is contained in:
@@ -117,6 +117,7 @@ export default function HydrogenDaily() {
|
||||
startDate: nextRange.start,
|
||||
endDate: nextRange.end,
|
||||
selectedDate: undefined,
|
||||
orderPage: undefined,
|
||||
}, 'replace');
|
||||
};
|
||||
|
||||
@@ -132,6 +133,7 @@ export default function HydrogenDaily() {
|
||||
startDate: normalized.start,
|
||||
endDate: normalized.end,
|
||||
selectedDate: undefined,
|
||||
orderPage: undefined,
|
||||
}, 'replace');
|
||||
};
|
||||
|
||||
@@ -142,6 +144,7 @@ export default function HydrogenDaily() {
|
||||
vehicleScope: next,
|
||||
startDate: effectiveRange.start,
|
||||
endDate: effectiveRange.end,
|
||||
orderPage: undefined,
|
||||
}, 'replace');
|
||||
};
|
||||
|
||||
@@ -162,6 +165,7 @@ export default function HydrogenDaily() {
|
||||
startDate: effectiveRange.start,
|
||||
endDate: effectiveRange.end,
|
||||
selectedDate: date,
|
||||
orderPage: undefined,
|
||||
}, 'push');
|
||||
};
|
||||
|
||||
@@ -172,9 +176,17 @@ export default function HydrogenDaily() {
|
||||
startDate: effectiveRange.start,
|
||||
endDate: effectiveRange.end,
|
||||
selectedDate: undefined,
|
||||
orderPage: undefined,
|
||||
}, 'replace');
|
||||
};
|
||||
|
||||
const changeOrderPage = useCallback((page: number, mode: 'push' | 'replace') => {
|
||||
commitDrillContext({
|
||||
...drillContext,
|
||||
orderPage: page > 1 ? page : undefined,
|
||||
}, mode);
|
||||
}, [commitDrillContext, drillContext]);
|
||||
|
||||
const retryLoad = () => {
|
||||
setRows(null);
|
||||
setError(null);
|
||||
@@ -388,9 +400,11 @@ export default function HydrogenDaily() {
|
||||
<HydrogenOrders
|
||||
date={selectedDate}
|
||||
dailyRow={selectedDailyRow}
|
||||
page={drillContext.orderPage ?? 1}
|
||||
vehicleScope={vehicleScope}
|
||||
stationId={selectedStationId}
|
||||
customerName={selectedCustomerName}
|
||||
onPageChange={changeOrderPage}
|
||||
onClose={closeOrders}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -13,41 +13,47 @@ function fmtMoney(value: number): string {
|
||||
export default function HydrogenOrders({
|
||||
date,
|
||||
dailyRow,
|
||||
page,
|
||||
vehicleScope,
|
||||
stationId,
|
||||
customerName,
|
||||
onPageChange,
|
||||
onClose,
|
||||
}: {
|
||||
date: string;
|
||||
dailyRow?: HydrogenDailyRow;
|
||||
page: number;
|
||||
vehicleScope: CustomerType;
|
||||
stationId?: number;
|
||||
customerName?: string;
|
||||
onPageChange: (page: number, mode: 'push' | 'replace') => void;
|
||||
onClose: () => void;
|
||||
}) {
|
||||
const [page, setPage] = useState(1);
|
||||
const [data, setData] = useState<HydrogenOrderResponse | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [retryKey, setRetryKey] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
setPage(1);
|
||||
}, [vehicleScope, customerName, date, stationId]);
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
setData(null);
|
||||
fetchHydrogenOrders({ date, customer: vehicleScope, stationId, customerName, page, limit: 20 })
|
||||
.then(result => { if (!cancelled) setData(result); })
|
||||
.then(result => {
|
||||
if (cancelled) return;
|
||||
if (page > result.totalPages) {
|
||||
onPageChange(result.totalPages, 'replace');
|
||||
return;
|
||||
}
|
||||
setData(result);
|
||||
})
|
||||
.catch(loadError => {
|
||||
if (!cancelled) setError(loadError instanceof Error ? loadError.message : String(loadError));
|
||||
})
|
||||
.finally(() => { if (!cancelled) setLoading(false); });
|
||||
return () => { cancelled = true; };
|
||||
}, [vehicleScope, customerName, date, page, retryKey, stationId]);
|
||||
}, [vehicleScope, customerName, date, onPageChange, page, retryKey, stationId]);
|
||||
|
||||
const totalPages = data?.totalPages ?? 1;
|
||||
const scope = customerName
|
||||
@@ -165,8 +171,8 @@ export default function HydrogenOrders({
|
||||
<footer className="flex items-center justify-between border-t border-slate-100 px-3 py-3 md:px-4">
|
||||
<span className="text-[10px] font-bold text-slate-400">第 {page} / {totalPages} 页</span>
|
||||
<div className="flex gap-2">
|
||||
<button type="button" onClick={() => setPage(current => Math.max(1, current - 1))} disabled={page <= 1 || loading} className="flex h-8 w-8 items-center justify-center rounded-lg border border-slate-200 text-slate-500 disabled:opacity-30" aria-label="上一页加氢订单" title="上一页"><ChevronLeft size={14} /></button>
|
||||
<button type="button" onClick={() => setPage(current => Math.min(totalPages, current + 1))} disabled={page >= totalPages || loading} className="flex h-8 w-8 items-center justify-center rounded-lg border border-slate-200 text-slate-500 disabled:opacity-30" aria-label="下一页加氢订单" title="下一页"><ChevronRight size={14} /></button>
|
||||
<button type="button" onClick={() => onPageChange(Math.max(1, page - 1), 'push')} disabled={page <= 1 || loading} className="flex h-8 w-8 items-center justify-center rounded-lg border border-slate-200 text-slate-500 disabled:opacity-30" aria-label="上一页加氢订单" title="上一页"><ChevronLeft size={14} /></button>
|
||||
<button type="button" onClick={() => onPageChange(Math.min(totalPages, page + 1), 'push')} disabled={page >= totalPages || loading} className="flex h-8 w-8 items-center justify-center rounded-lg border border-slate-200 text-slate-500 disabled:opacity-30" aria-label="下一页加氢订单" title="下一页"><ChevronRight size={14} /></button>
|
||||
</div>
|
||||
</footer>
|
||||
) : null}
|
||||
|
||||
@@ -82,20 +82,30 @@ test('clears station parameters when returning to overview', () => {
|
||||
assert.equal(url, '/energy?company=5&hydrogenScope=lingniu#hydrogen');
|
||||
});
|
||||
|
||||
test('preserves a selected order date in the hydrogen analysis URL', () => {
|
||||
test('preserves a selected order date and page in the hydrogen analysis URL', () => {
|
||||
const context = parseHydrogenDrillContext(
|
||||
'?hydrogenScope=lingniu&hydrogenStart=2026-08-01&hydrogenEnd=2026-08-07&hydrogenDate=2026-08-05',
|
||||
'?hydrogenScope=lingniu&hydrogenStart=2026-08-01&hydrogenEnd=2026-08-07&hydrogenDate=2026-08-05&hydrogenPage=3',
|
||||
);
|
||||
assert.equal(context.selectedDate, '2026-08-05');
|
||||
assert.equal(context.orderPage, 3);
|
||||
assert.equal(
|
||||
buildHydrogenDrillUrl(
|
||||
{ pathname: '/energy', search: '?company=5', hash: '#hydrogen' },
|
||||
context,
|
||||
),
|
||||
'/energy?company=5&hydrogenScope=lingniu&hydrogenStart=2026-08-01&hydrogenEnd=2026-08-07&hydrogenDate=2026-08-05#hydrogen',
|
||||
'/energy?company=5&hydrogenScope=lingniu&hydrogenStart=2026-08-01&hydrogenEnd=2026-08-07&hydrogenDate=2026-08-05&hydrogenPage=3#hydrogen',
|
||||
);
|
||||
assert.equal(
|
||||
parseHydrogenDrillContext('?hydrogenStart=2026-08-01&hydrogenEnd=2026-08-07&hydrogenDate=2026-08-08').selectedDate,
|
||||
undefined,
|
||||
);
|
||||
assert.equal(parseHydrogenDrillContext('?hydrogenPage=3').orderPage, undefined);
|
||||
assert.equal(parseHydrogenDrillContext('?hydrogenDate=2026-08-05&hydrogenPage=0').orderPage, undefined);
|
||||
assert.equal(
|
||||
buildHydrogenDrillUrl(
|
||||
{ pathname: '/energy', search: '', hash: '#hydrogen' },
|
||||
{ level: 'overview', vehicleScope: 'lingniu', orderPage: 3 },
|
||||
),
|
||||
'/energy?hydrogenScope=lingniu#hydrogen',
|
||||
);
|
||||
});
|
||||
|
||||
@@ -12,6 +12,7 @@ export interface HydrogenDrillContext {
|
||||
startDate?: string;
|
||||
endDate?: string;
|
||||
selectedDate?: string;
|
||||
orderPage?: number;
|
||||
}
|
||||
|
||||
interface LocationParts {
|
||||
@@ -74,6 +75,8 @@ export function parseHydrogenDrillContext(search: string): HydrogenDrillContext
|
||||
const rangeEnd = startDate && endDate ? (startDate <= endDate ? endDate : startDate) : undefined;
|
||||
if (selectedDate && (!rangeStart || !rangeEnd || (selectedDate >= rangeStart && selectedDate <= rangeEnd))) {
|
||||
context.selectedDate = selectedDate;
|
||||
const orderPage = positiveInteger(params.get('hydrogenPage'));
|
||||
if (orderPage && orderPage > 1) context.orderPage = orderPage;
|
||||
}
|
||||
return context;
|
||||
}
|
||||
@@ -93,6 +96,7 @@ export function buildHydrogenDrillUrl(
|
||||
'hydrogenStart',
|
||||
'hydrogenEnd',
|
||||
'hydrogenDate',
|
||||
'hydrogenPage',
|
||||
]) {
|
||||
params.delete(key);
|
||||
}
|
||||
@@ -110,6 +114,9 @@ export function buildHydrogenDrillUrl(
|
||||
if (context.startDate) params.set('hydrogenStart', context.startDate);
|
||||
if (context.endDate) params.set('hydrogenEnd', context.endDate);
|
||||
if (context.selectedDate) params.set('hydrogenDate', context.selectedDate);
|
||||
if (context.selectedDate && context.orderPage && context.orderPage > 1) {
|
||||
params.set('hydrogenPage', String(context.orderPage));
|
||||
}
|
||||
|
||||
const query = params.toString();
|
||||
return `${location.pathname}${query ? `?${query}` : ''}${location.hash}`;
|
||||
|
||||
Reference in New Issue
Block a user