@salesforcedevs/dx-components 1.32.1-alpha.1 → 1.32.1-alpha.3

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.32.1-alpha.1",
3
+ "version": "1.32.1-alpha.3",
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": "6bc5a213b2992c24d0f9ada1cc47dd016a70ca69"
47
+ "gitHead": "d2c2ec175856efed7388c6486bdb78695485afed"
48
48
  }
@@ -0,0 +1,4 @@
1
+ :host {
2
+ position: relative;
3
+ z-index: 2147483000;
4
+ }
@@ -1,83 +1,85 @@
1
1
  /* eslint-disable @lwc/lwc/no-document-query */
2
2
  import { LightningElement, api } from "lwc";
3
3
 
4
- const PAGE_BUILDER_TAG = "page-builder-miaw-ui";
4
+ const HOSTED_MIAW_UI_TAG = "page-builder-miaw-ui";
5
5
  const SCRIPT_SRC =
6
6
  "https://a.sfdcstatic.com/digital/@sfdc-www-emu/page-builder-miaw-ui/v1-stable/page-builder-miaw-ui.js";
7
- const DEFINE_TIMEOUT_MS = 60_000;
8
-
9
- let loadPromise: Promise<void> | null = null;
10
-
11
- function withTimeout<T>(
12
- promise: Promise<T>,
13
- ms: number,
14
- message: string
15
- ): Promise<T> {
16
- return Promise.race([
17
- promise,
18
- new Promise<T>((_, reject) => {
19
- window.setTimeout(() => reject(new Error(message)), ms);
20
- })
21
- ]);
7
+ const DEFINE_TIMEOUT_MS = 60000;
8
+
9
+ let miawInitPromise: Promise<void> | null = null;
10
+
11
+ function waitUntilHostedMiawUiDefined(): Promise<void> {
12
+ const message =
13
+ `MIAW UI embed (${HOSTED_MIAW_UI_TAG}) did not register within ${
14
+ DEFINE_TIMEOUT_MS / 1000
15
+ }s. ` +
16
+ "Confirm the script loads (network tab), your origin is allowed, and CSP permits this script.";
17
+
18
+ return new Promise((resolve, reject) => {
19
+ const timeoutId = window.setTimeout(() => {
20
+ reject(new Error(message));
21
+ }, DEFINE_TIMEOUT_MS);
22
+
23
+ customElements.whenDefined(HOSTED_MIAW_UI_TAG).then(
24
+ () => {
25
+ window.clearTimeout(timeoutId);
26
+ resolve();
27
+ },
28
+ (err: unknown) => {
29
+ window.clearTimeout(timeoutId);
30
+ reject(err);
31
+ }
32
+ );
33
+ });
22
34
  }
23
35
 
24
- function loadMiawUi(): Promise<void> {
25
- if (loadPromise) {
26
- return loadPromise;
36
+ async function ensureMiawScriptAndDefinition(): Promise<void> {
37
+ if (customElements.get(HOSTED_MIAW_UI_TAG)) {
38
+ return;
27
39
  }
28
40
 
29
- loadPromise = (async () => {
30
- let script = document.querySelector(
31
- `script[src="${SCRIPT_SRC}"]`
32
- ) as HTMLScriptElement | null;
33
-
34
- const awaitDefinition = () =>
35
- withTimeout(
36
- customElements.whenDefined(PAGE_BUILDER_TAG),
37
- DEFINE_TIMEOUT_MS,
38
- `${PAGE_BUILDER_TAG} did not register within ${
39
- DEFINE_TIMEOUT_MS / 1000
40
- }s. ` +
41
- "Confirm the script loads (network tab), your origin is allowed, and CSP permits this script."
42
- ).then(() => undefined);
43
-
44
- if (customElements.get(PAGE_BUILDER_TAG)) {
45
- return;
46
- }
41
+ let script = document.querySelector(
42
+ `script[src="${SCRIPT_SRC}"]`
43
+ ) as HTMLScriptElement | null;
47
44
 
48
- if (script) {
49
- await awaitDefinition();
50
- return;
51
- }
45
+ if (script) {
46
+ await waitUntilHostedMiawUiDefined();
47
+ return;
48
+ }
52
49
 
53
- script = document.createElement("script");
54
- script.type = "module";
55
- script.src = SCRIPT_SRC;
56
-
57
- await new Promise<void>((resolve, reject) => {
58
- script!.addEventListener("load", () => resolve(), { once: true });
59
- script!.addEventListener(
60
- "error",
61
- () =>
62
- reject(
63
- new Error(
64
- `Failed to load page-builder-miaw-ui script (${SCRIPT_SRC}). Check status code and referrer rules.`
65
- )
66
- ),
67
- { once: true }
68
- );
69
- document.head.appendChild(script!);
70
- });
50
+ script = document.createElement("script");
51
+ script.type = "module";
52
+ script.src = SCRIPT_SRC;
53
+
54
+ await new Promise<void>((resolve, reject) => {
55
+ script!.addEventListener("load", () => resolve(), { once: true });
56
+ script!.addEventListener(
57
+ "error",
58
+ () =>
59
+ reject(
60
+ new Error(
61
+ `Failed to load MIAW UI embed script (${SCRIPT_SRC}). Check status code and referrer rules.`
62
+ )
63
+ ),
64
+ { once: true }
65
+ );
66
+ document.head.appendChild(script!);
67
+ });
68
+
69
+ await waitUntilHostedMiawUiDefined();
70
+ }
71
71
 
72
- await awaitDefinition();
73
- })();
72
+ function loadMiawUi(): Promise<void> {
73
+ if (miawInitPromise) {
74
+ return miawInitPromise;
75
+ }
74
76
 
75
- loadPromise = loadPromise.catch((e) => {
76
- loadPromise = null;
77
+ miawInitPromise = ensureMiawScriptAndDefinition().catch((e) => {
78
+ miawInitPromise = null;
77
79
  throw e;
78
80
  });
79
81
 
80
- return loadPromise;
82
+ return miawInitPromise;
81
83
  }
82
84
 
83
85
  export default class AgentMiawUi extends LightningElement {
@@ -87,38 +89,81 @@ export default class AgentMiawUi extends LightningElement {
87
89
  @api messagingUrl!: string;
88
90
  @api deploymentDevName = "page_builder_miaw_ui";
89
91
  @api richComponentVersion = "v1-stable";
90
-
91
- private ensureMountedPromise: Promise<void> | null = null;
92
+ @api routingAttributes?: string;
93
+ /**
94
+ * JSON array of suggested prompt strings for the MIAW UI (e.g.
95
+ * `["Show me an Agentforce demo","Help me build a business case"]`); forwarded as `prompts` on the embed.
96
+ */
97
+ @api prompts?: string;
98
+ /** When set, forwarded to the embed as `welcome-text` (greeting / headline copy). */
99
+ @api welcomeText?: string;
100
+ /**
101
+ * When set, bar gradient start (CSS color); sets `--wes-color-af-bar-gradient-from` on the
102
+ * `.miaw-host` container and on the embed when present (LWC may reset `this.style` on the host).
103
+ */
104
+ @api gradientFrom?: string;
105
+ /**
106
+ * When set, bar gradient end (CSS color); sets `--wes-color-af-bar-gradient-to` the same way.
107
+ */
108
+ @api gradientTo?: string;
92
109
 
93
110
  renderedCallback(): void {
94
- if (!this.orgId || !this.messagingUrl) {
111
+ this.syncGradientToMiawSubtree();
112
+ }
113
+
114
+ /** Applies gradient custom properties where the embed can see them (not on `this` — LWC can clear host inline styles). */
115
+ private syncGradientToMiawSubtree(): void {
116
+ const from = this.gradientFrom?.trim();
117
+ const to = this.gradientTo?.trim();
118
+ if (!from && !to) {
95
119
  return;
96
120
  }
97
- if (
98
- this.template
99
- .querySelector(".miaw-host")
100
- ?.querySelector(PAGE_BUILDER_TAG)
101
- ) {
121
+
122
+ const container = this.template.querySelector(
123
+ ".miaw-host"
124
+ ) as HTMLElement | null;
125
+ if (!container) {
102
126
  return;
103
127
  }
104
128
 
105
- this.ensureMiawUiMounted();
106
- }
129
+ const embed = container.querySelector(
130
+ HOSTED_MIAW_UI_TAG
131
+ ) as HTMLElement | null;
132
+ const targets = embed ? [container, embed] : [container];
107
133
 
108
- private ensureMiawUiMounted(): Promise<void> {
109
- if (this.ensureMountedPromise) {
110
- return this.ensureMountedPromise;
134
+ for (const node of targets) {
135
+ if (from) {
136
+ node.style.setProperty(
137
+ "--wes-color-af-bar-gradient-from",
138
+ from
139
+ );
140
+ }
141
+ if (to) {
142
+ node.style.setProperty("--wes-color-af-bar-gradient-to", to);
143
+ }
111
144
  }
145
+ }
112
146
 
113
- this.ensureMountedPromise = (async () => {
147
+ connectedCallback(): void {
148
+ // Past the connect flush so `this.template` includes `.miaw-host`; parent supplies `@api` in markup.
149
+ queueMicrotask(() => {
150
+ this.mountMiawHost();
151
+ });
152
+ }
153
+
154
+ private mountMiawHost(): void {
155
+ if (!this.orgId || !this.messagingUrl) {
156
+ return;
157
+ }
158
+ (async () => {
114
159
  try {
115
160
  await loadMiawUi();
116
161
  const container = this.template.querySelector(".miaw-host");
117
- if (!container || container.querySelector(PAGE_BUILDER_TAG)) {
162
+ if (!container || container.querySelector(HOSTED_MIAW_UI_TAG)) {
118
163
  return;
119
164
  }
120
165
 
121
- const el = document.createElement(PAGE_BUILDER_TAG);
166
+ const el = document.createElement(HOSTED_MIAW_UI_TAG);
122
167
  el.setAttribute("org-id", this.orgId);
123
168
  el.setAttribute("messaging-url", this.messagingUrl);
124
169
  el.setAttribute("deployment-dev-name", this.deploymentDevName);
@@ -127,14 +172,23 @@ export default class AgentMiawUi extends LightningElement {
127
172
  "rich-component-version",
128
173
  this.richComponentVersion
129
174
  );
175
+ if (this.routingAttributes) {
176
+ el.setAttribute(
177
+ "routing-attributes",
178
+ this.routingAttributes
179
+ );
180
+ }
181
+ if (this.prompts) {
182
+ el.setAttribute("prompts", this.prompts);
183
+ }
184
+ if (this.welcomeText) {
185
+ el.setAttribute("welcome-text", this.welcomeText);
186
+ }
130
187
  container.appendChild(el);
188
+ this.syncGradientToMiawSubtree();
131
189
  } catch (e) {
132
190
  console.error(e);
133
- } finally {
134
- this.ensureMountedPromise = null;
135
191
  }
136
192
  })();
137
-
138
- return this.ensureMountedPromise;
139
193
  }
140
194
  }
@@ -1,5 +1,5 @@
1
- <template>
1
+ <template lwc:render-mode="light">
2
2
  <div lwc:ref="globalNavContainer" part="container">
3
3
  <dx-skip-nav-link></dx-skip-nav-link>
4
4
  </div>
5
- </template>
5
+ </template>
@@ -4,20 +4,28 @@ import { LightningElement, api } from "lwc";
4
4
  const defaultDomain = "https://developer.salesforce.com";
5
5
  const defaultLocale = "en-us";
6
6
  const defaultHeaderSettingsBasePath = "/c/public/header-settings";
7
- const headerSettingsJsonKeys = ['regionSelectorOverride', 'contactLinksOverride'];
7
+ const headerSettingsJsonKeys = [
8
+ "regionSelectorOverride",
9
+ "contactLinksOverride"
10
+ ];
8
11
 
9
12
  export default class DevExNavigation extends LightningElement {
13
+ static renderMode = "light";
14
+
10
15
  @api locale: string = defaultLocale;
11
16
  @api path: string = defaultHeaderSettingsBasePath;
12
17
  @api domain: string = defaultDomain;
13
18
 
14
19
  async connectedCallback(): Promise<void> {
15
20
  try {
16
- const headerSettingsResponse = await fetch(`${this.domain}${this.path}/${this.locale}.json`, {
17
- headers: {
18
- "Content-Type": "application/json",
19
- },
20
- });
21
+ const headerSettingsResponse = await fetch(
22
+ `${this.domain}${this.path}/${this.locale}.json`,
23
+ {
24
+ headers: {
25
+ "Content-Type": "application/json"
26
+ }
27
+ }
28
+ );
21
29
  if (headerSettingsResponse.ok) {
22
30
  this.createFullNav(await headerSettingsResponse.json());
23
31
  } else {
@@ -59,15 +67,15 @@ export default class DevExNavigation extends LightningElement {
59
67
  private createBarebonesNav(): void {
60
68
  const hgfNav = this.createGlobalNav({
61
69
  origin: "",
62
- contextNavEnabled: "true",
70
+ contextNavEnabled: "true"
63
71
  });
64
72
  const hgfNavContext = this.createContextNav({
65
73
  variation: "static",
66
74
  propertyTitle: {
67
75
  label: "Developers",
68
- url: "/",
76
+ url: "/"
69
77
  },
70
- menuGroup: {},
78
+ menuGroup: {}
71
79
  });
72
80
  const containerEl = this.refs.globalNavContainer as Element;
73
81
  containerEl.appendChild(hgfNav);