@ukiahinsure/a2ui-react-adapter 0.1.6 → 0.1.7
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/index.js +586 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -215,12 +215,16 @@ var A2UIClientAdapter = class {
|
|
|
215
215
|
envelope.surfaceId,
|
|
216
216
|
this.#persistedListRowsByPath
|
|
217
217
|
);
|
|
218
|
-
const
|
|
218
|
+
const actionCompleteMessages = ensureOptionalCoverageSkipActionMessages(
|
|
219
219
|
rawMessages,
|
|
220
|
+
envelope.surfaceId
|
|
221
|
+
);
|
|
222
|
+
const nextStructure = updateSurfaceStructures(
|
|
223
|
+
actionCompleteMessages,
|
|
220
224
|
envelope.kind === "snapshot" ? /* @__PURE__ */ new Map() : cloneSurfaceStructures(this.#structureBySurface)
|
|
221
225
|
);
|
|
222
226
|
const messages = normalizeChoiceValuesInMessages(
|
|
223
|
-
|
|
227
|
+
actionCompleteMessages,
|
|
224
228
|
envelope.surfaceId,
|
|
225
229
|
nextStructure.get(envelope.surfaceId)
|
|
226
230
|
);
|
|
@@ -290,11 +294,39 @@ var A2UIClientAdapter = class {
|
|
|
290
294
|
sourceComponentId: action.sourceComponentId,
|
|
291
295
|
context: { ...action.context }
|
|
292
296
|
};
|
|
297
|
+
const submittedProviderRow = submittedProviderRowFromEvent(event);
|
|
298
|
+
if (submittedProviderRow !== void 0) {
|
|
299
|
+
this.#rememberSubmittedProviderRow(
|
|
300
|
+
event.surfaceId,
|
|
301
|
+
submittedProviderRow,
|
|
302
|
+
event.context
|
|
303
|
+
);
|
|
304
|
+
}
|
|
293
305
|
this.#options.onAction?.(event);
|
|
294
306
|
for (const listener of this.#actionListeners) {
|
|
295
307
|
listener(event);
|
|
296
308
|
}
|
|
297
309
|
}
|
|
310
|
+
#rememberSubmittedProviderRow(surfaceId, row, context) {
|
|
311
|
+
const rows = upsertListRow(
|
|
312
|
+
this.#persistedListRowsByPath.get("needs.providers") ?? [],
|
|
313
|
+
row
|
|
314
|
+
);
|
|
315
|
+
this.#persistedListRowsByPath.set("needs.providers", rows);
|
|
316
|
+
const surface = this.#processor.model.getSurface(surfaceId);
|
|
317
|
+
if (surface === void 0) {
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
surface.dataModel.set("/needs.providers", cloneJsonArray(rows));
|
|
321
|
+
surface.dataModel.set("/needs/providers", cloneJsonArray(rows));
|
|
322
|
+
clearSubmittedProviderDraft(surface.dataModel, context);
|
|
323
|
+
removeSubmittedProviderDraftControls(
|
|
324
|
+
surface.componentsModel.entries,
|
|
325
|
+
eventSourceFieldPaths(context),
|
|
326
|
+
context
|
|
327
|
+
);
|
|
328
|
+
this.#notify();
|
|
329
|
+
}
|
|
298
330
|
#snapshotMessages() {
|
|
299
331
|
const messages = [];
|
|
300
332
|
for (const surface of this.#processor.model.surfacesMap.values()) {
|
|
@@ -364,6 +396,201 @@ function cloneSurfaceStructures(source) {
|
|
|
364
396
|
])
|
|
365
397
|
);
|
|
366
398
|
}
|
|
399
|
+
function ensureOptionalCoverageSkipActionMessages(messages, surfaceId) {
|
|
400
|
+
for (let index = 0; index < messages.length; index += 1) {
|
|
401
|
+
const message = messages[index];
|
|
402
|
+
if (!isRecord(message) || !isRecord(message.updateComponents)) {
|
|
403
|
+
continue;
|
|
404
|
+
}
|
|
405
|
+
const update = message.updateComponents;
|
|
406
|
+
if (update.surfaceId !== surfaceId || !Array.isArray(update.components)) {
|
|
407
|
+
continue;
|
|
408
|
+
}
|
|
409
|
+
const submit = update.components.find(
|
|
410
|
+
(component) => isRecord(component) && isNonEmptyString(component.id) && hasActionName(component, "flow.submit")
|
|
411
|
+
);
|
|
412
|
+
if (!isRecord(submit) || !isNonEmptyString(submit.id)) {
|
|
413
|
+
return messages;
|
|
414
|
+
}
|
|
415
|
+
const optionalCoverageField = optionalCoverageFieldName(
|
|
416
|
+
update.components,
|
|
417
|
+
submit.id
|
|
418
|
+
);
|
|
419
|
+
if (optionalCoverageField === void 0) {
|
|
420
|
+
continue;
|
|
421
|
+
}
|
|
422
|
+
const patchedSubmit = submitActionWithDefaultUnknown(
|
|
423
|
+
submit,
|
|
424
|
+
optionalCoverageField
|
|
425
|
+
);
|
|
426
|
+
const hasSkip = update.components.some(
|
|
427
|
+
(component) => hasActionName(component, "flow.skip")
|
|
428
|
+
);
|
|
429
|
+
if (hasSkip && patchedSubmit === submit) {
|
|
430
|
+
return messages;
|
|
431
|
+
}
|
|
432
|
+
if (hasSkip) {
|
|
433
|
+
const nextMessages2 = [...messages];
|
|
434
|
+
nextMessages2[index] = {
|
|
435
|
+
...message,
|
|
436
|
+
updateComponents: {
|
|
437
|
+
...update,
|
|
438
|
+
components: update.components.map(
|
|
439
|
+
(component) => component === submit ? patchedSubmit : component
|
|
440
|
+
)
|
|
441
|
+
}
|
|
442
|
+
};
|
|
443
|
+
return nextMessages2;
|
|
444
|
+
}
|
|
445
|
+
const parent = update.components.find(
|
|
446
|
+
(component) => isRecord(component) && Array.isArray(component.children) && component.children.includes(submit.id)
|
|
447
|
+
);
|
|
448
|
+
if (!isRecord(parent) || !Array.isArray(parent.children)) {
|
|
449
|
+
return messages;
|
|
450
|
+
}
|
|
451
|
+
const labelId = `${submit.id}:optional-skip-label`;
|
|
452
|
+
const buttonId = `${submit.id}:optional-skip`;
|
|
453
|
+
if (update.components.some(
|
|
454
|
+
(component) => isRecord(component) && (component.id === labelId || component.id === buttonId)
|
|
455
|
+
)) {
|
|
456
|
+
return messages;
|
|
457
|
+
}
|
|
458
|
+
const nextParent = {
|
|
459
|
+
...parent,
|
|
460
|
+
children: parent.children.flatMap(
|
|
461
|
+
(child) => child === submit.id ? [buttonId, child] : [child]
|
|
462
|
+
)
|
|
463
|
+
};
|
|
464
|
+
const nextComponents = update.components.map(
|
|
465
|
+
(component) => component === parent ? nextParent : component === submit ? patchedSubmit : component
|
|
466
|
+
);
|
|
467
|
+
nextComponents.push(
|
|
468
|
+
{
|
|
469
|
+
id: labelId,
|
|
470
|
+
component: "Text",
|
|
471
|
+
text: "Skip"
|
|
472
|
+
},
|
|
473
|
+
{
|
|
474
|
+
id: buttonId,
|
|
475
|
+
component: "Button",
|
|
476
|
+
child: labelId,
|
|
477
|
+
action: {
|
|
478
|
+
event: {
|
|
479
|
+
name: "flow.submit",
|
|
480
|
+
context: { [optionalCoverageField]: "unknown" }
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
);
|
|
485
|
+
const nextMessages = [...messages];
|
|
486
|
+
nextMessages[index] = {
|
|
487
|
+
...message,
|
|
488
|
+
updateComponents: {
|
|
489
|
+
...update,
|
|
490
|
+
components: nextComponents
|
|
491
|
+
}
|
|
492
|
+
};
|
|
493
|
+
return nextMessages;
|
|
494
|
+
}
|
|
495
|
+
return messages;
|
|
496
|
+
}
|
|
497
|
+
function submitActionWithDefaultUnknown(submit, field) {
|
|
498
|
+
if (!isRecord(submit.action) || !isRecord(submit.action.event)) {
|
|
499
|
+
return submit;
|
|
500
|
+
}
|
|
501
|
+
const event = submit.action.event;
|
|
502
|
+
const context = isRecord(event.context) ? event.context : {};
|
|
503
|
+
if (Object.hasOwn(context, field)) {
|
|
504
|
+
return submit;
|
|
505
|
+
}
|
|
506
|
+
return {
|
|
507
|
+
...submit,
|
|
508
|
+
action: {
|
|
509
|
+
...submit.action,
|
|
510
|
+
event: {
|
|
511
|
+
...event,
|
|
512
|
+
context: {
|
|
513
|
+
...context,
|
|
514
|
+
[field]: "unknown"
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
function optionalCoverageFieldName(components, submitId) {
|
|
521
|
+
const statePrefix = componentStatePrefix(submitId);
|
|
522
|
+
if (statePrefix !== void 0) {
|
|
523
|
+
const stateField = optionalCoverageFieldFromFieldBindings(
|
|
524
|
+
components.filter(
|
|
525
|
+
(component) => isRecord(component) && isNonEmptyString(component.id) && component.id.startsWith(`${statePrefix}:`)
|
|
526
|
+
)
|
|
527
|
+
);
|
|
528
|
+
if (stateField !== void 0) {
|
|
529
|
+
return stateField;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
const parent = components.find(
|
|
533
|
+
(component) => isRecord(component) && Array.isArray(component.children) && component.children.includes(submitId)
|
|
534
|
+
);
|
|
535
|
+
if (isRecord(parent) && Array.isArray(parent.children)) {
|
|
536
|
+
const childIds = new Set(parent.children.filter(isNonEmptyString));
|
|
537
|
+
const childField = optionalCoverageFieldFromFieldBindings(
|
|
538
|
+
components.filter(
|
|
539
|
+
(component) => isRecord(component) && isNonEmptyString(component.id) && childIds.has(component.id)
|
|
540
|
+
)
|
|
541
|
+
);
|
|
542
|
+
if (childField !== void 0) {
|
|
543
|
+
return childField;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
return void 0;
|
|
547
|
+
}
|
|
548
|
+
function componentStatePrefix(componentId) {
|
|
549
|
+
const marker = ":action:";
|
|
550
|
+
const markerIndex = componentId.indexOf(marker);
|
|
551
|
+
if (markerIndex > 0) {
|
|
552
|
+
return componentId.slice(0, markerIndex);
|
|
553
|
+
}
|
|
554
|
+
const fallbackIndex = componentId.lastIndexOf(":");
|
|
555
|
+
return fallbackIndex > 0 ? componentId.slice(0, fallbackIndex) : void 0;
|
|
556
|
+
}
|
|
557
|
+
function optionalCoverageFieldFromFieldBindings(components) {
|
|
558
|
+
const normalized = components.flatMap((component) => componentFieldSearchText(component)).map(normalizeSearchText).join(" ");
|
|
559
|
+
if (normalized.includes("vatricarebenefits") || normalized.includes("coveragevatricarebenefits") || normalized.includes("tricareorchampvabenefits") || normalized.includes("vachampvabenefits")) {
|
|
560
|
+
return "va_tricare_benefits";
|
|
561
|
+
}
|
|
562
|
+
if (normalized.includes("employerunioncoverage") || normalized.includes("coverageemployerunioncoverage")) {
|
|
563
|
+
return "employer_union_coverage";
|
|
564
|
+
}
|
|
565
|
+
return void 0;
|
|
566
|
+
}
|
|
567
|
+
function componentFieldSearchText(component) {
|
|
568
|
+
if (!isRecord(component)) {
|
|
569
|
+
return [];
|
|
570
|
+
}
|
|
571
|
+
const values = [];
|
|
572
|
+
for (const key of ["label", "field"]) {
|
|
573
|
+
const value2 = component[key];
|
|
574
|
+
if (typeof value2 === "string") {
|
|
575
|
+
values.push(value2);
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
const value = component.value;
|
|
579
|
+
if (isRecord(value) && typeof value.path === "string") {
|
|
580
|
+
values.push(value.path);
|
|
581
|
+
}
|
|
582
|
+
return values;
|
|
583
|
+
}
|
|
584
|
+
function normalizeSearchText(value) {
|
|
585
|
+
return value.toLowerCase().replace(/[^a-z0-9]+/g, "");
|
|
586
|
+
}
|
|
587
|
+
function hasActionName(component, actionName) {
|
|
588
|
+
if (!isRecord(component) || !isRecord(component.action)) {
|
|
589
|
+
return false;
|
|
590
|
+
}
|
|
591
|
+
const event = component.action.event;
|
|
592
|
+
return isRecord(event) && event.name === actionName;
|
|
593
|
+
}
|
|
367
594
|
function updateSurfaceStructures(messages, structures) {
|
|
368
595
|
for (const message of messages) {
|
|
369
596
|
if (!isRecord(message)) {
|
|
@@ -581,12 +808,11 @@ function mergePersistedListRowsIntoMessages(messages, surfaceId, persistedRowsBy
|
|
|
581
808
|
}
|
|
582
809
|
function mergePersistedListRowsIntoRoot(root, persistedRowsByPath) {
|
|
583
810
|
const merged = cloneJsonRecord(root);
|
|
584
|
-
const activeDraftListPaths = activeListDraftPaths(merged);
|
|
585
811
|
for (const [listPath, rows] of persistedRowsByPath) {
|
|
586
812
|
const dottedRows = merged[listPath];
|
|
587
813
|
const nestedRows = getNestedValue(merged, listPath);
|
|
588
814
|
const incomingRows = Array.isArray(dottedRows) ? dottedRows : Array.isArray(nestedRows) ? nestedRows : void 0;
|
|
589
|
-
const shouldPreserveCachedRows = rows.length > 0 && (incomingRows === void 0 || incomingRows.length === 0
|
|
815
|
+
const shouldPreserveCachedRows = rows.length > 0 && (incomingRows === void 0 || incomingRows.length === 0 && (!hasListDraft(merged, listPath) || hasBlankListDraft(merged, listPath)));
|
|
590
816
|
const effectiveRows = shouldPreserveCachedRows ? rows : incomingRows ?? rows;
|
|
591
817
|
if (!Array.isArray(dottedRows) || shouldPreserveCachedRows) {
|
|
592
818
|
merged[listPath] = cloneJsonArray(effectiveRows);
|
|
@@ -597,14 +823,32 @@ function mergePersistedListRowsIntoRoot(root, persistedRowsByPath) {
|
|
|
597
823
|
}
|
|
598
824
|
return merged;
|
|
599
825
|
}
|
|
600
|
-
function
|
|
826
|
+
function hasBlankListDraft(root, listPath) {
|
|
601
827
|
const drafts = root.__listDrafts;
|
|
602
828
|
if (!isRecord(drafts)) {
|
|
603
|
-
return
|
|
829
|
+
return false;
|
|
604
830
|
}
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
831
|
+
const draft = drafts[listPath];
|
|
832
|
+
if (!isRecord(draft)) {
|
|
833
|
+
return false;
|
|
834
|
+
}
|
|
835
|
+
return Object.values(draft).every(isBlankDraftValue);
|
|
836
|
+
}
|
|
837
|
+
function hasListDraft(root, listPath) {
|
|
838
|
+
const drafts = root.__listDrafts;
|
|
839
|
+
return isRecord(drafts) && isRecord(drafts[listPath]);
|
|
840
|
+
}
|
|
841
|
+
function isBlankDraftValue(value) {
|
|
842
|
+
if (value === null || value === void 0) {
|
|
843
|
+
return true;
|
|
844
|
+
}
|
|
845
|
+
if (typeof value === "string") {
|
|
846
|
+
return value.trim().length === 0;
|
|
847
|
+
}
|
|
848
|
+
if (Array.isArray(value)) {
|
|
849
|
+
return value.length === 0 || value.every(isBlankDraftValue);
|
|
850
|
+
}
|
|
851
|
+
return false;
|
|
608
852
|
}
|
|
609
853
|
function rememberPersistedListRows(persistedRowsByPath, root) {
|
|
610
854
|
if (!isRecord(root)) {
|
|
@@ -614,6 +858,249 @@ function rememberPersistedListRows(persistedRowsByPath, root) {
|
|
|
614
858
|
persistedRowsByPath.set(listPath, cloneJsonArray(rows));
|
|
615
859
|
}
|
|
616
860
|
}
|
|
861
|
+
function submittedProviderRowFromEvent(event) {
|
|
862
|
+
if (event.actionName !== "flow.submit") {
|
|
863
|
+
return void 0;
|
|
864
|
+
}
|
|
865
|
+
const listPath = event.context.listPath;
|
|
866
|
+
if (listPath !== "needs.providers" && !hasProviderSubmitFields(event.context)) {
|
|
867
|
+
return void 0;
|
|
868
|
+
}
|
|
869
|
+
const name = firstTextField(event.context, [
|
|
870
|
+
"primary_care_provider",
|
|
871
|
+
"primaryCareProvider",
|
|
872
|
+
"primary_provider",
|
|
873
|
+
"primaryProvider",
|
|
874
|
+
"primary_care_doctor",
|
|
875
|
+
"primaryCareDoctor",
|
|
876
|
+
"pcp",
|
|
877
|
+
"providerName",
|
|
878
|
+
"provider_name",
|
|
879
|
+
"displayName",
|
|
880
|
+
"display_name",
|
|
881
|
+
"doctorName",
|
|
882
|
+
"doctorname",
|
|
883
|
+
"doctor_name",
|
|
884
|
+
"name"
|
|
885
|
+
]);
|
|
886
|
+
const location = firstTextField(event.context, [
|
|
887
|
+
"primary_care_provider_location",
|
|
888
|
+
"primaryCareProviderLocation",
|
|
889
|
+
"provider_location",
|
|
890
|
+
"providerLocation",
|
|
891
|
+
"location_details",
|
|
892
|
+
"locationDetails",
|
|
893
|
+
"office_location",
|
|
894
|
+
"officeLocation",
|
|
895
|
+
"practice_location",
|
|
896
|
+
"practiceLocation",
|
|
897
|
+
"location",
|
|
898
|
+
"address"
|
|
899
|
+
]);
|
|
900
|
+
if (name === void 0 && location === void 0) {
|
|
901
|
+
return void 0;
|
|
902
|
+
}
|
|
903
|
+
return {
|
|
904
|
+
itemId: "submitted-primary-care-provider",
|
|
905
|
+
...name === void 0 ? {} : { primary_care_provider: name },
|
|
906
|
+
...location === void 0 ? {} : { primary_care_provider_location: location },
|
|
907
|
+
__displayText: [
|
|
908
|
+
name === void 0 ? void 0 : `Provider Name: ${name}`,
|
|
909
|
+
location === void 0 ? void 0 : `Provider Location: ${location}`
|
|
910
|
+
].filter((part) => part !== void 0).join(" | ")
|
|
911
|
+
};
|
|
912
|
+
}
|
|
913
|
+
function clearSubmittedProviderDraft(dataModel, context) {
|
|
914
|
+
for (const key of Object.keys(context)) {
|
|
915
|
+
if (key === "listPath") {
|
|
916
|
+
continue;
|
|
917
|
+
}
|
|
918
|
+
if (firstTextField(context, [key]) === void 0 || !isProviderSubmitField(key)) {
|
|
919
|
+
continue;
|
|
920
|
+
}
|
|
921
|
+
dataModel.set(`/__listDrafts/needs.providers/${key}`, "");
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
function removeSubmittedProviderDraftControls(entries, fieldPaths, context) {
|
|
925
|
+
const components = [...entries];
|
|
926
|
+
const controlIds = /* @__PURE__ */ new Set();
|
|
927
|
+
for (const [id, component] of components) {
|
|
928
|
+
if (component.type === "Button" && isProviderSubmitButton(component, context)) {
|
|
929
|
+
controlIds.add(id);
|
|
930
|
+
const child = component.properties.child;
|
|
931
|
+
if (typeof child === "string") {
|
|
932
|
+
controlIds.add(child);
|
|
933
|
+
}
|
|
934
|
+
continue;
|
|
935
|
+
}
|
|
936
|
+
if (component.type !== "TextField") {
|
|
937
|
+
continue;
|
|
938
|
+
}
|
|
939
|
+
const value = component.properties.value;
|
|
940
|
+
const label = component.properties.label;
|
|
941
|
+
if (isRecord(value) && typeof value.path === "string" && (fieldPaths.has(value.path) || isProviderDraftFieldPath(value.path)) || typeof label === "string" && isProviderSubmitLabel(label)) {
|
|
942
|
+
controlIds.add(id);
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
let changed = true;
|
|
946
|
+
while (changed) {
|
|
947
|
+
changed = false;
|
|
948
|
+
for (const [id, component] of components) {
|
|
949
|
+
if (controlIds.has(id) || component.type === "Column") {
|
|
950
|
+
continue;
|
|
951
|
+
}
|
|
952
|
+
const children = component.properties.children;
|
|
953
|
+
if (Array.isArray(children) && children.length > 0 && children.every(
|
|
954
|
+
(child) => typeof child === "string" && controlIds.has(child)
|
|
955
|
+
)) {
|
|
956
|
+
controlIds.add(id);
|
|
957
|
+
changed = true;
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
for (const [, component] of components) {
|
|
962
|
+
const children = component.properties.children;
|
|
963
|
+
if (!Array.isArray(children)) {
|
|
964
|
+
continue;
|
|
965
|
+
}
|
|
966
|
+
const nextChildren = children.filter(
|
|
967
|
+
(child) => typeof child !== "string" || !controlIds.has(child)
|
|
968
|
+
);
|
|
969
|
+
if (nextChildren.length === children.length) {
|
|
970
|
+
continue;
|
|
971
|
+
}
|
|
972
|
+
component.properties = {
|
|
973
|
+
...component.properties,
|
|
974
|
+
children: nextChildren
|
|
975
|
+
};
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
function isProviderSubmitButton(component, context) {
|
|
979
|
+
const action = component.properties.action;
|
|
980
|
+
if (!isRecord(action) || !isRecord(action.event)) {
|
|
981
|
+
return false;
|
|
982
|
+
}
|
|
983
|
+
const event = action.event;
|
|
984
|
+
return event.name === "flow.submit" && sameProviderSubmitContext(event.context, context);
|
|
985
|
+
}
|
|
986
|
+
function sameProviderSubmitContext(candidate, context) {
|
|
987
|
+
if (!isRecord(candidate) || candidate.listPath !== "needs.providers" && !hasProviderSubmitFields(candidate)) {
|
|
988
|
+
return false;
|
|
989
|
+
}
|
|
990
|
+
for (const key of Object.keys(context)) {
|
|
991
|
+
if (key === "listPath" || !isProviderSubmitField(key)) {
|
|
992
|
+
continue;
|
|
993
|
+
}
|
|
994
|
+
if (!(key in candidate)) {
|
|
995
|
+
return false;
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
return true;
|
|
999
|
+
}
|
|
1000
|
+
function hasProviderSubmitFields(context) {
|
|
1001
|
+
return Object.keys(context).some(
|
|
1002
|
+
(key) => key !== "listPath" && isProviderSubmitField(key)
|
|
1003
|
+
);
|
|
1004
|
+
}
|
|
1005
|
+
function isProviderSubmitField(key) {
|
|
1006
|
+
return (/* @__PURE__ */ new Set([
|
|
1007
|
+
"primary_care_provider",
|
|
1008
|
+
"primaryCareProvider",
|
|
1009
|
+
"primary_provider",
|
|
1010
|
+
"primaryProvider",
|
|
1011
|
+
"primary_care_doctor",
|
|
1012
|
+
"primaryCareDoctor",
|
|
1013
|
+
"pcp",
|
|
1014
|
+
"providerName",
|
|
1015
|
+
"provider_name",
|
|
1016
|
+
"displayName",
|
|
1017
|
+
"display_name",
|
|
1018
|
+
"doctorName",
|
|
1019
|
+
"doctorname",
|
|
1020
|
+
"doctor_name",
|
|
1021
|
+
"name",
|
|
1022
|
+
"primary_care_provider_location",
|
|
1023
|
+
"primaryCareProviderLocation",
|
|
1024
|
+
"provider_location",
|
|
1025
|
+
"providerLocation",
|
|
1026
|
+
"location_details",
|
|
1027
|
+
"locationDetails",
|
|
1028
|
+
"office_location",
|
|
1029
|
+
"officeLocation",
|
|
1030
|
+
"practice_location",
|
|
1031
|
+
"practiceLocation",
|
|
1032
|
+
"location",
|
|
1033
|
+
"address"
|
|
1034
|
+
])).has(key);
|
|
1035
|
+
}
|
|
1036
|
+
function eventSourceFieldPaths(context) {
|
|
1037
|
+
const paths = /* @__PURE__ */ new Set();
|
|
1038
|
+
for (const [key, value] of Object.entries(context)) {
|
|
1039
|
+
if (key === "listPath" || !isProviderSubmitField(key) || !isRecord(value)) {
|
|
1040
|
+
continue;
|
|
1041
|
+
}
|
|
1042
|
+
const path = value.path;
|
|
1043
|
+
if (typeof path === "string") {
|
|
1044
|
+
paths.add(path);
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
return paths;
|
|
1048
|
+
}
|
|
1049
|
+
function isProviderDraftFieldPath(path) {
|
|
1050
|
+
const prefix = "/__listDrafts/needs.providers/";
|
|
1051
|
+
const field = path.startsWith(prefix) ? path.slice(prefix.length) : lastPathSegment(path);
|
|
1052
|
+
return field !== void 0 && isProviderSubmitField(field);
|
|
1053
|
+
}
|
|
1054
|
+
function lastPathSegment(path) {
|
|
1055
|
+
const normalized = path.trim().replaceAll("\\", "/");
|
|
1056
|
+
const index = normalized.lastIndexOf("/");
|
|
1057
|
+
const segment = index >= 0 ? normalized.slice(index + 1) : normalized;
|
|
1058
|
+
return segment.length > 0 ? segment : void 0;
|
|
1059
|
+
}
|
|
1060
|
+
function isProviderSubmitLabel(label) {
|
|
1061
|
+
switch (normalizeFieldKey(label)) {
|
|
1062
|
+
case "provider_name":
|
|
1063
|
+
case "primary_care_provider":
|
|
1064
|
+
case "primary_care_provider_name":
|
|
1065
|
+
case "provider_location":
|
|
1066
|
+
case "primary_care_provider_location":
|
|
1067
|
+
case "location_details":
|
|
1068
|
+
return true;
|
|
1069
|
+
default:
|
|
1070
|
+
return false;
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
function normalizeFieldKey(key) {
|
|
1074
|
+
return key.trim().toLowerCase().replaceAll(/[^a-z0-9]+/g, "_").replaceAll(/^_+|_+$/g, "");
|
|
1075
|
+
}
|
|
1076
|
+
function upsertListRow(rows, row) {
|
|
1077
|
+
const itemId = row.itemId;
|
|
1078
|
+
if (typeof itemId !== "string" || itemId.length === 0) {
|
|
1079
|
+
return [...rows, row];
|
|
1080
|
+
}
|
|
1081
|
+
const next = [...rows];
|
|
1082
|
+
const existing = next.findIndex(
|
|
1083
|
+
(candidate) => isRecord(candidate) && candidate.itemId === itemId
|
|
1084
|
+
);
|
|
1085
|
+
if (existing >= 0) {
|
|
1086
|
+
next[existing] = row;
|
|
1087
|
+
return next;
|
|
1088
|
+
}
|
|
1089
|
+
return [...next, row];
|
|
1090
|
+
}
|
|
1091
|
+
function firstTextField(source, keys) {
|
|
1092
|
+
for (const key of keys) {
|
|
1093
|
+
const value = source[key];
|
|
1094
|
+
if (typeof value !== "string") {
|
|
1095
|
+
continue;
|
|
1096
|
+
}
|
|
1097
|
+
const text = value.trim();
|
|
1098
|
+
if (text.length > 0) {
|
|
1099
|
+
return text;
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
return void 0;
|
|
1103
|
+
}
|
|
617
1104
|
function listRowsFromRoot(root) {
|
|
618
1105
|
const rowsByPath = /* @__PURE__ */ new Map();
|
|
619
1106
|
for (const [key, value] of Object.entries(root)) {
|
|
@@ -796,6 +1283,7 @@ function A2UISurfaceHost({
|
|
|
796
1283
|
resolvedSurfaceMetadata?.fieldInteractions ?? []
|
|
797
1284
|
),
|
|
798
1285
|
annotateActionControls(root),
|
|
1286
|
+
suppressSkipForMandatoryFields(root, structure.fields),
|
|
799
1287
|
blockInvalidActionControls(root),
|
|
800
1288
|
setPendingGroupsDisabled(
|
|
801
1289
|
root,
|
|
@@ -1113,7 +1601,9 @@ function annotateActionControls(root) {
|
|
|
1113
1601
|
);
|
|
1114
1602
|
const groups = /* @__PURE__ */ new Set();
|
|
1115
1603
|
for (const action of actions) {
|
|
1604
|
+
const label = action.textContent?.trim().toLowerCase() ?? "";
|
|
1116
1605
|
action.dataset.a2uiAction = "true";
|
|
1606
|
+
action.dataset.a2uiActionLabel = label;
|
|
1117
1607
|
if (action.parentElement !== null) {
|
|
1118
1608
|
action.parentElement.dataset.a2uiActionGroup = "true";
|
|
1119
1609
|
groups.add(action.parentElement);
|
|
@@ -1122,12 +1612,40 @@ function annotateActionControls(root) {
|
|
|
1122
1612
|
return () => {
|
|
1123
1613
|
for (const action of actions) {
|
|
1124
1614
|
delete action.dataset.a2uiAction;
|
|
1615
|
+
delete action.dataset.a2uiActionLabel;
|
|
1125
1616
|
}
|
|
1126
1617
|
for (const group of groups) {
|
|
1127
1618
|
delete group.dataset.a2uiActionGroup;
|
|
1128
1619
|
}
|
|
1129
1620
|
};
|
|
1130
1621
|
}
|
|
1622
|
+
function suppressSkipForMandatoryFields(root, fields) {
|
|
1623
|
+
const requiredFields = fields.filter((field) => field.required);
|
|
1624
|
+
if (requiredFields.length === 0 || requiredFields.every((field) => isOptionalCoverageField(field.field))) {
|
|
1625
|
+
return () => void 0;
|
|
1626
|
+
}
|
|
1627
|
+
const skipButtons = [
|
|
1628
|
+
...root.querySelectorAll("[data-a2ui-action='true']")
|
|
1629
|
+
].filter((button) => button.dataset.a2uiActionLabel === "skip");
|
|
1630
|
+
const originals = skipButtons.map((button) => ({
|
|
1631
|
+
button,
|
|
1632
|
+
hidden: button.hidden,
|
|
1633
|
+
ariaHidden: button.getAttribute("aria-hidden")
|
|
1634
|
+
}));
|
|
1635
|
+
for (const button of skipButtons) {
|
|
1636
|
+
button.hidden = true;
|
|
1637
|
+
button.setAttribute("aria-hidden", "true");
|
|
1638
|
+
}
|
|
1639
|
+
return () => {
|
|
1640
|
+
for (const original of originals) {
|
|
1641
|
+
original.button.hidden = original.hidden;
|
|
1642
|
+
restoreAttribute(original.button, "aria-hidden", original.ariaHidden);
|
|
1643
|
+
}
|
|
1644
|
+
};
|
|
1645
|
+
}
|
|
1646
|
+
function isOptionalCoverageField(field) {
|
|
1647
|
+
return field === "employer_union_coverage" || field === "va_tricare_benefits" || field === "coverage.employerUnionCoverage" || field === "coverage.vaTricareBenefits";
|
|
1648
|
+
}
|
|
1131
1649
|
var EMPTY_STRUCTURE = { fields: [], tabs: [] };
|
|
1132
1650
|
var SurfaceErrorBoundary = class extends Component {
|
|
1133
1651
|
state = { failedSurfaceId: void 0 };
|
|
@@ -1288,6 +1806,9 @@ function blockInvalidActionControls(root) {
|
|
|
1288
1806
|
if (action === null || !root.contains(action)) {
|
|
1289
1807
|
return;
|
|
1290
1808
|
}
|
|
1809
|
+
if (action.dataset.a2uiActionLabel === "skip") {
|
|
1810
|
+
return;
|
|
1811
|
+
}
|
|
1291
1812
|
const invalid2 = firstInvalidInput(root);
|
|
1292
1813
|
if (invalid2 === void 0) {
|
|
1293
1814
|
return;
|
|
@@ -1985,7 +2506,7 @@ function decodeRendererAction(event) {
|
|
|
1985
2506
|
const listPath = event.context.listPath;
|
|
1986
2507
|
if (typeof listPath === "string" && listPath.length > 0) {
|
|
1987
2508
|
const fieldEntries2 = entries.filter(([key]) => key !== "listPath");
|
|
1988
|
-
const fields3 = scalarFields(fieldEntries2);
|
|
2509
|
+
const fields3 = scalarFields(fieldEntries2, listPath);
|
|
1989
2510
|
if (fields3 === null) {
|
|
1990
2511
|
return null;
|
|
1991
2512
|
}
|
|
@@ -2015,7 +2536,7 @@ function decodeRendererAction(event) {
|
|
|
2015
2536
|
const fieldEntries2 = entries.filter(
|
|
2016
2537
|
([key]) => key !== "listPath" && key !== "itemId"
|
|
2017
2538
|
);
|
|
2018
|
-
const fields2 = scalarFields(fieldEntries2);
|
|
2539
|
+
const fields2 = scalarFields(fieldEntries2, listPath);
|
|
2019
2540
|
if (action !== "flow.list.delete" && (fields2 === null || Object.keys(fields2).length === 0)) {
|
|
2020
2541
|
return null;
|
|
2021
2542
|
}
|
|
@@ -2045,17 +2566,69 @@ function decodeRendererAction(event) {
|
|
|
2045
2566
|
}
|
|
2046
2567
|
};
|
|
2047
2568
|
}
|
|
2048
|
-
function scalarFields(entries) {
|
|
2569
|
+
function scalarFields(entries, listPath) {
|
|
2049
2570
|
const fields = {};
|
|
2050
2571
|
for (const [key, value] of entries) {
|
|
2051
2572
|
const normalized = normalizeFieldValue(value);
|
|
2052
2573
|
if (normalized === void 0) {
|
|
2053
2574
|
return null;
|
|
2054
2575
|
}
|
|
2055
|
-
fields[key] = normalized;
|
|
2576
|
+
fields[canonicalListFieldKey(listPath, key)] = normalized;
|
|
2056
2577
|
}
|
|
2057
2578
|
return fields;
|
|
2058
2579
|
}
|
|
2580
|
+
function canonicalListFieldKey(listPath, key) {
|
|
2581
|
+
if (listPath !== "needs.providers") {
|
|
2582
|
+
return key;
|
|
2583
|
+
}
|
|
2584
|
+
switch (normalizeFieldKey2(key)) {
|
|
2585
|
+
case "primary_care_provider":
|
|
2586
|
+
case "primarycareprovider":
|
|
2587
|
+
case "primarycare":
|
|
2588
|
+
case "primary_care":
|
|
2589
|
+
case "primary_care_doctor":
|
|
2590
|
+
case "primary_doctor":
|
|
2591
|
+
case "primarydoctor":
|
|
2592
|
+
case "primary_provider":
|
|
2593
|
+
case "primaryprovider":
|
|
2594
|
+
case "pcp":
|
|
2595
|
+
case "provider_name":
|
|
2596
|
+
case "providername":
|
|
2597
|
+
case "display_name":
|
|
2598
|
+
case "displayname":
|
|
2599
|
+
return "primary_care_provider";
|
|
2600
|
+
case "primary_care_provider_location":
|
|
2601
|
+
case "primarycareproviderlocation":
|
|
2602
|
+
case "primarycarelocation":
|
|
2603
|
+
case "primary_care_location":
|
|
2604
|
+
case "provider_location":
|
|
2605
|
+
case "providerlocation":
|
|
2606
|
+
case "doctor_location":
|
|
2607
|
+
case "doctorlocation":
|
|
2608
|
+
case "doctor_address":
|
|
2609
|
+
case "doctoraddress":
|
|
2610
|
+
case "location_details":
|
|
2611
|
+
case "locationdetails":
|
|
2612
|
+
case "provider_address":
|
|
2613
|
+
case "provideraddress":
|
|
2614
|
+
case "office_location":
|
|
2615
|
+
case "officelocation":
|
|
2616
|
+
case "practice_location":
|
|
2617
|
+
case "practicelocation":
|
|
2618
|
+
case "city":
|
|
2619
|
+
case "city_state":
|
|
2620
|
+
case "cityandstate":
|
|
2621
|
+
case "city_and_state":
|
|
2622
|
+
case "location":
|
|
2623
|
+
case "address":
|
|
2624
|
+
return "primary_care_provider_location";
|
|
2625
|
+
default:
|
|
2626
|
+
return key;
|
|
2627
|
+
}
|
|
2628
|
+
}
|
|
2629
|
+
function normalizeFieldKey2(key) {
|
|
2630
|
+
return key.trim().toLowerCase().replaceAll(/[^a-z0-9]+/g, "_").replaceAll(/^_+|_+$/g, "");
|
|
2631
|
+
}
|
|
2059
2632
|
function isSameLogicalAction(envelope, candidate) {
|
|
2060
2633
|
return envelope.action === candidate.action && JSON.stringify(envelope.payload) === JSON.stringify(candidate.payload);
|
|
2061
2634
|
}
|