@salesforce/templates 66.11.1 → 66.12.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/lib/generators/projectGenerator.js +4 -1
- package/lib/generators/projectGenerator.js.map +1 -1
- package/lib/templates/project/angularextapp/.forceignore +15 -0
- package/lib/templates/project/angularextapp/.husky/pre-commit +4 -0
- package/lib/templates/project/angularextapp/.prettierignore +11 -0
- package/lib/templates/project/angularextapp/.prettierrc +17 -0
- package/lib/templates/project/angularextapp/CHANGELOG.md +4086 -0
- package/lib/templates/project/angularextapp/README.md +77 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_d_/_s_/angularextapp1/angularextapp1.digitalExperience-meta.xml +11 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_d_/_s_/angularextapp1/sfdc_cms__site/angularextapp1/_meta.json +5 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_d_/_s_/angularextapp1/sfdc_cms__site/angularextapp1/content.json +10 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_dc_/angularextapp1.digitalExperienceConfig-meta.xml +8 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/.forceignore +15 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/.postcssrc.json +5 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/.prettierignore +8 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/.prettierrc +12 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/CHANGELOG.md +4 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/README.md +85 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/angular.json +101 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/angularextapp.uibundle-meta.xml +8 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/e2e/app.spec.ts +15 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/esbuild/api-version.mjs +17 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/eslint.config.js +60 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/middleware/html.mjs +3 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/middleware/proxy.mjs +12 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/package-lock.json +13600 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/package.json +56 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/playwright.config.ts +25 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/public/favicon.ico +0 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/scripts/rewrite-e2e-assets.mjs +30 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/api/account/account-search.service.ts +196 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/api/account/distinctAccountIndustries.ts +26 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/api/account/distinctAccountTypes.ts +26 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/api/account/getAccountDetail.ts +128 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/api/account/searchAccounts.ts +58 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/api/data-client.service.spec.ts +184 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/api/data-client.service.ts +74 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/api/user-profile.service.ts +126 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/app.config.ts +22 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/app.html +1 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/app.routes.ts +77 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/app.spec.ts +18 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/app.ts +15 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/layout/app-layout/app-layout.html +53 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/layout/app-layout/app-layout.spec.ts +89 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/layout/app-layout/app-layout.ts +81 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/_field-size.scss +42 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/alert/alert.html +31 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/alert/alert.ts +53 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/button/button.html +18 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/button/button.scss +112 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/button/button.ts +57 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/card/card.scss +34 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/card/card.ts +110 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/collapsible/collapsible.html +10 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/collapsible/collapsible.ts +26 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-picker/date-picker.html +25 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-picker/date-picker.scss +36 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-picker/date-picker.ts +41 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-range-picker/date-range-picker.html +34 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-range-picker/date-range-picker.scss +33 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-range-picker/date-range-picker.ts +66 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/dialog/dialog.html +37 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/dialog/dialog.ts +55 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/field/field.html +21 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/field/field.ts +36 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/field-size.ts +8 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/input/input.html +19 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/input/input.scss +35 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/input/input.ts +36 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/label/label.html +3 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/label/label.ts +17 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/paginator/paginator.html +10 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/paginator/paginator.ts +37 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/popover/popover.html +41 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/popover/popover.ts +40 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/select/select.html +24 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/select/select.scss +35 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/select/select.ts +72 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/separator/separator.html +1 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/separator/separator.scss +23 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/separator/separator.ts +56 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/skeleton/skeleton.html +1 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/skeleton/skeleton.scss +28 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/skeleton/skeleton.ts +24 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/spinner/spinner.ts +35 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/auth/auth.guard.ts +50 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/auth/auth.service.ts +126 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/auth-form/auth-form.html +34 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/auth-form/auth-form.ts +94 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/auth-layout/auth-layout.html +2 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/auth-layout/auth-layout.ts +30 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/card-layout/card-layout.html +16 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/card-layout/card-layout.ts +40 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/config/authentication.config.ts +75 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/footer-link/footer-link.html +9 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/footer-link/footer-link.ts +26 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/menu/auth-menu/auth-menu.html +26 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/menu/auth-menu/auth-menu.ts +46 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/reactive-form-page.base.ts +50 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/session/session.html +55 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/session/session.ts +205 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/status-alert/status-alert.html +5 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/status-alert/status-alert.ts +52 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/submit-button/submit-button.html +5 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/submit-button/submit-button.scss +17 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/submit-button/submit-button.ts +35 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/utils/auth-helpers.ts +68 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/utils/auth-validators.ts +72 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/utils/helpers.ts +85 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/utils/session-time-servlet.ts +130 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/utils/session-timeout.config.ts +83 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/utils/session-timeout.service.ts +201 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/breadcrumb/breadcrumb.html +54 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/breadcrumb/breadcrumb.ts +40 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/active-filters.html +23 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/active-filters.ts +78 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/date-filter.html +18 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/date-filter.ts +137 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/date-range-filter.html +11 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/date-range-filter.ts +69 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/filter-field-wrapper.html +11 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/filter-field-wrapper.ts +36 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/multi-select-filter.html +10 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/multi-select-filter.ts +58 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/numeric-range-filter.html +22 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/numeric-range-filter.ts +146 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/search-filter.html +8 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/search-filter.ts +82 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/select-filter.html +12 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/select-filter.ts +65 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/text-filter.html +12 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/text-filter.ts +90 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/object-search-state.service.ts +232 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/pagination/pagination.html +8 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/pagination/pagination.ts +61 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/search-bar/search-bar.html +59 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/search-bar/search-bar.ts +108 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/sort-control/sort-control.html +50 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/sort-control/sort-control.ts +72 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/debounce.ts +31 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/field-utils.ts +54 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/filter-utils.ts +354 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/index.ts +12 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/sort-utils.ts +46 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/account-detail/account-detail-page.html +164 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/account-detail/account-detail-page.scss +7 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/account-detail/account-detail-page.ts +196 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/account-search/account-search-page.html +111 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/account-search/account-search-page.ts +217 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/change-password/change-password-page.html +68 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/change-password/change-password-page.ts +82 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/forgot-password/forgot-password-page.html +35 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/forgot-password/forgot-password-page.ts +87 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/home/home-page.html +18 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/home/home-page.ts +47 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/home/home.html +6 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/home/home.spec.ts +23 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/home/home.ts +13 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/login/login-page.html +47 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/login/login-page.ts +89 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/not-found/not-found.html +12 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/not-found/not-found.spec.ts +33 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/not-found/not-found.ts +15 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/profile/profile-page.html +116 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/profile/profile-page.ts +194 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/register/register-page.html +80 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/register/register-page.ts +93 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/reset-password/reset-password-page.html +60 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/reset-password/reset-password-page.ts +96 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/utils/async-data.ts +99 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/index.html +14 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/main.ts +5 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/styles.scss +170 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/theme.scss +39 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/types/sf-globals.d.ts +9 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/tsconfig.app.json +11 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/tsconfig.json +33 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/tsconfig.spec.json +10 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/ui-bundle.json +7 -0
- package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleAuthUtils.cls +68 -0
- package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleAuthUtils.cls-meta.xml +5 -0
- package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleChangePassword.cls +77 -0
- package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleChangePassword.cls-meta.xml +5 -0
- package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleForgotPassword.cls +71 -0
- package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleForgotPassword.cls-meta.xml +5 -0
- package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleLogin.cls +105 -0
- package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleLogin.cls-meta.xml +5 -0
- package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleRegistration.cls +162 -0
- package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleRegistration.cls-meta.xml +5 -0
- package/lib/templates/project/angularextapp/_p_/_m_/networks/angularextapp.network-meta.xml +60 -0
- package/lib/templates/project/angularextapp/_p_/_m_/package.xml +24 -0
- package/lib/templates/project/angularextapp/_p_/_m_/permissionsets/angularextapp_Guest_User_Api_Access.permissionset-meta.xml +9 -0
- package/lib/templates/project/angularextapp/_p_/_m_/sites/angularextapp.site-meta.xml +31 -0
- package/lib/templates/project/angularextapp/config/project-scratch-def.json +13 -0
- package/lib/templates/project/angularextapp/eslint.config.js +7 -0
- package/lib/templates/project/angularextapp/jest.config.js +6 -0
- package/lib/templates/project/angularextapp/package.json +46 -0
- package/lib/templates/project/angularextapp/scripts/apex/hello.apex +10 -0
- package/lib/templates/project/angularextapp/scripts/gitignore-templates.json +4 -0
- package/lib/templates/project/angularextapp/scripts/graphql-search.sh +191 -0
- package/lib/templates/project/angularextapp/scripts/org-setup-config-schema.mjs +103 -0
- package/lib/templates/project/angularextapp/scripts/org-setup-dev.mjs +87 -0
- package/lib/templates/project/angularextapp/scripts/org-setup-utils.mjs +369 -0
- package/lib/templates/project/angularextapp/scripts/org-setup-xml.mjs +182 -0
- package/lib/templates/project/angularextapp/scripts/org-setup.config.json +9 -0
- package/lib/templates/project/angularextapp/scripts/org-setup.mjs +1702 -0
- package/lib/templates/project/angularextapp/scripts/sf-project-setup.mjs +103 -0
- package/lib/templates/project/angularextapp/scripts/soql/account.soql +6 -0
- package/lib/templates/project/angularextapp/scripts/validate-org-setup-config.mjs +38 -0
- package/lib/templates/project/angularextapp/sfdx-project.json +12 -0
- package/lib/templates/project/angularintapp/.forceignore +15 -0
- package/lib/templates/project/angularintapp/.husky/pre-commit +4 -0
- package/lib/templates/project/angularintapp/.prettierignore +11 -0
- package/lib/templates/project/angularintapp/.prettierrc +17 -0
- package/lib/templates/project/angularintapp/CHANGELOG.md +4086 -0
- package/lib/templates/project/angularintapp/README.md +77 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/.forceignore +15 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/.postcssrc.json +5 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/.prettierignore +8 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/.prettierrc +12 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/CHANGELOG.md +4 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/README.md +85 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/angular.json +101 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/angularintapp.uibundle-meta.xml +8 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/e2e/app.spec.ts +15 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/esbuild/api-version.mjs +17 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/eslint.config.js +60 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/middleware/html.mjs +3 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/middleware/proxy.mjs +12 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/package-lock.json +13619 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/package.json +57 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/playwright.config.ts +25 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/public/favicon.ico +0 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/scripts/rewrite-e2e-assets.mjs +30 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/api/account/account-search.service.ts +196 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/api/account/distinctAccountIndustries.ts +26 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/api/account/distinctAccountTypes.ts +26 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/api/account/getAccountDetail.ts +128 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/api/account/searchAccounts.ts +58 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/api/data-client.service.spec.ts +184 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/api/data-client.service.ts +74 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/app.config.ts +22 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/app.html +1 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/app.routes.ts +31 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/app.spec.ts +18 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/app.ts +15 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/layout/app-layout/app-layout.html +52 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/layout/app-layout/app-layout.spec.ts +90 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/layout/app-layout/app-layout.ts +67 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/_field-size.scss +42 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/alert/alert.html +31 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/alert/alert.ts +53 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/button/button.html +18 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/button/button.scss +112 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/button/button.ts +57 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/card/card.scss +34 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/card/card.ts +110 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/collapsible/collapsible.html +10 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/collapsible/collapsible.ts +26 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-picker/date-picker.html +25 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-picker/date-picker.scss +36 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-picker/date-picker.ts +41 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-range-picker/date-range-picker.html +34 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-range-picker/date-range-picker.scss +33 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-range-picker/date-range-picker.ts +66 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/dialog/dialog.html +37 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/dialog/dialog.ts +55 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/field/field.html +21 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/field/field.ts +36 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/field-size.ts +8 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/input/input.html +19 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/input/input.scss +35 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/input/input.ts +36 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/label/label.html +3 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/label/label.ts +17 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/paginator/paginator.html +10 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/paginator/paginator.ts +37 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/popover/popover.html +41 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/popover/popover.ts +40 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/select/select.html +24 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/select/select.scss +35 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/select/select.ts +72 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/separator/separator.html +1 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/separator/separator.scss +23 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/separator/separator.ts +56 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/skeleton/skeleton.html +1 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/skeleton/skeleton.scss +28 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/skeleton/skeleton.ts +24 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/spinner/spinner.ts +35 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/agentforce/agentforce-embed.service.ts +177 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/agentforce/conversation.html +3 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/agentforce/conversation.ts +119 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/breadcrumb/breadcrumb.html +54 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/breadcrumb/breadcrumb.ts +40 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/active-filters.html +23 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/active-filters.ts +78 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/date-filter.html +18 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/date-filter.ts +137 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/date-range-filter.html +11 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/date-range-filter.ts +69 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/filter-field-wrapper.html +11 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/filter-field-wrapper.ts +36 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/multi-select-filter.html +10 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/multi-select-filter.ts +58 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/numeric-range-filter.html +22 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/numeric-range-filter.ts +146 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/search-filter.html +8 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/search-filter.ts +82 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/select-filter.html +12 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/select-filter.ts +65 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/text-filter.html +12 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/text-filter.ts +90 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/object-search-state.service.ts +232 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/pagination/pagination.html +8 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/pagination/pagination.ts +61 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/search-bar/search-bar.html +59 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/search-bar/search-bar.ts +108 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/sort-control/sort-control.html +50 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/sort-control/sort-control.ts +72 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/debounce.ts +31 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/field-utils.ts +54 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/filter-utils.ts +354 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/index.ts +12 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/sort-utils.ts +46 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/account-detail/account-detail-page.html +164 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/account-detail/account-detail-page.scss +7 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/account-detail/account-detail-page.ts +196 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/account-search/account-search-page.html +111 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/account-search/account-search-page.ts +217 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/home/home-page.html +18 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/home/home-page.ts +47 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/home/home.html +6 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/home/home.spec.ts +23 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/home/home.ts +13 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/not-found/not-found.html +12 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/not-found/not-found.spec.ts +33 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/not-found/not-found.ts +15 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/types/conversation.ts +55 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/types/globals.d.ts +13 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/utils/async-data.ts +99 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/index.html +14 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/index.ts +15 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/main.ts +5 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/styles.scss +170 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/theme.scss +39 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/types/sf-globals.d.ts +9 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/tsconfig.app.json +11 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/tsconfig.json +33 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/tsconfig.spec.json +10 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/ui-bundle.json +7 -0
- package/lib/templates/project/angularintapp/_p_/_m_/applications/angularintapp.app-meta.xml +17 -0
- package/lib/templates/project/angularintapp/_p_/_m_/permissionsets/angularintapp_Access.permissionset-meta.xml +13 -0
- package/lib/templates/project/angularintapp/config/project-scratch-def.json +13 -0
- package/lib/templates/project/angularintapp/eslint.config.js +7 -0
- package/lib/templates/project/angularintapp/jest.config.js +6 -0
- package/lib/templates/project/angularintapp/package.json +46 -0
- package/lib/templates/project/angularintapp/scripts/apex/hello.apex +10 -0
- package/lib/templates/project/angularintapp/scripts/gitignore-templates.json +4 -0
- package/lib/templates/project/angularintapp/scripts/graphql-search.sh +191 -0
- package/lib/templates/project/angularintapp/scripts/org-setup-config-schema.mjs +103 -0
- package/lib/templates/project/angularintapp/scripts/org-setup-dev.mjs +87 -0
- package/lib/templates/project/angularintapp/scripts/org-setup-utils.mjs +369 -0
- package/lib/templates/project/angularintapp/scripts/org-setup-xml.mjs +182 -0
- package/lib/templates/project/angularintapp/scripts/org-setup.config.json +9 -0
- package/lib/templates/project/angularintapp/scripts/org-setup.mjs +1702 -0
- package/lib/templates/project/angularintapp/scripts/sf-project-setup.mjs +103 -0
- package/lib/templates/project/angularintapp/scripts/soql/account.soql +6 -0
- package/lib/templates/project/angularintapp/scripts/validate-org-setup-config.mjs +38 -0
- package/lib/templates/project/angularintapp/sfdx-project.json +12 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/package-lock.json +589 -561
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/package-lock.json +589 -561
- package/lib/templates/uiBundles/angularbasic/package-lock.json +147 -168
- package/lib/templates/uiBundles/reactbasic/package-lock.json +589 -561
- package/lib/utils/types.d.ts +1 -1
- package/lib/utils/uiBundleTemplateUtils.js +10 -0
- package/lib/utils/uiBundleTemplateUtils.js.map +1 -1
- package/package.json +4 -2
package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/select/select.ts
ADDED
|
@@ -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.html',
|
|
31
|
+
styleUrl: './select.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.html',
|
|
35
|
+
styleUrl: './separator.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.html',
|
|
17
|
+
styleUrl: './skeleton.scss',
|
|
18
|
+
host: {
|
|
19
|
+
'data-slot': 'skeleton',
|
|
20
|
+
'aria-hidden': 'true',
|
|
21
|
+
class: 'bg-accent rounded-md',
|
|
22
|
+
},
|
|
23
|
+
})
|
|
24
|
+
export class SkeletonComponent {}
|
package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/spinner/spinner.ts
ADDED
|
@@ -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,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026, Salesforce, Inc.,
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* For full license text, see the LICENSE.txt file
|
|
5
|
+
*/
|
|
6
|
+
import { inject } from "@angular/core";
|
|
7
|
+
import { CanActivateFn, Router, UrlTree } from "@angular/router";
|
|
8
|
+
import { AuthService } from "./auth.service";
|
|
9
|
+
import { AUTH_REDIRECT_PARAM, ROUTES } from "../config/authentication.config";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Route guard — the Angular analogue of the React `PrivateRoute` layout.
|
|
13
|
+
*
|
|
14
|
+
* Allows activation when the user is authenticated. Otherwise redirects to the
|
|
15
|
+
* login page with a `startUrl` query param capturing the requested destination,
|
|
16
|
+
* so the user is returned there after a successful login.
|
|
17
|
+
*
|
|
18
|
+
* Because `AuthService` runs its initial check on construction, the guard first
|
|
19
|
+
* awaits any in-flight `loading` state (equivalent to the React guard returning
|
|
20
|
+
* `null` while loading, then re-rendering once auth resolves). It resolves to a
|
|
21
|
+
* boolean `true` or a `UrlTree` redirect — never leaves the user on a blank
|
|
22
|
+
* screen.
|
|
23
|
+
*/
|
|
24
|
+
export const authGuard: CanActivateFn = async (route, state): Promise<boolean | UrlTree> => {
|
|
25
|
+
const authService = inject(AuthService);
|
|
26
|
+
const router = inject(Router);
|
|
27
|
+
|
|
28
|
+
// Wait for the initial auth check to settle before deciding. If a check is
|
|
29
|
+
// already resolved this returns immediately.
|
|
30
|
+
if (authService.loading()) {
|
|
31
|
+
await authService.checkAuth();
|
|
32
|
+
} else if (authService.user() === null && authService.error() !== null) {
|
|
33
|
+
// The prior check finished unauthenticated *because of an error* (e.g. a
|
|
34
|
+
// transient network failure), not a confirmed guest. Without this, a single
|
|
35
|
+
// failed initial check would poison protected-route access until a full page
|
|
36
|
+
// reload. Re-run the check on guard entry so recovery doesn't require reload.
|
|
37
|
+
await authService.checkAuth();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (authService.isAuthenticated()) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Capture the current destination (path + query) to return to after login.
|
|
45
|
+
// `state.url` is already the resolved absolute URL for the attempted route.
|
|
46
|
+
const destination = state.url;
|
|
47
|
+
return router.createUrlTree([ROUTES.LOGIN.PATH], {
|
|
48
|
+
queryParams: { [AUTH_REDIRECT_PARAM]: destination },
|
|
49
|
+
});
|
|
50
|
+
};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026, Salesforce, Inc.,
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* For full license text, see the LICENSE.txt file
|
|
5
|
+
*/
|
|
6
|
+
import { computed, inject, Injectable, signal } from "@angular/core";
|
|
7
|
+
import { DataClient } from "../../../api/data-client.service";
|
|
8
|
+
import { API_ROUTES } from "../config/authentication.config";
|
|
9
|
+
|
|
10
|
+
/** The authenticated user shape (mirrors the React `AuthContext` `User`). */
|
|
11
|
+
export interface AuthUser {
|
|
12
|
+
readonly id: string;
|
|
13
|
+
readonly name: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// UI API version used for the Chatter current-user lookup. Mirrors the constant
|
|
17
|
+
// baked into @salesforce/ui-bundle's getCurrentUser helper.
|
|
18
|
+
const API_VERSION = "65.0";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Angular signal-based replacement for the React `AuthProvider` / `useAuth`.
|
|
22
|
+
*
|
|
23
|
+
* `providedIn: 'root'` makes the service a single app-wide singleton, so it
|
|
24
|
+
* replaces the React context+provider wrapper without any `<AuthProvider>` in
|
|
25
|
+
* the tree (the coordinator-approved design). State is exposed as readonly
|
|
26
|
+
* signals; `isAuthenticated` is a computed mirror of `user !== null`.
|
|
27
|
+
*
|
|
28
|
+
* Authentication is checked on construction (equivalent to the React mount
|
|
29
|
+
* `useEffect`). `checkAuth()` re-runs the lookup on demand.
|
|
30
|
+
*
|
|
31
|
+
* The current-user lookup goes through the base app's `DataClient.fetch` to the
|
|
32
|
+
* Chatter `/users/me` endpoint — the exact call `@salesforce/ui-bundle`'s
|
|
33
|
+
* `getCurrentUser` makes — so the feature reuses the base app's existing
|
|
34
|
+
* `@salesforce/platform-sdk` dependency and adds no new package.
|
|
35
|
+
*/
|
|
36
|
+
@Injectable({ providedIn: "root" })
|
|
37
|
+
export class AuthService {
|
|
38
|
+
// DataClient is provided by the base-angular-app; consumed via the
|
|
39
|
+
// `__inherit__` stub under app/api/ (patches-cli strips the prefix at compose
|
|
40
|
+
// so it resolves to the seeded base data-client.service.ts).
|
|
41
|
+
private readonly dataClient = inject(DataClient);
|
|
42
|
+
|
|
43
|
+
private readonly _user = signal<AuthUser | null>(null);
|
|
44
|
+
private readonly _loading = signal<boolean>(true);
|
|
45
|
+
private readonly _error = signal<string | null>(null);
|
|
46
|
+
|
|
47
|
+
/** The current authenticated user, or null when unauthenticated. */
|
|
48
|
+
readonly user = this._user.asReadonly();
|
|
49
|
+
/** True while the initial (or a manual) auth check is in flight. */
|
|
50
|
+
readonly loading = this._loading.asReadonly();
|
|
51
|
+
/** Error message from the most recent failed auth check, else null. */
|
|
52
|
+
readonly error = this._error.asReadonly();
|
|
53
|
+
/** Mirrors React `isAuthenticated = user !== null`. */
|
|
54
|
+
readonly isAuthenticated = computed(() => this._user() !== null);
|
|
55
|
+
|
|
56
|
+
constructor() {
|
|
57
|
+
// Kick off the initial check on construction (React mount `useEffect`).
|
|
58
|
+
void this.checkAuth();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Fetches the current user and updates state. Mirrors the React `checkAuth`.
|
|
63
|
+
*/
|
|
64
|
+
async checkAuth(): Promise<void> {
|
|
65
|
+
this._loading.set(true);
|
|
66
|
+
this._error.set(null);
|
|
67
|
+
try {
|
|
68
|
+
const userData = await this.getCurrentUser();
|
|
69
|
+
this._user.set(userData);
|
|
70
|
+
} catch (err) {
|
|
71
|
+
console.error("Authentication failed", err);
|
|
72
|
+
this._error.set("Authentication failed");
|
|
73
|
+
this._user.set(null);
|
|
74
|
+
} finally {
|
|
75
|
+
this._loading.set(false);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Returns the current user, throwing when unauthenticated. The Angular
|
|
81
|
+
* analogue of the React `useUser()` hook — used by the Profile page which
|
|
82
|
+
* only renders behind the auth guard.
|
|
83
|
+
*/
|
|
84
|
+
requireUser(): AuthUser {
|
|
85
|
+
const user = this._user();
|
|
86
|
+
if (!user) {
|
|
87
|
+
throw new Error("Authenticated context not established");
|
|
88
|
+
}
|
|
89
|
+
return user;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Navigate to the server-side logout endpoint. Uses `replace` to prevent the
|
|
94
|
+
* back button from returning to an authenticated session. Direct port of the
|
|
95
|
+
* React `logout`.
|
|
96
|
+
*/
|
|
97
|
+
logout(startURL?: string): void {
|
|
98
|
+
const finalLogoutUrl = startURL
|
|
99
|
+
? `${API_ROUTES.LOGOUT}?startURL=${encodeURIComponent(startURL)}`
|
|
100
|
+
: API_ROUTES.LOGOUT;
|
|
101
|
+
window.location.replace(finalLogoutUrl);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Fetches the current user via the Chatter `/users/me` endpoint. Reproduces
|
|
106
|
+
* `@salesforce/ui-bundle`'s `getCurrentUser` so we don't add ui-bundle as a
|
|
107
|
+
* dependency (base app only ships @salesforce/platform-sdk).
|
|
108
|
+
*/
|
|
109
|
+
private async getCurrentUser(): Promise<AuthUser> {
|
|
110
|
+
const response = await this.dataClient.fetch(
|
|
111
|
+
`/services/data/v${API_VERSION}/chatter/users/me`,
|
|
112
|
+
{
|
|
113
|
+
method: "GET",
|
|
114
|
+
headers: { Accept: "application/json" },
|
|
115
|
+
},
|
|
116
|
+
);
|
|
117
|
+
if (!response.ok) {
|
|
118
|
+
throw new Error(`Failed to fetch current user: HTTP ${response.status}`);
|
|
119
|
+
}
|
|
120
|
+
const data = (await response.json()) as { id?: string; name?: string };
|
|
121
|
+
if (!data?.id) {
|
|
122
|
+
throw new Error("Current user response missing id");
|
|
123
|
+
}
|
|
124
|
+
return { id: data.id, name: data.name || "User" };
|
|
125
|
+
}
|
|
126
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<app-card-layout [title]="title()" [subtitle]="description()">
|
|
2
|
+
<div class="space-y-6">
|
|
3
|
+
@if (showAuthAlert()) {
|
|
4
|
+
<app-status-alert variant="info" message="You are already logged in." />
|
|
5
|
+
} @if (errorMessages().length > 0) { @if (errorMessages().length === 1) {
|
|
6
|
+
<app-status-alert variant="error" [message]="errorMessages()[0]" />
|
|
7
|
+
} @else {
|
|
8
|
+
<app-status-alert variant="error">
|
|
9
|
+
<ul>
|
|
10
|
+
@for (msg of errorMessages(); track msg) {
|
|
11
|
+
<li>{{ msg }}</li>
|
|
12
|
+
}
|
|
13
|
+
</ul>
|
|
14
|
+
</app-status-alert>
|
|
15
|
+
} } @if (success()) {
|
|
16
|
+
<app-status-alert variant="success" [message]="success()!" />
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
<form (ngSubmit)="onSubmit()">
|
|
20
|
+
<ng-content />
|
|
21
|
+
<app-submit-button
|
|
22
|
+
class="mt-6 block"
|
|
23
|
+
[label]="submitText()"
|
|
24
|
+
[loadingLabel]="submitLoadingText()"
|
|
25
|
+
[submitting]="submitting()"
|
|
26
|
+
[disabled]="isSubmitDisabled()"
|
|
27
|
+
/>
|
|
28
|
+
</form>
|
|
29
|
+
|
|
30
|
+
@if (footer(); as f) {
|
|
31
|
+
<app-footer-link [text]="f.text ?? ''" [to]="f.link" [linkText]="f.linkText" />
|
|
32
|
+
}
|
|
33
|
+
</div>
|
|
34
|
+
</app-card-layout>
|
|
@@ -0,0 +1,94 @@
|
|
|
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, computed, inject, input, output } from "@angular/core";
|
|
7
|
+
import { FormsModule } from "@angular/forms";
|
|
8
|
+
import { CardLayoutComponent } from "../card-layout/card-layout";
|
|
9
|
+
import { StatusAlertComponent } from "../status-alert/status-alert";
|
|
10
|
+
import { SubmitButtonComponent } from "../submit-button/submit-button";
|
|
11
|
+
import { FooterLinkComponent } from "../footer-link/footer-link";
|
|
12
|
+
import { AuthService } from "../auth/auth.service";
|
|
13
|
+
|
|
14
|
+
/** Footer link descriptor for the auth form frame. */
|
|
15
|
+
export interface AuthFormFooter {
|
|
16
|
+
text?: string;
|
|
17
|
+
link: string;
|
|
18
|
+
linkText: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Wrapper enforcing a consistent layout (card) and error/success alert
|
|
23
|
+
* positioning for all authentication forms — the Angular port of the React
|
|
24
|
+
* `AuthForm`.
|
|
25
|
+
*
|
|
26
|
+
* Auth-aware behavior (identical to React):
|
|
27
|
+
* - While auth state is loading, the submit button is disabled.
|
|
28
|
+
* - If the user is already authenticated and `showAlreadyLoggedIn` is true, an
|
|
29
|
+
* info alert is shown and submit is disabled.
|
|
30
|
+
*
|
|
31
|
+
* The owning page holds the FormGroup and binds `[formGroup]` on the projected
|
|
32
|
+
* `<form>`; this component renders the frame, alerts, submit button, and footer.
|
|
33
|
+
* It emits `(submitted)` when the submit button is pressed so the page runs its
|
|
34
|
+
* submit handler. The page passes its submitting flag via `[submitting]` and any
|
|
35
|
+
* extra disabled condition via `[submitDisabled]`.
|
|
36
|
+
*/
|
|
37
|
+
@Component({
|
|
38
|
+
selector: "app-auth-form",
|
|
39
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
40
|
+
imports: [
|
|
41
|
+
FormsModule,
|
|
42
|
+
CardLayoutComponent,
|
|
43
|
+
StatusAlertComponent,
|
|
44
|
+
SubmitButtonComponent,
|
|
45
|
+
FooterLinkComponent,
|
|
46
|
+
],
|
|
47
|
+
templateUrl: "./auth-form.html",
|
|
48
|
+
})
|
|
49
|
+
export class AuthFormComponent {
|
|
50
|
+
private readonly authService = inject(AuthService);
|
|
51
|
+
|
|
52
|
+
readonly title = input.required<string>();
|
|
53
|
+
readonly description = input<string>("");
|
|
54
|
+
/** Error message(s) to surface; empty/null hides the error alert. */
|
|
55
|
+
readonly error = input<string | string[] | null>(null);
|
|
56
|
+
/** Success message to surface; empty/null hides the success alert. */
|
|
57
|
+
readonly success = input<string | null>(null);
|
|
58
|
+
/** Whether to show the "already logged in" alert and disable submit. @default true */
|
|
59
|
+
readonly showAlreadyLoggedIn = input<boolean>(true);
|
|
60
|
+
readonly submitText = input.required<string>();
|
|
61
|
+
readonly submitLoadingText = input<string>("Submitting…");
|
|
62
|
+
/** True while the page's async submit is in flight. */
|
|
63
|
+
readonly submitting = input<boolean>(false);
|
|
64
|
+
/** Extra disabled condition from the page (e.g. success state). */
|
|
65
|
+
readonly submitDisabled = input<boolean>(false);
|
|
66
|
+
readonly footer = input<AuthFormFooter | null>(null);
|
|
67
|
+
|
|
68
|
+
/** Emitted when the submit button is pressed (page runs its handler). */
|
|
69
|
+
readonly submitted = output<void>();
|
|
70
|
+
|
|
71
|
+
protected readonly isAuthenticated = this.authService.isAuthenticated;
|
|
72
|
+
protected readonly loading = this.authService.loading;
|
|
73
|
+
|
|
74
|
+
/** Info alert shown when already authenticated on a public page. */
|
|
75
|
+
protected readonly showAuthAlert = computed(
|
|
76
|
+
() => this.showAlreadyLoggedIn() && this.isAuthenticated(),
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
/** Submit disabled when: caller says so, already-logged-in, or auth loading. */
|
|
80
|
+
protected readonly isSubmitDisabled = computed(
|
|
81
|
+
() => this.submitDisabled() || this.showAuthAlert() || this.loading(),
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
/** Normalizes the error input to an array for the template's list rendering. */
|
|
85
|
+
protected readonly errorMessages = computed<string[]>(() => {
|
|
86
|
+
const err = this.error();
|
|
87
|
+
if (!err) return [];
|
|
88
|
+
return Array.isArray(err) ? err : [err];
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
protected onSubmit(): void {
|
|
92
|
+
this.submitted.emit();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
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
|
+
import { AppLayoutComponent } from "../../../components/layout/app-layout/app-layout";
|
|
8
|
+
import { SessionTimeoutValidatorComponent } from "../session/session";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Top-level app wrapper — the faithful Angular port of the React `AuthAppLayout`
|
|
12
|
+
* (`<AuthProvider><SessionTimeoutValidator/><AppLayout/></AuthProvider>`).
|
|
13
|
+
*
|
|
14
|
+
* There is no AuthProvider equivalent: `AuthService` is `providedIn: 'root'`, so
|
|
15
|
+
* auth state is app-wide automatically. This component renders the
|
|
16
|
+
* session-timeout validator (whose warning modal is thus available on every
|
|
17
|
+
* child route, exactly like React) followed by the base `app-layout`. Child
|
|
18
|
+
* routes render inside the base layout's own `<router-outlet />` post-compose.
|
|
19
|
+
*
|
|
20
|
+
* Wired as the top route node's `component` in `app.routes.ts`; the route-merger
|
|
21
|
+
* swaps the base layout node for this wrapper (the same element-swap object-search
|
|
22
|
+
* performs by repeating `component: AppLayoutComponent`).
|
|
23
|
+
*/
|
|
24
|
+
@Component({
|
|
25
|
+
selector: "app-auth-app-layout",
|
|
26
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
27
|
+
imports: [SessionTimeoutValidatorComponent, AppLayoutComponent],
|
|
28
|
+
templateUrl: "./auth-layout.html",
|
|
29
|
+
})
|
|
30
|
+
export class AuthAppLayoutComponent {}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<div class="p-4">
|
|
2
|
+
<app-card class="w-full">
|
|
3
|
+
@if (title() || subtitle()) {
|
|
4
|
+
<app-card-header>
|
|
5
|
+
@if (title()) {
|
|
6
|
+
<app-card-title>{{ title() }}</app-card-title>
|
|
7
|
+
} @if (subtitle()) {
|
|
8
|
+
<app-card-description>{{ subtitle() }}</app-card-description>
|
|
9
|
+
}
|
|
10
|
+
</app-card-header>
|
|
11
|
+
}
|
|
12
|
+
<app-card-content>
|
|
13
|
+
<ng-content />
|
|
14
|
+
</app-card-content>
|
|
15
|
+
</app-card>
|
|
16
|
+
</div>
|
|
@@ -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 { ChangeDetectionStrategy, Component, input } from "@angular/core";
|
|
7
|
+
import {
|
|
8
|
+
CardComponent,
|
|
9
|
+
CardContentComponent,
|
|
10
|
+
CardDescriptionComponent,
|
|
11
|
+
CardHeaderComponent,
|
|
12
|
+
CardTitleComponent,
|
|
13
|
+
} from "../../../components/ui/card/card";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Centered page shell for auth pages — a feature-owned composition over the base
|
|
17
|
+
* `app-card` ui primitives (not a base-template component). Renders a single
|
|
18
|
+
* `app-card` centered in the viewport with an optional title / subtitle header,
|
|
19
|
+
* and content-projects the page body.
|
|
20
|
+
*
|
|
21
|
+
* Consumed by the authentication login / register / reset pages as the
|
|
22
|
+
* `CenteredPageLayout` analogue's card frame. Tailwind utilities pass through
|
|
23
|
+
* via the host `class`.
|
|
24
|
+
*/
|
|
25
|
+
@Component({
|
|
26
|
+
selector: "app-card-layout",
|
|
27
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
28
|
+
imports: [
|
|
29
|
+
CardComponent,
|
|
30
|
+
CardHeaderComponent,
|
|
31
|
+
CardTitleComponent,
|
|
32
|
+
CardDescriptionComponent,
|
|
33
|
+
CardContentComponent,
|
|
34
|
+
],
|
|
35
|
+
templateUrl: "./card-layout.html",
|
|
36
|
+
})
|
|
37
|
+
export class CardLayoutComponent {
|
|
38
|
+
readonly title = input<string>("");
|
|
39
|
+
readonly subtitle = input<string | null>(null);
|
|
40
|
+
}
|