construct-hub 0.3.251 → 0.3.255
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/.jsii +2 -2
- package/changelog.md +1 -1
- package/lib/backend/orchestration/index.js +13 -2
- package/lib/backend/transliterator/transliterator.ecs-entrypoint.bundle/index.js +2 -2
- package/lib/construct-hub.js +1 -1
- package/lib/package-sources/code-artifact.js +1 -1
- package/lib/package-sources/npmjs.js +1 -1
- package/lib/package-tag/index.js +3 -3
- package/lib/package-tag-group/index.js +2 -2
- package/lib/preload-file/index.js +1 -1
- package/lib/s3/storage.js +1 -1
- package/lib/spdx-license.js +1 -1
- package/package.json +4 -4
- package/releasetag.txt +1 -1
- package/version.txt +1 -1
- package/website/asset-manifest.json +11 -11
- package/website/index.html +1 -1
- package/website/static/js/122.48b6d425.chunk.js +2 -0
- package/website/static/js/122.48b6d425.chunk.js.map +1 -0
- package/website/static/js/51.3b58a25f.chunk.js +2 -0
- package/website/static/js/{51.e972cd06.chunk.js.map → 51.3b58a25f.chunk.js.map} +1 -1
- package/website/static/js/634.2f9ebff7.chunk.js +3 -0
- package/website/static/js/{634.f14c809b.chunk.js.LICENSE.txt → 634.2f9ebff7.chunk.js.LICENSE.txt} +0 -0
- package/website/static/js/634.2f9ebff7.chunk.js.map +1 -0
- package/website/static/js/639.30409bf1.chunk.js.map +1 -1
- package/website/static/js/926.a296b10e.chunk.js +2 -0
- package/website/static/js/{926.1fc8761f.chunk.js.map → 926.a296b10e.chunk.js.map} +1 -1
- package/website/static/js/main.97f74932.js +3 -0
- package/website/static/js/{main.15478f1d.js.LICENSE.txt → main.97f74932.js.LICENSE.txt} +0 -0
- package/website/static/js/main.97f74932.js.map +1 -0
- package/website/static/js/122.b1307897.chunk.js +0 -2
- package/website/static/js/122.b1307897.chunk.js.map +0 -1
- package/website/static/js/51.e972cd06.chunk.js +0 -2
- package/website/static/js/634.f14c809b.chunk.js +0 -3
- package/website/static/js/634.f14c809b.chunk.js.map +0 -1
- package/website/static/js/926.1fc8761f.chunk.js +0 -2
- package/website/static/js/main.15478f1d.js +0 -3
- package/website/static/js/main.15478f1d.js.map +0 -1
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"static/js/51.e972cd06.chunk.js","mappings":"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","sources":["views/Search/constants.ts","views/Search/FilterHeading.tsx","views/Search/testIds.ts","views/Search/RadioFilter.tsx","views/Search/util.ts","views/Search/useSearchParam.ts","views/Search/useUpdateSearchParam.ts","views/Search/CDKFilter.tsx","views/Search/CheckboxFilter.tsx","views/Search/KeywordsFilter.tsx","views/Search/LanguageFilter.tsx","views/Search/TagFilter.tsx","views/Search/FilterPanel.tsx","components/PackageList/PackageList.tsx","components/PackageList/WideCardList.tsx","views/Search/ArrowButton.tsx","views/Search/GoToPage.tsx","views/Search/PageControls.tsx","views/Search/SearchBar.tsx","views/Search/SearchDetails.tsx","views/Search/SortFilter.tsx","views/Search/SortAndFilterDrawer.tsx","views/Search/SortedBy.tsx","views/Search/SearchResults.tsx","views/Search/Search.tsx"],"sourcesContent":["import { CatalogSearchSort } from \"../../api/catalog-search/constants\";\nimport type { QueryParamKey } from \"../../constants/url\";\nimport { eventName } from \"../../contexts/Analytics\";\n\nconst LIMITS = [25, 50, 75, 100];\nexport const LIMIT = LIMITS[0];\n\nexport type SearchQueryParam = Extract<QueryParamKey, \"offset\" | \"q\">;\n\nexport const SORT_RENDER_MAP = {\n [CatalogSearchSort.NameAsc]: \"A-Z\",\n [CatalogSearchSort.NameDesc]: \"Z-A\",\n [CatalogSearchSort.PublishDateAsc]: \"Oldest\",\n [CatalogSearchSort.PublishDateDesc]: \"Recently updated\",\n [CatalogSearchSort.DownloadsDesc]: \"Most downloads\",\n [CatalogSearchSort.DownloadsAsc]: \"Least downloads\",\n};\n\nconst searchEvent: typeof eventName = (...e) => eventName(\"Search\", ...e);\n\nexport const SEARCH_ANALYTICS = {\n FILTERS: searchEvent(\"Filters\"),\n RESULTS: searchEvent(\"Results\"),\n SEARCH: searchEvent(\"Search\"),\n SORT: searchEvent(\"Sort\"),\n};\n","import { QuestionIcon } from \"@chakra-ui/icons\";\nimport {\n Flex,\n Heading,\n Text,\n Popover,\n PopoverTrigger,\n PopoverBody,\n PopoverArrow,\n PopoverContent,\n useBreakpointValue,\n PlacementWithLogical,\n} from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\nimport { eventName } from \"../../contexts/Analytics\";\nimport { SEARCH_ANALYTICS } from \"./constants\";\n\nexport interface FilterHeadingProps {\n name: string;\n hint?: string;\n}\n\nexport const FilterHeading: FunctionComponent<FilterHeadingProps> = ({\n name,\n hint,\n}) => {\n const placement = useBreakpointValue<PlacementWithLogical>({\n base: \"auto\",\n md: \"right\",\n });\n\n return (\n <Flex align=\"center\" mb={1}>\n <Heading as=\"h3\" size=\"sm\" w=\"max-content\">\n {name}\n </Heading>\n {hint ? (\n <Popover colorScheme=\"dark\" placement={placement} strategy=\"fixed\">\n <PopoverTrigger>\n <Flex\n aria-label={`Hint: ${name}`}\n as=\"button\"\n data-event={eventName(SEARCH_ANALYTICS.FILTERS, name, \"Popover\")}\n ml={2}\n >\n <QuestionIcon h={3.5} w={3.5} />\n </Flex>\n </PopoverTrigger>\n <PopoverContent\n bg=\"gray.700\"\n borderRadius=\"base\"\n color=\"white\"\n fontSize=\"sm\"\n mx={{ base: \"1rem\", md: \"initial\" }}\n shadow=\"whiteAlpha.300\"\n >\n <PopoverArrow bg=\"gray.700\" />\n <PopoverBody>\n <Text>{hint}</Text>\n </PopoverBody>\n </PopoverContent>\n </Popover>\n ) : null}\n </Flex>\n );\n};\n","import { createTestIds } from \"../../util/createTestIds\";\n\nexport default createTestIds(\"searchRedesign\", [\n \"page\",\n // Results\n \"searchDetails\",\n \"nextPage\",\n \"prevPage\",\n \"goToPage\",\n // Sorting\n \"sortButton\",\n \"sortDropdown\",\n \"sortItem\",\n // Filters Panel\n \"filtersPanel\",\n \"cdkTypeFilter\",\n \"cdkVersionFilter\",\n \"filterItem\",\n \"languagesFilter\",\n] as const);\n","import { Radio, RadioGroup, Stack, Text } from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\nimport { eventName } from \"../../contexts/Analytics\";\nimport { SEARCH_ANALYTICS } from \"./constants\";\nimport { FilterHeading, FilterHeadingProps } from \"./FilterHeading\";\nimport testIds from \"./testIds\";\n\nexport interface RadioFilterProps extends FilterHeadingProps {\n \"data-testid\"?: string;\n value?: string;\n onValueChange: (value: string) => void;\n options: {\n display: string;\n value: string;\n }[];\n}\n\nexport const RadioFilter: FunctionComponent<RadioFilterProps> = ({\n \"data-testid\": dataTestid,\n value: checkedValue,\n onValueChange,\n options,\n name,\n hint,\n}) => {\n return (\n <Stack data-testid={dataTestid} spacing={1}>\n <FilterHeading hint={hint} name={name} />\n <RadioGroup onChange={onValueChange} value={checkedValue}>\n <Stack spacing={1}>\n {options.map(({ display, value }) => {\n const dataEvent = eventName(\n SEARCH_ANALYTICS.FILTERS,\n name,\n \"Filter\",\n display\n );\n return (\n <Radio data-event={dataEvent} key={value} value={value}>\n <Text\n color=\"textTertiary\"\n data-event={dataEvent}\n data-testid={testIds.filterItem}\n data-value={value}\n isTruncated\n >\n {display}\n </Text>\n </Radio>\n );\n })}\n </Stack>\n </RadioGroup>\n </Stack>\n );\n};\n","import { CatalogSearchSort } from \"../../api/catalog-search/constants\";\nimport { CDKType } from \"../../constants/constructs\";\nimport { Language } from \"../../constants/languages\";\nimport { QUERY_PARAMS } from \"../../constants/url\";\n\nexport const toNum = (val: string) => {\n const result = parseInt(val);\n\n if (`${result}` === \"NaN\") {\n return 0;\n }\n\n return result;\n};\n\nexport const parseQueryArray = <T extends string>(\n queryString: string | null\n) => {\n if (!queryString) return [];\n\n return decodeURIComponent(queryString).split(\",\") as T[];\n};\n\nconst getParamFromUrl = (key: string) => {\n if (typeof window === \"undefined\") return null;\n const queryParams = new URL(window.location.href).searchParams;\n return queryParams.get(key);\n};\n\nexport const getSearchUrlParams = () => {\n return {\n query: getParamFromUrl(QUERY_PARAMS.SEARCH_QUERY) ?? \"\",\n keywords: parseQueryArray(getParamFromUrl(QUERY_PARAMS.KEYWORDS)),\n cdkType: (getParamFromUrl(QUERY_PARAMS.CDK_TYPE) as CDKType) ?? undefined,\n cdkMajor: (() => {\n const cdkMajorParam = getParamFromUrl(QUERY_PARAMS.CDK_MAJOR);\n return cdkMajorParam ? toNum(cdkMajorParam) : undefined;\n })(),\n languages: parseQueryArray(\n getParamFromUrl(QUERY_PARAMS.LANGUAGES)\n ) as Language[],\n offset: toNum(getParamFromUrl(QUERY_PARAMS.OFFSET) ?? \"\"),\n sort:\n (getParamFromUrl(QUERY_PARAMS.SORT) as CatalogSearchSort) ?? undefined,\n tags: parseQueryArray(getParamFromUrl(QUERY_PARAMS.TAGS)),\n };\n};\n","import { useMemo } from \"react\";\nimport { CatalogSearchSort } from \"../../api/catalog-search/constants\";\nimport { CDKType } from \"../../constants/constructs\";\nimport { Language } from \"../../constants/languages\";\nimport { QUERY_PARAMS } from \"../../constants/url\";\nimport { useQueryParams } from \"../../hooks/useQueryParams\";\nimport { parseQueryArray, toNum } from \"./util\";\n\nconst useSearchParam = <T = string | null>(\n key: string,\n transform?: (param: string | null) => T\n): T => {\n const queryParams = useQueryParams();\n const qp = queryParams.get(key);\n\n return useMemo(\n () => (transform ? transform(qp) : (qp as unknown as T)),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [qp]\n );\n};\n\nexport const useCdkType = () => {\n const cdkType: CDKType | undefined =\n useSearchParam(QUERY_PARAMS.CDK_TYPE) ?? undefined;\n\n return cdkType;\n};\n\nexport const useCdkMajor = () => {\n const cdkMajor: number | undefined = useSearchParam(\n QUERY_PARAMS.CDK_MAJOR,\n (p) => (p ? toNum(p) : undefined)\n );\n\n return cdkMajor;\n};\n\nexport const useKeywords = () => {\n const keywords: string[] = useSearchParam(\n QUERY_PARAMS.KEYWORDS,\n parseQueryArray\n );\n\n return keywords;\n};\n\nexport const useLanguages = () => {\n const languages: Language[] = useSearchParam(\n QUERY_PARAMS.LANGUAGES,\n parseQueryArray\n ) as Language[];\n\n return languages;\n};\n\nexport const useOffset = () => {\n const offset = useSearchParam(QUERY_PARAMS.OFFSET, (o) => toNum(o ?? \"\"));\n return offset;\n};\n\nexport const useSearchQuery = () => {\n const query: string = useSearchParam(QUERY_PARAMS.SEARCH_QUERY) ?? \"\";\n return query;\n};\n\nexport const useSort = () => {\n const sort: CatalogSearchSort | undefined =\n useSearchParam(QUERY_PARAMS.SORT) ?? undefined;\n return sort;\n};\n\nexport const useTags = () => {\n const tags: string[] = useSearchParam(QUERY_PARAMS.TAGS, parseQueryArray);\n return tags;\n};\n","import { useCallback } from \"react\";\nimport { useHistory } from \"react-router-dom\";\nimport { getSearchPath } from \"../../util/url\";\nimport { getSearchUrlParams } from \"./util\";\n\nexport const useUpdateSearchParam = () => {\n const { push } = useHistory();\n\n return useCallback(\n (p?: Partial<Parameters<typeof getSearchPath>[0]>) => {\n const { offset, ...params } = p ?? {};\n\n push(\n getSearchPath({\n ...getSearchUrlParams(),\n ...params,\n offset: offset ?? 0,\n })\n );\n },\n [push]\n );\n};\n","import { FunctionComponent, useMemo } from \"react\";\nimport { CatalogConstructFrameworkMeta } from \"../../api/catalog-search\";\nimport { CDKType, CDKTYPE_NAME_MAP } from \"../../constants/constructs\";\nimport { useSearchContext } from \"../../contexts/Search\";\nimport { RadioFilter } from \"./RadioFilter\";\nimport testIds from \"./testIds\";\nimport { useCdkMajor, useCdkType } from \"./useSearchParam\";\nimport { useUpdateSearchParam } from \"./useUpdateSearchParam\";\n\ntype CDKOptions = Partial<{\n [key in CDKType]: CatalogConstructFrameworkMeta & {\n display: string;\n value: key;\n };\n}>;\n\nexport const CDKFilter: FunctionComponent = () => {\n const cdkType = useCdkType();\n const cdkMajor = useCdkMajor();\n\n const updateSearch = useUpdateSearchParam();\n\n const searchAPI = useSearchContext()!;\n\n // Options with less than one package will be omitted\n const cdkOptions = useMemo(() => {\n const cdkTypes = searchAPI.constructFrameworks;\n const options = Object.entries(cdkTypes).reduce((opts, [name, meta]) => {\n if (meta.pkgCount < 1) {\n return opts;\n }\n\n return {\n ...opts,\n [name]: {\n display: CDKTYPE_NAME_MAP[name as CDKType],\n value: name,\n ...meta,\n },\n };\n }, {});\n\n return Object.keys(options).length ? (options as CDKOptions) : undefined;\n }, [searchAPI]);\n\n const majorsOptions = useMemo(() => {\n if (!cdkOptions || !cdkType) return undefined;\n const majorVersions = cdkOptions[cdkType]?.majorVersions;\n\n if (!majorVersions) return undefined;\n\n return [...majorVersions]\n .sort((a, b) => a - b)\n .map((value) => ({\n value: value.toString(),\n display: `${CDKTYPE_NAME_MAP[cdkType]} v${value}`,\n }));\n }, [cdkOptions, cdkType]);\n\n if (!cdkOptions) {\n return null;\n }\n\n const onCdkTypeChange = (type: string) => {\n const cdk = type as CDKType;\n updateSearch({ cdkType: type ? cdk : undefined, cdkMajor: undefined });\n };\n\n const onCdkMajorChange = (major: string) => {\n let majorNum: number | undefined = undefined;\n\n if (major) {\n majorNum = parseInt(major, 10);\n }\n\n updateSearch({ cdkMajor: majorNum });\n };\n\n return (\n <>\n <RadioFilter\n data-testid={testIds.cdkTypeFilter}\n hint=\"Choose the right CDK for your IaC technology: AWS CDK for AWS CloudFormation, CDKtf for Terraform, or CDK8s for Kubernetes.\"\n name=\"CDK Type\"\n onValueChange={onCdkTypeChange}\n options={[\n { display: \"Any CDK Type\", value: \"\" },\n ...Object.values(cdkOptions),\n ]}\n value={cdkType ?? \"\"}\n />\n {/* No point in showing major versions if only a single one is available */}\n {!!(majorsOptions && majorsOptions.length > 1) && (\n <RadioFilter\n data-testid={testIds.cdkVersionFilter}\n hint=\"Choose the major version of the CDK you're using to see only constructs that will work with that version.\"\n name=\"CDK Major Version\"\n onValueChange={onCdkMajorChange}\n options={[\n { display: \"Any Major Version\", value: \"\" },\n ...majorsOptions,\n ]}\n value={cdkMajor?.toString() ?? \"\"}\n />\n )}\n </>\n );\n};\n","import { ChevronDownIcon, ChevronUpIcon } from \"@chakra-ui/icons\";\nimport {\n Flex,\n Button,\n Collapse,\n Checkbox,\n Stack,\n Text,\n Tooltip,\n useDisclosure,\n} from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\nimport { clickEvent, eventName, useAnalytics } from \"../../contexts/Analytics\";\nimport { SEARCH_ANALYTICS } from \"./constants\";\nimport { FilterHeading, FilterHeadingProps } from \"./FilterHeading\";\nimport testIds from \"./testIds\";\n\ninterface CheckboxOption {\n display: string;\n value: string;\n isDisabled?: boolean;\n disabledHint?: string;\n}\n\ninterface CheckboxItemProps extends CheckboxOption {\n onChange: () => void;\n isChecked: boolean;\n}\n\nexport interface CheckboxFilterProps extends FilterHeadingProps {\n /**\n * Test ID to select checkbox in tests\n */\n \"data-testid\"?: string;\n /**\n * Number of items that can be initially shown\n */\n initialItemCount?: number;\n /**\n * Defines checkbox items\n */\n options: CheckboxOption[];\n /**\n * Selected values\n */\n values: string[];\n /**\n * Callback triggered when an item is clicked\n */\n onValueChange: (value: string) => void;\n}\n\nconst CheckboxItem: FunctionComponent<CheckboxItemProps> = ({\n display,\n value,\n isDisabled,\n disabledHint,\n isChecked,\n onChange,\n}) => (\n <Checkbox\n isChecked={isChecked}\n isDisabled={isDisabled}\n key={value}\n onChange={onChange}\n >\n <Tooltip\n hasArrow\n isDisabled={!isDisabled && !disabledHint}\n label={disabledHint}\n placement=\"right\"\n >\n <Text\n color=\"textTertiary\"\n data-testid={testIds.filterItem}\n data-value={value}\n isTruncated\n >\n {display}\n </Text>\n </Tooltip>\n </Checkbox>\n);\n\nexport const CheckboxFilter: FunctionComponent<CheckboxFilterProps> = ({\n \"data-testid\": dataTestid,\n initialItemCount,\n hint,\n name,\n options,\n values: checkedValues,\n onValueChange,\n}) => {\n const collapse = useDisclosure();\n const { trackCustomEvent } = useAnalytics();\n\n const getOnChange = (item: CheckboxOption) => () => {\n trackCustomEvent(\n clickEvent({\n name: eventName(SEARCH_ANALYTICS.FILTERS, name, \"Filter\", item.display),\n })\n );\n onValueChange(item.value);\n };\n\n let alwaysShow: typeof options = options;\n let showWhenExpanded: typeof options = [];\n\n if (initialItemCount) {\n alwaysShow = options.slice(0, initialItemCount);\n showWhenExpanded = options.slice(initialItemCount, options.length);\n }\n\n const isExpandible = showWhenExpanded.length > 0;\n\n return (\n <Flex data-testid={dataTestid} direction=\"column\">\n <FilterHeading hint={hint} name={name} />\n <Stack mt={1} spacing={1}>\n {alwaysShow.map((item) => (\n <CheckboxItem\n {...item}\n isChecked={checkedValues.includes(item.value)}\n key={item.value}\n onChange={getOnChange(item)}\n />\n ))}\n {isExpandible && (\n <Collapse animateOpacity in={collapse.isOpen} unmountOnExit>\n <Stack spacing={1}>\n {showWhenExpanded.map((item) => (\n <CheckboxItem\n {...item}\n isChecked={checkedValues.includes(item.value)}\n key={item.value}\n onChange={getOnChange(item)}\n />\n ))}\n </Stack>\n </Collapse>\n )}\n </Stack>\n {isExpandible && (\n <Flex align=\"start\" mt={1}>\n <Button\n color=\"textTertiary\"\n data-event={eventName(SEARCH_ANALYTICS.FILTERS, name, \"Show More\")}\n fontWeight=\"normal\"\n leftIcon={collapse.isOpen ? <ChevronUpIcon /> : <ChevronDownIcon />}\n onClick={collapse.onToggle}\n size=\"sm\"\n textAlign=\"left\"\n variant=\"link\"\n w=\"auto\"\n >\n {collapse.isOpen\n ? `Show fewer options (${alwaysShow.length})`\n : `Show more options (${showWhenExpanded.length})`}\n </Button>\n </Flex>\n )}\n </Flex>\n );\n};\n","import { FunctionComponent, useMemo } from \"react\";\nimport { useSearchContext } from \"../../contexts/Search\";\nimport { CheckboxFilter } from \"./CheckboxFilter\";\nimport testIds from \"./testIds\";\nimport { useKeywords } from \"./useSearchParam\";\nimport { useUpdateSearchParam } from \"./useUpdateSearchParam\";\n\nexport const KeywordsFilter: FunctionComponent = () => {\n const keywords = useKeywords();\n const keywordMap = useSearchContext()!.keywords;\n const updateSearch = useUpdateSearchParam();\n\n const onKeywordChange = (keyword: string) => {\n updateSearch({\n keywords: keywords.includes(keyword)\n ? keywords.filter((k) => k !== keyword)\n : [...keywords, keyword],\n });\n };\n\n const keywordOptions = useMemo(() => {\n const baseOptions = [...keywordMap.entries()]\n .sort(([, count1], [, count2]) => {\n return count1 < count2 ? 1 : -1;\n })\n .filter(([keyword]) => !keywords.includes(keyword))\n .map(([keyword]) => ({\n display: keyword,\n value: keyword,\n }))\n .slice(0, 25);\n\n const keywordsNotInOptions = keywords.filter(\n (k) => !baseOptions.some((opt) => opt.value === k)\n );\n\n return [\n ...keywordsNotInOptions.map((k) => ({ display: k, value: k })),\n ...baseOptions,\n ];\n }, [keywordMap, keywords]);\n\n return (\n <CheckboxFilter\n data-testid={testIds.languagesFilter}\n hint=\"Focus the results by choosing one or more keywords reflecting the kind of construct you're looking for. Keywords are provided by construct authors.\"\n initialItemCount={5}\n name=\"Keywords\"\n onValueChange={onKeywordChange}\n options={keywordOptions}\n values={keywords}\n />\n );\n};\n","import { FunctionComponent } from \"react\";\nimport {\n Language,\n LANGUAGE_NAME_MAP,\n TEMP_SUPPORTED_LANGUAGES,\n} from \"../../constants/languages\";\nimport { CheckboxFilter } from \"./CheckboxFilter\";\nimport testIds from \"./testIds\";\nimport { useLanguages } from \"./useSearchParam\";\nimport { useUpdateSearchParam } from \"./useUpdateSearchParam\";\n\nconst languageOptions = Object.entries(LANGUAGE_NAME_MAP)\n .map(([key, value]) => ({\n display: value,\n value: key,\n ...(TEMP_SUPPORTED_LANGUAGES.has(key as Language)\n ? { isDisabled: false }\n : {\n isDisabled: true,\n disabledHint: `${\n LANGUAGE_NAME_MAP[key as Language]\n } support is coming soon!`,\n }),\n }))\n .sort((l1, l2) => {\n // Push disabled languages to back of list\n return l1.isDisabled > l2.isDisabled ? 1 : -1;\n });\n\nexport const LanguageFilter: FunctionComponent = () => {\n const languages = useLanguages();\n\n const updateSearch = useUpdateSearchParam();\n\n const onLanguagesChange = (lang: string) => {\n const language = lang as Language;\n\n updateSearch({\n languages: languages.includes(language)\n ? languages.filter((l) => l !== language)\n : [...languages, language],\n });\n };\n\n return (\n <CheckboxFilter\n data-testid={testIds.languagesFilter}\n hint=\"Choose one or more languages. Results include constructs for use with at least one of the selected languages.\"\n name=\"Programming Language\"\n onValueChange={onLanguagesChange}\n options={languageOptions}\n values={languages}\n />\n );\n};\n","import { FunctionComponent, useCallback, useMemo } from \"react\";\nimport { PackageTagConfig, TagGroupConfig } from \"../../api/config\";\nimport { useConfigValue } from \"../../hooks/useConfigValue\";\nimport { CheckboxFilter } from \"./CheckboxFilter\";\nimport { RadioFilter } from \"./RadioFilter\";\nimport { useTags } from \"./useSearchParam\";\nimport { useUpdateSearchParam } from \"./useUpdateSearchParam\";\n\ninterface FilterGroup extends Partial<TagGroupConfig> {\n id: string;\n tags: PackageTagConfig[];\n}\ninterface FilterGroups {\n [group: string]: FilterGroup;\n}\n\n/**\n * Creates a plain object map of FilterGroups keyed by group id\n */\nexport const mapTagsToFilterGroups = (\n packageTags: PackageTagConfig[],\n tagGroupsMap: Map<string, TagGroupConfig>\n): FilterGroups => {\n return packageTags.reduce(\n (accum: FilterGroups, tag: PackageTagConfig): FilterGroups => {\n const groupIdOrName = tag.searchFilter?.groupBy;\n const customGroup = groupIdOrName\n ? tagGroupsMap.get(groupIdOrName)\n : undefined;\n\n if (groupIdOrName && customGroup) {\n const entry = accum[groupIdOrName];\n if (entry) {\n entry.tags = [...entry.tags, tag];\n return accum;\n }\n\n return {\n ...accum,\n [groupIdOrName]: {\n ...customGroup,\n tags: [tag],\n },\n };\n }\n\n if (groupIdOrName) {\n return {\n ...accum,\n [groupIdOrName]: {\n id: groupIdOrName,\n tags: [...(accum?.[groupIdOrName]?.tags ?? []), tag],\n },\n };\n }\n return accum;\n },\n {}\n );\n};\n\nexport const TagFilter: FunctionComponent = () => {\n const packageTags = useConfigValue(\"packageTags\");\n const packageTagGroups = useConfigValue(\"packageTagGroups\");\n\n const tagFilterGroups: FilterGroups = useMemo(() => {\n const tagGroupsMap = new Map<string, TagGroupConfig>();\n packageTagGroups?.forEach((group) => {\n tagGroupsMap.set(group.id, group);\n });\n\n const filterableTags =\n packageTags?.filter((tag) => Boolean(tag.searchFilter)) ?? [];\n\n return mapTagsToFilterGroups(filterableTags, tagGroupsMap);\n }, [packageTags, packageTagGroups]);\n\n const tags = useTags();\n const updateSearch = useUpdateSearchParam();\n\n const onTagsChange = (tag: string) => {\n updateSearch({\n tags: tags.includes(tag) ? tags.filter((t) => t !== tag) : [...tags, tag],\n });\n };\n\n const getOnRadioTagChange = useCallback(\n (groupName: string) => {\n const groupTags = new Set(\n (tagFilterGroups[groupName]?.tags ?? []).map(({ id }) => id)\n );\n\n return (tag: string) => {\n const filteredTags = tags.filter((t) => !groupTags.has(t));\n\n updateSearch({\n tags: tag ? [...filteredTags, tag] : filteredTags,\n });\n };\n },\n [tagFilterGroups, tags, updateSearch]\n );\n\n return (\n <>\n {Object.values(tagFilterGroups).map(\n ({ filterType, id, label, tooltip, tags: tagItems }) => {\n const sharedProps = {\n hint: tooltip,\n name: label ?? id,\n options: tagItems.map((tag) => {\n return {\n display: tag.searchFilter!.display,\n value: tag.id,\n };\n }),\n };\n\n if (filterType === \"radio\") {\n return (\n <RadioFilter\n {...sharedProps}\n key={id}\n onValueChange={getOnRadioTagChange(id)}\n options={[\n { display: `Any ${sharedProps.name}`, value: \"\" },\n ...sharedProps.options,\n ]}\n value={tagItems.find((t) => tags.includes(t.id))?.id ?? \"\"}\n />\n );\n }\n\n return (\n <CheckboxFilter\n {...sharedProps}\n key={id}\n onValueChange={onTagsChange}\n values={tags}\n />\n );\n }\n )}\n </>\n );\n};\n","import { Heading, Stack } from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\nimport { Card } from \"../../components/Card\";\nimport { CDKFilter } from \"./CDKFilter\";\nimport { KeywordsFilter } from \"./KeywordsFilter\";\nimport { LanguageFilter } from \"./LanguageFilter\";\nimport { TagFilter } from \"./TagFilter\";\nimport testIds from \"./testIds\";\n\nexport interface FilterPanelProps {}\n\n// Header height + section padding\nconst TOP_OFFSET = \"5.75rem\";\n\n/**\n * The desktop Resolution Filter Panel\n */\nexport const FilterPanel: FunctionComponent<FilterPanelProps> = () => {\n return (\n <Card\n borderRadius=\"sm\"\n data-testid={testIds.filtersPanel}\n display={{ base: \"none\", md: \"flex\" }}\n maxH={`calc(100vh - ${TOP_OFFSET} - 1.25rem)`}\n maxW=\"23rem\"\n minW=\"100%\"\n overflow=\"hidden auto\"\n p={4}\n pos=\"sticky\"\n top={TOP_OFFSET}\n zIndex=\"docked\"\n >\n <Stack color=\"textPrimary\" h=\"max-content\" spacing={4} top={4}>\n <Heading as=\"h2\" size=\"sm\">\n Filters\n </Heading>\n\n <CDKFilter />\n\n <LanguageFilter />\n\n <TagFilter />\n\n <KeywordsFilter />\n </Stack>\n </Card>\n );\n};\n","import { Center, Spinner } from \"@chakra-ui/react\";\nimport { FunctionComponent, memo } from \"react\";\nimport { ExtendedCatalogPackage } from \"../../api/catalog-search\";\nimport { PackageCardType } from \"../PackageCard\";\nimport { WideCardList } from \"./WideCardList\";\n\nconst listViews = {\n [PackageCardType.Wide]: WideCardList,\n};\n\nexport interface PackageListViewProps {\n \"data-event\"?: string;\n items: ExtendedCatalogPackage[];\n}\n\nexport interface PackageListProps extends Partial<PackageListViewProps> {\n cardView?: PackageCardType;\n loading?: boolean;\n title?: string;\n}\n\nexport const PackageList: FunctionComponent<PackageListProps> = memo(\n ({\n \"data-event\": dataEvent,\n cardView = PackageCardType.Wide,\n items,\n loading,\n }) => {\n if (loading || !items) {\n return (\n <Center>\n <Spinner size=\"xl\" />\n </Center>\n );\n }\n\n const View = listViews[cardView];\n\n return <View data-event={dataEvent} items={items} />;\n }\n);\n\nPackageList.displayName = \"PackageList\";\n","import { Stack } from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\nimport { PackageCard, PackageCardType } from \"../PackageCard\";\nimport { PackageListViewProps } from \"./PackageList\";\n\nexport const WideCardList: FunctionComponent<PackageListViewProps> = ({\n \"data-event\": dataEvent,\n items,\n}) => {\n return (\n <Stack spacing={4}>\n {items.map((pkg) => (\n <PackageCard\n data-event={dataEvent}\n key={`${pkg.name}-${pkg.version}`}\n pkg={pkg}\n variant={PackageCardType.Wide}\n />\n ))}\n </Stack>\n );\n};\n","import { IconButton, IconProps } from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\n\nexport interface ArrowButtonProps {\n \"data-event\"?: string;\n \"data-testid\"?: string;\n icon: FunctionComponent<IconProps>;\n label: string;\n onClick?: () => void;\n}\n\nexport const ArrowButton: FunctionComponent<ArrowButtonProps> = ({\n \"data-event\": dataEvent,\n \"data-testid\": dataTestid,\n icon: Icon,\n label,\n onClick,\n}) => {\n const props = {\n \"aria-label\": label,\n borderRadius: \"md\",\n borderColor: \"blue.500\",\n colorScheme: \"blue\",\n \"data-event\": dataEvent,\n \"data-testid\": dataTestid,\n icon: <Icon color=\"blue.500\" h={5} w={5} />,\n mx: 2,\n h: 10,\n w: 10,\n variant: \"outline\",\n };\n\n return <IconButton {...props} disabled={!onClick} onClick={onClick} />;\n};\n","import { Flex, Input, Text } from \"@chakra-ui/react\";\nimport {\n FormEventHandler,\n FunctionComponent,\n SyntheticEvent,\n useEffect,\n useState,\n} from \"react\";\nimport { clickEvent, useAnalytics } from \"../../contexts/Analytics\";\nimport { useUpdateSearchParam } from \"./useUpdateSearchParam\";\n\nexport interface GoToPageProps {\n \"data-event\"?: string;\n \"data-testid\"?: string;\n pageLimit: number;\n offset: number;\n}\n\nexport const GoToPage: FunctionComponent<GoToPageProps> = ({\n \"data-event\": dataEvent,\n \"data-testid\": dataTestid,\n pageLimit,\n offset,\n}) => {\n const updateSearch = useUpdateSearchParam();\n const { trackCustomEvent } = useAnalytics();\n const [inputValue, setInputValue] = useState((offset + 1).toString());\n\n useEffect(() => {\n setInputValue((offset + 1).toString());\n }, [offset]);\n\n const onInputChange = (e: SyntheticEvent<HTMLInputElement>) => {\n e.preventDefault();\n setInputValue((e.target as HTMLInputElement).value);\n };\n\n const onSubmit: FormEventHandler<HTMLInputElement> = (e) => {\n e.preventDefault();\n updateSearch({ offset: parseInt(inputValue) - 1 });\n };\n\n return (\n <Flex align=\"center\" as=\"form\" mx={2} onSubmit={onSubmit}>\n <Input\n aria-label=\"Jump to page\"\n colorScheme=\"brand\"\n data-testid={dataTestid}\n h={10}\n max={pageLimit + 1}\n min={1}\n name=\"page\"\n onChange={onInputChange}\n onFocus={() => {\n if (dataEvent) {\n trackCustomEvent(clickEvent({ name: dataEvent }));\n }\n }}\n p={0}\n textAlign=\"center\"\n type=\"number\"\n value={inputValue}\n w={10}\n />\n <Text ml={2} w=\"max-content\">\n of {pageLimit + 1}\n </Text>\n </Flex>\n );\n};\n","import { ChevronLeftIcon, ChevronRightIcon } from \"@chakra-ui/icons\";\nimport { Stack } from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\nimport { eventName } from \"../../contexts/Analytics\";\nimport { ArrowButton } from \"./ArrowButton\";\nimport { SEARCH_ANALYTICS } from \"./constants\";\nimport { GoToPage } from \"./GoToPage\";\nimport testIds from \"./testIds\";\nimport { useUpdateSearchParam } from \"./useUpdateSearchParam\";\n\nexport interface PageControlsProps {\n offset: number;\n pageLimit: number;\n}\n\nexport const PageControls: FunctionComponent<PageControlsProps> = ({\n offset,\n pageLimit,\n}) => {\n const updateSearch = useUpdateSearchParam();\n const goForward =\n offset < pageLimit ? () => updateSearch({ offset: offset + 1 }) : undefined;\n const goBack =\n offset > 0 ? () => updateSearch({ offset: offset - 1 }) : undefined;\n\n return (\n <Stack\n align=\"center\"\n direction=\"row\"\n justify=\"space-between\"\n maxW=\"18rem\"\n mx=\"auto\"\n spacing={4}\n w=\"full\"\n >\n <ArrowButton\n data-event={eventName(SEARCH_ANALYTICS.RESULTS, \"Previous Page\")}\n data-testid={testIds.prevPage}\n icon={ChevronLeftIcon}\n label=\"Previous page button\"\n onClick={goBack}\n />\n <GoToPage\n data-event={eventName(SEARCH_ANALYTICS.RESULTS, \"Go to Page\")}\n data-testid={testIds.goToPage}\n offset={offset}\n pageLimit={pageLimit}\n />\n <ArrowButton\n data-event={eventName(SEARCH_ANALYTICS.RESULTS, \"Next Page\")}\n data-testid={testIds.nextPage}\n icon={ChevronRightIcon}\n label=\"Next page button\"\n onClick={goForward}\n />\n </Stack>\n );\n};\n","import { FunctionComponent, useState } from \"react\";\nimport { SearchBar as SearchBarComponent } from \"../../components/SearchBar\";\nimport { SEARCH_ANALYTICS } from \"./constants\";\nimport { useSearchQuery } from \"./useSearchParam\";\nimport { useUpdateSearchParam } from \"./useUpdateSearchParam\";\n\nexport const SearchBar: FunctionComponent = () => {\n const query = useSearchQuery();\n const updateSearch = useUpdateSearchParam();\n\n const [value, setValue] = useState(query ?? \"\");\n\n return (\n <SearchBarComponent\n bg=\"bgSecondary\"\n data-event={SEARCH_ANALYTICS.SEARCH}\n onChange={(e) => setValue(e.target.value)}\n onSubmit={(e) => {\n e.preventDefault();\n\n updateSearch({\n query: value,\n sort: undefined,\n });\n }}\n value={value}\n />\n );\n};\n","import { Text } from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\nimport testIds from \"./testIds\";\n\nexport interface SearchDetailsProps {\n limit: number;\n offset: number;\n count: number;\n filtered: boolean;\n query?: string;\n}\n\nconst Em: FunctionComponent = ({ children }) => (\n <Text as=\"strong\" color=\"textSecondary\">\n {children}\n </Text>\n);\n\nconst Count: FunctionComponent<{\n first: number;\n count: number;\n last: number;\n}> = ({ first, count, last }) => {\n if (!first && last >= count) {\n return (\n <>\n <Em>{count}</Em> of <Em>{count}</Em>\n </>\n );\n }\n\n return (\n <>\n <Em>\n {count ? first + 1 : count} - {last > count ? count : last}\n </Em>{\" \"}\n of <Em>{count}</Em>\n </>\n );\n};\n\nexport const SearchDetails: FunctionComponent<SearchDetailsProps> = ({\n limit,\n offset,\n count,\n filtered,\n query,\n}) => {\n const first = limit * offset;\n const last = first + limit;\n const hasResults = count > 0;\n\n return (\n <Text data-testid={testIds.searchDetails}>\n {hasResults ? (\n <>\n Displaying <Count count={count} first={first} last={last} />{\" \"}\n {filtered ? \"search results\" : \"constructs\"}\n </>\n ) : (\n <>{filtered ? \"There were no search results\" : \"No constructs found\"}</>\n )}\n {query && (\n <>\n {\" for \"}\n <Em>{query}</Em>\n </>\n )}\n .{!hasResults && filtered && <> Try a different term.</>}\n </Text>\n );\n};\n","import { FunctionComponent } from \"react\";\nimport { CatalogSearchSort } from \"../../api/catalog-search/constants\";\nimport { SORT_RENDER_MAP } from \"./constants\";\nimport { RadioFilter } from \"./RadioFilter\";\nimport { useSort } from \"./useSearchParam\";\nimport { useUpdateSearchParam } from \"./useUpdateSearchParam\";\n\nexport const SortFilter: FunctionComponent = () => {\n const sort = useSort();\n const updateSearch = useUpdateSearchParam();\n\n const onSortChange = (newSort: string) => {\n updateSearch({\n sort: newSort ? (newSort as CatalogSearchSort) : undefined,\n });\n };\n\n return (\n <RadioFilter\n hint=\"Sets the order of search results\"\n name=\"Sorted By\"\n onValueChange={onSortChange}\n options={[\n { display: \"Relevance\", value: \"\" },\n ...Object.entries(SORT_RENDER_MAP).map(([value, display]) => ({\n display,\n value,\n })),\n ]}\n value={sort ?? \"\"}\n />\n );\n};\n","import { ChevronDownIcon } from \"@chakra-ui/icons\";\nimport {\n Button,\n Drawer,\n Stack,\n DrawerBody,\n DrawerHeader,\n DrawerOverlay,\n DrawerContent,\n DrawerCloseButton,\n useDisclosure,\n} from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\nimport { CDKFilter } from \"./CDKFilter\";\nimport { KeywordsFilter } from \"./KeywordsFilter\";\nimport { LanguageFilter } from \"./LanguageFilter\";\nimport { SortFilter } from \"./SortFilter\";\nimport { TagFilter } from \"./TagFilter\";\n\n/**\n * The mobile filter Drawer (Bottomsheet in iOS terminology)\n */\nexport const SortAndFilterDrawer: FunctionComponent = () => {\n const drawer = useDisclosure();\n return (\n <>\n <Button\n colorScheme=\"brand\"\n display={{ md: \"none\" }}\n onClick={drawer.onOpen}\n rightIcon={<ChevronDownIcon />}\n variant=\"link\"\n >\n Sorting and Filters\n </Button>\n <Drawer {...drawer} placement=\"bottom\">\n <DrawerOverlay />\n\n <DrawerContent color=\"textPrimary\" maxH=\"full\">\n <DrawerHeader borderBottom=\"base\">Sorting and Filters</DrawerHeader>\n\n <DrawerCloseButton />\n\n <DrawerBody>\n <Stack color=\"textPrimary\" pb={4} spacing={4}>\n <SortFilter />\n\n <CDKFilter />\n\n <LanguageFilter />\n\n <TagFilter />\n\n <KeywordsFilter />\n </Stack>\n </DrawerBody>\n </DrawerContent>\n </Drawer>\n </>\n );\n};\n","import { ChevronDownIcon } from \"@chakra-ui/icons\";\nimport {\n Flex,\n Text,\n Menu,\n MenuButton,\n MenuList,\n MenuItem,\n Button,\n} from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\nimport { CatalogSearchSort } from \"../../api/catalog-search/constants\";\nimport { eventName } from \"../../contexts/Analytics\";\nimport { SEARCH_ANALYTICS, SORT_RENDER_MAP } from \"./constants\";\nimport testIds from \"./testIds\";\nimport { useSort } from \"./useSearchParam\";\nimport { useUpdateSearchParam } from \"./useUpdateSearchParam\";\n\nexport const SortedBy: FunctionComponent = () => {\n const sort = useSort();\n const updateSearch = useUpdateSearchParam();\n\n const selected = sort ? SORT_RENDER_MAP[sort] : \"Relevance\";\n\n return (\n <Flex align=\"center\">\n <Text>Sorted by</Text>\n <Menu>\n <MenuButton\n as={Button}\n color=\"link\"\n data-event={eventName(SEARCH_ANALYTICS.SORT, \"Menu\")}\n data-testid={testIds.sortButton}\n ml={2}\n pl={2} // For some reason, the px shorthand doesn't work on this Button\n pr={2}\n py={1}\n rightIcon={<ChevronDownIcon />}\n variant=\"link\"\n >\n {selected}\n </MenuButton>\n <MenuList data-testid={testIds.sortDropdown} minW=\"180\" zIndex=\"sticky\">\n <MenuItem\n data-event={eventName(SEARCH_ANALYTICS.SORT, \"Option\", \"Relevance\")}\n data-testid={testIds.sortItem}\n data-value=\"\"\n key=\"Relevance\"\n onClick={() => updateSearch({ sort: undefined })}\n >\n Relevance\n </MenuItem>\n {Object.entries(SORT_RENDER_MAP).map(([value, display]) => (\n <MenuItem\n data-event={eventName(SEARCH_ANALYTICS.SORT, \"Option\", display)}\n data-testid={testIds.sortItem}\n data-value={value}\n key={value}\n onClick={() => updateSearch({ sort: value as CatalogSearchSort })}\n >\n {display}\n </MenuItem>\n ))}\n </MenuList>\n </Menu>\n </Flex>\n );\n};\n","import { Box, Stack } from \"@chakra-ui/react\";\nimport { FunctionComponent, useEffect } from \"react\";\nimport { PackageList } from \"../../components/PackageList\";\nimport { Page } from \"../../components/Page\";\nimport { useCatalogResults } from \"../../hooks/useCatalogResults\";\nimport { LIMIT, SEARCH_ANALYTICS } from \"./constants\";\nimport { PageControls } from \"./PageControls\";\nimport { SearchBar } from \"./SearchBar\";\nimport { SearchDetails } from \"./SearchDetails\";\nimport { SortAndFilterDrawer } from \"./SortAndFilterDrawer\";\nimport { SortedBy } from \"./SortedBy\";\nimport {\n useCdkType,\n useCdkMajor,\n useKeywords,\n useLanguages,\n useOffset,\n useSearchQuery,\n useSort,\n useTags,\n} from \"./useSearchParam\";\nimport { useUpdateSearchParam } from \"./useUpdateSearchParam\";\n\nexport const SearchResults: FunctionComponent = () => {\n const updateSearch = useUpdateSearchParam();\n\n const offset = useOffset();\n const query = useSearchQuery();\n const keywords = useKeywords();\n const languages = useLanguages();\n const cdkMajor = useCdkMajor();\n const cdkType = useCdkType();\n const sort = useSort();\n const tags = useTags();\n\n const { page, pageLimit, results } = useCatalogResults({\n offset,\n limit: LIMIT,\n query,\n keywords,\n languages,\n cdkMajor,\n cdkType,\n sort,\n tags,\n });\n\n // Resets the page number to 1 if query param offset is below 0, or to the last page if offset is higher than page count\n useEffect(() => {\n // If the query has results but the page has nothing to show...\n if (results.length && (offset < 0 || offset > pageLimit)) {\n // Handle an out of bounds offset\n if (offset < 0) {\n updateSearch({ offset: 0 });\n } else {\n // Offset is too large, just take last page\n updateSearch({ offset: pageLimit });\n }\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [results, offset, pageLimit]);\n\n // Scroll to top on page change\n useEffect(() => {\n window.scrollTo(0, 0);\n }, [page]);\n\n return (\n <Page\n meta={{\n title: query || \"Search\",\n description: query\n ? `${results.length} results for ${query} at Construct Hub`\n : \"Search reusable components for your cloud application\",\n }}\n pageName=\"search\"\n >\n <Stack direction=\"column\" maxW=\"100vw\" pb={4} px={4} spacing={4}>\n <SearchBar />\n\n <Stack\n align={{ base: \"start\", lg: \"center\" }}\n direction={{ base: \"column-reverse\", lg: \"row\" }}\n justify={{ base: \"initial\", lg: \"space-between\" }}\n spacing={4}\n >\n <SearchDetails\n count={results.length}\n filtered={!!query}\n limit={LIMIT}\n offset={offset}\n query={query}\n />\n\n <Box display={{ base: \"none\", md: \"initial\" }}>\n <SortedBy />\n </Box>\n\n <Box display={{ md: \"none\" }}>\n <SortAndFilterDrawer />\n </Box>\n </Stack>\n\n <PackageList data-event={SEARCH_ANALYTICS.RESULTS} items={page} />\n\n <Box w=\"full\">\n <PageControls offset={offset} pageLimit={pageLimit} />\n </Box>\n </Stack>\n </Page>\n );\n};\n","import { Grid } from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\nimport { Page } from \"../../components/Page\";\nimport { FilterPanel } from \"./FilterPanel\";\nimport { SearchResults } from \"./SearchResults\";\nimport testIds from \"./testIds\";\n\nexport const Search: FunctionComponent = () => {\n return (\n <Page\n meta={{\n title: \"Search - Construct Hub\",\n description: \"Search Construct Libraries for AWS CDK, CDK8s, and CDKtf\",\n }}\n pageName=\"search\"\n >\n <Grid\n data-testid={testIds.page}\n gap={4}\n h=\"full\"\n maxW=\"100%\"\n px={{ base: 0, md: 6 }}\n py={6}\n templateColumns={{ base: \"1fr\", md: \"auto 1fr\" }}\n templateRows=\"1fr\"\n >\n {/* Filter Panel Desktop */}\n <FilterPanel />\n\n {/* Results, Info, and Controls */}\n <SearchResults />\n </Grid>\n </Page>\n );\n};\n"],"names":["SORT_RENDER_MAP","CatalogSearchSort","searchEvent","e","eventName","SEARCH_ANALYTICS","FILTERS","RESULTS","SEARCH","SORT","FilterHeading","name","hint","placement","useBreakpointValue","base","md","align","mb","as","size","w","colorScheme","strategy","ml","h","bg","borderRadius","color","fontSize","mx","shadow","createTestIds","RadioFilter","dataTestid","checkedValue","value","onValueChange","options","spacing","onChange","map","display","dataEvent","testIds","filterItem","isTruncated","toNum","val","result","parseInt","parseQueryArray","queryString","decodeURIComponent","split","getParamFromUrl","key","window","URL","location","href","searchParams","get","useSearchParam","transform","qp","useQueryParams","useMemo","useCdkType","QUERY_PARAMS","undefined","useCdkMajor","p","useKeywords","useLanguages","useSearchQuery","useSort","useTags","useUpdateSearchParam","push","useHistory","useCallback","offset","params","getSearchPath","query","keywords","cdkType","cdkMajor","cdkMajorParam","languages","sort","tags","getSearchUrlParams","CDKFilter","updateSearch","searchAPI","useSearchContext","cdkOptions","cdkTypes","constructFrameworks","Object","entries","reduce","opts","meta","pkgCount","CDKTYPE_NAME_MAP","keys","length","majorsOptions","majorVersions","a","b","toString","cdkTypeFilter","type","values","cdkVersionFilter","major","majorNum","CheckboxItem","isDisabled","disabledHint","isChecked","hasArrow","label","CheckboxFilter","initialItemCount","checkedValues","collapse","useDisclosure","trackCustomEvent","useAnalytics","getOnChange","item","clickEvent","alwaysShow","showWhenExpanded","slice","isExpandible","direction","mt","includes","animateOpacity","in","isOpen","unmountOnExit","fontWeight","leftIcon","onClick","onToggle","textAlign","variant","KeywordsFilter","keywordMap","keywordOptions","baseOptions","filter","keyword","keywordsNotInOptions","k","some","opt","languagesFilter","languageOptions","LANGUAGE_NAME_MAP","TEMP_SUPPORTED_LANGUAGES","l1","l2","LanguageFilter","lang","language","l","TagFilter","packageTags","useConfigValue","packageTagGroups","tagFilterGroups","tagGroupsMap","Map","forEach","group","set","id","accum","tag","groupIdOrName","searchFilter","groupBy","customGroup","entry","mapTagsToFilterGroups","Boolean","onTagsChange","t","getOnRadioTagChange","groupName","groupTags","Set","filteredTags","has","filterType","tooltip","tagItems","sharedProps","find","TOP_OFFSET","FilterPanel","Card","filtersPanel","maxH","maxW","minW","overflow","pos","top","zIndex","listViews","PackageCardType","items","pkg","PackageCard","version","PackageList","memo","cardView","loading","View","displayName","ArrowButton","Icon","icon","props","borderColor","disabled","GoToPage","pageLimit","useState","inputValue","setInputValue","useEffect","onSubmit","preventDefault","max","min","target","onFocus","PageControls","goForward","goBack","justify","prevPage","ChevronLeftIcon","goToPage","nextPage","ChevronRightIcon","SearchBar","setValue","Em","children","Count","first","count","last","SearchDetails","limit","filtered","hasResults","searchDetails","SortFilter","newSort","SortAndFilterDrawer","drawer","onOpen","rightIcon","borderBottom","pb","SortedBy","selected","Button","sortButton","pl","pr","py","sortDropdown","sortItem","SearchResults","o","useCatalogResults","page","results","scrollTo","Page","title","description","pageName","px","lg","Search","gap","templateColumns","templateRows"],"sourceRoot":""}
|
1
|
+
{"version":3,"file":"static/js/51.3b58a25f.chunk.js","mappings":"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","sources":["views/Search/constants.ts","views/Search/FilterHeading.tsx","views/Search/testIds.ts","views/Search/RadioFilter.tsx","views/Search/util.ts","views/Search/useSearchParam.ts","views/Search/useUpdateSearchParam.ts","views/Search/CDKFilter.tsx","views/Search/CheckboxFilter.tsx","views/Search/KeywordsFilter.tsx","views/Search/LanguageFilter.tsx","views/Search/TagFilter.tsx","views/Search/FilterPanel.tsx","components/PackageList/PackageList.tsx","components/PackageList/WideCardList.tsx","views/Search/ArrowButton.tsx","views/Search/GoToPage.tsx","views/Search/PageControls.tsx","views/Search/SearchBar.tsx","views/Search/SearchDetails.tsx","views/Search/SortFilter.tsx","views/Search/SortAndFilterDrawer.tsx","views/Search/SortedBy.tsx","views/Search/SearchResults.tsx","views/Search/Search.tsx"],"sourcesContent":["import { CatalogSearchSort } from \"../../api/catalog-search/constants\";\nimport type { QueryParamKey } from \"../../constants/url\";\nimport { eventName } from \"../../contexts/Analytics\";\n\nconst LIMITS = [25, 50, 75, 100];\nexport const LIMIT = LIMITS[0];\n\nexport type SearchQueryParam = Extract<QueryParamKey, \"offset\" | \"q\">;\n\nexport const SORT_RENDER_MAP = {\n [CatalogSearchSort.NameAsc]: \"A-Z\",\n [CatalogSearchSort.NameDesc]: \"Z-A\",\n [CatalogSearchSort.PublishDateAsc]: \"Oldest\",\n [CatalogSearchSort.PublishDateDesc]: \"Recently updated\",\n [CatalogSearchSort.DownloadsDesc]: \"Most downloads\",\n [CatalogSearchSort.DownloadsAsc]: \"Least downloads\",\n};\n\nconst searchEvent: typeof eventName = (...e) => eventName(\"Search\", ...e);\n\nexport const SEARCH_ANALYTICS = {\n FILTERS: searchEvent(\"Filters\"),\n RESULTS: searchEvent(\"Results\"),\n SEARCH: searchEvent(\"Search\"),\n SORT: searchEvent(\"Sort\"),\n};\n","import { QuestionIcon } from \"@chakra-ui/icons\";\nimport {\n Flex,\n Heading,\n Text,\n Popover,\n PopoverTrigger,\n PopoverBody,\n PopoverArrow,\n PopoverContent,\n useBreakpointValue,\n PlacementWithLogical,\n} from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\nimport { eventName } from \"../../contexts/Analytics\";\nimport { SEARCH_ANALYTICS } from \"./constants\";\n\nexport interface FilterHeadingProps {\n name: string;\n hint?: string;\n}\n\nexport const FilterHeading: FunctionComponent<FilterHeadingProps> = ({\n name,\n hint,\n}) => {\n const placement = useBreakpointValue<PlacementWithLogical>({\n base: \"auto\",\n md: \"right\",\n });\n\n return (\n <Flex align=\"center\" mb={1}>\n <Heading as=\"h3\" size=\"sm\" w=\"max-content\">\n {name}\n </Heading>\n {hint ? (\n <Popover colorScheme=\"dark\" placement={placement} strategy=\"fixed\">\n <PopoverTrigger>\n <Flex\n aria-label={`Hint: ${name}`}\n as=\"button\"\n data-event={eventName(SEARCH_ANALYTICS.FILTERS, name, \"Popover\")}\n ml={2}\n >\n <QuestionIcon h={3.5} w={3.5} />\n </Flex>\n </PopoverTrigger>\n <PopoverContent\n bg=\"gray.700\"\n borderRadius=\"base\"\n color=\"white\"\n fontSize=\"sm\"\n mx={{ base: \"1rem\", md: \"initial\" }}\n shadow=\"whiteAlpha.300\"\n >\n <PopoverArrow bg=\"gray.700\" />\n <PopoverBody>\n <Text>{hint}</Text>\n </PopoverBody>\n </PopoverContent>\n </Popover>\n ) : null}\n </Flex>\n );\n};\n","import { createTestIds } from \"../../util/createTestIds\";\n\nexport default createTestIds(\"searchRedesign\", [\n \"page\",\n // Results\n \"searchDetails\",\n \"nextPage\",\n \"prevPage\",\n \"goToPage\",\n // Sorting\n \"sortButton\",\n \"sortDropdown\",\n \"sortItem\",\n // Filters Panel\n \"filtersPanel\",\n \"cdkTypeFilter\",\n \"cdkVersionFilter\",\n \"filterItem\",\n \"languagesFilter\",\n] as const);\n","import { Radio, RadioGroup, Stack, Text } from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\nimport { eventName } from \"../../contexts/Analytics\";\nimport { SEARCH_ANALYTICS } from \"./constants\";\nimport { FilterHeading, FilterHeadingProps } from \"./FilterHeading\";\nimport testIds from \"./testIds\";\n\nexport interface RadioFilterProps extends FilterHeadingProps {\n \"data-testid\"?: string;\n value?: string;\n onValueChange: (value: string) => void;\n options: {\n display: string;\n value: string;\n }[];\n}\n\nexport const RadioFilter: FunctionComponent<RadioFilterProps> = ({\n \"data-testid\": dataTestid,\n value: checkedValue,\n onValueChange,\n options,\n name,\n hint,\n}) => {\n return (\n <Stack data-testid={dataTestid} spacing={1}>\n <FilterHeading hint={hint} name={name} />\n <RadioGroup onChange={onValueChange} value={checkedValue}>\n <Stack spacing={1}>\n {options.map(({ display, value }) => {\n const dataEvent = eventName(\n SEARCH_ANALYTICS.FILTERS,\n name,\n \"Filter\",\n display\n );\n return (\n <Radio data-event={dataEvent} key={value} value={value}>\n <Text\n color=\"textTertiary\"\n data-event={dataEvent}\n data-testid={testIds.filterItem}\n data-value={value}\n isTruncated\n >\n {display}\n </Text>\n </Radio>\n );\n })}\n </Stack>\n </RadioGroup>\n </Stack>\n );\n};\n","import { CatalogSearchSort } from \"../../api/catalog-search/constants\";\nimport { CDKType } from \"../../constants/constructs\";\nimport { Language } from \"../../constants/languages\";\nimport { QUERY_PARAMS } from \"../../constants/url\";\n\nexport const toNum = (val: string) => {\n const result = parseInt(val);\n\n if (`${result}` === \"NaN\") {\n return 0;\n }\n\n return result;\n};\n\nexport const parseQueryArray = <T extends string>(\n queryString: string | null\n) => {\n if (!queryString) return [];\n\n return decodeURIComponent(queryString).split(\",\") as T[];\n};\n\nconst getParamFromUrl = (key: string) => {\n if (typeof window === \"undefined\") return null;\n const queryParams = new URL(window.location.href).searchParams;\n return queryParams.get(key);\n};\n\nexport const getSearchUrlParams = () => {\n return {\n query: getParamFromUrl(QUERY_PARAMS.SEARCH_QUERY) ?? \"\",\n keywords: parseQueryArray(getParamFromUrl(QUERY_PARAMS.KEYWORDS)),\n cdkType: (getParamFromUrl(QUERY_PARAMS.CDK_TYPE) as CDKType) ?? undefined,\n cdkMajor: (() => {\n const cdkMajorParam = getParamFromUrl(QUERY_PARAMS.CDK_MAJOR);\n return cdkMajorParam ? toNum(cdkMajorParam) : undefined;\n })(),\n languages: parseQueryArray(\n getParamFromUrl(QUERY_PARAMS.LANGUAGES)\n ) as Language[],\n offset: toNum(getParamFromUrl(QUERY_PARAMS.OFFSET) ?? \"\"),\n sort:\n (getParamFromUrl(QUERY_PARAMS.SORT) as CatalogSearchSort) ?? undefined,\n tags: parseQueryArray(getParamFromUrl(QUERY_PARAMS.TAGS)),\n };\n};\n","import { useMemo } from \"react\";\nimport { CatalogSearchSort } from \"../../api/catalog-search/constants\";\nimport { CDKType } from \"../../constants/constructs\";\nimport { Language } from \"../../constants/languages\";\nimport { QUERY_PARAMS } from \"../../constants/url\";\nimport { useQueryParams } from \"../../hooks/useQueryParams\";\nimport { parseQueryArray, toNum } from \"./util\";\n\nconst useSearchParam = <T = string | null>(\n key: string,\n transform?: (param: string | null) => T\n): T => {\n const queryParams = useQueryParams();\n const qp = queryParams.get(key);\n\n return useMemo(\n () => (transform ? transform(qp) : (qp as unknown as T)),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [qp]\n );\n};\n\nexport const useCdkType = () => {\n const cdkType: CDKType | undefined =\n useSearchParam(QUERY_PARAMS.CDK_TYPE) ?? undefined;\n\n return cdkType;\n};\n\nexport const useCdkMajor = () => {\n const cdkMajor: number | undefined = useSearchParam(\n QUERY_PARAMS.CDK_MAJOR,\n (p) => (p ? toNum(p) : undefined)\n );\n\n return cdkMajor;\n};\n\nexport const useKeywords = () => {\n const keywords: string[] = useSearchParam(\n QUERY_PARAMS.KEYWORDS,\n parseQueryArray\n );\n\n return keywords;\n};\n\nexport const useLanguages = () => {\n const languages: Language[] = useSearchParam(\n QUERY_PARAMS.LANGUAGES,\n parseQueryArray\n ) as Language[];\n\n return languages;\n};\n\nexport const useOffset = () => {\n const offset = useSearchParam(QUERY_PARAMS.OFFSET, (o) => toNum(o ?? \"\"));\n return offset;\n};\n\nexport const useSearchQuery = () => {\n const query: string = useSearchParam(QUERY_PARAMS.SEARCH_QUERY) ?? \"\";\n return query;\n};\n\nexport const useSort = () => {\n const sort: CatalogSearchSort | undefined =\n useSearchParam(QUERY_PARAMS.SORT) ?? undefined;\n return sort;\n};\n\nexport const useTags = () => {\n const tags: string[] = useSearchParam(QUERY_PARAMS.TAGS, parseQueryArray);\n return tags;\n};\n","import { useCallback } from \"react\";\nimport { useHistory } from \"react-router-dom\";\nimport { getSearchPath } from \"../../util/url\";\nimport { getSearchUrlParams } from \"./util\";\n\nexport const useUpdateSearchParam = () => {\n const { push } = useHistory();\n\n return useCallback(\n (p?: Partial<Parameters<typeof getSearchPath>[0]>) => {\n const { offset, ...params } = p ?? {};\n\n push(\n getSearchPath({\n ...getSearchUrlParams(),\n ...params,\n offset: offset ?? 0,\n })\n );\n },\n [push]\n );\n};\n","import { FunctionComponent, useMemo } from \"react\";\nimport { CatalogConstructFrameworkMeta } from \"../../api/catalog-search\";\nimport { CDKType, CDKTYPE_NAME_MAP } from \"../../constants/constructs\";\nimport { useSearchContext } from \"../../contexts/Search\";\nimport { RadioFilter } from \"./RadioFilter\";\nimport testIds from \"./testIds\";\nimport { useCdkMajor, useCdkType } from \"./useSearchParam\";\nimport { useUpdateSearchParam } from \"./useUpdateSearchParam\";\n\ntype CDKOptions = Partial<{\n [key in CDKType]: CatalogConstructFrameworkMeta & {\n display: string;\n value: key;\n };\n}>;\n\nexport const CDKFilter: FunctionComponent = () => {\n const cdkType = useCdkType();\n const cdkMajor = useCdkMajor();\n\n const updateSearch = useUpdateSearchParam();\n\n const searchAPI = useSearchContext()!;\n\n // Options with less than one package will be omitted\n const cdkOptions = useMemo(() => {\n const cdkTypes = searchAPI.constructFrameworks;\n const options = Object.entries(cdkTypes).reduce((opts, [name, meta]) => {\n if (meta.pkgCount < 1) {\n return opts;\n }\n\n return {\n ...opts,\n [name]: {\n display: CDKTYPE_NAME_MAP[name as CDKType],\n value: name,\n ...meta,\n },\n };\n }, {});\n\n return Object.keys(options).length ? (options as CDKOptions) : undefined;\n }, [searchAPI]);\n\n const majorsOptions = useMemo(() => {\n if (!cdkOptions || !cdkType) return undefined;\n const majorVersions = cdkOptions[cdkType]?.majorVersions;\n\n if (!majorVersions) return undefined;\n\n return [...majorVersions]\n .sort((a, b) => a - b)\n .map((value) => ({\n value: value.toString(),\n display: `${CDKTYPE_NAME_MAP[cdkType]} v${value}`,\n }));\n }, [cdkOptions, cdkType]);\n\n if (!cdkOptions) {\n return null;\n }\n\n const onCdkTypeChange = (type: string) => {\n const cdk = type as CDKType;\n updateSearch({ cdkType: type ? cdk : undefined, cdkMajor: undefined });\n };\n\n const onCdkMajorChange = (major: string) => {\n let majorNum: number | undefined = undefined;\n\n if (major) {\n majorNum = parseInt(major, 10);\n }\n\n updateSearch({ cdkMajor: majorNum });\n };\n\n return (\n <>\n <RadioFilter\n data-testid={testIds.cdkTypeFilter}\n hint=\"Choose the right CDK for your IaC technology: AWS CDK for AWS CloudFormation, CDKtf for Terraform, or CDK8s for Kubernetes.\"\n name=\"CDK Type\"\n onValueChange={onCdkTypeChange}\n options={[\n { display: \"Any CDK Type\", value: \"\" },\n ...Object.values(cdkOptions),\n ]}\n value={cdkType ?? \"\"}\n />\n {/* No point in showing major versions if only a single one is available */}\n {!!(majorsOptions && majorsOptions.length > 1) && (\n <RadioFilter\n data-testid={testIds.cdkVersionFilter}\n hint=\"Choose the major version of the CDK you're using to see only constructs that will work with that version.\"\n name=\"CDK Major Version\"\n onValueChange={onCdkMajorChange}\n options={[\n { display: \"Any Major Version\", value: \"\" },\n ...majorsOptions,\n ]}\n value={cdkMajor?.toString() ?? \"\"}\n />\n )}\n </>\n );\n};\n","import { ChevronDownIcon, ChevronUpIcon } from \"@chakra-ui/icons\";\nimport {\n Flex,\n Button,\n Collapse,\n Checkbox,\n Stack,\n Text,\n Tooltip,\n useDisclosure,\n} from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\nimport { clickEvent, eventName, useAnalytics } from \"../../contexts/Analytics\";\nimport { SEARCH_ANALYTICS } from \"./constants\";\nimport { FilterHeading, FilterHeadingProps } from \"./FilterHeading\";\nimport testIds from \"./testIds\";\n\ninterface CheckboxOption {\n display: string;\n value: string;\n isDisabled?: boolean;\n disabledHint?: string;\n}\n\ninterface CheckboxItemProps extends CheckboxOption {\n onChange: () => void;\n isChecked: boolean;\n}\n\nexport interface CheckboxFilterProps extends FilterHeadingProps {\n /**\n * Test ID to select checkbox in tests\n */\n \"data-testid\"?: string;\n /**\n * Number of items that can be initially shown\n */\n initialItemCount?: number;\n /**\n * Defines checkbox items\n */\n options: CheckboxOption[];\n /**\n * Selected values\n */\n values: string[];\n /**\n * Callback triggered when an item is clicked\n */\n onValueChange: (value: string) => void;\n}\n\nconst CheckboxItem: FunctionComponent<CheckboxItemProps> = ({\n display,\n value,\n isDisabled,\n disabledHint,\n isChecked,\n onChange,\n}) => (\n <Checkbox\n isChecked={isChecked}\n isDisabled={isDisabled}\n key={value}\n onChange={onChange}\n >\n <Tooltip\n hasArrow\n isDisabled={!isDisabled && !disabledHint}\n label={disabledHint}\n placement=\"right\"\n >\n <Text\n color=\"textTertiary\"\n data-testid={testIds.filterItem}\n data-value={value}\n isTruncated\n >\n {display}\n </Text>\n </Tooltip>\n </Checkbox>\n);\n\nexport const CheckboxFilter: FunctionComponent<CheckboxFilterProps> = ({\n \"data-testid\": dataTestid,\n initialItemCount,\n hint,\n name,\n options,\n values: checkedValues,\n onValueChange,\n}) => {\n const collapse = useDisclosure();\n const { trackCustomEvent } = useAnalytics();\n\n const getOnChange = (item: CheckboxOption) => () => {\n trackCustomEvent(\n clickEvent({\n name: eventName(SEARCH_ANALYTICS.FILTERS, name, \"Filter\", item.display),\n })\n );\n onValueChange(item.value);\n };\n\n let alwaysShow: typeof options = options;\n let showWhenExpanded: typeof options = [];\n\n if (initialItemCount) {\n alwaysShow = options.slice(0, initialItemCount);\n showWhenExpanded = options.slice(initialItemCount, options.length);\n }\n\n const isExpandible = showWhenExpanded.length > 0;\n\n return (\n <Flex data-testid={dataTestid} direction=\"column\">\n <FilterHeading hint={hint} name={name} />\n <Stack mt={1} spacing={1}>\n {alwaysShow.map((item) => (\n <CheckboxItem\n {...item}\n isChecked={checkedValues.includes(item.value)}\n key={item.value}\n onChange={getOnChange(item)}\n />\n ))}\n {isExpandible && (\n <Collapse animateOpacity in={collapse.isOpen} unmountOnExit>\n <Stack spacing={1}>\n {showWhenExpanded.map((item) => (\n <CheckboxItem\n {...item}\n isChecked={checkedValues.includes(item.value)}\n key={item.value}\n onChange={getOnChange(item)}\n />\n ))}\n </Stack>\n </Collapse>\n )}\n </Stack>\n {isExpandible && (\n <Flex align=\"start\" mt={1}>\n <Button\n color=\"textTertiary\"\n data-event={eventName(SEARCH_ANALYTICS.FILTERS, name, \"Show More\")}\n fontWeight=\"normal\"\n leftIcon={collapse.isOpen ? <ChevronUpIcon /> : <ChevronDownIcon />}\n onClick={collapse.onToggle}\n size=\"sm\"\n textAlign=\"left\"\n variant=\"link\"\n w=\"auto\"\n >\n {collapse.isOpen\n ? `Show fewer options (${alwaysShow.length})`\n : `Show more options (${showWhenExpanded.length})`}\n </Button>\n </Flex>\n )}\n </Flex>\n );\n};\n","import { FunctionComponent, useMemo } from \"react\";\nimport { useSearchContext } from \"../../contexts/Search\";\nimport { CheckboxFilter } from \"./CheckboxFilter\";\nimport testIds from \"./testIds\";\nimport { useKeywords } from \"./useSearchParam\";\nimport { useUpdateSearchParam } from \"./useUpdateSearchParam\";\n\nexport const KeywordsFilter: FunctionComponent = () => {\n const keywords = useKeywords();\n const keywordMap = useSearchContext()!.keywords;\n const updateSearch = useUpdateSearchParam();\n\n const onKeywordChange = (keyword: string) => {\n updateSearch({\n keywords: keywords.includes(keyword)\n ? keywords.filter((k) => k !== keyword)\n : [...keywords, keyword],\n });\n };\n\n const keywordOptions = useMemo(() => {\n const baseOptions = [...keywordMap.entries()]\n .sort(([, count1], [, count2]) => {\n return count1 < count2 ? 1 : -1;\n })\n .filter(([keyword]) => !keywords.includes(keyword))\n .map(([keyword]) => ({\n display: keyword,\n value: keyword,\n }))\n .slice(0, 25);\n\n const keywordsNotInOptions = keywords.filter(\n (k) => !baseOptions.some((opt) => opt.value === k)\n );\n\n return [\n ...keywordsNotInOptions.map((k) => ({ display: k, value: k })),\n ...baseOptions,\n ];\n }, [keywordMap, keywords]);\n\n return (\n <CheckboxFilter\n data-testid={testIds.languagesFilter}\n hint=\"Focus the results by choosing one or more keywords reflecting the kind of construct you're looking for. Keywords are provided by construct authors.\"\n initialItemCount={5}\n name=\"Keywords\"\n onValueChange={onKeywordChange}\n options={keywordOptions}\n values={keywords}\n />\n );\n};\n","import { FunctionComponent } from \"react\";\nimport {\n Language,\n LANGUAGE_NAME_MAP,\n TEMP_SUPPORTED_LANGUAGES,\n} from \"../../constants/languages\";\nimport { CheckboxFilter } from \"./CheckboxFilter\";\nimport testIds from \"./testIds\";\nimport { useLanguages } from \"./useSearchParam\";\nimport { useUpdateSearchParam } from \"./useUpdateSearchParam\";\n\nconst languageOptions = Object.entries(LANGUAGE_NAME_MAP)\n .map(([key, value]) => ({\n display: value,\n value: key,\n ...(TEMP_SUPPORTED_LANGUAGES.has(key as Language)\n ? { isDisabled: false }\n : {\n isDisabled: true,\n disabledHint: `${\n LANGUAGE_NAME_MAP[key as Language]\n } support is coming soon!`,\n }),\n }))\n .sort((l1, l2) => {\n // Push disabled languages to back of list\n return l1.isDisabled > l2.isDisabled ? 1 : -1;\n });\n\nexport const LanguageFilter: FunctionComponent = () => {\n const languages = useLanguages();\n\n const updateSearch = useUpdateSearchParam();\n\n const onLanguagesChange = (lang: string) => {\n const language = lang as Language;\n\n updateSearch({\n languages: languages.includes(language)\n ? languages.filter((l) => l !== language)\n : [...languages, language],\n });\n };\n\n return (\n <CheckboxFilter\n data-testid={testIds.languagesFilter}\n hint=\"Choose one or more languages. Results include constructs for use with at least one of the selected languages.\"\n name=\"Programming Language\"\n onValueChange={onLanguagesChange}\n options={languageOptions}\n values={languages}\n />\n );\n};\n","import { FunctionComponent, useCallback, useMemo } from \"react\";\nimport { PackageTagConfig, TagGroupConfig } from \"../../api/config\";\nimport { useConfigValue } from \"../../hooks/useConfigValue\";\nimport { CheckboxFilter } from \"./CheckboxFilter\";\nimport { RadioFilter } from \"./RadioFilter\";\nimport { useTags } from \"./useSearchParam\";\nimport { useUpdateSearchParam } from \"./useUpdateSearchParam\";\n\ninterface FilterGroup extends Partial<TagGroupConfig> {\n id: string;\n tags: PackageTagConfig[];\n}\ninterface FilterGroups {\n [group: string]: FilterGroup;\n}\n\n/**\n * Creates a plain object map of FilterGroups keyed by group id\n */\nexport const mapTagsToFilterGroups = (\n packageTags: PackageTagConfig[],\n tagGroupsMap: Map<string, TagGroupConfig>\n): FilterGroups => {\n return packageTags.reduce(\n (accum: FilterGroups, tag: PackageTagConfig): FilterGroups => {\n const groupIdOrName = tag.searchFilter?.groupBy;\n const customGroup = groupIdOrName\n ? tagGroupsMap.get(groupIdOrName)\n : undefined;\n\n if (groupIdOrName && customGroup) {\n const entry = accum[groupIdOrName];\n if (entry) {\n entry.tags = [...entry.tags, tag];\n return accum;\n }\n\n return {\n ...accum,\n [groupIdOrName]: {\n ...customGroup,\n tags: [tag],\n },\n };\n }\n\n if (groupIdOrName) {\n return {\n ...accum,\n [groupIdOrName]: {\n id: groupIdOrName,\n tags: [...(accum?.[groupIdOrName]?.tags ?? []), tag],\n },\n };\n }\n return accum;\n },\n {}\n );\n};\n\nexport const TagFilter: FunctionComponent = () => {\n const packageTags = useConfigValue(\"packageTags\");\n const packageTagGroups = useConfigValue(\"packageTagGroups\");\n\n const tagFilterGroups: FilterGroups = useMemo(() => {\n const tagGroupsMap = new Map<string, TagGroupConfig>();\n packageTagGroups?.forEach((group) => {\n tagGroupsMap.set(group.id, group);\n });\n\n const filterableTags =\n packageTags?.filter((tag) => Boolean(tag.searchFilter)) ?? [];\n\n return mapTagsToFilterGroups(filterableTags, tagGroupsMap);\n }, [packageTags, packageTagGroups]);\n\n const tags = useTags();\n const updateSearch = useUpdateSearchParam();\n\n const onTagsChange = (tag: string) => {\n updateSearch({\n tags: tags.includes(tag) ? tags.filter((t) => t !== tag) : [...tags, tag],\n });\n };\n\n const getOnRadioTagChange = useCallback(\n (groupName: string) => {\n const groupTags = new Set(\n (tagFilterGroups[groupName]?.tags ?? []).map(({ id }) => id)\n );\n\n return (tag: string) => {\n const filteredTags = tags.filter((t) => !groupTags.has(t));\n\n updateSearch({\n tags: tag ? [...filteredTags, tag] : filteredTags,\n });\n };\n },\n [tagFilterGroups, tags, updateSearch]\n );\n\n return (\n <>\n {Object.values(tagFilterGroups).map(\n ({ filterType, id, label, tooltip, tags: tagItems }) => {\n const sharedProps = {\n hint: tooltip,\n name: label ?? id,\n options: tagItems.map((tag) => {\n return {\n display: tag.searchFilter!.display,\n value: tag.id,\n };\n }),\n };\n\n if (filterType === \"radio\") {\n return (\n <RadioFilter\n {...sharedProps}\n key={id}\n onValueChange={getOnRadioTagChange(id)}\n options={[\n { display: `Any ${sharedProps.name}`, value: \"\" },\n ...sharedProps.options,\n ]}\n value={tagItems.find((t) => tags.includes(t.id))?.id ?? \"\"}\n />\n );\n }\n\n return (\n <CheckboxFilter\n {...sharedProps}\n key={id}\n onValueChange={onTagsChange}\n values={tags}\n />\n );\n }\n )}\n </>\n );\n};\n","import { Heading, Stack } from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\nimport { Card } from \"../../components/Card\";\nimport { CDKFilter } from \"./CDKFilter\";\nimport { KeywordsFilter } from \"./KeywordsFilter\";\nimport { LanguageFilter } from \"./LanguageFilter\";\nimport { TagFilter } from \"./TagFilter\";\nimport testIds from \"./testIds\";\n\nexport interface FilterPanelProps {}\n\n// Header height + section padding\nconst TOP_OFFSET = \"5.75rem\";\n\n/**\n * The desktop Resolution Filter Panel\n */\nexport const FilterPanel: FunctionComponent<FilterPanelProps> = () => {\n return (\n <Card\n borderRadius=\"sm\"\n data-testid={testIds.filtersPanel}\n display={{ base: \"none\", md: \"flex\" }}\n maxH={`calc(100vh - ${TOP_OFFSET} - 1.25rem)`}\n maxW=\"23rem\"\n minW=\"100%\"\n overflow=\"hidden auto\"\n p={4}\n pos=\"sticky\"\n top={TOP_OFFSET}\n zIndex=\"docked\"\n >\n <Stack color=\"textPrimary\" h=\"max-content\" spacing={4} top={4}>\n <Heading as=\"h2\" size=\"sm\">\n Filters\n </Heading>\n\n <CDKFilter />\n\n <LanguageFilter />\n\n <TagFilter />\n\n <KeywordsFilter />\n </Stack>\n </Card>\n );\n};\n","import { Center, Spinner } from \"@chakra-ui/react\";\nimport { FunctionComponent, memo } from \"react\";\nimport { ExtendedCatalogPackage } from \"../../api/catalog-search\";\nimport { PackageCardType } from \"../PackageCard\";\nimport { WideCardList } from \"./WideCardList\";\n\nconst listViews = {\n [PackageCardType.Wide]: WideCardList,\n};\n\nexport interface PackageListViewProps {\n \"data-event\"?: string;\n items: ExtendedCatalogPackage[];\n}\n\nexport interface PackageListProps extends Partial<PackageListViewProps> {\n cardView?: PackageCardType;\n loading?: boolean;\n title?: string;\n}\n\nexport const PackageList: FunctionComponent<PackageListProps> = memo(\n ({\n \"data-event\": dataEvent,\n cardView = PackageCardType.Wide,\n items,\n loading,\n }) => {\n if (loading || !items) {\n return (\n <Center>\n <Spinner size=\"xl\" />\n </Center>\n );\n }\n\n const View = listViews[cardView];\n\n return <View data-event={dataEvent} items={items} />;\n }\n);\n\nPackageList.displayName = \"PackageList\";\n","import { Stack } from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\nimport { PackageCard, PackageCardType } from \"../PackageCard\";\nimport { PackageListViewProps } from \"./PackageList\";\n\nexport const WideCardList: FunctionComponent<PackageListViewProps> = ({\n \"data-event\": dataEvent,\n items,\n}) => {\n return (\n <Stack spacing={4}>\n {items.map((pkg) => (\n <PackageCard\n data-event={dataEvent}\n key={`${pkg.name}-${pkg.version}`}\n pkg={pkg}\n variant={PackageCardType.Wide}\n />\n ))}\n </Stack>\n );\n};\n","import { IconButton, IconProps } from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\n\nexport interface ArrowButtonProps {\n \"data-event\"?: string;\n \"data-testid\"?: string;\n icon: FunctionComponent<IconProps>;\n label: string;\n onClick?: () => void;\n}\n\nexport const ArrowButton: FunctionComponent<ArrowButtonProps> = ({\n \"data-event\": dataEvent,\n \"data-testid\": dataTestid,\n icon: Icon,\n label,\n onClick,\n}) => {\n const props = {\n \"aria-label\": label,\n borderRadius: \"md\",\n borderColor: \"blue.500\",\n colorScheme: \"blue\",\n \"data-event\": dataEvent,\n \"data-testid\": dataTestid,\n icon: <Icon color=\"blue.500\" h={5} w={5} />,\n mx: 2,\n h: 10,\n w: 10,\n variant: \"outline\",\n };\n\n return <IconButton {...props} disabled={!onClick} onClick={onClick} />;\n};\n","import { Flex, Input, Text } from \"@chakra-ui/react\";\nimport {\n FormEventHandler,\n FunctionComponent,\n SyntheticEvent,\n useEffect,\n useState,\n} from \"react\";\nimport { clickEvent, useAnalytics } from \"../../contexts/Analytics\";\nimport { useUpdateSearchParam } from \"./useUpdateSearchParam\";\n\nexport interface GoToPageProps {\n \"data-event\"?: string;\n \"data-testid\"?: string;\n pageLimit: number;\n offset: number;\n}\n\nexport const GoToPage: FunctionComponent<GoToPageProps> = ({\n \"data-event\": dataEvent,\n \"data-testid\": dataTestid,\n pageLimit,\n offset,\n}) => {\n const updateSearch = useUpdateSearchParam();\n const { trackCustomEvent } = useAnalytics();\n const [inputValue, setInputValue] = useState((offset + 1).toString());\n\n useEffect(() => {\n setInputValue((offset + 1).toString());\n }, [offset]);\n\n const onInputChange = (e: SyntheticEvent<HTMLInputElement>) => {\n e.preventDefault();\n setInputValue((e.target as HTMLInputElement).value);\n };\n\n const onSubmit: FormEventHandler<HTMLInputElement> = (e) => {\n e.preventDefault();\n updateSearch({ offset: parseInt(inputValue) - 1 });\n };\n\n return (\n <Flex align=\"center\" as=\"form\" mx={2} onSubmit={onSubmit}>\n <Input\n aria-label=\"Jump to page\"\n colorScheme=\"brand\"\n data-testid={dataTestid}\n h={10}\n max={pageLimit + 1}\n min={1}\n name=\"page\"\n onChange={onInputChange}\n onFocus={() => {\n if (dataEvent) {\n trackCustomEvent(clickEvent({ name: dataEvent }));\n }\n }}\n p={0}\n textAlign=\"center\"\n type=\"number\"\n value={inputValue}\n w={10}\n />\n <Text ml={2} w=\"max-content\">\n of {pageLimit + 1}\n </Text>\n </Flex>\n );\n};\n","import { ChevronLeftIcon, ChevronRightIcon } from \"@chakra-ui/icons\";\nimport { Stack } from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\nimport { eventName } from \"../../contexts/Analytics\";\nimport { ArrowButton } from \"./ArrowButton\";\nimport { SEARCH_ANALYTICS } from \"./constants\";\nimport { GoToPage } from \"./GoToPage\";\nimport testIds from \"./testIds\";\nimport { useUpdateSearchParam } from \"./useUpdateSearchParam\";\n\nexport interface PageControlsProps {\n offset: number;\n pageLimit: number;\n}\n\nexport const PageControls: FunctionComponent<PageControlsProps> = ({\n offset,\n pageLimit,\n}) => {\n const updateSearch = useUpdateSearchParam();\n const goForward =\n offset < pageLimit ? () => updateSearch({ offset: offset + 1 }) : undefined;\n const goBack =\n offset > 0 ? () => updateSearch({ offset: offset - 1 }) : undefined;\n\n return (\n <Stack\n align=\"center\"\n direction=\"row\"\n justify=\"space-between\"\n maxW=\"18rem\"\n mx=\"auto\"\n spacing={4}\n w=\"full\"\n >\n <ArrowButton\n data-event={eventName(SEARCH_ANALYTICS.RESULTS, \"Previous Page\")}\n data-testid={testIds.prevPage}\n icon={ChevronLeftIcon}\n label=\"Previous page button\"\n onClick={goBack}\n />\n <GoToPage\n data-event={eventName(SEARCH_ANALYTICS.RESULTS, \"Go to Page\")}\n data-testid={testIds.goToPage}\n offset={offset}\n pageLimit={pageLimit}\n />\n <ArrowButton\n data-event={eventName(SEARCH_ANALYTICS.RESULTS, \"Next Page\")}\n data-testid={testIds.nextPage}\n icon={ChevronRightIcon}\n label=\"Next page button\"\n onClick={goForward}\n />\n </Stack>\n );\n};\n","import { FunctionComponent, useState } from \"react\";\nimport { SearchBar as SearchBarComponent } from \"../../components/SearchBar\";\nimport { SEARCH_ANALYTICS } from \"./constants\";\nimport { useSearchQuery } from \"./useSearchParam\";\nimport { useUpdateSearchParam } from \"./useUpdateSearchParam\";\n\nexport const SearchBar: FunctionComponent = () => {\n const query = useSearchQuery();\n const updateSearch = useUpdateSearchParam();\n\n const [value, setValue] = useState(query ?? \"\");\n\n return (\n <SearchBarComponent\n bg=\"bgSecondary\"\n data-event={SEARCH_ANALYTICS.SEARCH}\n onChange={(e) => setValue(e.target.value)}\n onSubmit={(e) => {\n e.preventDefault();\n\n updateSearch({\n query: value,\n sort: undefined,\n });\n }}\n value={value}\n />\n );\n};\n","import { Text } from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\nimport testIds from \"./testIds\";\n\nexport interface SearchDetailsProps {\n limit: number;\n offset: number;\n count: number;\n filtered: boolean;\n query?: string;\n}\n\nconst Em: FunctionComponent = ({ children }) => (\n <Text as=\"strong\" color=\"textSecondary\">\n {children}\n </Text>\n);\n\nconst Count: FunctionComponent<{\n first: number;\n count: number;\n last: number;\n}> = ({ first, count, last }) => {\n if (!first && last >= count) {\n return (\n <>\n <Em>{count}</Em> of <Em>{count}</Em>\n </>\n );\n }\n\n return (\n <>\n <Em>\n {count ? first + 1 : count} - {last > count ? count : last}\n </Em>{\" \"}\n of <Em>{count}</Em>\n </>\n );\n};\n\nexport const SearchDetails: FunctionComponent<SearchDetailsProps> = ({\n limit,\n offset,\n count,\n filtered,\n query,\n}) => {\n const first = limit * offset;\n const last = first + limit;\n const hasResults = count > 0;\n\n return (\n <Text data-testid={testIds.searchDetails}>\n {hasResults ? (\n <>\n Displaying <Count count={count} first={first} last={last} />{\" \"}\n {filtered ? \"search results\" : \"constructs\"}\n </>\n ) : (\n <>{filtered ? \"There were no search results\" : \"No constructs found\"}</>\n )}\n {query && (\n <>\n {\" for \"}\n <Em>{query}</Em>\n </>\n )}\n .{!hasResults && filtered && <> Try a different term.</>}\n </Text>\n );\n};\n","import { FunctionComponent } from \"react\";\nimport { CatalogSearchSort } from \"../../api/catalog-search/constants\";\nimport { SORT_RENDER_MAP } from \"./constants\";\nimport { RadioFilter } from \"./RadioFilter\";\nimport { useSort } from \"./useSearchParam\";\nimport { useUpdateSearchParam } from \"./useUpdateSearchParam\";\n\nexport const SortFilter: FunctionComponent = () => {\n const sort = useSort();\n const updateSearch = useUpdateSearchParam();\n\n const onSortChange = (newSort: string) => {\n updateSearch({\n sort: newSort ? (newSort as CatalogSearchSort) : undefined,\n });\n };\n\n return (\n <RadioFilter\n hint=\"Sets the order of search results\"\n name=\"Sorted By\"\n onValueChange={onSortChange}\n options={[\n { display: \"Relevance\", value: \"\" },\n ...Object.entries(SORT_RENDER_MAP).map(([value, display]) => ({\n display,\n value,\n })),\n ]}\n value={sort ?? \"\"}\n />\n );\n};\n","import { ChevronDownIcon } from \"@chakra-ui/icons\";\nimport {\n Button,\n Drawer,\n Stack,\n DrawerBody,\n DrawerHeader,\n DrawerOverlay,\n DrawerContent,\n DrawerCloseButton,\n useDisclosure,\n} from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\nimport { CDKFilter } from \"./CDKFilter\";\nimport { KeywordsFilter } from \"./KeywordsFilter\";\nimport { LanguageFilter } from \"./LanguageFilter\";\nimport { SortFilter } from \"./SortFilter\";\nimport { TagFilter } from \"./TagFilter\";\n\n/**\n * The mobile filter Drawer (Bottomsheet in iOS terminology)\n */\nexport const SortAndFilterDrawer: FunctionComponent = () => {\n const drawer = useDisclosure();\n return (\n <>\n <Button\n colorScheme=\"brand\"\n display={{ md: \"none\" }}\n onClick={drawer.onOpen}\n rightIcon={<ChevronDownIcon />}\n variant=\"link\"\n >\n Sorting and Filters\n </Button>\n <Drawer {...drawer} placement=\"bottom\">\n <DrawerOverlay />\n\n <DrawerContent color=\"textPrimary\" maxH=\"full\">\n <DrawerHeader borderBottom=\"base\">Sorting and Filters</DrawerHeader>\n\n <DrawerCloseButton />\n\n <DrawerBody>\n <Stack color=\"textPrimary\" pb={4} spacing={4}>\n <SortFilter />\n\n <CDKFilter />\n\n <LanguageFilter />\n\n <TagFilter />\n\n <KeywordsFilter />\n </Stack>\n </DrawerBody>\n </DrawerContent>\n </Drawer>\n </>\n );\n};\n","import { ChevronDownIcon } from \"@chakra-ui/icons\";\nimport {\n Flex,\n Text,\n Menu,\n MenuButton,\n MenuList,\n MenuItem,\n Button,\n} from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\nimport { CatalogSearchSort } from \"../../api/catalog-search/constants\";\nimport { eventName } from \"../../contexts/Analytics\";\nimport { SEARCH_ANALYTICS, SORT_RENDER_MAP } from \"./constants\";\nimport testIds from \"./testIds\";\nimport { useSort } from \"./useSearchParam\";\nimport { useUpdateSearchParam } from \"./useUpdateSearchParam\";\n\nexport const SortedBy: FunctionComponent = () => {\n const sort = useSort();\n const updateSearch = useUpdateSearchParam();\n\n const selected = sort ? SORT_RENDER_MAP[sort] : \"Relevance\";\n\n return (\n <Flex align=\"center\">\n <Text>Sorted by</Text>\n <Menu>\n <MenuButton\n as={Button}\n color=\"link\"\n data-event={eventName(SEARCH_ANALYTICS.SORT, \"Menu\")}\n data-testid={testIds.sortButton}\n ml={2}\n pl={2} // For some reason, the px shorthand doesn't work on this Button\n pr={2}\n py={1}\n rightIcon={<ChevronDownIcon />}\n variant=\"link\"\n >\n {selected}\n </MenuButton>\n <MenuList data-testid={testIds.sortDropdown} minW=\"180\" zIndex=\"sticky\">\n <MenuItem\n data-event={eventName(SEARCH_ANALYTICS.SORT, \"Option\", \"Relevance\")}\n data-testid={testIds.sortItem}\n data-value=\"\"\n key=\"Relevance\"\n onClick={() => updateSearch({ sort: undefined })}\n >\n Relevance\n </MenuItem>\n {Object.entries(SORT_RENDER_MAP).map(([value, display]) => (\n <MenuItem\n data-event={eventName(SEARCH_ANALYTICS.SORT, \"Option\", display)}\n data-testid={testIds.sortItem}\n data-value={value}\n key={value}\n onClick={() => updateSearch({ sort: value as CatalogSearchSort })}\n >\n {display}\n </MenuItem>\n ))}\n </MenuList>\n </Menu>\n </Flex>\n );\n};\n","import { Box, Stack } from \"@chakra-ui/react\";\nimport { FunctionComponent, useEffect } from \"react\";\nimport { PackageList } from \"../../components/PackageList\";\nimport { Page } from \"../../components/Page\";\nimport { useCatalogResults } from \"../../hooks/useCatalogResults\";\nimport { LIMIT, SEARCH_ANALYTICS } from \"./constants\";\nimport { PageControls } from \"./PageControls\";\nimport { SearchBar } from \"./SearchBar\";\nimport { SearchDetails } from \"./SearchDetails\";\nimport { SortAndFilterDrawer } from \"./SortAndFilterDrawer\";\nimport { SortedBy } from \"./SortedBy\";\nimport {\n useCdkType,\n useCdkMajor,\n useKeywords,\n useLanguages,\n useOffset,\n useSearchQuery,\n useSort,\n useTags,\n} from \"./useSearchParam\";\nimport { useUpdateSearchParam } from \"./useUpdateSearchParam\";\n\nexport const SearchResults: FunctionComponent = () => {\n const updateSearch = useUpdateSearchParam();\n\n const offset = useOffset();\n const query = useSearchQuery();\n const keywords = useKeywords();\n const languages = useLanguages();\n const cdkMajor = useCdkMajor();\n const cdkType = useCdkType();\n const sort = useSort();\n const tags = useTags();\n\n const { page, pageLimit, results } = useCatalogResults({\n offset,\n limit: LIMIT,\n query,\n keywords,\n languages,\n cdkMajor,\n cdkType,\n sort,\n tags,\n });\n\n // Resets the page number to 1 if query param offset is below 0, or to the last page if offset is higher than page count\n useEffect(() => {\n // If the query has results but the page has nothing to show...\n if (results.length && (offset < 0 || offset > pageLimit)) {\n // Handle an out of bounds offset\n if (offset < 0) {\n updateSearch({ offset: 0 });\n } else {\n // Offset is too large, just take last page\n updateSearch({ offset: pageLimit });\n }\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [results, offset, pageLimit]);\n\n // Scroll to top on page change\n useEffect(() => {\n window.scrollTo(0, 0);\n }, [page]);\n\n return (\n <Page\n meta={{\n title: query || \"Search\",\n description: query\n ? `${results.length} results for ${query} at Construct Hub`\n : \"Search reusable components for your cloud application\",\n }}\n pageName=\"search\"\n >\n <Stack direction=\"column\" maxW=\"100vw\" pb={4} px={4} spacing={4}>\n <SearchBar />\n\n <Stack\n align={{ base: \"start\", lg: \"center\" }}\n direction={{ base: \"column-reverse\", lg: \"row\" }}\n justify={{ base: \"initial\", lg: \"space-between\" }}\n spacing={4}\n >\n <SearchDetails\n count={results.length}\n filtered={!!query}\n limit={LIMIT}\n offset={offset}\n query={query}\n />\n\n <Box display={{ base: \"none\", md: \"initial\" }}>\n <SortedBy />\n </Box>\n\n <Box display={{ md: \"none\" }}>\n <SortAndFilterDrawer />\n </Box>\n </Stack>\n\n <PackageList data-event={SEARCH_ANALYTICS.RESULTS} items={page} />\n\n <Box w=\"full\">\n <PageControls offset={offset} pageLimit={pageLimit} />\n </Box>\n </Stack>\n </Page>\n );\n};\n","import { Grid } from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\nimport { Page } from \"../../components/Page\";\nimport { FilterPanel } from \"./FilterPanel\";\nimport { SearchResults } from \"./SearchResults\";\nimport testIds from \"./testIds\";\n\nexport const Search: FunctionComponent = () => {\n return (\n <Page\n meta={{\n title: \"Search - Construct Hub\",\n description: \"Search Construct Libraries for AWS CDK, CDK8s, and CDKtf\",\n }}\n pageName=\"search\"\n >\n <Grid\n data-testid={testIds.page}\n gap={4}\n h=\"full\"\n maxW=\"100%\"\n px={{ base: 0, md: 6 }}\n py={6}\n templateColumns={{ base: \"1fr\", md: \"auto 1fr\" }}\n templateRows=\"1fr\"\n >\n {/* Filter Panel Desktop */}\n <FilterPanel />\n\n {/* Results, Info, and Controls */}\n <SearchResults />\n </Grid>\n </Page>\n );\n};\n"],"names":["SORT_RENDER_MAP","CatalogSearchSort","searchEvent","e","eventName","SEARCH_ANALYTICS","FILTERS","RESULTS","SEARCH","SORT","FilterHeading","name","hint","placement","useBreakpointValue","base","md","align","mb","as","size","w","colorScheme","strategy","ml","h","bg","borderRadius","color","fontSize","mx","shadow","createTestIds","RadioFilter","dataTestid","checkedValue","value","onValueChange","options","spacing","onChange","map","display","dataEvent","testIds","filterItem","isTruncated","toNum","val","result","parseInt","parseQueryArray","queryString","decodeURIComponent","split","getParamFromUrl","key","window","URL","location","href","searchParams","get","useSearchParam","transform","qp","useQueryParams","useMemo","useCdkType","QUERY_PARAMS","undefined","useCdkMajor","p","useKeywords","useLanguages","useSearchQuery","useSort","useTags","useUpdateSearchParam","push","useHistory","useCallback","offset","params","getSearchPath","query","keywords","cdkType","cdkMajor","cdkMajorParam","languages","sort","tags","getSearchUrlParams","CDKFilter","updateSearch","searchAPI","useSearchContext","cdkOptions","cdkTypes","constructFrameworks","Object","entries","reduce","opts","meta","pkgCount","CDKTYPE_NAME_MAP","keys","length","majorsOptions","majorVersions","a","b","toString","cdkTypeFilter","type","values","cdkVersionFilter","major","majorNum","CheckboxItem","isDisabled","disabledHint","isChecked","hasArrow","label","CheckboxFilter","initialItemCount","checkedValues","collapse","useDisclosure","trackCustomEvent","useAnalytics","getOnChange","item","clickEvent","alwaysShow","showWhenExpanded","slice","isExpandible","direction","mt","includes","animateOpacity","in","isOpen","unmountOnExit","fontWeight","leftIcon","onClick","onToggle","textAlign","variant","KeywordsFilter","keywordMap","keywordOptions","baseOptions","filter","keyword","keywordsNotInOptions","k","some","opt","languagesFilter","languageOptions","LANGUAGE_NAME_MAP","TEMP_SUPPORTED_LANGUAGES","l1","l2","LanguageFilter","lang","language","l","TagFilter","packageTags","useConfigValue","packageTagGroups","tagFilterGroups","tagGroupsMap","Map","forEach","group","set","id","accum","tag","groupIdOrName","searchFilter","groupBy","customGroup","entry","mapTagsToFilterGroups","Boolean","onTagsChange","t","getOnRadioTagChange","groupName","groupTags","Set","filteredTags","has","filterType","tooltip","tagItems","sharedProps","find","TOP_OFFSET","FilterPanel","Card","filtersPanel","maxH","maxW","minW","overflow","pos","top","zIndex","listViews","PackageCardType","items","pkg","PackageCard","version","PackageList","memo","cardView","loading","View","displayName","ArrowButton","Icon","icon","props","borderColor","disabled","GoToPage","pageLimit","useState","inputValue","setInputValue","useEffect","onSubmit","preventDefault","max","min","target","onFocus","PageControls","goForward","goBack","justify","prevPage","ChevronLeftIcon","goToPage","nextPage","ChevronRightIcon","SearchBar","setValue","Em","children","Count","first","count","last","SearchDetails","limit","filtered","hasResults","searchDetails","SortFilter","newSort","SortAndFilterDrawer","drawer","onOpen","rightIcon","borderBottom","pb","SortedBy","selected","Button","sortButton","pl","pr","py","sortDropdown","sortItem","SearchResults","o","useCatalogResults","page","results","scrollTo","Page","title","description","pageName","px","lg","Search","gap","templateColumns","templateRows"],"sourceRoot":""}
|