@salesforcedevs/dx-components 1.34.0 → 1.35.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": "@salesforcedevs/dx-components",
3
- "version": "1.34.0",
3
+ "version": "1.35.0",
4
4
  "description": "DX Lightning web components",
5
5
  "license": "MIT",
6
6
  "engines": {
@@ -44,5 +44,5 @@
44
44
  "luxon": "3.4.4",
45
45
  "msw": "^2.12.4"
46
46
  },
47
- "gitHead": "5d072e2fa81d7eccadcbfb4134ee007ce2b0c7c4"
47
+ "gitHead": "7f00db154db1ca528e2bed2c33226a3ff674cd17"
48
48
  }
@@ -57,6 +57,24 @@ function loadMiawUiScript(): Promise<void> {
57
57
  return scriptLoaded;
58
58
  }
59
59
 
60
+ function dropCookie(cookieDomain: string) {
61
+ const { hostname, protocol } = window.location;
62
+ const onCookieDomain =
63
+ !!cookieDomain &&
64
+ (hostname === cookieDomain || hostname.endsWith(`.${cookieDomain}`));
65
+
66
+ document.cookie = [
67
+ "show_agent=true",
68
+ "Path=/",
69
+ "Max-Age=2592000",
70
+ "SameSite=Lax",
71
+ protocol === "https:" ? "Secure" : null,
72
+ onCookieDomain ? `Domain=${cookieDomain}` : null
73
+ ]
74
+ .filter(Boolean)
75
+ .join("; ");
76
+ }
77
+
60
78
  export default class AgentMiawUi extends LightningElement {
61
79
  private static readonly SIDEBAR_OPEN_ATTR = "data-xsf-agent-sidebar-open";
62
80
  private static readonly AGENT_ROOT_SELECTOR = '[data-testid="agent-root"]';
@@ -78,6 +96,16 @@ export default class AgentMiawUi extends LightningElement {
78
96
  /** When set, forwarded to the embed as `welcome-text` (greeting / headline copy). */
79
97
  @api welcomeText?: string;
80
98
  @api agentforceEnv?: string;
99
+ /**
100
+ * When true, mounting of the agent is gated behind the `showAgent=true` query param
101
+ * or `show_agent=true` cookie opt-in; otherwise (and by default), gating is off.
102
+ */
103
+ @api hideAgentConditionally: boolean = false;
104
+ /**
105
+ * Apex domain that the opt-in cookie targets (covers subdomains); applied only when the
106
+ * current host matches it, so local dev / preview hosts fall back to a host-only cookie.
107
+ */
108
+ @api cookieDomain?: string;
81
109
 
82
110
  /** After first mount attempt is scheduled, we do not run it again for this instance. */
83
111
  private hasRendered = false;
@@ -87,7 +115,9 @@ export default class AgentMiawUi extends LightningElement {
87
115
  renderedCallback(): void {
88
116
  if (!this.hasRendered) {
89
117
  this.hasRendered = true;
90
- this.mountMiawHost();
118
+ if (this.shouldMount()) {
119
+ this.mountMiawHost();
120
+ }
91
121
  }
92
122
  }
93
123
 
@@ -96,6 +126,39 @@ export default class AgentMiawUi extends LightningElement {
96
126
  this.sidebarStateObserver = null;
97
127
  }
98
128
 
129
+ /**
130
+ * Decide whether the agent should mount. If conditional gating is off, always mount.
131
+ * If conditional gating of the agent is on, return `true` only when the user has opted in
132
+ * via the `showAgent=true` query param or the `show_agent=true` cookie. (When only the
133
+ * param is present, persists a sticky opt-in cookie (~30 days) as a side effect so the
134
+ * choice carries across pages and subdomains.)
135
+ *
136
+ * CROSS-SITE CONTRACT: the param key/value, cookie token, Max-Age, SameSite, Secure and
137
+ * Domain-scoping logic are MIRRORED in architect-sf, since both serve pages for Architect.
138
+ * Changing these values requires a coordinated change in all repos.
139
+ */
140
+ private shouldMount(): boolean {
141
+ if (!this.hideAgentConditionally) {
142
+ return true;
143
+ }
144
+
145
+ // When the agent should be conditionally hidden, we check for special query param or
146
+ // cookie required for actually mounting/rendering it.
147
+ const hasParam =
148
+ new URLSearchParams(window.location.search).get("showAgent") ===
149
+ "true";
150
+ const hasCookie = /(?:^|;\s*)show_agent=true(?:;|$)/.test(
151
+ document.cookie
152
+ );
153
+
154
+ // If the user doesn't have the cookie yet but does have the param, set the cookie
155
+ if (hasParam && !hasCookie) {
156
+ dropCookie(this.cookieDomain || "");
157
+ }
158
+
159
+ return hasParam || hasCookie;
160
+ }
161
+
99
162
  private async mountMiawHost(): Promise<void> {
100
163
  try {
101
164
  await loadMiawUiScript();
@@ -114,10 +177,7 @@ export default class AgentMiawUi extends LightningElement {
114
177
  this.richComponentVersion
115
178
  );
116
179
  if (this.routingAttributes) {
117
- el.setAttribute(
118
- "routing-attributes",
119
- this.routingAttributes
120
- );
180
+ el.setAttribute("routing-attributes", this.routingAttributes);
121
181
  }
122
182
  if (this.prompts) {
123
183
  el.setAttribute("prompts", this.prompts);
@@ -134,7 +194,9 @@ export default class AgentMiawUi extends LightningElement {
134
194
  }
135
195
 
136
196
  private setSidebarOpenState(isOpen: boolean): void {
137
- const targets = document.querySelectorAll(this.sidebarStateTargetSelector);
197
+ const targets = document.querySelectorAll(
198
+ this.sidebarStateTargetSelector
199
+ );
138
200
  targets.forEach((target) => {
139
201
  target.setAttribute(
140
202
  AgentMiawUi.SIDEBAR_OPEN_ATTR,