@burdenoff/microfe-movethewheels 2026.1031.2 → 2026.1031.4

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.
Files changed (74) hide show
  1. package/dist/MoveTheWheelsRoot.js +121 -104
  2. package/dist/MoveTheWheelsRoutes.js +142 -133
  3. package/dist/components/DocumentsCard.js +11 -11
  4. package/dist/components/ProofOfDeliveryCard.js +13 -13
  5. package/dist/components/ShipmentRiskDialog.js +24 -24
  6. package/dist/components/ShippingQuoteResults.js +46 -46
  7. package/dist/components/TrackingAlertList.js +17 -17
  8. package/dist/generated/tracking-quality-operations.d.ts +140 -0
  9. package/dist/hooks/useEntityImport.js +68 -0
  10. package/dist/hooks/useOrderDispatch.js +17 -17
  11. package/dist/movethewheels/hooks/useEntityImport.d.ts +19 -0
  12. package/dist/movethewheels/pages/ImportExportPage.d.ts +9 -0
  13. package/dist/movethewheels/pages/SettingsPage.d.ts +1 -0
  14. package/dist/movethewheels/providers/ModuleSettingsProvider.d.ts +17 -0
  15. package/dist/movethewheels/utils/entityImport.d.ts +109 -0
  16. package/dist/movethewheels/utils/formatters.d.ts +23 -3
  17. package/dist/movethewheels/utils/moduleSettings.d.ts +52 -0
  18. package/dist/node_modules/lucide-react/dist/esm/icons/arrow-down-up.js +22 -0
  19. package/dist/node_modules/lucide-react/dist/esm/icons/bell.js +11 -0
  20. package/dist/node_modules/lucide-react/dist/esm/icons/file-spreadsheet.js +30 -0
  21. package/dist/node_modules/lucide-react/dist/esm/icons/file-up.js +22 -0
  22. package/dist/node_modules/lucide-react/dist/esm/icons/key-round.js +14 -0
  23. package/dist/node_modules/lucide-react/dist/esm/icons/plug.js +22 -0
  24. package/dist/node_modules/lucide-react/dist/esm/icons/rotate-ccw.js +11 -0
  25. package/dist/node_modules/lucide-react/dist/esm/icons/settings.js +13 -0
  26. package/dist/pages/AnalyticsPage.js +27 -27
  27. package/dist/pages/CreateOrderPage.js +340 -317
  28. package/dist/pages/CustomerDetailsPage.js +246 -246
  29. package/dist/pages/CustomersPage.js +88 -79
  30. package/dist/pages/DashboardPage.js +24 -24
  31. package/dist/pages/DeliveryCapturePage.js +74 -74
  32. package/dist/pages/DriverDetailsPage.js +337 -337
  33. package/dist/pages/DriversPage.js +119 -110
  34. package/dist/pages/FinancePage.js +26 -26
  35. package/dist/pages/ImportExportPage.js +435 -0
  36. package/dist/pages/InventoryPage.js +28 -28
  37. package/dist/pages/LiveTrackingPage.js +108 -108
  38. package/dist/pages/MarketplacePage.js +44 -44
  39. package/dist/pages/OrderDetailsPage.js +306 -306
  40. package/dist/pages/OrdersListPage.js +27 -27
  41. package/dist/pages/ProductDetailsPage.js +89 -89
  42. package/dist/pages/ProductsPage.js +86 -77
  43. package/dist/pages/RouteDetailsPage.js +282 -285
  44. package/dist/pages/RoutesPage.js +78 -78
  45. package/dist/pages/SettingsPage.js +459 -0
  46. package/dist/pages/TrackingPage.js +41 -41
  47. package/dist/pages/VehicleDetailsPage.js +207 -207
  48. package/dist/pages/VehiclesPage.js +100 -90
  49. package/dist/pages/WarehouseDetailsPage.js +132 -132
  50. package/dist/pages/WarehousesPage.js +97 -88
  51. package/dist/providers/ModuleSettingsProvider.js +74 -0
  52. package/dist/utils/entityImport.js +73 -0
  53. package/dist/utils/formatters.js +53 -26
  54. package/dist/utils/moduleSettings.js +132 -0
  55. package/package.json +4 -2
  56. package/src/generated/tracking-quality-operations.ts +184 -0
  57. package/src/movethewheels/MoveTheWheelsRoot.tsx +22 -3
  58. package/src/movethewheels/MoveTheWheelsRoutes.tsx +13 -0
  59. package/src/movethewheels/hooks/useEntityImport.ts +108 -0
  60. package/src/movethewheels/pages/CreateOrderPage.tsx +38 -6
  61. package/src/movethewheels/pages/CustomersPage.tsx +6 -1
  62. package/src/movethewheels/pages/DriversPage.tsx +6 -0
  63. package/src/movethewheels/pages/ImportExportPage.tsx +483 -0
  64. package/src/movethewheels/pages/ProductsPage.tsx +16 -3
  65. package/src/movethewheels/pages/RouteDetailsPage.tsx +3 -6
  66. package/src/movethewheels/pages/RoutesPage.tsx +2 -2
  67. package/src/movethewheels/pages/SettingsPage.tsx +516 -0
  68. package/src/movethewheels/pages/VehicleDetailsPage.tsx +4 -2
  69. package/src/movethewheels/pages/VehiclesPage.tsx +8 -1
  70. package/src/movethewheels/pages/WarehousesPage.tsx +6 -1
  71. package/src/movethewheels/providers/ModuleSettingsProvider.tsx +133 -0
  72. package/src/movethewheels/utils/entityImport.ts +239 -0
  73. package/src/movethewheels/utils/formatters.ts +69 -10
  74. package/src/movethewheels/utils/moduleSettings.ts +224 -0
@@ -0,0 +1,224 @@
1
+ /**
2
+ * Module settings — client side of wspace-movethewheels-svc's workspace
3
+ * operational defaults (BOFF-10488).
4
+ *
5
+ * The service owns validation and storage; this module holds the GraphQL
6
+ * documents, the platform defaults (used until the settings load), the
7
+ * picker options and the mapping between the service's order priorities and
8
+ * the order form's. Kept free of React so the contract can be unit-tested.
9
+ */
10
+ import type { FormatPreferences } from './formatters';
11
+
12
+ export type MtwDistanceUnit = 'KM' | 'MI';
13
+ export type MtwWeightUnit = 'KG' | 'LB';
14
+ export type MtwOrderPriority = 'LOW' | 'MEDIUM' | 'HIGH' | 'URGENT' | 'CRITICAL';
15
+
16
+ export interface MtwModuleSettings {
17
+ workspaceId: string;
18
+ defaultCurrency: string;
19
+ distanceUnit: MtwDistanceUnit;
20
+ weightUnit: MtwWeightUnit;
21
+ /** IANA zone; null shows each viewer their own local time. */
22
+ timezone: string | null;
23
+ defaultOrderPriority: MtwOrderPriority;
24
+ defaultDeliveryWindowHours: number;
25
+ isCustomized: boolean;
26
+ updatedAt: string | null;
27
+ updatedBy: string | null;
28
+ }
29
+
30
+ export type MtwModuleSettingsInput = Partial<
31
+ Pick<
32
+ MtwModuleSettings,
33
+ | 'defaultCurrency'
34
+ | 'distanceUnit'
35
+ | 'weightUnit'
36
+ | 'timezone'
37
+ | 'defaultOrderPriority'
38
+ | 'defaultDeliveryWindowHours'
39
+ >
40
+ >;
41
+
42
+ /** Mirrors the service range for the default delivery window. */
43
+ export const DELIVERY_WINDOW_MIN_HOURS = 1;
44
+ export const DELIVERY_WINDOW_MAX_HOURS = 720;
45
+
46
+ /** The service's platform defaults, shown until the workspace's settings load. */
47
+ export function platformDefaults(workspaceId = ''): MtwModuleSettings {
48
+ return {
49
+ workspaceId,
50
+ defaultCurrency: 'USD',
51
+ distanceUnit: 'KM',
52
+ weightUnit: 'KG',
53
+ timezone: null,
54
+ defaultOrderPriority: 'MEDIUM',
55
+ defaultDeliveryWindowHours: 24,
56
+ isCustomized: false,
57
+ updatedAt: null,
58
+ updatedBy: null,
59
+ };
60
+ }
61
+
62
+ const SETTINGS_FIELDS = `
63
+ workspaceId
64
+ defaultCurrency
65
+ distanceUnit
66
+ weightUnit
67
+ timezone
68
+ defaultOrderPriority
69
+ defaultDeliveryWindowHours
70
+ isCustomized
71
+ updatedAt
72
+ updatedBy
73
+ `;
74
+
75
+ export const MTW_MODULE_SETTINGS_QUERY = `
76
+ query MtwModuleSettings {
77
+ mtwModuleSettings {
78
+ ${SETTINGS_FIELDS}
79
+ }
80
+ }
81
+ `;
82
+
83
+ export const UPDATE_MTW_MODULE_SETTINGS_MUTATION = `
84
+ mutation UpdateMtwModuleSettings($input: UpdateMtwModuleSettingsInput!) {
85
+ updateMtwModuleSettings(input: $input) {
86
+ ${SETTINGS_FIELDS}
87
+ }
88
+ }
89
+ `;
90
+
91
+ /** What the formatters need from the settings. */
92
+ export function toFormatPreferences(settings: MtwModuleSettings): FormatPreferences {
93
+ return {
94
+ currency: settings.defaultCurrency,
95
+ distanceUnit: settings.distanceUnit,
96
+ weightUnit: settings.weightUnit,
97
+ timeZone: settings.timezone,
98
+ };
99
+ }
100
+
101
+ export const DISTANCE_UNIT_OPTIONS: ReadonlyArray<{ value: MtwDistanceUnit; label: string }> = [
102
+ { value: 'KM', label: 'Kilometres (km)' },
103
+ { value: 'MI', label: 'Miles (mi)' },
104
+ ];
105
+
106
+ export const WEIGHT_UNIT_OPTIONS: ReadonlyArray<{ value: MtwWeightUnit; label: string }> = [
107
+ { value: 'KG', label: 'Kilograms (kg)' },
108
+ { value: 'LB', label: 'Pounds (lb)' },
109
+ ];
110
+
111
+ export const ORDER_PRIORITY_OPTIONS: ReadonlyArray<{ value: MtwOrderPriority; label: string }> = [
112
+ { value: 'LOW', label: 'Low' },
113
+ { value: 'MEDIUM', label: 'Normal' },
114
+ { value: 'HIGH', label: 'High' },
115
+ { value: 'URGENT', label: 'Urgent' },
116
+ { value: 'CRITICAL', label: 'Critical' },
117
+ ];
118
+
119
+ /** The order form's four priorities for a service priority (CRITICAL shows as urgent). */
120
+ export function orderFormPriority(
121
+ priority: MtwOrderPriority
122
+ ): 'low' | 'normal' | 'high' | 'urgent' {
123
+ switch (priority) {
124
+ case 'LOW':
125
+ return 'low';
126
+ case 'HIGH':
127
+ return 'high';
128
+ case 'URGENT':
129
+ case 'CRITICAL':
130
+ return 'urgent';
131
+ default:
132
+ return 'normal';
133
+ }
134
+ }
135
+
136
+ /** Commonly used currencies first, then every other code the browser knows. */
137
+ const PREFERRED_CURRENCIES = ['USD', 'EUR', 'GBP', 'INR', 'AED', 'SGD', 'AUD', 'CAD', 'JPY', 'CNY'];
138
+
139
+ function supportedValues(key: 'currency' | 'timeZone'): string[] {
140
+ // Older browsers lack Intl.supportedValuesOf; the pickers then offer the
141
+ // preferred list plus the saved value.
142
+ return typeof Intl.supportedValuesOf === 'function' ? Intl.supportedValuesOf(key) : [];
143
+ }
144
+
145
+ export function currencyOptions(current?: string): string[] {
146
+ const all = new Set([...PREFERRED_CURRENCIES, ...supportedValues('currency')]);
147
+ if (current) all.add(current);
148
+ const rest = [...all].filter((code) => !PREFERRED_CURRENCIES.includes(code)).sort();
149
+ return [...PREFERRED_CURRENCIES, ...rest];
150
+ }
151
+
152
+ export function currencyLabel(code: string): string {
153
+ try {
154
+ const name = new Intl.DisplayNames(['en'], { type: 'currency' }).of(code);
155
+ return name && name !== code ? `${code} — ${name}` : code;
156
+ } catch {
157
+ return code;
158
+ }
159
+ }
160
+
161
+ export function timeZoneOptions(current?: string | null): string[] {
162
+ const zones = new Set(['UTC', ...supportedValues('timeZone')]);
163
+ if (current) zones.add(current);
164
+ return [...zones].sort((a, b) => (a === 'UTC' ? -1 : b === 'UTC' ? 1 : a.localeCompare(b)));
165
+ }
166
+
167
+ /** The browser's own zone, for the "viewer's local time" option label. */
168
+ export function browserTimeZone(): string {
169
+ try {
170
+ return Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC';
171
+ } catch {
172
+ return 'UTC';
173
+ }
174
+ }
175
+
176
+ /** Client-side check of the delivery window before it is sent. */
177
+ export function deliveryWindowError(value: string): string | null {
178
+ const hours = Number(value);
179
+ if (
180
+ !value.trim() ||
181
+ !Number.isInteger(hours) ||
182
+ hours < DELIVERY_WINDOW_MIN_HOURS ||
183
+ hours > DELIVERY_WINDOW_MAX_HOURS
184
+ ) {
185
+ return `Enter a whole number of hours between ${DELIVERY_WINDOW_MIN_HOURS} and ${DELIVERY_WINDOW_MAX_HOURS}.`;
186
+ }
187
+ return null;
188
+ }
189
+
190
+ /** Only the fields that differ from the saved settings. */
191
+ export function changedSettings(
192
+ saved: MtwModuleSettings,
193
+ draft: MtwModuleSettingsInput
194
+ ): MtwModuleSettingsInput {
195
+ const changes: MtwModuleSettingsInput = {};
196
+ if (draft.defaultCurrency !== undefined && draft.defaultCurrency !== saved.defaultCurrency)
197
+ changes.defaultCurrency = draft.defaultCurrency;
198
+ if (draft.distanceUnit !== undefined && draft.distanceUnit !== saved.distanceUnit)
199
+ changes.distanceUnit = draft.distanceUnit;
200
+ if (draft.weightUnit !== undefined && draft.weightUnit !== saved.weightUnit)
201
+ changes.weightUnit = draft.weightUnit;
202
+ if (draft.timezone !== undefined && draft.timezone !== saved.timezone)
203
+ changes.timezone = draft.timezone;
204
+ if (
205
+ draft.defaultOrderPriority !== undefined &&
206
+ draft.defaultOrderPriority !== saved.defaultOrderPriority
207
+ )
208
+ changes.defaultOrderPriority = draft.defaultOrderPriority;
209
+ if (
210
+ draft.defaultDeliveryWindowHours !== undefined &&
211
+ draft.defaultDeliveryWindowHours !== saved.defaultDeliveryWindowHours
212
+ )
213
+ changes.defaultDeliveryWindowHours = draft.defaultDeliveryWindowHours;
214
+ return changes;
215
+ }
216
+
217
+ /** A `datetime-local` value `hours` from `from`, in the viewer's clock. */
218
+ export function deliveryWindowValue(hours: number, from: Date = new Date()): string {
219
+ const target = new Date(from.getTime() + hours * 3600 * 1000);
220
+ const pad = (value: number) => String(value).padStart(2, '0');
221
+ return `${target.getFullYear()}-${pad(target.getMonth() + 1)}-${pad(target.getDate())}T${pad(
222
+ target.getHours()
223
+ )}:${pad(target.getMinutes())}`;
224
+ }