feat: persist mileage monitoring context
This commit is contained in:
@@ -24,6 +24,11 @@ import {
|
||||
type MileageDrillContext,
|
||||
} from './drill-context';
|
||||
import { formatMileageSnapshotTime } from './data-freshness';
|
||||
import {
|
||||
buildMileageMonitoringUrl,
|
||||
parseMileageMonitoringContext,
|
||||
type MileageMonitoringContext,
|
||||
} from './monitoring-context';
|
||||
|
||||
const HIGH_MILEAGE_ALERT_TARGETS = new Set([
|
||||
'交投40辆4.5T普货',
|
||||
@@ -454,10 +459,11 @@ export default function MonitoringView() {
|
||||
const [drillContext, setDrillContext] = useState<MileageDrillContext>(() => (
|
||||
parseMileageDrillContext(window.location.search)
|
||||
));
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const [filterDept, setFilterDept] = useState('All');
|
||||
const [sortBy, setSortBy] = useState<'today' | 'total' | 'statisticTime'>('today');
|
||||
const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('desc');
|
||||
const [initialMonitoringContext] = useState(() => parseMileageMonitoringContext(window.location.search));
|
||||
const [searchTerm, setSearchTerm] = useState(initialMonitoringContext.search || '');
|
||||
const [filterDept, setFilterDept] = useState(initialMonitoringContext.department || 'All');
|
||||
const [sortBy, setSortBy] = useState<'today' | 'total' | 'statisticTime'>(initialMonitoringContext.sortBy);
|
||||
const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>(initialMonitoringContext.sortOrder);
|
||||
const [isFilterOpen, setIsFilterOpen] = useState(false);
|
||||
const [isFullscreen, setIsFullscreen] = useState(false);
|
||||
const [fullscreenVehicles, setFullscreenVehicles] = useState<MonitoringVehicle[]>([]);
|
||||
@@ -469,24 +475,31 @@ export default function MonitoringView() {
|
||||
const [fullscreenUpdatedAt, setFullscreenUpdatedAt] = useState<string | null>(null);
|
||||
|
||||
// New filters from image
|
||||
const [filterPlates, setFilterPlates] = useState<string[]>(() => (
|
||||
drillContext.level === 'vehicle' && drillContext.plate ? [drillContext.plate] : []
|
||||
const [filterPlates, setFilterPlates] = useState<string[]>(initialMonitoringContext.plates);
|
||||
const [drillPlateFallback, setDrillPlateFallback] = useState<string | undefined>(() => (
|
||||
drillContext.level === 'vehicle' && drillContext.plate ? drillContext.plate : undefined
|
||||
));
|
||||
const [filterCustomer, setFilterCustomer] = useState('All');
|
||||
const [filterProject, setFilterProject] = useState('All');
|
||||
const [filterEntity, setFilterEntity] = useState('All');
|
||||
const [filterRentStatus, setFilterRentStatus] = useState('All');
|
||||
const [filterPlatePrefix, setFilterPlatePrefix] = useState('All');
|
||||
const [filterTargetNames, setFilterTargetNames] = useState<string[]>([]);
|
||||
const [filterRegion, setFilterRegion] = useState('All');
|
||||
const [filterBrands, setFilterBrands] = useState<string[]>([]);
|
||||
const [filterMileageRange, setFilterMileageRange] = useState({ min: '', max: '' });
|
||||
const [appliedMileageRange, setAppliedMileageRange] = useState({ min: '', max: '' });
|
||||
const [filterCustomer, setFilterCustomer] = useState(initialMonitoringContext.customer || 'All');
|
||||
const [filterProject, setFilterProject] = useState(initialMonitoringContext.project || 'All');
|
||||
const [filterEntity, setFilterEntity] = useState(initialMonitoringContext.entity || 'All');
|
||||
const [filterRentStatus, setFilterRentStatus] = useState(initialMonitoringContext.rentStatus || 'All');
|
||||
const [filterPlatePrefix, setFilterPlatePrefix] = useState(initialMonitoringContext.platePrefix || 'All');
|
||||
const [filterTargetNames, setFilterTargetNames] = useState<string[]>(initialMonitoringContext.targetNames);
|
||||
const [filterRegion, setFilterRegion] = useState(initialMonitoringContext.region || 'All');
|
||||
const [filterBrands, setFilterBrands] = useState<string[]>(initialMonitoringContext.brands);
|
||||
const [filterMileageRange, setFilterMileageRange] = useState({
|
||||
min: initialMonitoringContext.mileageMin || '',
|
||||
max: initialMonitoringContext.mileageMax || '',
|
||||
});
|
||||
const [appliedMileageRange, setAppliedMileageRange] = useState({
|
||||
min: initialMonitoringContext.mileageMin || '',
|
||||
max: initialMonitoringContext.mileageMax || '',
|
||||
});
|
||||
const [exporting, setExporting] = useState(false);
|
||||
const [exportStatus, setExportStatus] = useState<{ type: 'success' | 'error'; message: string } | null>(null);
|
||||
const [rangeStart, setRangeStart] = useState(() => drillContext.startDate || defaultMileageDate());
|
||||
const [rangeEnd, setRangeEnd] = useState(() => drillContext.endDate || defaultMileageDate());
|
||||
const [sourcePriority, setSourcePriority] = useState<MileageSourceGroup[]>(drillContext.sourcePriority);
|
||||
const [rangeStart, setRangeStart] = useState(() => initialMonitoringContext.startDate || drillContext.startDate || defaultMileageDate());
|
||||
const [rangeEnd, setRangeEnd] = useState(() => initialMonitoringContext.endDate || drillContext.endDate || defaultMileageDate());
|
||||
const [sourcePriority, setSourcePriority] = useState<MileageSourceGroup[]>(initialMonitoringContext.sourcePriority);
|
||||
|
||||
const [vehicles, setVehicles] = useState<MonitoringVehicle[]>([]);
|
||||
const [stats, setStats] = useState<MonitoringStats>({ totalToday: 0, totalAll: 0, vehicleCount: 0, yesterdayTotal: 0 });
|
||||
@@ -515,6 +528,7 @@ export default function MonitoringView() {
|
||||
}, []);
|
||||
|
||||
const openVehicleDetail = useCallback((vehicle: MonitoringVehicle) => {
|
||||
setDrillPlateFallback(undefined);
|
||||
commitDrillContext({
|
||||
level: 'vehicle',
|
||||
plate: vehicle.plate,
|
||||
@@ -525,6 +539,7 @@ export default function MonitoringView() {
|
||||
}, [commitDrillContext, effectiveRange.end, effectiveRange.start, sourcePriority]);
|
||||
|
||||
const closeVehicleDetail = useCallback(() => {
|
||||
setDrillPlateFallback(undefined);
|
||||
commitDrillContext({
|
||||
level: 'overview',
|
||||
startDate: effectiveRange.start,
|
||||
@@ -541,11 +556,31 @@ export default function MonitoringView() {
|
||||
useEffect(() => {
|
||||
const handlePopState = () => {
|
||||
const next = parseMileageDrillContext(window.location.search);
|
||||
const nextMonitoring = parseMileageMonitoringContext(window.location.search);
|
||||
setDrillContext(next);
|
||||
if (next.startDate) setRangeStart(next.startDate);
|
||||
if (next.endDate) setRangeEnd(next.endDate);
|
||||
setSourcePriority(next.sourcePriority);
|
||||
if (next.level === 'vehicle' && next.plate) setFilterPlates([next.plate]);
|
||||
setRangeStart(nextMonitoring.startDate || defaultMileageDate());
|
||||
setRangeEnd(nextMonitoring.endDate || defaultMileageDate());
|
||||
setSourcePriority(nextMonitoring.sourcePriority);
|
||||
setFilterTargetNames(nextMonitoring.targetNames);
|
||||
setFilterRegion(nextMonitoring.region || 'All');
|
||||
setFilterPlates(nextMonitoring.plates);
|
||||
setDrillPlateFallback(next.level === 'vehicle' && next.plate ? next.plate : undefined);
|
||||
setFilterDept(nextMonitoring.department || 'All');
|
||||
setFilterCustomer(nextMonitoring.customer || 'All');
|
||||
setFilterProject(nextMonitoring.project || 'All');
|
||||
setFilterEntity(nextMonitoring.entity || 'All');
|
||||
setFilterRentStatus(nextMonitoring.rentStatus || 'All');
|
||||
setFilterBrands(nextMonitoring.brands);
|
||||
setFilterPlatePrefix(nextMonitoring.platePrefix || 'All');
|
||||
setSearchTerm(nextMonitoring.search || '');
|
||||
const nextMileageRange = {
|
||||
min: nextMonitoring.mileageMin || '',
|
||||
max: nextMonitoring.mileageMax || '',
|
||||
};
|
||||
setFilterMileageRange(nextMileageRange);
|
||||
setAppliedMileageRange(nextMileageRange);
|
||||
setSortBy(nextMonitoring.sortBy);
|
||||
setSortOrder(nextMonitoring.sortOrder);
|
||||
};
|
||||
window.addEventListener('popstate', handlePopState);
|
||||
return () => window.removeEventListener('popstate', handlePopState);
|
||||
@@ -565,6 +600,11 @@ export default function MonitoringView() {
|
||||
return inAlertTarget && Math.max(0, v.dailyKm || 0) >= HIGH_MILEAGE_ALERT_KM;
|
||||
}, [filterTargetNames]);
|
||||
|
||||
const requestPlates = useMemo(() => Array.from(new Set([
|
||||
...filterPlates,
|
||||
...(drillPlateFallback ? [drillPlateFallback] : []),
|
||||
])), [drillPlateFallback, filterPlates]);
|
||||
|
||||
const monitoringFilters = useMemo<MonitoringRequestParams>(() => ({
|
||||
search: searchTerm || undefined,
|
||||
dept: filterDept !== 'All' ? filterDept : undefined,
|
||||
@@ -575,13 +615,50 @@ export default function MonitoringView() {
|
||||
platePrefix: filterPlatePrefix !== 'All' ? filterPlatePrefix : undefined,
|
||||
targetNames: filterTargetNames.length > 0 ? filterTargetNames : undefined,
|
||||
region: filterRegion !== 'All' ? filterRegion : undefined,
|
||||
plate: filterPlates.length > 0 ? filterPlates.join(',') : undefined,
|
||||
plate: requestPlates.length > 0 ? requestPlates.join(',') : undefined,
|
||||
mileageMin: appliedMileageRange.min || undefined,
|
||||
mileageMax: appliedMileageRange.max || undefined,
|
||||
startDate: rangeStart || undefined,
|
||||
endDate: rangeEnd || undefined,
|
||||
brands: filterBrands.length > 0 ? filterBrands : undefined,
|
||||
sourcePriority,
|
||||
}), [
|
||||
appliedMileageRange.max,
|
||||
appliedMileageRange.min,
|
||||
filterBrands,
|
||||
filterCustomer,
|
||||
filterDept,
|
||||
filterEntity,
|
||||
filterPlatePrefix,
|
||||
filterProject,
|
||||
filterRegion,
|
||||
filterRentStatus,
|
||||
filterTargetNames,
|
||||
rangeEnd,
|
||||
rangeStart,
|
||||
requestPlates,
|
||||
searchTerm,
|
||||
sourcePriority,
|
||||
]);
|
||||
const monitoringUrlContext = useMemo<MileageMonitoringContext>(() => ({
|
||||
startDate: rangeStart || undefined,
|
||||
endDate: rangeEnd || undefined,
|
||||
sourcePriority,
|
||||
targetNames: filterTargetNames,
|
||||
region: filterRegion !== 'All' ? filterRegion : undefined,
|
||||
plates: filterPlates,
|
||||
department: filterDept !== 'All' ? filterDept : undefined,
|
||||
customer: filterCustomer !== 'All' ? filterCustomer : undefined,
|
||||
project: filterProject !== 'All' ? filterProject : undefined,
|
||||
entity: filterEntity !== 'All' ? filterEntity : undefined,
|
||||
rentStatus: filterRentStatus !== 'All' ? filterRentStatus : undefined,
|
||||
brands: filterBrands,
|
||||
platePrefix: filterPlatePrefix !== 'All' ? filterPlatePrefix : undefined,
|
||||
search: searchTerm || undefined,
|
||||
mileageMin: appliedMileageRange.min || undefined,
|
||||
mileageMax: appliedMileageRange.max || undefined,
|
||||
sortBy,
|
||||
sortOrder,
|
||||
}), [
|
||||
appliedMileageRange.max,
|
||||
appliedMileageRange.min,
|
||||
@@ -598,8 +675,17 @@ export default function MonitoringView() {
|
||||
rangeEnd,
|
||||
rangeStart,
|
||||
searchTerm,
|
||||
sortBy,
|
||||
sortOrder,
|
||||
sourcePriority,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
const nextUrl = buildMileageMonitoringUrl(window.location, monitoringUrlContext);
|
||||
const currentUrl = `${window.location.pathname}${window.location.search}${window.location.hash}`;
|
||||
if (nextUrl !== currentUrl) window.history.replaceState(null, '', nextUrl);
|
||||
}, [monitoringUrlContext]);
|
||||
|
||||
const monitoringRequestKey = useMemo(
|
||||
() => JSON.stringify({ ...monitoringFilters, sortBy, sortOrder }),
|
||||
[monitoringFilters, sortBy, sortOrder],
|
||||
@@ -705,6 +791,7 @@ export default function MonitoringView() {
|
||||
// 区域级联:plate 选项收窄后,剔除已选但已不属于该区域的车牌
|
||||
useEffect(() => {
|
||||
if (filterPlates.length === 0) return;
|
||||
if (filterOptions.plates.length === 0) return;
|
||||
const valid = new Set(filterOptions.plates);
|
||||
const next = filterPlates.filter(p => valid.has(p));
|
||||
if (next.length !== filterPlates.length) setFilterPlates(next);
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
import {
|
||||
buildMileageMonitoringUrl,
|
||||
parseMileageMonitoringContext,
|
||||
} from './monitoring-context.js';
|
||||
|
||||
test('parses a complete mileage monitoring context', () => {
|
||||
const context = parseMileageMonitoringContext(
|
||||
'?mileageStart=2026-08-01&mileageEnd=2026-08-07&mileageSource=gps,instrument'
|
||||
+ '&mileageBatch=%E4%BA%A4%E6%8A%95190%E8%BE%86&mileageBatch=%E7%BE%9A%E7%89%9B136%E8%BE%86'
|
||||
+ '&mileageRegion=%E5%B9%BF%E5%B7%9E&mileageFilterPlate=%E7%B2%A4A12345&mileageDepartment=%E4%B8%9A%E5%8A%A1%E4%B8%80%E9%83%A8'
|
||||
+ '&mileageCustomer=%E5%AE%A2%E6%88%B7A&mileageProject=%E9%A1%B9%E7%9B%AEA&mileageEntity=%E4%B8%BB%E4%BD%93A'
|
||||
+ '&mileageRentStatus=%E7%A7%9F%E8%B5%81&mileageBrand=%E7%8E%B0%E4%BB%A3&mileagePlatePrefix=%E7%B2%A4A'
|
||||
+ '&mileageSearch=123&mileageMin=10&mileageMax=500&mileageSort=total&mileageOrder=asc',
|
||||
);
|
||||
|
||||
assert.deepEqual(context, {
|
||||
startDate: '2026-08-01',
|
||||
endDate: '2026-08-07',
|
||||
sourcePriority: ['gps', 'instrument'],
|
||||
targetNames: ['交投190辆', '羚牛136辆'],
|
||||
region: '广州',
|
||||
plates: ['粤A12345'],
|
||||
department: '业务一部',
|
||||
customer: '客户A',
|
||||
project: '项目A',
|
||||
entity: '主体A',
|
||||
rentStatus: '租赁',
|
||||
brands: ['现代'],
|
||||
platePrefix: '粤A',
|
||||
search: '123',
|
||||
mileageMin: '10',
|
||||
mileageMax: '500',
|
||||
sortBy: 'total',
|
||||
sortOrder: 'asc',
|
||||
});
|
||||
});
|
||||
|
||||
test('normalizes invalid monitoring URL values', () => {
|
||||
const context = parseMileageMonitoringContext(
|
||||
'?mileageStart=invalid&mileageSource=unknown&mileageBatch=&mileageRegion=All&mileageSort=unknown&mileageOrder=unknown',
|
||||
);
|
||||
|
||||
assert.deepEqual(context, {
|
||||
startDate: undefined,
|
||||
endDate: undefined,
|
||||
sourcePriority: ['instrument'],
|
||||
targetNames: [],
|
||||
region: undefined,
|
||||
plates: [],
|
||||
department: undefined,
|
||||
customer: undefined,
|
||||
project: undefined,
|
||||
entity: undefined,
|
||||
rentStatus: undefined,
|
||||
brands: [],
|
||||
platePrefix: undefined,
|
||||
search: undefined,
|
||||
mileageMin: undefined,
|
||||
mileageMax: undefined,
|
||||
sortBy: 'today',
|
||||
sortOrder: 'desc',
|
||||
});
|
||||
});
|
||||
|
||||
test('builds monitoring state without removing drill or unrelated context', () => {
|
||||
const url = buildMileageMonitoringUrl(
|
||||
{
|
||||
pathname: '/asset',
|
||||
search: '?company=5&mileageLevel=vehicle&mileagePlate=%E7%B2%A4A08190F&mileageBatch=old',
|
||||
hash: '#mileage',
|
||||
},
|
||||
{
|
||||
startDate: '2026-08-01',
|
||||
endDate: '2026-08-07',
|
||||
sourcePriority: ['instrument'],
|
||||
targetNames: ['交投190辆', '羚牛136辆'],
|
||||
region: '广州',
|
||||
plates: ['粤A12345'],
|
||||
department: undefined,
|
||||
customer: undefined,
|
||||
project: undefined,
|
||||
entity: undefined,
|
||||
rentStatus: undefined,
|
||||
brands: [],
|
||||
platePrefix: undefined,
|
||||
search: undefined,
|
||||
mileageMin: undefined,
|
||||
mileageMax: undefined,
|
||||
sortBy: 'statisticTime',
|
||||
sortOrder: 'asc',
|
||||
},
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
url,
|
||||
'/asset?company=5&mileageLevel=vehicle&mileagePlate=%E7%B2%A4A08190F&mileageStart=2026-08-01&mileageEnd=2026-08-07&mileageSource=instrument&mileageBatch=%E4%BA%A4%E6%8A%95190%E8%BE%86&mileageBatch=%E7%BE%9A%E7%89%9B136%E8%BE%86&mileageRegion=%E5%B9%BF%E5%B7%9E&mileageFilterPlate=%E7%B2%A4A12345&mileageSort=statisticTime&mileageOrder=asc#mileage',
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,136 @@
|
||||
import type { MileageSourceGroup } from './types';
|
||||
|
||||
export type MonitoringSortBy = 'today' | 'total' | 'statisticTime';
|
||||
export type MonitoringSortOrder = 'asc' | 'desc';
|
||||
|
||||
export interface MileageMonitoringContext {
|
||||
startDate?: string;
|
||||
endDate?: string;
|
||||
sourcePriority: MileageSourceGroup[];
|
||||
targetNames: string[];
|
||||
region?: string;
|
||||
plates: string[];
|
||||
department?: string;
|
||||
customer?: string;
|
||||
project?: string;
|
||||
entity?: string;
|
||||
rentStatus?: string;
|
||||
brands: string[];
|
||||
platePrefix?: string;
|
||||
search?: string;
|
||||
mileageMin?: string;
|
||||
mileageMax?: string;
|
||||
sortBy: MonitoringSortBy;
|
||||
sortOrder: MonitoringSortOrder;
|
||||
}
|
||||
|
||||
interface LocationParts {
|
||||
pathname: string;
|
||||
search: string;
|
||||
hash: string;
|
||||
}
|
||||
|
||||
const DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
|
||||
const CONTEXT_KEYS = [
|
||||
'mileageStart',
|
||||
'mileageEnd',
|
||||
'mileageSource',
|
||||
'mileageBatch',
|
||||
'mileageRegion',
|
||||
'mileageFilterPlate',
|
||||
'mileageDepartment',
|
||||
'mileageCustomer',
|
||||
'mileageProject',
|
||||
'mileageEntity',
|
||||
'mileageRentStatus',
|
||||
'mileageBrand',
|
||||
'mileagePlatePrefix',
|
||||
'mileageSearch',
|
||||
'mileageMin',
|
||||
'mileageMax',
|
||||
'mileageSort',
|
||||
'mileageOrder',
|
||||
] as const;
|
||||
|
||||
function validDate(value: string | null): string | undefined {
|
||||
if (!value || !DATE_PATTERN.test(value)) return undefined;
|
||||
const timestamp = Date.parse(`${value}T00:00:00+08:00`);
|
||||
return Number.isFinite(timestamp) ? value : undefined;
|
||||
}
|
||||
|
||||
function boundedValue(value: string | null, maxLength = 200): string | undefined {
|
||||
const normalized = value?.trim();
|
||||
if (!normalized || normalized === 'All') return undefined;
|
||||
return normalized.slice(0, maxLength);
|
||||
}
|
||||
|
||||
function uniqueValues(values: string[], limit = 200): string[] {
|
||||
return Array.from(new Set(values.map(value => boundedValue(value)).filter((value): value is string => !!value))).slice(0, limit);
|
||||
}
|
||||
|
||||
function parseSourcePriority(value: string | null): MileageSourceGroup[] {
|
||||
const sources = value
|
||||
?.split(',')
|
||||
.filter((source): source is MileageSourceGroup => source === 'instrument' || source === 'gps');
|
||||
return sources && sources.length > 0 ? Array.from(new Set(sources)).slice(0, 2) : ['instrument'];
|
||||
}
|
||||
|
||||
function appendValues(params: URLSearchParams, key: string, values: string[]): void {
|
||||
uniqueValues(values).forEach(value => params.append(key, value));
|
||||
}
|
||||
|
||||
export function parseMileageMonitoringContext(search: string): MileageMonitoringContext {
|
||||
const params = new URLSearchParams(search);
|
||||
const rawSortBy = params.get('mileageSort');
|
||||
const rawSortOrder = params.get('mileageOrder');
|
||||
return {
|
||||
startDate: validDate(params.get('mileageStart')),
|
||||
endDate: validDate(params.get('mileageEnd')),
|
||||
sourcePriority: parseSourcePriority(params.get('mileageSource')),
|
||||
targetNames: uniqueValues(params.getAll('mileageBatch')),
|
||||
region: boundedValue(params.get('mileageRegion')),
|
||||
plates: uniqueValues(params.getAll('mileageFilterPlate')),
|
||||
department: boundedValue(params.get('mileageDepartment')),
|
||||
customer: boundedValue(params.get('mileageCustomer')),
|
||||
project: boundedValue(params.get('mileageProject')),
|
||||
entity: boundedValue(params.get('mileageEntity')),
|
||||
rentStatus: boundedValue(params.get('mileageRentStatus')),
|
||||
brands: uniqueValues(params.getAll('mileageBrand')),
|
||||
platePrefix: boundedValue(params.get('mileagePlatePrefix')),
|
||||
search: boundedValue(params.get('mileageSearch')),
|
||||
mileageMin: boundedValue(params.get('mileageMin'), 32),
|
||||
mileageMax: boundedValue(params.get('mileageMax'), 32),
|
||||
sortBy: rawSortBy === 'total' || rawSortBy === 'statisticTime' ? rawSortBy : 'today',
|
||||
sortOrder: rawSortOrder === 'asc' ? 'asc' : 'desc',
|
||||
};
|
||||
}
|
||||
|
||||
export function buildMileageMonitoringUrl(
|
||||
location: LocationParts,
|
||||
context: MileageMonitoringContext,
|
||||
): string {
|
||||
const params = new URLSearchParams(location.search);
|
||||
CONTEXT_KEYS.forEach(key => params.delete(key));
|
||||
|
||||
if (context.startDate) params.set('mileageStart', context.startDate);
|
||||
if (context.endDate) params.set('mileageEnd', context.endDate);
|
||||
if (context.sourcePriority.length > 0) params.set('mileageSource', context.sourcePriority.join(','));
|
||||
appendValues(params, 'mileageBatch', context.targetNames);
|
||||
if (context.region) params.set('mileageRegion', context.region);
|
||||
appendValues(params, 'mileageFilterPlate', context.plates);
|
||||
if (context.department) params.set('mileageDepartment', context.department);
|
||||
if (context.customer) params.set('mileageCustomer', context.customer);
|
||||
if (context.project) params.set('mileageProject', context.project);
|
||||
if (context.entity) params.set('mileageEntity', context.entity);
|
||||
if (context.rentStatus) params.set('mileageRentStatus', context.rentStatus);
|
||||
appendValues(params, 'mileageBrand', context.brands);
|
||||
if (context.platePrefix) params.set('mileagePlatePrefix', context.platePrefix);
|
||||
if (context.search) params.set('mileageSearch', context.search);
|
||||
if (context.mileageMin) params.set('mileageMin', context.mileageMin);
|
||||
if (context.mileageMax) params.set('mileageMax', context.mileageMax);
|
||||
if (context.sortBy !== 'today') params.set('mileageSort', context.sortBy);
|
||||
if (context.sortOrder !== 'desc') params.set('mileageOrder', context.sortOrder);
|
||||
|
||||
const query = params.toString();
|
||||
return `${location.pathname}${query ? `?${query}` : ''}${location.hash}`;
|
||||
}
|
||||
Reference in New Issue
Block a user