@ukiahinsure/a2ui-react-adapter 0.1.5 → 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 CHANGED
@@ -215,12 +215,16 @@ var A2UIClientAdapter = class {
215
215
  envelope.surfaceId,
216
216
  this.#persistedListRowsByPath
217
217
  );
218
- const nextStructure = updateSurfaceStructures(
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
- rawMessages,
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) && !activeDraftListPaths.has(listPath);
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 activeListDraftPaths(root) {
826
+ function hasBlankListDraft(root, listPath) {
601
827
  const drafts = root.__listDrafts;
602
828
  if (!isRecord(drafts)) {
603
- return /* @__PURE__ */ new Set();
829
+ return false;
604
830
  }
605
- return new Set(
606
- Object.keys(drafts).filter((listPath) => listPath.trim().length > 0)
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
  }