@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,55 @@
|
|
|
1
|
+
<nav aria-label="Breadcrumb" class="mb-3">
|
|
2
|
+
<ol
|
|
3
|
+
class="text-muted-foreground flex flex-wrap items-center gap-1.5 text-sm break-words sm:gap-2.5"
|
|
4
|
+
>
|
|
5
|
+
@if (includeHome()) {
|
|
6
|
+
<li class="inline-flex items-center gap-1.5">
|
|
7
|
+
<a [routerLink]="'/'" class="hover:text-foreground transition-colors">{{ homeLabel() }}</a>
|
|
8
|
+
</li>
|
|
9
|
+
<li aria-hidden="true" class="[&>svg]:size-3.5">
|
|
10
|
+
<svg
|
|
11
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
12
|
+
viewBox="0 0 24 24"
|
|
13
|
+
fill="none"
|
|
14
|
+
stroke="currentColor"
|
|
15
|
+
stroke-width="2"
|
|
16
|
+
stroke-linecap="round"
|
|
17
|
+
stroke-linejoin="round"
|
|
18
|
+
>
|
|
19
|
+
<polyline points="9 18 15 12 9 6" />
|
|
20
|
+
</svg>
|
|
21
|
+
</li>
|
|
22
|
+
}
|
|
23
|
+
@if (isDetailView()) {
|
|
24
|
+
<li class="inline-flex items-center gap-1.5">
|
|
25
|
+
<a [routerLink]="listPath()" class="hover:text-foreground transition-colors">{{
|
|
26
|
+
listLabel()
|
|
27
|
+
}}</a>
|
|
28
|
+
</li>
|
|
29
|
+
<li aria-hidden="true" class="[&>svg]:size-3.5">
|
|
30
|
+
<svg
|
|
31
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
32
|
+
viewBox="0 0 24 24"
|
|
33
|
+
fill="none"
|
|
34
|
+
stroke="currentColor"
|
|
35
|
+
stroke-width="2"
|
|
36
|
+
stroke-linecap="round"
|
|
37
|
+
stroke-linejoin="round"
|
|
38
|
+
>
|
|
39
|
+
<polyline points="9 18 15 12 9 6" />
|
|
40
|
+
</svg>
|
|
41
|
+
</li>
|
|
42
|
+
<li class="inline-flex items-center gap-1.5">
|
|
43
|
+
@if (loading() && !recordName()) {
|
|
44
|
+
<app-skeleton class="h-4 w-32" />
|
|
45
|
+
} @else {
|
|
46
|
+
<span class="text-foreground font-normal" aria-current="page">{{ recordName() }}</span>
|
|
47
|
+
}
|
|
48
|
+
</li>
|
|
49
|
+
} @else {
|
|
50
|
+
<li class="inline-flex items-center gap-1.5">
|
|
51
|
+
<span class="text-foreground font-normal" aria-current="page">{{ listLabel() }}</span>
|
|
52
|
+
</li>
|
|
53
|
+
}
|
|
54
|
+
</ol>
|
|
55
|
+
</nav>
|
|
@@ -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, computed, input } from "@angular/core";
|
|
7
|
+
import { RouterLink } from "@angular/router";
|
|
8
|
+
import { SkeletonComponent } from "../../../../components/ui/skeleton/skeleton.component";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Object-search breadcrumb — Home > Records list > (optional) Record name.
|
|
12
|
+
*
|
|
13
|
+
* Mirrors the React `ObjectBreadcrumb`. Renders the list-only crumb by default
|
|
14
|
+
* and switches to the detail-view crumb (with record name + skeleton fallback)
|
|
15
|
+
* as soon as `loading` or `recordName` is set. Uses Angular `routerLink` where
|
|
16
|
+
* the React version uses `react-router`'s `Link`.
|
|
17
|
+
*/
|
|
18
|
+
@Component({
|
|
19
|
+
selector: "app-object-breadcrumb",
|
|
20
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
21
|
+
imports: [RouterLink, SkeletonComponent],
|
|
22
|
+
templateUrl: "./object-breadcrumb.component.html",
|
|
23
|
+
})
|
|
24
|
+
export class ObjectBreadcrumbComponent {
|
|
25
|
+
/** Router path for the object list view (e.g. `/accounts`). */
|
|
26
|
+
readonly listPath = input.required<string>();
|
|
27
|
+
/** Label for the list crumb (e.g. `Accounts`). */
|
|
28
|
+
readonly listLabel = input.required<string>();
|
|
29
|
+
/** Record name for the detail-view leaf crumb; omit for list-only view. */
|
|
30
|
+
readonly recordName = input<string | undefined>(undefined);
|
|
31
|
+
/** Show a skeleton in the leaf crumb while the record is loading. */
|
|
32
|
+
readonly loading = input<boolean>(false);
|
|
33
|
+
/** Prepend a Home crumb (default `true`). */
|
|
34
|
+
readonly includeHome = input<boolean>(true);
|
|
35
|
+
/** Label for the Home crumb (default `Home`). */
|
|
36
|
+
readonly homeLabel = input<string>("Home");
|
|
37
|
+
|
|
38
|
+
/** `true` when the crumb should render list + record leaves. */
|
|
39
|
+
protected readonly isDetailView = computed(() => this.loading() || !!this.recordName());
|
|
40
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
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, inject, input } from "@angular/core";
|
|
7
|
+
import type { PageEvent } from "@angular/material/paginator";
|
|
8
|
+
import { PaginatorComponent } from "../../../../components/ui/paginator/paginator.component";
|
|
9
|
+
import { ObjectSearchStateService } from "../../object-search-state.service";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Cursor-pagination bridge. Feeds the shared cursor state into the presentational
|
|
13
|
+
* {@link PaginatorComponent} (`app-paginator`) and translates its offset-style
|
|
14
|
+
* `(page)` event back into the cursor walk the state service understands.
|
|
15
|
+
*
|
|
16
|
+
* State comes from the shared {@link ObjectSearchStateService} (`pageIndex`,
|
|
17
|
+
* `pageSize`); the hosting page supplies the cursor-derived inputs
|
|
18
|
+
* (`totalCount`, `hasNextPage`, `endCursor`) after each fetch. A next-page step
|
|
19
|
+
* needs the current `endCursor`; a previous step and page-size changes are
|
|
20
|
+
* handled entirely by the state service's cursor stack.
|
|
21
|
+
*/
|
|
22
|
+
@Component({
|
|
23
|
+
selector: "app-pagination-controls",
|
|
24
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
25
|
+
imports: [PaginatorComponent],
|
|
26
|
+
templateUrl: "./pagination-controls.component.html",
|
|
27
|
+
})
|
|
28
|
+
export class PaginationControlsComponent {
|
|
29
|
+
/** Total row count from the latest fetch; drives the paginator's range label. */
|
|
30
|
+
readonly totalCount = input<number | undefined>(undefined);
|
|
31
|
+
/** Whether the API reports another page after the current one. */
|
|
32
|
+
readonly hasNextPage = input<boolean>(false);
|
|
33
|
+
/** `endCursor` from the latest page-info; forwarded to `goToNextPage`. */
|
|
34
|
+
readonly endCursor = input<string | undefined>(undefined);
|
|
35
|
+
/** Allowed page-size choices. */
|
|
36
|
+
readonly pageSizeOptions = input.required<readonly number[]>();
|
|
37
|
+
/** Disable navigation and the size select (e.g. while loading). */
|
|
38
|
+
readonly disabled = input<boolean>(false);
|
|
39
|
+
|
|
40
|
+
private readonly state = inject(ObjectSearchStateService);
|
|
41
|
+
protected readonly pageIndex = this.state.pageIndex;
|
|
42
|
+
protected readonly pageSize = this.state.pageSize;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Route Material's offset-style page event onto the cursor model: a page-size
|
|
46
|
+
* change resets pagination; a forward step walks the `endCursor`; a backward
|
|
47
|
+
* step pops the cursor stack.
|
|
48
|
+
*/
|
|
49
|
+
protected onPage(event: PageEvent): void {
|
|
50
|
+
if (event.pageSize !== this.pageSize()) {
|
|
51
|
+
this.state.setPageSize(event.pageSize);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (event.pageIndex > this.pageIndex()) {
|
|
55
|
+
const cursor = this.endCursor();
|
|
56
|
+
if (cursor && this.hasNextPage()) this.state.goToNextPage(cursor);
|
|
57
|
+
} else if (event.pageIndex < this.pageIndex()) {
|
|
58
|
+
this.state.goToPreviousPage();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
<div class="flex items-center gap-2 w-full">
|
|
2
|
+
<div class="relative flex-1">
|
|
3
|
+
<svg
|
|
4
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
5
|
+
class="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground pointer-events-none z-10"
|
|
6
|
+
viewBox="0 0 24 24"
|
|
7
|
+
fill="none"
|
|
8
|
+
stroke="currentColor"
|
|
9
|
+
stroke-width="2"
|
|
10
|
+
stroke-linecap="round"
|
|
11
|
+
stroke-linejoin="round"
|
|
12
|
+
aria-hidden="true"
|
|
13
|
+
>
|
|
14
|
+
<circle cx="11" cy="11" r="8" />
|
|
15
|
+
<path d="m21 21-4.3-4.3" />
|
|
16
|
+
</svg>
|
|
17
|
+
<app-input
|
|
18
|
+
class="pl-9 block"
|
|
19
|
+
type="text"
|
|
20
|
+
[placeholder]="searchConfig().placeholder ?? ''"
|
|
21
|
+
[label]="searchConfig().label"
|
|
22
|
+
[(value)]="term"
|
|
23
|
+
/>
|
|
24
|
+
</div>
|
|
25
|
+
<app-popover [(open)]="popoverOpen" align="end">
|
|
26
|
+
<app-button
|
|
27
|
+
trigger
|
|
28
|
+
appearance="outlined"
|
|
29
|
+
[attr.aria-expanded]="popoverOpen()"
|
|
30
|
+
aria-label="Toggle filters"
|
|
31
|
+
class="gap-2"
|
|
32
|
+
>
|
|
33
|
+
<svg
|
|
34
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
35
|
+
class="h-4 w-4"
|
|
36
|
+
viewBox="0 0 24 24"
|
|
37
|
+
fill="none"
|
|
38
|
+
stroke="currentColor"
|
|
39
|
+
stroke-width="2"
|
|
40
|
+
stroke-linecap="round"
|
|
41
|
+
stroke-linejoin="round"
|
|
42
|
+
aria-hidden="true"
|
|
43
|
+
>
|
|
44
|
+
<path d="M3 6h18M7 12h10M10 18h4" />
|
|
45
|
+
</svg>
|
|
46
|
+
<span>Filters</span>
|
|
47
|
+
@if (nonSearchFilterCount() > 0) {
|
|
48
|
+
<span
|
|
49
|
+
class="inline-flex items-center justify-center h-5 min-w-5 rounded-full bg-primary text-primary-foreground text-xs px-1"
|
|
50
|
+
>
|
|
51
|
+
{{ nonSearchFilterCount() }}
|
|
52
|
+
</span>
|
|
53
|
+
}
|
|
54
|
+
</app-button>
|
|
55
|
+
<div class="p-3 min-w-72 max-w-96 space-y-3">
|
|
56
|
+
<ng-content select="[filters]" />
|
|
57
|
+
</div>
|
|
58
|
+
</app-popover>
|
|
59
|
+
</div>
|
|
@@ -0,0 +1,108 @@
|
|
|
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
|
+
ChangeDetectionStrategy,
|
|
8
|
+
Component,
|
|
9
|
+
computed,
|
|
10
|
+
DestroyRef,
|
|
11
|
+
inject,
|
|
12
|
+
input,
|
|
13
|
+
type OnInit,
|
|
14
|
+
signal,
|
|
15
|
+
} from "@angular/core";
|
|
16
|
+
import { takeUntilDestroyed, toObservable } from "@angular/core/rxjs-interop";
|
|
17
|
+
import { debounceTime } from "rxjs/operators";
|
|
18
|
+
import { ButtonComponent } from "../../../../components/ui/button/button.component";
|
|
19
|
+
import { InputComponent } from "../../../../components/ui/input/input.component";
|
|
20
|
+
import { PopoverComponent } from "../../../../components/ui/popover/popover.component";
|
|
21
|
+
import { ObjectSearchStateService } from "../../object-search-state.service";
|
|
22
|
+
import type { FilterFieldConfig } from "../../utils/filter-utils";
|
|
23
|
+
|
|
24
|
+
/** How long to wait after the last keystroke before writing to state. */
|
|
25
|
+
const SEARCH_DEBOUNCE_MS = 300;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Search-bar header for an object-search page: a debounced text input bound to
|
|
29
|
+
* the `search` filter, plus an optional filter popover that content-projects
|
|
30
|
+
* the sibling filter components (owned by the filters wave).
|
|
31
|
+
*
|
|
32
|
+
* Mirrors the React `SearchBar`, with the composed additions from the ground-
|
|
33
|
+
* truth example page (filter panel toggle). Filter components are NOT imported
|
|
34
|
+
* here — the hosting page projects them via the `[filters]` slot so the
|
|
35
|
+
* feature can pick which filters it renders.
|
|
36
|
+
*
|
|
37
|
+
* ## Usage
|
|
38
|
+
* ```html
|
|
39
|
+
* <app-search-bar [searchConfig]="searchCfg" [filterConfigs]="filterCfgs">
|
|
40
|
+
* <div filters>
|
|
41
|
+
* <app-text-filter .../>
|
|
42
|
+
* <app-select-filter .../>
|
|
43
|
+
* </div>
|
|
44
|
+
* </app-search-bar>
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
@Component({
|
|
48
|
+
selector: "app-search-bar",
|
|
49
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
50
|
+
imports: [ButtonComponent, InputComponent, PopoverComponent],
|
|
51
|
+
templateUrl: "./search-bar.component.html",
|
|
52
|
+
})
|
|
53
|
+
export class SearchBarComponent implements OnInit {
|
|
54
|
+
/** Config for the multi-field search filter (its label, placeholder, etc.). */
|
|
55
|
+
readonly searchConfig = input.required<FilterFieldConfig>();
|
|
56
|
+
/**
|
|
57
|
+
* Configs for the filters projected into the popover. Not consumed directly
|
|
58
|
+
* here — surfaced so the hosting page and this component agree on which
|
|
59
|
+
* filters exist, and reserved for a future filter-count badge.
|
|
60
|
+
*/
|
|
61
|
+
readonly filterConfigs = input<FilterFieldConfig[]>([]);
|
|
62
|
+
|
|
63
|
+
private readonly state = inject(ObjectSearchStateService);
|
|
64
|
+
private readonly destroyRef = inject(DestroyRef);
|
|
65
|
+
|
|
66
|
+
/** Local, debounced mirror of the search filter's `value`. */
|
|
67
|
+
protected readonly term = signal<string>("");
|
|
68
|
+
protected readonly popoverOpen = signal<boolean>(false);
|
|
69
|
+
|
|
70
|
+
/** Count of currently active filters minus the search itself (for the badge). */
|
|
71
|
+
protected readonly nonSearchFilterCount = computed(
|
|
72
|
+
() => this.state.filters().filter((f) => f.type !== "search").length,
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
constructor() {
|
|
76
|
+
// Required inputs are not yet resolved in the constructor, so the search
|
|
77
|
+
// config is read lazily inside the subscription (which emits after init).
|
|
78
|
+
toObservable(this.term)
|
|
79
|
+
.pipe(debounceTime(SEARCH_DEBOUNCE_MS), takeUntilDestroyed(this.destroyRef))
|
|
80
|
+
.subscribe((value) => {
|
|
81
|
+
const cfg = this.searchConfig();
|
|
82
|
+
if (value) {
|
|
83
|
+
this.state.setFilter(cfg.field, {
|
|
84
|
+
field: cfg.field,
|
|
85
|
+
label: cfg.label,
|
|
86
|
+
type: cfg.type,
|
|
87
|
+
value,
|
|
88
|
+
});
|
|
89
|
+
} else {
|
|
90
|
+
this.state.removeFilter(cfg.field);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
ngOnInit(): void {
|
|
96
|
+
// Seed the local term from any existing search filter (deep-link support).
|
|
97
|
+
// Done here (not the constructor) so the required `searchConfig` input is
|
|
98
|
+
// resolved before it is read.
|
|
99
|
+
const existing = this.state.filterFor(this.searchConfig().field);
|
|
100
|
+
if (existing?.value) {
|
|
101
|
+
this.term.set(existing.value);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
protected togglePopover(): void {
|
|
106
|
+
this.popoverOpen.set(!this.popoverOpen());
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<div class="flex items-center gap-2">
|
|
2
|
+
<span class="text-sm text-muted-foreground whitespace-nowrap">{{ label() }}</span>
|
|
3
|
+
<app-select
|
|
4
|
+
class="w-[160px]"
|
|
5
|
+
[options]="options()"
|
|
6
|
+
[value]="selectedValue()"
|
|
7
|
+
(valueChange)="onFieldChange($event)"
|
|
8
|
+
placeholder="Default"
|
|
9
|
+
/>
|
|
10
|
+
@if (sort(); as active) {
|
|
11
|
+
<app-button
|
|
12
|
+
appearance="text"
|
|
13
|
+
size="icon-sm"
|
|
14
|
+
[attr.aria-label]="'Sort ' + (active.direction === 'ASC' ? 'descending' : 'ascending')"
|
|
15
|
+
(clicked)="toggleDirection()"
|
|
16
|
+
>
|
|
17
|
+
@if (active.direction === "ASC") {
|
|
18
|
+
<svg
|
|
19
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
20
|
+
class="h-4 w-4"
|
|
21
|
+
viewBox="0 0 24 24"
|
|
22
|
+
fill="none"
|
|
23
|
+
stroke="currentColor"
|
|
24
|
+
stroke-width="2"
|
|
25
|
+
stroke-linecap="round"
|
|
26
|
+
stroke-linejoin="round"
|
|
27
|
+
aria-hidden="true"
|
|
28
|
+
>
|
|
29
|
+
<path d="m5 12 7-7 7 7" />
|
|
30
|
+
<path d="M12 19V5" />
|
|
31
|
+
</svg>
|
|
32
|
+
} @else {
|
|
33
|
+
<svg
|
|
34
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
35
|
+
class="h-4 w-4"
|
|
36
|
+
viewBox="0 0 24 24"
|
|
37
|
+
fill="none"
|
|
38
|
+
stroke="currentColor"
|
|
39
|
+
stroke-width="2"
|
|
40
|
+
stroke-linecap="round"
|
|
41
|
+
stroke-linejoin="round"
|
|
42
|
+
aria-hidden="true"
|
|
43
|
+
>
|
|
44
|
+
<path d="M12 5v14" />
|
|
45
|
+
<path d="m19 12-7 7-7-7" />
|
|
46
|
+
</svg>
|
|
47
|
+
}
|
|
48
|
+
</app-button>
|
|
49
|
+
}
|
|
50
|
+
</div>
|
|
@@ -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 { ChangeDetectionStrategy, Component, computed, inject, input } from "@angular/core";
|
|
7
|
+
import { ButtonComponent } from "../../../../components/ui/button/button.component";
|
|
8
|
+
import {
|
|
9
|
+
SelectComponent,
|
|
10
|
+
type AppSelectOption,
|
|
11
|
+
} from "../../../../components/ui/select/select.component";
|
|
12
|
+
import { ObjectSearchStateService } from "../../object-search-state.service";
|
|
13
|
+
import type { SortFieldConfig, SortState } from "../../utils/sort-utils";
|
|
14
|
+
|
|
15
|
+
/** Sentinel value used in the select to represent "no sort". */
|
|
16
|
+
const NONE_VALUE = "__none__";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Sort field + direction toggle. Mirrors the React `SortControl`.
|
|
20
|
+
*
|
|
21
|
+
* Reads `sort()` from the {@link ObjectSearchStateService} and drives changes
|
|
22
|
+
* via `setSort`. Choosing a field applies ASC by default; the direction button
|
|
23
|
+
* flips ASC/DESC and only appears while a sort is active. Selecting `Default`
|
|
24
|
+
* clears the sort (`setSort(null)`).
|
|
25
|
+
*/
|
|
26
|
+
@Component({
|
|
27
|
+
selector: "app-sort-control",
|
|
28
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
29
|
+
imports: [ButtonComponent, SelectComponent],
|
|
30
|
+
templateUrl: "./sort-control.component.html",
|
|
31
|
+
})
|
|
32
|
+
export class SortControlComponent {
|
|
33
|
+
/** Sortable fields to expose in the select. */
|
|
34
|
+
readonly sortFields = input.required<SortFieldConfig[]>();
|
|
35
|
+
/** Override for the leading label (default `Sort by`). */
|
|
36
|
+
readonly label = input<string>("Sort by");
|
|
37
|
+
|
|
38
|
+
private readonly state = inject(ObjectSearchStateService);
|
|
39
|
+
/** Current sort state from the shared state service. */
|
|
40
|
+
protected readonly sort = this.state.sort;
|
|
41
|
+
|
|
42
|
+
/** Select options — the `Default` sentinel plus one per sortable field. */
|
|
43
|
+
protected readonly options = computed<AppSelectOption[]>(() => [
|
|
44
|
+
{ value: NONE_VALUE, label: "Default" },
|
|
45
|
+
...this.sortFields().map((c) => ({ value: c.field, label: c.label })),
|
|
46
|
+
]);
|
|
47
|
+
|
|
48
|
+
/** Value shown in the select — either the current field or the sentinel. */
|
|
49
|
+
protected readonly selectedValue = computed(() => this.sort()?.field ?? NONE_VALUE);
|
|
50
|
+
|
|
51
|
+
protected onFieldChange(field: string): void {
|
|
52
|
+
if (field === NONE_VALUE) {
|
|
53
|
+
this.state.setSort(null);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const current = this.sort();
|
|
57
|
+
const next: SortState = {
|
|
58
|
+
field,
|
|
59
|
+
direction: current?.direction ?? "ASC",
|
|
60
|
+
};
|
|
61
|
+
this.state.setSort(next);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
protected toggleDirection(): void {
|
|
65
|
+
const current = this.sort();
|
|
66
|
+
if (!current) return;
|
|
67
|
+
this.state.setSort({
|
|
68
|
+
field: current.field,
|
|
69
|
+
direction: current.direction === "ASC" ? "DESC" : "ASC",
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|