sgerp-frontend-lib 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/constants/timezones.d.ts +7 -2
- package/dist/constants/timezones.d.ts.map +1 -1
- package/dist/constants/timezones.js +17 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/locales/locale-server.d.ts +1 -1
- package/dist/locales/locale-server.d.ts.map +1 -1
- package/dist/locales/locale-server.js +5 -0
- package/dist/locales/locale.d.ts +1 -1
- package/dist/locales/locale.d.ts.map +1 -1
- package/dist/locales/locale.js +6 -2
- package/dist/locales/locale_en.d.ts.map +1 -1
- package/dist/locales/locale_en.js +236 -1
- package/dist/locales/locale_id.d.ts +2 -0
- package/dist/locales/locale_id.d.ts.map +1 -0
- package/dist/locales/locale_id.js +2473 -0
- package/dist/locales/locale_ja.d.ts.map +1 -1
- package/dist/locales/locale_ja.js +188 -1
- package/dist/locales/locale_ms.d.ts.map +1 -1
- package/dist/locales/locale_ms.js +60 -1
- package/dist/locales/locale_tl.d.ts +2 -0
- package/dist/locales/locale_tl.d.ts.map +1 -0
- package/dist/locales/locale_tl.js +1122 -0
- package/dist/sgerp/collection.d.ts.map +1 -1
- package/dist/sgerp/collection.js +18 -4
- package/dist/sgerp/domains.d.ts +16 -2
- package/dist/sgerp/domains.d.ts.map +1 -1
- package/dist/sgerp/domains.js +47 -1
- package/dist/sgerp/hooks/use-selection-state.d.ts +37 -0
- package/dist/sgerp/hooks/use-selection-state.d.ts.map +1 -0
- package/dist/sgerp/hooks/use-selection-state.js +121 -0
- package/dist/sgerp/hooks/use-simulation-data.d.ts +105 -0
- package/dist/sgerp/hooks/use-simulation-data.d.ts.map +1 -0
- package/dist/sgerp/hooks/use-simulation-data.js +146 -0
- package/dist/sgerp/hooks/use-simulation-state.d.ts +80 -0
- package/dist/sgerp/hooks/use-simulation-state.d.ts.map +1 -0
- package/dist/sgerp/hooks/use-simulation-state.js +161 -0
- package/dist/sgerp/index.d.ts +10 -3
- package/dist/sgerp/index.d.ts.map +1 -1
- package/dist/sgerp/index.js +30 -2
- package/dist/sgerp/simulation-logic/fetchUtils.d.ts +18 -0
- package/dist/sgerp/simulation-logic/fetchUtils.d.ts.map +1 -1
- package/dist/sgerp/simulation-logic/fetchUtils.js +196 -0
- package/dist/sgerp/simulation-logic/index.d.ts +7 -2
- package/dist/sgerp/simulation-logic/index.d.ts.map +1 -1
- package/dist/sgerp/simulation-logic/index.js +18 -1
- package/dist/sgerp/simulation-logic/liveUpdates.d.ts +102 -0
- package/dist/sgerp/simulation-logic/liveUpdates.d.ts.map +1 -0
- package/dist/sgerp/simulation-logic/liveUpdates.js +87 -0
- package/dist/sgerp/simulation-logic/prepareSimulationData.d.ts +36 -0
- package/dist/sgerp/simulation-logic/prepareSimulationData.d.ts.map +1 -0
- package/dist/sgerp/simulation-logic/prepareSimulationData.js +34 -0
- package/dist/sgerp/simulation-logic/routeCalculationUtils.d.ts +7 -1
- package/dist/sgerp/simulation-logic/routeCalculationUtils.d.ts.map +1 -1
- package/dist/sgerp/simulation-logic/routeCalculationUtils.js +81 -0
- package/dist/sgerp/simulation-logic/vrpStatsCalculator.d.ts +52 -0
- package/dist/sgerp/simulation-logic/vrpStatsCalculator.d.ts.map +1 -0
- package/dist/sgerp/simulation-logic/vrpStatsCalculator.js +247 -0
- package/dist/sgerp/simulation-logic/vrpStatsUtils.d.ts +17 -0
- package/dist/sgerp/simulation-logic/vrpStatsUtils.d.ts.map +1 -0
- package/dist/sgerp/simulation-logic/vrpStatsUtils.js +48 -0
- package/dist/sgerp/utils/timezone.d.ts +15 -0
- package/dist/sgerp/utils/timezone.d.ts.map +1 -0
- package/dist/sgerp/utils/timezone.js +19 -0
- package/dist/sgerp/vrptoolbox-analyzer.d.ts +39 -0
- package/dist/sgerp/vrptoolbox-analyzer.d.ts.map +1 -0
- package/dist/sgerp/vrptoolbox-analyzer.js +210 -0
- package/dist/vrptoolbox/collection.d.ts +16 -0
- package/dist/vrptoolbox/collection.d.ts.map +1 -0
- package/dist/vrptoolbox/collection.js +62 -0
- package/dist/vrptoolbox/index.d.ts +7 -0
- package/dist/vrptoolbox/index.d.ts.map +1 -0
- package/dist/vrptoolbox/index.js +24 -0
- package/dist/vrptoolbox/types/job.d.ts +46 -0
- package/dist/vrptoolbox/types/job.d.ts.map +1 -0
- package/dist/vrptoolbox/types/job.js +5 -0
- package/dist/vrptoolbox/vrptoolbox-utils.d.ts +133 -0
- package/dist/vrptoolbox/vrptoolbox-utils.d.ts.map +1 -0
- package/dist/vrptoolbox/vrptoolbox-utils.js +207 -0
- package/package.json +9 -4
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OptimizationJobCollection = void 0;
|
|
4
|
+
const collection_1 = require("../sgerp/collection");
|
|
5
|
+
/**
|
|
6
|
+
* Adapter to convert VRP Toolbox response to SGERP format
|
|
7
|
+
*/
|
|
8
|
+
function adaptVRPToolboxResponse(vrpResponse) {
|
|
9
|
+
const { meta, objects } = vrpResponse;
|
|
10
|
+
// Convert VRP Toolbox meta to SGERP meta
|
|
11
|
+
const sgerpMeta = {
|
|
12
|
+
has_more: !!meta.next,
|
|
13
|
+
next: meta.next || null,
|
|
14
|
+
next_offset: meta.next || null,
|
|
15
|
+
};
|
|
16
|
+
return {
|
|
17
|
+
meta: sgerpMeta,
|
|
18
|
+
objects,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Collection class for VRP Toolbox Optimization Jobs
|
|
23
|
+
*/
|
|
24
|
+
class OptimizationJobCollection extends collection_1.Collection {
|
|
25
|
+
constructor(baseUrl, username, password) {
|
|
26
|
+
// Create fetch function that adapts VRP Toolbox API to SGERP format
|
|
27
|
+
const fetchFn = async (params) => {
|
|
28
|
+
const searchParams = new URLSearchParams();
|
|
29
|
+
if (params && typeof params === 'object') {
|
|
30
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
31
|
+
if (value !== undefined && value !== null) {
|
|
32
|
+
searchParams.append(key, String(value));
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
const url = `${baseUrl}/jobs/list/?${searchParams.toString()}`;
|
|
37
|
+
const headers = {};
|
|
38
|
+
if (username && password) {
|
|
39
|
+
const credentials = btoa(`${username}:${password}`);
|
|
40
|
+
headers['Authorization'] = `Basic ${credentials}`;
|
|
41
|
+
}
|
|
42
|
+
const response = await fetch(url, { headers });
|
|
43
|
+
if (!response.ok) {
|
|
44
|
+
throw new Error(`Failed to fetch jobs: ${response.status} ${response.statusText}`);
|
|
45
|
+
}
|
|
46
|
+
const vrpResponse = await response.json();
|
|
47
|
+
return adaptVRPToolboxResponse(vrpResponse);
|
|
48
|
+
};
|
|
49
|
+
super(fetchFn);
|
|
50
|
+
this.baseUrl = baseUrl;
|
|
51
|
+
this.username = username;
|
|
52
|
+
this.password = password;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Set authentication credentials
|
|
56
|
+
*/
|
|
57
|
+
setCredentials(username, password) {
|
|
58
|
+
this.username = username;
|
|
59
|
+
this.password = password;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.OptimizationJobCollection = OptimizationJobCollection;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VRP Toolbox library exports
|
|
3
|
+
*/
|
|
4
|
+
export { OptimizationJobCollection } from './collection';
|
|
5
|
+
export type { OptimizationJob, VRPToolboxListResponse, VRPToolboxMeta, } from './types/job';
|
|
6
|
+
export * from './vrptoolbox-utils';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../sgerplib/vrptoolbox/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,YAAY,EACV,eAAe,EACf,sBAAsB,EACtB,cAAc,GACf,MAAM,aAAa,CAAC;AAGrB,cAAc,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* VRP Toolbox library exports
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
17
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.OptimizationJobCollection = void 0;
|
|
21
|
+
var collection_1 = require("./collection");
|
|
22
|
+
Object.defineProperty(exports, "OptimizationJobCollection", { enumerable: true, get: function () { return collection_1.OptimizationJobCollection; } });
|
|
23
|
+
// VRPToolbox data processing utilities
|
|
24
|
+
__exportStar(require("./vrptoolbox-utils"), exports);
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VRP Toolbox Optimization Task/Job types
|
|
3
|
+
*/
|
|
4
|
+
export interface OptimizationJob {
|
|
5
|
+
id: string;
|
|
6
|
+
status: string;
|
|
7
|
+
type: string;
|
|
8
|
+
created_at: string;
|
|
9
|
+
modified_at?: string;
|
|
10
|
+
processing_started_at?: string;
|
|
11
|
+
processing_completed_at?: string;
|
|
12
|
+
created_by_id?: number;
|
|
13
|
+
creator_username?: string;
|
|
14
|
+
auth_backend?: string;
|
|
15
|
+
executor?: string;
|
|
16
|
+
label?: string;
|
|
17
|
+
project_id?: number;
|
|
18
|
+
error?: string;
|
|
19
|
+
vehicles_count?: number;
|
|
20
|
+
nodes_count?: number;
|
|
21
|
+
solver_parameters_time_limit_ms?: number;
|
|
22
|
+
solver_parameters_first_solution_strategy?: number;
|
|
23
|
+
solver_parameters_use_local_search_metaheuristic?: boolean;
|
|
24
|
+
calculation_parameters_scheduling_mode?: string;
|
|
25
|
+
status_uri?: string;
|
|
26
|
+
result_uri?: string;
|
|
27
|
+
payload_uri?: string;
|
|
28
|
+
result_with_payload_uri?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* VRP Toolbox meta (Tastypie-style pagination)
|
|
32
|
+
*/
|
|
33
|
+
export interface VRPToolboxMeta {
|
|
34
|
+
limit: number;
|
|
35
|
+
offset: number;
|
|
36
|
+
next?: string | null;
|
|
37
|
+
previous?: string | null;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* VRP Toolbox list response (Tastypie format)
|
|
41
|
+
*/
|
|
42
|
+
export interface VRPToolboxListResponse<T> {
|
|
43
|
+
meta: VRPToolboxMeta;
|
|
44
|
+
objects: T[];
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=job.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job.d.ts","sourceRoot":"","sources":["../../../sgerplib/vrptoolbox/types/job.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+BAA+B,CAAC,EAAE,MAAM,CAAC;IACzC,yCAAyC,CAAC,EAAE,MAAM,CAAC;IACnD,gDAAgD,CAAC,EAAE,OAAO,CAAC;IAC3D,sCAAsC,CAAC,EAAE,MAAM,CAAC;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB,CAAC,CAAC;IACvC,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE,CAAC,EAAE,CAAC;CACd"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VRPToolbox data processing utilities
|
|
3
|
+
* Converts VRPToolbox API response to simulation-like state for visualization
|
|
4
|
+
*/
|
|
5
|
+
export interface VRPSimulation {
|
|
6
|
+
id: number;
|
|
7
|
+
name: string;
|
|
8
|
+
project_id: number;
|
|
9
|
+
stateless_api_request_data?: any;
|
|
10
|
+
result?: any;
|
|
11
|
+
}
|
|
12
|
+
export interface VRPVehicle {
|
|
13
|
+
id: number;
|
|
14
|
+
agent_id: string;
|
|
15
|
+
simulation_id: number;
|
|
16
|
+
registration_number?: string;
|
|
17
|
+
color?: string;
|
|
18
|
+
assigned_nodes: string[];
|
|
19
|
+
completed_nodes: string[];
|
|
20
|
+
capacity?: any;
|
|
21
|
+
shift_start?: string;
|
|
22
|
+
shift_end?: string;
|
|
23
|
+
start_lat?: number;
|
|
24
|
+
start_lon?: number;
|
|
25
|
+
end_lat?: number;
|
|
26
|
+
end_lon?: number;
|
|
27
|
+
vehicle_type_id?: number;
|
|
28
|
+
routing_engine_settings?: any;
|
|
29
|
+
is_active?: boolean;
|
|
30
|
+
[key: string]: any;
|
|
31
|
+
}
|
|
32
|
+
export interface VRPNode {
|
|
33
|
+
id: number;
|
|
34
|
+
uid: string;
|
|
35
|
+
simulation_id: number;
|
|
36
|
+
booking_id?: number;
|
|
37
|
+
booking_uid?: string;
|
|
38
|
+
lat: number;
|
|
39
|
+
lon: number;
|
|
40
|
+
node_type: string;
|
|
41
|
+
status: string;
|
|
42
|
+
scheduled_ts?: string | null;
|
|
43
|
+
assigned_vehicle_id?: number | null;
|
|
44
|
+
location_name?: string;
|
|
45
|
+
display_name?: string;
|
|
46
|
+
service_time?: number;
|
|
47
|
+
time_window_start?: string;
|
|
48
|
+
time_window_end?: string;
|
|
49
|
+
priority?: number;
|
|
50
|
+
[key: string]: any;
|
|
51
|
+
}
|
|
52
|
+
export interface VRPBooking {
|
|
53
|
+
id: number;
|
|
54
|
+
uid: string;
|
|
55
|
+
simulation_id: number;
|
|
56
|
+
pickup_lat?: number;
|
|
57
|
+
pickup_lon?: number;
|
|
58
|
+
dropoff_lat?: number;
|
|
59
|
+
dropoff_lon?: number;
|
|
60
|
+
pickup_location_name?: string;
|
|
61
|
+
dropoff_location_name?: string;
|
|
62
|
+
passenger_count?: number;
|
|
63
|
+
status?: string;
|
|
64
|
+
assigned_vehicle_id?: number | null;
|
|
65
|
+
[key: string]: any;
|
|
66
|
+
}
|
|
67
|
+
export interface SimulationLiveUpdateData {
|
|
68
|
+
simulation: VRPSimulation;
|
|
69
|
+
vehicles: VRPVehicle[];
|
|
70
|
+
nodes: VRPNode[];
|
|
71
|
+
bookings: VRPBooking[];
|
|
72
|
+
vehicleRoutes: Map<number, any>;
|
|
73
|
+
nodesByVehicle: Map<number, VRPNode[]>;
|
|
74
|
+
bookingsByVehicle: Map<number, VRPBooking[]>;
|
|
75
|
+
vehicleIndex: Map<number, VRPVehicle>;
|
|
76
|
+
nodeIndex: Map<number, VRPNode>;
|
|
77
|
+
bookingIndex: Map<number, VRPBooking>;
|
|
78
|
+
}
|
|
79
|
+
export interface VRPToolboxPayload {
|
|
80
|
+
vehicles: Array<{
|
|
81
|
+
agent_id: string;
|
|
82
|
+
assigned_nodes?: any[];
|
|
83
|
+
completed_nodes?: any[];
|
|
84
|
+
routing_engine?: any;
|
|
85
|
+
[key: string]: any;
|
|
86
|
+
}>;
|
|
87
|
+
nodes: Array<{
|
|
88
|
+
uid: string;
|
|
89
|
+
booking_uid?: string;
|
|
90
|
+
lat: number;
|
|
91
|
+
lon: number;
|
|
92
|
+
node_type?: string;
|
|
93
|
+
[key: string]: any;
|
|
94
|
+
}>;
|
|
95
|
+
engine_settings?: {
|
|
96
|
+
routing_engine?: any;
|
|
97
|
+
[key: string]: any;
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
export interface VRPToolboxResult {
|
|
101
|
+
vehicles: {
|
|
102
|
+
[vehicleAgentId: string]: Array<{
|
|
103
|
+
uid: string;
|
|
104
|
+
scheduled_ts?: string;
|
|
105
|
+
[key: string]: any;
|
|
106
|
+
}>;
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
export interface VRPToolboxResponse {
|
|
110
|
+
payload: VRPToolboxPayload;
|
|
111
|
+
result: VRPToolboxResult;
|
|
112
|
+
}
|
|
113
|
+
export interface VRPToolboxSimulationState {
|
|
114
|
+
simulation: VRPSimulation;
|
|
115
|
+
vehicles: VRPVehicle[];
|
|
116
|
+
nodes: VRPNode[];
|
|
117
|
+
bookings: VRPBooking[];
|
|
118
|
+
liveUpdateData: SimulationLiveUpdateData;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Fetches VRPToolbox job result with payload
|
|
122
|
+
*/
|
|
123
|
+
export declare function fetchVRPToolboxJobData(vrpServer: string, taskId: string): Promise<VRPToolboxResponse>;
|
|
124
|
+
/**
|
|
125
|
+
* Converts VRPToolbox response to simulation-like state
|
|
126
|
+
* Based on the logic from dashviewer's createStateFromCommuteOffers
|
|
127
|
+
*/
|
|
128
|
+
export declare function convertVRPToolboxToSimulationState(data: VRPToolboxResponse, taskId: string): VRPToolboxSimulationState;
|
|
129
|
+
/**
|
|
130
|
+
* Fetches and processes VRPToolbox data into simulation state
|
|
131
|
+
*/
|
|
132
|
+
export declare function loadVRPToolboxSimulation(vrpServer: string, taskId: string): Promise<VRPToolboxSimulationState>;
|
|
133
|
+
//# sourceMappingURL=vrptoolbox-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vrptoolbox-utils.d.ts","sourceRoot":"","sources":["../../sgerplib/vrptoolbox/vrptoolbox-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,0BAA0B,CAAC,EAAE,GAAG,CAAC;IACjC,MAAM,CAAC,EAAE,GAAG,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,uBAAuB,CAAC,EAAE,GAAG,CAAC;IAC9B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAGD,MAAM,WAAW,wBAAwB;IACvC,UAAU,EAAE,aAAa,CAAC;IAC1B,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;IACvC,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;IAC7C,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACtC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,KAAK,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,CAAC,EAAE,GAAG,EAAE,CAAC;QACvB,eAAe,CAAC,EAAE,GAAG,EAAE,CAAC;QACxB,cAAc,CAAC,EAAE,GAAG,CAAC;QACrB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACpB,CAAC,CAAC;IACH,KAAK,EAAE,KAAK,CAAC;QACX,GAAG,EAAE,MAAM,CAAC;QACZ,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;QACZ,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACpB,CAAC,CAAC;IACH,eAAe,CAAC,EAAE;QAChB,cAAc,CAAC,EAAE,GAAG,CAAC;QACrB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACpB,CAAC;CACH;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE;QACR,CAAC,cAAc,EAAE,MAAM,GAAG,KAAK,CAAC;YAC9B,GAAG,EAAE,MAAM,CAAC;YACZ,YAAY,CAAC,EAAE,MAAM,CAAC;YACtB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;SACpB,CAAC,CAAC;KACJ,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,iBAAiB,CAAC;IAC3B,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,aAAa,CAAC;IAC1B,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,cAAc,EAAE,wBAAwB,CAAC;CAC1C;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,kBAAkB,CAAC,CAS7B;AAED;;;GAGG;AACH,wBAAgB,kCAAkC,CAChD,IAAI,EAAE,kBAAkB,EACxB,MAAM,EAAE,MAAM,GACb,yBAAyB,CA+L3B;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,yBAAyB,CAAC,CAGpC"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* VRPToolbox data processing utilities
|
|
4
|
+
* Converts VRPToolbox API response to simulation-like state for visualization
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.fetchVRPToolboxJobData = fetchVRPToolboxJobData;
|
|
8
|
+
exports.convertVRPToolboxToSimulationState = convertVRPToolboxToSimulationState;
|
|
9
|
+
exports.loadVRPToolboxSimulation = loadVRPToolboxSimulation;
|
|
10
|
+
/**
|
|
11
|
+
* Fetches VRPToolbox job result with payload
|
|
12
|
+
*/
|
|
13
|
+
async function fetchVRPToolboxJobData(vrpServer, taskId) {
|
|
14
|
+
const url = `${vrpServer}/jobs/${taskId}/result_with_payload`;
|
|
15
|
+
const response = await fetch(url);
|
|
16
|
+
if (!response.ok) {
|
|
17
|
+
throw new Error(`Failed to fetch VRPToolbox data: ${response.statusText}`);
|
|
18
|
+
}
|
|
19
|
+
return await response.json();
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Converts VRPToolbox response to simulation-like state
|
|
23
|
+
* Based on the logic from dashviewer's createStateFromCommuteOffers
|
|
24
|
+
*/
|
|
25
|
+
function convertVRPToolboxToSimulationState(data, taskId) {
|
|
26
|
+
const { payload, result } = data;
|
|
27
|
+
// Create assigned nodes cache from result
|
|
28
|
+
const assignedNodesCache = {};
|
|
29
|
+
Object.entries(result.vehicles).forEach(([vehicleAgentId, vehicleNodes]) => {
|
|
30
|
+
vehicleNodes.forEach((node) => {
|
|
31
|
+
assignedNodesCache[node.uid] = Object.assign(Object.assign({}, node), { assigned_vehicle_id: vehicleAgentId, status: 'assigned' });
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
// Process vehicles
|
|
35
|
+
const vehicles = payload.vehicles.map((vehicle) => {
|
|
36
|
+
var _a, _b;
|
|
37
|
+
const assignedNodes = vehicle.assigned_nodes || [];
|
|
38
|
+
const completedNodes = vehicle.completed_nodes || [];
|
|
39
|
+
// Map assigned node UIDs from the result
|
|
40
|
+
const assignedNodeIds = ((_a = result.vehicles[vehicle.agent_id]) === null || _a === void 0 ? void 0 : _a.map((n) => n.uid)) || [];
|
|
41
|
+
return {
|
|
42
|
+
id: parseInt(vehicle.agent_id),
|
|
43
|
+
agent_id: vehicle.agent_id,
|
|
44
|
+
simulation_id: parseInt(taskId),
|
|
45
|
+
assigned_nodes: assignedNodeIds,
|
|
46
|
+
completed_nodes: completedNodes.map((n) => n.uid),
|
|
47
|
+
routing_engine_settings: vehicle.routing_engine ||
|
|
48
|
+
((_b = payload.engine_settings) === null || _b === void 0 ? void 0 : _b.routing_engine) ||
|
|
49
|
+
{ routing_engine_name: 'osrm' },
|
|
50
|
+
// Map other vehicle fields
|
|
51
|
+
registration_number: vehicle.registration_number || vehicle.agent_id,
|
|
52
|
+
color: vehicle.color || '#4A90E2',
|
|
53
|
+
capacity: vehicle.capacity || {},
|
|
54
|
+
shift_start: vehicle.shift_start,
|
|
55
|
+
shift_end: vehicle.shift_end,
|
|
56
|
+
start_lat: vehicle.start_lat,
|
|
57
|
+
start_lon: vehicle.start_lon,
|
|
58
|
+
end_lat: vehicle.end_lat,
|
|
59
|
+
end_lon: vehicle.end_lon,
|
|
60
|
+
// Add other required vehicle fields with defaults
|
|
61
|
+
vehicle_type_id: vehicle.vehicle_type_id || 1,
|
|
62
|
+
is_active: true,
|
|
63
|
+
};
|
|
64
|
+
});
|
|
65
|
+
// Process nodes
|
|
66
|
+
const nodes = [];
|
|
67
|
+
const bookingsMap = new Map();
|
|
68
|
+
payload.nodes.forEach((node) => {
|
|
69
|
+
const assignedData = assignedNodesCache[node.uid];
|
|
70
|
+
const processedNode = {
|
|
71
|
+
id: parseInt(node.uid),
|
|
72
|
+
uid: node.uid,
|
|
73
|
+
simulation_id: parseInt(taskId),
|
|
74
|
+
booking_id: parseInt(node.booking_uid || '0'),
|
|
75
|
+
booking_uid: node.booking_uid,
|
|
76
|
+
lat: node.lat,
|
|
77
|
+
lon: node.lon,
|
|
78
|
+
node_type: node.node_type || 'pickup',
|
|
79
|
+
status: (assignedData === null || assignedData === void 0 ? void 0 : assignedData.status) || 'rejected_by_system',
|
|
80
|
+
scheduled_ts: (assignedData === null || assignedData === void 0 ? void 0 : assignedData.scheduled_ts) || null,
|
|
81
|
+
assigned_vehicle_id: (assignedData === null || assignedData === void 0 ? void 0 : assignedData.assigned_vehicle_id) ?
|
|
82
|
+
parseInt(assignedData.assigned_vehicle_id) : null,
|
|
83
|
+
// Map other node fields
|
|
84
|
+
location_name: node.location_name || node.display_name || '',
|
|
85
|
+
display_name: node.display_name || '',
|
|
86
|
+
service_time: node.service_time || 0,
|
|
87
|
+
time_window_start: node.time_window_start,
|
|
88
|
+
time_window_end: node.time_window_end,
|
|
89
|
+
priority: node.priority || 1,
|
|
90
|
+
};
|
|
91
|
+
nodes.push(processedNode);
|
|
92
|
+
// Create or update booking
|
|
93
|
+
if (node.booking_uid) {
|
|
94
|
+
if (!bookingsMap.has(node.booking_uid)) {
|
|
95
|
+
bookingsMap.set(node.booking_uid, {
|
|
96
|
+
id: parseInt(node.booking_uid),
|
|
97
|
+
uid: node.booking_uid,
|
|
98
|
+
simulation_id: parseInt(taskId),
|
|
99
|
+
pickup_lat: node.node_type === 'pickup' ? node.lat : 0,
|
|
100
|
+
pickup_lon: node.node_type === 'pickup' ? node.lon : 0,
|
|
101
|
+
dropoff_lat: node.node_type === 'dropoff' ? node.lat : 0,
|
|
102
|
+
dropoff_lon: node.node_type === 'dropoff' ? node.lon : 0,
|
|
103
|
+
pickup_location_name: '',
|
|
104
|
+
dropoff_location_name: '',
|
|
105
|
+
passenger_count: 1,
|
|
106
|
+
status: assignedData ? 'assigned' : 'unassigned',
|
|
107
|
+
assigned_vehicle_id: (assignedData === null || assignedData === void 0 ? void 0 : assignedData.assigned_vehicle_id) ?
|
|
108
|
+
parseInt(assignedData.assigned_vehicle_id) : null,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
const booking = bookingsMap.get(node.booking_uid);
|
|
113
|
+
if (node.node_type === 'pickup') {
|
|
114
|
+
booking.pickup_lat = node.lat;
|
|
115
|
+
booking.pickup_lon = node.lon;
|
|
116
|
+
booking.pickup_location_name = node.location_name || '';
|
|
117
|
+
}
|
|
118
|
+
else if (node.node_type === 'dropoff') {
|
|
119
|
+
booking.dropoff_lat = node.lat;
|
|
120
|
+
booking.dropoff_lon = node.lon;
|
|
121
|
+
booking.dropoff_location_name = node.location_name || '';
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
// Add partial route nodes that weren't in the main nodes list
|
|
127
|
+
payload.vehicles.forEach((vehicle) => {
|
|
128
|
+
const assignedNodes = vehicle.assigned_nodes || [];
|
|
129
|
+
assignedNodes.forEach((vehicleNode) => {
|
|
130
|
+
const nodeId = vehicleNode.uid;
|
|
131
|
+
if (!nodes.find(n => n.uid === nodeId)) {
|
|
132
|
+
const assignedData = assignedNodesCache[nodeId];
|
|
133
|
+
nodes.push({
|
|
134
|
+
id: parseInt(nodeId),
|
|
135
|
+
uid: nodeId,
|
|
136
|
+
simulation_id: parseInt(taskId),
|
|
137
|
+
booking_id: parseInt(vehicleNode.booking_uid || '0'),
|
|
138
|
+
booking_uid: vehicleNode.booking_uid,
|
|
139
|
+
lat: vehicleNode.lat || 0,
|
|
140
|
+
lon: vehicleNode.lon || 0,
|
|
141
|
+
node_type: vehicleNode.node_type || 'pickup',
|
|
142
|
+
status: (assignedData === null || assignedData === void 0 ? void 0 : assignedData.status) || 'assigned',
|
|
143
|
+
scheduled_ts: (assignedData === null || assignedData === void 0 ? void 0 : assignedData.scheduled_ts) || null,
|
|
144
|
+
assigned_vehicle_id: vehicle.agent_id ? parseInt(vehicle.agent_id) : null,
|
|
145
|
+
location_name: vehicleNode.location_name || '',
|
|
146
|
+
display_name: vehicleNode.display_name || '',
|
|
147
|
+
service_time: vehicleNode.service_time || 0,
|
|
148
|
+
priority: vehicleNode.priority || 1,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
const bookings = Array.from(bookingsMap.values());
|
|
154
|
+
// Create simulation object
|
|
155
|
+
const simulation = {
|
|
156
|
+
id: parseInt(taskId),
|
|
157
|
+
name: `VRPToolbox Job ${taskId}`,
|
|
158
|
+
project_id: 0,
|
|
159
|
+
stateless_api_request_data: payload,
|
|
160
|
+
result: result,
|
|
161
|
+
};
|
|
162
|
+
// Create live update data structure
|
|
163
|
+
const liveUpdateData = {
|
|
164
|
+
simulation,
|
|
165
|
+
vehicles,
|
|
166
|
+
nodes,
|
|
167
|
+
bookings,
|
|
168
|
+
vehicleRoutes: new Map(),
|
|
169
|
+
nodesByVehicle: new Map(),
|
|
170
|
+
bookingsByVehicle: new Map(),
|
|
171
|
+
vehicleIndex: new Map(vehicles.map(v => [v.id, v])),
|
|
172
|
+
nodeIndex: new Map(nodes.map(n => [n.id, n])),
|
|
173
|
+
bookingIndex: new Map(bookings.map(b => [b.id, b])),
|
|
174
|
+
};
|
|
175
|
+
// Group nodes by vehicle
|
|
176
|
+
nodes.forEach(node => {
|
|
177
|
+
if (node.assigned_vehicle_id) {
|
|
178
|
+
if (!liveUpdateData.nodesByVehicle.has(node.assigned_vehicle_id)) {
|
|
179
|
+
liveUpdateData.nodesByVehicle.set(node.assigned_vehicle_id, []);
|
|
180
|
+
}
|
|
181
|
+
liveUpdateData.nodesByVehicle.get(node.assigned_vehicle_id).push(node);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
// Group bookings by vehicle
|
|
185
|
+
bookings.forEach(booking => {
|
|
186
|
+
if (booking.assigned_vehicle_id) {
|
|
187
|
+
if (!liveUpdateData.bookingsByVehicle.has(booking.assigned_vehicle_id)) {
|
|
188
|
+
liveUpdateData.bookingsByVehicle.set(booking.assigned_vehicle_id, []);
|
|
189
|
+
}
|
|
190
|
+
liveUpdateData.bookingsByVehicle.get(booking.assigned_vehicle_id).push(booking);
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
return {
|
|
194
|
+
simulation,
|
|
195
|
+
vehicles,
|
|
196
|
+
nodes,
|
|
197
|
+
bookings,
|
|
198
|
+
liveUpdateData,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Fetches and processes VRPToolbox data into simulation state
|
|
203
|
+
*/
|
|
204
|
+
async function loadVRPToolboxSimulation(vrpServer, taskId) {
|
|
205
|
+
const data = await fetchVRPToolboxJobData(vrpServer, taskId);
|
|
206
|
+
return convertVRPToolboxToSimulationState(data, taskId);
|
|
207
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sgerp-frontend-lib",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "TypeScript/React library for interacting with the SGERP API, providing client SDK, Backbone.js-style Collections, and pre-built React components",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
"test:e2e:transitstopsets": "playwright test e2e/ptapp/transitstopsets.spec.ts",
|
|
53
53
|
"test:all": "./run-tests.sh",
|
|
54
54
|
"test:all:open": "./run-tests.sh --open-coverage",
|
|
55
|
+
"translate": "tsx scripts/translate-locales.ts",
|
|
55
56
|
"prepare": "husky"
|
|
56
57
|
},
|
|
57
58
|
"dependencies": {
|
|
@@ -77,6 +78,7 @@
|
|
|
77
78
|
"@radix-ui/react-toggle": "^1.1.10",
|
|
78
79
|
"@radix-ui/react-toggle-group": "^1.1.11",
|
|
79
80
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
81
|
+
"@tanstack/react-virtual": "^3.13.12",
|
|
80
82
|
"class-variance-authority": "^0.7.1",
|
|
81
83
|
"clsx": "^2.1.1",
|
|
82
84
|
"cmdk": "^1.1.1",
|
|
@@ -86,13 +88,15 @@
|
|
|
86
88
|
"lucide-react": "^0.545.0",
|
|
87
89
|
"mapbox-gl": "^3.16.0",
|
|
88
90
|
"moment-timezone": "^0.6.0",
|
|
89
|
-
"next": "15.5.
|
|
91
|
+
"next": "^15.5.7",
|
|
90
92
|
"next-themes": "^0.4.6",
|
|
91
93
|
"nuqs": "^2.7.2",
|
|
92
|
-
"react": "^19.1
|
|
94
|
+
"react": "^19.0.1",
|
|
93
95
|
"react-day-picker": "^9.11.1",
|
|
94
|
-
"react-dom": "19.1
|
|
96
|
+
"react-dom": "^19.0.1",
|
|
95
97
|
"react-markdown": "^10.1.0",
|
|
98
|
+
"react-resizable-panels": "^3.0.6",
|
|
99
|
+
"recharts": "^2.15.4",
|
|
96
100
|
"rehype-highlight": "^7.0.2",
|
|
97
101
|
"rehype-slug": "^6.0.0",
|
|
98
102
|
"remark-gfm": "^4.0.1",
|
|
@@ -119,6 +123,7 @@
|
|
|
119
123
|
"husky": "^9.1.7",
|
|
120
124
|
"jsdom": "^27.0.1",
|
|
121
125
|
"tailwindcss": "^4",
|
|
126
|
+
"tsx": "^4.21.0",
|
|
122
127
|
"tw-animate-css": "^1.4.0",
|
|
123
128
|
"typescript": "^5",
|
|
124
129
|
"vitest": "^3.2.4"
|