feat: persist hydrogen order pages
This commit is contained in:
@@ -117,6 +117,7 @@ export default function HydrogenDaily() {
|
|||||||
startDate: nextRange.start,
|
startDate: nextRange.start,
|
||||||
endDate: nextRange.end,
|
endDate: nextRange.end,
|
||||||
selectedDate: undefined,
|
selectedDate: undefined,
|
||||||
|
orderPage: undefined,
|
||||||
}, 'replace');
|
}, 'replace');
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -132,6 +133,7 @@ export default function HydrogenDaily() {
|
|||||||
startDate: normalized.start,
|
startDate: normalized.start,
|
||||||
endDate: normalized.end,
|
endDate: normalized.end,
|
||||||
selectedDate: undefined,
|
selectedDate: undefined,
|
||||||
|
orderPage: undefined,
|
||||||
}, 'replace');
|
}, 'replace');
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -142,6 +144,7 @@ export default function HydrogenDaily() {
|
|||||||
vehicleScope: next,
|
vehicleScope: next,
|
||||||
startDate: effectiveRange.start,
|
startDate: effectiveRange.start,
|
||||||
endDate: effectiveRange.end,
|
endDate: effectiveRange.end,
|
||||||
|
orderPage: undefined,
|
||||||
}, 'replace');
|
}, 'replace');
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -162,6 +165,7 @@ export default function HydrogenDaily() {
|
|||||||
startDate: effectiveRange.start,
|
startDate: effectiveRange.start,
|
||||||
endDate: effectiveRange.end,
|
endDate: effectiveRange.end,
|
||||||
selectedDate: date,
|
selectedDate: date,
|
||||||
|
orderPage: undefined,
|
||||||
}, 'push');
|
}, 'push');
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -172,9 +176,17 @@ export default function HydrogenDaily() {
|
|||||||
startDate: effectiveRange.start,
|
startDate: effectiveRange.start,
|
||||||
endDate: effectiveRange.end,
|
endDate: effectiveRange.end,
|
||||||
selectedDate: undefined,
|
selectedDate: undefined,
|
||||||
|
orderPage: undefined,
|
||||||
}, 'replace');
|
}, 'replace');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const changeOrderPage = useCallback((page: number, mode: 'push' | 'replace') => {
|
||||||
|
commitDrillContext({
|
||||||
|
...drillContext,
|
||||||
|
orderPage: page > 1 ? page : undefined,
|
||||||
|
}, mode);
|
||||||
|
}, [commitDrillContext, drillContext]);
|
||||||
|
|
||||||
const retryLoad = () => {
|
const retryLoad = () => {
|
||||||
setRows(null);
|
setRows(null);
|
||||||
setError(null);
|
setError(null);
|
||||||
@@ -388,9 +400,11 @@ export default function HydrogenDaily() {
|
|||||||
<HydrogenOrders
|
<HydrogenOrders
|
||||||
date={selectedDate}
|
date={selectedDate}
|
||||||
dailyRow={selectedDailyRow}
|
dailyRow={selectedDailyRow}
|
||||||
|
page={drillContext.orderPage ?? 1}
|
||||||
vehicleScope={vehicleScope}
|
vehicleScope={vehicleScope}
|
||||||
stationId={selectedStationId}
|
stationId={selectedStationId}
|
||||||
customerName={selectedCustomerName}
|
customerName={selectedCustomerName}
|
||||||
|
onPageChange={changeOrderPage}
|
||||||
onClose={closeOrders}
|
onClose={closeOrders}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -13,41 +13,47 @@ function fmtMoney(value: number): string {
|
|||||||
export default function HydrogenOrders({
|
export default function HydrogenOrders({
|
||||||
date,
|
date,
|
||||||
dailyRow,
|
dailyRow,
|
||||||
|
page,
|
||||||
vehicleScope,
|
vehicleScope,
|
||||||
stationId,
|
stationId,
|
||||||
customerName,
|
customerName,
|
||||||
|
onPageChange,
|
||||||
onClose,
|
onClose,
|
||||||
}: {
|
}: {
|
||||||
date: string;
|
date: string;
|
||||||
dailyRow?: HydrogenDailyRow;
|
dailyRow?: HydrogenDailyRow;
|
||||||
|
page: number;
|
||||||
vehicleScope: CustomerType;
|
vehicleScope: CustomerType;
|
||||||
stationId?: number;
|
stationId?: number;
|
||||||
customerName?: string;
|
customerName?: string;
|
||||||
|
onPageChange: (page: number, mode: 'push' | 'replace') => void;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
}) {
|
}) {
|
||||||
const [page, setPage] = useState(1);
|
|
||||||
const [data, setData] = useState<HydrogenOrderResponse | null>(null);
|
const [data, setData] = useState<HydrogenOrderResponse | null>(null);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
const [retryKey, setRetryKey] = useState(0);
|
const [retryKey, setRetryKey] = useState(0);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setPage(1);
|
|
||||||
}, [vehicleScope, customerName, date, stationId]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let cancelled = false;
|
let cancelled = false;
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setError(null);
|
setError(null);
|
||||||
setData(null);
|
setData(null);
|
||||||
fetchHydrogenOrders({ date, customer: vehicleScope, stationId, customerName, page, limit: 20 })
|
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 => {
|
.catch(loadError => {
|
||||||
if (!cancelled) setError(loadError instanceof Error ? loadError.message : String(loadError));
|
if (!cancelled) setError(loadError instanceof Error ? loadError.message : String(loadError));
|
||||||
})
|
})
|
||||||
.finally(() => { if (!cancelled) setLoading(false); });
|
.finally(() => { if (!cancelled) setLoading(false); });
|
||||||
return () => { cancelled = true; };
|
return () => { cancelled = true; };
|
||||||
}, [vehicleScope, customerName, date, page, retryKey, stationId]);
|
}, [vehicleScope, customerName, date, onPageChange, page, retryKey, stationId]);
|
||||||
|
|
||||||
const totalPages = data?.totalPages ?? 1;
|
const totalPages = data?.totalPages ?? 1;
|
||||||
const scope = customerName
|
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">
|
<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>
|
<span className="text-[10px] font-bold text-slate-400">第 {page} / {totalPages} 页</span>
|
||||||
<div className="flex gap-2">
|
<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={() => 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={() => 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.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>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
) : null}
|
) : null}
|
||||||
|
|||||||
@@ -82,20 +82,30 @@ test('clears station parameters when returning to overview', () => {
|
|||||||
assert.equal(url, '/energy?company=5&hydrogenScope=lingniu#hydrogen');
|
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(
|
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.selectedDate, '2026-08-05');
|
||||||
|
assert.equal(context.orderPage, 3);
|
||||||
assert.equal(
|
assert.equal(
|
||||||
buildHydrogenDrillUrl(
|
buildHydrogenDrillUrl(
|
||||||
{ pathname: '/energy', search: '?company=5', hash: '#hydrogen' },
|
{ pathname: '/energy', search: '?company=5', hash: '#hydrogen' },
|
||||||
context,
|
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(
|
assert.equal(
|
||||||
parseHydrogenDrillContext('?hydrogenStart=2026-08-01&hydrogenEnd=2026-08-07&hydrogenDate=2026-08-08').selectedDate,
|
parseHydrogenDrillContext('?hydrogenStart=2026-08-01&hydrogenEnd=2026-08-07&hydrogenDate=2026-08-08').selectedDate,
|
||||||
undefined,
|
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;
|
startDate?: string;
|
||||||
endDate?: string;
|
endDate?: string;
|
||||||
selectedDate?: string;
|
selectedDate?: string;
|
||||||
|
orderPage?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface LocationParts {
|
interface LocationParts {
|
||||||
@@ -74,6 +75,8 @@ export function parseHydrogenDrillContext(search: string): HydrogenDrillContext
|
|||||||
const rangeEnd = startDate && endDate ? (startDate <= endDate ? endDate : startDate) : undefined;
|
const rangeEnd = startDate && endDate ? (startDate <= endDate ? endDate : startDate) : undefined;
|
||||||
if (selectedDate && (!rangeStart || !rangeEnd || (selectedDate >= rangeStart && selectedDate <= rangeEnd))) {
|
if (selectedDate && (!rangeStart || !rangeEnd || (selectedDate >= rangeStart && selectedDate <= rangeEnd))) {
|
||||||
context.selectedDate = selectedDate;
|
context.selectedDate = selectedDate;
|
||||||
|
const orderPage = positiveInteger(params.get('hydrogenPage'));
|
||||||
|
if (orderPage && orderPage > 1) context.orderPage = orderPage;
|
||||||
}
|
}
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
@@ -93,6 +96,7 @@ export function buildHydrogenDrillUrl(
|
|||||||
'hydrogenStart',
|
'hydrogenStart',
|
||||||
'hydrogenEnd',
|
'hydrogenEnd',
|
||||||
'hydrogenDate',
|
'hydrogenDate',
|
||||||
|
'hydrogenPage',
|
||||||
]) {
|
]) {
|
||||||
params.delete(key);
|
params.delete(key);
|
||||||
}
|
}
|
||||||
@@ -110,6 +114,9 @@ export function buildHydrogenDrillUrl(
|
|||||||
if (context.startDate) params.set('hydrogenStart', context.startDate);
|
if (context.startDate) params.set('hydrogenStart', context.startDate);
|
||||||
if (context.endDate) params.set('hydrogenEnd', context.endDate);
|
if (context.endDate) params.set('hydrogenEnd', context.endDate);
|
||||||
if (context.selectedDate) params.set('hydrogenDate', context.selectedDate);
|
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();
|
const query = params.toString();
|
||||||
return `${location.pathname}${query ? `?${query}` : ''}${location.hash}`;
|
return `${location.pathname}${query ? `?${query}` : ''}${location.hash}`;
|
||||||
|
|||||||
Reference in New Issue
Block a user