@salesforce/ui-bundle-template-app-angular-template-b2e 11.30.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/LICENSE.txt +82 -0
- package/dist/.forceignore +15 -0
- package/dist/.husky/pre-commit +4 -0
- package/dist/.prettierignore +11 -0
- package/dist/.prettierrc +17 -0
- package/dist/CHANGELOG.md +3966 -0
- package/dist/README.md +77 -0
- package/dist/config/project-scratch-def.json +13 -0
- package/dist/eslint.config.js +7 -0
- package/dist/force-app/main/default/applications/angularinternalapp.app-meta.xml +17 -0
- package/dist/force-app/main/default/permissionsets/angularinternalapp_Access.permissionset-meta.xml +13 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/.forceignore +15 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/.postcssrc.json +5 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/.prettierignore +8 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/.prettierrc +12 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/CHANGELOG.md +4 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/README.md +85 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/angular.json +98 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/angularinternalapp.uibundle-meta.xml +8 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/e2e/app.spec.ts +15 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/esbuild/api-version.mjs +17 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/eslint.config.js +60 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/middleware/html.mjs +3 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/middleware/proxy.mjs +12 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/package.json +57 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/playwright.config.ts +25 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/public/favicon.ico +0 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/scripts/rewrite-e2e-assets.mjs +30 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/api/account/account-search.service.ts +196 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/api/account/distinctAccountIndustries.ts +26 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/api/account/distinctAccountTypes.ts +26 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/api/account/getAccountDetail.ts +128 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/api/account/searchAccounts.ts +58 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/api/data-client.service.spec.ts +184 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/api/data-client.service.ts +74 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/app.config.ts +22 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/app.html +1 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/app.routes.ts +31 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/app.spec.ts +18 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/app.ts +15 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/layout/app-layout/app-layout.component.html +52 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/layout/app-layout/app-layout.component.spec.ts +90 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/layout/app-layout/app-layout.component.ts +67 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/_field-size.scss +42 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/alert/alert.component.html +31 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/alert/alert.component.ts +53 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/button/button.component.html +18 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/button/button.component.scss +112 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/button/button.component.ts +57 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/card/card.component.scss +34 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/card/card.component.ts +110 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/collapsible/collapsible.component.html +10 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/collapsible/collapsible.component.ts +26 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/date-picker/date-picker.component.html +25 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/date-picker/date-picker.component.scss +36 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/date-picker/date-picker.component.ts +41 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/date-range-picker/date-range-picker.component.html +34 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/date-range-picker/date-range-picker.component.scss +33 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/date-range-picker/date-range-picker.component.ts +66 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/dialog/dialog.component.html +37 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/dialog/dialog.component.ts +55 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/field/field.component.html +21 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/field/field.component.ts +36 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/field-size.ts +8 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/input/input.component.html +19 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/input/input.component.scss +35 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/input/input.component.ts +36 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/label/label.component.html +3 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/label/label.component.ts +17 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/paginator/paginator.component.html +10 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/paginator/paginator.component.ts +37 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/popover/popover.component.html +41 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/popover/popover.component.ts +40 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/select/select.component.html +24 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/select/select.component.scss +35 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/select/select.component.ts +72 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/separator/separator.component.html +1 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/separator/separator.component.scss +23 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/separator/separator.component.ts +56 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/skeleton/skeleton.component.html +1 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/skeleton/skeleton.component.scss +28 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/skeleton/skeleton.component.ts +24 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/spinner/spinner.component.ts +35 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/agentforce/agentforce-conversation-client/agentforce-conversation-client.component.html +3 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/agentforce/agentforce-conversation-client/agentforce-conversation-client.component.ts +119 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/agentforce/agentforce-embed.service.ts +177 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/active-filters/active-filters.component.html +23 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/active-filters/active-filters.component.ts +78 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/date-filter/date-filter.component.html +18 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/date-filter/date-filter.component.ts +137 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/date-range-filter/date-range-filter.component.html +11 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/date-range-filter/date-range-filter.component.ts +69 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/filter-field-wrapper/filter-field-wrapper.component.html +11 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/filter-field-wrapper/filter-field-wrapper.component.ts +36 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/multi-select-filter/multi-select-filter.component.html +10 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/multi-select-filter/multi-select-filter.component.ts +58 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/numeric-range-filter/numeric-range-filter.component.html +22 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/numeric-range-filter/numeric-range-filter.component.ts +146 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/search-filter/search-filter.component.html +8 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/search-filter/search-filter.component.ts +82 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/select-filter/select-filter.component.html +12 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/select-filter/select-filter.component.ts +65 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/text-filter/text-filter.component.html +12 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/text-filter/text-filter.component.ts +90 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/object-breadcrumb/object-breadcrumb.component.html +55 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/object-breadcrumb/object-breadcrumb.component.ts +40 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/pagination-controls/pagination-controls.component.html +8 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/pagination-controls/pagination-controls.component.ts +61 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/search-bar/search-bar.component.html +59 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/search-bar/search-bar.component.ts +108 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/sort-control/sort-control.component.html +50 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/sort-control/sort-control.component.ts +72 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/object-search-state.service.ts +232 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/utils/debounce.ts +31 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/utils/field-utils.ts +54 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/utils/filter-utils.ts +354 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/utils/index.ts +12 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/utils/sort-utils.ts +46 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/pages/account-detail/account-detail-page.component.html +174 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/pages/account-detail/account-detail-page.component.scss +7 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/pages/account-detail/account-detail-page.component.ts +199 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/pages/account-search/account-search-page.component.html +111 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/pages/account-search/account-search-page.component.ts +217 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/pages/home/home-page.component.html +18 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/pages/home/home-page.component.ts +47 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/pages/home/home.component.html +6 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/pages/home/home.component.spec.ts +23 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/pages/home/home.component.ts +13 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/pages/not-found/not-found.component.html +12 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/pages/not-found/not-found.component.spec.ts +33 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/pages/not-found/not-found.component.ts +15 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/types/conversation.ts +55 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/types/globals.d.ts +13 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/utils/async-data.ts +99 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/index.html +14 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/index.ts +15 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/main.ts +5 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/styles.scss +170 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/theme.scss +39 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/types/sf-globals.d.ts +9 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/tsconfig.app.json +11 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/tsconfig.json +33 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/tsconfig.spec.json +10 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/ui-bundle.json +7 -0
- package/dist/jest.config.js +6 -0
- package/dist/package-lock.json +10066 -0
- package/dist/package.json +46 -0
- package/dist/scripts/apex/hello.apex +10 -0
- package/dist/scripts/gitignore-templates.json +4 -0
- package/dist/scripts/graphql-search.sh +191 -0
- package/dist/scripts/org-setup-config-schema.mjs +103 -0
- package/dist/scripts/org-setup-dev.mjs +87 -0
- package/dist/scripts/org-setup-utils.mjs +369 -0
- package/dist/scripts/org-setup-xml.mjs +182 -0
- package/dist/scripts/org-setup.config.json +9 -0
- package/dist/scripts/org-setup.mjs +1702 -0
- package/dist/scripts/sf-project-setup.mjs +103 -0
- package/dist/scripts/soql/account.soql +6 -0
- package/dist/scripts/validate-org-setup-config.mjs +38 -0
- package/dist/sfdx-project.json +12 -0
- package/package.json +40 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<mat-paginator
|
|
2
|
+
[length]="length()"
|
|
3
|
+
[pageIndex]="pageIndex()"
|
|
4
|
+
[pageSize]="pageSize()"
|
|
5
|
+
[pageSizeOptions]="pageSizeOptions()"
|
|
6
|
+
[hidePageSize]="hidePageSize()"
|
|
7
|
+
[showFirstLastButtons]="showFirstLastButtons()"
|
|
8
|
+
[disabled]="disabled()"
|
|
9
|
+
(page)="page.emit($event)"
|
|
10
|
+
/>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026, Salesforce, Inc.,
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* For full license text, see the LICENSE.txt file
|
|
5
|
+
*/
|
|
6
|
+
import { booleanAttribute, ChangeDetectionStrategy, Component, input, output } from '@angular/core';
|
|
7
|
+
import { MatPaginator, type PageEvent } from '@angular/material/paginator';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Thin wrapper over Material's `mat-paginator`. Presentation only — the host
|
|
11
|
+
* decides what each page change means by listening to `(page)`.
|
|
12
|
+
*/
|
|
13
|
+
@Component({
|
|
14
|
+
selector: 'app-paginator',
|
|
15
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
16
|
+
imports: [MatPaginator],
|
|
17
|
+
templateUrl: './paginator.component.html',
|
|
18
|
+
})
|
|
19
|
+
export class PaginatorComponent {
|
|
20
|
+
/** Total item count; Material derives the page count as `ceil(length / pageSize)`. */
|
|
21
|
+
readonly length = input<number>(0);
|
|
22
|
+
/** Zero-based index of the current page. */
|
|
23
|
+
readonly pageIndex = input<number>(0);
|
|
24
|
+
/** Items shown per page. */
|
|
25
|
+
readonly pageSize = input<number>(10);
|
|
26
|
+
/** Selectable page sizes; omit/empty to hide the size selector. */
|
|
27
|
+
readonly pageSizeOptions = input<readonly number[]>([]);
|
|
28
|
+
/** Disable navigation buttons and the size select (e.g. while loading). */
|
|
29
|
+
readonly disabled = input(false, { transform: booleanAttribute });
|
|
30
|
+
/** Hide the "Items per page" selector. */
|
|
31
|
+
readonly hidePageSize = input(false, { transform: booleanAttribute });
|
|
32
|
+
/** Show the first / last page jump buttons. */
|
|
33
|
+
readonly showFirstLastButtons = input(false, { transform: booleanAttribute });
|
|
34
|
+
|
|
35
|
+
/** Emitted when the user changes page or page size. */
|
|
36
|
+
readonly page = output<PageEvent>();
|
|
37
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<span
|
|
2
|
+
cdkOverlayOrigin
|
|
3
|
+
#origin="cdkOverlayOrigin"
|
|
4
|
+
role="button"
|
|
5
|
+
tabindex="0"
|
|
6
|
+
[attr.aria-expanded]="open()"
|
|
7
|
+
(click)="toggle()"
|
|
8
|
+
(keydown.enter)="toggle()"
|
|
9
|
+
(keydown.space)="$event.preventDefault(); toggle()"
|
|
10
|
+
>
|
|
11
|
+
<ng-content select="[trigger]" />
|
|
12
|
+
</span>
|
|
13
|
+
|
|
14
|
+
<ng-template
|
|
15
|
+
cdkConnectedOverlay
|
|
16
|
+
[cdkConnectedOverlayOrigin]="origin"
|
|
17
|
+
[cdkConnectedOverlayOpen]="open()"
|
|
18
|
+
[cdkConnectedOverlayHasBackdrop]="true"
|
|
19
|
+
cdkConnectedOverlayBackdropClass="cdk-overlay-transparent-backdrop"
|
|
20
|
+
[cdkConnectedOverlayOffsetY]="sideOffset()"
|
|
21
|
+
[cdkConnectedOverlayPositions]="[
|
|
22
|
+
{
|
|
23
|
+
originX: align(),
|
|
24
|
+
originY: 'bottom',
|
|
25
|
+
overlayX: align(),
|
|
26
|
+
overlayY: 'top',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
originX: align(),
|
|
30
|
+
originY: 'top',
|
|
31
|
+
overlayX: align(),
|
|
32
|
+
overlayY: 'bottom',
|
|
33
|
+
},
|
|
34
|
+
]"
|
|
35
|
+
(backdropClick)="close()"
|
|
36
|
+
(detach)="close()"
|
|
37
|
+
>
|
|
38
|
+
<div class="bg-white text-sm rounded-lg shadow-md ring-1 ring-black/10 outline-none">
|
|
39
|
+
<ng-content />
|
|
40
|
+
</div>
|
|
41
|
+
</ng-template>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026, Salesforce, Inc.,
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* For full license text, see the LICENSE.txt file
|
|
5
|
+
*/
|
|
6
|
+
import { CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay';
|
|
7
|
+
import { ChangeDetectionStrategy, Component, input, model } from '@angular/core';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Popover backed by CDK Overlay. Slots: `[trigger]` (anchor, toggles the
|
|
11
|
+
* popover) and default (body). `open` is a two-way model; a backdrop click
|
|
12
|
+
* closes it.
|
|
13
|
+
*/
|
|
14
|
+
@Component({
|
|
15
|
+
selector: 'app-popover',
|
|
16
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
17
|
+
imports: [CdkConnectedOverlay, CdkOverlayOrigin],
|
|
18
|
+
templateUrl: './popover.component.html',
|
|
19
|
+
})
|
|
20
|
+
export class PopoverComponent {
|
|
21
|
+
/**
|
|
22
|
+
* Two-way bindable open state. Supports `[(open)]`, a plain `[open]`
|
|
23
|
+
* input, or listening to the auto-generated `(openChange)` event.
|
|
24
|
+
*/
|
|
25
|
+
readonly open = model<boolean>(false);
|
|
26
|
+
|
|
27
|
+
/** Panel alignment relative to the trigger. Defaults to below-start. */
|
|
28
|
+
readonly align = input<'start' | 'center' | 'end'>('start');
|
|
29
|
+
|
|
30
|
+
/** Vertical gap between the trigger and the panel, in px. */
|
|
31
|
+
readonly sideOffset = input<number>(4);
|
|
32
|
+
|
|
33
|
+
toggle(): void {
|
|
34
|
+
this.open.set(!this.open());
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
close(): void {
|
|
38
|
+
this.open.set(false);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<mat-form-field
|
|
2
|
+
class="w-full"
|
|
3
|
+
[class]="'size-' + size()"
|
|
4
|
+
[appearance]="appearance()"
|
|
5
|
+
subscriptSizing="dynamic"
|
|
6
|
+
>
|
|
7
|
+
@if (label()) {
|
|
8
|
+
<mat-label>{{ label() }}</mat-label>
|
|
9
|
+
}
|
|
10
|
+
<mat-select
|
|
11
|
+
[multiple]="multiple()"
|
|
12
|
+
[placeholder]="placeholder()"
|
|
13
|
+
[disabled]="disabled()"
|
|
14
|
+
[ngModel]="selection()"
|
|
15
|
+
(ngModelChange)="onSelectionChange($event)"
|
|
16
|
+
>
|
|
17
|
+
@if (multiple()) {
|
|
18
|
+
<mat-select-trigger>{{ multiTriggerLabel() }}</mat-select-trigger>
|
|
19
|
+
}
|
|
20
|
+
@for (option of options(); track option.value) {
|
|
21
|
+
<mat-option [value]="option.value">{{ option.label }}</mat-option>
|
|
22
|
+
}
|
|
23
|
+
</mat-select>
|
|
24
|
+
</mat-form-field>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026, Salesforce, Inc.,
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* For full license text, see the LICENSE.txt file
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
@use '../field-size' as field-size;
|
|
8
|
+
|
|
9
|
+
/*
|
|
10
|
+
* Form-field-specific structural styling. Height comes from the `size` input
|
|
11
|
+
* (see field-size.scss); colour comes from the --mat-sys-* remap (styles.css).
|
|
12
|
+
* Here we only: give the outline our design-token radius, emit the size
|
|
13
|
+
* classes, and collapse the empty hint/error subscript row.
|
|
14
|
+
*/
|
|
15
|
+
@include field-size.sizes;
|
|
16
|
+
|
|
17
|
+
:host {
|
|
18
|
+
display: block;
|
|
19
|
+
/*
|
|
20
|
+
* Allow the host to shrink below the mat-form-field's intrinsic width when
|
|
21
|
+
* used as a flex item (e.g. the operator select beside a date picker in a
|
|
22
|
+
* date filter row). Without this, the default `min-width: auto` on a flex
|
|
23
|
+
* item keeps each field at its content width and the row overflows.
|
|
24
|
+
*/
|
|
25
|
+
min-width: 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.mat-mdc-form-field {
|
|
29
|
+
--mdc-outlined-text-field-container-shape: var(--radius-md);
|
|
30
|
+
font-size: 0.875rem; /* text-sm, matches the React inputs */
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.mat-mdc-form-field-subscript-wrapper {
|
|
34
|
+
display: none;
|
|
35
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026, Salesforce, Inc.,
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* For full license text, see the LICENSE.txt file
|
|
5
|
+
*/
|
|
6
|
+
import {
|
|
7
|
+
booleanAttribute,
|
|
8
|
+
ChangeDetectionStrategy,
|
|
9
|
+
Component,
|
|
10
|
+
computed,
|
|
11
|
+
input,
|
|
12
|
+
model,
|
|
13
|
+
} from '@angular/core';
|
|
14
|
+
import { FormsModule } from '@angular/forms';
|
|
15
|
+
import { MatFormFieldModule, type MatFormFieldAppearance } from '@angular/material/form-field';
|
|
16
|
+
import { MatSelectModule } from '@angular/material/select';
|
|
17
|
+
import type { AppFieldSize } from '../field-size';
|
|
18
|
+
|
|
19
|
+
/** Shape of an option rendered in the dropdown. */
|
|
20
|
+
export interface AppSelectOption {
|
|
21
|
+
value: string;
|
|
22
|
+
label: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Thin wrapper over Material's `mat-form-field` + `mat-select`. */
|
|
26
|
+
@Component({
|
|
27
|
+
selector: 'app-select',
|
|
28
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
29
|
+
imports: [FormsModule, MatFormFieldModule, MatSelectModule],
|
|
30
|
+
templateUrl: './select.component.html',
|
|
31
|
+
styleUrl: './select.component.scss',
|
|
32
|
+
})
|
|
33
|
+
export class SelectComponent {
|
|
34
|
+
/** Two-way bindable single-select value. Ignored when `multiple` is set. */
|
|
35
|
+
readonly value = model<string>('');
|
|
36
|
+
|
|
37
|
+
/** Two-way bindable multi-select values. Used only when `multiple` is `true`. */
|
|
38
|
+
readonly values = model<readonly string[]>([]);
|
|
39
|
+
|
|
40
|
+
/** Render checkbox options and allow more than one selection. */
|
|
41
|
+
readonly multiple = input(false, { transform: booleanAttribute });
|
|
42
|
+
|
|
43
|
+
readonly options = input<readonly AppSelectOption[]>([]);
|
|
44
|
+
readonly placeholder = input<string>('');
|
|
45
|
+
readonly label = input<string>('');
|
|
46
|
+
readonly disabled = input<boolean>(false);
|
|
47
|
+
readonly appearance = input<MatFormFieldAppearance>('outline');
|
|
48
|
+
/** Field height: `sm` = 24px, `default` = 32px, `lg` = 40px. */
|
|
49
|
+
readonly size = input<AppFieldSize>('default');
|
|
50
|
+
|
|
51
|
+
/** Value handed to `mat-select`: the `values` array when `multiple`, else `value`. */
|
|
52
|
+
protected readonly selection = computed(() => (this.multiple() ? this.values() : this.value()));
|
|
53
|
+
|
|
54
|
+
/** Multi-select trigger summary: the sole option's label, else "N selected". */
|
|
55
|
+
protected readonly multiTriggerLabel = computed(() => {
|
|
56
|
+
const selected = this.values();
|
|
57
|
+
if (selected.length === 1) {
|
|
58
|
+
const only = selected[0];
|
|
59
|
+
return this.options().find((o) => o.value === only)?.label ?? only;
|
|
60
|
+
}
|
|
61
|
+
return `${selected.length} selected`;
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
/** Single change handler — routes to the right model based on `multiple`. */
|
|
65
|
+
protected onSelectionChange(next: string | string[]): void {
|
|
66
|
+
if (this.multiple()) {
|
|
67
|
+
this.values.set((next as string[]) ?? []);
|
|
68
|
+
} else {
|
|
69
|
+
this.value.set((next as string) ?? '');
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<mat-divider role="presentation" [vertical]="isVertical()" [inset]="inset()" />
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026, Salesforce, Inc.,
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* For full license text, see the LICENSE.txt file
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/*
|
|
8
|
+
* Material's `mat-divider` draws a full-height border for the vertical variant,
|
|
9
|
+
* so its element must fill the host. The host itself carries `self-stretch`
|
|
10
|
+
* (see component `hostClass`) to take the flex row's height; here we make the
|
|
11
|
+
* inner divider fill that height. Horizontal needs nothing extra — the divider
|
|
12
|
+
* is already `display:block; width:100%`.
|
|
13
|
+
*/
|
|
14
|
+
:host {
|
|
15
|
+
// A vertical divider is a zero-width line; keep it out of flex growth math.
|
|
16
|
+
&[data-orientation='vertical'] {
|
|
17
|
+
display: flex;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.mat-divider-vertical {
|
|
22
|
+
height: 100%;
|
|
23
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026, Salesforce, Inc.,
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* For full license text, see the LICENSE.txt file
|
|
5
|
+
*/
|
|
6
|
+
import {
|
|
7
|
+
booleanAttribute,
|
|
8
|
+
ChangeDetectionStrategy,
|
|
9
|
+
Component,
|
|
10
|
+
computed,
|
|
11
|
+
input,
|
|
12
|
+
} from '@angular/core';
|
|
13
|
+
import { MatDivider } from '@angular/material/divider';
|
|
14
|
+
|
|
15
|
+
/** Layout axis of the separator line. */
|
|
16
|
+
export type AppSeparatorOrientation = 'horizontal' | 'vertical';
|
|
17
|
+
|
|
18
|
+
const BASE_CLASSES = 'shrink-0';
|
|
19
|
+
const ORIENTATION_CLASSES: Record<AppSeparatorOrientation, string> = {
|
|
20
|
+
horizontal: 'block w-full',
|
|
21
|
+
vertical: 'self-stretch',
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Divider built on Material's `mat-divider`. `decorative` (default) hides the
|
|
26
|
+
* host from assistive tech (`role="none"`); when false it exposes
|
|
27
|
+
* `role="separator"` + `aria-orientation`. The inner `mat-divider` is marked
|
|
28
|
+
* `role="presentation"` so it never announces a duplicate separator.
|
|
29
|
+
*/
|
|
30
|
+
@Component({
|
|
31
|
+
selector: 'app-separator',
|
|
32
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
33
|
+
imports: [MatDivider],
|
|
34
|
+
templateUrl: './separator.component.html',
|
|
35
|
+
styleUrl: './separator.component.scss',
|
|
36
|
+
host: {
|
|
37
|
+
'data-slot': 'separator',
|
|
38
|
+
'[attr.data-orientation]': 'orientation()',
|
|
39
|
+
'[attr.role]': "decorative() ? 'none' : 'separator'",
|
|
40
|
+
'[attr.aria-orientation]':
|
|
41
|
+
"decorative() ? null : (orientation() === 'vertical' ? 'vertical' : 'horizontal')",
|
|
42
|
+
'[class]': 'hostClass()',
|
|
43
|
+
},
|
|
44
|
+
})
|
|
45
|
+
export class SeparatorComponent {
|
|
46
|
+
readonly orientation = input<AppSeparatorOrientation>('horizontal');
|
|
47
|
+
readonly decorative = input(true, { transform: booleanAttribute });
|
|
48
|
+
/** Adds Material's horizontal inset margin so the line doesn't run edge-to-edge. */
|
|
49
|
+
readonly inset = input(false, { transform: booleanAttribute });
|
|
50
|
+
|
|
51
|
+
protected readonly isVertical = computed(() => this.orientation() === 'vertical');
|
|
52
|
+
|
|
53
|
+
protected readonly hostClass = computed(
|
|
54
|
+
() => `${BASE_CLASSES} ${ORIENTATION_CLASSES[this.orientation()]}`,
|
|
55
|
+
);
|
|
56
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<ng-content />
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026, Salesforce, Inc.,
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* For full license text, see the LICENSE.txt file
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/*
|
|
8
|
+
* The skeleton is a block by default so call sites only need to supply a width
|
|
9
|
+
* and height (`h-4 w-32`) — no `block` utility to repeat. The pulse lives here
|
|
10
|
+
* (rather than Tailwind's `animate-pulse`) so it can be switched off for users
|
|
11
|
+
* who ask for reduced motion.
|
|
12
|
+
*/
|
|
13
|
+
:host {
|
|
14
|
+
display: block;
|
|
15
|
+
animation: app-skeleton-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@keyframes app-skeleton-pulse {
|
|
19
|
+
50% {
|
|
20
|
+
opacity: 0.5;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@media (prefers-reduced-motion: reduce) {
|
|
25
|
+
:host {
|
|
26
|
+
animation: none;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026, Salesforce, Inc.,
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* For full license text, see the LICENSE.txt file
|
|
5
|
+
*/
|
|
6
|
+
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Loading skeleton — a pulsing block sized by host `class` utilities (e.g.
|
|
10
|
+
* `class="h-4 w-32"`); it has no intrinsic size, so always set width/height.
|
|
11
|
+
* `aria-hidden`, so announce loading via the container's `aria-busy`.
|
|
12
|
+
*/
|
|
13
|
+
@Component({
|
|
14
|
+
selector: 'app-skeleton',
|
|
15
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
16
|
+
templateUrl: './skeleton.component.html',
|
|
17
|
+
styleUrl: './skeleton.component.scss',
|
|
18
|
+
host: {
|
|
19
|
+
'data-slot': 'skeleton',
|
|
20
|
+
'aria-hidden': 'true',
|
|
21
|
+
class: 'bg-accent rounded-md',
|
|
22
|
+
},
|
|
23
|
+
})
|
|
24
|
+
export class SkeletonComponent {}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026, Salesforce, Inc.,
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* For full license text, see the LICENSE.txt file
|
|
5
|
+
*/
|
|
6
|
+
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
|
|
7
|
+
import { MatProgressSpinnerModule, ProgressSpinnerMode } from '@angular/material/progress-spinner';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Thin wrapper over Material's `mat-progress-spinner`. Defaults to an
|
|
11
|
+
* indeterminate 24px spinner. `ariaLabel` names the `role="progressbar"`.
|
|
12
|
+
*/
|
|
13
|
+
@Component({
|
|
14
|
+
selector: 'app-spinner',
|
|
15
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
16
|
+
imports: [MatProgressSpinnerModule],
|
|
17
|
+
template: `
|
|
18
|
+
<mat-progress-spinner
|
|
19
|
+
[mode]="mode()"
|
|
20
|
+
[diameter]="diameter()"
|
|
21
|
+
[value]="value()"
|
|
22
|
+
[attr.aria-label]="ariaLabel()"
|
|
23
|
+
/>
|
|
24
|
+
`,
|
|
25
|
+
})
|
|
26
|
+
export class SpinnerComponent {
|
|
27
|
+
readonly diameter = input<number>(24);
|
|
28
|
+
readonly mode = input<ProgressSpinnerMode>('indeterminate');
|
|
29
|
+
|
|
30
|
+
/** Progress value (0–100) used only when `mode` is `determinate`. */
|
|
31
|
+
readonly value = input<number>(0);
|
|
32
|
+
|
|
33
|
+
/** Accessible name announced by assistive tech. */
|
|
34
|
+
readonly ariaLabel = input<string>('Loading', { alias: 'aria-label' });
|
|
35
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026, Salesforce, Inc.,
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* For full license text, see the LICENSE.txt file
|
|
5
|
+
*/
|
|
6
|
+
import {
|
|
7
|
+
afterNextRender,
|
|
8
|
+
ChangeDetectionStrategy,
|
|
9
|
+
Component,
|
|
10
|
+
computed,
|
|
11
|
+
ElementRef,
|
|
12
|
+
inject,
|
|
13
|
+
input,
|
|
14
|
+
viewChild,
|
|
15
|
+
} from "@angular/core";
|
|
16
|
+
import type { AgentforceClientConfig } from "@salesforce/agentforce-conversation-client";
|
|
17
|
+
import type {
|
|
18
|
+
AgentforceErrorHandler,
|
|
19
|
+
AgentforceReadyHandler,
|
|
20
|
+
StyleTokens,
|
|
21
|
+
} from "../../../types/conversation";
|
|
22
|
+
import { AgentforceEmbedService } from "../agentforce-embed.service";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Angular component that embeds the Agentforce Conversation Client (copilot /
|
|
26
|
+
* agent UI) via Lightning Out. The faithful port of the React
|
|
27
|
+
* `AgentforceConversationClient`: flat inputs are normalized into an
|
|
28
|
+
* `AgentforceClientConfig` (a `computed()`, the analogue of the React `useMemo`)
|
|
29
|
+
* and handed to {@link AgentforceEmbedService}, which owns the one-time embed
|
|
30
|
+
* (the analogue of the React window-singleton).
|
|
31
|
+
*
|
|
32
|
+
* Rendering mode follows `inline`: inline embeds render into this component's
|
|
33
|
+
* own `<div #host>`, floating embeds attach to a shared body-level host and this
|
|
34
|
+
* component renders nothing. Requires a valid Salesforce session for the org;
|
|
35
|
+
* config is passed through to the embed client as-is.
|
|
36
|
+
*/
|
|
37
|
+
@Component({
|
|
38
|
+
selector: "app-agentforce-conversation-client",
|
|
39
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
40
|
+
templateUrl: "./agentforce-conversation-client.component.html",
|
|
41
|
+
})
|
|
42
|
+
export class AgentforceConversationClientComponent {
|
|
43
|
+
private readonly embedService = inject(AgentforceEmbedService);
|
|
44
|
+
|
|
45
|
+
/** Required: id of the agent to load. */
|
|
46
|
+
readonly agentId = input.required<string>();
|
|
47
|
+
/** Display name for the agent shown in the chat header. */
|
|
48
|
+
readonly agentLabel = input<string>();
|
|
49
|
+
/** If true, renders inline. If omitted/false, renders floating. */
|
|
50
|
+
readonly inline = input<boolean>(false);
|
|
51
|
+
/** Show/hide chat header. Defaults to true for floating; can only be set for inline mode. */
|
|
52
|
+
readonly headerEnabled = input<boolean>();
|
|
53
|
+
/** Show/hide agent icon in the header. */
|
|
54
|
+
readonly showHeaderIcon = input<boolean>();
|
|
55
|
+
/** Inline width. */
|
|
56
|
+
readonly width = input<string | number>();
|
|
57
|
+
/** Inline height. */
|
|
58
|
+
readonly height = input<string | number>();
|
|
59
|
+
/** Theme overrides for the chat UI. */
|
|
60
|
+
readonly styleTokens = input<StyleTokens>();
|
|
61
|
+
readonly isFileBased = input<boolean>();
|
|
62
|
+
/** Optional. Resolved internally when omitted (frontdoor in dev, org URL in prod). */
|
|
63
|
+
readonly salesforceOrigin = input<string>();
|
|
64
|
+
/** Optional. Resolved internally in dev via /__lo/frontdoor when omitted. */
|
|
65
|
+
readonly frontdoorUrl = input<string>();
|
|
66
|
+
/** Callback invoked when the Lightning Out application is ready. */
|
|
67
|
+
readonly onReady = input<AgentforceReadyHandler>();
|
|
68
|
+
/** Callback invoked when a Lightning Out error occurs. */
|
|
69
|
+
readonly onError = input<AgentforceErrorHandler>();
|
|
70
|
+
|
|
71
|
+
/** Inline render target — present only when `inline()` is true. */
|
|
72
|
+
private readonly host = viewChild<ElementRef<HTMLDivElement>>("host");
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Normalized embed config built from the flat inputs. Mirrors the React
|
|
76
|
+
* `useMemo`: undefined inputs are omitted so client defaults apply, and the
|
|
77
|
+
* `renderingConfig.mode` derives from `inline`. `showAvatar` and `channel`
|
|
78
|
+
* are fixed to match the React feature.
|
|
79
|
+
*/
|
|
80
|
+
protected readonly config = computed<AgentforceClientConfig>(() => {
|
|
81
|
+
const renderingConfig: NonNullable<AgentforceClientConfig["renderingConfig"]> = {
|
|
82
|
+
mode: this.inline() ? "inline" : "floating",
|
|
83
|
+
...(this.headerEnabled() !== undefined && { headerEnabled: this.headerEnabled() }),
|
|
84
|
+
...(this.showHeaderIcon() !== undefined && { showHeaderIcon: this.showHeaderIcon() }),
|
|
85
|
+
showAvatar: false,
|
|
86
|
+
...(this.width() !== undefined && { width: this.width() }),
|
|
87
|
+
...(this.height() !== undefined && { height: this.height() }),
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
return {
|
|
91
|
+
agentId: this.agentId(),
|
|
92
|
+
...(this.agentLabel() !== undefined && { agentLabel: this.agentLabel() }),
|
|
93
|
+
...(this.styleTokens() !== undefined && { styleTokens: this.styleTokens() }),
|
|
94
|
+
...(this.isFileBased() !== undefined && { isFileBased: this.isFileBased() }),
|
|
95
|
+
renderingConfig,
|
|
96
|
+
channel: "Vibes",
|
|
97
|
+
};
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
/** Whether the chat should render inline (drives the host `<div>`). */
|
|
101
|
+
protected readonly isInline = computed(() => this.config().renderingConfig?.mode === "inline");
|
|
102
|
+
|
|
103
|
+
constructor() {
|
|
104
|
+
// Embed after the view (and any inline host `<div>`) exists in the DOM —
|
|
105
|
+
// the analogue of the React `useEffect`. The service guards against
|
|
106
|
+
// double-embedding, so running once after render is sufficient.
|
|
107
|
+
afterNextRender(() => {
|
|
108
|
+
this.embedService.embed(
|
|
109
|
+
this.config(),
|
|
110
|
+
{
|
|
111
|
+
salesforceOrigin: this.salesforceOrigin(),
|
|
112
|
+
frontdoorUrl: this.frontdoorUrl(),
|
|
113
|
+
},
|
|
114
|
+
this.host()?.nativeElement ?? null,
|
|
115
|
+
{ onReady: this.onReady(), onError: this.onError() },
|
|
116
|
+
);
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|