@salesforce/ui-bundle-template-app-angular-template-b2x 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/classes/UIBundleAuthUtils.cls +68 -0
- package/dist/force-app/main/default/classes/UIBundleAuthUtils.cls-meta.xml +5 -0
- package/dist/force-app/main/default/classes/UIBundleChangePassword.cls +77 -0
- package/dist/force-app/main/default/classes/UIBundleChangePassword.cls-meta.xml +5 -0
- package/dist/force-app/main/default/classes/UIBundleForgotPassword.cls +71 -0
- package/dist/force-app/main/default/classes/UIBundleForgotPassword.cls-meta.xml +5 -0
- package/dist/force-app/main/default/classes/UIBundleLogin.cls +105 -0
- package/dist/force-app/main/default/classes/UIBundleLogin.cls-meta.xml +5 -0
- package/dist/force-app/main/default/classes/UIBundleRegistration.cls +162 -0
- package/dist/force-app/main/default/classes/UIBundleRegistration.cls-meta.xml +5 -0
- package/dist/force-app/main/default/digitalExperienceConfigs/angularexternalapp1.digitalExperienceConfig-meta.xml +8 -0
- package/dist/force-app/main/default/digitalExperiences/site/angularexternalapp1/angularexternalapp1.digitalExperience-meta.xml +11 -0
- package/dist/force-app/main/default/digitalExperiences/site/angularexternalapp1/sfdc_cms__site/angularexternalapp1/_meta.json +5 -0
- package/dist/force-app/main/default/digitalExperiences/site/angularexternalapp1/sfdc_cms__site/angularexternalapp1/content.json +10 -0
- package/dist/force-app/main/default/networks/angularexternalapp.network-meta.xml +60 -0
- package/dist/force-app/main/default/package.xml +24 -0
- package/dist/force-app/main/default/permissionsets/angularexternalapp_Guest_User_Api_Access.permissionset-meta.xml +9 -0
- package/dist/force-app/main/default/sites/angularexternalapp.site-meta.xml +31 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/.forceignore +15 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/.postcssrc.json +5 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/.prettierignore +8 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/.prettierrc +12 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/CHANGELOG.md +4 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/README.md +85 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/angular.json +98 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/angularexternalapp.uibundle-meta.xml +8 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/e2e/app.spec.ts +15 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/esbuild/api-version.mjs +17 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/eslint.config.js +60 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/middleware/html.mjs +3 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/middleware/proxy.mjs +12 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/package.json +56 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/playwright.config.ts +25 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/public/favicon.ico +0 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/scripts/rewrite-e2e-assets.mjs +30 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/api/account/account-search.service.ts +196 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/api/account/distinctAccountIndustries.ts +26 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/api/account/distinctAccountTypes.ts +26 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/api/account/getAccountDetail.ts +128 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/api/account/searchAccounts.ts +58 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/api/data-client.service.spec.ts +184 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/api/data-client.service.ts +74 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/api/user-profile.service.ts +126 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/app.config.ts +22 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/app.html +1 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/app.routes.ts +77 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/app.spec.ts +18 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/app.ts +15 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/layout/app-layout/app-layout.component.html +53 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/layout/app-layout/app-layout.component.spec.ts +89 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/layout/app-layout/app-layout.component.ts +81 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/_field-size.scss +42 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/alert/alert.component.html +31 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/alert/alert.component.ts +53 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/button/button.component.html +18 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/button/button.component.scss +112 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/button/button.component.ts +57 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/card/card.component.scss +34 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/card/card.component.ts +110 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/collapsible/collapsible.component.html +10 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/collapsible/collapsible.component.ts +26 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/date-picker/date-picker.component.html +25 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/date-picker/date-picker.component.scss +36 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/date-picker/date-picker.component.ts +41 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/date-range-picker/date-range-picker.component.html +34 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/date-range-picker/date-range-picker.component.scss +33 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/date-range-picker/date-range-picker.component.ts +66 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/dialog/dialog.component.html +37 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/dialog/dialog.component.ts +55 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/field/field.component.html +21 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/field/field.component.ts +36 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/field-size.ts +8 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/input/input.component.html +19 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/input/input.component.scss +35 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/input/input.component.ts +36 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/label/label.component.html +3 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/label/label.component.ts +17 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/paginator/paginator.component.html +10 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/paginator/paginator.component.ts +37 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/popover/popover.component.html +41 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/popover/popover.component.ts +40 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/select/select.component.html +24 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/select/select.component.scss +35 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/select/select.component.ts +72 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/separator/separator.component.html +1 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/separator/separator.component.scss +23 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/separator/separator.component.ts +56 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/skeleton/skeleton.component.html +1 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/skeleton/skeleton.component.scss +28 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/skeleton/skeleton.component.ts +24 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/components/ui/spinner/spinner.component.ts +35 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/authentication/auth/auth.guard.ts +50 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/authentication/auth/auth.service.ts +126 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/authentication/components/status-alert/status-alert.component.html +7 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/authentication/components/status-alert/status-alert.component.ts +52 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/authentication/config/authentication.config.ts +75 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/authentication/forms/auth-form/auth-form.component.html +38 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/authentication/forms/auth-form/auth-form.component.ts +94 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/authentication/forms/footer-link/footer-link.component.html +11 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/authentication/forms/footer-link/footer-link.component.ts +26 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/authentication/forms/reactive-form-page.base.ts +50 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/authentication/forms/submit-button/submit-button.component.html +8 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/authentication/forms/submit-button/submit-button.component.scss +17 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/authentication/forms/submit-button/submit-button.component.ts +35 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/authentication/layouts/auth-app-layout/auth-app-layout.component.html +2 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/authentication/layouts/auth-app-layout/auth-app-layout.component.ts +30 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/authentication/layouts/card-layout/card-layout.component.html +17 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/authentication/layouts/card-layout/card-layout.component.ts +40 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/authentication/menu/auth-menu/auth-menu.component.html +26 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/authentication/menu/auth-menu/auth-menu.component.ts +46 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/authentication/session-timeout/session-time-servlet.ts +130 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/authentication/session-timeout/session-timeout-validator/session-timeout-validator.component.html +57 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/authentication/session-timeout/session-timeout-validator/session-timeout-validator.component.ts +205 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/authentication/session-timeout/session-timeout.config.ts +83 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/authentication/session-timeout/session-timeout.service.ts +201 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/authentication/utils/auth-helpers.ts +68 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/authentication/utils/auth-validators.ts +72 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/authentication/utils/helpers.ts +85 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/components/active-filters/active-filters.component.html +23 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/components/active-filters/active-filters.component.ts +78 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/components/filters/date-filter/date-filter.component.html +18 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/components/filters/date-filter/date-filter.component.ts +137 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/components/filters/date-range-filter/date-range-filter.component.html +11 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/components/filters/date-range-filter/date-range-filter.component.ts +69 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/components/filters/filter-field-wrapper/filter-field-wrapper.component.html +11 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/components/filters/filter-field-wrapper/filter-field-wrapper.component.ts +36 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/components/filters/multi-select-filter/multi-select-filter.component.html +10 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/components/filters/multi-select-filter/multi-select-filter.component.ts +58 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/components/filters/numeric-range-filter/numeric-range-filter.component.html +22 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/components/filters/numeric-range-filter/numeric-range-filter.component.ts +146 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/components/filters/search-filter/search-filter.component.html +8 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/components/filters/search-filter/search-filter.component.ts +82 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/components/filters/select-filter/select-filter.component.html +12 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/components/filters/select-filter/select-filter.component.ts +65 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/components/filters/text-filter/text-filter.component.html +12 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/components/filters/text-filter/text-filter.component.ts +90 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/components/object-breadcrumb/object-breadcrumb.component.html +55 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/components/object-breadcrumb/object-breadcrumb.component.ts +40 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/components/pagination-controls/pagination-controls.component.html +8 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/components/pagination-controls/pagination-controls.component.ts +61 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/components/search-bar/search-bar.component.html +59 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/components/search-bar/search-bar.component.ts +108 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/components/sort-control/sort-control.component.html +50 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/components/sort-control/sort-control.component.ts +72 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/object-search-state.service.ts +232 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/utils/debounce.ts +31 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/utils/field-utils.ts +54 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/utils/filter-utils.ts +354 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/utils/index.ts +12 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/features/object-search/utils/sort-utils.ts +46 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/pages/account-detail/account-detail-page.component.html +174 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/pages/account-detail/account-detail-page.component.scss +7 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/pages/account-detail/account-detail-page.component.ts +199 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/pages/account-search/account-search-page.component.html +111 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/pages/account-search/account-search-page.component.ts +217 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/pages/change-password/change-password-page.component.html +68 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/pages/change-password/change-password-page.component.ts +82 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/pages/forgot-password/forgot-password-page.component.html +35 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/pages/forgot-password/forgot-password-page.component.ts +87 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/pages/home/home-page.component.html +18 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/pages/home/home-page.component.ts +47 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/pages/home/home.component.html +6 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/pages/home/home.component.spec.ts +23 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/pages/home/home.component.ts +13 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/pages/login/login-page.component.html +47 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/pages/login/login-page.component.ts +89 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/pages/not-found/not-found.component.html +12 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/pages/not-found/not-found.component.spec.ts +33 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/pages/not-found/not-found.component.ts +15 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/pages/profile/profile-page.component.html +126 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/pages/profile/profile-page.component.ts +194 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/pages/register/register-page.component.html +80 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/pages/register/register-page.component.ts +93 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/pages/reset-password/reset-password-page.component.html +60 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/pages/reset-password/reset-password-page.component.ts +96 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/app/utils/async-data.ts +99 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/index.html +14 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/main.ts +5 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/styles.scss +170 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/theme.scss +39 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/src/types/sf-globals.d.ts +9 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/tsconfig.app.json +11 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/tsconfig.json +33 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/tsconfig.spec.json +10 -0
- package/dist/force-app/main/default/uiBundles/angularexternalapp/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,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026, Salesforce, Inc.,
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* For full license text, see the LICENSE.txt file
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// NOTE: The React reference imports `ResultOrder` / `NullOrder` from generated
|
|
8
|
+
// GraphQL types (graphql-operations-types.ts). Codegen is parked for the
|
|
9
|
+
// Angular port, so the enum string values are inlined here. When codegen lands,
|
|
10
|
+
// swap these constants for the generated enums.
|
|
11
|
+
/** GraphQL `ResultOrder` values. */
|
|
12
|
+
const RESULT_ORDER = { asc: "ASC", desc: "DESC" } as const;
|
|
13
|
+
/** GraphQL `NullOrder` values. */
|
|
14
|
+
const NULL_ORDER = { first: "FIRST", last: "LAST" } as const;
|
|
15
|
+
|
|
16
|
+
export interface SortFieldConfig<TFieldName extends string = string> {
|
|
17
|
+
field: TFieldName;
|
|
18
|
+
label: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface SortState<TFieldName extends string = string> {
|
|
22
|
+
field: TFieldName;
|
|
23
|
+
direction: "ASC" | "DESC";
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Converts a {@link SortState} into a GraphQL order-by object.
|
|
28
|
+
*
|
|
29
|
+
* @typeParam TOrderBy - The GraphQL order-by input type (e.g. `Account_OrderBy`).
|
|
30
|
+
* @param sort - The current sort state from the UI, or `null` if no sort is applied.
|
|
31
|
+
* @returns An order-by object for the query's `orderBy` variable, or `undefined`
|
|
32
|
+
* when no sort is active (defers to the API's default ordering).
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* buildOrderBy({ field: 'Name', direction: 'ASC' })
|
|
36
|
+
* // => { Name: { order: 'ASC', nulls: 'LAST' } }
|
|
37
|
+
*/
|
|
38
|
+
export function buildOrderBy<TOrderBy>(sort: SortState | null): TOrderBy | undefined {
|
|
39
|
+
if (!sort) return undefined;
|
|
40
|
+
return {
|
|
41
|
+
[sort.field]: {
|
|
42
|
+
order: sort.direction === "ASC" ? RESULT_ORDER.asc : RESULT_ORDER.desc,
|
|
43
|
+
nulls: NULL_ORDER.last,
|
|
44
|
+
},
|
|
45
|
+
} as TOrderBy;
|
|
46
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
<div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 py-6" [attr.aria-busy]="loading()">
|
|
2
|
+
<app-object-breadcrumb
|
|
3
|
+
listPath="/accounts"
|
|
4
|
+
listLabel="Accounts"
|
|
5
|
+
[loading]="loading()"
|
|
6
|
+
[recordName]="recordName()"
|
|
7
|
+
/>
|
|
8
|
+
|
|
9
|
+
@if (loading()) {
|
|
10
|
+
<!-- Loading state -->
|
|
11
|
+
<app-skeleton class="h-8 w-56 mb-4" />
|
|
12
|
+
<app-card>
|
|
13
|
+
<app-card-content class="space-y-8">
|
|
14
|
+
<div class="space-y-4">
|
|
15
|
+
@for (row of skeletonRows; track row) {
|
|
16
|
+
<div class="grid grid-cols-2 gap-x-8 gap-y-4">
|
|
17
|
+
<div>
|
|
18
|
+
<app-skeleton class="h-4 w-24 mb-1.5" />
|
|
19
|
+
<app-skeleton class="h-5 w-40" />
|
|
20
|
+
</div>
|
|
21
|
+
<div>
|
|
22
|
+
<app-skeleton class="h-4 w-24 mb-1.5" />
|
|
23
|
+
<app-skeleton class="h-5 w-40" />
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
}
|
|
27
|
+
</div>
|
|
28
|
+
<app-separator />
|
|
29
|
+
<div class="space-y-4">
|
|
30
|
+
<app-skeleton class="h-7 w-48 py-2" />
|
|
31
|
+
<div class="grid grid-cols-2 gap-x-8 gap-y-4">
|
|
32
|
+
<app-skeleton class="h-12 w-full" />
|
|
33
|
+
<app-skeleton class="h-12 w-full" />
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
</app-card-content>
|
|
37
|
+
</app-card>
|
|
38
|
+
} @else if (error()) {
|
|
39
|
+
<!-- Error state -->
|
|
40
|
+
<app-alert
|
|
41
|
+
variant="destructive"
|
|
42
|
+
icon="error"
|
|
43
|
+
title="Failed to load account"
|
|
44
|
+
description="Something went wrong while loading this account. Please try again later."
|
|
45
|
+
/>
|
|
46
|
+
<div class="mt-4 flex gap-3">
|
|
47
|
+
<app-button appearance="outlined" (clicked)="goBack()">← Back</app-button>
|
|
48
|
+
<app-button appearance="outlined" (clicked)="reload()">Retry</app-button>
|
|
49
|
+
</div>
|
|
50
|
+
} @else if (notFound()) {
|
|
51
|
+
<!-- Not found state -->
|
|
52
|
+
<app-card>
|
|
53
|
+
<app-card-content class="flex flex-col items-center justify-center py-16 text-center">
|
|
54
|
+
<svg
|
|
55
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
56
|
+
class="size-12 text-muted-foreground mb-4"
|
|
57
|
+
viewBox="0 0 24 24"
|
|
58
|
+
fill="none"
|
|
59
|
+
stroke="currentColor"
|
|
60
|
+
stroke-width="2"
|
|
61
|
+
stroke-linecap="round"
|
|
62
|
+
stroke-linejoin="round"
|
|
63
|
+
aria-hidden="true"
|
|
64
|
+
>
|
|
65
|
+
<path d="M12 17h.01" />
|
|
66
|
+
<path d="M10.1 9a2.4 2.4 0 0 1 3.9 1.9c0 1.5-2 2-2 3" />
|
|
67
|
+
<path d="M14.5 4.5 20 10l-2 2" />
|
|
68
|
+
<path d="M4 4h9l7 7v9a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1Z" />
|
|
69
|
+
</svg>
|
|
70
|
+
<h2 class="text-lg font-semibold mb-1">Account not found</h2>
|
|
71
|
+
<p class="text-sm text-muted-foreground mb-6">
|
|
72
|
+
The account you're looking for doesn't exist or may have been deleted.
|
|
73
|
+
</p>
|
|
74
|
+
<app-button appearance="outlined" (clicked)="goBack()">← Go back</app-button>
|
|
75
|
+
</app-card-content>
|
|
76
|
+
</app-card>
|
|
77
|
+
} @else if (account()) {
|
|
78
|
+
<!-- Content -->
|
|
79
|
+
<h1 class="text-2xl font-bold mb-4">Account: {{ title() }}</h1>
|
|
80
|
+
|
|
81
|
+
<app-card>
|
|
82
|
+
<app-card-content class="space-y-8">
|
|
83
|
+
<!-- Top section -->
|
|
84
|
+
<div class="space-y-4">
|
|
85
|
+
@for (row of topRows(); track $index) {
|
|
86
|
+
<div class="grid grid-cols-2 gap-x-8 gap-y-4">
|
|
87
|
+
@for (field of row; track field.label) {
|
|
88
|
+
<div>
|
|
89
|
+
<dt class="text-sm text-muted-foreground">{{ field.label }}</dt>
|
|
90
|
+
<dd class="mt-0.5">
|
|
91
|
+
@if (field.value && field.telephone) {
|
|
92
|
+
<a [href]="'tel:' + field.value" class="underline">{{ field.value }}</a>
|
|
93
|
+
} @else {
|
|
94
|
+
{{ field.value ?? "—" }}
|
|
95
|
+
}
|
|
96
|
+
</dd>
|
|
97
|
+
</div>
|
|
98
|
+
}
|
|
99
|
+
</div>
|
|
100
|
+
}
|
|
101
|
+
</div>
|
|
102
|
+
|
|
103
|
+
<app-separator />
|
|
104
|
+
|
|
105
|
+
<!-- Additional Information -->
|
|
106
|
+
<app-collapsible title="Additional Information" [(open)]="additionalOpen">
|
|
107
|
+
<div class="space-y-4">
|
|
108
|
+
@for (row of additionalRows(); track $index) {
|
|
109
|
+
<div class="grid grid-cols-2 gap-x-8 gap-y-4">
|
|
110
|
+
@for (field of row; track field.label) {
|
|
111
|
+
<div>
|
|
112
|
+
<dt class="text-sm text-muted-foreground">{{ field.label }}</dt>
|
|
113
|
+
<dd class="mt-0.5">{{ field.value ?? "—" }}</dd>
|
|
114
|
+
</div>
|
|
115
|
+
}
|
|
116
|
+
</div>
|
|
117
|
+
}
|
|
118
|
+
<div>
|
|
119
|
+
<dt class="text-sm text-muted-foreground">Description</dt>
|
|
120
|
+
<dd class="mt-0.5">{{ description() ?? "—" }}</dd>
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
</app-collapsible>
|
|
124
|
+
<div class="space-y-4"></div>
|
|
125
|
+
<app-separator />
|
|
126
|
+
|
|
127
|
+
<!-- Address Information -->
|
|
128
|
+
<app-collapsible title="Address Information" [(open)]="addressOpen">
|
|
129
|
+
<div class="grid grid-cols-2 gap-x-8 gap-y-4">
|
|
130
|
+
<div>
|
|
131
|
+
<dt class="text-sm text-muted-foreground">Billing Address</dt>
|
|
132
|
+
<dd class="mt-0.5">
|
|
133
|
+
@if (billingAddress()) {
|
|
134
|
+
@for (line of billingAddress(); track $index) {
|
|
135
|
+
<div>{{ line }}</div>
|
|
136
|
+
}
|
|
137
|
+
} @else {
|
|
138
|
+
—
|
|
139
|
+
}
|
|
140
|
+
</dd>
|
|
141
|
+
</div>
|
|
142
|
+
<div>
|
|
143
|
+
<dt class="text-sm text-muted-foreground">Shipping Address</dt>
|
|
144
|
+
<dd class="mt-0.5">
|
|
145
|
+
@if (shippingAddress()) {
|
|
146
|
+
@for (line of shippingAddress(); track $index) {
|
|
147
|
+
<div>{{ line }}</div>
|
|
148
|
+
}
|
|
149
|
+
} @else {
|
|
150
|
+
—
|
|
151
|
+
}
|
|
152
|
+
</dd>
|
|
153
|
+
</div>
|
|
154
|
+
</div>
|
|
155
|
+
</app-collapsible>
|
|
156
|
+
<div class="space-y-4"></div>
|
|
157
|
+
<app-separator />
|
|
158
|
+
<!-- System Information -->
|
|
159
|
+
<app-collapsible title="System Information" [(open)]="systemOpen">
|
|
160
|
+
<div class="grid grid-cols-2 gap-x-8 gap-y-4">
|
|
161
|
+
<div>
|
|
162
|
+
<dt class="text-sm text-muted-foreground">Created By</dt>
|
|
163
|
+
<dd class="mt-0.5">{{ createdBy() ?? "—" }}</dd>
|
|
164
|
+
</div>
|
|
165
|
+
<div>
|
|
166
|
+
<dt class="text-sm text-muted-foreground">Last Modified By</dt>
|
|
167
|
+
<dd class="mt-0.5">{{ lastModifiedBy() ?? "—" }}</dd>
|
|
168
|
+
</div>
|
|
169
|
+
</div>
|
|
170
|
+
</app-collapsible>
|
|
171
|
+
</app-card-content>
|
|
172
|
+
</app-card>
|
|
173
|
+
}
|
|
174
|
+
</div>
|
|
@@ -0,0 +1,199 @@
|
|
|
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, signal } from "@angular/core";
|
|
7
|
+
import { ActivatedRoute, Router } from "@angular/router";
|
|
8
|
+
import { toSignal } from "@angular/core/rxjs-interop";
|
|
9
|
+
import { map } from "rxjs/operators";
|
|
10
|
+
// Base-app UI wrappers, inherited (not recreated) by this feature. Post-compose
|
|
11
|
+
// they land at uiBundles/<target>/src/app/components/ui/..., three levels up from this
|
|
12
|
+
// page folder (app/features/account-search/ -> app/components/ui/).
|
|
13
|
+
import { AlertComponent } from "../../components/ui/alert/alert.component";
|
|
14
|
+
import { ButtonComponent } from "../../components/ui/button/button.component";
|
|
15
|
+
import {
|
|
16
|
+
CardComponent,
|
|
17
|
+
CardContentComponent,
|
|
18
|
+
} from "../../components/ui/card/card.component";
|
|
19
|
+
import { CollapsibleComponent } from "../../components/ui/collapsible/collapsible.component";
|
|
20
|
+
import { SeparatorComponent } from "../../components/ui/separator/separator.component";
|
|
21
|
+
import { SkeletonComponent } from "../../components/ui/skeleton/skeleton.component";
|
|
22
|
+
// Object-search feature building blocks (Waves 1-2), two levels up.
|
|
23
|
+
import { ObjectBreadcrumbComponent } from "../../features/object-search/components/object-breadcrumb/object-breadcrumb.component";
|
|
24
|
+
import { createAsyncData } from "../../utils/async-data";
|
|
25
|
+
import {
|
|
26
|
+
fieldValue,
|
|
27
|
+
getAddressFieldLines,
|
|
28
|
+
formatDateTimeField,
|
|
29
|
+
} from "../../features/object-search/utils/field-utils";
|
|
30
|
+
import { AccountSearchService } from "../../api/account/account-search.service";
|
|
31
|
+
|
|
32
|
+
/** `Intl` options for the created / last-modified timestamps (matches React). */
|
|
33
|
+
const DATE_TIME_OPTIONS: Intl.DateTimeFormatOptions = {
|
|
34
|
+
dateStyle: "medium",
|
|
35
|
+
timeStyle: "short",
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/** A `{ label, value }` pair rendered in a field grid. */
|
|
39
|
+
interface Field {
|
|
40
|
+
label: string;
|
|
41
|
+
value: string | null;
|
|
42
|
+
/** `true` renders the value as a `tel:` link (Phone / Fax). */
|
|
43
|
+
telephone?: boolean;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Account detail page. The Angular analogue of the React
|
|
48
|
+
* `AccountObjectDetailPage`: a breadcrumb plus a card of collapsible sections
|
|
49
|
+
* (top fields, Additional / Address / System information), with loading,
|
|
50
|
+
* error, and not-found states.
|
|
51
|
+
*
|
|
52
|
+
* The record id comes from the `:recordId` route param (reactively, so a
|
|
53
|
+
* client-side nav between two detail routes refetches). Data flows through
|
|
54
|
+
* {@link createAsyncData} for latest-wins fetching.
|
|
55
|
+
*/
|
|
56
|
+
@Component({
|
|
57
|
+
selector: "app-account-detail-page",
|
|
58
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
59
|
+
imports: [
|
|
60
|
+
AlertComponent,
|
|
61
|
+
ButtonComponent,
|
|
62
|
+
CardComponent,
|
|
63
|
+
CardContentComponent,
|
|
64
|
+
CollapsibleComponent,
|
|
65
|
+
SeparatorComponent,
|
|
66
|
+
SkeletonComponent,
|
|
67
|
+
ObjectBreadcrumbComponent,
|
|
68
|
+
],
|
|
69
|
+
templateUrl: "./account-detail-page.component.html",
|
|
70
|
+
styleUrl: "./account-detail-page.component.scss",
|
|
71
|
+
})
|
|
72
|
+
export class AccountDetailPageComponent {
|
|
73
|
+
private readonly service = inject(AccountSearchService);
|
|
74
|
+
private readonly route = inject(ActivatedRoute);
|
|
75
|
+
private readonly router = inject(Router);
|
|
76
|
+
|
|
77
|
+
/** Reactive `:recordId` param — drives (and re-drives) the fetch. */
|
|
78
|
+
private readonly recordId = toSignal(
|
|
79
|
+
this.route.paramMap.pipe(map((p) => p.get("recordId") ?? "")),
|
|
80
|
+
{ initialValue: this.route.snapshot.paramMap.get("recordId") ?? "" },
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
private readonly result = createAsyncData(this.recordId, (id) =>
|
|
84
|
+
this.service.getAccountDetail(id),
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
protected readonly account = this.result.data;
|
|
88
|
+
protected readonly loading = this.result.loading;
|
|
89
|
+
protected readonly error = this.result.error;
|
|
90
|
+
/** True once a resolved fetch returned no record (distinct from loading). */
|
|
91
|
+
protected readonly notFound = computed(() => !this.loading() && !this.error() && !this.account());
|
|
92
|
+
|
|
93
|
+
/** Per-section collapsible open state (all default open, matching React). */
|
|
94
|
+
protected readonly additionalOpen = signal<boolean>(true);
|
|
95
|
+
protected readonly addressOpen = signal<boolean>(true);
|
|
96
|
+
protected readonly systemOpen = signal<boolean>(true);
|
|
97
|
+
|
|
98
|
+
/** Placeholder rows for skeleton field grids. */
|
|
99
|
+
protected readonly skeletonRows = [0, 1, 2];
|
|
100
|
+
|
|
101
|
+
// -- Breadcrumb leaf label -------------------------------------------------
|
|
102
|
+
protected readonly recordName = computed<string | undefined>(() => {
|
|
103
|
+
const a = this.account();
|
|
104
|
+
if (a) return fieldValue(a.Name) ?? "";
|
|
105
|
+
if (this.error()) return "Error";
|
|
106
|
+
if (this.loading()) return undefined;
|
|
107
|
+
return "Not Found";
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// -- Header ----------------------------------------------------------------
|
|
111
|
+
protected readonly title = computed(() => fieldValue(this.account()?.Name ?? null) ?? "");
|
|
112
|
+
|
|
113
|
+
// -- Top field rows --------------------------------------------------------
|
|
114
|
+
protected readonly topRows = computed<Field[][]>(() => {
|
|
115
|
+
const a = this.account();
|
|
116
|
+
if (!a) return [];
|
|
117
|
+
return [
|
|
118
|
+
[
|
|
119
|
+
{ label: "Account Owner", value: fieldValue(a.Owner?.Name) },
|
|
120
|
+
{ label: "Phone", value: fieldValue(a.Phone), telephone: true },
|
|
121
|
+
],
|
|
122
|
+
[
|
|
123
|
+
{ label: "Account Name", value: fieldValue(a.Name) },
|
|
124
|
+
{ label: "Fax", value: fieldValue(a.Fax), telephone: true },
|
|
125
|
+
],
|
|
126
|
+
[
|
|
127
|
+
{ label: "Parent Account", value: fieldValue(a.Parent?.Name) },
|
|
128
|
+
{ label: "Website", value: fieldValue(a.Website) },
|
|
129
|
+
],
|
|
130
|
+
];
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// -- Additional Information ------------------------------------------------
|
|
134
|
+
protected readonly additionalRows = computed<Field[][]>(() => {
|
|
135
|
+
const a = this.account();
|
|
136
|
+
if (!a) return [];
|
|
137
|
+
return [
|
|
138
|
+
[
|
|
139
|
+
{ label: "Type", value: fieldValue(a.Type) },
|
|
140
|
+
{ label: "Employees", value: fieldValue(a.NumberOfEmployees) },
|
|
141
|
+
],
|
|
142
|
+
[
|
|
143
|
+
{ label: "Industry", value: fieldValue(a.Industry) },
|
|
144
|
+
{ label: "Annual Revenue", value: fieldValue(a.AnnualRevenue) },
|
|
145
|
+
],
|
|
146
|
+
];
|
|
147
|
+
});
|
|
148
|
+
protected readonly description = computed(() => fieldValue(this.account()?.Description ?? null));
|
|
149
|
+
|
|
150
|
+
// -- Address Information ---------------------------------------------------
|
|
151
|
+
protected readonly billingAddress = computed<string[] | null>(() => {
|
|
152
|
+
const a = this.account();
|
|
153
|
+
if (!a) return null;
|
|
154
|
+
return getAddressFieldLines({
|
|
155
|
+
street: fieldValue(a.BillingStreet),
|
|
156
|
+
city: fieldValue(a.BillingCity),
|
|
157
|
+
state: fieldValue(a.BillingState),
|
|
158
|
+
postalCode: fieldValue(a.BillingPostalCode),
|
|
159
|
+
country: fieldValue(a.BillingCountry),
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
protected readonly shippingAddress = computed<string[] | null>(() => {
|
|
163
|
+
const a = this.account();
|
|
164
|
+
if (!a) return null;
|
|
165
|
+
return getAddressFieldLines({
|
|
166
|
+
street: fieldValue(a.ShippingStreet),
|
|
167
|
+
city: fieldValue(a.ShippingCity),
|
|
168
|
+
state: fieldValue(a.ShippingState),
|
|
169
|
+
postalCode: fieldValue(a.ShippingPostalCode),
|
|
170
|
+
country: fieldValue(a.ShippingCountry),
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
// -- System Information ----------------------------------------------------
|
|
175
|
+
protected readonly createdBy = computed(() =>
|
|
176
|
+
this.joinNameAndDate(this.account()?.CreatedBy?.Name, this.account()?.CreatedDate),
|
|
177
|
+
);
|
|
178
|
+
protected readonly lastModifiedBy = computed(() =>
|
|
179
|
+
this.joinNameAndDate(this.account()?.LastModifiedBy?.Name, this.account()?.LastModifiedDate),
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
private joinNameAndDate(
|
|
183
|
+
name: { value?: unknown; displayValue?: string | null } | null | undefined,
|
|
184
|
+
date: { value?: unknown; displayValue?: string | null } | null | undefined,
|
|
185
|
+
): string | null {
|
|
186
|
+
const formatted = formatDateTimeField(fieldValue(date ?? null), undefined, DATE_TIME_OPTIONS);
|
|
187
|
+
return [fieldValue(name ?? null), formatted].filter(Boolean).join(" ") || null;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/** Navigate back to the previous view (mirrors the React `navigate(-1)`). */
|
|
191
|
+
protected goBack(): void {
|
|
192
|
+
void this.router.navigate(["/accounts"]);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/** Full page reload retry, matching the React "Retry" affordance. */
|
|
196
|
+
protected reload(): void {
|
|
197
|
+
window.location.reload();
|
|
198
|
+
}
|
|
199
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
<div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
|
|
2
|
+
<app-object-breadcrumb listPath="/accounts" listLabel="Accounts" />
|
|
3
|
+
|
|
4
|
+
<h1 class="text-2xl font-bold mb-4">Search Accounts</h1>
|
|
5
|
+
|
|
6
|
+
<div class="flex flex-col lg:flex-row gap-6">
|
|
7
|
+
<!-- Sidebar — Filter Panel -->
|
|
8
|
+
<aside class="w-full lg:w-80 shrink-0">
|
|
9
|
+
<app-collapsible title="Filters" [(open)]="filtersOpen">
|
|
10
|
+
<div class="space-y-1">
|
|
11
|
+
<app-search-filter [config]="searchConfig" />
|
|
12
|
+
<app-text-filter [config]="nameConfig" />
|
|
13
|
+
<app-select-filter [config]="industryConfig()" />
|
|
14
|
+
<app-multi-select-filter [config]="typeConfig()" />
|
|
15
|
+
<app-numeric-range-filter [config]="revenueConfig" />
|
|
16
|
+
<app-date-filter [config]="createdConfig" filterType="datetime" />
|
|
17
|
+
<app-date-range-filter [config]="lastModifiedConfig" filterType="datetimerange" />
|
|
18
|
+
</div>
|
|
19
|
+
</app-collapsible>
|
|
20
|
+
</aside>
|
|
21
|
+
|
|
22
|
+
<!-- Main area — Sort + Results -->
|
|
23
|
+
<div class="flex-1 min-w-0">
|
|
24
|
+
<div class="flex flex-wrap items-center gap-2 mb-4">
|
|
25
|
+
<app-sort-control [sortFields]="sortConfigs" />
|
|
26
|
+
<app-active-filters />
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
<div class="min-h-132" [attr.aria-busy]="loading()">
|
|
30
|
+
@if (loading()) {
|
|
31
|
+
<app-skeleton class="h-5 w-30 mb-3" />
|
|
32
|
+
<div class="divide-y">
|
|
33
|
+
@for (row of skeletonRows(); track row) {
|
|
34
|
+
<div class="flex items-center justify-between py-3">
|
|
35
|
+
<div class="space-y-2">
|
|
36
|
+
<app-skeleton class="h-5 w-40" />
|
|
37
|
+
<app-skeleton class="h-4 w-28" />
|
|
38
|
+
</div>
|
|
39
|
+
<div class="space-y-2 flex flex-col items-end">
|
|
40
|
+
<app-skeleton class="h-4 w-24" />
|
|
41
|
+
<app-skeleton class="h-4 w-20" />
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
}
|
|
45
|
+
</div>
|
|
46
|
+
} @else if (error()) {
|
|
47
|
+
<p class="text-sm text-muted-foreground mb-3">0 accounts found</p>
|
|
48
|
+
<app-alert
|
|
49
|
+
variant="destructive"
|
|
50
|
+
icon="error"
|
|
51
|
+
title="Failed to load accounts"
|
|
52
|
+
description="Something went wrong while loading accounts. Please try again later."
|
|
53
|
+
/>
|
|
54
|
+
} @else if (nodes().length > 0) {
|
|
55
|
+
<p class="text-sm text-muted-foreground mb-3">{{ resultCountLabel() }}</p>
|
|
56
|
+
<ul class="divide-y">
|
|
57
|
+
@for (node of nodes(); track node.Id) {
|
|
58
|
+
<li>
|
|
59
|
+
<a
|
|
60
|
+
[routerLink]="['/accounts', node.Id]"
|
|
61
|
+
class="flex items-center justify-between py-3 px-3 -mx-3 rounded-md transition-colors hover:bg-accent"
|
|
62
|
+
>
|
|
63
|
+
<div>
|
|
64
|
+
<span class="font-medium">{{ name(node) }}</span>
|
|
65
|
+
<p class="text-sm text-muted-foreground">{{ secondaryLine(node) }}</p>
|
|
66
|
+
</div>
|
|
67
|
+
<div class="text-right text-sm">
|
|
68
|
+
<p>{{ phone(node) }}</p>
|
|
69
|
+
<p class="text-muted-foreground">{{ ownerName(node) }}</p>
|
|
70
|
+
</div>
|
|
71
|
+
</a>
|
|
72
|
+
</li>
|
|
73
|
+
}
|
|
74
|
+
</ul>
|
|
75
|
+
} @else {
|
|
76
|
+
<div class="flex flex-col items-center justify-center py-16 text-center">
|
|
77
|
+
<svg
|
|
78
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
79
|
+
class="size-12 text-muted-foreground mb-4"
|
|
80
|
+
viewBox="0 0 24 24"
|
|
81
|
+
fill="none"
|
|
82
|
+
stroke="currentColor"
|
|
83
|
+
stroke-width="2"
|
|
84
|
+
stroke-linecap="round"
|
|
85
|
+
stroke-linejoin="round"
|
|
86
|
+
aria-hidden="true"
|
|
87
|
+
>
|
|
88
|
+
<path d="m13.5 8.5-5 5" />
|
|
89
|
+
<path d="m8.5 8.5 5 5" />
|
|
90
|
+
<circle cx="11" cy="11" r="8" />
|
|
91
|
+
<path d="m21 21-4.3-4.3" />
|
|
92
|
+
</svg>
|
|
93
|
+
<h2 class="text-lg font-semibold mb-1">No accounts found</h2>
|
|
94
|
+
<p class="text-sm text-muted-foreground">
|
|
95
|
+
Try adjusting your filters or search criteria.
|
|
96
|
+
</p>
|
|
97
|
+
</div>
|
|
98
|
+
}
|
|
99
|
+
</div>
|
|
100
|
+
|
|
101
|
+
<!-- Pagination — always visible, disabled while loading or on error -->
|
|
102
|
+
<app-pagination-controls
|
|
103
|
+
[totalCount]="totalCount()"
|
|
104
|
+
[hasNextPage]="hasNextPage()"
|
|
105
|
+
[endCursor]="endCursor()"
|
|
106
|
+
[pageSizeOptions]="pageSizeOptions"
|
|
107
|
+
[disabled]="controlsDisabled()"
|
|
108
|
+
/>
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|