kaafil-react-uikit 0.3.0 → 0.4.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/CHANGELOG.md +54 -0
- package/dist/admin/index.cjs +565 -387
- package/dist/admin/index.cjs.map +1 -1
- package/dist/admin/index.d.cts +2 -2
- package/dist/admin/index.d.ts +2 -2
- package/dist/admin/index.js +231 -53
- package/dist/admin/index.js.map +1 -1
- package/dist/{chunk-YTSYRLGS.js → chunk-2LMFSKZU.js} +56 -17
- package/dist/chunk-2LMFSKZU.js.map +1 -0
- package/dist/{chunk-BBC5EX5O.cjs → chunk-2XW5EIMS.cjs} +17 -17
- package/dist/{chunk-BBC5EX5O.cjs.map → chunk-2XW5EIMS.cjs.map} +1 -1
- package/dist/{chunk-YU2242AR.js → chunk-3BEQYIFU.js} +5 -5
- package/dist/{chunk-YU2242AR.js.map → chunk-3BEQYIFU.js.map} +1 -1
- package/dist/{chunk-UALMCHNW.cjs → chunk-3N2EQ2KC.cjs} +84 -36
- package/dist/chunk-3N2EQ2KC.cjs.map +1 -0
- package/dist/{chunk-57SUK3GD.cjs → chunk-4QYI7TOF.cjs} +7 -7
- package/dist/{chunk-57SUK3GD.cjs.map → chunk-4QYI7TOF.cjs.map} +1 -1
- package/dist/{chunk-ECCQW5LN.cjs → chunk-6BY2NPBZ.cjs} +4 -4
- package/dist/{chunk-ECCQW5LN.cjs.map → chunk-6BY2NPBZ.cjs.map} +1 -1
- package/dist/{chunk-YNHOPYBK.cjs → chunk-7356B6YS.cjs} +12 -12
- package/dist/{chunk-YNHOPYBK.cjs.map → chunk-7356B6YS.cjs.map} +1 -1
- package/dist/{chunk-A4Z2YBEF.js → chunk-7G6IENKN.js} +84 -36
- package/dist/chunk-7G6IENKN.js.map +1 -0
- package/dist/{chunk-MNUCVVIE.cjs → chunk-A7C74SJT.cjs} +302 -148
- package/dist/chunk-A7C74SJT.cjs.map +1 -0
- package/dist/{chunk-KW5LH6KV.js → chunk-CLHAJBJS.js} +3 -3
- package/dist/{chunk-KW5LH6KV.js.map → chunk-CLHAJBJS.js.map} +1 -1
- package/dist/{chunk-GJ2J3PYN.js → chunk-E6ER25BG.js} +3 -3
- package/dist/{chunk-GJ2J3PYN.js.map → chunk-E6ER25BG.js.map} +1 -1
- package/dist/{chunk-HACH2NUM.cjs → chunk-KETEED2T.cjs} +9 -9
- package/dist/{chunk-HACH2NUM.cjs.map → chunk-KETEED2T.cjs.map} +1 -1
- package/dist/{chunk-RWLO6IFX.js → chunk-KTEXDGAA.js} +3 -3
- package/dist/{chunk-RWLO6IFX.js.map → chunk-KTEXDGAA.js.map} +1 -1
- package/dist/{chunk-VLP323AD.js → chunk-RBIEMGHT.js} +3 -3
- package/dist/{chunk-VLP323AD.js.map → chunk-RBIEMGHT.js.map} +1 -1
- package/dist/{chunk-WTTGPWMR.js → chunk-WPQB7JWS.js} +227 -73
- package/dist/chunk-WPQB7JWS.js.map +1 -0
- package/dist/{chunk-FVK7HMQ5.cjs → chunk-XBLAVNP3.cjs} +88 -48
- package/dist/chunk-XBLAVNP3.cjs.map +1 -0
- package/dist/core/index.cjs +124 -121
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +10 -1
- package/dist/core/index.d.ts +10 -1
- package/dist/core/index.js +20 -19
- package/dist/core/index.js.map +1 -1
- package/dist/index.css +1 -1
- package/dist/manager/index.cjs +239 -239
- package/dist/manager/index.js +6 -6
- package/dist/tokens.json +5013 -0
- package/dist/traveller/index.cjs +46 -40
- package/dist/traveller/index.cjs.map +1 -1
- package/dist/traveller/index.js +16 -10
- package/dist/traveller/index.js.map +1 -1
- package/dist/{useAgencyTrip-BUYSIaC2.d.cts → useAgencyTrip-C1YmfuQq.d.cts} +35 -1
- package/dist/{useAgencyTrip-BzyJB1D9.d.ts → useAgencyTrip-gZB0NILH.d.ts} +35 -1
- package/package.json +4 -3
- package/dist/chunk-A4Z2YBEF.js.map +0 -1
- package/dist/chunk-FVK7HMQ5.cjs.map +0 -1
- package/dist/chunk-MNUCVVIE.cjs.map +0 -1
- package/dist/chunk-UALMCHNW.cjs.map +0 -1
- package/dist/chunk-WTTGPWMR.js.map +0 -1
- package/dist/chunk-YTSYRLGS.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { OfflineEngineContext, KaafilClientContext, useCapabilityRows, UNKNOWN_CAPABILITY_TRIPLE, deriveCapabilityTriple, darkReasonFor, useKaafilClient, useOfflineMutation, usePersona, isDevelopment, useOfflineEvent } from './chunk-
|
|
2
|
-
import { UnsatisfiableSchemeError, isKaafilError, SyncOpMethod } from 'kaafil-js/client';
|
|
1
|
+
import { OfflineEngineContext, KaafilClientContext, useCapabilityRows, UNKNOWN_CAPABILITY_TRIPLE, deriveCapabilityTriple, darkReasonFor, useKaafilClient, useOfflineMutation, usePersona, isDevelopment, useOfflineEvent } from './chunk-7G6IENKN.js';
|
|
2
|
+
import { UnsatisfiableSchemeError, isKaafilError, SyncOpMethod, normalizeDateTimeInput } from 'kaafil-js/client';
|
|
3
3
|
export { FALLBACK_GLYPH, SHADES_PER_FAMILY, TONE_FAMILIES, parseRoomingTone, roomingHeuristicSeverity } from 'kaafil-js/client';
|
|
4
4
|
import { useContext, useState, useRef, useCallback, useEffect } from 'react';
|
|
5
5
|
|
|
@@ -176,6 +176,43 @@ function createDomainHook(moduleKey, build) {
|
|
|
176
176
|
}
|
|
177
177
|
|
|
178
178
|
// src/core/hooks/useChecklists.ts
|
|
179
|
+
function optimisticChecklistItem(input, sections, fetchedAt) {
|
|
180
|
+
return {
|
|
181
|
+
// Replaced by the id the engine mints — this hook never invents identity.
|
|
182
|
+
id: "pending",
|
|
183
|
+
// Cannot beat any server row in the snapshot's version-guarded merge.
|
|
184
|
+
version: 0,
|
|
185
|
+
// The write addresses a section by KEY; the board groups rows by ID. An
|
|
186
|
+
// unknown section leaves the row ungrouped rather than filing it under a
|
|
187
|
+
// heading that does not exist.
|
|
188
|
+
sectionId: sections.find((section) => section.key === input.sectionKey)?.id ?? "",
|
|
189
|
+
// The server derives the key from the title when one is not sent. Blank
|
|
190
|
+
// rather than a guessed slug: a key that disagrees with the server's is
|
|
191
|
+
// worse than an obviously-absent one, and nothing renders it.
|
|
192
|
+
key: input.key ?? "",
|
|
193
|
+
title: input.title,
|
|
194
|
+
subLine: null,
|
|
195
|
+
status: "OPEN",
|
|
196
|
+
// `=== true`, never `?? false` (hard rule #5): an omitted `mandatory` is
|
|
197
|
+
// the SERVER's default to apply, not this hook's to guess.
|
|
198
|
+
isMandatory: input.mandatory === true,
|
|
199
|
+
// `'NONE'`, never null. The add request carries no `gate` at all — the
|
|
200
|
+
// engine derives it from `phase` — and `'NONE'` is the one value that
|
|
201
|
+
// cannot make a pending item look like it is blocking the trip.
|
|
202
|
+
gate: "NONE",
|
|
203
|
+
dayOffset: null,
|
|
204
|
+
// Appended. The server's own ordering arrives with the canonical row.
|
|
205
|
+
sortOrder: Number.MAX_SAFE_INTEGER,
|
|
206
|
+
completedByManagerId: null,
|
|
207
|
+
performedByKind: null,
|
|
208
|
+
performedById: null,
|
|
209
|
+
completedAt: null,
|
|
210
|
+
// The last reading the SERVER gave this hook, never a device clock (hard
|
|
211
|
+
// rule #6). Blank when nothing has been fetched yet, which is the only
|
|
212
|
+
// honest answer and which the board already prefers `fetchedAt` over.
|
|
213
|
+
updatedAt: fetchedAt ?? ""
|
|
214
|
+
};
|
|
215
|
+
}
|
|
179
216
|
function appendPendingRows(fromAggregate, fromSnapshot) {
|
|
180
217
|
if (fromSnapshot.length === 0) {
|
|
181
218
|
return fromAggregate;
|
|
@@ -283,28 +320,7 @@ var useChecklistsInternal = createDomainHook("checklists", (tripRef) => {
|
|
|
283
320
|
// yet resolves to `''` and the row sits ungrouped until the write
|
|
284
321
|
// lands — correct rather than clever: inventing a section id would
|
|
285
322
|
// put the item under a heading that does not exist.
|
|
286
|
-
optimistic:
|
|
287
|
-
id: "pending",
|
|
288
|
-
version: 0,
|
|
289
|
-
sectionId: aggregate.sections.find((section) => section.key === input.sectionKey)?.id ?? "",
|
|
290
|
-
key: input.key ?? null,
|
|
291
|
-
title: input.title,
|
|
292
|
-
subLine: null,
|
|
293
|
-
status: "OPEN",
|
|
294
|
-
// `=== true`, never `?? false` (hard rule #5): an omitted
|
|
295
|
-
// `mandatory` is the SERVER's default to apply, not this hook's to
|
|
296
|
-
// guess. The optimistic row shows it unstarred for the moment it
|
|
297
|
-
// takes the write to land, and the canonical row replaces it.
|
|
298
|
-
isMandatory: input.mandatory === true,
|
|
299
|
-
gate: null,
|
|
300
|
-
dayOffset: null,
|
|
301
|
-
sortOrder: Number.MAX_SAFE_INTEGER,
|
|
302
|
-
completedByManagerId: null,
|
|
303
|
-
performedByKind: null,
|
|
304
|
-
performedById: null,
|
|
305
|
-
completedAt: null,
|
|
306
|
-
updatedAt: null
|
|
307
|
-
}
|
|
323
|
+
optimistic: optimisticChecklistItem(input, aggregate.sections, aggregate.fetchedAt)
|
|
308
324
|
}),
|
|
309
325
|
// ── THE DESK LANE ─────────────────────────────────────────────────
|
|
310
326
|
// All five checklist writes take the admin triple, and a desk console
|
|
@@ -539,6 +555,34 @@ var useCloseoutInternal = createDomainHook("closing-day", (tripRef) => {
|
|
|
539
555
|
function useCloseout(tripRef) {
|
|
540
556
|
return useCloseoutInternal(tripRef);
|
|
541
557
|
}
|
|
558
|
+
function optimisticCollection(input, syncedAt) {
|
|
559
|
+
const collectedAt = input.collectedAt === void 0 ? "" : normalizeDateTimeInput(input.collectedAt, "collectedAt");
|
|
560
|
+
return {
|
|
561
|
+
// Replaced by the id the engine mints.
|
|
562
|
+
id: "pending",
|
|
563
|
+
version: 0,
|
|
564
|
+
travellerId: input.travellerId,
|
|
565
|
+
amountMinor: input.amountMinor,
|
|
566
|
+
// The request's own default, restated: this tenant's money unit.
|
|
567
|
+
currency: input.currency ?? "INR",
|
|
568
|
+
mode: input.mode,
|
|
569
|
+
reference: input.reference ?? null,
|
|
570
|
+
note: input.note ?? null,
|
|
571
|
+
collectedByManagerId: null,
|
|
572
|
+
performedByKind: null,
|
|
573
|
+
performedById: null,
|
|
574
|
+
collectedAt,
|
|
575
|
+
reportedAt: null,
|
|
576
|
+
voidedAt: null,
|
|
577
|
+
voidReason: null,
|
|
578
|
+
// The server's arithmetic, deliberately not guessed — see above.
|
|
579
|
+
outstandingMinor: null,
|
|
580
|
+
// The last reading the SERVER gave this list, never a device clock
|
|
581
|
+
// (hard rule #6).
|
|
582
|
+
createdAt: syncedAt ?? "",
|
|
583
|
+
updatedAt: syncedAt ?? ""
|
|
584
|
+
};
|
|
585
|
+
}
|
|
542
586
|
var useCollectionsInternal = createDomainHook("collections", (tripRef) => {
|
|
543
587
|
const client = useKaafilClient();
|
|
544
588
|
const {
|
|
@@ -588,7 +632,12 @@ var useCollectionsInternal = createDomainHook("collections", (tripRef) => {
|
|
|
588
632
|
// hardcoded literal, verified against
|
|
589
633
|
// `kaafil-js/src/generated/security.ts` this session.
|
|
590
634
|
operationId: "recordCollection",
|
|
591
|
-
body: input
|
|
635
|
+
body: input,
|
|
636
|
+
// A payment recorded out of signal appears at once — see
|
|
637
|
+
// `optimisticCollection` for what it deliberately does not claim.
|
|
638
|
+
creates: true,
|
|
639
|
+
entity: { listName: "collections" },
|
|
640
|
+
optimistic: optimisticCollection(input, syncedAt)
|
|
592
641
|
}),
|
|
593
642
|
// The desk lane. `recordCollection` takes the admin triple, and a desk
|
|
594
643
|
// console mounts no `OfflineShell` — without this the write has no
|
|
@@ -677,9 +726,19 @@ var useExpensesInternal = createDomainHook("expenses", (tripRef) => {
|
|
|
677
726
|
useEffect(() => {
|
|
678
727
|
void refreshTotals();
|
|
679
728
|
}, [refreshTotals]);
|
|
729
|
+
const engine = useContext(OfflineEngineContext);
|
|
730
|
+
useEffect(() => {
|
|
731
|
+
if (engine === null) {
|
|
732
|
+
return;
|
|
733
|
+
}
|
|
734
|
+
const unsubscribe = engine.events.on("sync.drained", () => {
|
|
735
|
+
void refreshTotals();
|
|
736
|
+
});
|
|
737
|
+
return unsubscribe;
|
|
738
|
+
}, [engine, refreshTotals]);
|
|
680
739
|
const logMutation = useOfflineMutation({
|
|
681
740
|
tripRef,
|
|
682
|
-
enqueue: (
|
|
741
|
+
enqueue: (engine2, input) => engine2.enqueue({
|
|
683
742
|
tripRef,
|
|
684
743
|
method: SyncOpMethod.Post,
|
|
685
744
|
path: `/api/v1/trips/${tripRef}/expenses`,
|
|
@@ -700,9 +759,9 @@ var useExpensesInternal = createDomainHook("expenses", (tripRef) => {
|
|
|
700
759
|
});
|
|
701
760
|
const linkReceiptMutation = useOfflineMutation({
|
|
702
761
|
tripRef,
|
|
703
|
-
enqueue: (
|
|
762
|
+
enqueue: (engine2, input) => {
|
|
704
763
|
const { expenseId, ...body } = input;
|
|
705
|
-
return
|
|
764
|
+
return engine2.enqueue({
|
|
706
765
|
tripRef,
|
|
707
766
|
method: SyncOpMethod.Patch,
|
|
708
767
|
path: `/api/v1/trips/${tripRef}/expenses/${expenseId}/receipt`,
|
|
@@ -723,9 +782,9 @@ var useExpensesInternal = createDomainHook("expenses", (tripRef) => {
|
|
|
723
782
|
});
|
|
724
783
|
const voidMutation = useOfflineMutation({
|
|
725
784
|
tripRef,
|
|
726
|
-
enqueue: (
|
|
785
|
+
enqueue: (engine2, input) => {
|
|
727
786
|
const { expenseId, version, ...body } = input;
|
|
728
|
-
return
|
|
787
|
+
return engine2.enqueue({
|
|
729
788
|
tripRef,
|
|
730
789
|
method: SyncOpMethod.Delete,
|
|
731
790
|
path: `/api/v1/trips/${tripRef}/expenses/${expenseId}/void`,
|
|
@@ -738,9 +797,9 @@ var useExpensesInternal = createDomainHook("expenses", (tripRef) => {
|
|
|
738
797
|
});
|
|
739
798
|
const submitClaimMutation = useOfflineMutation({
|
|
740
799
|
tripRef,
|
|
741
|
-
enqueue: (
|
|
800
|
+
enqueue: (engine2, input) => {
|
|
742
801
|
const { expenseId } = input;
|
|
743
|
-
return
|
|
802
|
+
return engine2.enqueue({
|
|
744
803
|
tripRef,
|
|
745
804
|
method: SyncOpMethod.Post,
|
|
746
805
|
path: `/api/v1/trips/${tripRef}/expenses/${expenseId}/claim`,
|
|
@@ -751,9 +810,9 @@ var useExpensesInternal = createDomainHook("expenses", (tripRef) => {
|
|
|
751
810
|
});
|
|
752
811
|
const withdrawClaimMutation = useOfflineMutation({
|
|
753
812
|
tripRef,
|
|
754
|
-
enqueue: (
|
|
813
|
+
enqueue: (engine2, input) => {
|
|
755
814
|
const { expenseId, version } = input;
|
|
756
|
-
return
|
|
815
|
+
return engine2.enqueue({
|
|
757
816
|
tripRef,
|
|
758
817
|
method: SyncOpMethod.Delete,
|
|
759
818
|
path: `/api/v1/trips/${tripRef}/expenses/${expenseId}/claim/withdraw`,
|
|
@@ -1220,6 +1279,16 @@ function useItinerary(tripRef) {
|
|
|
1220
1279
|
useEffect(() => {
|
|
1221
1280
|
void refresh();
|
|
1222
1281
|
}, [refresh]);
|
|
1282
|
+
const engine = useContext(OfflineEngineContext);
|
|
1283
|
+
const refreshAfterDrain = useCallback(() => {
|
|
1284
|
+
if (engine === null) {
|
|
1285
|
+
return;
|
|
1286
|
+
}
|
|
1287
|
+
const unsubscribe = engine.events.on("sync.drained", () => {
|
|
1288
|
+
unsubscribe();
|
|
1289
|
+
void refresh();
|
|
1290
|
+
});
|
|
1291
|
+
}, [engine, refresh]);
|
|
1223
1292
|
const [changeLog, setChangeLog] = useState([]);
|
|
1224
1293
|
const [changeLogLoaded, setChangeLogLoaded] = useState(false);
|
|
1225
1294
|
const [changeLogFetchFailed, setChangeLogFetchFailed] = useState(false);
|
|
@@ -1238,9 +1307,9 @@ function useItinerary(tripRef) {
|
|
|
1238
1307
|
);
|
|
1239
1308
|
const patchDayMutation = useOfflineMutation({
|
|
1240
1309
|
tripRef,
|
|
1241
|
-
enqueue: (
|
|
1310
|
+
enqueue: (engine2, input) => {
|
|
1242
1311
|
const { dayIndex, version, ...body } = input;
|
|
1243
|
-
return
|
|
1312
|
+
return engine2.enqueue({
|
|
1244
1313
|
tripRef,
|
|
1245
1314
|
method: SyncOpMethod.Patch,
|
|
1246
1315
|
path: `/api/v1/trips/${tripRef}/itinerary/days/${dayIndex}`,
|
|
@@ -1256,13 +1325,14 @@ function useItinerary(tripRef) {
|
|
|
1256
1325
|
async (input) => {
|
|
1257
1326
|
const op = await patchDayMutate(input);
|
|
1258
1327
|
void refresh();
|
|
1328
|
+
refreshAfterDrain();
|
|
1259
1329
|
return op;
|
|
1260
1330
|
},
|
|
1261
|
-
[patchDayMutate, refresh]
|
|
1331
|
+
[patchDayMutate, refresh, refreshAfterDrain]
|
|
1262
1332
|
);
|
|
1263
1333
|
const addItemMutation = useOfflineMutation({
|
|
1264
1334
|
tripRef,
|
|
1265
|
-
enqueue: (
|
|
1335
|
+
enqueue: (engine2, input) => engine2.enqueue({
|
|
1266
1336
|
tripRef,
|
|
1267
1337
|
method: SyncOpMethod.Post,
|
|
1268
1338
|
path: `/api/v1/trips/${tripRef}/itinerary/items`,
|
|
@@ -1276,15 +1346,16 @@ function useItinerary(tripRef) {
|
|
|
1276
1346
|
async (input) => {
|
|
1277
1347
|
const op = await addItemMutate(input);
|
|
1278
1348
|
void refresh();
|
|
1349
|
+
refreshAfterDrain();
|
|
1279
1350
|
return op;
|
|
1280
1351
|
},
|
|
1281
|
-
[addItemMutate, refresh]
|
|
1352
|
+
[addItemMutate, refresh, refreshAfterDrain]
|
|
1282
1353
|
);
|
|
1283
1354
|
const patchItemMutation = useOfflineMutation({
|
|
1284
1355
|
tripRef,
|
|
1285
|
-
enqueue: (
|
|
1356
|
+
enqueue: (engine2, input) => {
|
|
1286
1357
|
const { itemId, version, ...body } = input;
|
|
1287
|
-
return
|
|
1358
|
+
return engine2.enqueue({
|
|
1288
1359
|
tripRef,
|
|
1289
1360
|
method: SyncOpMethod.Patch,
|
|
1290
1361
|
path: `/api/v1/trips/${tripRef}/itinerary/items/${itemId}`,
|
|
@@ -1300,15 +1371,16 @@ function useItinerary(tripRef) {
|
|
|
1300
1371
|
async (input) => {
|
|
1301
1372
|
const op = await patchItemMutate(input);
|
|
1302
1373
|
void refresh();
|
|
1374
|
+
refreshAfterDrain();
|
|
1303
1375
|
return op;
|
|
1304
1376
|
},
|
|
1305
|
-
[patchItemMutate, refresh]
|
|
1377
|
+
[patchItemMutate, refresh, refreshAfterDrain]
|
|
1306
1378
|
);
|
|
1307
1379
|
const removeItemMutation = useOfflineMutation({
|
|
1308
1380
|
tripRef,
|
|
1309
|
-
enqueue: (
|
|
1381
|
+
enqueue: (engine2, input) => {
|
|
1310
1382
|
const { itemId, version } = input;
|
|
1311
|
-
return
|
|
1383
|
+
return engine2.enqueue({
|
|
1312
1384
|
tripRef,
|
|
1313
1385
|
method: SyncOpMethod.Delete,
|
|
1314
1386
|
path: `/api/v1/trips/${tripRef}/itinerary/items/${itemId}`,
|
|
@@ -1323,15 +1395,16 @@ function useItinerary(tripRef) {
|
|
|
1323
1395
|
async (input) => {
|
|
1324
1396
|
const op = await removeItemMutate(input);
|
|
1325
1397
|
void refresh();
|
|
1398
|
+
refreshAfterDrain();
|
|
1326
1399
|
return op;
|
|
1327
1400
|
},
|
|
1328
|
-
[removeItemMutate, refresh]
|
|
1401
|
+
[removeItemMutate, refresh, refreshAfterDrain]
|
|
1329
1402
|
);
|
|
1330
1403
|
const reorderItemMutation = useOfflineMutation({
|
|
1331
1404
|
tripRef,
|
|
1332
|
-
enqueue: (
|
|
1405
|
+
enqueue: (engine2, input) => {
|
|
1333
1406
|
const { itemId, ...body } = input;
|
|
1334
|
-
return
|
|
1407
|
+
return engine2.enqueue({
|
|
1335
1408
|
tripRef,
|
|
1336
1409
|
method: SyncOpMethod.Post,
|
|
1337
1410
|
path: `/api/v1/trips/${tripRef}/itinerary/items/${itemId}/reorder`,
|
|
@@ -1346,9 +1419,10 @@ function useItinerary(tripRef) {
|
|
|
1346
1419
|
async (input) => {
|
|
1347
1420
|
const op = await reorderItemMutate(input);
|
|
1348
1421
|
void refresh();
|
|
1422
|
+
refreshAfterDrain();
|
|
1349
1423
|
return op;
|
|
1350
1424
|
},
|
|
1351
|
-
[reorderItemMutate, refresh]
|
|
1425
|
+
[reorderItemMutate, refresh, refreshAfterDrain]
|
|
1352
1426
|
);
|
|
1353
1427
|
if (!loaded && !lastFetchFailed) {
|
|
1354
1428
|
return { status: "loading" };
|
|
@@ -1576,6 +1650,34 @@ function useParties(tripRef) {
|
|
|
1576
1650
|
remove
|
|
1577
1651
|
};
|
|
1578
1652
|
}
|
|
1653
|
+
function optimisticPickupStop(input, syncedAt) {
|
|
1654
|
+
return {
|
|
1655
|
+
// Replaced by the id the engine mints.
|
|
1656
|
+
id: "pending",
|
|
1657
|
+
version: 0,
|
|
1658
|
+
// The request's own default, restated rather than guessed: the SDK's
|
|
1659
|
+
// `kind` is optional and the engine treats an absent one as a pickup.
|
|
1660
|
+
kind: input.kind ?? "PICKUP",
|
|
1661
|
+
name: input.name,
|
|
1662
|
+
locationLabel: input.locationLabel ?? null,
|
|
1663
|
+
lat: input.lat ?? null,
|
|
1664
|
+
lng: input.lng ?? null,
|
|
1665
|
+
scheduledTime: normalizeDateTimeInput(input.scheduledTime, "scheduledTime"),
|
|
1666
|
+
// Appended; the server's ordering arrives with the canonical row.
|
|
1667
|
+
sortOrder: input.sortOrder ?? Number.MAX_SAFE_INTEGER,
|
|
1668
|
+
status: "OPEN",
|
|
1669
|
+
closedAt: null,
|
|
1670
|
+
closedByManagerId: null,
|
|
1671
|
+
performedByKind: null,
|
|
1672
|
+
performedById: null,
|
|
1673
|
+
rollup: "not_started",
|
|
1674
|
+
boardedCount: 0,
|
|
1675
|
+
expectedCount: 0,
|
|
1676
|
+
// The last reading the SERVER gave this list, never a device clock
|
|
1677
|
+
// (hard rule #6).
|
|
1678
|
+
updatedAt: syncedAt ?? ""
|
|
1679
|
+
};
|
|
1680
|
+
}
|
|
1579
1681
|
var usePickupsInternal = createDomainHook("pickup-points", (tripRef) => {
|
|
1580
1682
|
const client = useKaafilClient();
|
|
1581
1683
|
const {
|
|
@@ -1599,7 +1701,14 @@ var usePickupsInternal = createDomainHook("pickup-points", (tripRef) => {
|
|
|
1599
1701
|
// literal below is checked against `kaafil-js/src/generated/
|
|
1600
1702
|
// security.ts`'s own operation-id table.
|
|
1601
1703
|
operationId: "createPickupStop",
|
|
1602
|
-
body: input
|
|
1704
|
+
body: input,
|
|
1705
|
+
// A stop added out of signal appears at once, keyed on an id the
|
|
1706
|
+
// ENGINE mints and swapped for the server's row when the write lands
|
|
1707
|
+
// — see `optimisticPickupStop` for why every field here is one the
|
|
1708
|
+
// client can honestly know.
|
|
1709
|
+
creates: true,
|
|
1710
|
+
entity: { listName: "pickups" },
|
|
1711
|
+
optimistic: optimisticPickupStop(input, syncedAt)
|
|
1603
1712
|
}),
|
|
1604
1713
|
// The desk lane. `board`, `close` and `reopen` below deliberately get
|
|
1605
1714
|
// NONE — they are `managerAuth`-only on the wire, so a direct call from
|
|
@@ -1745,6 +1854,24 @@ var usePickupsInternal = createDomainHook("pickup-points", (tripRef) => {
|
|
|
1745
1854
|
function usePickups(tripRef) {
|
|
1746
1855
|
return usePickupsInternal(tripRef);
|
|
1747
1856
|
}
|
|
1857
|
+
function optimisticStayWindow(input, syncedAt) {
|
|
1858
|
+
return {
|
|
1859
|
+
// Replaced by the id the engine mints.
|
|
1860
|
+
id: "pending",
|
|
1861
|
+
version: 0,
|
|
1862
|
+
label: input.label,
|
|
1863
|
+
startDate: normalizeDateTimeInput(input.startDate, "startDate"),
|
|
1864
|
+
endDate: normalizeDateTimeInput(input.endDate, "endDate"),
|
|
1865
|
+
// Appended; the server's ordering arrives with the canonical row.
|
|
1866
|
+
sortOrder: input.sortOrder ?? Number.MAX_SAFE_INTEGER,
|
|
1867
|
+
// A window created by hand has no CRM segment behind it. This is a fact
|
|
1868
|
+
// about the write, not a placeholder.
|
|
1869
|
+
sourceSegmentRef: null,
|
|
1870
|
+
sourceUpdatedAt: null,
|
|
1871
|
+
// The last reading the SERVER gave this list, never a device clock.
|
|
1872
|
+
updatedAt: syncedAt ?? ""
|
|
1873
|
+
};
|
|
1874
|
+
}
|
|
1748
1875
|
var useRoomingInternal = createDomainHook("rooming", (tripRef) => {
|
|
1749
1876
|
const client = useKaafilClient();
|
|
1750
1877
|
const {
|
|
@@ -1772,7 +1899,7 @@ var useRoomingInternal = createDomainHook("rooming", (tripRef) => {
|
|
|
1772
1899
|
}, [refreshRoomsLive, refreshWindowsLive]);
|
|
1773
1900
|
const assignMutation = useOfflineMutation({
|
|
1774
1901
|
tripRef,
|
|
1775
|
-
enqueue: (
|
|
1902
|
+
enqueue: (engine2, input) => engine2.enqueue({
|
|
1776
1903
|
tripRef,
|
|
1777
1904
|
method: SyncOpMethod.Post,
|
|
1778
1905
|
path: `/api/v1/trips/${tripRef}/rooming/assign`,
|
|
@@ -1816,6 +1943,16 @@ var useRoomingInternal = createDomainHook("rooming", (tripRef) => {
|
|
|
1816
1943
|
useEffect(() => {
|
|
1817
1944
|
void refreshUnassignedPool();
|
|
1818
1945
|
}, [refreshUnassignedPool]);
|
|
1946
|
+
const engine = useContext(OfflineEngineContext);
|
|
1947
|
+
useEffect(() => {
|
|
1948
|
+
if (engine === null) {
|
|
1949
|
+
return;
|
|
1950
|
+
}
|
|
1951
|
+
const unsubscribe = engine.events.on("sync.drained", () => {
|
|
1952
|
+
void refreshUnassignedPool(lastRequestedStayWindowIdRef.current);
|
|
1953
|
+
});
|
|
1954
|
+
return unsubscribe;
|
|
1955
|
+
}, [engine, refreshUnassignedPool]);
|
|
1819
1956
|
const assignMutate = assignMutation.mutate;
|
|
1820
1957
|
const assign = useCallback(
|
|
1821
1958
|
async (input) => {
|
|
@@ -1827,20 +1964,27 @@ var useRoomingInternal = createDomainHook("rooming", (tripRef) => {
|
|
|
1827
1964
|
);
|
|
1828
1965
|
const createWindowMutation = useOfflineMutation({
|
|
1829
1966
|
tripRef,
|
|
1830
|
-
enqueue: (
|
|
1967
|
+
enqueue: (engine2, input) => engine2.enqueue({
|
|
1831
1968
|
tripRef,
|
|
1832
1969
|
method: SyncOpMethod.Post,
|
|
1833
1970
|
path: `/api/v1/trips/${tripRef}/rooming/stay-windows`,
|
|
1834
1971
|
operationId: "createRoomingStayWindow",
|
|
1835
|
-
body: input
|
|
1972
|
+
body: input,
|
|
1973
|
+
// A window added out of signal appears at once. Every field of a
|
|
1974
|
+
// stay window is either given by the caller or genuinely absent —
|
|
1975
|
+
// which is exactly what `createRoom` below cannot say, and why only
|
|
1976
|
+
// this one of the two gets an optimistic row.
|
|
1977
|
+
creates: true,
|
|
1978
|
+
entity: { listName: "stayWindows" },
|
|
1979
|
+
optimistic: optimisticStayWindow(input, windowsSyncedAt)
|
|
1836
1980
|
}),
|
|
1837
1981
|
direct: (liveClient, input) => liveClient.rooming.stayWindows.create({ tripRef, ...input })
|
|
1838
1982
|
});
|
|
1839
1983
|
const patchWindowMutation = useOfflineMutation({
|
|
1840
1984
|
tripRef,
|
|
1841
|
-
enqueue: (
|
|
1985
|
+
enqueue: (engine2, input) => {
|
|
1842
1986
|
const { windowId, version, ...body } = input;
|
|
1843
|
-
return
|
|
1987
|
+
return engine2.enqueue({
|
|
1844
1988
|
tripRef,
|
|
1845
1989
|
method: SyncOpMethod.Patch,
|
|
1846
1990
|
path: `/api/v1/trips/${tripRef}/rooming/stay-windows/${windowId}`,
|
|
@@ -1853,10 +1997,10 @@ var useRoomingInternal = createDomainHook("rooming", (tripRef) => {
|
|
|
1853
1997
|
});
|
|
1854
1998
|
const removeWindowMutation = useOfflineMutation({
|
|
1855
1999
|
tripRef,
|
|
1856
|
-
enqueue: (
|
|
2000
|
+
enqueue: (engine2, input) => {
|
|
1857
2001
|
const { windowId, version, force } = input;
|
|
1858
2002
|
const query = force === true ? "?force=true" : "";
|
|
1859
|
-
return
|
|
2003
|
+
return engine2.enqueue({
|
|
1860
2004
|
tripRef,
|
|
1861
2005
|
method: SyncOpMethod.Delete,
|
|
1862
2006
|
path: `/api/v1/trips/${tripRef}/rooming/stay-windows/${windowId}${query}`,
|
|
@@ -1868,7 +2012,7 @@ var useRoomingInternal = createDomainHook("rooming", (tripRef) => {
|
|
|
1868
2012
|
});
|
|
1869
2013
|
const createRoomMutation = useOfflineMutation({
|
|
1870
2014
|
tripRef,
|
|
1871
|
-
enqueue: (
|
|
2015
|
+
enqueue: (engine2, input) => engine2.enqueue({
|
|
1872
2016
|
tripRef,
|
|
1873
2017
|
method: SyncOpMethod.Post,
|
|
1874
2018
|
path: `/api/v1/trips/${tripRef}/rooming/rooms`,
|
|
@@ -1879,9 +2023,9 @@ var useRoomingInternal = createDomainHook("rooming", (tripRef) => {
|
|
|
1879
2023
|
});
|
|
1880
2024
|
const patchRoomMutation = useOfflineMutation({
|
|
1881
2025
|
tripRef,
|
|
1882
|
-
enqueue: (
|
|
2026
|
+
enqueue: (engine2, input) => {
|
|
1883
2027
|
const { roomId, version, ...body } = input;
|
|
1884
|
-
return
|
|
2028
|
+
return engine2.enqueue({
|
|
1885
2029
|
tripRef,
|
|
1886
2030
|
method: SyncOpMethod.Patch,
|
|
1887
2031
|
path: `/api/v1/trips/${tripRef}/rooming/rooms/${roomId}`,
|
|
@@ -1894,10 +2038,10 @@ var useRoomingInternal = createDomainHook("rooming", (tripRef) => {
|
|
|
1894
2038
|
});
|
|
1895
2039
|
const removeRoomMutation = useOfflineMutation({
|
|
1896
2040
|
tripRef,
|
|
1897
|
-
enqueue: (
|
|
2041
|
+
enqueue: (engine2, input) => {
|
|
1898
2042
|
const { roomId, version, force } = input;
|
|
1899
2043
|
const query = force === true ? "?force=true" : "";
|
|
1900
|
-
return
|
|
2044
|
+
return engine2.enqueue({
|
|
1901
2045
|
tripRef,
|
|
1902
2046
|
method: SyncOpMethod.Delete,
|
|
1903
2047
|
path: `/api/v1/trips/${tripRef}/rooming/rooms/${roomId}${query}`,
|
|
@@ -1951,7 +2095,7 @@ var useSeatingInternal = createDomainHook("transport-seating", (tripRef) => {
|
|
|
1951
2095
|
});
|
|
1952
2096
|
const assignMutation = useOfflineMutation({
|
|
1953
2097
|
tripRef,
|
|
1954
|
-
enqueue: (
|
|
2098
|
+
enqueue: (engine2, input) => engine2.enqueue({
|
|
1955
2099
|
tripRef,
|
|
1956
2100
|
method: SyncOpMethod.Post,
|
|
1957
2101
|
path: `/api/v1/trips/${tripRef}/seating/assign`,
|
|
@@ -1988,6 +2132,16 @@ var useSeatingInternal = createDomainHook("transport-seating", (tripRef) => {
|
|
|
1988
2132
|
useEffect(() => {
|
|
1989
2133
|
void refreshUnassignedPool();
|
|
1990
2134
|
}, [refreshUnassignedPool]);
|
|
2135
|
+
const engine = useContext(OfflineEngineContext);
|
|
2136
|
+
useEffect(() => {
|
|
2137
|
+
if (engine === null) {
|
|
2138
|
+
return;
|
|
2139
|
+
}
|
|
2140
|
+
const unsubscribe = engine.events.on("sync.drained", () => {
|
|
2141
|
+
void refreshUnassignedPool();
|
|
2142
|
+
});
|
|
2143
|
+
return unsubscribe;
|
|
2144
|
+
}, [engine, refreshUnassignedPool]);
|
|
1991
2145
|
const assignMutate = assignMutation.mutate;
|
|
1992
2146
|
const assign = useCallback(
|
|
1993
2147
|
async (input) => {
|
|
@@ -1999,7 +2153,7 @@ var useSeatingInternal = createDomainHook("transport-seating", (tripRef) => {
|
|
|
1999
2153
|
);
|
|
2000
2154
|
const createVehicleMutation = useOfflineMutation({
|
|
2001
2155
|
tripRef,
|
|
2002
|
-
enqueue: (
|
|
2156
|
+
enqueue: (engine2, input) => engine2.enqueue({
|
|
2003
2157
|
tripRef,
|
|
2004
2158
|
method: SyncOpMethod.Post,
|
|
2005
2159
|
path: `/api/v1/trips/${tripRef}/seating/vehicles`,
|
|
@@ -2010,9 +2164,9 @@ var useSeatingInternal = createDomainHook("transport-seating", (tripRef) => {
|
|
|
2010
2164
|
});
|
|
2011
2165
|
const patchVehicleMutation = useOfflineMutation({
|
|
2012
2166
|
tripRef,
|
|
2013
|
-
enqueue: (
|
|
2167
|
+
enqueue: (engine2, input) => {
|
|
2014
2168
|
const { vehicleId, version, ...body } = input;
|
|
2015
|
-
return
|
|
2169
|
+
return engine2.enqueue({
|
|
2016
2170
|
tripRef,
|
|
2017
2171
|
method: SyncOpMethod.Patch,
|
|
2018
2172
|
path: `/api/v1/trips/${tripRef}/seating/vehicles/${vehicleId}`,
|
|
@@ -2025,9 +2179,9 @@ var useSeatingInternal = createDomainHook("transport-seating", (tripRef) => {
|
|
|
2025
2179
|
});
|
|
2026
2180
|
const removeVehicleMutation = useOfflineMutation({
|
|
2027
2181
|
tripRef,
|
|
2028
|
-
enqueue: (
|
|
2182
|
+
enqueue: (engine2, input) => {
|
|
2029
2183
|
const { vehicleId, version } = input;
|
|
2030
|
-
return
|
|
2184
|
+
return engine2.enqueue({
|
|
2031
2185
|
tripRef,
|
|
2032
2186
|
method: SyncOpMethod.Delete,
|
|
2033
2187
|
path: `/api/v1/trips/${tripRef}/seating/vehicles/${vehicleId}`,
|
|
@@ -2067,9 +2221,9 @@ var useSeatingInternal = createDomainHook("transport-seating", (tripRef) => {
|
|
|
2067
2221
|
);
|
|
2068
2222
|
const linkManagerMutation = useOfflineMutation({
|
|
2069
2223
|
tripRef,
|
|
2070
|
-
enqueue: (
|
|
2224
|
+
enqueue: (engine2, input) => {
|
|
2071
2225
|
const { vehicleId, ...body } = input;
|
|
2072
|
-
return
|
|
2226
|
+
return engine2.enqueue({
|
|
2073
2227
|
tripRef,
|
|
2074
2228
|
method: SyncOpMethod.Post,
|
|
2075
2229
|
path: `/api/v1/trips/${tripRef}/seating/vehicles/${vehicleId}/manager`,
|
|
@@ -2081,9 +2235,9 @@ var useSeatingInternal = createDomainHook("transport-seating", (tripRef) => {
|
|
|
2081
2235
|
});
|
|
2082
2236
|
const unlinkManagerMutation = useOfflineMutation({
|
|
2083
2237
|
tripRef,
|
|
2084
|
-
enqueue: (
|
|
2238
|
+
enqueue: (engine2, input) => {
|
|
2085
2239
|
const { vehicleId, version } = input;
|
|
2086
|
-
return
|
|
2240
|
+
return engine2.enqueue({
|
|
2087
2241
|
tripRef,
|
|
2088
2242
|
method: SyncOpMethod.Delete,
|
|
2089
2243
|
path: `/api/v1/trips/${tripRef}/seating/vehicles/${vehicleId}/manager`,
|
|
@@ -2221,5 +2375,5 @@ function useVendors(tripRef, agencyRef) {
|
|
|
2221
2375
|
}
|
|
2222
2376
|
|
|
2223
2377
|
export { ERROR_HANDLING_PATH, FORM_FIELD_KIND_SINGLE_BOOLEAN, classifyError, createDomainHook, useChecklists, useCloseout, useCollections, useExpenses, useFiles, useFloat, useForms, useItinerary, useManagerToday, useManagers, useParties, usePickups, useRooming, useSeating, useSnapshotList, useTravellerProfile, useVendors };
|
|
2224
|
-
//# sourceMappingURL=chunk-
|
|
2225
|
-
//# sourceMappingURL=chunk-
|
|
2378
|
+
//# sourceMappingURL=chunk-WPQB7JWS.js.map
|
|
2379
|
+
//# sourceMappingURL=chunk-WPQB7JWS.js.map
|