@fluid-app/portal-sdk 0.1.518 → 0.1.519

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 (39) hide show
  1. package/dist/{ContactsScreen-By9x021F.mjs → ContactsScreen-5tn5LOdL.mjs} +2 -2
  2. package/dist/{ContactsScreen-DP5A5yQN.mjs → ContactsScreen-BIjEr68m.mjs} +2 -2
  3. package/dist/{ContactsScreen-DP5A5yQN.mjs.map → ContactsScreen-BIjEr68m.mjs.map} +1 -1
  4. package/dist/{ContactsScreen-DV0hoorh.cjs → ContactsScreen-CQeHdBSj.cjs} +2 -2
  5. package/dist/{ContactsScreen-B6_KXScY.cjs → ContactsScreen-DJsCRndV.cjs} +2 -2
  6. package/dist/{ContactsScreen-B6_KXScY.cjs.map → ContactsScreen-DJsCRndV.cjs.map} +1 -1
  7. package/dist/{MessagingScreen-B-J6jRWH.cjs → MessagingScreen-B5nW8HBw.cjs} +2 -2
  8. package/dist/{MessagingScreen-CEHNxhs9.cjs → MessagingScreen-BGE1AxdJ.cjs} +2 -2
  9. package/dist/{MessagingScreen-CEHNxhs9.cjs.map → MessagingScreen-BGE1AxdJ.cjs.map} +1 -1
  10. package/dist/{MessagingScreen-B5zl1dov.mjs → MessagingScreen-DeAqHKhM.mjs} +2 -2
  11. package/dist/{MessagingScreen-B5zl1dov.mjs.map → MessagingScreen-DeAqHKhM.mjs.map} +1 -1
  12. package/dist/{MessagingScreen-CUOhRPr-.mjs → MessagingScreen-GvlF96hh.mjs} +2 -2
  13. package/dist/{MySiteScreen-DV7iYs_P.mjs → MySiteScreen-BOwQw4Ud.mjs} +2 -2
  14. package/dist/{MySiteScreen-q4tciAP1.cjs → MySiteScreen-C6_2pJ3S.cjs} +2 -2
  15. package/dist/{MySiteScreen-q4tciAP1.cjs.map → MySiteScreen-C6_2pJ3S.cjs.map} +1 -1
  16. package/dist/{MySiteScreen-CAvKw9Yo.mjs → MySiteScreen-CktOXvV5.mjs} +2 -2
  17. package/dist/{MySiteScreen-CAvKw9Yo.mjs.map → MySiteScreen-CktOXvV5.mjs.map} +1 -1
  18. package/dist/{MySiteScreen-DMZyJGuY.cjs → MySiteScreen-nmG9-sZI.cjs} +2 -2
  19. package/dist/{ProfileScreen-DDo49SL5.cjs → ProfileScreen-BO42YrZX.cjs} +2 -2
  20. package/dist/{ProfileScreen-DDo49SL5.cjs.map → ProfileScreen-BO42YrZX.cjs.map} +1 -1
  21. package/dist/{ProfileScreen-DdhsKq8b.cjs → ProfileScreen-BuEH2Tus.cjs} +2 -2
  22. package/dist/{ProfileScreen-thlAvVV-.mjs → ProfileScreen-CKd7qK-I.mjs} +2 -2
  23. package/dist/{ProfileScreen-thlAvVV-.mjs.map → ProfileScreen-CKd7qK-I.mjs.map} +1 -1
  24. package/dist/{ProfileScreen-CQia71t1.mjs → ProfileScreen-Di3UqOU1.mjs} +2 -2
  25. package/dist/{SubscriptionsScreen-AW_duq75.cjs → SubscriptionsScreen-BIFMUL6T.cjs} +2 -2
  26. package/dist/{SubscriptionsScreen-C0ZFD-A5.mjs → SubscriptionsScreen-B_GCaXRS.mjs} +2 -2
  27. package/dist/{SubscriptionsScreen-CRHFGux0.cjs → SubscriptionsScreen-CsylqAg0.cjs} +103 -55
  28. package/dist/SubscriptionsScreen-CsylqAg0.cjs.map +1 -0
  29. package/dist/{SubscriptionsScreen-CdDBKpkc.mjs → SubscriptionsScreen-vktnPB8s.mjs} +104 -56
  30. package/dist/SubscriptionsScreen-vktnPB8s.mjs.map +1 -0
  31. package/dist/index.cjs +16 -16
  32. package/dist/index.mjs +16 -16
  33. package/dist/{sidebar-DS8r8yy1.mjs → sidebar-CQpJWKMc.mjs} +2 -2
  34. package/dist/{sidebar-DS8r8yy1.mjs.map → sidebar-CQpJWKMc.mjs.map} +1 -1
  35. package/dist/{sidebar-Cu7C835M.cjs → sidebar-zkV-HxHW.cjs} +7 -1
  36. package/dist/{sidebar-Cu7C835M.cjs.map → sidebar-zkV-HxHW.cjs.map} +1 -1
  37. package/package.json +7 -7
  38. package/dist/SubscriptionsScreen-CRHFGux0.cjs.map +0 -1
  39. package/dist/SubscriptionsScreen-CdDBKpkc.mjs.map +0 -1
@@ -15,7 +15,7 @@ const require_MobileActionSheet = require("./MobileActionSheet-Diex9dkG.cjs");
15
15
  const require_ResponsiveDialog = require("./ResponsiveDialog-BZ3Cf5m9.cjs");
16
16
  const require_AppNavigationContext = require("./AppNavigationContext-C6FeqL-k.cjs");
17
17
  const require_use_store = require("./use-store-CZPKdvkG.cjs");
18
- const require_sidebar = require("./sidebar-Cu7C835M.cjs");
18
+ const require_sidebar = require("./sidebar-zkV-HxHW.cjs");
19
19
  const require_ScreenHeaderContext = require("./ScreenHeaderContext-Df1DvpEW.cjs");
20
20
  const require_use_portal_card_add_3ds_flow = require("./use-portal-card-add-3ds-flow-Bvs0RcyI.cjs");
21
21
  const require_isAfter = require("./isAfter-DvjGDS5r.cjs");
@@ -8604,7 +8604,7 @@ function PortalSubscriptionShippingAddressSectionInner({ addressId, address: cur
8604
8604
  * 6. Never lets a stalled sibling invalidation hold up the target's own
8605
8605
  * awaited refetch.
8606
8606
  */
8607
- function useUpdateAutoApplyPoints({ currentSubscriptionToken, onSuccess, onError } = {}) {
8607
+ function useUpdateAutoApplyPoints({ queryKeys, currentSubscriptionToken, onSuccess, onError }) {
8608
8608
  const api = useAutoApplyPointsApi();
8609
8609
  const queryClient = (0, _tanstack_react_query.useQueryClient)();
8610
8610
  const latestTokenRef = (0, react.useRef)(currentSubscriptionToken);
@@ -8618,17 +8618,16 @@ function useUpdateAutoApplyPoints({ currentSubscriptionToken, onSuccess, onError
8618
8618
  onSuccess: async (result, variables) => {
8619
8619
  const siblingTokens = [...new Set([...result.resolvedSubscriptionTokens, ...variables.bundleTokens ?? []])].filter((token) => token !== variables.subscriptionToken);
8620
8620
  Promise.all(siblingTokens.map((token) => queryClient.invalidateQueries({
8621
- queryKey: subscriptionsKeys.detail(token),
8621
+ queryKey: queryKeys.detail(token),
8622
8622
  exact: true
8623
8623
  }).catch(() => {})));
8624
- queryClient.invalidateQueries({ queryKey: subscriptionsKeys.lists });
8625
- queryClient.invalidateQueries({ queryKey: subscriptionsKeys.infiniteLists });
8624
+ for (const listKey of queryKeys.lists) queryClient.invalidateQueries({ queryKey: listKey });
8626
8625
  await queryClient.refetchQueries({
8627
- queryKey: subscriptionsKeys.detail(variables.subscriptionToken),
8626
+ queryKey: queryKeys.detail(variables.subscriptionToken),
8628
8627
  exact: true
8629
8628
  });
8630
8629
  if (latestTokenRef.current && latestTokenRef.current !== variables.subscriptionToken) return;
8631
- const refreshedDetail = queryClient.getQueryData(subscriptionsKeys.detail(variables.subscriptionToken));
8630
+ const refreshedDetail = queryClient.getQueryData(queryKeys.detail(variables.subscriptionToken));
8632
8631
  onSuccess?.({
8633
8632
  result,
8634
8633
  refreshed: refreshedDetail?.subscription.auto_apply_points === variables.autoApplyPoints,
@@ -8642,16 +8641,30 @@ function useUpdateAutoApplyPoints({ currentSubscriptionToken, onSuccess, onError
8642
8641
  });
8643
8642
  }
8644
8643
  //#endregion
8645
- //#region src/subscriptions/subscription-auto-apply-points.ts
8644
+ //#region ../../subscriptions/ui/src/lib/auto-apply-points.ts
8645
+ /**
8646
+ * Whether the control belongs on this subscription at all.
8647
+ *
8648
+ * Split out of the state below because a host needs the same answer before
8649
+ * this component renders: the host owns the surrounding layout, so it has to
8650
+ * know whether to draw the frame rather than leaving an empty one behind.
8651
+ *
8652
+ * An absent `pointsEnabled` counts as off rather than on. The field is
8653
+ * additive, so an older payload, or a read path that quietly drops it, must
8654
+ * hide a setting that could not act instead of offering it.
8655
+ *
8656
+ * Returns true when the control should render.
8657
+ */
8658
+ function autoApplyPointsControlVisible(pointsEnabled) {
8659
+ return pointsEnabled === true;
8660
+ }
8646
8661
  /**
8647
8662
  * Resolve what the auto-apply-points switch shows, from server state alone.
8648
8663
  *
8649
8664
  * Three rules, each written against a specific way this can go wrong:
8650
8665
  *
8651
- * - A company that does not run a points program never sees the control. An
8652
- * absent `pointsEnabled` counts as off rather than on: the field is
8653
- * additive, so an older payload, or a read path that quietly drops it,
8654
- * must hide a setting that could not act instead of offering it.
8666
+ * - A company that does not run a points program never sees the control.
8667
+ * See autoApplyPointsControlVisible for why an absent flag counts as off.
8655
8668
  * - `checked` comes from the payload and never from a default. Defaulting to
8656
8669
  * off would render the switch unset while the server held the customer's
8657
8670
  * opt-in, which reads as "their choice was lost".
@@ -8662,7 +8675,7 @@ function useUpdateAutoApplyPoints({ currentSubscriptionToken, onSuccess, onError
8662
8675
  */
8663
8676
  function autoApplyPointsControlState(input) {
8664
8677
  return {
8665
- visible: input.pointsEnabled === true,
8678
+ visible: autoApplyPointsControlVisible(input.pointsEnabled),
8666
8679
  checked: input.autoApplyPoints === true,
8667
8680
  disabled: input.subscriptionDisabled || input.writeInFlight
8668
8681
  };
@@ -8703,7 +8716,7 @@ function autoApplyPointsMembershipDrifted(input) {
8703
8716
  return [...input.resolvedTokens].sort().join("\0") !== [...expected].sort().join("\0");
8704
8717
  }
8705
8718
  //#endregion
8706
- //#region src/subscriptions/BundleFanOutDialog.tsx
8719
+ //#region ../../subscriptions/ui/src/components/AutoApplyPointsFanOutDialog.tsx
8707
8720
  /**
8708
8721
  * Asks whether a points opt-in applies to the whole renewal group.
8709
8722
  *
@@ -8714,9 +8727,8 @@ function autoApplyPointsMembershipDrifted(input) {
8714
8727
  * this gets a focus trap, escape-to-close and backdrop dismissal for free
8715
8728
  * rather than reimplementing dialog semantics by hand.
8716
8729
  */
8717
- function BundleFanOutDialog({ bundle, pointsLabel, nextValue, onConfirmAll, onConfirmOne, onCancel }) {
8730
+ function AutoApplyPointsFanOutDialog({ bundle, pointsLabel, nextValue, presentation = "dialog", onConfirmAll, onConfirmOne, onCancel }) {
8718
8731
  const { t } = useSubscriptionsTranslation();
8719
- const { isMobile } = require_sidebar.useSidebar();
8720
8732
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_ResponsiveDialog.ResponsiveDialog, {
8721
8733
  open: true,
8722
8734
  onOpenChange: (next) => {
@@ -8724,7 +8736,7 @@ function BundleFanOutDialog({ bundle, pointsLabel, nextValue, onConfirmAll, onCo
8724
8736
  },
8725
8737
  title: t(nextValue ? "auto_apply_points_bundle_title" : "auto_apply_points_bundle_title_off", { label: pointsLabel }),
8726
8738
  description: t("auto_apply_points_bundle_body"),
8727
- presentation: isMobile ? "bottom-sheet" : "dialog",
8739
+ presentation,
8728
8740
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
8729
8741
  className: "space-y-1 text-sm",
8730
8742
  children: bundle.members.map((bundleMember) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", {
@@ -8754,19 +8766,26 @@ function BundleFanOutDialog({ bundle, pointsLabel, nextValue, onConfirmAll, onCo
8754
8766
  });
8755
8767
  }
8756
8768
  //#endregion
8757
- //#region src/subscriptions/PortalSubscriptionAutoApplyPointsSection.tsx
8769
+ //#region ../../subscriptions/ui/src/components/AutoApplyPointsSection.tsx
8758
8770
  /**
8759
8771
  * Lets a customer turn automatic points redemption on or off for one
8760
- * subscription. The switch reads the stored choice from the payload and writes
8761
- * through the subscription update the portal already owns, so an explicit
8762
- * "off" is a real write rather than a locally remembered preference.
8772
+ * subscription. The switch reads the stored choice from the payload and
8773
+ * writes it through, so an explicit "off" is a real write rather than a
8774
+ * locally remembered preference.
8775
+ *
8776
+ * Host-neutral. Everything the portal used to reach for directly, its store
8777
+ * label, its shell presentation and its query keys, arrives as a prop, so the
8778
+ * checkout renders the same control against its own cache and transport.
8779
+ *
8780
+ * Renders the row and nothing around it. Surrounding layout belongs to the
8781
+ * host, which knows how the row sits on its own screen; a host that draws a
8782
+ * frame should ask autoApplyPointsControlVisible first, because this renders
8783
+ * nothing for a company without a points program.
8763
8784
  */
8764
- function PortalSubscriptionAutoApplyPointsSection({ autoApplyPoints, pointsEnabled, subscriptionToken, disabled, renewalBundle, onSuccess, onError }) {
8785
+ function AutoApplyPointsSection({ autoApplyPoints, pointsEnabled, subscriptionToken, disabled, renewalBundle, pointsLabel, queryKeys, presentation = "dialog", onSuccess, onError }) {
8765
8786
  const { t } = useSubscriptionsTranslation();
8766
8787
  const labelId = (0, react.useId)();
8767
8788
  const queryClient = (0, _tanstack_react_query.useQueryClient)();
8768
- const { data: store } = require_use_optional_store.useOptionalStore();
8769
- const pointsLabel = store?.reward_points_label_plural || "points";
8770
8789
  const latestSubscriptionTokenRef = (0, react.useRef)(subscriptionToken);
8771
8790
  latestSubscriptionTokenRef.current = subscriptionToken;
8772
8791
  const [pendingValue, setPendingValue] = (0, react.useState)(null);
@@ -8778,24 +8797,26 @@ function PortalSubscriptionAutoApplyPointsSection({ autoApplyPoints, pointsEnabl
8778
8797
  confirmedRef.current = false;
8779
8798
  }
8780
8799
  const updateSubscription = useUpdateSubscriptionInfo({
8800
+ skipAutoInvalidate: true,
8781
8801
  onSuccess: async ({ subscriptionToken: updatedSubscriptionToken, body }) => {
8782
- if (!isCurrentSubscriptionPaymentAttempt(latestSubscriptionTokenRef.current, updatedSubscriptionToken)) return;
8802
+ for (const listKey of queryKeys.lists) queryClient.invalidateQueries({ queryKey: listKey });
8783
8803
  await queryClient.refetchQueries({
8784
- queryKey: subscriptionsKeys.detail(updatedSubscriptionToken),
8804
+ queryKey: queryKeys.detail(updatedSubscriptionToken),
8785
8805
  exact: true
8786
8806
  });
8787
- if (!isCurrentSubscriptionPaymentAttempt(latestSubscriptionTokenRef.current, updatedSubscriptionToken)) return;
8788
- if (queryClient.getQueryData(subscriptionsKeys.detail(updatedSubscriptionToken))?.subscription.auto_apply_points !== body.auto_apply_points) {
8807
+ if (latestSubscriptionTokenRef.current !== updatedSubscriptionToken) return;
8808
+ if (queryClient.getQueryData(queryKeys.detail(updatedSubscriptionToken))?.subscription.auto_apply_points !== body.auto_apply_points) {
8789
8809
  onSuccess?.(t("auto_apply_points_saved_but_not_refreshed", { label: pointsLabel }), "warning");
8790
8810
  return;
8791
8811
  }
8792
8812
  onSuccess?.(t("auto_apply_points_updated", { label: pointsLabel }));
8793
8813
  },
8794
8814
  onError: (error, { subscriptionToken: failedSubscriptionToken }) => {
8795
- if (isCurrentSubscriptionPaymentAttempt(latestSubscriptionTokenRef.current, failedSubscriptionToken)) onError?.(t("failed_to_update_auto_apply_points", { label: pointsLabel }), error);
8815
+ if (latestSubscriptionTokenRef.current === failedSubscriptionToken) onError?.(t("failed_to_update_auto_apply_points", { label: pointsLabel }), error);
8796
8816
  }
8797
8817
  });
8798
8818
  const fanOut = useUpdateAutoApplyPoints({
8819
+ queryKeys,
8799
8820
  currentSubscriptionToken: subscriptionToken,
8800
8821
  onSuccess: ({ result, refreshed, variables }) => {
8801
8822
  if (autoApplyPointsMembershipDrifted({
@@ -8822,7 +8843,7 @@ function PortalSubscriptionAutoApplyPointsSection({ autoApplyPoints, pointsEnabl
8822
8843
  }
8823
8844
  });
8824
8845
  const detailRefetching = (0, _tanstack_react_query.useIsFetching)({
8825
- queryKey: subscriptionsKeys.detail(subscriptionToken),
8846
+ queryKey: queryKeys.detail(subscriptionToken),
8826
8847
  exact: true
8827
8848
  }) > 0;
8828
8849
  const control = autoApplyPointsControlState({
@@ -8866,31 +8887,58 @@ function PortalSubscriptionAutoApplyPointsSection({ autoApplyPoints, pointsEnabl
8866
8887
  });
8867
8888
  }
8868
8889
  if (!control.visible) return null;
8869
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8890
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8891
+ className: "flex items-start justify-between gap-4",
8892
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8893
+ id: labelId,
8894
+ className: "text-foreground text-sm font-medium",
8895
+ children: t("auto_apply_points_each_renewal", { label: pointsLabel })
8896
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8897
+ className: "text-muted-foreground mt-1 text-sm",
8898
+ children: t("auto_apply_points_partial_balance")
8899
+ })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Switch, {
8900
+ "aria-labelledby": labelId,
8901
+ checked: control.checked,
8902
+ disabled: control.disabled,
8903
+ onCheckedChange: requestChange
8904
+ })]
8905
+ }), pendingValue !== null && renewalBundle ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AutoApplyPointsFanOutDialog, {
8906
+ bundle: renewalBundle,
8907
+ pointsLabel,
8908
+ nextValue: pendingValue,
8909
+ presentation,
8910
+ onConfirmAll: () => confirm("bundle"),
8911
+ onConfirmOne: () => confirm("subscription"),
8912
+ onCancel: () => setPendingValue(null)
8913
+ }) : null] });
8914
+ }
8915
+ //#endregion
8916
+ //#region src/subscriptions/PortalSubscriptionAutoApplyPointsSection.tsx
8917
+ /**
8918
+ * The portal's binding for the auto-apply-points control.
8919
+ *
8920
+ * The control itself is host-neutral and lives in
8921
+ * @fluid-app/subscriptions-ui. Everything this file still does is portal:
8922
+ * resolving the store's points label, the shell's presentation, the portal's
8923
+ * own query keys, and the separator this row sits in on the detail screen.
8924
+ * Kept as a wrapper rather than a renamed re-export so its callers and their
8925
+ * tests carry on passing the props they always did.
8926
+ */
8927
+ function PortalSubscriptionAutoApplyPointsSection(props) {
8928
+ const { data: store } = require_use_optional_store.useOptionalStore();
8929
+ const sidebar = (0, react.useContext)(require_sidebar.SidebarContext);
8930
+ if (!autoApplyPointsControlVisible(props.pointsEnabled)) return null;
8931
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8870
8932
  className: "border-border mb-6 border-b pb-4",
8871
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8872
- className: "flex items-start justify-between gap-4",
8873
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8874
- id: labelId,
8875
- className: "text-foreground text-sm font-medium",
8876
- children: t("auto_apply_points_each_renewal", { label: pointsLabel })
8877
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8878
- className: "text-muted-foreground mt-1 text-sm",
8879
- children: t("auto_apply_points_partial_balance")
8880
- })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Switch, {
8881
- "aria-labelledby": labelId,
8882
- checked: control.checked,
8883
- disabled: control.disabled,
8884
- onCheckedChange: requestChange
8885
- })]
8886
- }), pendingValue !== null && renewalBundle ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BundleFanOutDialog, {
8887
- bundle: renewalBundle,
8888
- pointsLabel,
8889
- nextValue: pendingValue,
8890
- onConfirmAll: () => confirm("bundle"),
8891
- onConfirmOne: () => confirm("subscription"),
8892
- onCancel: () => setPendingValue(null)
8893
- }) : null]
8933
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AutoApplyPointsSection, {
8934
+ ...props,
8935
+ pointsLabel: store?.reward_points_label_plural || "points",
8936
+ presentation: sidebar?.isMobile ? "bottom-sheet" : "dialog",
8937
+ queryKeys: {
8938
+ detail: subscriptionsKeys.detail,
8939
+ lists: [subscriptionsKeys.lists, subscriptionsKeys.infiniteLists]
8940
+ }
8941
+ })
8894
8942
  });
8895
8943
  }
8896
8944
  //#endregion
@@ -9104,4 +9152,4 @@ Object.defineProperty(exports, "subscriptionsScreenPropertySchema", {
9104
9152
  }
9105
9153
  });
9106
9154
 
9107
- //# sourceMappingURL=SubscriptionsScreen-CRHFGux0.cjs.map
9155
+ //# sourceMappingURL=SubscriptionsScreen-CsylqAg0.cjs.map