sgerp-frontend-lib 0.1.3 → 0.1.5
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 +23 -0
- package/dist/constants/timezones.d.ts.map +1 -0
- package/dist/constants/timezones.js +107 -0
- 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 +77 -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 +76 -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/markdown.d.ts +33 -0
- package/dist/markdown.d.ts.map +1 -0
- package/dist/markdown.js +117 -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 +24 -2
- package/dist/sgerp/index.d.ts.map +1 -1
- package/dist/sgerp/index.js +62 -2
- package/dist/sgerp/simulation-logic/fetchUtils.d.ts.map +1 -1
- package/dist/sgerp/simulation-logic/fetchUtils.js +2 -0
- package/dist/sgerp/simulation-logic/index.d.ts +3 -1
- package/dist/sgerp/simulation-logic/index.d.ts.map +1 -1
- package/dist/sgerp/simulation-logic/index.js +10 -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/utils/countries.d.ts +15 -0
- package/dist/utils/countries.d.ts.map +1 -0
- package/dist/utils/countries.js +112 -0
- package/dist/utils.d.ts +3 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +8 -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 +6 -0
- package/dist/vrptoolbox/index.d.ts.map +1 -0
- package/dist/vrptoolbox/index.js +8 -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/package.json +7 -4
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export type Language = 'en' | 'ja' | 'ms';
|
|
2
|
+
export interface DocMetadata {
|
|
3
|
+
title: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
[key: string]: unknown;
|
|
6
|
+
}
|
|
7
|
+
export interface Heading {
|
|
8
|
+
id: string;
|
|
9
|
+
text: string;
|
|
10
|
+
level: number;
|
|
11
|
+
}
|
|
12
|
+
export interface DocContent {
|
|
13
|
+
metadata: DocMetadata;
|
|
14
|
+
content: string;
|
|
15
|
+
slug: string;
|
|
16
|
+
headings?: Heading[];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Extract headings from markdown content
|
|
20
|
+
*/
|
|
21
|
+
export declare function extractHeadings(content: string): Heading[];
|
|
22
|
+
/**
|
|
23
|
+
* Get a documentation file by slug with locale support
|
|
24
|
+
* @param slug - The slug path (e.g., ['getting-started'])
|
|
25
|
+
* @param locale - The language locale (defaults to 'en')
|
|
26
|
+
* @returns The documentation content or null if not found
|
|
27
|
+
*/
|
|
28
|
+
export declare function getDocBySlug(slug: string[], locale?: Language): DocContent | null;
|
|
29
|
+
/**
|
|
30
|
+
* Get all documentation slugs
|
|
31
|
+
*/
|
|
32
|
+
export declare function getAllDocSlugs(): string[][];
|
|
33
|
+
//# sourceMappingURL=markdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../sgerplib/markdown.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,QAAQ,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAc1C,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,WAAW,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;CACtB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,EAAE,CA6B1D;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,GAAE,QAAe,GAAG,UAAU,GAAG,IAAI,CAqCvF;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,EAAE,EAAE,CAwB3C"}
|
package/dist/markdown.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.extractHeadings = extractHeadings;
|
|
7
|
+
exports.getDocBySlug = getDocBySlug;
|
|
8
|
+
exports.getAllDocSlugs = getAllDocSlugs;
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const gray_matter_1 = __importDefault(require("gray-matter"));
|
|
12
|
+
/**
|
|
13
|
+
* Get the content directory for a specific locale
|
|
14
|
+
* @param locale - The language locale (en, ja, ms)
|
|
15
|
+
* @returns The path to the content directory
|
|
16
|
+
*/
|
|
17
|
+
function getContentDirectory(locale = 'en') {
|
|
18
|
+
const suffix = locale === 'en' ? '' : `-${locale}`;
|
|
19
|
+
return path_1.default.join(process.cwd(), `content/docs${suffix}`);
|
|
20
|
+
}
|
|
21
|
+
const contentDirectory = path_1.default.join(process.cwd(), 'content/docs');
|
|
22
|
+
/**
|
|
23
|
+
* Extract headings from markdown content
|
|
24
|
+
*/
|
|
25
|
+
function extractHeadings(content) {
|
|
26
|
+
const headings = [];
|
|
27
|
+
const lines = content.split('\n');
|
|
28
|
+
const idCounts = new Map();
|
|
29
|
+
for (const line of lines) {
|
|
30
|
+
// Match markdown headings (## Heading)
|
|
31
|
+
const match = line.match(/^(#{2,3})\s+(.+)$/);
|
|
32
|
+
if (match) {
|
|
33
|
+
const level = match[1].length;
|
|
34
|
+
const text = match[2].trim();
|
|
35
|
+
// Create a slug from the heading text
|
|
36
|
+
let id = text
|
|
37
|
+
.toLowerCase()
|
|
38
|
+
.replace(/[^a-z0-9\s-]/g, '')
|
|
39
|
+
.replace(/\s+/g, '-');
|
|
40
|
+
// Handle duplicate IDs
|
|
41
|
+
const count = idCounts.get(id) || 0;
|
|
42
|
+
if (count > 0) {
|
|
43
|
+
id = `${id}-${count}`;
|
|
44
|
+
}
|
|
45
|
+
idCounts.set(id.replace(/-\d+$/, ''), count + 1);
|
|
46
|
+
headings.push({ id, text, level });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return headings;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get a documentation file by slug with locale support
|
|
53
|
+
* @param slug - The slug path (e.g., ['getting-started'])
|
|
54
|
+
* @param locale - The language locale (defaults to 'en')
|
|
55
|
+
* @returns The documentation content or null if not found
|
|
56
|
+
*/
|
|
57
|
+
function getDocBySlug(slug, locale = 'en') {
|
|
58
|
+
try {
|
|
59
|
+
const slugPath = slug.join('/');
|
|
60
|
+
const localeContentDir = getContentDirectory(locale);
|
|
61
|
+
let fullPath = path_1.default.join(localeContentDir, `${slugPath}.md`);
|
|
62
|
+
// If the direct path doesn't exist, try index.md inside the directory
|
|
63
|
+
if (!fs_1.default.existsSync(fullPath)) {
|
|
64
|
+
const indexPath = path_1.default.join(localeContentDir, slugPath, 'index.md');
|
|
65
|
+
if (fs_1.default.existsSync(indexPath)) {
|
|
66
|
+
fullPath = indexPath;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
// Fallback to English if locale file doesn't exist
|
|
70
|
+
if (locale !== 'en') {
|
|
71
|
+
return getDocBySlug(slug, 'en');
|
|
72
|
+
}
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const fileContents = fs_1.default.readFileSync(fullPath, 'utf8');
|
|
77
|
+
const { data, content } = (0, gray_matter_1.default)(fileContents);
|
|
78
|
+
return {
|
|
79
|
+
metadata: data,
|
|
80
|
+
content,
|
|
81
|
+
slug: slugPath,
|
|
82
|
+
headings: extractHeadings(content),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
console.error('Error reading doc:', error);
|
|
87
|
+
// Fallback to English on error if not already English
|
|
88
|
+
if (locale !== 'en') {
|
|
89
|
+
return getDocBySlug(slug, 'en');
|
|
90
|
+
}
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Get all documentation slugs
|
|
96
|
+
*/
|
|
97
|
+
function getAllDocSlugs() {
|
|
98
|
+
const slugs = [];
|
|
99
|
+
function traverseDirectory(dir, currentPath = []) {
|
|
100
|
+
const files = fs_1.default.readdirSync(dir);
|
|
101
|
+
files.forEach((file) => {
|
|
102
|
+
const filePath = path_1.default.join(dir, file);
|
|
103
|
+
const stat = fs_1.default.statSync(filePath);
|
|
104
|
+
if (stat.isDirectory()) {
|
|
105
|
+
traverseDirectory(filePath, [...currentPath, file]);
|
|
106
|
+
}
|
|
107
|
+
else if (file.endsWith('.md')) {
|
|
108
|
+
const slug = [...currentPath, file.replace(/\.md$/, '')];
|
|
109
|
+
slugs.push(slug);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
if (fs_1.default.existsSync(contentDirectory)) {
|
|
114
|
+
traverseDirectory(contentDirectory);
|
|
115
|
+
}
|
|
116
|
+
return slugs;
|
|
117
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../../sgerplib/sgerp/collection.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../../sgerplib/sgerp/collection.ts"],"names":[],"mappings":"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"}
|
package/dist/sgerp/collection.js
CHANGED
|
@@ -212,9 +212,13 @@ class Collection {
|
|
|
212
212
|
// Update or add to models array
|
|
213
213
|
const existingIndex = newModels.findIndex(m => m.id === model.id);
|
|
214
214
|
if (existingIndex >= 0) {
|
|
215
|
-
//
|
|
216
|
-
|
|
217
|
-
|
|
215
|
+
// Merge with existing model to preserve client-side attributes
|
|
216
|
+
// Spread existing first, then new data, so server data takes precedence
|
|
217
|
+
// But client-side-only attributes (like visible_position) are preserved if not in new data
|
|
218
|
+
const existingModel = newModels[existingIndex];
|
|
219
|
+
const mergedModel = Object.assign(Object.assign({}, existingModel), model);
|
|
220
|
+
newModels[existingIndex] = mergedModel;
|
|
221
|
+
this._index.set(model.id, mergedModel);
|
|
218
222
|
hasChanges = true;
|
|
219
223
|
}
|
|
220
224
|
else {
|
|
@@ -225,8 +229,18 @@ class Collection {
|
|
|
225
229
|
});
|
|
226
230
|
// Only update and notify if something actually changed
|
|
227
231
|
if (hasChanges) {
|
|
232
|
+
// Safety check: deduplicate by ID (should not happen, but prevents React key errors)
|
|
233
|
+
const seen = new Set();
|
|
234
|
+
const deduplicated = newModels.filter(model => {
|
|
235
|
+
if (seen.has(model.id)) {
|
|
236
|
+
console.warn(`[Collection] Duplicate model with ID ${model.id} detected and removed`);
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
seen.add(model.id);
|
|
240
|
+
return true;
|
|
241
|
+
});
|
|
228
242
|
// Create new array reference for React to detect changes
|
|
229
|
-
this._models =
|
|
243
|
+
this._models = deduplicated;
|
|
230
244
|
this._notifyChange();
|
|
231
245
|
}
|
|
232
246
|
}
|
package/dist/sgerp/domains.d.ts
CHANGED
|
@@ -37,11 +37,25 @@ export declare const DEFAULT_SERVERS: {
|
|
|
37
37
|
url: string;
|
|
38
38
|
}[];
|
|
39
39
|
/**
|
|
40
|
-
*
|
|
40
|
+
* Backend environment type (for OSRM routing)
|
|
41
41
|
*/
|
|
42
|
-
export type
|
|
42
|
+
export type BackendEnvironment = 'development' | 'staging' | 'production' | 'tc' | 'tcp' | 'ppe';
|
|
43
43
|
/**
|
|
44
44
|
* OSRM backend type
|
|
45
45
|
*/
|
|
46
46
|
export type OSRMBackend = keyof typeof SGERP_DOMAINS.osrm;
|
|
47
|
+
/**
|
|
48
|
+
* Backend environment detection rules
|
|
49
|
+
* Maps URL patterns to backend environment types
|
|
50
|
+
*/
|
|
51
|
+
export declare const BACKEND_DETECTION_RULES: Array<{
|
|
52
|
+
patterns: string[];
|
|
53
|
+
backend: OSRMBackend;
|
|
54
|
+
}>;
|
|
55
|
+
/**
|
|
56
|
+
* Detect backend environment from base URL
|
|
57
|
+
* @param baseUrl - The SGERP API base URL
|
|
58
|
+
* @returns The detected backend environment or 'development' as default
|
|
59
|
+
*/
|
|
60
|
+
export declare function detectBackendFromUrl(baseUrl: string): OSRMBackend;
|
|
47
61
|
//# sourceMappingURL=domains.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"domains.d.ts","sourceRoot":"","sources":["../../sgerplib/sgerp/domains.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,eAAO,MAAM,aAAa;;;;;;;;;;;;CAehB,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,eAAe;;;GAK8B,CAAC;AAE3D;;GAEG;AACH,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"domains.d.ts","sourceRoot":"","sources":["../../sgerplib/sgerp/domains.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,eAAO,MAAM,aAAa;;;;;;;;;;;;CAehB,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,eAAe;;;GAK8B,CAAC;AAE3D;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,aAAa,GAAG,SAAS,GAAG,YAAY,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,CAAC;AAEjG;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,aAAa,CAAC,IAAI,CAAC;AAE1D;;;GAGG;AACH,eAAO,MAAM,uBAAuB,EAAE,KAAK,CAAC;IAC1C,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,WAAW,CAAC;CACtB,CA0BA,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAUjE"}
|
package/dist/sgerp/domains.js
CHANGED
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
* - NEXT_PUBLIC_OSRM_DOMAIN_PPE
|
|
17
17
|
*/
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
-
exports.DEFAULT_SERVERS = exports.SGERP_DOMAINS = void 0;
|
|
19
|
+
exports.BACKEND_DETECTION_RULES = exports.DEFAULT_SERVERS = exports.SGERP_DOMAINS = void 0;
|
|
20
|
+
exports.detectBackendFromUrl = detectBackendFromUrl;
|
|
20
21
|
exports.SGERP_DOMAINS = {
|
|
21
22
|
// SGERP API Domains
|
|
22
23
|
staging: process.env.NEXT_PUBLIC_SGERP_DOMAIN_STAGING || '',
|
|
@@ -43,3 +44,48 @@ exports.DEFAULT_SERVERS = [
|
|
|
43
44
|
{ labelKey: "env.tcp", url: exports.SGERP_DOMAINS.tcp },
|
|
44
45
|
{ labelKey: "env.ppe", url: exports.SGERP_DOMAINS.ppe },
|
|
45
46
|
].filter(server => server.url && server.url.trim() !== '');
|
|
47
|
+
/**
|
|
48
|
+
* Backend environment detection rules
|
|
49
|
+
* Maps URL patterns to backend environment types
|
|
50
|
+
*/
|
|
51
|
+
exports.BACKEND_DETECTION_RULES = [
|
|
52
|
+
{
|
|
53
|
+
patterns: ['gcdev', 'gcstage', 'staging', 'stage', 'dev'],
|
|
54
|
+
backend: 'development',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
patterns: ['gcprod', 'prod'],
|
|
58
|
+
backend: 'production',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
patterns: [
|
|
62
|
+
process.env.NEXT_PUBLIC_BACKEND_TC_PATTERN || 'tc.example',
|
|
63
|
+
],
|
|
64
|
+
backend: 'tc',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
patterns: [
|
|
68
|
+
process.env.NEXT_PUBLIC_BACKEND_TCP_PATTERN || 'tcp.example',
|
|
69
|
+
process.env.NEXT_PUBLIC_BACKEND_TCP_PATTERN_2 || 'tms-planning.example',
|
|
70
|
+
],
|
|
71
|
+
backend: 'tcp',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
patterns: ['ppe'],
|
|
75
|
+
backend: 'ppe',
|
|
76
|
+
},
|
|
77
|
+
];
|
|
78
|
+
/**
|
|
79
|
+
* Detect backend environment from base URL
|
|
80
|
+
* @param baseUrl - The SGERP API base URL
|
|
81
|
+
* @returns The detected backend environment or 'development' as default
|
|
82
|
+
*/
|
|
83
|
+
function detectBackendFromUrl(baseUrl) {
|
|
84
|
+
const lowerUrl = baseUrl.toLowerCase();
|
|
85
|
+
for (const rule of exports.BACKEND_DETECTION_RULES) {
|
|
86
|
+
if (rule.patterns.some(pattern => lowerUrl.includes(pattern))) {
|
|
87
|
+
return rule.backend;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return 'development'; // Default fallback
|
|
91
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook for managing selection state (vehicles, bookings, etc.)
|
|
3
|
+
* Provides consistent selection management across simulation pages
|
|
4
|
+
*/
|
|
5
|
+
export interface SelectionState<T extends number | string> {
|
|
6
|
+
selected: Set<T>;
|
|
7
|
+
count: number;
|
|
8
|
+
isSelected: (id: T) => boolean;
|
|
9
|
+
toggle: (id: T) => void;
|
|
10
|
+
selectAll: (ids: T[]) => void;
|
|
11
|
+
clearAll: () => void;
|
|
12
|
+
setSelection: (ids: T[]) => void;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Hook for managing selection state with Set-based storage
|
|
16
|
+
* Useful for checkbox selections, multi-select, etc.
|
|
17
|
+
*
|
|
18
|
+
* @param initialIds - Initial selected IDs
|
|
19
|
+
* @returns Selection state and methods
|
|
20
|
+
*/
|
|
21
|
+
export declare function useSelectionState<T extends number | string>(initialIds?: T[]): SelectionState<T>;
|
|
22
|
+
/**
|
|
23
|
+
* Hook for tracking recently changed items (for visual feedback)
|
|
24
|
+
* Automatically clears highlights after a timeout
|
|
25
|
+
*
|
|
26
|
+
* @param timeoutMs - How long to highlight changes (default: 3000ms)
|
|
27
|
+
*/
|
|
28
|
+
export declare function useRecentChanges<T extends number | string>(timeoutMs?: number): {
|
|
29
|
+
recentlyChanged: Set<T>;
|
|
30
|
+
isRecentlyChanged: (id: T) => boolean;
|
|
31
|
+
detectChanges: (items: Array<{
|
|
32
|
+
id?: T;
|
|
33
|
+
uid?: T;
|
|
34
|
+
[key: string]: any;
|
|
35
|
+
}>, stateKey: string) => void;
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=use-selection-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-selection-state.d.ts","sourceRoot":"","sources":["../../../sgerplib/sgerp/hooks/use-selection-state.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,cAAc,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IACvD,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,OAAO,CAAC;IAC/B,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,IAAI,CAAC;IACxB,SAAS,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC;IAC9B,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,YAAY,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC;CAClC;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EACzD,UAAU,GAAE,CAAC,EAAO,GACnB,cAAc,CAAC,CAAC,CAAC,CAsDnB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EACxD,SAAS,GAAE,MAAa;;4BA8CjB,CAAC,KAAG,OAAO;2BAvCR,KAAK,CAAC;QAAE,EAAE,CAAC,EAAE,CAAC,CAAC;QAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAC,YAAY,MAAM;EA2D3E"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Hook for managing selection state (vehicles, bookings, etc.)
|
|
4
|
+
* Provides consistent selection management across simulation pages
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.useSelectionState = useSelectionState;
|
|
8
|
+
exports.useRecentChanges = useRecentChanges;
|
|
9
|
+
const react_1 = require("react");
|
|
10
|
+
/**
|
|
11
|
+
* Hook for managing selection state with Set-based storage
|
|
12
|
+
* Useful for checkbox selections, multi-select, etc.
|
|
13
|
+
*
|
|
14
|
+
* @param initialIds - Initial selected IDs
|
|
15
|
+
* @returns Selection state and methods
|
|
16
|
+
*/
|
|
17
|
+
function useSelectionState(initialIds = []) {
|
|
18
|
+
const selectedRef = (0, react_1.useRef)(new Set(initialIds));
|
|
19
|
+
const [count, setCount] = (0, react_1.useState)(initialIds.length);
|
|
20
|
+
const [refreshCounter, setRefreshCounter] = (0, react_1.useState)(0);
|
|
21
|
+
// Keep ref in sync with initial value changes
|
|
22
|
+
(0, react_1.useEffect)(() => {
|
|
23
|
+
if (initialIds.length > 0 && selectedRef.current.size === 0) {
|
|
24
|
+
selectedRef.current = new Set(initialIds);
|
|
25
|
+
setCount(initialIds.length);
|
|
26
|
+
}
|
|
27
|
+
}, [initialIds]);
|
|
28
|
+
const isSelected = (0, react_1.useCallback)((id) => {
|
|
29
|
+
return selectedRef.current.has(id);
|
|
30
|
+
}, [refreshCounter]); // Refresh when counter changes
|
|
31
|
+
const toggle = (0, react_1.useCallback)((id) => {
|
|
32
|
+
if (selectedRef.current.has(id)) {
|
|
33
|
+
selectedRef.current.delete(id);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
selectedRef.current.add(id);
|
|
37
|
+
}
|
|
38
|
+
setCount(selectedRef.current.size);
|
|
39
|
+
setRefreshCounter((c) => c + 1);
|
|
40
|
+
}, []);
|
|
41
|
+
const selectAll = (0, react_1.useCallback)((ids) => {
|
|
42
|
+
selectedRef.current = new Set(ids);
|
|
43
|
+
setCount(ids.length);
|
|
44
|
+
setRefreshCounter((c) => c + 1);
|
|
45
|
+
}, []);
|
|
46
|
+
const clearAll = (0, react_1.useCallback)(() => {
|
|
47
|
+
selectedRef.current.clear();
|
|
48
|
+
setCount(0);
|
|
49
|
+
setRefreshCounter((c) => c + 1);
|
|
50
|
+
}, []);
|
|
51
|
+
const setSelection = (0, react_1.useCallback)((ids) => {
|
|
52
|
+
selectedRef.current = new Set(ids);
|
|
53
|
+
setCount(ids.length);
|
|
54
|
+
setRefreshCounter((c) => c + 1);
|
|
55
|
+
}, []);
|
|
56
|
+
return {
|
|
57
|
+
selected: selectedRef.current,
|
|
58
|
+
count,
|
|
59
|
+
isSelected,
|
|
60
|
+
toggle,
|
|
61
|
+
selectAll,
|
|
62
|
+
clearAll,
|
|
63
|
+
setSelection,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Hook for tracking recently changed items (for visual feedback)
|
|
68
|
+
* Automatically clears highlights after a timeout
|
|
69
|
+
*
|
|
70
|
+
* @param timeoutMs - How long to highlight changes (default: 3000ms)
|
|
71
|
+
*/
|
|
72
|
+
function useRecentChanges(timeoutMs = 3000) {
|
|
73
|
+
const [recentlyChanged, setRecentlyChanged] = (0, react_1.useState)(new Set());
|
|
74
|
+
const previousStatesRef = (0, react_1.useRef)(new Map());
|
|
75
|
+
const timeoutRef = (0, react_1.useRef)(null);
|
|
76
|
+
const detectChanges = (0, react_1.useCallback)((items, stateKey) => {
|
|
77
|
+
const changedIds = new Set();
|
|
78
|
+
items.forEach((item) => {
|
|
79
|
+
const id = (item.id || item.uid);
|
|
80
|
+
if (!id)
|
|
81
|
+
return;
|
|
82
|
+
const previousState = previousStatesRef.current.get(id);
|
|
83
|
+
const currentState = item[stateKey];
|
|
84
|
+
// If we have a previous state and it's different from current, mark as changed
|
|
85
|
+
if (previousState !== undefined && previousState !== currentState) {
|
|
86
|
+
changedIds.add(id);
|
|
87
|
+
}
|
|
88
|
+
// Update the previous state map
|
|
89
|
+
previousStatesRef.current.set(id, currentState);
|
|
90
|
+
});
|
|
91
|
+
// If we detected changes, highlight them
|
|
92
|
+
if (changedIds.size > 0) {
|
|
93
|
+
setRecentlyChanged(changedIds);
|
|
94
|
+
// Clear existing timeout
|
|
95
|
+
if (timeoutRef.current) {
|
|
96
|
+
clearTimeout(timeoutRef.current);
|
|
97
|
+
}
|
|
98
|
+
// Set new timeout to clear highlights
|
|
99
|
+
timeoutRef.current = setTimeout(() => {
|
|
100
|
+
setRecentlyChanged(new Set());
|
|
101
|
+
timeoutRef.current = null;
|
|
102
|
+
}, timeoutMs);
|
|
103
|
+
}
|
|
104
|
+
}, [timeoutMs]);
|
|
105
|
+
const isRecentlyChanged = (0, react_1.useCallback)((id) => {
|
|
106
|
+
return recentlyChanged.has(id);
|
|
107
|
+
}, [recentlyChanged]);
|
|
108
|
+
// Cleanup timeout on unmount
|
|
109
|
+
(0, react_1.useEffect)(() => {
|
|
110
|
+
return () => {
|
|
111
|
+
if (timeoutRef.current) {
|
|
112
|
+
clearTimeout(timeoutRef.current);
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
}, []);
|
|
116
|
+
return {
|
|
117
|
+
recentlyChanged,
|
|
118
|
+
isRecentlyChanged,
|
|
119
|
+
detectChanges,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import type { SGERPClient } from '../client';
|
|
2
|
+
import type { Simulation } from '../types/simulation/simulation';
|
|
3
|
+
import type { Booking } from '../types/simulation/booking';
|
|
4
|
+
import type { Vehicle } from '../types/simulation/vehicle';
|
|
5
|
+
import type { Driver } from '../types/simulation/driver';
|
|
6
|
+
import type { Geofence } from '../types/simulation/geofence';
|
|
7
|
+
import type { Node } from '../types/simulation/node';
|
|
8
|
+
import { type RouteNode } from '../utils/routeUtils';
|
|
9
|
+
export interface SimulationDataState {
|
|
10
|
+
vehicles: Vehicle[];
|
|
11
|
+
bookings: Booking[];
|
|
12
|
+
nodes: Node[];
|
|
13
|
+
drivers: Driver[];
|
|
14
|
+
geofences: Geofence[];
|
|
15
|
+
mainGeofence: Geofence | null;
|
|
16
|
+
vehicleRoutes: Map<number, {
|
|
17
|
+
waypoints: any[];
|
|
18
|
+
polyline?: any;
|
|
19
|
+
}>;
|
|
20
|
+
vehicleData: Map<number, {
|
|
21
|
+
assigned_nodes: RouteNode[];
|
|
22
|
+
completed_nodes: RouteNode[];
|
|
23
|
+
assigned_booking_uids: Set<string>;
|
|
24
|
+
completed_booking_uids: Set<string>;
|
|
25
|
+
}>;
|
|
26
|
+
loading: boolean;
|
|
27
|
+
error: Error | null;
|
|
28
|
+
}
|
|
29
|
+
export interface UseSimulationDataOptions {
|
|
30
|
+
/**
|
|
31
|
+
* Enable automatic data fetching on mount
|
|
32
|
+
* @default true
|
|
33
|
+
*/
|
|
34
|
+
enabled?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Enable live updates for vehicles, bookings, and nodes
|
|
37
|
+
* @default false
|
|
38
|
+
*/
|
|
39
|
+
enableLiveUpdates?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Live update interval in milliseconds
|
|
42
|
+
* @default 5000
|
|
43
|
+
*/
|
|
44
|
+
liveUpdateInterval?: number;
|
|
45
|
+
/**
|
|
46
|
+
* Callback when data is successfully loaded
|
|
47
|
+
*/
|
|
48
|
+
onSuccess?: (data: Omit<SimulationDataState, 'loading' | 'error'>) => void;
|
|
49
|
+
/**
|
|
50
|
+
* Callback when data loading fails
|
|
51
|
+
*/
|
|
52
|
+
onError?: (error: Error) => void;
|
|
53
|
+
/**
|
|
54
|
+
* Callback when live update occurs
|
|
55
|
+
*/
|
|
56
|
+
onLiveUpdate?: () => void;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* React hook for fetching and managing simulation data
|
|
60
|
+
* Encapsulates the full data loading pipeline: fetch, attach references, generate routes
|
|
61
|
+
*
|
|
62
|
+
* @param api - SGERP client instance
|
|
63
|
+
* @param simulationId - Simulation ID to fetch data for
|
|
64
|
+
* @param simulation - Optional simulation object (for fetching main geofence)
|
|
65
|
+
* @param options - Hook options
|
|
66
|
+
* @returns Simulation data state and control functions
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```tsx
|
|
70
|
+
* function SimulationPage({ simulationId }) {
|
|
71
|
+
* const api = useSGERP();
|
|
72
|
+
* const simulation = useCollection(api?.collections.simulation ?? null)
|
|
73
|
+
* ?.find(s => s.id === simulationId);
|
|
74
|
+
*
|
|
75
|
+
* // Basic usage - fetches data once
|
|
76
|
+
* const {
|
|
77
|
+
* vehicles,
|
|
78
|
+
* bookings,
|
|
79
|
+
* nodes,
|
|
80
|
+
* vehicleRoutes,
|
|
81
|
+
* vehicleData,
|
|
82
|
+
* loading,
|
|
83
|
+
* error,
|
|
84
|
+
* refetch
|
|
85
|
+
* } = useSimulationData(api, simulationId, simulation);
|
|
86
|
+
*
|
|
87
|
+
* // With live updates - automatically refreshes every 5 seconds
|
|
88
|
+
* const data = useSimulationData(api, simulationId, simulation, {
|
|
89
|
+
* enableLiveUpdates: true,
|
|
90
|
+
* liveUpdateInterval: 5000,
|
|
91
|
+
* onLiveUpdate: () => console.log('Data updated!')
|
|
92
|
+
* });
|
|
93
|
+
*
|
|
94
|
+
* if (loading) return <Spinner />;
|
|
95
|
+
* if (error) return <Error message={error.message} />;
|
|
96
|
+
*
|
|
97
|
+
* // All data is already processed - routes generated, references attached
|
|
98
|
+
* return <SimulationView vehicles={vehicles} bookings={bookings} routes={vehicleRoutes} />;
|
|
99
|
+
* }
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
export declare function useSimulationData(api: SGERPClient | null, simulationId: number | string | null, simulation?: Simulation | null, options?: UseSimulationDataOptions): SimulationDataState & {
|
|
103
|
+
refetch: () => Promise<void>;
|
|
104
|
+
};
|
|
105
|
+
//# sourceMappingURL=use-simulation-data.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-simulation-data.d.ts","sourceRoot":"","sources":["../../../sgerplib/sgerp/hooks/use-simulation-data.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAGrD,OAAO,EAAgC,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGnF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,YAAY,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,SAAS,EAAE,GAAG,EAAE,CAAC;QAAC,QAAQ,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC,CAAC;IACjE,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE;QACvB,cAAc,EAAE,SAAS,EAAE,CAAC;QAC5B,eAAe,EAAE,SAAS,EAAE,CAAC;QAC7B,qBAAqB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QACnC,sBAAsB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;KACrC,CAAC,CAAC;IACH,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAE5B;;OAEG;IACH,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,mBAAmB,EAAE,SAAS,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC;IAE3E;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAEjC;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,WAAW,GAAG,IAAI,EACvB,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,EACpC,UAAU,GAAE,UAAU,GAAG,IAAW,EACpC,OAAO,GAAE,wBAA6B,GACrC,mBAAmB,GAAG;IAAE,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CA2JxD"}
|