{"version":3,"file":"18323.a5f9f17a06367fec6c61.index.js","mappings":"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","sources":["webpack://richie-education/./js/common/searchFields/getSuggestionsSection.ts","webpack://richie-education/./js/common/searchFields/index.tsx","webpack://richie-education/./js/types/Suggestion.ts","webpack://richie-education/./js/components/RootSearchSuggestField/index.tsx","webpack://richie-education/./js/components/SearchInput/index.tsx","webpack://richie-education/./js/data/useStaticFilters/index.tsx"],"sourcesContent":["import take from 'lodash-es/take';\nimport { stringify } from 'query-string';\n\nimport { Suggestion } from 'types/Suggestion';\nimport { handle } from 'utils/errors/handle';\n\n/**\n * Build a suggestion section from a model name and a title, requesting the relevant\n * values to populate it from the API\n * @param kind The kind of suggestion we're issuing the completion request for. Determines the API\n * endpoint we're sending the request to.\n * @param sectionTitleMessage MessageDescriptor for the title of the section that displays the suggestions.\n * @param query The actual payload to run the completion search with.\n */\nexport const getSuggestionsSection = async (kind: string, title: string, query: string) => {\n // Run the search for the section on the API\n let response: Response;\n try {\n response = await fetch(`/api/v1.0/${kind}/autocomplete/?${stringify({ query })}`, {\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n } catch (error) {\n return handle(error);\n }\n\n // Fetch treats remote errors (400, 404, 503...) as successes\n // The ok flag is the way to discriminate\n if (!response.ok) {\n const error = new Error(`Failed to get list from ${kind} autocomplete : ${response.status}`);\n return response.status === 400 ? handle(error, await response.json()) : handle(error);\n }\n\n let responseData: Suggestion[];\n try {\n responseData = await response.json();\n } catch (error) {\n return handle(new Error('Failed to decode JSON in getSuggestionSection ' + error));\n }\n\n return {\n kind,\n title,\n values: take(responseData, 3),\n };\n};\n","import React from 'react';\nimport debounce from 'lodash-es/debounce';\n\nimport { StaticFilterDefinitions } from 'types/filters';\nimport {\n SearchAutosuggestProps,\n SearchSuggestion,\n SearchSuggestionSection,\n} from 'types/Suggestion';\nimport { handle } from 'utils/errors/handle';\nimport { getSuggestionsSection } from './getSuggestionsSection';\n\n/**\n * `react-autosuggest` callback to get a human string value from a Suggestion object.\n * @param suggestion The relevant suggestion object.\n */\nexport const getSuggestionValue: SearchAutosuggestProps['getSuggestionValue'] = (suggestion) =>\n suggestion.title;\n\n/**\n * `react-autosuggest` callback to render one suggestion.\n * @param suggestion Either a resource suggestion with a model name & a machine name, or the default\n * suggestion with some text to render.\n */\nexport const renderSuggestion: SearchAutosuggestProps['renderSuggestion'] = (suggestion) => (\n {suggestion.title}\n);\n\n/**\n * `react-autosuggest` callback to build up the list of suggestions and sections whenever user\n * interaction requires us to create or update that list.\n * @param filters The general filters object as returned by the API on a course search.\n * @param setSuggestions The suggestion setter method for the component using our helper.\n * @param incomingValue The current value of the search suggest form field.\n */\nconst onSuggestionsFetchRequested = async (\n filters: StaticFilterDefinitions,\n setSuggestions: (suggestions: SearchSuggestionSection[]) => void,\n incomingValue: string,\n) => {\n if (incomingValue.length < 3) {\n return setSuggestions([]);\n }\n\n // Fetch the suggestions for each resource-based section to build out the sections\n let sections: SearchSuggestionSection[];\n try {\n sections = (await Promise.all(\n Object.values(await filters)\n .filter((filterdef) => filterdef.is_autocompletable)\n .map((filterdef) =>\n getSuggestionsSection(filterdef.name, filterdef.human_name, incomingValue),\n ),\n // We can assert this because of the catch below\n )) as SearchSuggestionSection[];\n } catch (error) {\n return handle(error);\n }\n\n setSuggestions(\n // Drop sections with no results as there's no use displaying them\n sections.filter((section) => !!section!.values.length),\n );\n};\n\nexport const onSuggestionsFetchRequestedDebounced = debounce(onSuggestionsFetchRequested, 200, {\n maxWait: 1000,\n});\n\n/**\n * Helper to pick out the relevant filter for a suggestion from the general filters object.\n * @param filters The general filters object as returned by the API on a course search.\n * @param suggestion The suggestion with which we're doing some work (eg. the suggestion the user selected).\n */\nexport const getRelevantFilter = (\n filters: StaticFilterDefinitions,\n suggestion: SearchSuggestion,\n) => {\n // Use the `kind` field on the suggestion to pick the relevant filter to update.\n let filter = Object.values(filters).find((fltr) => fltr.name === suggestion.kind)!;\n\n // We need a special-case to handle categories until we refactor the API to separate endpoints between\n // kinds of categories\n if (!filter) {\n // Pick the filter to update based on the payload's path: it contains the relevant filter's page path\n // (for eg. a meta-category or the \"organizations\" root page)\n filter = Object.values(filters).find(\n (fltr) => !!fltr.base_path && String(suggestion.id).substr(2).startsWith(fltr.base_path),\n )!;\n }\n\n return filter;\n};\n","import { AutosuggestProps } from 'react-autosuggest';\n\n/**\n * A Default suggestion shape for cases where we need one.\n */\ninterface DefaultSuggestion {\n kind: 'default';\n title: string;\n}\n\n/**\n * A generic suggestion shape for autocomplete. Can be used for categories, organizations, persons, etc.\n */\ninterface GenericSuggestion {\n id: string;\n kind: string;\n title: string;\n}\n\n/**\n * Courses suggestions need their own type because they have the extra field `absolute_url`.\n */\ninterface CourseSuggestion extends GenericSuggestion {\n absolute_url: string;\n kind: 'courses';\n}\n\n/**\n * We also need a way to help TypeScript discriminate between CourseSuggestions and GenericSuggestions\n */\nexport function isCourseSuggestion(suggestion: Suggestion): suggestion is CourseSuggestion {\n return suggestion.kind === 'courses';\n}\n\n/**\n * Utility type that allows a consumer to easily define the kinds of suggestions it supports and\n * get proper typechecking around them.\n */\nexport type Suggestion = Kind extends 'default'\n ? DefaultSuggestion\n : Kind extends 'courses'\n ? CourseSuggestion\n : GenericSuggestion;\n\n/**\n * The base shape of a resource suggestion section. Contains a bunch of suggestions and a title.\n * Used by our `\u001creact-autosuggest` callbacks to display, build & generally use our suggestions.\n * @kind A name such as a filter or model name for this kind of suggestion section.\n * @title A translated string for the title of the section.\n * @values An array that contains all the Suggestion instances for this section.\n */\ninterface ResourceSuggestionSection> {\n kind: S['kind'];\n title: string;\n values: S[];\n}\n\n/**\n * The default suggestion section. The only reason this is a section is we cannot put sections and\n * suggestions directly in the same autosuggest. We can instead make a section with only one suggestion and\n * no title to effectively get a suggestion.\n * @kind Always `'default'` for the default suggestion.\n * @title Always `\u001cnull` for the default suggestion.\n * @value The default suggestion.\n */\ninterface DefaultSuggestionSection {\n kind: DefaultSuggestion['kind'];\n title: null;\n values: Suggestion<'default'>[];\n}\n\n/**\n * Utility type that allows a consumer to easily define the kinds of suggestion sections it supports and\n * get proper typechecking around them.\n */\nexport type SuggestionSection> = S extends DefaultSuggestion\n ? DefaultSuggestionSection\n : ResourceSuggestionSection;\n\n/**\n * Define the kind of suggestions our `` and `` components support.\n */\nexport type SearchSuggestion = Suggestion<'categories' | 'courses' | 'organizations' | 'persons'>;\n\n/**\n * Derive from `SearchSuggestion` the kind of suggestion sections our `` and\n * `` components support\n */\nexport type SearchSuggestionSection = SuggestionSection;\n\n/**\n * Helper to typecheck `react-autosuggest` expected props. Defines what is acceptable as a suggestion\n * throughout our code related to this instance of ``.\n */\nexport type SearchAutosuggestProps = AutosuggestProps;\n","import { stringify } from 'query-string';\nimport React, { useState } from 'react';\nimport Autosuggest from 'react-autosuggest';\nimport { defineMessages, useIntl } from 'react-intl';\n\nimport {\n getRelevantFilter,\n getSuggestionValue,\n onSuggestionsFetchRequestedDebounced,\n renderSuggestion,\n} from 'common/searchFields';\nimport { SearchInput } from 'components/SearchInput';\nimport { useStaticFilters } from 'data/useStaticFilters';\nimport { API_LIST_DEFAULT_PARAMS } from 'settings';\nimport { CommonDataProps } from 'types/commonDataProps';\nimport {\n isCourseSuggestion,\n SearchAutosuggestProps,\n SearchSuggestionSection,\n} from 'types/Suggestion';\nimport { location } from 'utils/indirection/window';\n\nconst messages = defineMessages({\n searchFieldPlaceholder: {\n defaultMessage: 'Search for courses',\n description: 'Placeholder text displayed in the search field when it is empty.',\n id: 'components.RootSearchSuggestField.searchFieldPlaceholder',\n },\n});\n\ninterface RootSearchSuggestFieldProps {\n courseSearchPageUrl: string;\n}\n\n/**\n * Component. Displays the main search field alon with any suggestions organized in relevant sections.\n * @param context General contextual app information as defined in common data props.\n * @param courseSearchPageUrl URL for the course search page. Where users are sent when they use filtering options.\n */\nconst RootSearchSuggestField = ({\n context,\n courseSearchPageUrl,\n}: RootSearchSuggestFieldProps & CommonDataProps) => {\n const intl = useIntl();\n\n // We need static filter definitions to act as config for our suggestion sections & requests.\n const getFilters = useStaticFilters(true);\n\n // Initialize hooks for the two pieces of state the controlled component needs to interact with:\n // the current list of suggestions and the input value.\n // Note: the input value is initialized from the courseSearchParams, ie. the `query` query string parameter\n const [value, setValue] = useState('');\n const [suggestions, setSuggestions] = useState([]);\n\n // Helper to know if the user is currently highlighting a suggestion. This is necessary to make sure we do not\n // override default `Autosuggest` behavior when we receive the ENTER keycode that triggers text search.\n const [hasHighlightedSuggestion, setHasHighlightedSuggestion] = useState(false);\n\n /**\n * Helper function; sends the user to the Search view with the current input value as full text search.\n */\n const moveToSearchViewWithQuery = () =>\n location.assign(\n `${courseSearchPageUrl}?${stringify({\n ...API_LIST_DEFAULT_PARAMS,\n query: value,\n })}`,\n );\n\n const inputProps: SearchAutosuggestProps['inputProps'] = {\n /**\n * Callback triggered on every user input.\n * @param _ Unused: change event.\n * @param params Incoming parameters related to the change event.\n * - `newValue` is the search suggest form field value.\n */\n onChange: (_, { newValue }) => {\n // Always update the state\n setValue(newValue);\n },\n onKeyDown: (event) => {\n // When ther user presses enter from the search field, move to the course search view with\n // whatever is currently in the field as a text query.\n // Unless they are currently highlighting a suggestion, in which case we let Autosuggest handle it.\n if (event.keyCode === 13 /* enter */ && !hasHighlightedSuggestion) {\n moveToSearchViewWithQuery();\n }\n },\n placeholder: intl.formatMessage(messages.searchFieldPlaceholder),\n value,\n };\n\n /**\n * `react-autosuggest` callback triggered when the user picks a suggestion, to handle the interaction.\n * Different interactions have different expected outcomes:\n * - picking a course directs to the course detailed page (as this is a course search);\n * - picking another resource suggestion adds that resource as a filter;\n * - the default suggestion runs a full-text search on the content of the search suggest form field.\n * @param _ Unused: selection event.\n * @param suggestion `suggestion` as key to an anonymous object: the suggestion the user picked.\n */\n const onSuggestionSelected: SearchAutosuggestProps['onSuggestionSelected'] = async (\n _,\n { suggestion },\n ) => {\n // Course suggestions are treated differently: when the user finds a course they're interested in,\n // we're just sending them to that's course page instead of the course search page.\n if (isCourseSuggestion(suggestion)) {\n return location.assign(suggestion.absolute_url);\n }\n\n // Get the relevant filter and move to the course search view with the selected suggestion as an\n // active filter value.\n const filter = getRelevantFilter(await getFilters(), suggestion);\n location.assign(\n `${courseSearchPageUrl}?${stringify({\n ...API_LIST_DEFAULT_PARAMS,\n [filter.name]: suggestion.id,\n })}`,\n );\n };\n\n return (\n // TypeScript incorrectly infers the type of the Autosuggest suggestions prop as SearchSuggestion, which\n // would be correct if we did not use sections, but is incorrect as it is.\n section.values}\n getSuggestionValue={getSuggestionValue}\n inputProps={inputProps}\n multiSection={true}\n onSuggestionsClearRequested={() => setSuggestions([])}\n onSuggestionsFetchRequested={async ({ value: incomingValue }) =>\n onSuggestionsFetchRequestedDebounced(await getFilters(), setSuggestions, incomingValue)\n }\n onSuggestionHighlighted={({ suggestion }) => setHasHighlightedSuggestion(!!suggestion)}\n onSuggestionSelected={onSuggestionSelected}\n renderInputComponent={(passthroughInputProps) => (\n \n )}\n renderSectionTitle={(section) => section.title}\n renderSuggestion={renderSuggestion}\n shouldRenderSuggestions={(val) => val.length > 2}\n suggestions={suggestions as any}\n />\n );\n};\n\nexport default RootSearchSuggestField;\n","import React from 'react';\nimport { defineMessages, FormattedMessage } from 'react-intl';\n\nimport { CommonDataProps } from 'types/commonDataProps';\n\nconst messages = defineMessages({\n button: {\n defaultMessage: 'Search',\n description: 'Accessibility text for the search button inside the Search input.',\n id: 'components.SearchInput.button',\n },\n});\n\n/**\n * Component. Search input to be used exclusively with `react-autosuggest` as it does not create necessary a11y\n * markup at all (as `` does that for us).\n * @param context General contextual app information as defined in common data props.\n * @param inputProps Mandatory passthrough for inputProps provided by ``.\n * @param onClick Handler to call when the user clicks on the search icon.\n */\nexport const SearchInput = ({\n inputProps, // just a passthrough from react-autosuggest to react-autosuggest\n onClick = () => {}, // by default, do nothing, this will just remove focus and close suggestions\n}: { inputProps: any; onClick?: () => void } & CommonDataProps) => (\n
\n \n \n
\n);\n","import { useRef, useState } from 'react';\n\nimport { FilterDefinition, StaticFilterDefinitions } from 'types/filters';\nimport { Nullable } from 'utils/types';\nimport { useAsyncEffect } from 'utils/useAsyncEffect';\n\n// Our search and autosuggestion pipeline operated based on filter definitions. Obviously, we can't filters\n// courses by courses, but we still need a filter-definition-like config to run courses autocompletion.\nconst coursesConfig: FilterDefinition = {\n base_path: null,\n human_name: 'Courses',\n is_autocompletable: true,\n is_searchable: true,\n name: 'courses',\n position: 99,\n};\n\n/**\n * Hook to provide static filter definitions to components as a promise while abstracting away\n * data-fetching & caching logic.\n * @param includeCoursesConfig Whether to include the courses filter-like configuration in the resulting definitions.\n * @returns A getter function that returns a promise which will be resolved with the static filter definitions.\n */\nexport const useStaticFilters = (includeCoursesConfig = false) => {\n const [needsFilters, setNeedsFilters] = useState(false);\n\n const filtersResolver = useRef void>>(null);\n const [filtersPromise] = useState>(\n () => new Promise((resolve) => (filtersResolver.current = resolve)),\n );\n\n useAsyncEffect(async () => {\n if (needsFilters) {\n const response = await fetch('/api/v1.0/filter-definitions/');\n if (!response.ok) {\n throw new Error('Failed to get filter definitions.');\n }\n\n const filters = await response.json();\n\n filtersResolver.current!({\n ...filters,\n ...(includeCoursesConfig ? { courses: coursesConfig } : {}),\n });\n }\n }, [needsFilters]);\n\n return () => {\n setNeedsFilters(true);\n return filtersPromise!;\n };\n};\n"],"names":["getSuggestionsSection","kind","title","query","fetch","stringify","headers","response","handle","ok","error","Error","status","json","responseData","values","take","getSuggestionValue","suggestion","renderSuggestion","onSuggestionsFetchRequested","filters","setSuggestions","incomingValue","length","Promise","Object","filter","filterdef","is_autocompletable","map","name","human_name","all","sections","section","onSuggestionsFetchRequestedDebounced","debounce","maxWait","getRelevantFilter","find","fltr","base_path","String","id","substr","startsWith","isCourseSuggestion","messages","defineMessages","searchFieldPlaceholder","context","courseSearchPageUrl","intl","useIntl","getFilters","useStaticFilters","useState","value","setValue","suggestions","hasHighlightedSuggestion","setHasHighlightedSuggestion","moveToSearchViewWithQuery","location","API_LIST_DEFAULT_PARAMS","inputProps","onChange","_","newValue","onKeyDown","event","keyCode","placeholder","formatMessage","onSuggestionSelected","absolute_url","getSectionSuggestions","multiSection","onSuggestionsClearRequested","onSuggestionHighlighted","renderInputComponent","passthroughInputProps","SearchInput","onClick","renderSectionTitle","shouldRenderSuggestions","val","button","className","role","xlinkHref","coursesConfig","is_searchable","position","includeCoursesConfig","needsFilters","setNeedsFilters","filtersResolver","useRef","resolve","current","filtersPromise","useAsyncEffect","courses"],"sourceRoot":""}