@backstage/plugin-search-react 1.8.7 → 1.8.8-next.1
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/CHANGELOG.md +30 -0
- package/dist/alpha/blueprints/SearchResultListItemBlueprint.esm.js +7 -6
- package/dist/alpha/blueprints/SearchResultListItemBlueprint.esm.js.map +1 -1
- package/dist/components/DefaultResultListItem/DefaultResultListItem.esm.js +42 -38
- package/dist/components/DefaultResultListItem/DefaultResultListItem.esm.js.map +1 -1
- package/dist/components/HighlightedSearchResultText/HighlightedSearchResultText.esm.js +5 -4
- package/dist/components/HighlightedSearchResultText/HighlightedSearchResultText.esm.js.map +1 -1
- package/dist/components/SearchAutocomplete/SearchAutocomplete.esm.js +7 -6
- package/dist/components/SearchAutocomplete/SearchAutocomplete.esm.js.map +1 -1
- package/dist/components/SearchAutocomplete/SearchAutocompleteDefaultOption.esm.js +14 -11
- package/dist/components/SearchAutocomplete/SearchAutocompleteDefaultOption.esm.js.map +1 -1
- package/dist/components/SearchBar/SearchBar.esm.js +23 -22
- package/dist/components/SearchBar/SearchBar.esm.js.map +1 -1
- package/dist/components/SearchFilter/SearchFilter.Autocomplete.esm.js +5 -4
- package/dist/components/SearchFilter/SearchFilter.Autocomplete.esm.js.map +1 -1
- package/dist/components/SearchFilter/SearchFilter.esm.js +45 -42
- package/dist/components/SearchFilter/SearchFilter.esm.js.map +1 -1
- package/dist/components/SearchPagination/SearchPagination.esm.js +4 -3
- package/dist/components/SearchPagination/SearchPagination.esm.js.map +1 -1
- package/dist/components/SearchResult/SearchResult.esm.js +12 -12
- package/dist/components/SearchResult/SearchResult.esm.js.map +1 -1
- package/dist/components/SearchResultGroup/SearchResultGroup.esm.js +99 -79
- package/dist/components/SearchResultGroup/SearchResultGroup.esm.js.map +1 -1
- package/dist/components/SearchResultList/SearchResultList.esm.js +22 -22
- package/dist/components/SearchResultList/SearchResultList.esm.js.map +1 -1
- package/dist/components/SearchResultPager/SearchResultPager.esm.js +24 -21
- package/dist/components/SearchResultPager/SearchResultPager.esm.js.map +1 -1
- package/dist/context/SearchContext.esm.js +7 -6
- package/dist/context/SearchContext.esm.js.map +1 -1
- package/dist/extensions.esm.js +23 -22
- package/dist/extensions.esm.js.map +1 -1
- package/dist/index.d.ts +39 -37
- package/package.json +16 -16
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useRef } from 'react';
|
|
2
3
|
import { capitalize } from 'lodash';
|
|
3
4
|
import { v4 } from 'uuid';
|
|
4
5
|
import FormControl from '@material-ui/core/FormControl';
|
|
@@ -57,37 +58,39 @@ const CheckboxFilter = (props) => {
|
|
|
57
58
|
return items.length ? { ...others, [name]: items } : others;
|
|
58
59
|
});
|
|
59
60
|
};
|
|
60
|
-
return /* @__PURE__ */
|
|
61
|
+
return /* @__PURE__ */ jsxs(
|
|
61
62
|
FormControl,
|
|
62
63
|
{
|
|
63
64
|
className,
|
|
64
65
|
disabled: loading,
|
|
65
66
|
fullWidth: true,
|
|
66
|
-
"data-testid": "search-checkboxfilter-next"
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
{
|
|
72
|
-
key: value,
|
|
73
|
-
classes: {
|
|
74
|
-
root: classes.checkboxWrapper,
|
|
75
|
-
label: classes.textWrapper
|
|
76
|
-
},
|
|
77
|
-
label: value,
|
|
78
|
-
control: /* @__PURE__ */ React.createElement(
|
|
79
|
-
Checkbox,
|
|
67
|
+
"data-testid": "search-checkboxfilter-next",
|
|
68
|
+
children: [
|
|
69
|
+
label ? /* @__PURE__ */ jsx(FormLabel, { className: classes.label, children: label }) : null,
|
|
70
|
+
values.map((value) => /* @__PURE__ */ jsx(
|
|
71
|
+
FormControlLabel,
|
|
80
72
|
{
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
73
|
+
classes: {
|
|
74
|
+
root: classes.checkboxWrapper,
|
|
75
|
+
label: classes.textWrapper
|
|
76
|
+
},
|
|
77
|
+
label: value,
|
|
78
|
+
control: /* @__PURE__ */ jsx(
|
|
79
|
+
Checkbox,
|
|
80
|
+
{
|
|
81
|
+
color: "primary",
|
|
82
|
+
inputProps: { "aria-labelledby": value },
|
|
83
|
+
value,
|
|
84
|
+
name: value,
|
|
85
|
+
onChange: handleChange,
|
|
86
|
+
checked: (filters[name] ?? []).includes(value)
|
|
87
|
+
}
|
|
88
|
+
)
|
|
89
|
+
},
|
|
90
|
+
value
|
|
91
|
+
))
|
|
92
|
+
]
|
|
93
|
+
}
|
|
91
94
|
);
|
|
92
95
|
};
|
|
93
96
|
const SelectFilter = (props) => {
|
|
@@ -118,33 +121,33 @@ const SelectFilter = (props) => {
|
|
|
118
121
|
});
|
|
119
122
|
};
|
|
120
123
|
const items = [allOption, ...values.map((value) => ({ value, label: value }))];
|
|
121
|
-
return /* @__PURE__ */
|
|
124
|
+
return /* @__PURE__ */ jsx(
|
|
122
125
|
FormControl,
|
|
123
126
|
{
|
|
124
127
|
disabled: loading,
|
|
125
128
|
className,
|
|
126
129
|
variant: "filled",
|
|
127
130
|
fullWidth: true,
|
|
128
|
-
"data-testid": "search-selectfilter-next"
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
131
|
+
"data-testid": "search-selectfilter-next",
|
|
132
|
+
children: /* @__PURE__ */ jsx(
|
|
133
|
+
Select,
|
|
134
|
+
{
|
|
135
|
+
label: label ?? capitalize(name),
|
|
136
|
+
selected: filters[name] || allOptionValue.current,
|
|
137
|
+
onChange: handleChange,
|
|
138
|
+
items
|
|
139
|
+
}
|
|
140
|
+
)
|
|
141
|
+
}
|
|
139
142
|
);
|
|
140
143
|
};
|
|
141
144
|
const SearchFilter = (props) => {
|
|
142
145
|
const { component: Element, ...elementProps } = props;
|
|
143
|
-
return /* @__PURE__ */
|
|
146
|
+
return /* @__PURE__ */ jsx(Element, { ...elementProps });
|
|
144
147
|
};
|
|
145
|
-
SearchFilter.Checkbox = (props) => /* @__PURE__ */
|
|
146
|
-
SearchFilter.Select = (props) => /* @__PURE__ */
|
|
147
|
-
SearchFilter.Autocomplete = (props) => /* @__PURE__ */
|
|
148
|
+
SearchFilter.Checkbox = (props) => /* @__PURE__ */ jsx(SearchFilter, { ...props, component: CheckboxFilter });
|
|
149
|
+
SearchFilter.Select = (props) => /* @__PURE__ */ jsx(SearchFilter, { ...props, component: SelectFilter });
|
|
150
|
+
SearchFilter.Autocomplete = (props) => /* @__PURE__ */ jsx(SearchFilter, { ...props, component: AutocompleteFilter });
|
|
148
151
|
|
|
149
152
|
export { CheckboxFilter, SearchFilter, SelectFilter };
|
|
150
153
|
//# sourceMappingURL=SearchFilter.esm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchFilter.esm.js","sources":["../../../src/components/SearchFilter/SearchFilter.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { ReactElement, ChangeEvent, useRef } from 'react';\nimport { capitalize } from 'lodash';\nimport { v4 as uuid } from 'uuid';\nimport FormControl from '@material-ui/core/FormControl';\nimport FormControlLabel from '@material-ui/core/FormControlLabel';\nimport Checkbox from '@material-ui/core/Checkbox';\nimport FormLabel from '@material-ui/core/FormLabel';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { Select, SelectedItems } from '@backstage/core-components';\n\nimport { useSearch } from '../../context';\nimport {\n AutocompleteFilter,\n SearchAutocompleteFilterProps,\n} from './SearchFilter.Autocomplete';\nimport { useAsyncFilterValues, useDefaultFilterValue } from './hooks';\n\nconst useStyles = makeStyles({\n label: {\n textTransform: 'capitalize',\n },\n checkboxWrapper: {\n display: 'flex',\n alignItems: 'center',\n width: '100%',\n },\n textWrapper: {\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n});\n\n/**\n * @public\n */\nexport type SearchFilterComponentProps = {\n className?: string;\n name: string;\n label?: string;\n /**\n * Either an array of values directly, or an async function to return a list\n * of values to be used in the filter. In the autocomplete filter, the last\n * input value is provided as an input to allow values to be filtered. This\n * function is debounced and values cached.\n */\n values?: string[] | ((partial: string) => Promise<string[]>);\n defaultValue?: string[] | string | null;\n /**\n * Debounce time in milliseconds, used when values is an async callback.\n * Defaults to 250ms.\n */\n valuesDebounceMs?: number;\n};\n\n/**\n * @public\n */\nexport type SearchFilterWrapperProps = SearchFilterComponentProps & {\n component: (props: SearchFilterComponentProps) => ReactElement;\n debug?: boolean;\n};\n\n/**\n * @public\n */\nexport const CheckboxFilter = (props: SearchFilterComponentProps) => {\n const {\n className,\n defaultValue,\n label,\n name,\n values: givenValues = [],\n valuesDebounceMs,\n } = props;\n const classes = useStyles();\n const { filters, setFilters } = useSearch();\n useDefaultFilterValue(name, defaultValue);\n const asyncValues =\n typeof givenValues === 'function' ? givenValues : undefined;\n const defaultValues =\n typeof givenValues === 'function' ? undefined : givenValues;\n const { value: values = [], loading } = useAsyncFilterValues(\n asyncValues,\n '',\n defaultValues,\n valuesDebounceMs,\n );\n\n const handleChange = (e: ChangeEvent<HTMLInputElement>) => {\n const {\n target: { value, checked },\n } = e;\n\n setFilters(prevFilters => {\n const { [name]: filter, ...others } = prevFilters;\n const rest = ((filter as string[]) || []).filter(i => i !== value);\n const items = checked ? [...rest, value] : rest;\n return items.length ? { ...others, [name]: items } : others;\n });\n };\n\n return (\n <FormControl\n className={className}\n disabled={loading}\n fullWidth\n data-testid=\"search-checkboxfilter-next\"\n >\n {label ? <FormLabel className={classes.label}>{label}</FormLabel> : null}\n {values.map((value: string) => (\n <FormControlLabel\n key={value}\n classes={{\n root: classes.checkboxWrapper,\n label: classes.textWrapper,\n }}\n label={value}\n control={\n <Checkbox\n color=\"primary\"\n inputProps={{ 'aria-labelledby': value }}\n value={value}\n name={value}\n onChange={handleChange}\n checked={((filters[name] as string[]) ?? []).includes(value)}\n />\n }\n />\n ))}\n </FormControl>\n );\n};\n\n/**\n * @public\n */\nexport const SelectFilter = (props: SearchFilterComponentProps) => {\n const {\n className,\n defaultValue,\n label,\n name,\n values: givenValues,\n valuesDebounceMs,\n } = props;\n useDefaultFilterValue(name, defaultValue);\n const asyncValues =\n typeof givenValues === 'function' ? givenValues : undefined;\n const defaultValues =\n typeof givenValues === 'function' ? undefined : givenValues;\n const { value: values = [], loading } = useAsyncFilterValues(\n asyncValues,\n '',\n defaultValues,\n valuesDebounceMs,\n );\n const allOptionValue = useRef(uuid());\n const allOption = { value: allOptionValue.current, label: 'All' };\n const { filters, setFilters } = useSearch();\n\n const handleChange = (value: SelectedItems) => {\n setFilters(prevFilters => {\n const { [name]: filter, ...others } = prevFilters;\n return value !== allOptionValue.current\n ? { ...others, [name]: value as string }\n : others;\n });\n };\n\n const items = [allOption, ...values.map(value => ({ value, label: value }))];\n\n return (\n <FormControl\n disabled={loading}\n className={className}\n variant=\"filled\"\n fullWidth\n data-testid=\"search-selectfilter-next\"\n >\n <Select\n label={label ?? capitalize(name)}\n selected={(filters[name] || allOptionValue.current) as string}\n onChange={handleChange}\n items={items}\n />\n </FormControl>\n );\n};\n\n/**\n * @public\n */\nconst SearchFilter = (props: SearchFilterWrapperProps) => {\n const { component: Element, ...elementProps } = props;\n return <Element {...elementProps} />;\n};\n\nSearchFilter.Checkbox = (\n props: Omit<SearchFilterWrapperProps, 'component'> &\n SearchFilterComponentProps,\n) => <SearchFilter {...props} component={CheckboxFilter} />;\n\nSearchFilter.Select = (\n props: Omit<SearchFilterWrapperProps, 'component'> &\n SearchFilterComponentProps,\n) => <SearchFilter {...props} component={SelectFilter} />;\n\n/**\n * A control surface for a given filter field name, rendered as an autocomplete\n * textfield. A hard-coded list of values may be provided, or an async function\n * which returns values may be provided instead.\n *\n * @public\n */\nSearchFilter.Autocomplete = (props: SearchAutocompleteFilterProps) => (\n <SearchFilter {...props} component={AutocompleteFilter} />\n);\n\nexport { SearchFilter };\n"],"names":["uuid"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SearchFilter.esm.js","sources":["../../../src/components/SearchFilter/SearchFilter.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ReactElement, ChangeEvent, useRef } from 'react';\nimport { capitalize } from 'lodash';\nimport { v4 as uuid } from 'uuid';\nimport FormControl from '@material-ui/core/FormControl';\nimport FormControlLabel from '@material-ui/core/FormControlLabel';\nimport Checkbox from '@material-ui/core/Checkbox';\nimport FormLabel from '@material-ui/core/FormLabel';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { Select, SelectedItems } from '@backstage/core-components';\n\nimport { useSearch } from '../../context';\nimport {\n AutocompleteFilter,\n SearchAutocompleteFilterProps,\n} from './SearchFilter.Autocomplete';\nimport { useAsyncFilterValues, useDefaultFilterValue } from './hooks';\n\nconst useStyles = makeStyles({\n label: {\n textTransform: 'capitalize',\n },\n checkboxWrapper: {\n display: 'flex',\n alignItems: 'center',\n width: '100%',\n },\n textWrapper: {\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n});\n\n/**\n * @public\n */\nexport type SearchFilterComponentProps = {\n className?: string;\n name: string;\n label?: string;\n /**\n * Either an array of values directly, or an async function to return a list\n * of values to be used in the filter. In the autocomplete filter, the last\n * input value is provided as an input to allow values to be filtered. This\n * function is debounced and values cached.\n */\n values?: string[] | ((partial: string) => Promise<string[]>);\n defaultValue?: string[] | string | null;\n /**\n * Debounce time in milliseconds, used when values is an async callback.\n * Defaults to 250ms.\n */\n valuesDebounceMs?: number;\n};\n\n/**\n * @public\n */\nexport type SearchFilterWrapperProps = SearchFilterComponentProps & {\n component: (props: SearchFilterComponentProps) => ReactElement;\n debug?: boolean;\n};\n\n/**\n * @public\n */\nexport const CheckboxFilter = (props: SearchFilterComponentProps) => {\n const {\n className,\n defaultValue,\n label,\n name,\n values: givenValues = [],\n valuesDebounceMs,\n } = props;\n const classes = useStyles();\n const { filters, setFilters } = useSearch();\n useDefaultFilterValue(name, defaultValue);\n const asyncValues =\n typeof givenValues === 'function' ? givenValues : undefined;\n const defaultValues =\n typeof givenValues === 'function' ? undefined : givenValues;\n const { value: values = [], loading } = useAsyncFilterValues(\n asyncValues,\n '',\n defaultValues,\n valuesDebounceMs,\n );\n\n const handleChange = (e: ChangeEvent<HTMLInputElement>) => {\n const {\n target: { value, checked },\n } = e;\n\n setFilters(prevFilters => {\n const { [name]: filter, ...others } = prevFilters;\n const rest = ((filter as string[]) || []).filter(i => i !== value);\n const items = checked ? [...rest, value] : rest;\n return items.length ? { ...others, [name]: items } : others;\n });\n };\n\n return (\n <FormControl\n className={className}\n disabled={loading}\n fullWidth\n data-testid=\"search-checkboxfilter-next\"\n >\n {label ? <FormLabel className={classes.label}>{label}</FormLabel> : null}\n {values.map((value: string) => (\n <FormControlLabel\n key={value}\n classes={{\n root: classes.checkboxWrapper,\n label: classes.textWrapper,\n }}\n label={value}\n control={\n <Checkbox\n color=\"primary\"\n inputProps={{ 'aria-labelledby': value }}\n value={value}\n name={value}\n onChange={handleChange}\n checked={((filters[name] as string[]) ?? []).includes(value)}\n />\n }\n />\n ))}\n </FormControl>\n );\n};\n\n/**\n * @public\n */\nexport const SelectFilter = (props: SearchFilterComponentProps) => {\n const {\n className,\n defaultValue,\n label,\n name,\n values: givenValues,\n valuesDebounceMs,\n } = props;\n useDefaultFilterValue(name, defaultValue);\n const asyncValues =\n typeof givenValues === 'function' ? givenValues : undefined;\n const defaultValues =\n typeof givenValues === 'function' ? undefined : givenValues;\n const { value: values = [], loading } = useAsyncFilterValues(\n asyncValues,\n '',\n defaultValues,\n valuesDebounceMs,\n );\n const allOptionValue = useRef(uuid());\n const allOption = { value: allOptionValue.current, label: 'All' };\n const { filters, setFilters } = useSearch();\n\n const handleChange = (value: SelectedItems) => {\n setFilters(prevFilters => {\n const { [name]: filter, ...others } = prevFilters;\n return value !== allOptionValue.current\n ? { ...others, [name]: value as string }\n : others;\n });\n };\n\n const items = [allOption, ...values.map(value => ({ value, label: value }))];\n\n return (\n <FormControl\n disabled={loading}\n className={className}\n variant=\"filled\"\n fullWidth\n data-testid=\"search-selectfilter-next\"\n >\n <Select\n label={label ?? capitalize(name)}\n selected={(filters[name] || allOptionValue.current) as string}\n onChange={handleChange}\n items={items}\n />\n </FormControl>\n );\n};\n\n/**\n * @public\n */\nconst SearchFilter = (props: SearchFilterWrapperProps) => {\n const { component: Element, ...elementProps } = props;\n return <Element {...elementProps} />;\n};\n\nSearchFilter.Checkbox = (\n props: Omit<SearchFilterWrapperProps, 'component'> &\n SearchFilterComponentProps,\n) => <SearchFilter {...props} component={CheckboxFilter} />;\n\nSearchFilter.Select = (\n props: Omit<SearchFilterWrapperProps, 'component'> &\n SearchFilterComponentProps,\n) => <SearchFilter {...props} component={SelectFilter} />;\n\n/**\n * A control surface for a given filter field name, rendered as an autocomplete\n * textfield. A hard-coded list of values may be provided, or an async function\n * which returns values may be provided instead.\n *\n * @public\n */\nSearchFilter.Autocomplete = (props: SearchAutocompleteFilterProps) => (\n <SearchFilter {...props} component={AutocompleteFilter} />\n);\n\nexport { SearchFilter };\n"],"names":["uuid"],"mappings":";;;;;;;;;;;;;;AAiCA,MAAM,YAAY,UAAW,CAAA;AAAA,EAC3B,KAAO,EAAA;AAAA,IACL,aAAe,EAAA;AAAA,GACjB;AAAA,EACA,eAAiB,EAAA;AAAA,IACf,OAAS,EAAA,MAAA;AAAA,IACT,UAAY,EAAA,QAAA;AAAA,IACZ,KAAO,EAAA;AAAA,GACT;AAAA,EACA,WAAa,EAAA;AAAA,IACX,QAAU,EAAA,QAAA;AAAA,IACV,YAAc,EAAA,UAAA;AAAA,IACd,UAAY,EAAA;AAAA;AAEhB,CAAC,CAAA;AAmCY,MAAA,cAAA,GAAiB,CAAC,KAAsC,KAAA;AACnE,EAAM,MAAA;AAAA,IACJ,SAAA;AAAA,IACA,YAAA;AAAA,IACA,KAAA;AAAA,IACA,IAAA;AAAA,IACA,MAAA,EAAQ,cAAc,EAAC;AAAA,IACvB;AAAA,GACE,GAAA,KAAA;AACJ,EAAA,MAAM,UAAU,SAAU,EAAA;AAC1B,EAAA,MAAM,EAAE,OAAA,EAAS,UAAW,EAAA,GAAI,SAAU,EAAA;AAC1C,EAAA,qBAAA,CAAsB,MAAM,YAAY,CAAA;AACxC,EAAA,MAAM,WACJ,GAAA,OAAO,WAAgB,KAAA,UAAA,GAAa,WAAc,GAAA,KAAA,CAAA;AACpD,EAAA,MAAM,aACJ,GAAA,OAAO,WAAgB,KAAA,UAAA,GAAa,KAAY,CAAA,GAAA,WAAA;AAClD,EAAA,MAAM,EAAE,KAAO,EAAA,MAAA,GAAS,EAAC,EAAG,SAAY,GAAA,oBAAA;AAAA,IACtC,WAAA;AAAA,IACA,EAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAM,MAAA,YAAA,GAAe,CAAC,CAAqC,KAAA;AACzD,IAAM,MAAA;AAAA,MACJ,MAAA,EAAQ,EAAE,KAAA,EAAO,OAAQ;AAAA,KACvB,GAAA,CAAA;AAEJ,IAAA,UAAA,CAAW,CAAe,WAAA,KAAA;AACxB,MAAA,MAAM,EAAE,CAAC,IAAI,GAAG,MAAQ,EAAA,GAAG,QAAW,GAAA,WAAA;AACtC,MAAA,MAAM,QAAS,MAAuB,IAAA,IAAI,MAAO,CAAA,CAAA,CAAA,KAAK,MAAM,KAAK,CAAA;AACjE,MAAA,MAAM,QAAQ,OAAU,GAAA,CAAC,GAAG,IAAA,EAAM,KAAK,CAAI,GAAA,IAAA;AAC3C,MAAO,OAAA,KAAA,CAAM,SAAS,EAAE,GAAG,QAAQ,CAAC,IAAI,GAAG,KAAA,EAAU,GAAA,MAAA;AAAA,KACtD,CAAA;AAAA,GACH;AAEA,EACE,uBAAA,IAAA;AAAA,IAAC,WAAA;AAAA,IAAA;AAAA,MACC,SAAA;AAAA,MACA,QAAU,EAAA,OAAA;AAAA,MACV,SAAS,EAAA,IAAA;AAAA,MACT,aAAY,EAAA,4BAAA;AAAA,MAEX,QAAA,EAAA;AAAA,QAAA,KAAA,uBAAS,SAAU,EAAA,EAAA,SAAA,EAAW,OAAQ,CAAA,KAAA,EAAQ,iBAAM,CAAe,GAAA,IAAA;AAAA,QACnE,MAAA,CAAO,GAAI,CAAA,CAAC,KACX,qBAAA,GAAA;AAAA,UAAC,gBAAA;AAAA,UAAA;AAAA,YAEC,OAAS,EAAA;AAAA,cACP,MAAM,OAAQ,CAAA,eAAA;AAAA,cACd,OAAO,OAAQ,CAAA;AAAA,aACjB;AAAA,YACA,KAAO,EAAA,KAAA;AAAA,YACP,OACE,kBAAA,GAAA;AAAA,cAAC,QAAA;AAAA,cAAA;AAAA,gBACC,KAAM,EAAA,SAAA;AAAA,gBACN,UAAA,EAAY,EAAE,iBAAA,EAAmB,KAAM,EAAA;AAAA,gBACvC,KAAA;AAAA,gBACA,IAAM,EAAA,KAAA;AAAA,gBACN,QAAU,EAAA,YAAA;AAAA,gBACV,UAAW,OAAQ,CAAA,IAAI,KAAkB,EAAC,EAAG,SAAS,KAAK;AAAA;AAAA;AAC7D,WAAA;AAAA,UAdG;AAAA,SAiBR;AAAA;AAAA;AAAA,GACH;AAEJ;AAKa,MAAA,YAAA,GAAe,CAAC,KAAsC,KAAA;AACjE,EAAM,MAAA;AAAA,IACJ,SAAA;AAAA,IACA,YAAA;AAAA,IACA,KAAA;AAAA,IACA,IAAA;AAAA,IACA,MAAQ,EAAA,WAAA;AAAA,IACR;AAAA,GACE,GAAA,KAAA;AACJ,EAAA,qBAAA,CAAsB,MAAM,YAAY,CAAA;AACxC,EAAA,MAAM,WACJ,GAAA,OAAO,WAAgB,KAAA,UAAA,GAAa,WAAc,GAAA,KAAA,CAAA;AACpD,EAAA,MAAM,aACJ,GAAA,OAAO,WAAgB,KAAA,UAAA,GAAa,KAAY,CAAA,GAAA,WAAA;AAClD,EAAA,MAAM,EAAE,KAAO,EAAA,MAAA,GAAS,EAAC,EAAG,SAAY,GAAA,oBAAA;AAAA,IACtC,WAAA;AAAA,IACA,EAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACF;AACA,EAAM,MAAA,cAAA,GAAiB,MAAO,CAAAA,EAAA,EAAM,CAAA;AACpC,EAAA,MAAM,YAAY,EAAE,KAAA,EAAO,cAAe,CAAA,OAAA,EAAS,OAAO,KAAM,EAAA;AAChE,EAAA,MAAM,EAAE,OAAA,EAAS,UAAW,EAAA,GAAI,SAAU,EAAA;AAE1C,EAAM,MAAA,YAAA,GAAe,CAAC,KAAyB,KAAA;AAC7C,IAAA,UAAA,CAAW,CAAe,WAAA,KAAA;AACxB,MAAA,MAAM,EAAE,CAAC,IAAI,GAAG,MAAQ,EAAA,GAAG,QAAW,GAAA,WAAA;AACtC,MAAO,OAAA,KAAA,KAAU,cAAe,CAAA,OAAA,GAC5B,EAAE,GAAG,QAAQ,CAAC,IAAI,GAAG,KAAA,EACrB,GAAA,MAAA;AAAA,KACL,CAAA;AAAA,GACH;AAEA,EAAA,MAAM,KAAQ,GAAA,CAAC,SAAW,EAAA,GAAG,MAAO,CAAA,GAAA,CAAI,CAAU,KAAA,MAAA,EAAE,KAAO,EAAA,KAAA,EAAO,KAAM,EAAA,CAAE,CAAC,CAAA;AAE3E,EACE,uBAAA,GAAA;AAAA,IAAC,WAAA;AAAA,IAAA;AAAA,MACC,QAAU,EAAA,OAAA;AAAA,MACV,SAAA;AAAA,MACA,OAAQ,EAAA,QAAA;AAAA,MACR,SAAS,EAAA,IAAA;AAAA,MACT,aAAY,EAAA,0BAAA;AAAA,MAEZ,QAAA,kBAAA,GAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAO,KAAS,IAAA,UAAA,CAAW,IAAI,CAAA;AAAA,UAC/B,QAAW,EAAA,OAAA,CAAQ,IAAI,CAAA,IAAK,cAAe,CAAA,OAAA;AAAA,UAC3C,QAAU,EAAA,YAAA;AAAA,UACV;AAAA;AAAA;AACF;AAAA,GACF;AAEJ;AAKM,MAAA,YAAA,GAAe,CAAC,KAAoC,KAAA;AACxD,EAAA,MAAM,EAAE,SAAA,EAAW,OAAS,EAAA,GAAG,cAAiB,GAAA,KAAA;AAChD,EAAO,uBAAA,GAAA,CAAC,OAAS,EAAA,EAAA,GAAG,YAAc,EAAA,CAAA;AACpC;AAEA,YAAa,CAAA,QAAA,GAAW,CACtB,KAEG,qBAAA,GAAA,CAAC,gBAAc,GAAG,KAAA,EAAO,WAAW,cAAgB,EAAA,CAAA;AAEzD,YAAa,CAAA,MAAA,GAAS,CACpB,KAEG,qBAAA,GAAA,CAAC,gBAAc,GAAG,KAAA,EAAO,WAAW,YAAc,EAAA,CAAA;AASvD,YAAa,CAAA,YAAA,GAAe,CAAC,KAC3B,qBAAA,GAAA,CAAC,gBAAc,GAAG,KAAA,EAAO,WAAW,kBAAoB,EAAA,CAAA;;;;"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useMemo, useCallback } from 'react';
|
|
2
3
|
import TablePagination from '@material-ui/core/TablePagination';
|
|
3
4
|
import { useSearch } from '../../context/SearchContext.esm.js';
|
|
4
5
|
|
|
@@ -36,7 +37,7 @@ const SearchPaginationBase = (props) => {
|
|
|
36
37
|
},
|
|
37
38
|
[onPageLimitChange]
|
|
38
39
|
);
|
|
39
|
-
return /* @__PURE__ */
|
|
40
|
+
return /* @__PURE__ */ jsx(
|
|
40
41
|
TablePagination,
|
|
41
42
|
{
|
|
42
43
|
...rest,
|
|
@@ -64,7 +65,7 @@ const SearchPagination = (props) => {
|
|
|
64
65
|
},
|
|
65
66
|
[setPageLimit, setPageCursor]
|
|
66
67
|
);
|
|
67
|
-
return /* @__PURE__ */
|
|
68
|
+
return /* @__PURE__ */ jsx(
|
|
68
69
|
SearchPaginationBase,
|
|
69
70
|
{
|
|
70
71
|
...props,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchPagination.esm.js","sources":["../../../src/components/SearchPagination/SearchPagination.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport
|
|
1
|
+
{"version":3,"file":"SearchPagination.esm.js","sources":["../../../src/components/SearchPagination/SearchPagination.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n ReactNode,\n ChangeEvent,\n MouseEvent,\n useCallback,\n useMemo,\n} from 'react';\nimport TablePagination from '@material-ui/core/TablePagination';\nimport { useSearch } from '../../context';\n\nconst encodePageCursor = (pageCursor: number): string => {\n return Buffer.from(pageCursor.toString(), 'utf-8').toString('base64');\n};\n\nconst decodePageCursor = (pageCursor?: string): number => {\n if (!pageCursor) return 0;\n return Number(Buffer.from(pageCursor, 'base64').toString('utf-8'));\n};\n\n/**\n * A page limit option, this value must not be greater than 100.\n * @public\n */\nexport type SearchPaginationLimitOption<\n Current extends number = 101,\n Accumulator extends number[] = [],\n> = Accumulator['length'] extends Current\n ? Accumulator[number]\n : SearchPaginationLimitOption<\n Current,\n [...Accumulator, Accumulator['length']]\n >;\n\n/**\n * A page limit text, this function is called with a \"\\{ from, to, page, count \\}\" object.\n * @public\n */\nexport type SearchPaginationLimitText = (params: {\n from: number;\n to: number;\n page: number;\n count: number;\n}) => ReactNode;\n\n/**\n * Props for {@link SearchPaginationBase}.\n * @public\n */\nexport type SearchPaginationBaseProps = {\n /**\n * The component class name.\n */\n className?: string;\n /**\n * The total number of results.\n * For an unknown number of items, provide -1.\n * Defaults to -1.\n */\n total?: number;\n /**\n * The cursor for the current page.\n */\n cursor?: string;\n /**\n * Whether a next page exists\n */\n hasNextPage?: boolean;\n /**\n * Callback fired when the current page cursor is changed.\n */\n onCursorChange?: (pageCursor: string) => void;\n /**\n * The limit of results per page.\n * Set -1 to display all the results.\n */\n limit?: number;\n /**\n * Customize the results per page label.\n * Defaults to \"Results per page:\".\n */\n limitLabel?: ReactNode;\n /**\n * Customize the results per page text.\n * Defaults to \"(\\{ from, to, count \\}) =\\> count \\> 0 ? `of $\\{count\\}` : `$\\{from\\}-$\\{to\\}`\".\n */\n limitText?: SearchPaginationLimitText;\n /**\n * Options for setting how many results show per page.\n * If less than two options are available, no select field will be displayed.\n * Use -1 for the value with a custom label to show all the results.\n * Defaults to [10, 25, 50, 100].\n */\n limitOptions?: SearchPaginationLimitOption[];\n /**\n * Callback fired when the number of results per page is changed.\n */\n onLimitChange?: (value: number) => void;\n};\n\n/**\n * A component with controls for search results pagination.\n * @param props - See {@link SearchPaginationBaseProps}.\n * @public\n */\nexport const SearchPaginationBase = (props: SearchPaginationBaseProps) => {\n const {\n total: count = -1,\n cursor: pageCursor,\n hasNextPage,\n onCursorChange: onPageCursorChange,\n limit: rowsPerPage = 25,\n limitLabel: labelRowsPerPage = 'Results per page:',\n limitText: labelDisplayedRows = ({ from, to }) =>\n count > 0 ? `of ${count}` : `${from}-${to}`,\n limitOptions: rowsPerPageOptions,\n onLimitChange: onPageLimitChange,\n ...rest\n } = props;\n\n const page = useMemo(() => decodePageCursor(pageCursor), [pageCursor]);\n\n const handlePageChange = useCallback(\n (_: MouseEvent<HTMLButtonElement> | null, newValue: number) => {\n onPageCursorChange?.(encodePageCursor(newValue));\n },\n [onPageCursorChange],\n );\n\n const handleRowsPerPageChange = useCallback(\n (e: ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {\n const newValue = e.target.value;\n onPageLimitChange?.(parseInt(newValue, 10));\n },\n [onPageLimitChange],\n );\n\n return (\n <TablePagination\n {...rest}\n component=\"div\"\n count={count}\n page={page}\n nextIconButtonProps={{\n ...(hasNextPage !== undefined && { disabled: !hasNextPage }),\n }}\n onPageChange={handlePageChange}\n rowsPerPage={rowsPerPage}\n labelRowsPerPage={labelRowsPerPage}\n labelDisplayedRows={labelDisplayedRows}\n rowsPerPageOptions={rowsPerPageOptions}\n onRowsPerPageChange={handleRowsPerPageChange}\n />\n );\n};\n\n/**\n * Props for {@link SearchPagination}.\n * @public\n */\nexport type SearchPaginationProps = Omit<\n SearchPaginationBaseProps,\n | 'pageLimit'\n | 'onLimitChange'\n | 'pageCursor'\n | 'onPageCursorChange'\n | 'hasNextPage'\n>;\n\n/**\n * A component for setting the search context page limit and cursor.\n * @param props - See {@link SearchPaginationProps}.\n * @public\n */\nexport const SearchPagination = (props: SearchPaginationProps) => {\n const { pageLimit, setPageLimit, pageCursor, setPageCursor, fetchNextPage } =\n useSearch();\n\n const handlePageLimitChange = useCallback(\n (newPageLimit: number) => {\n setPageLimit(newPageLimit);\n setPageCursor(undefined);\n },\n [setPageLimit, setPageCursor],\n );\n\n return (\n <SearchPaginationBase\n {...props}\n hasNextPage={!!fetchNextPage}\n limit={pageLimit}\n onLimitChange={handlePageLimitChange}\n cursor={pageCursor}\n onCursorChange={setPageCursor}\n />\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
2
|
import useAsync from 'react-use/esm/useAsync';
|
|
3
3
|
import { isFunction } from 'lodash';
|
|
4
4
|
import { Progress, ResponseErrorPanel, EmptyState } from '@backstage/core-components';
|
|
@@ -24,21 +24,21 @@ const SearchResultApi = (props) => {
|
|
|
24
24
|
};
|
|
25
25
|
const SearchResultState = (props) => {
|
|
26
26
|
const { query, children } = props;
|
|
27
|
-
return query ? /* @__PURE__ */
|
|
27
|
+
return query ? /* @__PURE__ */ jsx(SearchResultApi, { query, children }) : /* @__PURE__ */ jsx(SearchResultContext, { children });
|
|
28
28
|
};
|
|
29
29
|
const SearchResultComponent = (props) => {
|
|
30
30
|
const {
|
|
31
31
|
query,
|
|
32
32
|
children,
|
|
33
|
-
noResultsComponent = /* @__PURE__ */
|
|
33
|
+
noResultsComponent = /* @__PURE__ */ jsx(EmptyState, { missing: "data", title: "Sorry, no results were found" }),
|
|
34
34
|
...rest
|
|
35
35
|
} = props;
|
|
36
|
-
return /* @__PURE__ */
|
|
36
|
+
return /* @__PURE__ */ jsx(SearchResultState, { query, children: ({ loading, error, value }) => {
|
|
37
37
|
if (loading) {
|
|
38
|
-
return /* @__PURE__ */
|
|
38
|
+
return /* @__PURE__ */ jsx(Progress, {});
|
|
39
39
|
}
|
|
40
40
|
if (error) {
|
|
41
|
-
return /* @__PURE__ */
|
|
41
|
+
return /* @__PURE__ */ jsx(
|
|
42
42
|
ResponseErrorPanel,
|
|
43
43
|
{
|
|
44
44
|
title: "Error encountered while fetching search results",
|
|
@@ -52,18 +52,18 @@ const SearchResultComponent = (props) => {
|
|
|
52
52
|
if (isFunction(children)) {
|
|
53
53
|
return children(value);
|
|
54
54
|
}
|
|
55
|
-
return /* @__PURE__ */
|
|
56
|
-
});
|
|
55
|
+
return /* @__PURE__ */ jsx(SearchResultListItemExtensions, { ...rest, results: value.results, children });
|
|
56
|
+
} });
|
|
57
57
|
};
|
|
58
|
-
const SearchResult = (props) => /* @__PURE__ */
|
|
58
|
+
const SearchResult = (props) => /* @__PURE__ */ jsx(
|
|
59
59
|
AnalyticsContext,
|
|
60
60
|
{
|
|
61
61
|
attributes: {
|
|
62
62
|
pluginId: "search",
|
|
63
63
|
extension: "SearchResult"
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
},
|
|
65
|
+
children: /* @__PURE__ */ jsx(SearchResultComponent, { ...props })
|
|
66
|
+
}
|
|
67
67
|
);
|
|
68
68
|
|
|
69
69
|
export { SearchResult, SearchResultApi, SearchResultComponent, SearchResultContext, SearchResultState };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchResult.esm.js","sources":["../../../src/components/SearchResult/SearchResult.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport
|
|
1
|
+
{"version":3,"file":"SearchResult.esm.js","sources":["../../../src/components/SearchResult/SearchResult.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ReactNode } from 'react';\nimport useAsync, { AsyncState } from 'react-use/esm/useAsync';\nimport { isFunction } from 'lodash';\n\nimport {\n Progress,\n EmptyState,\n ResponseErrorPanel,\n} from '@backstage/core-components';\nimport { useApi, AnalyticsContext } from '@backstage/core-plugin-api';\nimport { SearchQuery, SearchResultSet } from '@backstage/plugin-search-common';\n\nimport { searchApiRef } from '../../api';\nimport { useSearch } from '../../context';\nimport {\n SearchResultListItemExtensions,\n SearchResultListItemExtensionsProps,\n} from '../../extensions';\n\n/**\n * Props for {@link SearchResultContext}\n * @public\n */\nexport type SearchResultContextProps = {\n /**\n * A child function that receives an asynchronous result set and returns a react element.\n */\n children: (\n state: AsyncState<SearchResultSet>,\n query: Partial<SearchQuery>,\n ) => JSX.Element | null;\n};\n\n/**\n * Provides context-based results to a child function.\n * @param props - see {@link SearchResultContextProps}.\n * @example\n * ```\n * <SearchResultContext>\n * {({ loading, error, value }) => (\n * <List>\n * {value?.map(({ document }) => (\n * <DefaultSearchResultListItem\n * key={document.location}\n * result={document}\n * />\n * ))}\n * </List>\n * )}\n * </SearchResultContext>\n * ```\n * @public\n */\nexport const SearchResultContext = (props: SearchResultContextProps) => {\n const { children } = props;\n const context = useSearch();\n const { result: state, ...query } = context;\n return children(state, query);\n};\n\n/**\n * Props for {@link SearchResultApi}\n * @public\n */\nexport type SearchResultApiProps = SearchResultContextProps & {\n query: Partial<SearchQuery>;\n};\n\n/**\n * Request results through the search api and provide them to a child function.\n * @param props - see {@link SearchResultApiProps}.\n * @example\n * ```\n * <SearchResultApi>\n * {({ loading, error, value }) => (\n * <List>\n * {value?.map(({ document }) => (\n * <DefaultSearchResultListItem\n * key={document.location}\n * result={document}\n * />\n * ))}\n * </List>\n * )}\n * </SearchResultApi>\n * ```\n * @public\n */\nexport const SearchResultApi = (props: SearchResultApiProps) => {\n const { query, children } = props;\n const searchApi = useApi(searchApiRef);\n\n const state = useAsync(() => {\n const { term = '', types = [], filters = {}, ...rest } = query;\n return searchApi.query({ ...rest, term, types, filters });\n }, [query]);\n\n return children(state, query);\n};\n\n/**\n * Props for {@link SearchResultState}\n * @public\n */\nexport type SearchResultStateProps = SearchResultContextProps &\n Partial<SearchResultApiProps>;\n\n/**\n * Call a child render function passing a search state as an argument.\n * @remarks By default, results are taken from context, but when a \"query\" prop is set, results are requested from the search api.\n * @param props - see {@link SearchResultStateProps}.\n * @example\n * Consuming results from context:\n * ```\n * <SearchResultState>\n * {({ loading, error, value }) => (\n * <List>\n * {value?.map(({ document }) => (\n * <DefaultSearchResultListItem\n * key={document.location}\n * result={document}\n * />\n * ))}\n * </List>\n * )}\n * </SearchResultState>\n * ```\n * @example\n * Requesting results using the search api:\n * ```\n * <SearchResultState query={{ term: 'documentation' }}>\n * {({ loading, error, value }) => (\n * <List>\n * {value?.map(({ document }) => (\n * <DefaultSearchResultListItem\n * key={document.location}\n * result={document}\n * />\n * ))}\n * </List>\n * )}\n * </SearchResultState>\n * ```\n * @public\n */\nexport const SearchResultState = (props: SearchResultStateProps) => {\n const { query, children } = props;\n\n return query ? (\n <SearchResultApi query={query}>{children}</SearchResultApi>\n ) : (\n <SearchResultContext>{children}</SearchResultContext>\n );\n};\n\n/**\n * Props for {@link SearchResult}\n * @public\n */\nexport type SearchResultProps = Pick<SearchResultStateProps, 'query'> &\n Omit<SearchResultListItemExtensionsProps, 'results' | 'children'> & {\n children?: ReactNode | ((resultSet: SearchResultSet) => JSX.Element);\n noResultsComponent?: JSX.Element;\n };\n\n/**\n * Renders results from a parent search context or api.\n * @remarks default components for loading, error and empty variants are returned.\n * @param props - see {@link SearchResultProps}.\n * @public\n */\nexport const SearchResultComponent = (props: SearchResultProps) => {\n const {\n query,\n children,\n noResultsComponent = (\n <EmptyState missing=\"data\" title=\"Sorry, no results were found\" />\n ),\n ...rest\n } = props;\n\n return (\n <SearchResultState query={query}>\n {({ loading, error, value }) => {\n if (loading) {\n return <Progress />;\n }\n\n if (error) {\n return (\n <ResponseErrorPanel\n title=\"Error encountered while fetching search results\"\n error={error}\n />\n );\n }\n\n if (!value?.results.length) {\n return noResultsComponent;\n }\n\n if (isFunction(children)) {\n return children(value);\n }\n\n return (\n <SearchResultListItemExtensions {...rest} results={value.results}>\n {children}\n </SearchResultListItemExtensions>\n );\n }}\n </SearchResultState>\n );\n};\n\n/**\n * A component returning the search result from a parent search context or api.\n * @param props - see {@link SearchResultProps}.\n * @public\n */\nexport const SearchResult = (props: SearchResultProps) => (\n <AnalyticsContext\n attributes={{\n pluginId: 'search',\n extension: 'SearchResult',\n }}\n >\n <SearchResultComponent {...props} />\n </AnalyticsContext>\n);\n"],"names":[],"mappings":";;;;;;;;;AAqEa,MAAA,mBAAA,GAAsB,CAAC,KAAoC,KAAA;AACtE,EAAM,MAAA,EAAE,UAAa,GAAA,KAAA;AACrB,EAAA,MAAM,UAAU,SAAU,EAAA;AAC1B,EAAA,MAAM,EAAE,MAAA,EAAQ,KAAO,EAAA,GAAG,OAAU,GAAA,OAAA;AACpC,EAAO,OAAA,QAAA,CAAS,OAAO,KAAK,CAAA;AAC9B;AA8Ba,MAAA,eAAA,GAAkB,CAAC,KAAgC,KAAA;AAC9D,EAAM,MAAA,EAAE,KAAO,EAAA,QAAA,EAAa,GAAA,KAAA;AAC5B,EAAM,MAAA,SAAA,GAAY,OAAO,YAAY,CAAA;AAErC,EAAM,MAAA,KAAA,GAAQ,SAAS,MAAM;AAC3B,IAAM,MAAA,EAAE,IAAO,GAAA,EAAA,EAAI,KAAQ,GAAA,EAAI,EAAA,OAAA,GAAU,EAAC,EAAG,GAAG,IAAA,EAAS,GAAA,KAAA;AACzD,IAAO,OAAA,SAAA,CAAU,MAAM,EAAE,GAAG,MAAM,IAAM,EAAA,KAAA,EAAO,SAAS,CAAA;AAAA,GAC1D,EAAG,CAAC,KAAK,CAAC,CAAA;AAEV,EAAO,OAAA,QAAA,CAAS,OAAO,KAAK,CAAA;AAC9B;AA+Ca,MAAA,iBAAA,GAAoB,CAAC,KAAkC,KAAA;AAClE,EAAM,MAAA,EAAE,KAAO,EAAA,QAAA,EAAa,GAAA,KAAA;AAE5B,EAAO,OAAA,KAAA,uBACJ,eAAgB,EAAA,EAAA,KAAA,EAAe,UAAS,CAEzC,mBAAA,GAAA,CAAC,uBAAqB,QAAS,EAAA,CAAA;AAEnC;AAkBa,MAAA,qBAAA,GAAwB,CAAC,KAA6B,KAAA;AACjE,EAAM,MAAA;AAAA,IACJ,KAAA;AAAA,IACA,QAAA;AAAA,IACA,qCACG,GAAA,CAAA,UAAA,EAAA,EAAW,OAAQ,EAAA,MAAA,EAAO,OAAM,8BAA+B,EAAA,CAAA;AAAA,IAElE,GAAG;AAAA,GACD,GAAA,KAAA;AAEJ,EACE,uBAAA,GAAA,CAAC,qBAAkB,KAChB,EAAA,QAAA,EAAA,CAAC,EAAE,OAAS,EAAA,KAAA,EAAO,OAAY,KAAA;AAC9B,IAAA,IAAI,OAAS,EAAA;AACX,MAAA,2BAAQ,QAAS,EAAA,EAAA,CAAA;AAAA;AAGnB,IAAA,IAAI,KAAO,EAAA;AACT,MACE,uBAAA,GAAA;AAAA,QAAC,kBAAA;AAAA,QAAA;AAAA,UACC,KAAM,EAAA,iDAAA;AAAA,UACN;AAAA;AAAA,OACF;AAAA;AAIJ,IAAI,IAAA,CAAC,KAAO,EAAA,OAAA,CAAQ,MAAQ,EAAA;AAC1B,MAAO,OAAA,kBAAA;AAAA;AAGT,IAAI,IAAA,UAAA,CAAW,QAAQ,CAAG,EAAA;AACxB,MAAA,OAAO,SAAS,KAAK,CAAA;AAAA;AAGvB,IAAA,2BACG,8BAAgC,EAAA,EAAA,GAAG,MAAM,OAAS,EAAA,KAAA,CAAM,SACtD,QACH,EAAA,CAAA;AAAA,GAGN,EAAA,CAAA;AAEJ;AAOa,MAAA,YAAA,GAAe,CAAC,KAC3B,qBAAA,GAAA;AAAA,EAAC,gBAAA;AAAA,EAAA;AAAA,IACC,UAAY,EAAA;AAAA,MACV,QAAU,EAAA,QAAA;AAAA,MACV,SAAW,EAAA;AAAA,KACb;AAAA,IAEA,QAAA,kBAAA,GAAA,CAAC,qBAAuB,EAAA,EAAA,GAAG,KAAO,EAAA;AAAA;AACpC;;;;"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { useCallback, useState } from 'react';
|
|
2
3
|
import qs from 'qs';
|
|
3
4
|
import List from '@material-ui/core/List';
|
|
4
5
|
import ListSubheader from '@material-ui/core/ListSubheader';
|
|
@@ -48,13 +49,17 @@ const useStyles = makeStyles((theme) => ({
|
|
|
48
49
|
const SearchResultGroupFilterFieldLayout = (props) => {
|
|
49
50
|
const classes = useStyles();
|
|
50
51
|
const { label, children, ...rest } = props;
|
|
51
|
-
return /* @__PURE__ */
|
|
52
|
+
return /* @__PURE__ */ jsx(
|
|
52
53
|
Chip,
|
|
53
54
|
{
|
|
54
55
|
...rest,
|
|
55
56
|
className: classes.listSubheaderFilter,
|
|
56
57
|
variant: "outlined",
|
|
57
|
-
label: /* @__PURE__ */
|
|
58
|
+
label: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
59
|
+
label,
|
|
60
|
+
": ",
|
|
61
|
+
children
|
|
62
|
+
] })
|
|
58
63
|
}
|
|
59
64
|
);
|
|
60
65
|
};
|
|
@@ -84,7 +89,7 @@ const SearchResultGroupTextFilterField = (props) => {
|
|
|
84
89
|
},
|
|
85
90
|
[onChange]
|
|
86
91
|
);
|
|
87
|
-
return /* @__PURE__ */
|
|
92
|
+
return /* @__PURE__ */ jsx(SearchResultGroupFilterFieldLayout, { label, onDelete, children: /* @__PURE__ */ jsx(
|
|
88
93
|
Typography,
|
|
89
94
|
{
|
|
90
95
|
role: "textbox",
|
|
@@ -92,10 +97,10 @@ const SearchResultGroupTextFilterField = (props) => {
|
|
|
92
97
|
className: classes.root,
|
|
93
98
|
onChange: handleChange,
|
|
94
99
|
contentEditable: true,
|
|
95
|
-
suppressContentEditableWarning: true
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
));
|
|
100
|
+
suppressContentEditableWarning: true,
|
|
101
|
+
children: value?.toString()
|
|
102
|
+
}
|
|
103
|
+
) });
|
|
99
104
|
};
|
|
100
105
|
const useSearchResultGroupSelectFilterStyles = makeStyles((theme) => ({
|
|
101
106
|
root: {
|
|
@@ -124,18 +129,20 @@ const SearchResultGroupSelectFilterField = (props) => {
|
|
|
124
129
|
},
|
|
125
130
|
[onChange]
|
|
126
131
|
);
|
|
127
|
-
return /* @__PURE__ */
|
|
132
|
+
return /* @__PURE__ */ jsx(SearchResultGroupFilterFieldLayout, { label, onDelete, children: /* @__PURE__ */ jsxs(
|
|
128
133
|
Select,
|
|
129
134
|
{
|
|
130
135
|
className: classes.root,
|
|
131
136
|
value,
|
|
132
137
|
onChange: handleChange,
|
|
133
|
-
input: /* @__PURE__ */
|
|
134
|
-
IconComponent: NullIcon
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
138
|
+
input: /* @__PURE__ */ jsx(InputBase, {}),
|
|
139
|
+
IconComponent: NullIcon,
|
|
140
|
+
children: [
|
|
141
|
+
/* @__PURE__ */ jsx(MenuItem, { value: "none", children: "None" }),
|
|
142
|
+
children
|
|
143
|
+
]
|
|
144
|
+
}
|
|
145
|
+
) });
|
|
139
146
|
};
|
|
140
147
|
function SearchResultGroupLayout(props) {
|
|
141
148
|
const classes = useStyles();
|
|
@@ -146,22 +153,25 @@ function SearchResultGroupLayout(props) {
|
|
|
146
153
|
icon,
|
|
147
154
|
title,
|
|
148
155
|
titleProps = {},
|
|
149
|
-
link = /* @__PURE__ */
|
|
156
|
+
link = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
157
|
+
"See all",
|
|
158
|
+
/* @__PURE__ */ jsx(ArrowRightIcon, { className: classes.listSubheaderLinkIcon })
|
|
159
|
+
] }),
|
|
150
160
|
linkProps = {},
|
|
151
161
|
filterOptions,
|
|
152
|
-
renderFilterOption = (filterOption) => /* @__PURE__ */
|
|
162
|
+
renderFilterOption = (filterOption) => /* @__PURE__ */ jsx(MenuItem, { value: String(filterOption), children: String(filterOption) }, String(filterOption)),
|
|
153
163
|
filterFields,
|
|
154
164
|
renderFilterField,
|
|
155
165
|
resultItems,
|
|
156
|
-
renderResultItem = (resultItem) => /* @__PURE__ */
|
|
166
|
+
renderResultItem = (resultItem) => /* @__PURE__ */ jsx(
|
|
157
167
|
HigherOrderDefaultResultListItem,
|
|
158
168
|
{
|
|
159
|
-
key: resultItem.document.location,
|
|
160
169
|
result: resultItem.document
|
|
161
|
-
}
|
|
170
|
+
},
|
|
171
|
+
resultItem.document.location
|
|
162
172
|
),
|
|
163
173
|
disableRenderingWithNoResults,
|
|
164
|
-
noResultsComponent = disableRenderingWithNoResults ? null : /* @__PURE__ */
|
|
174
|
+
noResultsComponent = disableRenderingWithNoResults ? null : /* @__PURE__ */ jsx(EmptyState, { missing: "data", title: "Sorry, no results were found" }),
|
|
165
175
|
...rest
|
|
166
176
|
} = props;
|
|
167
177
|
const handleClick = useCallback((e) => {
|
|
@@ -171,10 +181,10 @@ function SearchResultGroupLayout(props) {
|
|
|
171
181
|
setAnchorEl(null);
|
|
172
182
|
}, []);
|
|
173
183
|
if (loading) {
|
|
174
|
-
return /* @__PURE__ */
|
|
184
|
+
return /* @__PURE__ */ jsx(Progress, {});
|
|
175
185
|
}
|
|
176
186
|
if (error) {
|
|
177
|
-
return /* @__PURE__ */
|
|
187
|
+
return /* @__PURE__ */ jsx(
|
|
178
188
|
ResponseErrorPanel,
|
|
179
189
|
{
|
|
180
190
|
title: "Error encountered while fetching search results",
|
|
@@ -183,72 +193,82 @@ function SearchResultGroupLayout(props) {
|
|
|
183
193
|
);
|
|
184
194
|
}
|
|
185
195
|
if (!resultItems?.length) {
|
|
186
|
-
return /* @__PURE__ */
|
|
196
|
+
return /* @__PURE__ */ jsx(Fragment, { children: noResultsComponent });
|
|
187
197
|
}
|
|
188
|
-
return /* @__PURE__ */
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
198
|
+
return /* @__PURE__ */ jsxs(List, { ...rest, children: [
|
|
199
|
+
/* @__PURE__ */ jsxs(ListSubheader, { className: classes.listSubheader, children: [
|
|
200
|
+
icon,
|
|
201
|
+
/* @__PURE__ */ jsx(
|
|
202
|
+
Typography,
|
|
203
|
+
{
|
|
204
|
+
className: classes.listSubheaderName,
|
|
205
|
+
component: "strong",
|
|
206
|
+
...titleProps,
|
|
207
|
+
children: title
|
|
208
|
+
}
|
|
209
|
+
),
|
|
210
|
+
filterOptions ? /* @__PURE__ */ jsx(
|
|
211
|
+
Chip,
|
|
212
|
+
{
|
|
213
|
+
className: classes.listSubheaderChip,
|
|
214
|
+
component: "button",
|
|
215
|
+
icon: /* @__PURE__ */ jsx(AddIcon, {}),
|
|
216
|
+
variant: "outlined",
|
|
217
|
+
label: "Add filter",
|
|
218
|
+
"aria-controls": "filters-menu",
|
|
219
|
+
"aria-haspopup": "true",
|
|
220
|
+
onClick: handleClick
|
|
221
|
+
}
|
|
222
|
+
) : null,
|
|
223
|
+
filterOptions ? /* @__PURE__ */ jsx(
|
|
224
|
+
Menu,
|
|
225
|
+
{
|
|
226
|
+
id: "filters-menu",
|
|
227
|
+
anchorEl,
|
|
228
|
+
open: Boolean(anchorEl),
|
|
229
|
+
onClose: handleClose,
|
|
230
|
+
onClick: handleClose,
|
|
231
|
+
keepMounted: true,
|
|
232
|
+
children: filterOptions.map(renderFilterOption)
|
|
233
|
+
}
|
|
234
|
+
) : null,
|
|
235
|
+
filterFields?.map(
|
|
236
|
+
(filterField) => renderFilterField?.(filterField) ?? null
|
|
237
|
+
),
|
|
238
|
+
/* @__PURE__ */ jsx(Link, { className: classes.listSubheaderLink, to: "/search", ...linkProps, children: link })
|
|
239
|
+
] }),
|
|
240
|
+
resultItems.map(renderResultItem)
|
|
241
|
+
] });
|
|
222
242
|
}
|
|
223
243
|
function SearchResultGroup(props) {
|
|
224
244
|
const { query, children, renderResultItem, linkProps = {}, ...rest } = props;
|
|
225
245
|
const defaultRenderResultItem = useSearchResultListItemExtensions(children);
|
|
226
|
-
return /* @__PURE__ */
|
|
246
|
+
return /* @__PURE__ */ jsx(
|
|
227
247
|
AnalyticsContext,
|
|
228
248
|
{
|
|
229
249
|
attributes: {
|
|
230
250
|
pluginId: "search",
|
|
231
251
|
extension: "SearchResultGroup"
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
)
|
|
251
|
-
}
|
|
252
|
+
},
|
|
253
|
+
children: /* @__PURE__ */ jsx(SearchResultState, { query, children: ({ loading, error, value }, { term, types, pageCursor, filters = {} }) => {
|
|
254
|
+
const to = `/search?${qs.stringify(
|
|
255
|
+
{ term, types, filters, pageCursor, query: term },
|
|
256
|
+
{ arrayFormat: "brackets" }
|
|
257
|
+
)}`;
|
|
258
|
+
return /* @__PURE__ */ jsx(
|
|
259
|
+
SearchResultGroupLayout,
|
|
260
|
+
{
|
|
261
|
+
...rest,
|
|
262
|
+
error,
|
|
263
|
+
loading,
|
|
264
|
+
linkProps: { to, ...linkProps },
|
|
265
|
+
filterFields: Object.keys(filters),
|
|
266
|
+
resultItems: value?.results,
|
|
267
|
+
renderResultItem: renderResultItem ?? defaultRenderResultItem
|
|
268
|
+
}
|
|
269
|
+
);
|
|
270
|
+
} })
|
|
271
|
+
}
|
|
252
272
|
);
|
|
253
273
|
}
|
|
254
274
|
|