{ "version": 3, "sources": ["../../src/modern/hocs/ProjectSearchResults.js"], "sourcesContent": ["import React from 'react'\nimport PropTypes from 'prop-types'\nimport qs from 'qs'\n\nimport { t } from '@ulule/localize'\n\n// TODO: This should eventually be put in common\nimport { fetchSearchProjects, fetchSearchMoreProjects } from '$features/discover/services'\n\nconst DEFAULT_SORTING = 'popular'\nconst DEFAULT_OFFSET = 0\n\nexport const DEFAULT_LIMIT = 60\n\nconst SEARCH_API_FILTERS = {\n categories: {\n defaultValue: 'all',\n qualifier: 'tag_id',\n valueAttribute: 'id'\n },\n channels: {\n defaultValue: 'all',\n qualifier: 'channel_ids',\n valueAttribute: 'id'\n },\n cities: {\n defaultValue: 'all',\n qualifier: 'city_id',\n valueAttribute: 'id'\n },\n countries: {\n defaultValue: 'all',\n qualifier: 'country',\n valueAttribute: 'value'\n },\n languages: {\n defaultValue: 'all',\n qualifier: 'lang',\n valueAttribute: 'value'\n },\n statuses: {\n defaultValue: 'all',\n qualifier: 'status',\n valueAttribute: 'value'\n },\n regions: {\n defaultValue: 'all',\n qualifier: 'region_id',\n valueAttribute: 'id'\n },\n quality_score__not: {\n defaultValue: '',\n qualifier: 'quality_score__not',\n valueAttribute: 'value'\n }\n}\n\nconst getDisplayName = WrappedComponent => WrappedComponent.displayName || WrappedComponent.name || 'Component'\n\nexport const withProjectResults = WrappedComponent => {\n class ProjectSearchResults extends React.Component {\n constructor(props) {\n super(props)\n\n const { excludeXRatedProjects, initialSettings, limit } = props\n\n const { sorting, ...filtersFromQueryString } = window.location && this.parseQueryString(window.location.search)\n const sortingFromQueryString = sorting && sorting.length > 0 && sorting[sorting.length - 1]\n\n this.state = {\n currentFilters: {\n ...(excludeXRatedProjects && { quality_score__not: ['X'] }),\n ...initialSettings.filters,\n ...filtersFromQueryString\n },\n currentSorting: sortingFromQueryString || initialSettings.sorting || DEFAULT_SORTING,\n error: null,\n errorFetchingMore: false,\n isFetching: true,\n isFetchingMore: false,\n meta: {\n totalCount: 0,\n next: null,\n offset: DEFAULT_OFFSET,\n limit\n },\n results: []\n }\n }\n\n componentDidMount() {\n this.requestResults()\n }\n\n componentDidUpdate(prevProps, prevState) {\n // Fetch projects each time filters or sorting is updating\n // TODO: add deeper comparison to be more performant\n const { currentFilters, currentSorting } = this.state\n\n if (prevState.currentFilters !== currentFilters || prevState.currentSorting !== currentSorting) {\n this.requestResults()\n }\n }\n\n parseQualifiers = () => {\n const { currentFilters, currentSorting } = this.state\n\n const input = {\n sort: currentSorting\n }\n\n Object.keys(currentFilters).forEach(key => {\n const defaultValue = SEARCH_API_FILTERS && SEARCH_API_FILTERS[key] && SEARCH_API_FILTERS[key].defaultValue\n\n if (\n defaultValue &&\n currentFilters[key] &&\n currentFilters[key].length > 0 &&\n currentFilters[key][0] !== defaultValue\n ) {\n const qualifier = SEARCH_API_FILTERS && SEARCH_API_FILTERS[key] && SEARCH_API_FILTERS[key].qualifier\n input[qualifier] = currentFilters[key]\n }\n })\n\n return input\n }\n\n handleCloseError = event => {\n event.preventDefault()\n\n this.setState({ error: null })\n }\n\n handleFetchingError = (error, isFetchingMore = false) => {\n const errorProps = {\n level: 'alert',\n message: t(\n 'Oops... an error occured. Please refresh the page to retry. If the error persists, please contact support.'\n ),\n ...error\n }\n\n this.setState({\n ...this.oldState,\n isFetching: false,\n isFetchingMore: false,\n error: errorProps,\n errorFetchingMore: isFetchingMore\n })\n }\n\n handleFetchingPending = (isFetchingMore = false) => {\n const { results } = this.state\n\n // Save the old state in case of error\n this.oldState = this.state\n\n this.setState({\n results: isFetchingMore ? results : [],\n isFetching: !isFetchingMore,\n isFetchingMore\n })\n }\n\n handleFetchingSuccess = (results, meta) => {\n this.setState({\n isFetching: false,\n isFetchingMore: false,\n results: results || [],\n meta: {\n ...meta,\n totalCount: meta.total_count\n }\n })\n }\n\n handleLoadMore = event => {\n event.preventDefault()\n\n this.requestMoreResults()\n }\n\n parseQueryString = queryParams => {\n const parameters = qs.parse(queryParams, { ignoreQueryPrefix: true })\n const normalizedParamaters = {}\n\n Object.keys(parameters).forEach(key => {\n if (Array.isArray(parameters[key])) {\n normalizedParamaters[key] = parameters[key]\n } else {\n normalizedParamaters[key] = [parameters[key]]\n }\n })\n\n return normalizedParamaters\n }\n\n setQueryParam = (name, value, reset = false) => {\n const currentQueryParams = reset ? '' : window.location.search\n\n // Parse current query params in location\n // and add new query param\n const parsed = qs.parse(currentQueryParams, { ignoreQueryPrefix: true })\n parsed[name] = value\n\n // Stringify all new query params\n const stringified = qs.stringify(parsed)\n\n // Replace current URL in history\n const character = stringified.length > 0 ? '?' : ''\n window.history.replaceState(null, null, `${window.location.pathname}${character}${stringified}`)\n }\n\n requestMoreResults = async () => {\n this.handleFetchingPending(true)\n\n const { meta, results } = this.state\n\n try {\n const { userIsAuthenticated } = this.props\n const response = await fetchSearchMoreProjects(meta.next, userIsAuthenticated)\n const allResults = [...results, ...response.projects]\n\n this.handleFetchingSuccess(allResults, response.meta)\n } catch (error) {\n console.log(error)\n this.handleFetchingError(error, true)\n }\n }\n\n requestResults = async () => {\n this.handleFetchingPending(false)\n\n const { meta } = this.state\n\n try {\n const { currentLanguage, userIsAuthenticated } = this.props\n const qualifiers = this.parseQualifiers()\n const params = { lang: currentLanguage, limit: meta.limit }\n\n const response = await fetchSearchProjects(null, qualifiers, params, userIsAuthenticated)\n\n this.handleFetchingSuccess(response.projects, response.meta)\n } catch (error) {\n this.handleFetchingError(error)\n }\n }\n\n updateFilter = (filterName, optionValue) => {\n const { limit } = this.props\n const { currentFilters } = this.state\n\n this.setState({\n currentFilters: {\n ...currentFilters,\n [filterName]: [optionValue]\n },\n meta: {\n offset: DEFAULT_OFFSET,\n limit,\n totalCount: 0,\n next: null,\n previous: null\n }\n })\n\n this.setQueryParam(filterName, optionValue)\n }\n\n updateSorting = ({ value }) => {\n this.setState({ currentSorting: value })\n this.setQueryParam('sorting', value)\n }\n\n render() {\n const {\n currentFilters,\n currentSorting,\n errorFetchingMore,\n isFetching,\n isFetchingMore,\n meta,\n results\n } = this.state\n const { initialSettings } = this.props\n\n const currentStatus = currentFilters.statuses.length > 0 && currentFilters.statuses[0]\n const initialStatus = initialSettings.filters && initialSettings.filters.statuses[0]\n const projectCount = meta && meta.total_count\n\n const noProjectWithInitialParams = !isFetching && !projectCount && currentStatus === initialStatus\n\n return (\n <WrappedComponent\n {...this.props}\n currentFilters={currentFilters}\n currentSorting={currentSorting}\n errorFetchingMore={errorFetchingMore}\n isFetching={isFetching}\n isFetchingMore={isFetchingMore}\n loadMoreProjects={this.handleLoadMore}\n noProjectWithInitialParams={noProjectWithInitialParams}\n moreProjectsToFetch={meta && meta.next}\n projectCount={projectCount}\n results={results}\n updateFilter={this.updateFilter}\n updateSorting={this.updateSorting}\n />\n )\n }\n }\n\n ProjectSearchResults.defaultProps = {\n excludeXRatedProjects: false,\n initialSettings: {},\n limit: DEFAULT_LIMIT,\n userIsAuthenticated: false\n }\n\n ProjectSearchResults.displayName = `WithSearchResults(${getDisplayName(WrappedComponent)})`\n\n ProjectSearchResults.propTypes = {\n currentLanguage: PropTypes.string.isRequired,\n excludeXRatedProjects: PropTypes.bool,\n initialSettings: PropTypes.shape({\n filters: PropTypes.objectOf(PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string])))\n .isRequired,\n sorting: PropTypes.string\n }),\n userIsAuthenticated: PropTypes.bool,\n limit: PropTypes.number\n }\n return ProjectSearchResults\n}\n"], "mappings": "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", "names": ["init_define_process_env", "init_sentry_release_injection_stub", "import_react", "import_prop_types", "import_qs", "import_localize", "DEFAULT_SORTING", "DEFAULT_OFFSET", "DEFAULT_LIMIT", "SEARCH_API_FILTERS", "getDisplayName", "WrappedComponent", "withProjectResults", "ProjectSearchResults", "React", "props", "__publicField", "currentFilters", "currentSorting", "input", "key", "defaultValue", "qualifier", "event", "error", "isFetchingMore", "errorProps", "__spreadValues", "__spreadProps", "results", "meta", "queryParams", "parameters", "qs", "normalizedParamaters", "name", "value", "reset", "currentQueryParams", "parsed", "stringified", "character", "userIsAuthenticated", "response", "fetchSearchMoreProjects", "allResults", "currentLanguage", "qualifiers", "params", "fetchSearchProjects", "filterName", "optionValue", "limit", "excludeXRatedProjects", "initialSettings", "_a", "sorting", "filtersFromQueryString", "__objRest", "sortingFromQueryString", "prevProps", "prevState", "errorFetchingMore", "isFetching", "currentStatus", "initialStatus", "projectCount", "noProjectWithInitialParams", "PropTypes"] }