@salesforce/templates 66.17.4 → 66.18.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/analyticsTemplateGenerator.d.ts +1 -1
- package/lib/generators/analyticsTemplateGenerator.js +1 -1
- package/lib/generators/analyticsTemplateGenerator.js.map +1 -1
- package/lib/generators/apexClassGenerator.d.ts +1 -1
- package/lib/generators/apexClassGenerator.js +1 -0
- package/lib/generators/apexClassGenerator.js.map +1 -1
- package/lib/generators/apexTriggerGenerator.d.ts +1 -1
- package/lib/generators/baseGenerator.d.ts +1 -1
- package/lib/generators/baseGenerator.js +13 -7
- package/lib/generators/baseGenerator.js.map +1 -1
- package/lib/generators/digitalExperienceSiteGenerator.d.ts +1 -2
- package/lib/generators/digitalExperienceSiteGenerator.js +9 -9
- package/lib/generators/digitalExperienceSiteGenerator.js.map +1 -1
- package/lib/generators/flexipageGenerator.d.ts +1 -2
- package/lib/generators/flexipageGenerator.js +5 -7
- package/lib/generators/flexipageGenerator.js.map +1 -1
- package/lib/generators/lightningAppGenerator.d.ts +1 -1
- package/lib/generators/lightningComponentGenerator.d.ts +1 -1
- package/lib/generators/lightningEventGenerator.d.ts +1 -1
- package/lib/generators/lightningInterfaceGenerator.d.ts +1 -1
- package/lib/generators/lightningOutGenerator.d.ts +1 -1
- package/lib/generators/lightningOutGenerator.js +21 -5
- package/lib/generators/lightningOutGenerator.js.map +1 -1
- package/lib/generators/lightningTestGenerator.d.ts +1 -1
- package/lib/generators/lightningTestGenerator.js +1 -1
- package/lib/generators/lightningTestGenerator.js.map +1 -1
- package/lib/generators/projectGenerator.d.ts +1 -1
- package/lib/generators/projectGenerator.js +8 -5
- package/lib/generators/projectGenerator.js.map +1 -1
- package/lib/generators/staticResourceGenerator.d.ts +1 -1
- package/lib/generators/uiBundleGenerator.d.ts +1 -1
- package/lib/generators/uiBundleGenerator.js +4 -2
- package/lib/generators/uiBundleGenerator.js.map +1 -1
- package/lib/generators/uiEmbeddingGenerator.d.ts +1 -1
- package/lib/generators/uiEmbeddingGenerator.js +2 -1
- package/lib/generators/uiEmbeddingGenerator.js.map +1 -1
- package/lib/generators/visualforceComponentGenerator.d.ts +1 -1
- package/lib/generators/visualforcePageGenerator.d.ts +1 -1
- package/lib/i18n/index.js +1 -1
- package/lib/i18n/index.js.map +1 -1
- package/lib/i18n/localization.js +13 -12
- package/lib/i18n/localization.js.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/service/gitRepoUtils.d.ts +1 -1
- package/lib/service/gitRepoUtils.js +7 -8
- package/lib/service/gitRepoUtils.js.map +1 -1
- package/lib/service/templateService.d.ts +1 -1
- package/lib/service/templateService.js +1 -1
- package/lib/service/templateService.js.map +1 -1
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/package-lock.json +558 -533
- package/lib/templates/project/angularintapp/CHANGELOG.md +8 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/eslint.config.js +2 -1
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/package-lock.json +568 -543
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/package.json +4 -4
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/icon/icon.ts +44 -0
- package/lib/templates/project/angularintapp/package.json +1 -1
- package/lib/templates/project/reactexternalapp/CHANGELOG.md +40 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/eslint.config.js +8 -12
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/package-lock.json +362 -344
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/package.json +5 -5
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/components/ui/button.tsx +1 -1
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/components/ui/sonner.tsx +7 -1
- package/lib/templates/project/reactexternalapp/package.json +1 -1
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/package-lock.json +363 -345
- package/lib/templates/project/vueinternalapp/.forceignore +15 -0
- package/lib/templates/project/vueinternalapp/.husky/pre-commit +4 -0
- package/lib/templates/project/vueinternalapp/.prettierignore +11 -0
- package/lib/templates/project/vueinternalapp/.prettierrc +17 -0
- package/lib/templates/project/vueinternalapp/CHANGELOG.md +5375 -0
- package/lib/templates/project/vueinternalapp/PRD.md +35 -0
- package/lib/templates/project/vueinternalapp/README.md +125 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_ps_/vueinternalapp_Access.permissionset-meta.xml +13 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/.forceignore +15 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/.graphqlrc.yml +2 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/.prettierignore +9 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/.prettierrc +11 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/README.md +35 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/codegen.yml +95 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/components.json +19 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/e2e/app.spec.ts +17 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/eslint.config.js +124 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/index.html +12 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/package-lock.json +15530 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/package.json +73 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/playwright.config.ts +24 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/scripts/get-graphql-schema.mjs +71 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/scripts/rewrite-e2e-assets.mjs +23 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/App.vue +5 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/api/apiUtils.ts +56 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/api/orgApiVersionService.ts +37 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/api/searchableContentTypesService.ts +119 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/channelResolver.ts +40 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/cmsQueryFragment.ts +108 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/composables/useSearchableContentTypes.ts +132 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/contentTypeSessionCache.ts +134 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/contentTypeUtils.ts +40 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/index.ts +55 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/parseResponse.ts +65 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/searchChannel.ts +31 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/types.ts +66 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/registry.ts +38 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/sobject/index.ts +19 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/sobject/parseResponse.ts +55 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/sobject/queryFragment.ts +141 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/types.ts +103 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/api/distinctValuesService.ts +81 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/api/searchService.ts +136 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/GlobalSearchBox.types.ts +18 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/GlobalSearchBox.vue +73 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/MergedSearchResults.types.ts +24 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/MergedSearchResults.vue +263 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/Search.vue +200 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/SearchResults.vue +99 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/SourceSection.vue +204 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/PaginationControls.vue +180 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/ScopeSelector.vue +91 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/SearchBar.vue +56 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/SortControl.vue +55 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/ActiveFilters.vue +59 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/DefaultFilterField.vue +63 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/DefaultFilterPanel.vue +31 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/FilterContext.ts +45 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/FilterProvider.vue +23 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/FilterResetButton.vue +17 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/PicklistField.vue +35 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/BooleanFilter.vue +47 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/DateRangeFilter.vue +144 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/FilterFieldWrapper.vue +23 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/MultiSelectFilter.vue +95 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/NumericRangeFilter.vue +117 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/SelectFilter.vue +44 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/TextFilter.vue +49 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/results/CmsResultRow.vue +160 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/results/DefaultResultRow.vue +102 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/results/RenderVNode.ts +10 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/results/resolveResultRenderer.ts +41 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/composables/useAsyncData.ts +66 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/composables/useDistinctValues.ts +67 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/composables/useSearch.ts +906 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/config.json +88 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/constants.ts +8 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/index.ts +115 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/loadConfig.ts +14 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/queryBuilder.ts +100 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/types.ts +375 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/debounce.ts +17 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/fieldUtils.ts +14 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/filterUtils.ts +304 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/sortUtils.ts +34 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/api/account/query/getAccountDetail.graphql +121 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/api/graphqlClient.ts +44 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/appLayout.vue +153 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/AgentforceConversationClient.vue +76 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/account/AccountDetailContent.vue +124 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/account/AccountDetailError.vue +28 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/account/AccountDetailNotFound.vue +22 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/account/AccountDetailSkeleton.vue +57 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/account/DetailSection.vue +25 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/account/FieldItem.vue +17 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/account/FieldRow.vue +5 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/account/SkeletonFieldRow.vue +12 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/account/TelephoneField.vue +7 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/account/types.ts +42 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/alerts/status-alert.vue +59 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/layouts/card-layout.vue +30 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/alert/Alert.vue +21 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/alert/AlertAction.vue +17 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/alert/AlertDescription.vue +22 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/alert/AlertTitle.vue +22 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/alert/index.ts +25 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/avatar/Avatar.vue +23 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/avatar/AvatarFallback.vue +31 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/avatar/AvatarImage.vue +16 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/avatar/index.ts +3 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/button/Button.vue +33 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/button/index.ts +43 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/card/Card.vue +29 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/card/CardAction.vue +22 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/card/CardContent.vue +17 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/card/CardDescription.vue +17 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/card/CardFooter.vue +22 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/card/CardHeader.vue +22 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/card/CardTitle.vue +22 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/card/index.ts +7 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/checkbox/Checkbox.vue +43 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/checkbox/index.ts +1 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/collapsible/Collapsible.vue +19 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/collapsible/CollapsibleContent.vue +12 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/collapsible/CollapsibleTrigger.vue +12 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/collapsible/index.ts +3 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dialog/Dialog.vue +15 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dialog/DialogClose.vue +12 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dialog/DialogContent.vue +59 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dialog/DialogDescription.vue +31 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dialog/DialogFooter.vue +33 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dialog/DialogHeader.vue +17 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dialog/DialogOverlay.vue +31 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dialog/DialogPortal.vue +12 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dialog/DialogTitle.vue +26 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dialog/DialogTrigger.vue +12 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dialog/index.ts +10 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenu.vue +19 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +51 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenuContent.vue +47 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenuGroup.vue +12 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenuItem.vue +44 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenuLabel.vue +30 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenuPortal.vue +12 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +21 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +52 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenuSeparator.vue +26 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenuShortcut.vue +19 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenuSub.vue +19 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenuSubContent.vue +37 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +38 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenuTrigger.vue +17 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/index.ts +15 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/field/Field.vue +27 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/field/FieldContent.vue +22 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/field/FieldDescription.vue +24 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/field/FieldError.vue +48 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/field/FieldGroup.vue +22 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/field/FieldLabel.vue +24 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/field/FieldLegend.vue +29 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/field/FieldSeparator.vue +31 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/field/FieldSet.vue +22 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/field/FieldTitle.vue +22 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/field/index.ts +33 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/index.ts +115 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/input/Input.vue +30 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/input/index.ts +1 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/label/Label.vue +29 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/label/index.ts +1 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/pagination/Pagination.vue +17 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/pagination/PaginationContent.vue +15 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/pagination/PaginationEllipsis.vue +23 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/pagination/PaginationItem.vue +7 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/pagination/PaginationLink.vue +31 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/pagination/PaginationNext.vue +29 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/pagination/PaginationPrevious.vue +29 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/pagination/index.ts +7 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/popover/Popover.vue +15 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/popover/PopoverAnchor.vue +12 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/popover/PopoverContent.vue +44 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/popover/PopoverDescription.vue +17 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/popover/PopoverHeader.vue +17 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/popover/PopoverTitle.vue +14 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/popover/PopoverTrigger.vue +12 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/popover/index.ts +7 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/select/Select.vue +15 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/select/SelectContent.vue +65 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/select/SelectGroup.vue +26 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/select/SelectItem.vue +41 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/select/SelectLabel.vue +26 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/select/SelectScrollDownButton.vue +32 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/select/SelectScrollUpButton.vue +32 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/select/SelectSeparator.vue +24 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/select/SelectTrigger.vue +45 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/select/SelectValue.vue +12 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/select/index.ts +10 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/separator/Separator.vue +33 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/separator/index.ts +1 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/skeleton/Skeleton.vue +15 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/skeleton/index.ts +1 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/sonner/Sonner.vue +29 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/sonner/index.ts +3 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/spinner/Spinner.vue +17 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/spinner/index.ts +1 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/composables/useAsyncData.ts +69 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/index.ts +10 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/lib/utils.ts +6 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/main.ts +6 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/pages/AccountObjectDetailPage.vue +98 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/pages/Home.vue +20 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/pages/NotFound.vue +28 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/pages/SearchPage.vue +17 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/router-utils.ts +32 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/router.ts +51 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/styles/global.css +134 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/test/setup.ts +1 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/types/conversation.ts +54 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/types/globals.d.ts +13 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/utils/accountFields.ts +25 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/tsconfig.json +45 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/tsconfig.node.json +13 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/tsconfig.tsbuildinfo +1 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/ui-bundle.json +7 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/vite-env.d.ts +14 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/vite.config.ts +106 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/vitest-env.d.ts +2 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/vueinternalapp.uibundle-meta.xml +8 -0
- package/lib/templates/project/vueinternalapp/_p_/_m_/applications/vueinternalapp.app-meta.xml +17 -0
- package/lib/templates/project/vueinternalapp/config/project-scratch-def.json +13 -0
- package/lib/templates/project/vueinternalapp/eslint.config.js +7 -0
- package/lib/templates/project/vueinternalapp/jest.config.js +6 -0
- package/lib/templates/project/vueinternalapp/package.json +46 -0
- package/lib/templates/project/vueinternalapp/scripts/apex/hello.apex +10 -0
- package/lib/templates/project/vueinternalapp/scripts/gitignore-templates.json +4 -0
- package/lib/templates/project/vueinternalapp/scripts/graphql-search.sh +191 -0
- package/lib/templates/project/vueinternalapp/scripts/network-senders.mjs +84 -0
- package/lib/templates/project/vueinternalapp/scripts/org-setup-config-schema.mjs +132 -0
- package/lib/templates/project/vueinternalapp/scripts/org-setup-dev.mjs +114 -0
- package/lib/templates/project/vueinternalapp/scripts/org-setup-url.mjs +108 -0
- package/lib/templates/project/vueinternalapp/scripts/org-setup-utils.mjs +569 -0
- package/lib/templates/project/vueinternalapp/scripts/org-setup-xml.mjs +283 -0
- package/lib/templates/project/vueinternalapp/scripts/org-setup.config.json +9 -0
- package/lib/templates/project/vueinternalapp/scripts/org-setup.mjs +2545 -0
- package/lib/templates/project/vueinternalapp/scripts/sf-project-setup.mjs +103 -0
- package/lib/templates/project/vueinternalapp/scripts/soql/account.soql +6 -0
- package/lib/templates/project/vueinternalapp/scripts/validate-org-setup-config.mjs +38 -0
- package/lib/templates/project/vueinternalapp/sfdx-project.json +12 -0
- package/lib/templates/uiBundles/angularbasic/package-lock.json +558 -533
- package/lib/templates/uiBundles/reactbasic/eslint.config.js +8 -12
- package/lib/templates/uiBundles/reactbasic/package-lock.json +362 -344
- package/lib/templates/uiBundles/reactbasic/package.json +5 -5
- package/lib/templates/uiBundles/reactbasic/src/components/ui/button.tsx +1 -1
- package/lib/templates/uiBundles/reactbasic/src/components/ui/sonner.tsx +7 -1
- package/lib/templates/uiBundles/vuebasic/eslint.config.js +6 -1
- package/lib/templates/uiBundles/vuebasic/package-lock.json +339 -321
- package/lib/templates/uiBundles/vuebasic/package.json +5 -5
- package/lib/utils/createUtil.js +1 -1
- package/lib/utils/createUtil.js.map +1 -1
- package/lib/utils/types.d.ts +8 -7
- package/lib/utils/types.js +4 -4
- package/lib/utils/types.js.map +1 -1
- package/lib/utils/uiBundleTemplateUtils.js +13 -9
- package/lib/utils/uiBundleTemplateUtils.js.map +1 -1
- package/package.json +10 -12
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import TextFilter from "./inputs/TextFilter.vue";
|
|
3
|
+
import NumericRangeFilter from "./inputs/NumericRangeFilter.vue";
|
|
4
|
+
import BooleanFilter from "./inputs/BooleanFilter.vue";
|
|
5
|
+
import DateRangeFilter from "./inputs/DateRangeFilter.vue";
|
|
6
|
+
import PicklistField from "./PicklistField.vue";
|
|
7
|
+
import type { FilterFieldConfig } from "../../utils/filterUtils";
|
|
8
|
+
import type { SObjectSourceConfig } from "../../types";
|
|
9
|
+
|
|
10
|
+
defineProps<{ filter: FilterFieldConfig; source: SObjectSourceConfig }>();
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<template>
|
|
14
|
+
<TextFilter
|
|
15
|
+
v-if="filter.type === 'text'"
|
|
16
|
+
:field="filter.field"
|
|
17
|
+
:label="filter.label"
|
|
18
|
+
:placeholder="filter.placeholder"
|
|
19
|
+
:help-text="filter.helpText"
|
|
20
|
+
/>
|
|
21
|
+
<PicklistField
|
|
22
|
+
v-else-if="filter.type === 'picklist'"
|
|
23
|
+
:filter="filter"
|
|
24
|
+
:source="source"
|
|
25
|
+
:multi="false"
|
|
26
|
+
/>
|
|
27
|
+
<PicklistField
|
|
28
|
+
v-else-if="filter.type === 'multipicklist'"
|
|
29
|
+
:filter="filter"
|
|
30
|
+
:source="source"
|
|
31
|
+
:multi="true"
|
|
32
|
+
/>
|
|
33
|
+
<NumericRangeFilter
|
|
34
|
+
v-else-if="filter.type === 'numeric'"
|
|
35
|
+
:field="filter.field"
|
|
36
|
+
:label="filter.label"
|
|
37
|
+
:help-text="filter.helpText"
|
|
38
|
+
:min="filter.min"
|
|
39
|
+
:max="filter.max"
|
|
40
|
+
/>
|
|
41
|
+
<BooleanFilter
|
|
42
|
+
v-else-if="filter.type === 'boolean'"
|
|
43
|
+
:field="filter.field"
|
|
44
|
+
:label="filter.label"
|
|
45
|
+
:help-text="filter.helpText"
|
|
46
|
+
/>
|
|
47
|
+
<DateRangeFilter
|
|
48
|
+
v-else-if="filter.type === 'date' || filter.type === 'daterange'"
|
|
49
|
+
:field="filter.field"
|
|
50
|
+
:label="filter.label"
|
|
51
|
+
:help-text="filter.helpText"
|
|
52
|
+
filter-type="daterange"
|
|
53
|
+
:mode="filter.dateMode"
|
|
54
|
+
/>
|
|
55
|
+
<DateRangeFilter
|
|
56
|
+
v-else-if="filter.type === 'datetime' || filter.type === 'datetimerange'"
|
|
57
|
+
:field="filter.field"
|
|
58
|
+
:label="filter.label"
|
|
59
|
+
:help-text="filter.helpText"
|
|
60
|
+
filter-type="datetimerange"
|
|
61
|
+
:mode="filter.dateMode"
|
|
62
|
+
/>
|
|
63
|
+
</template>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Default filter panel used when no custom filters are supplied for a source.
|
|
4
|
+
*
|
|
5
|
+
* Renders one input per entry in `source.filterBy`, picking the right
|
|
6
|
+
* component for each `FilterFieldType`:
|
|
7
|
+
*
|
|
8
|
+
* - text -> TextFilter
|
|
9
|
+
* - picklist -> SelectFilter (inline options or auto-fetched)
|
|
10
|
+
* - multipicklist -> MultiSelectFilter (inline options or auto-fetched)
|
|
11
|
+
* - numeric -> NumericRangeFilter
|
|
12
|
+
* - boolean -> BooleanFilter
|
|
13
|
+
* - date / daterange / datetime / datetimerange -> DateRangeFilter
|
|
14
|
+
* (its Between / After / Before chrome is chosen by `filter.dateMode`)
|
|
15
|
+
*/
|
|
16
|
+
import type { SObjectSourceConfig } from "../../types";
|
|
17
|
+
import DefaultFilterField from "./DefaultFilterField.vue";
|
|
18
|
+
|
|
19
|
+
defineProps<{ source: SObjectSourceConfig }>();
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<template>
|
|
23
|
+
<template v-if="(source.filterBy ?? []).length > 0">
|
|
24
|
+
<DefaultFilterField
|
|
25
|
+
v-for="filter in source.filterBy"
|
|
26
|
+
:key="filter.field"
|
|
27
|
+
:filter="filter"
|
|
28
|
+
:source="source"
|
|
29
|
+
/>
|
|
30
|
+
</template>
|
|
31
|
+
</template>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filter context for custom filter UIs. `<FilterProvider>` provides the active
|
|
3
|
+
* filters plus change/remove/reset callbacks; `useFilterField` and
|
|
4
|
+
* `useFilterPanel` read them from any descendant.
|
|
5
|
+
*/
|
|
6
|
+
import {
|
|
7
|
+
computed,
|
|
8
|
+
inject,
|
|
9
|
+
toValue,
|
|
10
|
+
type ComputedRef,
|
|
11
|
+
type InjectionKey,
|
|
12
|
+
type MaybeRefOrGetter,
|
|
13
|
+
} from "vue";
|
|
14
|
+
import type { ActiveFilterValue } from "../../utils/filterUtils";
|
|
15
|
+
|
|
16
|
+
export interface FilterContextValue {
|
|
17
|
+
filters: ComputedRef<ActiveFilterValue[]>;
|
|
18
|
+
onFilterChange: (field: string, value: ActiveFilterValue | undefined) => void;
|
|
19
|
+
onFilterRemove: (field: string) => void;
|
|
20
|
+
onReset: () => void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const FILTER_CONTEXT_KEY: InjectionKey<FilterContextValue> = Symbol("search-filter-context");
|
|
24
|
+
|
|
25
|
+
function useFilterContext(): FilterContextValue {
|
|
26
|
+
const ctx = inject(FILTER_CONTEXT_KEY, null);
|
|
27
|
+
if (!ctx) throw new Error("useFilterField must be used within a FilterProvider");
|
|
28
|
+
return ctx;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function useFilterField(field: MaybeRefOrGetter<string>) {
|
|
32
|
+
const { filters, onFilterChange, onFilterRemove } = useFilterContext();
|
|
33
|
+
const value = computed(() => filters.value.find((f) => f.field === toValue(field)));
|
|
34
|
+
const onChange = (next: ActiveFilterValue | undefined) => {
|
|
35
|
+
const name = toValue(field);
|
|
36
|
+
if (next) onFilterChange(name, next);
|
|
37
|
+
else onFilterRemove(name);
|
|
38
|
+
};
|
|
39
|
+
return { value, onChange };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function useFilterPanel() {
|
|
43
|
+
const { filters, onReset } = useFilterContext();
|
|
44
|
+
return { hasActiveFilters: computed(() => filters.value.length > 0), resetAll: onReset };
|
|
45
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, provide } from "vue";
|
|
3
|
+
import type { ActiveFilterValue } from "../../utils/filterUtils";
|
|
4
|
+
import { FILTER_CONTEXT_KEY } from "./FilterContext";
|
|
5
|
+
|
|
6
|
+
const props = defineProps<{ filters: ActiveFilterValue[] }>();
|
|
7
|
+
const emit = defineEmits<{
|
|
8
|
+
filterChange: [field: string, value: ActiveFilterValue | undefined];
|
|
9
|
+
filterRemove: [field: string];
|
|
10
|
+
reset: [];
|
|
11
|
+
}>();
|
|
12
|
+
|
|
13
|
+
provide(FILTER_CONTEXT_KEY, {
|
|
14
|
+
filters: computed(() => props.filters),
|
|
15
|
+
onFilterChange: (field, value) => emit("filterChange", field, value),
|
|
16
|
+
onFilterRemove: (field) => emit("filterRemove", field),
|
|
17
|
+
onReset: () => emit("reset"),
|
|
18
|
+
});
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<template>
|
|
22
|
+
<slot />
|
|
23
|
+
</template>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { Button } from "../../../../components/ui/button";
|
|
3
|
+
import { useFilterPanel } from "./FilterContext";
|
|
4
|
+
|
|
5
|
+
const { hasActiveFilters, resetAll } = useFilterPanel();
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<template>
|
|
9
|
+
<Button
|
|
10
|
+
v-if="hasActiveFilters"
|
|
11
|
+
aria-label="Reset filters"
|
|
12
|
+
variant="destructive"
|
|
13
|
+
@click="resetAll"
|
|
14
|
+
>
|
|
15
|
+
<slot>Reset</slot>
|
|
16
|
+
</Button>
|
|
17
|
+
</template>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Resolves picklist options from inline config first; falls back to fetching
|
|
4
|
+
* distinct values from the GraphQL aggregate API.
|
|
5
|
+
*/
|
|
6
|
+
import { computed } from "vue";
|
|
7
|
+
import { useDistinctValues } from "../../composables/useDistinctValues";
|
|
8
|
+
import SelectFilter from "./inputs/SelectFilter.vue";
|
|
9
|
+
import MultiSelectFilter from "./inputs/MultiSelectFilter.vue";
|
|
10
|
+
import type { FilterFieldConfig } from "../../utils/filterUtils";
|
|
11
|
+
import type { SObjectSourceConfig } from "../../types";
|
|
12
|
+
|
|
13
|
+
const props = defineProps<{
|
|
14
|
+
filter: FilterFieldConfig;
|
|
15
|
+
source: SObjectSourceConfig;
|
|
16
|
+
multi: boolean;
|
|
17
|
+
}>();
|
|
18
|
+
|
|
19
|
+
const fetched = useDistinctValues(() =>
|
|
20
|
+
props.filter.options
|
|
21
|
+
? null
|
|
22
|
+
: { objectName: props.source.objectName, fieldName: props.filter.field },
|
|
23
|
+
);
|
|
24
|
+
const options = computed(() => props.filter.options ?? fetched.value ?? []);
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<template>
|
|
28
|
+
<component
|
|
29
|
+
:is="multi ? MultiSelectFilter : SelectFilter"
|
|
30
|
+
:field="filter.field"
|
|
31
|
+
:label="filter.label"
|
|
32
|
+
:options="options"
|
|
33
|
+
:help-text="filter.helpText"
|
|
34
|
+
/>
|
|
35
|
+
</template>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import {
|
|
3
|
+
Select,
|
|
4
|
+
SelectContent,
|
|
5
|
+
SelectItem,
|
|
6
|
+
SelectTrigger,
|
|
7
|
+
SelectValue,
|
|
8
|
+
} from "../../../../../components/ui/select";
|
|
9
|
+
import { useFilterField } from "../FilterContext";
|
|
10
|
+
import FilterFieldWrapper from "./FilterFieldWrapper.vue";
|
|
11
|
+
|
|
12
|
+
const ANY_VALUE = "__any__";
|
|
13
|
+
|
|
14
|
+
const props = withDefaults(
|
|
15
|
+
defineProps<{
|
|
16
|
+
field: string;
|
|
17
|
+
label: string;
|
|
18
|
+
trueLabel?: string;
|
|
19
|
+
falseLabel?: string;
|
|
20
|
+
helpText?: string;
|
|
21
|
+
}>(),
|
|
22
|
+
{ trueLabel: "Yes", falseLabel: "No" },
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
const { value, onChange } = useFilterField(() => props.field);
|
|
26
|
+
const id = `filter-${props.field}`;
|
|
27
|
+
|
|
28
|
+
const onValueChange = (v: unknown) => {
|
|
29
|
+
if (v === ANY_VALUE) onChange(undefined);
|
|
30
|
+
else onChange({ field: props.field, label: props.label, type: "boolean", value: String(v) });
|
|
31
|
+
};
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<template>
|
|
35
|
+
<FilterFieldWrapper :label="label" :html-for="id" :help-text="helpText">
|
|
36
|
+
<Select :model-value="value?.value ?? ANY_VALUE" @update:model-value="onValueChange">
|
|
37
|
+
<SelectTrigger :id="id" class="w-full">
|
|
38
|
+
<SelectValue />
|
|
39
|
+
</SelectTrigger>
|
|
40
|
+
<SelectContent>
|
|
41
|
+
<SelectItem :value="ANY_VALUE">Any</SelectItem>
|
|
42
|
+
<SelectItem value="true">{{ trueLabel }}</SelectItem>
|
|
43
|
+
<SelectItem value="false">{{ falseLabel }}</SelectItem>
|
|
44
|
+
</SelectContent>
|
|
45
|
+
</Select>
|
|
46
|
+
</FilterFieldWrapper>
|
|
47
|
+
</template>
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref } from "vue";
|
|
3
|
+
import { Input } from "../../../../../components/ui/input";
|
|
4
|
+
import {
|
|
5
|
+
Select,
|
|
6
|
+
SelectContent,
|
|
7
|
+
SelectItem,
|
|
8
|
+
SelectTrigger,
|
|
9
|
+
SelectValue,
|
|
10
|
+
} from "../../../../../components/ui/select";
|
|
11
|
+
import { useFilterField } from "../FilterContext";
|
|
12
|
+
import FilterFieldWrapper from "./FilterFieldWrapper.vue";
|
|
13
|
+
import type {
|
|
14
|
+
ActiveFilterValue,
|
|
15
|
+
DateFilterMode,
|
|
16
|
+
FilterFieldType,
|
|
17
|
+
} from "../../../utils/filterUtils";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* A date constraint whose chrome is driven by `mode`:
|
|
21
|
+
* - "range": a single Between control (two date inputs).
|
|
22
|
+
* - "comparison" (default): an After / Before selector with one input.
|
|
23
|
+
* - "both": a Between / After / Before selector spanning the two.
|
|
24
|
+
* They map onto the `min`/`max` bounds the query builder understands
|
|
25
|
+
* (after -> min only, before -> max only, between -> both).
|
|
26
|
+
*/
|
|
27
|
+
type DateOperator = "between" | "after" | "before";
|
|
28
|
+
|
|
29
|
+
const props = withDefaults(
|
|
30
|
+
defineProps<{
|
|
31
|
+
field: string;
|
|
32
|
+
label: string;
|
|
33
|
+
helpText?: string;
|
|
34
|
+
/** "daterange" (Date scalar) or "datetimerange" (DateTime scalar). */
|
|
35
|
+
filterType?: Extract<FilterFieldType, "daterange" | "datetimerange">;
|
|
36
|
+
/** Which comparison chrome to show. See DateFilterMode. */
|
|
37
|
+
mode?: DateFilterMode;
|
|
38
|
+
}>(),
|
|
39
|
+
{ filterType: "daterange", mode: "comparison" },
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
const OPERATOR_LABELS: Record<DateOperator, string> = {
|
|
43
|
+
between: "Between",
|
|
44
|
+
after: "After",
|
|
45
|
+
before: "Before",
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const MODE_OPERATORS: Record<DateFilterMode, DateOperator[]> = {
|
|
49
|
+
range: ["between"],
|
|
50
|
+
comparison: ["after", "before"],
|
|
51
|
+
both: ["between", "after", "before"],
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/** Pick the operator implied by an already-active filter (e.g. restored from the URL). */
|
|
55
|
+
function operatorFor(value: ActiveFilterValue | undefined): DateOperator {
|
|
56
|
+
const hasMin = !!value?.min;
|
|
57
|
+
const hasMax = !!value?.max;
|
|
58
|
+
if (hasMax && !hasMin) return "before";
|
|
59
|
+
if (hasMin && !hasMax) return "after";
|
|
60
|
+
return "between";
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const { value, onChange } = useFilterField(() => props.field);
|
|
64
|
+
const operators = MODE_OPERATORS[props.mode];
|
|
65
|
+
|
|
66
|
+
// Operator is local UI state: it must survive a moment where no date is yet
|
|
67
|
+
// entered (which clears the active filter), so it can't be derived from `value`.
|
|
68
|
+
const restored = operatorFor(value.value);
|
|
69
|
+
const operator = ref<DateOperator>(operators.includes(restored) ? restored : operators[0]);
|
|
70
|
+
|
|
71
|
+
const emitValue = (nextMin: string | undefined, nextMax: string | undefined) => {
|
|
72
|
+
if (!nextMin && !nextMax) onChange(undefined);
|
|
73
|
+
else
|
|
74
|
+
onChange({
|
|
75
|
+
field: props.field,
|
|
76
|
+
label: props.label,
|
|
77
|
+
type: props.filterType,
|
|
78
|
+
min: nextMin,
|
|
79
|
+
max: nextMax,
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const changeOperator = (next: unknown) => {
|
|
84
|
+
const op = next as DateOperator;
|
|
85
|
+
operator.value = op;
|
|
86
|
+
// Re-emit, keeping only the bound(s) the new operator uses.
|
|
87
|
+
if (op === "after") emitValue(value.value?.min, undefined);
|
|
88
|
+
else if (op === "before") emitValue(undefined, value.value?.max);
|
|
89
|
+
else emitValue(value.value?.min, value.value?.max);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const str = (v: string | number | undefined) =>
|
|
93
|
+
v === undefined || v === "" ? undefined : String(v);
|
|
94
|
+
const operatorId = `filter-${props.field}-op`;
|
|
95
|
+
// A lone "between" operator (mode="range") needs no selector — it can't change.
|
|
96
|
+
const showSelector = operators.length > 1;
|
|
97
|
+
</script>
|
|
98
|
+
|
|
99
|
+
<template>
|
|
100
|
+
<FilterFieldWrapper :label="label" :help-text="helpText">
|
|
101
|
+
<div class="flex flex-col gap-2">
|
|
102
|
+
<Select v-if="showSelector" :model-value="operator" @update:model-value="changeOperator">
|
|
103
|
+
<SelectTrigger :id="operatorId" class="w-full" :aria-label="`${label} comparison`">
|
|
104
|
+
<SelectValue />
|
|
105
|
+
</SelectTrigger>
|
|
106
|
+
<SelectContent>
|
|
107
|
+
<SelectItem v-for="op in operators" :key="op" :value="op">{{
|
|
108
|
+
OPERATOR_LABELS[op]
|
|
109
|
+
}}</SelectItem>
|
|
110
|
+
</SelectContent>
|
|
111
|
+
</Select>
|
|
112
|
+
|
|
113
|
+
<div v-if="operator === 'between'" class="flex items-center gap-2">
|
|
114
|
+
<Input
|
|
115
|
+
type="date"
|
|
116
|
+
:model-value="value?.min ?? ''"
|
|
117
|
+
:aria-label="`${label} from`"
|
|
118
|
+
@update:model-value="(v) => emitValue(str(v), value?.max)"
|
|
119
|
+
/>
|
|
120
|
+
<span class="text-sm text-muted-foreground">–</span>
|
|
121
|
+
<Input
|
|
122
|
+
type="date"
|
|
123
|
+
:model-value="value?.max ?? ''"
|
|
124
|
+
:aria-label="`${label} to`"
|
|
125
|
+
@update:model-value="(v) => emitValue(value?.min, str(v))"
|
|
126
|
+
/>
|
|
127
|
+
</div>
|
|
128
|
+
<Input
|
|
129
|
+
v-else-if="operator === 'after'"
|
|
130
|
+
type="date"
|
|
131
|
+
:model-value="value?.min ?? ''"
|
|
132
|
+
:aria-label="`${label} after`"
|
|
133
|
+
@update:model-value="(v) => emitValue(str(v), undefined)"
|
|
134
|
+
/>
|
|
135
|
+
<Input
|
|
136
|
+
v-else
|
|
137
|
+
type="date"
|
|
138
|
+
:model-value="value?.max ?? ''"
|
|
139
|
+
:aria-label="`${label} before`"
|
|
140
|
+
@update:model-value="(v) => emitValue(undefined, str(v))"
|
|
141
|
+
/>
|
|
142
|
+
</div>
|
|
143
|
+
</FilterFieldWrapper>
|
|
144
|
+
</template>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { Label } from "../../../../../components/ui/label";
|
|
3
|
+
|
|
4
|
+
defineProps<{
|
|
5
|
+
label: string;
|
|
6
|
+
htmlFor?: string;
|
|
7
|
+
errorId?: string;
|
|
8
|
+
helpText?: string;
|
|
9
|
+
error?: string;
|
|
10
|
+
class?: string;
|
|
11
|
+
}>();
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<template>
|
|
15
|
+
<div :class="['space-y-1', $props.class]">
|
|
16
|
+
<Label :for="htmlFor">{{ label }}</Label>
|
|
17
|
+
<slot />
|
|
18
|
+
<div class="min-h-4">
|
|
19
|
+
<p v-if="error" :id="errorId" role="alert" class="text-xs text-destructive">{{ error }}</p>
|
|
20
|
+
<p v-else-if="helpText" class="text-xs text-muted-foreground">{{ helpText }}</p>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
</template>
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed } from "vue";
|
|
3
|
+
import { ChevronDown } from "@lucide/vue";
|
|
4
|
+
import { Button } from "../../../../../components/ui/button";
|
|
5
|
+
import { Checkbox } from "../../../../../components/ui/checkbox";
|
|
6
|
+
import { Label } from "../../../../../components/ui/label";
|
|
7
|
+
import {
|
|
8
|
+
Popover,
|
|
9
|
+
PopoverContent,
|
|
10
|
+
PopoverTrigger,
|
|
11
|
+
} from "../../../../../components/ui/popover";
|
|
12
|
+
import { useFilterField } from "../FilterContext";
|
|
13
|
+
import FilterFieldWrapper from "./FilterFieldWrapper.vue";
|
|
14
|
+
|
|
15
|
+
const props = defineProps<{
|
|
16
|
+
field: string;
|
|
17
|
+
label: string;
|
|
18
|
+
options: Array<{ value: string; label: string }>;
|
|
19
|
+
helpText?: string;
|
|
20
|
+
}>();
|
|
21
|
+
|
|
22
|
+
const { value, onChange } = useFilterField(() => props.field);
|
|
23
|
+
const selected = computed(
|
|
24
|
+
() => new Set(value.value?.value ? value.value.value.split(",").filter(Boolean) : []),
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
const toggle = (v: string, on: boolean) => {
|
|
28
|
+
const next = new Set(selected.value);
|
|
29
|
+
if (on) next.add(v);
|
|
30
|
+
else next.delete(v);
|
|
31
|
+
const joined = Array.from(next).join(",");
|
|
32
|
+
if (joined === "") onChange(undefined);
|
|
33
|
+
else onChange({ field: props.field, label: props.label, type: "multipicklist", value: joined });
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// Summarize the selection on the collapsed trigger: the sole label when one is
|
|
37
|
+
// picked, a count when several are, and a placeholder when none.
|
|
38
|
+
const summary = computed(() => {
|
|
39
|
+
const size = selected.value.size;
|
|
40
|
+
if (size === 0) return `Select ${props.label.toLowerCase()}`;
|
|
41
|
+
if (size === 1) {
|
|
42
|
+
return props.options.find((o) => selected.value.has(o.value))?.label ?? `${size} selected`;
|
|
43
|
+
}
|
|
44
|
+
return `${size} selected`;
|
|
45
|
+
});
|
|
46
|
+
const triggerId = `filter-${props.field}`;
|
|
47
|
+
</script>
|
|
48
|
+
|
|
49
|
+
<template>
|
|
50
|
+
<FilterFieldWrapper :label="label" :html-for="triggerId" :help-text="helpText">
|
|
51
|
+
<Popover>
|
|
52
|
+
<PopoverTrigger as-child>
|
|
53
|
+
<Button
|
|
54
|
+
:id="triggerId"
|
|
55
|
+
variant="outline"
|
|
56
|
+
class="w-full justify-between font-normal"
|
|
57
|
+
:aria-label="`${label}: ${summary}`"
|
|
58
|
+
>
|
|
59
|
+
<span :class="['truncate', selected.size === 0 ? 'text-foreground/70' : '']">{{
|
|
60
|
+
summary
|
|
61
|
+
}}</span>
|
|
62
|
+
<ChevronDown class="ml-2 size-4 shrink-0 opacity-50" aria-hidden="true" />
|
|
63
|
+
</Button>
|
|
64
|
+
</PopoverTrigger>
|
|
65
|
+
<PopoverContent
|
|
66
|
+
align="start"
|
|
67
|
+
:aria-label="label"
|
|
68
|
+
class="w-(--reka-popover-trigger-width) max-h-72 overflow-y-auto"
|
|
69
|
+
>
|
|
70
|
+
<div role="group" class="flex flex-col gap-1">
|
|
71
|
+
<p v-if="options.length === 0" class="px-1 py-2 text-sm text-muted-foreground">
|
|
72
|
+
No options available.
|
|
73
|
+
</p>
|
|
74
|
+
<template v-else>
|
|
75
|
+
<div v-for="opt in options" :key="opt.value" class="flex items-center gap-2">
|
|
76
|
+
<Checkbox
|
|
77
|
+
:id="`filter-${field}-${opt.value}`"
|
|
78
|
+
:model-value="selected.has(opt.value)"
|
|
79
|
+
@update:model-value="
|
|
80
|
+
(checked: boolean | 'indeterminate') => toggle(opt.value, checked === true)
|
|
81
|
+
"
|
|
82
|
+
/>
|
|
83
|
+
<Label
|
|
84
|
+
:for="`filter-${field}-${opt.value}`"
|
|
85
|
+
class="text-sm font-normal cursor-pointer"
|
|
86
|
+
>
|
|
87
|
+
{{ opt.label }}
|
|
88
|
+
</Label>
|
|
89
|
+
</div>
|
|
90
|
+
</template>
|
|
91
|
+
</div>
|
|
92
|
+
</PopoverContent>
|
|
93
|
+
</Popover>
|
|
94
|
+
</FilterFieldWrapper>
|
|
95
|
+
</template>
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, ref, useId, watch } from "vue";
|
|
3
|
+
import { Input } from "../../../../../components/ui/input";
|
|
4
|
+
import { useFilterField } from "../FilterContext";
|
|
5
|
+
import FilterFieldWrapper from "./FilterFieldWrapper.vue";
|
|
6
|
+
import { debounce, FILTER_DEBOUNCE_MS } from "../../../utils/debounce";
|
|
7
|
+
|
|
8
|
+
const props = defineProps<{
|
|
9
|
+
field: string;
|
|
10
|
+
label: string;
|
|
11
|
+
helpText?: string;
|
|
12
|
+
min?: number;
|
|
13
|
+
max?: number;
|
|
14
|
+
}>();
|
|
15
|
+
|
|
16
|
+
const { value, onChange } = useFilterField(() => props.field);
|
|
17
|
+
const errorId = useId();
|
|
18
|
+
const draftMin = ref<string>(value.value?.min ?? "");
|
|
19
|
+
const draftMax = ref<string>(value.value?.max ?? "");
|
|
20
|
+
|
|
21
|
+
const emitDebounced = debounce((nextMin: string, nextMax: string) => {
|
|
22
|
+
if (!nextMin && !nextMax) onChange(undefined);
|
|
23
|
+
else
|
|
24
|
+
onChange({
|
|
25
|
+
field: props.field,
|
|
26
|
+
label: props.label,
|
|
27
|
+
type: "numeric",
|
|
28
|
+
min: nextMin || undefined,
|
|
29
|
+
max: nextMax || undefined,
|
|
30
|
+
});
|
|
31
|
+
}, FILTER_DEBOUNCE_MS);
|
|
32
|
+
|
|
33
|
+
watch(
|
|
34
|
+
() => [value.value?.min, value.value?.max],
|
|
35
|
+
([nextMin, nextMax]) => {
|
|
36
|
+
draftMin.value = nextMin ?? "";
|
|
37
|
+
draftMax.value = nextMax ?? "";
|
|
38
|
+
},
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const isOutOfBounds = (v: string) => {
|
|
42
|
+
if (v === "") return false;
|
|
43
|
+
const n = Number(v);
|
|
44
|
+
return (props.min != null && n < props.min) || (props.max != null && n > props.max);
|
|
45
|
+
};
|
|
46
|
+
const minOutOfBounds = computed(() => isOutOfBounds(draftMin.value));
|
|
47
|
+
const maxOutOfBounds = computed(() => isOutOfBounds(draftMax.value));
|
|
48
|
+
const isRangeInverted = computed(
|
|
49
|
+
() =>
|
|
50
|
+
draftMin.value !== "" &&
|
|
51
|
+
draftMax.value !== "" &&
|
|
52
|
+
Number(draftMin.value) > Number(draftMax.value),
|
|
53
|
+
);
|
|
54
|
+
const hasError = computed(
|
|
55
|
+
() => minOutOfBounds.value || maxOutOfBounds.value || isRangeInverted.value,
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
const boundsLabel = computed(() => {
|
|
59
|
+
const { min, max } = props;
|
|
60
|
+
if (min != null && max != null) return `${min}–${max}`;
|
|
61
|
+
if (min != null) return `${min} or more`;
|
|
62
|
+
if (max != null) return `${max} or less`;
|
|
63
|
+
return null;
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const errorMessage = computed(() => {
|
|
67
|
+
if (isRangeInverted.value) return "Min must not exceed max";
|
|
68
|
+
if ((minOutOfBounds.value || maxOutOfBounds.value) && boundsLabel.value) {
|
|
69
|
+
return `Value must be between ${boundsLabel.value}`;
|
|
70
|
+
}
|
|
71
|
+
return undefined;
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const onMin = (v: string | number | undefined) => {
|
|
75
|
+
draftMin.value = String(v ?? "");
|
|
76
|
+
emitDebounced(draftMin.value, draftMax.value);
|
|
77
|
+
};
|
|
78
|
+
const onMax = (v: string | number | undefined) => {
|
|
79
|
+
draftMax.value = String(v ?? "");
|
|
80
|
+
emitDebounced(draftMin.value, draftMax.value);
|
|
81
|
+
};
|
|
82
|
+
</script>
|
|
83
|
+
|
|
84
|
+
<template>
|
|
85
|
+
<FilterFieldWrapper
|
|
86
|
+
:label="label"
|
|
87
|
+
:help-text="helpText"
|
|
88
|
+
:error="errorMessage"
|
|
89
|
+
:error-id="errorId"
|
|
90
|
+
>
|
|
91
|
+
<div class="flex items-center gap-2">
|
|
92
|
+
<Input
|
|
93
|
+
type="number"
|
|
94
|
+
placeholder="Min"
|
|
95
|
+
:min="min"
|
|
96
|
+
:max="max"
|
|
97
|
+
:model-value="draftMin"
|
|
98
|
+
:aria-label="`${label} minimum`"
|
|
99
|
+
:aria-invalid="hasError || undefined"
|
|
100
|
+
:aria-describedby="hasError ? errorId : undefined"
|
|
101
|
+
@update:model-value="onMin"
|
|
102
|
+
/>
|
|
103
|
+
<span class="text-sm text-muted-foreground">–</span>
|
|
104
|
+
<Input
|
|
105
|
+
type="number"
|
|
106
|
+
placeholder="Max"
|
|
107
|
+
:min="min"
|
|
108
|
+
:max="max"
|
|
109
|
+
:model-value="draftMax"
|
|
110
|
+
:aria-label="`${label} maximum`"
|
|
111
|
+
:aria-invalid="hasError || undefined"
|
|
112
|
+
:aria-describedby="hasError ? errorId : undefined"
|
|
113
|
+
@update:model-value="onMax"
|
|
114
|
+
/>
|
|
115
|
+
</div>
|
|
116
|
+
</FilterFieldWrapper>
|
|
117
|
+
</template>
|