@growth-operations/ui-shared 1.32.0 → 1.33.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@growth-operations/ui-shared",
3
- "version": "1.32.0",
3
+ "version": "1.33.0",
4
4
  "description": "Shared HubSpot UI-extension modules (Home, Billing) for Growth Operations apps.",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -103,7 +103,7 @@ export function AutoProvisionToggle({
103
103
  <Alert variant="warning" title="Disable automatic credit provisioning?">
104
104
  <Box flex="auto">
105
105
  <Flex direction="column" gap="small">
106
- <Text>{autoProvisionConfirmBody(appName)}</Text>
106
+ <Text>{autoProvisionConfirmBody(appName, appKey)}</Text>
107
107
  <Flex direction="row" gap="small">
108
108
  <Button
109
109
  variant="destructive"
@@ -22,7 +22,7 @@ import { useStrictModeEffect } from "../lib/useStrictModeEffect";
22
22
  import { CreditMeter } from "../home/CreditMeter";
23
23
  import { PlanGrid } from "./PlanGrid";
24
24
  import { AutoProvisionToggle } from "./AutoProvisionToggle";
25
- import { resolveAutoProvision } from "../lib/autoProvision";
25
+ import { autoProvisionBlockOf, resolveAutoProvision } from "../lib/autoProvision";
26
26
  import { refreshBillingActionTokens } from "../sdk/billing";
27
27
  import { getInvoices } from "../sdk/app/topUps";
28
28
 
@@ -691,7 +691,12 @@ export function CreditsBilling({ context, state, appKey, openIframe = null }) {
691
691
  <AutoProvisionToggle
692
692
  context={context}
693
693
  appKey={appKey}
694
- enabled={resolveAutoProvision(state?.auto_provision).enabled}
694
+ // Dual-read: the backends nest auto_provision under
695
+ // payload.state — a top-level-only read would snap a disabled
696
+ // toggle back to ON on every refetch.
697
+ enabled={
698
+ resolveAutoProvision(autoProvisionBlockOf(state)).enabled
699
+ }
695
700
  appName={state?.app?.name ?? "this app"}
696
701
  // The POST's second auth dep (see setAutoProvision). `state`
697
702
  // here is BillingTab's interval-refreshed copy, so this token is
@@ -14,8 +14,19 @@ export function autoProvisionSubtext(appName) {
14
14
  return `If monthly credits are used, this will automatically purchase another pack of credits so use of ${appName} is not impacted.`;
15
15
  }
16
16
 
17
- export function autoProvisionConfirmBody(appName) {
18
- return `Are you sure you want to disable automatic credit provisioning? If monthly credits are used, ${appName} will no longer function and workflow actions will fail.`;
17
+ // The ON→OFF confirmation's ending, per app. The default names the generic
18
+ // consequence (workflow actions fail); ATS has no workflow actions — its
19
+ // credit-gated features just stop working — so Andrew's 2026-10-19 copy names
20
+ // the user-visible consequence instead.
21
+ const CONFIRM_BODY_ENDINGS = {
22
+ applicant_tracking_system:
23
+ "and features like resume parsing will stop functioning until credit renew at the start of the next bill period.",
24
+ };
25
+ const DEFAULT_CONFIRM_BODY_ENDING = "and workflow actions will fail.";
26
+
27
+ export function autoProvisionConfirmBody(appName, appKey) {
28
+ const ending = CONFIRM_BODY_ENDINGS[appKey] ?? DEFAULT_CONFIRM_BODY_ENDING;
29
+ return `Are you sure you want to disable automatic credit provisioning? If monthly credits are used, ${appName} will no longer function ${ending}`;
19
30
  }
20
31
 
21
32
  export const AUTO_PROVISION_CONFIRM_YES = "Yes, disable this feature.";
@@ -28,6 +39,15 @@ export function resolveAutoProvision(autoProvision) {
28
39
  return { enabled: autoProvision?.enabled !== false };
29
40
  }
30
41
 
42
+ // The auto_provision block off a /v1/home PAYLOAD, dual-read like
43
+ // planFitOf/periodComparisonOf (lib/homeBlocks): base-hosted and ATS backends
44
+ // nest it under payload.state; a top-level read alone silently resolves to
45
+ // the default ON for a disabled account after every refetch/remount.
46
+ export function autoProvisionBlockOf(state) {
47
+ if (!state || typeof state !== "object") return undefined;
48
+ return state.state?.auto_provision ?? state.auto_provision;
49
+ }
50
+
31
51
  // The toggle's interaction state. `enabled` itself lives in the component
32
52
  // (seeded from the payload, updated on save); this machine owns everything
33
53
  // around it: the ON→OFF confirmation and the in-flight POST.