@salesforce/templates 66.11.0 → 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/{uiBundles/angularbasic/src/app/api/graphql-client.service.spec.ts → project/angularextapp/_p_/_m_/_w_/_a_/src/app/api/data-client.service.spec.ts} +36 -6
- 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 +864 -807
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/package-lock.json +857 -800
- package/lib/templates/uiBundles/angularbasic/angular.json +11 -7
- package/lib/templates/uiBundles/angularbasic/eslint.config.js +4 -0
- package/lib/templates/uiBundles/angularbasic/package-lock.json +351 -319
- package/lib/templates/uiBundles/angularbasic/package.json +4 -0
- package/lib/templates/uiBundles/angularbasic/src/app/api/data-client.service.spec.ts +184 -0
- package/lib/templates/uiBundles/angularbasic/src/app/api/data-client.service.ts +74 -0
- package/lib/templates/uiBundles/angularbasic/src/app/app.config.ts +15 -1
- package/lib/templates/uiBundles/angularbasic/src/app/app.routes.ts +6 -1
- package/lib/templates/uiBundles/angularbasic/src/app/app.ts +7 -2
- package/lib/templates/uiBundles/angularbasic/src/app/{layout → components/layout/app-layout}/app-layout.component.html +2 -1
- package/lib/templates/uiBundles/angularbasic/src/app/{layout → components/layout/app-layout}/app-layout.component.ts +9 -3
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/_field-size.scss +42 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/alert/alert.component.html +31 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/alert/alert.component.ts +53 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/button/button.component.html +18 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/button/button.component.scss +112 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/button/button.component.ts +57 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/card/card.component.scss +34 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/card/card.component.ts +110 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/collapsible/collapsible.component.html +10 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/collapsible/collapsible.component.ts +26 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/date-picker/date-picker.component.html +25 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/date-picker/date-picker.component.scss +36 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/date-picker/date-picker.component.ts +41 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/date-range-picker/date-range-picker.component.html +34 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/date-range-picker/date-range-picker.component.scss +33 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/date-range-picker/date-range-picker.component.ts +66 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/dialog/dialog.component.html +37 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/dialog/dialog.component.ts +55 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/field/field.component.html +21 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/field/field.component.ts +36 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/field-size.ts +8 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/input/input.component.html +19 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/input/input.component.scss +35 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/input/input.component.ts +36 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/label/label.component.html +3 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/label/label.component.ts +17 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/paginator/paginator.component.html +10 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/paginator/paginator.component.ts +37 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/popover/popover.component.html +41 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/popover/popover.component.ts +40 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/select/select.component.html +24 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/select/select.component.scss +35 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/select/select.component.ts +72 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/separator/separator.component.html +1 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/separator/separator.component.scss +23 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/separator/separator.component.ts +56 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/skeleton/skeleton.component.html +1 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/skeleton/skeleton.component.scss +28 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/skeleton/skeleton.component.ts +24 -0
- package/lib/templates/uiBundles/angularbasic/src/app/components/ui/spinner/spinner.component.ts +35 -0
- package/lib/templates/uiBundles/angularbasic/src/app/pages/home/home.component.ts +7 -1
- package/lib/templates/uiBundles/angularbasic/src/app/pages/not-found/not-found.component.ts +7 -1
- package/lib/templates/uiBundles/angularbasic/src/app/utils/async-data.ts +99 -0
- package/lib/templates/uiBundles/angularbasic/src/index.html +1 -0
- package/lib/templates/uiBundles/angularbasic/src/styles.scss +170 -0
- package/lib/templates/uiBundles/angularbasic/src/theme.scss +39 -0
- package/lib/templates/uiBundles/reactbasic/package-lock.json +857 -800
- 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 +5 -3
- package/lib/templates/uiBundles/angularbasic/src/app/api/graphql-client.service.ts +0 -48
- package/lib/templates/uiBundles/angularbasic/src/app/app.css +0 -0
- package/lib/templates/uiBundles/angularbasic/src/styles.css +0 -12
- /package/lib/templates/uiBundles/angularbasic/src/app/{layout → components/layout/app-layout}/app-layout.component.spec.ts +0 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<app-filter-field-wrapper
|
|
2
|
+
[label]="config().label"
|
|
3
|
+
[htmlFor]="inputId()"
|
|
4
|
+
[helpText]="config().helpText"
|
|
5
|
+
>
|
|
6
|
+
<app-input
|
|
7
|
+
type="text"
|
|
8
|
+
[placeholder]="config().placeholder ?? 'Filter by ' + config().label.toLowerCase() + '...'"
|
|
9
|
+
[value]="localValue()"
|
|
10
|
+
(valueChange)="onValueChange($event)"
|
|
11
|
+
/>
|
|
12
|
+
</app-filter-field-wrapper>
|
|
@@ -0,0 +1,90 @@
|
|
|
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
|
+
DestroyRef,
|
|
10
|
+
effect,
|
|
11
|
+
inject,
|
|
12
|
+
input,
|
|
13
|
+
signal,
|
|
14
|
+
} from "@angular/core";
|
|
15
|
+
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
|
16
|
+
import { Subject } from "rxjs";
|
|
17
|
+
import { debounceTime } from "rxjs/operators";
|
|
18
|
+
// Base-app UI wrapper, inherited (not recreated) by this feature. Post-compose
|
|
19
|
+
// it lands at uiBundles/<target>/src/app/components/ui/input/..., three levels up.
|
|
20
|
+
import { InputComponent } from "../../../components/ui/input/input";
|
|
21
|
+
import { ObjectSearchStateService } from "../object-search-state.service";
|
|
22
|
+
import { FILTER_DEBOUNCE_MS } from "../utils/debounce";
|
|
23
|
+
import type { FilterFieldConfig } from "../utils/filter-utils";
|
|
24
|
+
import { FilterFieldWrapperComponent } from "./filter-field-wrapper";
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Text filter — free-text input that writes a `like %value%` clause via
|
|
28
|
+
* {@link ObjectSearchStateService.setFilter}. Keystrokes update the local
|
|
29
|
+
* signal immediately (for a responsive UI) and flush to shared state on a
|
|
30
|
+
* {@link FILTER_DEBOUNCE_MS}ms trailing debounce (to avoid a query per key).
|
|
31
|
+
*
|
|
32
|
+
* Reads the current value from `state.filterFor(config.field)` so URL /
|
|
33
|
+
* reset-all changes reflect back into the input.
|
|
34
|
+
*/
|
|
35
|
+
@Component({
|
|
36
|
+
selector: "app-text-filter",
|
|
37
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
38
|
+
imports: [InputComponent, FilterFieldWrapperComponent],
|
|
39
|
+
templateUrl: "./text-filter.html",
|
|
40
|
+
})
|
|
41
|
+
export class TextFilterComponent {
|
|
42
|
+
private readonly state = inject(ObjectSearchStateService);
|
|
43
|
+
private readonly destroyRef = inject(DestroyRef);
|
|
44
|
+
|
|
45
|
+
/** Field config: `field`, `label`, `placeholder`, `helpText`, ... */
|
|
46
|
+
readonly config = input.required<FilterFieldConfig>();
|
|
47
|
+
|
|
48
|
+
/** Local (uncommitted) value that drives the input while the user is typing. */
|
|
49
|
+
protected readonly localValue = signal<string>("");
|
|
50
|
+
|
|
51
|
+
/** DOM id shared by the wrapper label and the underlying input. */
|
|
52
|
+
protected readonly inputId = signal<string>("");
|
|
53
|
+
|
|
54
|
+
/** Coalesces rapid keystrokes into one shared-state write. */
|
|
55
|
+
private readonly commit$ = new Subject<string>();
|
|
56
|
+
|
|
57
|
+
constructor() {
|
|
58
|
+
this.commit$
|
|
59
|
+
.pipe(debounceTime(FILTER_DEBOUNCE_MS), takeUntilDestroyed(this.destroyRef))
|
|
60
|
+
.subscribe((v) => this.commit(v));
|
|
61
|
+
|
|
62
|
+
// Sync the input with the shared state (URL restore, reset-all, ...).
|
|
63
|
+
// Mirrors the React "reset local when external changes" pattern.
|
|
64
|
+
effect(() => {
|
|
65
|
+
const cfg = this.config();
|
|
66
|
+
this.inputId.set(`filter-${cfg.field}`);
|
|
67
|
+
const external = this.state.filterFor(cfg.field)?.value ?? "";
|
|
68
|
+
this.localValue.set(external);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
protected onValueChange(v: string): void {
|
|
73
|
+
this.localValue.set(v);
|
|
74
|
+
this.commit$.next(v);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
private commit(v: string): void {
|
|
78
|
+
const cfg = this.config();
|
|
79
|
+
if (v) {
|
|
80
|
+
this.state.setFilter(cfg.field, {
|
|
81
|
+
field: cfg.field,
|
|
82
|
+
label: cfg.label,
|
|
83
|
+
type: "text",
|
|
84
|
+
value: v,
|
|
85
|
+
});
|
|
86
|
+
} else {
|
|
87
|
+
this.state.removeFilter(cfg.field);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,232 @@
|
|
|
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, DestroyRef, inject, Injectable, signal, type Signal } from "@angular/core";
|
|
7
|
+
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
|
8
|
+
import { ActivatedRoute, Router } from "@angular/router";
|
|
9
|
+
import { Subject } from "rxjs";
|
|
10
|
+
import { debounceTime } from "rxjs/operators";
|
|
11
|
+
import {
|
|
12
|
+
buildFilter,
|
|
13
|
+
filtersToQueryParams,
|
|
14
|
+
queryParamsToFilters,
|
|
15
|
+
type ActiveFilterValue,
|
|
16
|
+
type FilterFieldConfig,
|
|
17
|
+
} from "./utils/filter-utils";
|
|
18
|
+
import { buildOrderBy, type SortState } from "./utils/sort-utils";
|
|
19
|
+
|
|
20
|
+
/** How long to wait before flushing state changes to the URL. */
|
|
21
|
+
const URL_SYNC_DEBOUNCE_MS = 300;
|
|
22
|
+
|
|
23
|
+
/** Cursor-pagination configuration for an object-search page. */
|
|
24
|
+
export interface PaginationConfig {
|
|
25
|
+
defaultPageSize: number;
|
|
26
|
+
validPageSizes: number[];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Derived, API-ready query signals returned from {@link ObjectSearchStateService.init}. */
|
|
30
|
+
export interface ObjectSearchQuery<TFilter, TOrderBy> {
|
|
31
|
+
where: Signal<TFilter | undefined>;
|
|
32
|
+
orderBy: Signal<TOrderBy | undefined>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Filter / sort / cursor-pagination state for one object-search page — the
|
|
37
|
+
* Angular analogue of the React `useObjectSearchParams` hook plus
|
|
38
|
+
* `FilterContext`.
|
|
39
|
+
*
|
|
40
|
+
* ## State model
|
|
41
|
+
* Signals drive instant UI updates. The URL query params are the durable source
|
|
42
|
+
* of truth so a refresh or shared link restores the same view. URL writes are
|
|
43
|
+
* debounced (300 ms) to avoid history spam.
|
|
44
|
+
*
|
|
45
|
+
* Unlike the React reference, the pagination cursor (`after`) is part of the URL
|
|
46
|
+
* (see {@link filtersToQueryParams}), so a deep-linked page N fetches page N's
|
|
47
|
+
* rows rather than page 1's rows shown under a higher page number.
|
|
48
|
+
*
|
|
49
|
+
* ## Scope
|
|
50
|
+
* Provide per route/component (`providers: [ObjectSearchStateService]`), NOT in
|
|
51
|
+
* root — each search page owns its own state and cursor stack.
|
|
52
|
+
*
|
|
53
|
+
* ## Usage
|
|
54
|
+
* Call {@link init} once from the hosting component with the field/pagination
|
|
55
|
+
* config, then read the exposed signals and call the mutators.
|
|
56
|
+
*/
|
|
57
|
+
@Injectable()
|
|
58
|
+
export class ObjectSearchStateService {
|
|
59
|
+
private readonly router = inject(Router);
|
|
60
|
+
private readonly route = inject(ActivatedRoute);
|
|
61
|
+
private readonly destroyRef = inject(DestroyRef);
|
|
62
|
+
|
|
63
|
+
private filterConfigs: FilterFieldConfig[] = [];
|
|
64
|
+
private defaultPageSize = 10;
|
|
65
|
+
private validPageSizes: number[] = [10];
|
|
66
|
+
private initialized = false;
|
|
67
|
+
|
|
68
|
+
// -- Core state signals -----------------------------------------------------
|
|
69
|
+
private readonly _filters = signal<ActiveFilterValue[]>([]);
|
|
70
|
+
private readonly _sort = signal<SortState | null>(null);
|
|
71
|
+
private readonly _pageSize = signal<number>(10);
|
|
72
|
+
private readonly _pageIndex = signal<number>(0);
|
|
73
|
+
private readonly _afterCursor = signal<string | undefined>(undefined);
|
|
74
|
+
|
|
75
|
+
/** Cursor stack for "previous page" — mirrors the React ref-held stack. */
|
|
76
|
+
private cursorStack: string[] = [];
|
|
77
|
+
/** Coalesces rapid state changes into a single debounced URL write. */
|
|
78
|
+
private readonly urlSync$ = new Subject<void>();
|
|
79
|
+
|
|
80
|
+
// -- Public read signals -----------------------------------------------------
|
|
81
|
+
readonly filters: Signal<ActiveFilterValue[]> = this._filters.asReadonly();
|
|
82
|
+
readonly sort: Signal<SortState | null> = this._sort.asReadonly();
|
|
83
|
+
readonly pageSize: Signal<number> = this._pageSize.asReadonly();
|
|
84
|
+
readonly pageIndex: Signal<number> = this._pageIndex.asReadonly();
|
|
85
|
+
readonly afterCursor: Signal<string | undefined> = this._afterCursor.asReadonly();
|
|
86
|
+
readonly hasActiveFilters = computed(() => this._filters().length > 0);
|
|
87
|
+
readonly hasPreviousPage = computed(() => this._pageIndex() > 0);
|
|
88
|
+
|
|
89
|
+
constructor() {
|
|
90
|
+
this.urlSync$
|
|
91
|
+
.pipe(debounceTime(URL_SYNC_DEBOUNCE_MS), takeUntilDestroyed(this.destroyRef))
|
|
92
|
+
.subscribe(() => this.flushToUrl());
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Initializes the service from the given config and seeds state from the
|
|
97
|
+
* current URL. Safe to call once; subsequent calls only recompute the
|
|
98
|
+
* derived query signals.
|
|
99
|
+
*/
|
|
100
|
+
init<TFilter, TOrderBy>(
|
|
101
|
+
filterConfigs: FilterFieldConfig[],
|
|
102
|
+
paginationConfig?: PaginationConfig,
|
|
103
|
+
): ObjectSearchQuery<TFilter, TOrderBy> {
|
|
104
|
+
if (!this.initialized) {
|
|
105
|
+
this.initialized = true;
|
|
106
|
+
this.filterConfigs = filterConfigs;
|
|
107
|
+
this.defaultPageSize = paginationConfig?.defaultPageSize ?? 10;
|
|
108
|
+
this.validPageSizes = paginationConfig?.validPageSizes ?? [this.defaultPageSize];
|
|
109
|
+
this.seedFromUrl();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const where = computed(() => buildFilter<TFilter>(this._filters(), this.filterConfigs));
|
|
113
|
+
const orderBy = computed(() => buildOrderBy<TOrderBy>(this._sort()));
|
|
114
|
+
return { where, orderBy };
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// -- Filter mutators ---------------------------------------------------------
|
|
118
|
+
|
|
119
|
+
/** Adds or replaces the filter for `field`; `undefined` removes it. */
|
|
120
|
+
setFilter(field: string, value: ActiveFilterValue | undefined): void {
|
|
121
|
+
this._filters.update((prev) => {
|
|
122
|
+
const next = prev.filter((f) => f.field !== field);
|
|
123
|
+
if (value) next.push(value);
|
|
124
|
+
return next;
|
|
125
|
+
});
|
|
126
|
+
this.resetPagination();
|
|
127
|
+
this.urlSync$.next();
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** Removes the active filter for `field`, if any. */
|
|
131
|
+
removeFilter(field: string): void {
|
|
132
|
+
this._filters.update((prev) => prev.filter((f) => f.field !== field));
|
|
133
|
+
this.resetPagination();
|
|
134
|
+
this.urlSync$.next();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** Reads the active filter value for a field (for filter components). */
|
|
138
|
+
filterFor(field: string): ActiveFilterValue | undefined {
|
|
139
|
+
return this._filters().find((f) => f.field === field);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// -- Sort mutator ------------------------------------------------------------
|
|
143
|
+
|
|
144
|
+
/** Sets (or clears) the sort; resets pagination to the first page. */
|
|
145
|
+
setSort(sort: SortState | null): void {
|
|
146
|
+
this._sort.set(sort);
|
|
147
|
+
this.resetPagination();
|
|
148
|
+
this.urlSync$.next();
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// -- Pagination mutators -----------------------------------------------------
|
|
152
|
+
|
|
153
|
+
/** Advances to the next page using the supplied `endCursor`. */
|
|
154
|
+
goToNextPage(endCursor: string): void {
|
|
155
|
+
this.cursorStack = [...this.cursorStack, endCursor];
|
|
156
|
+
this._afterCursor.set(endCursor);
|
|
157
|
+
this._pageIndex.update((i) => i + 1);
|
|
158
|
+
this.urlSync$.next();
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/** Returns to the previous page by popping the cursor stack. */
|
|
162
|
+
goToPreviousPage(): void {
|
|
163
|
+
this.cursorStack = this.cursorStack.slice(0, -1);
|
|
164
|
+
const prev =
|
|
165
|
+
this.cursorStack.length > 0 ? this.cursorStack[this.cursorStack.length - 1] : undefined;
|
|
166
|
+
this._afterCursor.set(prev);
|
|
167
|
+
this._pageIndex.update((i) => Math.max(0, i - 1));
|
|
168
|
+
this.urlSync$.next();
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/** Sets a validated page size and resets pagination. */
|
|
172
|
+
setPageSize(size: number): void {
|
|
173
|
+
this._pageSize.set(this.getValidPageSize(size));
|
|
174
|
+
this.resetPagination();
|
|
175
|
+
this.urlSync$.next();
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// -- Reset -------------------------------------------------------------------
|
|
179
|
+
|
|
180
|
+
/** Clears all filters, sort, and pagination in one call (flushed at once). */
|
|
181
|
+
resetAll(): void {
|
|
182
|
+
this._filters.set([]);
|
|
183
|
+
this._sort.set(null);
|
|
184
|
+
this._pageSize.set(this.defaultPageSize);
|
|
185
|
+
this.resetPagination();
|
|
186
|
+
this.flushToUrl();
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// -- Internals ---------------------------------------------------------------
|
|
190
|
+
|
|
191
|
+
private resetPagination(): void {
|
|
192
|
+
this._pageIndex.set(0);
|
|
193
|
+
this._afterCursor.set(undefined);
|
|
194
|
+
this.cursorStack = [];
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
private getValidPageSize(size: number): number {
|
|
198
|
+
return this.validPageSizes.includes(size) ? size : this.defaultPageSize;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
private seedFromUrl(): void {
|
|
202
|
+
const params = this.route.snapshot.queryParams as Record<string, string | undefined>;
|
|
203
|
+
const parsed = queryParamsToFilters(params, this.filterConfigs);
|
|
204
|
+
this._filters.set(parsed.filters);
|
|
205
|
+
this._sort.set(parsed.sort);
|
|
206
|
+
this._pageSize.set(this.getValidPageSize(parsed.pageSize ?? this.defaultPageSize));
|
|
207
|
+
this._pageIndex.set(parsed.pageIndex);
|
|
208
|
+
this._afterCursor.set(parsed.afterCursor);
|
|
209
|
+
// Rebuild a minimal cursor stack so "previous" works after a deep link.
|
|
210
|
+
// Pages before the current one are unknown, so pad the stack with the
|
|
211
|
+
// current cursor; going back drains it and eventually returns to page 1.
|
|
212
|
+
if (parsed.pageIndex > 0 && parsed.afterCursor) {
|
|
213
|
+
this.cursorStack = Array<string>(parsed.pageIndex).fill(parsed.afterCursor);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
private flushToUrl(): void {
|
|
218
|
+
const queryParams = filtersToQueryParams({
|
|
219
|
+
filters: this._filters(),
|
|
220
|
+
sort: this._sort(),
|
|
221
|
+
pageSize: this._pageSize(),
|
|
222
|
+
pageIndex: this._pageIndex(),
|
|
223
|
+
afterCursor: this._afterCursor(),
|
|
224
|
+
});
|
|
225
|
+
void this.router.navigate([], {
|
|
226
|
+
relativeTo: this.route,
|
|
227
|
+
queryParams,
|
|
228
|
+
// Replace so filter typing doesn't flood browser history.
|
|
229
|
+
replaceUrl: true,
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}
|
|
@@ -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";
|
|
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.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";
|
|
19
|
+
import { InputComponent } from "../../../components/ui/input/input";
|
|
20
|
+
import { PopoverComponent } from "../../../components/ui/popover/popover";
|
|
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.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>
|