@backstage/plugin-search-react 1.1.1-next.0 → 1.2.0-next.2

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 CHANGED
@@ -1,5 +1,103 @@
1
1
  # @backstage/plugin-search-react
2
2
 
3
+ ## 1.2.0-next.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+ - @backstage/plugin-search-common@1.1.0-next.2
9
+ - @backstage/core-components@0.11.2-next.2
10
+ - @backstage/core-plugin-api@1.0.7-next.2
11
+ - @backstage/theme@0.2.16
12
+ - @backstage/types@1.0.0
13
+ - @backstage/version-bridge@1.0.1
14
+
15
+ ## 1.2.0-next.1
16
+
17
+ ### Minor Changes
18
+
19
+ - 4ed1fa2480: The search query state now has an optional `pageLimit` property that determines how many results will be requested per page, it defaults to 25.
20
+
21
+ Examples:
22
+ _Basic_
23
+
24
+ ```jsx
25
+ <SearchResults query={{ pageLimit: 30 }}>
26
+ {results => {
27
+ // Item rendering logic is omitted
28
+ }}
29
+ </SearchResults>
30
+ ```
31
+
32
+ _With context_
33
+
34
+ ```jsx
35
+ <SearchContextProvider initialState={{ pageLimit: 30 }}>
36
+ <SearchResults>
37
+ {results => {
38
+ // Item rendering logic is omitted
39
+ }}
40
+ </SearchResults>
41
+ </SearchContextProvider>
42
+ ```
43
+
44
+ - bed5a1dc6e: The `<SearchResultList />` component now accepts an optional property `disableRenderingWithNoResults` to disable rendering when no results are returned.
45
+ Possibility to provide a custom no results component if needed through the `noResultsComponent` property.
46
+
47
+ Examples:
48
+
49
+ _Rendering a custom no results component_
50
+
51
+ ```jsx
52
+ <SearchResultList
53
+ query={query}
54
+ noResultsComponent={<ListItemText primary="No results were found" />}
55
+ />
56
+ ```
57
+
58
+ _Disable rendering when there are no results_
59
+
60
+ ```jsx
61
+ <SearchResultList query={query} disableRenderingWithNoResults />
62
+ ```
63
+
64
+ - 6faaa05626: The `<SearchResultGroup />` component now accepts an optional property `disableRenderingWithNoResults` to disable rendering when no results are returned.
65
+ Possibility to provide a custom no results component if needed through the `noResultsComponent` property.
66
+
67
+ Examples:
68
+
69
+ _Rendering a custom no results component_
70
+
71
+ ```jsx
72
+ <SearchResultGroup
73
+ query={query}
74
+ icon={<DocsIcon />}
75
+ title="Documentation"
76
+ noResultsComponent={<ListItemText primary="No results were found" />}
77
+ />
78
+ ```
79
+
80
+ _Disable rendering when there are no results_
81
+
82
+ ```jsx
83
+ <SearchResultGroup
84
+ query={query}
85
+ icon={<DocsIcon />}
86
+ title="Documentation"
87
+ disableRenderingWithNoResults
88
+ />
89
+ ```
90
+
91
+ ### Patch Changes
92
+
93
+ - Updated dependencies
94
+ - @backstage/plugin-search-common@1.1.0-next.1
95
+ - @backstage/core-components@0.11.2-next.1
96
+ - @backstage/core-plugin-api@1.0.7-next.1
97
+ - @backstage/theme@0.2.16
98
+ - @backstage/types@1.0.0
99
+ - @backstage/version-bridge@1.0.1
100
+
3
101
  ## 1.1.1-next.0
4
102
 
5
103
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -194,7 +194,7 @@ declare type SearchResultContextProps = {
194
194
  /**
195
195
  * A child function that receives an asynchronous result set and returns a react element.
196
196
  */
197
- children: (state: AsyncState<SearchResultSet>) => JSX.Element;
197
+ children: (state: AsyncState<SearchResultSet>) => JSX.Element | null;
198
198
  };
199
199
  /**
200
200
  * Provides context-based results to a child function.
@@ -216,7 +216,7 @@ declare type SearchResultContextProps = {
216
216
  * ```
217
217
  * @public
218
218
  */
219
- declare const SearchResultContext: (props: SearchResultContextProps) => JSX.Element;
219
+ declare const SearchResultContext: (props: SearchResultContextProps) => JSX.Element | null;
220
220
  /**
221
221
  * Props for {@link SearchResultApi}
222
222
  * @public
@@ -244,7 +244,7 @@ declare type SearchResultApiProps = SearchResultContextProps & {
244
244
  * ```
245
245
  * @public
246
246
  */
247
- declare const SearchResultApi: (props: SearchResultApiProps) => JSX.Element;
247
+ declare const SearchResultApi: (props: SearchResultApiProps) => JSX.Element | null;
248
248
  /**
249
249
  * Props for {@link SearchResultState}
250
250
  * @public
@@ -327,7 +327,7 @@ declare type SearchResultListLayoutProps = ListProps & {
327
327
  /**
328
328
  * Function to customize how result items are rendered.
329
329
  */
330
- renderResultItem?: (resultItem: SearchResult$1) => JSX.Element;
330
+ renderResultItem?: (value: SearchResult$1, index: number, array: SearchResult$1[]) => JSX.Element | null;
331
331
  /**
332
332
  * If defined, will render a default error panel.
333
333
  */
@@ -336,6 +336,10 @@ declare type SearchResultListLayoutProps = ListProps & {
336
336
  * If defined, will render a default loading progress.
337
337
  */
338
338
  loading?: boolean;
339
+ /**
340
+ * Optional component to render when no results. Default to <EmptyState /> component.
341
+ */
342
+ noResultsComponent?: ReactNode;
339
343
  };
340
344
  /**
341
345
  * Default layout for rendering search results in a list.
@@ -352,6 +356,10 @@ declare type SearchResultListProps = Omit<SearchResultListLayoutProps, 'loading'
352
356
  * A search query used for requesting the results to be listed.
353
357
  */
354
358
  query: Partial<SearchQuery>;
359
+ /**
360
+ * Optional property to provide if component should not render the component when no results are found.
361
+ */
362
+ disableRenderingWithNoResults?: boolean;
355
363
  };
356
364
  /**
357
365
  * Given a query, search for results and render them as a list.
@@ -462,7 +470,7 @@ declare type SearchResultGroupLayoutProps<FilterOption> = ListProps & {
462
470
  * Function to customize how filter options are rendered.
463
471
  * @remarks Defaults to a menu item where its value and label bounds to the option string.
464
472
  */
465
- renderFilterOption?: (filterOption: FilterOption) => JSX.Element;
473
+ renderFilterOption?: (value: FilterOption, index: number, array: FilterOption[]) => JSX.Element | null;
466
474
  /**
467
475
  * A list of search filter keys, also known as filter field names.
468
476
  */
@@ -478,7 +486,7 @@ declare type SearchResultGroupLayoutProps<FilterOption> = ListProps & {
478
486
  /**
479
487
  * Function to customize how result items are rendered.
480
488
  */
481
- renderResultItem?: (resultItem: SearchResult$1) => JSX.Element;
489
+ renderResultItem?: (value: SearchResult$1, index: number, array: SearchResult$1[]) => JSX.Element | null;
482
490
  /**
483
491
  * If defined, will render a default error panel.
484
492
  */
@@ -487,6 +495,10 @@ declare type SearchResultGroupLayoutProps<FilterOption> = ListProps & {
487
495
  * If defined, will render a default loading progress.
488
496
  */
489
497
  loading?: boolean;
498
+ /**
499
+ * Optional component to render when no results. Default to <EmptyState /> component.
500
+ */
501
+ noResultsComponent?: ReactNode;
490
502
  };
491
503
  /**
492
504
  * Default layout for rendering search results in a group.
@@ -503,6 +515,10 @@ declare type SearchResultGroupProps<FilterOption> = Omit<SearchResultGroupLayout
503
515
  * A search query used for requesting the results to be grouped.
504
516
  */
505
517
  query: Partial<SearchQuery>;
518
+ /**
519
+ * Optional property to provide if component should not render the group when no results are found.
520
+ */
521
+ disableRenderingWithNoResults?: boolean;
506
522
  };
507
523
  /**
508
524
  * Given a query, search for results and render them as a group.
@@ -538,6 +554,7 @@ declare type SearchContextValue = {
538
554
  setTerm: React.Dispatch<React.SetStateAction<string>>;
539
555
  setTypes: React.Dispatch<React.SetStateAction<string[]>>;
540
556
  setFilters: React.Dispatch<React.SetStateAction<JsonObject>>;
557
+ setPageLimit: React.Dispatch<React.SetStateAction<number | undefined>>;
541
558
  setPageCursor: React.Dispatch<React.SetStateAction<string | undefined>>;
542
559
  fetchNextPage?: React.DispatchWithoutAction;
543
560
  fetchPreviousPage?: React.DispatchWithoutAction;
@@ -550,6 +567,7 @@ declare type SearchContextState = {
550
567
  term: string;
551
568
  types: string[];
552
569
  filters: JsonObject;
570
+ pageLimit?: number;
553
571
  pageCursor?: string;
554
572
  };
555
573
  /**
package/dist/index.esm.js CHANGED
@@ -70,9 +70,10 @@ const useSearchContextCheck = () => {
70
70
  };
71
71
  const searchInitialState = {
72
72
  term: "",
73
- pageCursor: void 0,
73
+ types: [],
74
74
  filters: {},
75
- types: []
75
+ pageLimit: void 0,
76
+ pageCursor: void 0
76
77
  };
77
78
  const useSearchContextValue = (initialValue = searchInitialState) => {
78
79
  var _a, _b, _c, _d;
@@ -80,6 +81,9 @@ const useSearchContextValue = (initialValue = searchInitialState) => {
80
81
  const [term, setTerm] = useState(initialValue.term);
81
82
  const [types, setTypes] = useState(initialValue.types);
82
83
  const [filters, setFilters] = useState(initialValue.filters);
84
+ const [pageLimit, setPageLimit] = useState(
85
+ initialValue.pageLimit
86
+ );
83
87
  const [pageCursor, setPageCursor] = useState(
84
88
  initialValue.pageCursor
85
89
  );
@@ -88,11 +92,12 @@ const useSearchContextValue = (initialValue = searchInitialState) => {
88
92
  const result = useAsync(
89
93
  () => searchApi.query({
90
94
  term,
95
+ types,
91
96
  filters,
92
- pageCursor,
93
- types
97
+ pageLimit,
98
+ pageCursor
94
99
  }),
95
- [term, types, filters, pageCursor]
100
+ [term, types, filters, pageLimit, pageCursor]
96
101
  );
97
102
  const hasNextPage = !result.loading && !result.error && ((_a = result.value) == null ? void 0 : _a.nextPageCursor);
98
103
  const hasPreviousPage = !result.loading && !result.error && ((_b = result.value) == null ? void 0 : _b.previousPageCursor);
@@ -116,12 +121,14 @@ const useSearchContextValue = (initialValue = searchInitialState) => {
116
121
  }, [filters, prevFilters, setPageCursor]);
117
122
  const value = {
118
123
  result,
119
- filters,
120
- setFilters,
121
124
  term,
122
125
  setTerm,
123
126
  types,
124
127
  setTypes,
128
+ filters,
129
+ setFilters,
130
+ pageLimit,
131
+ setPageLimit,
125
132
  pageCursor,
126
133
  setPageCursor,
127
134
  fetchNextPage: hasNextPage ? fetchNextPage : void 0,
@@ -613,18 +620,10 @@ const SearchResultContext = (props) => {
613
620
  const SearchResultApi = (props) => {
614
621
  const { query, children } = props;
615
622
  const searchApi = useApi(searchApiRef);
616
- const state = useAsync(
617
- () => {
618
- var _a, _b, _c;
619
- return searchApi.query({
620
- term: (_a = query.term) != null ? _a : "",
621
- types: (_b = query.types) != null ? _b : [],
622
- filters: (_c = query.filters) != null ? _c : {},
623
- pageCursor: query.pageCursor
624
- });
625
- },
626
- [query]
627
- );
623
+ const state = useAsync(() => {
624
+ const { term = "", types = [], filters = {}, ...rest } = query;
625
+ return searchApi.query({ ...rest, term, types, filters });
626
+ }, [query]);
628
627
  return children(state);
629
628
  };
630
629
  const SearchResultState = (props) => {
@@ -751,29 +750,29 @@ const HigherOrderDefaultResultListItem = (props) => {
751
750
  };
752
751
 
753
752
  const SearchResultListLayout = (props) => {
754
- const { loading, error, resultItems, renderResultItem, ...rest } = props;
753
+ const {
754
+ loading,
755
+ error,
756
+ resultItems,
757
+ renderResultItem = (resultItem) => /* @__PURE__ */ React.createElement(HigherOrderDefaultResultListItem, {
758
+ key: resultItem.document.location,
759
+ result: resultItem.document
760
+ }),
761
+ noResultsComponent = /* @__PURE__ */ React.createElement(EmptyState, {
762
+ missing: "data",
763
+ title: "Sorry, no results were found"
764
+ }),
765
+ ...rest
766
+ } = props;
755
767
  return /* @__PURE__ */ React.createElement(List, {
756
768
  ...rest
757
769
  }, loading ? /* @__PURE__ */ React.createElement(Progress, null) : null, !loading && error ? /* @__PURE__ */ React.createElement(ResponseErrorPanel, {
758
770
  title: "Error encountered while fetching search results",
759
771
  error
760
- }) : null, !loading && !error && (resultItems == null ? void 0 : resultItems.length) ? resultItems.map((resultItem) => {
761
- var _a;
762
- return (_a = renderResultItem == null ? void 0 : renderResultItem(resultItem)) != null ? _a : null;
763
- }) : null, !loading && !error && !(resultItems == null ? void 0 : resultItems.length) ? /* @__PURE__ */ React.createElement(EmptyState, {
764
- missing: "data",
765
- title: "Sorry, no results were found"
766
- }) : null);
772
+ }) : null, !loading && !error && (resultItems == null ? void 0 : resultItems.length) ? resultItems.map(renderResultItem) : null, !loading && !error && !(resultItems == null ? void 0 : resultItems.length) ? /* @__PURE__ */ React.createElement(ListItem, null, noResultsComponent) : null);
767
773
  };
768
774
  const SearchResultList = (props) => {
769
- const {
770
- query,
771
- renderResultItem = ({ document }) => /* @__PURE__ */ React.createElement(HigherOrderDefaultResultListItem, {
772
- key: document.location,
773
- result: document
774
- }),
775
- ...rest
776
- } = props;
775
+ const { query, disableRenderingWithNoResults, ...rest } = props;
777
776
  return /* @__PURE__ */ React.createElement(AnalyticsContext, {
778
777
  attributes: {
779
778
  pluginId: "search",
@@ -781,13 +780,18 @@ const SearchResultList = (props) => {
781
780
  }
782
781
  }, /* @__PURE__ */ React.createElement(SearchResultState, {
783
782
  query
784
- }, ({ loading, error, value }) => /* @__PURE__ */ React.createElement(SearchResultListLayout, {
785
- ...rest,
786
- loading,
787
- error,
788
- resultItems: value == null ? void 0 : value.results,
789
- renderResultItem
790
- })));
783
+ }, ({ loading, error, value }) => {
784
+ var _a;
785
+ if (!((_a = value == null ? void 0 : value.results) == null ? void 0 : _a.length) && disableRenderingWithNoResults) {
786
+ return null;
787
+ }
788
+ return /* @__PURE__ */ React.createElement(SearchResultListLayout, {
789
+ ...rest,
790
+ loading,
791
+ error,
792
+ resultItems: value == null ? void 0 : value.results
793
+ });
794
+ }));
791
795
  };
792
796
 
793
797
  const useStyles = makeStyles((theme) => ({
@@ -915,14 +919,26 @@ function SearchResultGroupLayout(props) {
915
919
  icon,
916
920
  title,
917
921
  titleProps = {},
918
- link,
922
+ link = /* @__PURE__ */ React.createElement(React.Fragment, null, "See all", /* @__PURE__ */ React.createElement(ArrowForwardIosIcon, {
923
+ className: classes.listSubheaderLinkIcon
924
+ })),
919
925
  linkProps = {},
920
926
  filterOptions,
921
- renderFilterOption,
927
+ renderFilterOption = (filterOption) => /* @__PURE__ */ React.createElement(MenuItem, {
928
+ key: String(filterOption),
929
+ value: String(filterOption)
930
+ }, filterOption),
922
931
  filterFields,
923
932
  renderFilterField,
924
933
  resultItems,
925
- renderResultItem,
934
+ renderResultItem = (resultItem) => /* @__PURE__ */ React.createElement(HigherOrderDefaultResultListItem, {
935
+ key: resultItem.document.location,
936
+ result: resultItem.document
937
+ }),
938
+ noResultsComponent = /* @__PURE__ */ React.createElement(EmptyState, {
939
+ missing: "data",
940
+ title: "Sorry, no results were found"
941
+ }),
926
942
  ...rest
927
943
  } = props;
928
944
  const handleClick = useCallback((e) => {
@@ -955,12 +971,7 @@ function SearchResultGroupLayout(props) {
955
971
  onClose: handleClose,
956
972
  onClick: handleClose,
957
973
  keepMounted: true
958
- }, filterOptions.map(
959
- (filterOption) => renderFilterOption ? renderFilterOption(filterOption) : /* @__PURE__ */ React.createElement(MenuItem, {
960
- key: String(filterOption),
961
- value: String(filterOption)
962
- }, filterOption)
963
- )) : null, filterFields == null ? void 0 : filterFields.map(
974
+ }, filterOptions.map(renderFilterOption)) : null, filterFields == null ? void 0 : filterFields.map(
964
975
  (filterField) => {
965
976
  var _a;
966
977
  return (_a = renderFilterField == null ? void 0 : renderFilterField(filterField)) != null ? _a : null;
@@ -969,27 +980,16 @@ function SearchResultGroupLayout(props) {
969
980
  className: classes.listSubheaderLink,
970
981
  to: "/search",
971
982
  ...linkProps
972
- }, link != null ? link : /* @__PURE__ */ React.createElement(React.Fragment, null, "See all", /* @__PURE__ */ React.createElement(ArrowForwardIosIcon, {
973
- className: classes.listSubheaderLinkIcon
974
- })))), loading ? /* @__PURE__ */ React.createElement(Progress, null) : null, !loading && error ? /* @__PURE__ */ React.createElement(ResponseErrorPanel, {
983
+ }, link)), loading ? /* @__PURE__ */ React.createElement(Progress, null) : null, !loading && error ? /* @__PURE__ */ React.createElement(ResponseErrorPanel, {
975
984
  title: "Error encountered while fetching search results",
976
985
  error
977
- }) : null, !loading && !error && (resultItems == null ? void 0 : resultItems.length) ? resultItems.map((resultItem) => {
978
- var _a;
979
- return (_a = renderResultItem == null ? void 0 : renderResultItem(resultItem)) != null ? _a : null;
980
- }) : null, !loading && !error && !(resultItems == null ? void 0 : resultItems.length) ? /* @__PURE__ */ React.createElement(ListItem, null, /* @__PURE__ */ React.createElement(EmptyState, {
981
- missing: "data",
982
- title: "Sorry, no results were found"
983
- })) : null);
986
+ }) : null, !loading && !error && (resultItems == null ? void 0 : resultItems.length) ? resultItems.map(renderResultItem) : null, !loading && !error && !(resultItems == null ? void 0 : resultItems.length) ? /* @__PURE__ */ React.createElement(ListItem, null, noResultsComponent) : null);
984
987
  }
985
988
  function SearchResultGroup(props) {
986
989
  const {
987
990
  query,
988
991
  linkProps = {},
989
- renderResultItem = ({ document }) => /* @__PURE__ */ React.createElement(HigherOrderDefaultResultListItem, {
990
- key: document.location,
991
- result: document
992
- }),
992
+ disableRenderingWithNoResults,
993
993
  ...rest
994
994
  } = props;
995
995
  const to = `/search?${qs.stringify(
@@ -1009,15 +1009,17 @@ function SearchResultGroup(props) {
1009
1009
  }, /* @__PURE__ */ React.createElement(SearchResultState, {
1010
1010
  query
1011
1011
  }, ({ loading, error, value }) => {
1012
- var _a;
1012
+ var _a, _b;
1013
+ if (!((_a = value == null ? void 0 : value.results) == null ? void 0 : _a.length) && disableRenderingWithNoResults) {
1014
+ return null;
1015
+ }
1013
1016
  return /* @__PURE__ */ React.createElement(SearchResultGroupLayout, {
1014
1017
  ...rest,
1015
1018
  loading,
1016
1019
  error,
1017
1020
  linkProps: { to, ...linkProps },
1018
1021
  resultItems: value == null ? void 0 : value.results,
1019
- renderResultItem,
1020
- filterFields: Object.keys((_a = query.filters) != null ? _a : {})
1022
+ filterFields: Object.keys((_b = query.filters) != null ? _b : {})
1021
1023
  });
1022
1024
  }));
1023
1025
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/api.ts","../src/components/HighlightedSearchResultText/HighlightedSearchResultText.tsx","../src/context/SearchContext.tsx","../src/components/SearchTracker/SearchTracker.tsx","../src/components/SearchBar/SearchBar.tsx","../src/components/SearchAutocomplete/SearchAutocomplete.tsx","../src/components/SearchAutocomplete/SearchAutocompleteDefaultOption.tsx","../src/components/SearchFilter/hooks.ts","../src/components/SearchFilter/SearchFilter.Autocomplete.tsx","../src/components/SearchFilter/SearchFilter.tsx","../src/components/SearchResult/SearchResult.tsx","../src/components/SearchResultPager/SearchResultPager.tsx","../src/components/DefaultResultListItem/DefaultResultListItem.tsx","../src/components/SearchResultList/SearchResultList.tsx","../src/components/SearchResultGroup/SearchResultGroup.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 { SearchQuery, SearchResultSet } from '@backstage/plugin-search-common';\nimport { createApiRef } from '@backstage/core-plugin-api';\n\n/**\n * @public\n */\nexport const searchApiRef = createApiRef<SearchApi>({\n id: 'plugin.search.queryservice',\n});\n\n/**\n * @public\n */\nexport interface SearchApi {\n query(query: SearchQuery): Promise<SearchResultSet>;\n}\n\n/**\n * @public\n *\n * Search Api Mock that can be used in tests and storybooks\n */\nexport class MockSearchApi implements SearchApi {\n constructor(public mockedResults?: SearchResultSet) {}\n\n query(): Promise<SearchResultSet> {\n return Promise.resolve(this.mockedResults || { results: [] });\n }\n}\n","/*\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, { useMemo } from 'react';\nimport { makeStyles } from '@material-ui/core';\n\nconst useStyles = makeStyles(\n () => ({\n highlight: {},\n }),\n { name: 'BackstageHighlightedSearchResultText' },\n);\n\n/**\n * Props for {@link HighlightedSearchResultText}.\n *\n * @public\n */\nexport type HighlightedSearchResultTextProps = {\n text: string;\n preTag: string;\n postTag: string;\n};\n\n/**\n * @public\n */\nexport const HighlightedSearchResultText = ({\n text,\n preTag,\n postTag,\n}: HighlightedSearchResultTextProps) => {\n const classes = useStyles();\n const terms = useMemo(\n () => text.split(new RegExp(`(${preTag}.+?${postTag})`)),\n [postTag, preTag, text],\n );\n return (\n <>\n {terms.map((t, idx) =>\n t.includes(preTag) ? (\n <mark className={classes.highlight} key={idx}>\n {t.replace(new RegExp(`${preTag}|${postTag}`, 'g'), '')}\n </mark>\n ) : (\n t\n ),\n )}\n </>\n );\n};\n","/*\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 { isEqual } from 'lodash';\nimport React, {\n PropsWithChildren,\n useCallback,\n useContext,\n useEffect,\n useState,\n} from 'react';\nimport useAsync, { AsyncState } from 'react-use/lib/useAsync';\nimport usePrevious from 'react-use/lib/usePrevious';\n\nimport {\n createVersionedContext,\n createVersionedValueMap,\n} from '@backstage/version-bridge';\nimport { JsonObject } from '@backstage/types';\nimport { AnalyticsContext, useApi } from '@backstage/core-plugin-api';\nimport { SearchResultSet } from '@backstage/plugin-search-common';\n\nimport { searchApiRef } from '../api';\n\n/**\n *\n * @public\n */\nexport type SearchContextValue = {\n result: AsyncState<SearchResultSet>;\n setTerm: React.Dispatch<React.SetStateAction<string>>;\n setTypes: React.Dispatch<React.SetStateAction<string[]>>;\n setFilters: React.Dispatch<React.SetStateAction<JsonObject>>;\n setPageCursor: React.Dispatch<React.SetStateAction<string | undefined>>;\n fetchNextPage?: React.DispatchWithoutAction;\n fetchPreviousPage?: React.DispatchWithoutAction;\n} & SearchContextState;\n\n/**\n *\n * @public\n */\nexport type SearchContextState = {\n term: string;\n types: string[];\n filters: JsonObject;\n pageCursor?: string;\n};\n\nconst SearchContext = createVersionedContext<{\n 1: SearchContextValue;\n}>('search-context');\n\n/**\n * @public\n *\n * React hook which provides the search context\n */\nexport const useSearch = () => {\n const context = useContext(SearchContext);\n if (!context) {\n throw new Error('useSearch must be used within a SearchContextProvider');\n }\n\n const value = context.atVersion(1);\n if (!value) {\n throw new Error('No SearchContext v1 found');\n }\n return value;\n};\n\n/**\n * @public\n *\n * React hook which checks for an existing search context\n */\nexport const useSearchContextCheck = () => {\n const context = useContext(SearchContext);\n return context !== undefined;\n};\n\n/**\n * The initial state of `SearchContextProvider`.\n *\n */\nconst searchInitialState: SearchContextState = {\n term: '',\n pageCursor: undefined,\n filters: {},\n types: [],\n};\n\nconst useSearchContextValue = (\n initialValue: SearchContextState = searchInitialState,\n) => {\n const searchApi = useApi(searchApiRef);\n\n const [term, setTerm] = useState<string>(initialValue.term);\n const [types, setTypes] = useState<string[]>(initialValue.types);\n const [filters, setFilters] = useState<JsonObject>(initialValue.filters);\n const [pageCursor, setPageCursor] = useState<string | undefined>(\n initialValue.pageCursor,\n );\n\n const prevTerm = usePrevious(term);\n const prevFilters = usePrevious(filters);\n\n const result = useAsync(\n () =>\n searchApi.query({\n term,\n filters,\n pageCursor,\n types,\n }),\n [term, types, filters, pageCursor],\n );\n\n const hasNextPage =\n !result.loading && !result.error && result.value?.nextPageCursor;\n const hasPreviousPage =\n !result.loading && !result.error && result.value?.previousPageCursor;\n const fetchNextPage = useCallback(() => {\n setPageCursor(result.value?.nextPageCursor);\n }, [result.value?.nextPageCursor]);\n const fetchPreviousPage = useCallback(() => {\n setPageCursor(result.value?.previousPageCursor);\n }, [result.value?.previousPageCursor]);\n\n useEffect(() => {\n // Any time a term is reset, we want to start from page 0.\n // Only reset the term if it has been modified by the user at least once, the initial state must not reset the term.\n if (prevTerm !== undefined && term !== prevTerm) {\n setPageCursor(undefined);\n }\n }, [term, prevTerm, setPageCursor]);\n\n useEffect(() => {\n // Any time filters is reset, we want to start from page 0.\n // Only reset the page if it has been modified by the user at least once, the initial state must not reset the page.\n if (prevFilters !== undefined && !isEqual(filters, prevFilters)) {\n setPageCursor(undefined);\n }\n }, [filters, prevFilters, setPageCursor]);\n\n const value: SearchContextValue = {\n result,\n filters,\n setFilters,\n term,\n setTerm,\n types,\n setTypes,\n pageCursor,\n setPageCursor,\n fetchNextPage: hasNextPage ? fetchNextPage : undefined,\n fetchPreviousPage: hasPreviousPage ? fetchPreviousPage : undefined,\n };\n\n return value;\n};\n\nexport type LocalSearchContextProps = PropsWithChildren<{\n initialState?: SearchContextState;\n}>;\n\nconst LocalSearchContext = (props: SearchContextProviderProps) => {\n const { initialState, children } = props;\n const value = useSearchContextValue(initialState);\n\n return (\n <AnalyticsContext\n attributes={{ searchTypes: value.types.sort().join(',') }}\n >\n <SearchContext.Provider value={createVersionedValueMap({ 1: value })}>\n {children}\n </SearchContext.Provider>\n </AnalyticsContext>\n );\n};\n\n/**\n * Props for {@link SearchContextProvider}\n *\n * @public\n */\nexport type SearchContextProviderProps =\n | PropsWithChildren<{\n /**\n * State initialized by a local context.\n */\n initialState?: SearchContextState;\n /**\n * Do not create an inheritance from the parent, as a new initial state must be defined in a local context.\n */\n inheritParentContextIfAvailable?: never;\n }>\n | PropsWithChildren<{\n /**\n * Does not accept initial state since it is already initialized by parent context.\n */\n initialState?: never;\n /**\n * If true, don't create a child context if there is a parent one already defined.\n * @remarks Defaults to false.\n */\n inheritParentContextIfAvailable?: boolean;\n }>;\n\n/**\n * @public\n * Search context provider which gives you access to shared state between search components\n */\nexport const SearchContextProvider = (props: SearchContextProviderProps) => {\n const { initialState, inheritParentContextIfAvailable, children } = props;\n const hasParentContext = useSearchContextCheck();\n\n return hasParentContext && inheritParentContextIfAvailable ? (\n <>{children}</>\n ) : (\n <LocalSearchContext initialState={initialState}>\n {children}\n </LocalSearchContext>\n );\n};\n","/*\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, { useEffect } from 'react';\nimport { useAnalytics } from '@backstage/core-plugin-api';\nimport { useSearch } from '../../context';\n\n/**\n * Capture search event on term change.\n */\nexport const TrackSearch = ({ children }: { children: React.ReactChild }) => {\n const analytics = useAnalytics();\n const { term } = useSearch();\n\n useEffect(() => {\n if (term) {\n // Capture analytics search event with search term provided as value\n analytics.captureEvent('search', term);\n }\n }, [analytics, term]);\n\n return <>{children}</>;\n};\n","/*\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, {\n ChangeEvent,\n KeyboardEvent,\n useState,\n useEffect,\n useCallback,\n forwardRef,\n ComponentType,\n ForwardRefExoticComponent,\n} from 'react';\nimport useDebounce from 'react-use/lib/useDebounce';\n\nimport {\n InputBase,\n InputBaseProps,\n InputAdornment,\n IconButton,\n} from '@material-ui/core';\nimport SearchIcon from '@material-ui/icons/Search';\nimport ClearButton from '@material-ui/icons/Clear';\n\nimport {\n AnalyticsContext,\n configApiRef,\n useApi,\n} from '@backstage/core-plugin-api';\n\nimport { SearchContextProvider, useSearch } from '../../context';\nimport { TrackSearch } from '../SearchTracker';\n\nfunction withContext<T>(Component: ComponentType<T>) {\n return forwardRef<unknown, T>((props, ref) => (\n <SearchContextProvider inheritParentContextIfAvailable>\n <Component {...props} ref={ref} />\n </SearchContextProvider>\n ));\n}\n\n/**\n * Props for {@link SearchBarBase}.\n *\n * @public\n */\nexport type SearchBarBaseProps = Omit<InputBaseProps, 'onChange'> & {\n debounceTime?: number;\n clearButton?: boolean;\n onClear?: () => void;\n onSubmit?: () => void;\n onChange: (value: string) => void;\n};\n\n/**\n * All search boxes exported by the search plugin are based on the <SearchBarBase />,\n * and this one is based on the <InputBase /> component from Material UI.\n * Recommended if you don't use Search Provider or Search Context.\n *\n * @public\n */\nexport const SearchBarBase: ForwardRefExoticComponent<SearchBarBaseProps> =\n withContext(\n forwardRef((props, ref) => {\n const {\n onChange,\n onKeyDown = () => {},\n onClear = () => {},\n onSubmit = () => {},\n debounceTime = 200,\n clearButton = true,\n fullWidth = true,\n value: defaultValue,\n placeholder: defaultPlaceholder,\n inputProps: defaultInputProps = {},\n endAdornment: defaultEndAdornment,\n ...rest\n } = props;\n\n const configApi = useApi(configApiRef);\n const [value, setValue] = useState<string>('');\n\n useEffect(() => {\n setValue(prevValue =>\n prevValue !== defaultValue ? String(defaultValue) : prevValue,\n );\n }, [defaultValue]);\n\n useDebounce(() => onChange(value), debounceTime, [value]);\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n setValue(e.target.value);\n },\n [setValue],\n );\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLInputElement>) => {\n if (onKeyDown) onKeyDown(e);\n if (onSubmit && e.key === 'Enter') {\n onSubmit();\n }\n },\n [onKeyDown, onSubmit],\n );\n\n const handleClear = useCallback(() => {\n onChange('');\n if (onClear) {\n onClear();\n }\n }, [onChange, onClear]);\n\n const placeholder =\n defaultPlaceholder ??\n `Search in ${configApi.getOptionalString('app.title') || 'Backstage'}`;\n\n const startAdornment = (\n <InputAdornment position=\"start\">\n <IconButton aria-label=\"Query\" size=\"small\" disabled>\n <SearchIcon />\n </IconButton>\n </InputAdornment>\n );\n\n const endAdornment = (\n <InputAdornment position=\"end\">\n <IconButton aria-label=\"Clear\" size=\"small\" onClick={handleClear}>\n <ClearButton />\n </IconButton>\n </InputAdornment>\n );\n\n return (\n <TrackSearch>\n <InputBase\n data-testid=\"search-bar-next\"\n ref={ref}\n value={value}\n placeholder={placeholder}\n startAdornment={startAdornment}\n endAdornment={clearButton ? endAdornment : defaultEndAdornment}\n inputProps={{ 'aria-label': 'Search', ...defaultInputProps }}\n fullWidth={fullWidth}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n {...rest}\n />\n </TrackSearch>\n );\n }),\n );\n\n/**\n * Props for {@link SearchBar}.\n *\n * @public\n */\nexport type SearchBarProps = Partial<SearchBarBaseProps>;\n\n/**\n * Recommended search bar when you use the Search Provider or Search Context.\n *\n * @public\n */\nexport const SearchBar: ForwardRefExoticComponent<SearchBarProps> = withContext(\n forwardRef((props, ref) => {\n const { value: initialValue = '', onChange, ...rest } = props;\n\n const { term, setTerm } = useSearch();\n\n useEffect(() => {\n if (initialValue) {\n setTerm(String(initialValue));\n }\n }, [initialValue, setTerm]);\n\n const handleChange = useCallback(\n (newValue: string) => {\n if (onChange) {\n onChange(newValue);\n } else {\n setTerm(newValue);\n }\n },\n [onChange, setTerm],\n );\n\n return (\n <AnalyticsContext\n attributes={{ pluginId: 'search', extension: 'SearchBar' }}\n >\n <SearchBarBase\n {...rest}\n ref={ref}\n value={term}\n onChange={handleChange}\n />\n </AnalyticsContext>\n );\n }),\n);\n","/*\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, { ChangeEvent, useCallback, useMemo } from 'react';\n\nimport { CircularProgress } from '@material-ui/core';\nimport {\n Autocomplete,\n AutocompleteProps,\n AutocompleteChangeDetails,\n AutocompleteChangeReason,\n AutocompleteRenderInputParams,\n} from '@material-ui/lab';\n\nimport { SearchContextProvider, useSearch } from '../../context';\nimport { SearchBar, SearchBarProps } from '../SearchBar';\n\n/**\n * Props for {@link SearchAutocomplete}.\n *\n * @public\n */\nexport type SearchAutocompleteProps<Option> = Omit<\n AutocompleteProps<Option, undefined, undefined, boolean>,\n 'renderInput' | 'disableClearable' | 'multiple'\n> & {\n 'data-testid'?: string;\n inputPlaceholder?: SearchBarProps['placeholder'];\n inputDebounceTime?: SearchBarProps['debounceTime'];\n};\n\n/**\n * Type for {@link SearchAutocomplete}.\n *\n * @public\n */\nexport type SearchAutocompleteComponent = <Option>(\n props: SearchAutocompleteProps<Option>,\n) => JSX.Element;\n\nconst withContext = (\n Component: SearchAutocompleteComponent,\n): SearchAutocompleteComponent => {\n return props => (\n <SearchContextProvider inheritParentContextIfAvailable>\n <Component {...props} />\n </SearchContextProvider>\n );\n};\n\n/**\n * Recommended search autocomplete when you use the Search Provider or Search Context.\n *\n * @public\n */\nexport const SearchAutocomplete = withContext(\n function SearchAutocompleteComponent<Option>(\n props: SearchAutocompleteProps<Option>,\n ) {\n const {\n loading,\n value,\n onChange = () => {},\n options = [],\n getOptionLabel = (option: Option) => String(option),\n inputPlaceholder,\n inputDebounceTime,\n freeSolo = true,\n fullWidth = true,\n clearOnBlur = false,\n 'data-testid': dataTestId = 'search-autocomplete',\n ...rest\n } = props;\n\n const { setTerm } = useSearch();\n\n const getInputValue = useCallback(\n (option?: null | string | Option) => {\n if (!option) return '';\n if (typeof option === 'string') return option;\n return getOptionLabel(option);\n },\n [getOptionLabel],\n );\n\n const inputValue = useMemo(\n () => getInputValue(value),\n [value, getInputValue],\n );\n\n const handleChange = useCallback(\n (\n event: ChangeEvent<{}>,\n option: null | string | Option,\n reason: AutocompleteChangeReason,\n details?: AutocompleteChangeDetails<Option>,\n ) => {\n setTerm(getInputValue(option));\n onChange(event, option, reason, details);\n },\n [getInputValue, setTerm, onChange],\n );\n\n const renderInput = useCallback(\n ({\n InputProps: { ref, endAdornment },\n InputLabelProps,\n ...params\n }: AutocompleteRenderInputParams) => (\n <SearchBar\n {...params}\n ref={ref}\n clearButton={false}\n value={inputValue}\n placeholder={inputPlaceholder}\n debounceTime={inputDebounceTime}\n endAdornment={\n loading ? (\n <CircularProgress\n data-testid=\"search-autocomplete-progressbar\"\n color=\"inherit\"\n size={20}\n />\n ) : (\n endAdornment\n )\n }\n />\n ),\n [loading, inputValue, inputPlaceholder, inputDebounceTime],\n );\n\n return (\n <Autocomplete\n {...rest}\n data-testid={dataTestId}\n value={value}\n onChange={handleChange}\n options={options}\n getOptionLabel={getOptionLabel}\n renderInput={renderInput}\n freeSolo={freeSolo}\n fullWidth={fullWidth}\n clearOnBlur={clearOnBlur}\n />\n );\n },\n);\n","/*\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, { ReactNode } from 'react';\nimport {\n ListItemIcon,\n ListItemText,\n ListItemTextProps,\n} from '@material-ui/core';\n\n/**\n * Props for {@link SearchAutocompleteDefaultOption}.\n *\n * @public\n */\nexport type SearchAutocompleteDefaultOptionProps = {\n icon?: ReactNode;\n primaryText: ListItemTextProps['primary'];\n primaryTextTypographyProps?: ListItemTextProps['primaryTypographyProps'];\n secondaryText?: ListItemTextProps['secondary'];\n secondaryTextTypographyProps?: ListItemTextProps['secondaryTypographyProps'];\n disableTextTypography?: ListItemTextProps['disableTypography'];\n};\n\n/**\n * A default search autocomplete option component.\n *\n * @public\n */\nexport const SearchAutocompleteDefaultOption = ({\n icon,\n primaryText,\n primaryTextTypographyProps,\n secondaryText,\n secondaryTextTypographyProps,\n disableTextTypography,\n}: SearchAutocompleteDefaultOptionProps) => (\n <>\n {icon ? <ListItemIcon>{icon}</ListItemIcon> : null}\n <ListItemText\n primary={primaryText}\n primaryTypographyProps={primaryTextTypographyProps}\n secondary={secondaryText}\n secondaryTypographyProps={secondaryTextTypographyProps}\n disableTypography={disableTextTypography}\n />\n </>\n);\n","/*\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 { useEffect, useRef } from 'react';\nimport useAsyncFn from 'react-use/lib/useAsyncFn';\nimport useDebounce from 'react-use/lib/useDebounce';\n\nimport { useSearch } from '../../context';\n\n/**\n * Utility hook for either asynchronously loading filter values from a given\n * function or synchronously providing a given list of default values.\n *\n * @public\n */\nexport const useAsyncFilterValues = (\n fn: ((partial: string) => Promise<string[]>) | undefined,\n inputValue: string,\n defaultValues: string[] = [],\n debounce: number = 250,\n) => {\n const valuesMemo = useRef<Record<string, string[] | Promise<string[]>>>({});\n const definiteFn = fn || (() => Promise.resolve([]));\n\n const [state, callback] = useAsyncFn(definiteFn, [inputValue], {\n loading: true,\n });\n\n // Do not invoke the given function more than necessary.\n useDebounce(\n () => {\n // Performance optimization: only invoke the callback once per inputValue\n // for the lifetime of the hook/component.\n if (valuesMemo.current[inputValue] === undefined) {\n valuesMemo.current[inputValue] = callback(inputValue).then(values => {\n // Override the value for future immediate returns.\n valuesMemo.current[inputValue] = values;\n return values;\n });\n }\n },\n debounce,\n [callback, inputValue],\n );\n\n // Immediately return the default values if they are provided.\n if (defaultValues.length) {\n return {\n loading: false,\n value: defaultValues,\n };\n }\n\n // Immediately return a memoized value if it is set (and not a promise).\n const possibleValue = valuesMemo.current[inputValue];\n if (Array.isArray(possibleValue)) {\n return {\n loading: false,\n value: possibleValue,\n };\n }\n\n return state;\n};\n\n/**\n * Utility hook for applying a given default value to the search context.\n *\n * @public\n */\nexport const useDefaultFilterValue = (\n name: string,\n defaultValue?: string | string[] | null,\n) => {\n const { setFilters } = useSearch();\n\n useEffect(() => {\n if (defaultValue && [defaultValue].flat().length > 0) {\n setFilters(prevFilters => ({\n ...prevFilters,\n [name]: defaultValue,\n }));\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n};\n","/*\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, { ChangeEvent, useState } from 'react';\nimport { Chip, TextField } from '@material-ui/core';\nimport {\n Autocomplete,\n AutocompleteGetTagProps,\n AutocompleteRenderInputParams,\n} from '@material-ui/lab';\n\nimport { useSearch } from '../../context';\nimport { useAsyncFilterValues, useDefaultFilterValue } from './hooks';\nimport { SearchFilterComponentProps } from './SearchFilter';\n\n/**\n * @public\n */\nexport type SearchAutocompleteFilterProps = SearchFilterComponentProps & {\n filterSelectedOptions?: boolean;\n limitTags?: number;\n multiple?: boolean;\n};\n\n/**\n * @public\n */\nexport const AutocompleteFilter = (props: SearchAutocompleteFilterProps) => {\n const {\n className,\n defaultValue,\n name,\n values: givenValues,\n valuesDebounceMs,\n label,\n filterSelectedOptions,\n limitTags,\n multiple,\n } = props;\n const [inputValue, setInputValue] = useState<string>('');\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 inputValue,\n defaultValues,\n valuesDebounceMs,\n );\n const { filters, setFilters } = useSearch();\n const filterValue =\n (filters[name] as string | string[] | undefined) || (multiple ? [] : null);\n\n // Set new filter values on input change.\n const handleChange = (\n _: ChangeEvent<{}>,\n newValue: string | string[] | null,\n ) => {\n setFilters(prevState => {\n const { [name]: filter, ...others } = prevState;\n\n if (newValue) {\n return { ...others, [name]: newValue };\n }\n return { ...others };\n });\n };\n\n // Provide the input field.\n const renderInput = (params: AutocompleteRenderInputParams) => (\n <TextField\n {...params}\n name=\"search\"\n variant=\"outlined\"\n label={label}\n fullWidth\n />\n );\n\n // Render tags as primary-colored chips.\n const renderTags = (\n tagValue: string[],\n getTagProps: AutocompleteGetTagProps,\n ) =>\n tagValue.map((option: string, index: number) => (\n <Chip label={option} color=\"primary\" {...getTagProps({ index })} />\n ));\n\n return (\n <Autocomplete\n filterSelectedOptions={filterSelectedOptions}\n limitTags={limitTags}\n multiple={multiple}\n className={className}\n id={`${multiple ? 'multi-' : ''}select-filter-${name}--select`}\n options={values || []}\n loading={loading}\n value={filterValue}\n onChange={handleChange}\n onInputChange={(_, newValue) => setInputValue(newValue)}\n renderInput={renderInput}\n renderTags={renderTags}\n />\n );\n};\n","/*\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 } from 'react';\nimport {\n makeStyles,\n FormControl,\n FormControlLabel,\n InputLabel,\n Checkbox,\n Select,\n MenuItem,\n FormLabel,\n} from '@material-ui/core';\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});\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 control={\n <Checkbox\n color=\"primary\"\n tabIndex={-1}\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 label={value}\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 const classes = useStyles();\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 { filters, setFilters } = useSearch();\n\n const handleChange = (e: ChangeEvent<{ value: unknown }>) => {\n const {\n target: { value },\n } = e;\n\n setFilters(prevFilters => {\n const { [name]: filter, ...others } = prevFilters;\n return value ? { ...others, [name]: value as string } : others;\n });\n };\n\n return (\n <FormControl\n disabled={loading}\n className={className}\n variant=\"filled\"\n fullWidth\n data-testid=\"search-selectfilter-next\"\n >\n {label ? (\n <InputLabel className={classes.label} margin=\"dense\">\n {label}\n </InputLabel>\n ) : null}\n <Select\n variant=\"outlined\"\n value={filters[name] || ''}\n onChange={handleChange}\n >\n <MenuItem value=\"\">\n <em>All</em>\n </MenuItem>\n {values.map((value: string) => (\n <MenuItem key={value} value={value}>\n {value}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n );\n};\n\n/**\n * @public\n */\nconst SearchFilter = ({\n component: Element,\n ...props\n}: SearchFilterWrapperProps) => <Element {...props} />;\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","/*\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 from 'react';\nimport useAsync, { AsyncState } from 'react-use/lib/useAsync';\n\nimport {\n EmptyState,\n Progress,\n ResponseErrorPanel,\n} from '@backstage/core-components';\nimport { AnalyticsContext, useApi } from '@backstage/core-plugin-api';\nimport { SearchQuery, SearchResultSet } from '@backstage/plugin-search-common';\n\nimport { useSearch } from '../../context';\nimport { searchApiRef } from '../../api';\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: (state: AsyncState<SearchResultSet>) => JSX.Element;\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 state = context.result;\n return children(state);\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 () =>\n searchApi.query({\n term: query.term ?? '',\n types: query.types ?? [],\n filters: query.filters ?? {},\n pageCursor: query.pageCursor,\n }),\n [query],\n );\n\n return children(state);\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 children: (resultSet: SearchResultSet) => 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 { query, children } = 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 (\n <EmptyState missing=\"data\" title=\"Sorry, no results were found\" />\n );\n }\n\n return children(value);\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","/*\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 from 'react';\n\nimport { Button, makeStyles } from '@material-ui/core';\nimport ArrowBackIosIcon from '@material-ui/icons/ArrowBackIos';\nimport ArrowForwardIosIcon from '@material-ui/icons/ArrowForwardIos';\n\nimport { useSearch } from '../../context';\n\nconst useStyles = makeStyles(theme => ({\n root: {\n display: 'flex',\n justifyContent: 'space-between',\n gap: theme.spacing(2),\n margin: theme.spacing(2, 0),\n },\n}));\n\n/**\n * @public\n */\nexport const SearchResultPager = () => {\n const { fetchNextPage, fetchPreviousPage } = useSearch();\n const classes = useStyles();\n\n if (!fetchNextPage && !fetchPreviousPage) {\n return <></>;\n }\n\n return (\n <nav aria-label=\"pagination navigation\" className={classes.root}>\n <Button\n aria-label=\"previous page\"\n disabled={!fetchPreviousPage}\n onClick={fetchPreviousPage}\n startIcon={<ArrowBackIosIcon />}\n >\n Previous\n </Button>\n\n <Button\n aria-label=\"next page\"\n disabled={!fetchNextPage}\n onClick={fetchNextPage}\n endIcon={<ArrowForwardIosIcon />}\n >\n Next\n </Button>\n </nav>\n );\n};\n","/*\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, { ReactNode } from 'react';\nimport { AnalyticsContext, useAnalytics } from '@backstage/core-plugin-api';\nimport {\n ResultHighlight,\n SearchDocument,\n} from '@backstage/plugin-search-common';\nimport { HighlightedSearchResultText } from '../HighlightedSearchResultText';\nimport {\n ListItem,\n ListItemIcon,\n ListItemText,\n Box,\n Divider,\n} from '@material-ui/core';\nimport { Link } from '@backstage/core-components';\n\n/**\n * Props for {@link DefaultResultListItem}\n *\n * @public\n */\nexport type DefaultResultListItemProps = {\n icon?: ReactNode;\n secondaryAction?: ReactNode;\n result: SearchDocument;\n highlight?: ResultHighlight;\n rank?: number;\n lineClamp?: number;\n};\n\n/**\n * A default result list item.\n *\n * @public\n */\nexport const DefaultResultListItemComponent = ({\n result,\n highlight,\n rank,\n icon,\n secondaryAction,\n lineClamp = 5,\n}: DefaultResultListItemProps) => {\n const analytics = useAnalytics();\n const handleClick = () => {\n analytics.captureEvent('discover', result.title, {\n attributes: { to: result.location },\n value: rank,\n });\n };\n\n return (\n <Link noTrack to={result.location} onClick={handleClick}>\n <ListItem alignItems=\"center\">\n {icon && <ListItemIcon>{icon}</ListItemIcon>}\n <ListItemText\n primaryTypographyProps={{ variant: 'h6' }}\n primary={\n highlight?.fields.title ? (\n <HighlightedSearchResultText\n text={highlight.fields.title}\n preTag={highlight.preTag}\n postTag={highlight.postTag}\n />\n ) : (\n result.title\n )\n }\n secondary={\n <span\n style={{\n display: '-webkit-box',\n WebkitBoxOrient: 'vertical',\n WebkitLineClamp: lineClamp,\n overflow: 'hidden',\n }}\n >\n {highlight?.fields.text ? (\n <HighlightedSearchResultText\n text={highlight.fields.text}\n preTag={highlight.preTag}\n postTag={highlight.postTag}\n />\n ) : (\n result.text\n )}\n </span>\n }\n />\n {secondaryAction && <Box alignItems=\"flex-end\">{secondaryAction}</Box>}\n </ListItem>\n <Divider />\n </Link>\n );\n};\n\n/**\n * @public\n */\nconst HigherOrderDefaultResultListItem = (\n props: DefaultResultListItemProps,\n) => {\n return (\n <AnalyticsContext\n attributes={{\n pluginId: 'search',\n extension: 'DefaultResultListItem',\n }}\n >\n <DefaultResultListItemComponent {...props} />\n </AnalyticsContext>\n );\n};\n\nexport { HigherOrderDefaultResultListItem as DefaultResultListItem };\n","/*\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 from 'react';\n\nimport { List, ListProps } from '@material-ui/core';\n\nimport {\n EmptyState,\n Progress,\n ResponseErrorPanel,\n} from '@backstage/core-components';\nimport { AnalyticsContext } from '@backstage/core-plugin-api';\nimport { SearchQuery, SearchResult } from '@backstage/plugin-search-common';\n\nimport { DefaultResultListItem } from '../DefaultResultListItem';\nimport { SearchResultState } from '../SearchResult';\n\n/**\n * Props for {@link SearchResultListLayout}\n * @public\n */\nexport type SearchResultListLayoutProps = ListProps & {\n /**\n * Search results to be rendered as a list.\n */\n resultItems?: SearchResult[];\n /**\n * Function to customize how result items are rendered.\n */\n renderResultItem?: (resultItem: SearchResult) => JSX.Element;\n /**\n * If defined, will render a default error panel.\n */\n error?: Error;\n /**\n * If defined, will render a default loading progress.\n */\n loading?: boolean;\n};\n\n/**\n * Default layout for rendering search results in a list.\n * @param props - See {@link SearchResultListLayoutProps}.\n * @public\n */\nexport const SearchResultListLayout = (props: SearchResultListLayoutProps) => {\n const { loading, error, resultItems, renderResultItem, ...rest } = props;\n\n return (\n <List {...rest}>\n {loading ? <Progress /> : null}\n {!loading && error ? (\n <ResponseErrorPanel\n title=\"Error encountered while fetching search results\"\n error={error}\n />\n ) : null}\n {!loading && !error && resultItems?.length\n ? resultItems.map(resultItem => renderResultItem?.(resultItem) ?? null)\n : null}\n {!loading && !error && !resultItems?.length ? (\n <EmptyState missing=\"data\" title=\"Sorry, no results were found\" />\n ) : null}\n </List>\n );\n};\n\n/**\n * Props for {@link SearchResultList}.\n * @public\n */\nexport type SearchResultListProps = Omit<\n SearchResultListLayoutProps,\n 'loading' | 'error' | 'resultItems'\n> & {\n /**\n * A search query used for requesting the results to be listed.\n */\n query: Partial<SearchQuery>;\n};\n\n/**\n * Given a query, search for results and render them as a list.\n * @param props - See {@link SearchResultListProps}.\n * @public\n */\nexport const SearchResultList = (props: SearchResultListProps) => {\n const {\n query,\n renderResultItem = ({ document }) => (\n <DefaultResultListItem key={document.location} result={document} />\n ),\n ...rest\n } = props;\n\n return (\n <AnalyticsContext\n attributes={{\n pluginId: 'search',\n extension: 'SearchResultList',\n }}\n >\n <SearchResultState query={query}>\n {({ loading, error, value }) => (\n <SearchResultListLayout\n {...rest}\n loading={loading}\n error={error}\n resultItems={value?.results}\n renderResultItem={renderResultItem}\n />\n )}\n </SearchResultState>\n </AnalyticsContext>\n );\n};\n","/*\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, {\n ChangeEvent,\n PropsWithChildren,\n ReactNode,\n useCallback,\n useState,\n} from 'react';\nimport qs from 'qs';\n\nimport {\n makeStyles,\n Theme,\n List,\n ListSubheader,\n ListItem,\n ListProps,\n Menu,\n MenuItem,\n InputBase,\n Select,\n Chip,\n Typography,\n TypographyProps,\n} from '@material-ui/core';\nimport AddIcon from '@material-ui/icons/Add';\nimport ArrowRightIcon from '@material-ui/icons/ArrowForwardIos';\n\nimport { JsonValue } from '@backstage/types';\nimport {\n EmptyState,\n Link,\n LinkProps,\n Progress,\n ResponseErrorPanel,\n} from '@backstage/core-components';\nimport { AnalyticsContext } from '@backstage/core-plugin-api';\nimport { SearchQuery, SearchResult } from '@backstage/plugin-search-common';\n\nimport { DefaultResultListItem } from '../DefaultResultListItem';\nimport { SearchResultState } from '../SearchResult';\n\nconst useStyles = makeStyles((theme: Theme) => ({\n listSubheader: {\n display: 'flex',\n alignItems: 'center',\n },\n listSubheaderName: {\n marginLeft: theme.spacing(1),\n textTransform: 'uppercase',\n },\n listSubheaderChip: {\n color: theme.palette.text.secondary,\n margin: theme.spacing(0, 0, 0, 1.5),\n },\n listSubheaderFilter: {\n display: 'flex',\n color: theme.palette.text.secondary,\n margin: theme.spacing(0, 0, 0, 1.5),\n },\n listSubheaderLink: {\n marginLeft: 'auto',\n display: 'flex',\n alignItems: 'center',\n },\n listSubheaderLinkIcon: {\n fontSize: 'inherit',\n marginLeft: theme.spacing(0.5),\n },\n}));\n\n/**\n * Props for {@link SearchResultGroupFilterFieldLayout}\n * @public\n */\nexport type SearchResultGroupFilterFieldLayoutProps = PropsWithChildren<{\n label: string;\n value?: JsonValue;\n onDelete: () => void;\n}>;\n\n/**\n * Default layout for a search group filter field.\n * @param props - See {@link SearchResultGroupFilterFieldLayoutProps}.\n * @public\n */\nexport const SearchResultGroupFilterFieldLayout = (\n props: SearchResultGroupFilterFieldLayoutProps,\n) => {\n const classes = useStyles();\n const { label, children, ...rest } = props;\n\n return (\n <Chip\n {...rest}\n className={classes.listSubheaderFilter}\n variant=\"outlined\"\n label={\n <>\n {label}: {children}\n </>\n }\n />\n );\n};\n\nconst NullIcon = () => null;\n\n/**\n * Common props for a result group filter field.\n * @public\n */\nexport type SearchResultGroupFilterFieldPropsWith<T> = T &\n SearchResultGroupFilterFieldLayoutProps & {\n onChange: (value: JsonValue) => void;\n };\n\nconst useSearchResultGroupTextFilterStyles = makeStyles((theme: Theme) => ({\n root: {\n fontSize: 'inherit',\n '&:focus': {\n outline: 'none',\n background: theme.palette.common.white,\n },\n '&:not(:focus)': {\n cursor: 'pointer',\n color: theme.palette.primary.main,\n '&:hover': {\n textDecoration: 'underline',\n },\n },\n },\n}));\n\n/**\n * Props for {@link SearchResultGroupTextFilterField}.\n * @public\n */\nexport type SearchResultGroupTextFilterFieldProps =\n SearchResultGroupFilterFieldPropsWith<{}>;\n\n/**\n * A text field that can be used as filter on search result groups.\n * @param props - See {@link SearchResultGroupTextFilterFieldProps}.\n * @example\n * ```\n * <SearchResultGroupTextFilterField\n * id=\"lifecycle\"\n * label=\"Lifecycle\"\n * value={value}\n * onChange={handleChangeFilter}\n * onDelete={handleDeleteFilter}\n * />\n * ```\n * @public\n */\nexport const SearchResultGroupTextFilterField = (\n props: SearchResultGroupTextFilterFieldProps,\n) => {\n const classes = useSearchResultGroupTextFilterStyles();\n const { label, value = 'None', onChange, onDelete } = props;\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n onChange(e.target.value);\n },\n [onChange],\n );\n\n return (\n <SearchResultGroupFilterFieldLayout label={label} onDelete={onDelete}>\n <Typography\n role=\"textbox\"\n component=\"span\"\n className={classes.root}\n onChange={handleChange}\n contentEditable\n suppressContentEditableWarning\n >\n {value}\n </Typography>\n </SearchResultGroupFilterFieldLayout>\n );\n};\n\nconst useSearchResultGroupSelectFilterStyles = makeStyles((theme: Theme) => ({\n root: {\n fontSize: 'inherit',\n '&:not(:focus)': {\n cursor: 'pointer',\n color: theme.palette.primary.main,\n '&:hover': {\n textDecoration: 'underline',\n },\n },\n '&:focus': {\n outline: 'none',\n },\n '&>div:first-child': {\n padding: 0,\n },\n },\n}));\n\n/**\n * Props for {@link SearchResultGroupTextFilterField}.\n * @public\n */\nexport type SearchResultGroupSelectFilterFieldProps =\n SearchResultGroupFilterFieldPropsWith<{\n children: ReactNode;\n }>;\n\n/**\n * A select field that can be used as filter on search result groups.\n * @param props - See {@link SearchResultGroupSelectFilterFieldProps}.\n * @example\n * ```\n * <SearchResultGroupSelectFilterField\n * id=\"lifecycle\"\n * label=\"Lifecycle\"\n * value={filters.lifecycle}\n * onChange={handleChangeFilter}\n * onDelete={handleDeleteFilter}\n * >\n * <MenuItem value=\"experimental\">Experimental</MenuItem>\n * <MenuItem value=\"production\">Production</MenuItem>\n * </SearchResultGroupSelectFilterField>\n * ```\n * @public\n */\nexport const SearchResultGroupSelectFilterField = (\n props: SearchResultGroupSelectFilterFieldProps,\n) => {\n const classes = useSearchResultGroupSelectFilterStyles();\n const { label, value = 'none', onChange, onDelete, children } = props;\n\n const handleChange = useCallback(\n (e: ChangeEvent<{ value: unknown }>) => {\n onChange(e.target.value as JsonValue);\n },\n [onChange],\n );\n\n return (\n <SearchResultGroupFilterFieldLayout label={label} onDelete={onDelete}>\n <Select\n className={classes.root}\n value={value}\n onChange={handleChange}\n input={<InputBase />}\n IconComponent={NullIcon}\n >\n <MenuItem value=\"none\">None</MenuItem>\n {children}\n </Select>\n </SearchResultGroupFilterFieldLayout>\n );\n};\n\n/**\n * Props for {@link SearchResultGroupLayout}\n * @public\n */\nexport type SearchResultGroupLayoutProps<FilterOption> = ListProps & {\n /**\n * Icon that representing a result group.\n */\n icon: JSX.Element;\n /**\n * The results group title content, it could be a text or an element.\n */\n title: ReactNode;\n /**\n * Props for the results group title.\n */\n titleProps?: Partial<TypographyProps>;\n /**\n * The results group link content, it could be a text or an element.\n */\n link?: ReactNode;\n /**\n * Props for the results group link, the \"to\" prop defaults to \"/search\".\n */\n linkProps?: Partial<LinkProps>;\n /**\n * A generic filter options that is rendered on the \"Add filter\" dropdown.\n */\n filterOptions?: FilterOption[];\n /**\n * Function to customize how filter options are rendered.\n * @remarks Defaults to a menu item where its value and label bounds to the option string.\n */\n renderFilterOption?: (filterOption: FilterOption) => JSX.Element;\n /**\n * A list of search filter keys, also known as filter field names.\n */\n filterFields?: string[];\n /**\n * Function to customize how filter chips are rendered.\n */\n renderFilterField?: (key: string) => JSX.Element | null;\n /**\n * Search results to be rendered as a group.\n */\n resultItems?: SearchResult[];\n /**\n * Function to customize how result items are rendered.\n */\n renderResultItem?: (resultItem: SearchResult) => JSX.Element;\n /**\n * If defined, will render a default error panel.\n */\n error?: Error;\n /**\n * If defined, will render a default loading progress.\n */\n loading?: boolean;\n};\n\n/**\n * Default layout for rendering search results in a group.\n * @param props - See {@link SearchResultGroupLayoutProps}.\n * @public\n */\nexport function SearchResultGroupLayout<FilterOption>(\n props: SearchResultGroupLayoutProps<FilterOption>,\n) {\n const classes = useStyles();\n const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);\n\n const {\n loading,\n error,\n icon,\n title,\n titleProps = {},\n link,\n linkProps = {},\n filterOptions,\n renderFilterOption,\n filterFields,\n renderFilterField,\n resultItems,\n renderResultItem,\n ...rest\n } = props;\n\n const handleClick = useCallback((e: React.MouseEvent<HTMLButtonElement>) => {\n setAnchorEl(e.currentTarget);\n }, []);\n\n const handleClose = useCallback(() => {\n setAnchorEl(null);\n }, []);\n\n return (\n <List {...rest}>\n <ListSubheader className={classes.listSubheader}>\n {icon}\n <Typography\n className={classes.listSubheaderName}\n component=\"strong\"\n {...titleProps}\n >\n {title}\n </Typography>\n {filterOptions ? (\n <Chip\n className={classes.listSubheaderChip}\n component=\"button\"\n icon={<AddIcon />}\n variant=\"outlined\"\n label=\"Add filter\"\n aria-controls=\"filters-menu\"\n aria-haspopup=\"true\"\n onClick={handleClick}\n />\n ) : null}\n {filterOptions ? (\n <Menu\n id=\"filters-menu\"\n anchorEl={anchorEl}\n open={Boolean(anchorEl)}\n onClose={handleClose}\n onClick={handleClose}\n keepMounted\n >\n {filterOptions.map(filterOption =>\n renderFilterOption ? (\n renderFilterOption(filterOption)\n ) : (\n <MenuItem\n key={String(filterOption)}\n value={String(filterOption)}\n >\n {filterOption}\n </MenuItem>\n ),\n )}\n </Menu>\n ) : null}\n {filterFields?.map(\n filterField => renderFilterField?.(filterField) ?? null,\n )}\n <Link className={classes.listSubheaderLink} to=\"/search\" {...linkProps}>\n {link ?? (\n <>\n See all\n <ArrowRightIcon className={classes.listSubheaderLinkIcon} />\n </>\n )}\n </Link>\n </ListSubheader>\n {loading ? <Progress /> : null}\n {!loading && error ? (\n <ResponseErrorPanel\n title=\"Error encountered while fetching search results\"\n error={error}\n />\n ) : null}\n {!loading && !error && resultItems?.length\n ? resultItems.map(resultItem => renderResultItem?.(resultItem) ?? null)\n : null}\n {!loading && !error && !resultItems?.length ? (\n <ListItem>\n <EmptyState missing=\"data\" title=\"Sorry, no results were found\" />\n </ListItem>\n ) : null}\n </List>\n );\n}\n\n/**\n * Props for {@link SearchResultGroup}.\n * @public\n */\nexport type SearchResultGroupProps<FilterOption> = Omit<\n SearchResultGroupLayoutProps<FilterOption>,\n 'loading' | 'error' | 'resultItems' | 'filterFields'\n> & {\n /**\n * A search query used for requesting the results to be grouped.\n */\n query: Partial<SearchQuery>;\n};\n\n/**\n * Given a query, search for results and render them as a group.\n * @param props - See {@link SearchResultGroupProps}.\n * @public\n */\nexport function SearchResultGroup<FilterOption>(\n props: SearchResultGroupProps<FilterOption>,\n) {\n const {\n query,\n linkProps = {},\n renderResultItem = ({ document }) => (\n <DefaultResultListItem key={document.location} result={document} />\n ),\n ...rest\n } = props;\n\n const to = `/search?${qs.stringify(\n {\n query: query.term,\n types: query.types,\n filters: query.filters,\n pageCursor: query.pageCursor,\n },\n { arrayFormat: 'brackets' },\n )}`;\n\n return (\n <AnalyticsContext\n attributes={{\n pluginId: 'search',\n extension: 'SearchResultGroup',\n }}\n >\n <SearchResultState query={query}>\n {({ loading, error, value }) => (\n <SearchResultGroupLayout\n {...rest}\n loading={loading}\n error={error}\n linkProps={{ to, ...linkProps }}\n resultItems={value?.results}\n renderResultItem={renderResultItem}\n filterFields={Object.keys(query.filters ?? {})}\n />\n )}\n </SearchResultState>\n </AnalyticsContext>\n );\n}\n"],"names":["useStyles","_a","withContext","DefaultResultListItem","ArrowRightIcon"],"mappings":";;;;;;;;;;;;;;;;;;AAsBO,MAAM,eAAe,YAAwB,CAAA;AAAA,EAClD,EAAI,EAAA,4BAAA;AACN,CAAC,EAAA;AAcM,MAAM,aAAmC,CAAA;AAAA,EAC9C,YAAmB,aAAiC,EAAA;AAAjC,IAAA,IAAA,CAAA,aAAA,GAAA,aAAA,CAAA;AAAA,GAAkC;AAAA,EAErD,KAAkC,GAAA;AAChC,IAAO,OAAA,OAAA,CAAQ,QAAQ,IAAK,CAAA,aAAA,IAAiB,EAAE,OAAS,EAAA,IAAI,CAAA,CAAA;AAAA,GAC9D;AACF;;ACzBA,MAAMA,WAAY,GAAA,UAAA;AAAA,EAChB,OAAO;AAAA,IACL,WAAW,EAAC;AAAA,GACd,CAAA;AAAA,EACA,EAAE,MAAM,sCAAuC,EAAA;AACjD,CAAA,CAAA;AAgBO,MAAM,8BAA8B,CAAC;AAAA,EAC1C,IAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AACF,CAAwC,KAAA;AACtC,EAAA,MAAM,UAAUA,WAAU,EAAA,CAAA;AAC1B,EAAA,MAAM,KAAQ,GAAA,OAAA;AAAA,IACZ,MAAM,KAAK,KAAM,CAAA,IAAI,OAAO,CAAI,CAAA,EAAA,MAAA,CAAA,GAAA,EAAY,UAAU,CAAC,CAAA;AAAA,IACvD,CAAC,OAAS,EAAA,MAAA,EAAQ,IAAI,CAAA;AAAA,GACxB,CAAA;AACA,EAAA,iEAEK,KAAM,CAAA,GAAA;AAAA,IAAI,CAAC,CAAG,EAAA,GAAA,KACb,EAAE,QAAS,CAAA,MAAM,oBACd,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,MAAK,WAAW,OAAQ,CAAA,SAAA;AAAA,MAAW,GAAK,EAAA,GAAA;AAAA,KACtC,EAAA,CAAA,CAAE,OAAQ,CAAA,IAAI,MAAO,CAAA,CAAA,EAAG,MAAU,CAAA,CAAA,EAAA,OAAA,CAAA,CAAA,EAAW,GAAG,CAAA,EAAG,EAAE,CACxD,CAEA,GAAA,CAAA;AAAA,GAGN,CAAA,CAAA;AAEJ;;ACDA,MAAM,aAAA,GAAgB,uBAEnB,gBAAgB,CAAA,CAAA;AAOZ,MAAM,YAAY,MAAM;AAC7B,EAAM,MAAA,OAAA,GAAU,WAAW,aAAa,CAAA,CAAA;AACxC,EAAA,IAAI,CAAC,OAAS,EAAA;AACZ,IAAM,MAAA,IAAI,MAAM,uDAAuD,CAAA,CAAA;AAAA,GACzE;AAEA,EAAM,MAAA,KAAA,GAAQ,OAAQ,CAAA,SAAA,CAAU,CAAC,CAAA,CAAA;AACjC,EAAA,IAAI,CAAC,KAAO,EAAA;AACV,IAAM,MAAA,IAAI,MAAM,2BAA2B,CAAA,CAAA;AAAA,GAC7C;AACA,EAAO,OAAA,KAAA,CAAA;AACT,EAAA;AAOO,MAAM,wBAAwB,MAAM;AACzC,EAAM,MAAA,OAAA,GAAU,WAAW,aAAa,CAAA,CAAA;AACxC,EAAA,OAAO,OAAY,KAAA,KAAA,CAAA,CAAA;AACrB,EAAA;AAMA,MAAM,kBAAyC,GAAA;AAAA,EAC7C,IAAM,EAAA,EAAA;AAAA,EACN,UAAY,EAAA,KAAA,CAAA;AAAA,EACZ,SAAS,EAAC;AAAA,EACV,OAAO,EAAC;AACV,CAAA,CAAA;AAEA,MAAM,qBAAA,GAAwB,CAC5B,YAAA,GAAmC,kBAChC,KAAA;AA3GL,EAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,CAAA;AA4GE,EAAM,MAAA,SAAA,GAAY,OAAO,YAAY,CAAA,CAAA;AAErC,EAAA,MAAM,CAAC,IAAM,EAAA,OAAO,CAAI,GAAA,QAAA,CAAiB,aAAa,IAAI,CAAA,CAAA;AAC1D,EAAA,MAAM,CAAC,KAAO,EAAA,QAAQ,CAAI,GAAA,QAAA,CAAmB,aAAa,KAAK,CAAA,CAAA;AAC/D,EAAA,MAAM,CAAC,OAAS,EAAA,UAAU,CAAI,GAAA,QAAA,CAAqB,aAAa,OAAO,CAAA,CAAA;AACvE,EAAM,MAAA,CAAC,UAAY,EAAA,aAAa,CAAI,GAAA,QAAA;AAAA,IAClC,YAAa,CAAA,UAAA;AAAA,GACf,CAAA;AAEA,EAAM,MAAA,QAAA,GAAW,YAAY,IAAI,CAAA,CAAA;AACjC,EAAM,MAAA,WAAA,GAAc,YAAY,OAAO,CAAA,CAAA;AAEvC,EAAA,MAAM,MAAS,GAAA,QAAA;AAAA,IACb,MACE,UAAU,KAAM,CAAA;AAAA,MACd,IAAA;AAAA,MACA,OAAA;AAAA,MACA,UAAA;AAAA,MACA,KAAA;AAAA,KACD,CAAA;AAAA,IACH,CAAC,IAAA,EAAM,KAAO,EAAA,OAAA,EAAS,UAAU,CAAA;AAAA,GACnC,CAAA;AAEA,EAAM,MAAA,WAAA,GACJ,CAAC,MAAO,CAAA,OAAA,IAAW,CAAC,MAAO,CAAA,KAAA,KAAA,CAAS,EAAO,GAAA,MAAA,CAAA,KAAA,KAAP,IAAc,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,cAAA,CAAA,CAAA;AACpD,EAAM,MAAA,eAAA,GACJ,CAAC,MAAO,CAAA,OAAA,IAAW,CAAC,MAAO,CAAA,KAAA,KAAA,CAAS,EAAO,GAAA,MAAA,CAAA,KAAA,KAAP,IAAc,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,kBAAA,CAAA,CAAA;AACpD,EAAM,MAAA,aAAA,GAAgB,YAAY,MAAM;AAvI1C,IAAAC,IAAAA,GAAAA,CAAAA;AAwII,IAAA,aAAA,CAAA,CAAcA,GAAA,GAAA,MAAA,CAAO,KAAP,KAAA,IAAA,GAAA,KAAA,CAAA,GAAAA,IAAc,cAAc,CAAA,CAAA;AAAA,KACzC,CAAC,CAAA,EAAA,GAAA,MAAA,CAAO,KAAP,KAAA,IAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAc,cAAc,CAAC,CAAA,CAAA;AACjC,EAAM,MAAA,iBAAA,GAAoB,YAAY,MAAM;AA1I9C,IAAAA,IAAAA,GAAAA,CAAAA;AA2II,IAAA,aAAA,CAAA,CAAcA,GAAA,GAAA,MAAA,CAAO,KAAP,KAAA,IAAA,GAAA,KAAA,CAAA,GAAAA,IAAc,kBAAkB,CAAA,CAAA;AAAA,KAC7C,CAAC,CAAA,EAAA,GAAA,MAAA,CAAO,KAAP,KAAA,IAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAc,kBAAkB,CAAC,CAAA,CAAA;AAErC,EAAA,SAAA,CAAU,MAAM;AAGd,IAAI,IAAA,QAAA,KAAa,KAAa,CAAA,IAAA,IAAA,KAAS,QAAU,EAAA;AAC/C,MAAA,aAAA,CAAc,KAAS,CAAA,CAAA,CAAA;AAAA,KACzB;AAAA,GACC,EAAA,CAAC,IAAM,EAAA,QAAA,EAAU,aAAa,CAAC,CAAA,CAAA;AAElC,EAAA,SAAA,CAAU,MAAM;AAGd,IAAA,IAAI,gBAAgB,KAAa,CAAA,IAAA,CAAC,OAAQ,CAAA,OAAA,EAAS,WAAW,CAAG,EAAA;AAC/D,MAAA,aAAA,CAAc,KAAS,CAAA,CAAA,CAAA;AAAA,KACzB;AAAA,GACC,EAAA,CAAC,OAAS,EAAA,WAAA,EAAa,aAAa,CAAC,CAAA,CAAA;AAExC,EAAA,MAAM,KAA4B,GAAA;AAAA,IAChC,MAAA;AAAA,IACA,OAAA;AAAA,IACA,UAAA;AAAA,IACA,IAAA;AAAA,IACA,OAAA;AAAA,IACA,KAAA;AAAA,IACA,QAAA;AAAA,IACA,UAAA;AAAA,IACA,aAAA;AAAA,IACA,aAAA,EAAe,cAAc,aAAgB,GAAA,KAAA,CAAA;AAAA,IAC7C,iBAAA,EAAmB,kBAAkB,iBAAoB,GAAA,KAAA,CAAA;AAAA,GAC3D,CAAA;AAEA,EAAO,OAAA,KAAA,CAAA;AACT,CAAA,CAAA;AAMA,MAAM,kBAAA,GAAqB,CAAC,KAAsC,KAAA;AAChE,EAAM,MAAA,EAAE,YAAc,EAAA,QAAA,EAAa,GAAA,KAAA,CAAA;AACnC,EAAM,MAAA,KAAA,GAAQ,sBAAsB,YAAY,CAAA,CAAA;AAEhD,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,gBAAA,EAAA;AAAA,IACC,UAAA,EAAY,EAAE,WAAa,EAAA,KAAA,CAAM,MAAM,IAAK,EAAA,CAAE,IAAK,CAAA,GAAG,CAAE,EAAA;AAAA,GAExD,kBAAA,KAAA,CAAA,aAAA,CAAC,cAAc,QAAd,EAAA;AAAA,IAAuB,KAAO,EAAA,uBAAA,CAAwB,EAAE,CAAA,EAAG,OAAO,CAAA;AAAA,GAAA,EAChE,QACH,CACF,CAAA,CAAA;AAEJ,CAAA,CAAA;AAkCa,MAAA,qBAAA,GAAwB,CAAC,KAAsC,KAAA;AAC1E,EAAA,MAAM,EAAE,YAAA,EAAc,+BAAiC,EAAA,QAAA,EAAa,GAAA,KAAA,CAAA;AACpE,EAAA,MAAM,mBAAmB,qBAAsB,EAAA,CAAA;AAE/C,EAAA,OAAO,gBAAoB,IAAA,+BAAA,mBACtB,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,EAAA,QAAS,oBAEX,KAAA,CAAA,aAAA,CAAA,kBAAA,EAAA;AAAA,IAAmB,YAAA;AAAA,GAAA,EACjB,QACH,CAAA,CAAA;AAEJ;;ACtNO,MAAM,WAAc,GAAA,CAAC,EAAE,QAAA,EAA+C,KAAA;AAC3E,EAAA,MAAM,YAAY,YAAa,EAAA,CAAA;AAC/B,EAAM,MAAA,EAAE,IAAK,EAAA,GAAI,SAAU,EAAA,CAAA;AAE3B,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,IAAM,EAAA;AAER,MAAU,SAAA,CAAA,YAAA,CAAa,UAAU,IAAI,CAAA,CAAA;AAAA,KACvC;AAAA,GACC,EAAA,CAAC,SAAW,EAAA,IAAI,CAAC,CAAA,CAAA;AAEpB,EAAA,iEAAU,QAAS,CAAA,CAAA;AACrB,CAAA;;ACWA,SAASC,cAAe,SAA6B,EAAA;AACnD,EAAA,OAAO,UAAuB,CAAA,CAAC,KAAO,EAAA,GAAA,qBACnC,KAAA,CAAA,aAAA,CAAA,qBAAA,EAAA;AAAA,IAAsB,+BAA+B,EAAA,IAAA;AAAA,GAAA,kBACnD,KAAA,CAAA,aAAA,CAAA,SAAA,EAAA;AAAA,IAAW,GAAG,KAAA;AAAA,IAAO,GAAA;AAAA,GAAU,CAClC,CACD,CAAA,CAAA;AACH,CAAA;AAsBO,MAAM,aACX,GAAAA,aAAA;AAAA,EACE,UAAA,CAAW,CAAC,KAAA,EAAO,GAAQ,KAAA;AACzB,IAAM,MAAA;AAAA,MACJ,QAAA;AAAA,MACA,YAAY,MAAM;AAAA,OAAC;AAAA,MACnB,UAAU,MAAM;AAAA,OAAC;AAAA,MACjB,WAAW,MAAM;AAAA,OAAC;AAAA,MAClB,YAAe,GAAA,GAAA;AAAA,MACf,WAAc,GAAA,IAAA;AAAA,MACd,SAAY,GAAA,IAAA;AAAA,MACZ,KAAO,EAAA,YAAA;AAAA,MACP,WAAa,EAAA,kBAAA;AAAA,MACb,UAAA,EAAY,oBAAoB,EAAC;AAAA,MACjC,YAAc,EAAA,mBAAA;AAAA,MACX,GAAA,IAAA;AAAA,KACD,GAAA,KAAA,CAAA;AAEJ,IAAM,MAAA,SAAA,GAAY,OAAO,YAAY,CAAA,CAAA;AACrC,IAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAiB,EAAE,CAAA,CAAA;AAE7C,IAAA,SAAA,CAAU,MAAM;AACd,MAAA,QAAA;AAAA,QAAS,CACP,SAAA,KAAA,SAAA,KAAc,YAAe,GAAA,MAAA,CAAO,YAAY,CAAI,GAAA,SAAA;AAAA,OACtD,CAAA;AAAA,KACF,EAAG,CAAC,YAAY,CAAC,CAAA,CAAA;AAEjB,IAAA,WAAA,CAAY,MAAM,QAAS,CAAA,KAAK,GAAG,YAAc,EAAA,CAAC,KAAK,CAAC,CAAA,CAAA;AAExD,IAAA,MAAM,YAAe,GAAA,WAAA;AAAA,MACnB,CAAC,CAAqC,KAAA;AACpC,QAAS,QAAA,CAAA,CAAA,CAAE,OAAO,KAAK,CAAA,CAAA;AAAA,OACzB;AAAA,MACA,CAAC,QAAQ,CAAA;AAAA,KACX,CAAA;AAEA,IAAA,MAAM,aAAgB,GAAA,WAAA;AAAA,MACpB,CAAC,CAAuC,KAAA;AACtC,QAAI,IAAA,SAAA;AAAW,UAAA,SAAA,CAAU,CAAC,CAAA,CAAA;AAC1B,QAAI,IAAA,QAAA,IAAY,CAAE,CAAA,GAAA,KAAQ,OAAS,EAAA;AACjC,UAAS,QAAA,EAAA,CAAA;AAAA,SACX;AAAA,OACF;AAAA,MACA,CAAC,WAAW,QAAQ,CAAA;AAAA,KACtB,CAAA;AAEA,IAAM,MAAA,WAAA,GAAc,YAAY,MAAM;AACpC,MAAA,QAAA,CAAS,EAAE,CAAA,CAAA;AACX,MAAA,IAAI,OAAS,EAAA;AACX,QAAQ,OAAA,EAAA,CAAA;AAAA,OACV;AAAA,KACC,EAAA,CAAC,QAAU,EAAA,OAAO,CAAC,CAAA,CAAA;AAEtB,IAAA,MAAM,cACJ,kBACA,IAAA,IAAA,GAAA,kBAAA,GAAA,CAAA,UAAA,EAAa,SAAU,CAAA,iBAAA,CAAkB,WAAW,CAAK,IAAA,WAAA,CAAA,CAAA,CAAA;AAE3D,IAAA,MAAM,iCACH,KAAA,CAAA,aAAA,CAAA,cAAA,EAAA;AAAA,MAAe,QAAS,EAAA,OAAA;AAAA,KAAA,kBACtB,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA;AAAA,MAAW,YAAW,EAAA,OAAA;AAAA,MAAQ,IAAK,EAAA,OAAA;AAAA,MAAQ,QAAQ,EAAA,IAAA;AAAA,KAClD,kBAAA,KAAA,CAAA,aAAA,CAAC,UAAW,EAAA,IAAA,CACd,CACF,CAAA,CAAA;AAGF,IAAA,MAAM,+BACH,KAAA,CAAA,aAAA,CAAA,cAAA,EAAA;AAAA,MAAe,QAAS,EAAA,KAAA;AAAA,KAAA,kBACtB,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA;AAAA,MAAW,YAAW,EAAA,OAAA;AAAA,MAAQ,IAAK,EAAA,OAAA;AAAA,MAAQ,OAAS,EAAA,WAAA;AAAA,KACnD,kBAAA,KAAA,CAAA,aAAA,CAAC,WAAY,EAAA,IAAA,CACf,CACF,CAAA,CAAA;AAGF,IACE,uBAAA,KAAA,CAAA,aAAA,CAAC,mCACE,KAAA,CAAA,aAAA,CAAA,SAAA,EAAA;AAAA,MACC,aAAY,EAAA,iBAAA;AAAA,MACZ,GAAA;AAAA,MACA,KAAA;AAAA,MACA,WAAA;AAAA,MACA,cAAA;AAAA,MACA,YAAA,EAAc,cAAc,YAAe,GAAA,mBAAA;AAAA,MAC3C,UAAY,EAAA,EAAE,YAAc,EAAA,QAAA,EAAU,GAAG,iBAAkB,EAAA;AAAA,MAC3D,SAAA;AAAA,MACA,QAAU,EAAA,YAAA;AAAA,MACV,SAAW,EAAA,aAAA;AAAA,MACV,GAAG,IAAA;AAAA,KACN,CACF,CAAA,CAAA;AAAA,GAEH,CAAA;AACH,EAAA;AAcK,MAAM,SAAuD,GAAAA,aAAA;AAAA,EAClE,UAAA,CAAW,CAAC,KAAA,EAAO,GAAQ,KAAA;AACzB,IAAA,MAAM,EAAE,KAAO,EAAA,YAAA,GAAe,EAAI,EAAA,QAAA,EAAA,GAAa,MAAS,GAAA,KAAA,CAAA;AAExD,IAAA,MAAM,EAAE,IAAA,EAAM,OAAQ,EAAA,GAAI,SAAU,EAAA,CAAA;AAEpC,IAAA,SAAA,CAAU,MAAM;AACd,MAAA,IAAI,YAAc,EAAA;AAChB,QAAQ,OAAA,CAAA,MAAA,CAAO,YAAY,CAAC,CAAA,CAAA;AAAA,OAC9B;AAAA,KACC,EAAA,CAAC,YAAc,EAAA,OAAO,CAAC,CAAA,CAAA;AAE1B,IAAA,MAAM,YAAe,GAAA,WAAA;AAAA,MACnB,CAAC,QAAqB,KAAA;AACpB,QAAA,IAAI,QAAU,EAAA;AACZ,UAAA,QAAA,CAAS,QAAQ,CAAA,CAAA;AAAA,SACZ,MAAA;AACL,UAAA,OAAA,CAAQ,QAAQ,CAAA,CAAA;AAAA,SAClB;AAAA,OACF;AAAA,MACA,CAAC,UAAU,OAAO,CAAA;AAAA,KACpB,CAAA;AAEA,IAAA,uBACG,KAAA,CAAA,aAAA,CAAA,gBAAA,EAAA;AAAA,MACC,UAAY,EAAA,EAAE,QAAU,EAAA,QAAA,EAAU,WAAW,WAAY,EAAA;AAAA,KAAA,kBAExD,KAAA,CAAA,aAAA,CAAA,aAAA,EAAA;AAAA,MACE,GAAG,IAAA;AAAA,MACJ,GAAA;AAAA,MACA,KAAO,EAAA,IAAA;AAAA,MACP,QAAU,EAAA,YAAA;AAAA,KACZ,CACF,CAAA,CAAA;AAAA,GAEH,CAAA;AACH;;AClKA,MAAM,WAAA,GAAc,CAClB,SACgC,KAAA;AAChC,EAAA,OAAO,2BACJ,KAAA,CAAA,aAAA,CAAA,qBAAA,EAAA;AAAA,IAAsB,+BAA+B,EAAA,IAAA;AAAA,GAAA,kBACnD,KAAA,CAAA,aAAA,CAAA,SAAA,EAAA;AAAA,IAAW,GAAG,KAAA;AAAA,GAAO,CACxB,CAAA,CAAA;AAEJ,CAAA,CAAA;AAOO,MAAM,kBAAqB,GAAA,WAAA;AAAA,EAChC,SAAS,4BACP,KACA,EAAA;AACA,IAAM,MAAA;AAAA,MACJ,OAAA;AAAA,MACA,KAAA;AAAA,MACA,WAAW,MAAM;AAAA,OAAC;AAAA,MAClB,UAAU,EAAC;AAAA,MACX,cAAiB,GAAA,CAAC,MAAmB,KAAA,MAAA,CAAO,MAAM,CAAA;AAAA,MAClD,gBAAA;AAAA,MACA,iBAAA;AAAA,MACA,QAAW,GAAA,IAAA;AAAA,MACX,SAAY,GAAA,IAAA;AAAA,MACZ,WAAc,GAAA,KAAA;AAAA,MACd,eAAe,UAAa,GAAA,qBAAA;AAAA,MACzB,GAAA,IAAA;AAAA,KACD,GAAA,KAAA,CAAA;AAEJ,IAAM,MAAA,EAAE,OAAQ,EAAA,GAAI,SAAU,EAAA,CAAA;AAE9B,IAAA,MAAM,aAAgB,GAAA,WAAA;AAAA,MACpB,CAAC,MAAoC,KAAA;AACnC,QAAA,IAAI,CAAC,MAAA;AAAQ,UAAO,OAAA,EAAA,CAAA;AACpB,QAAA,IAAI,OAAO,MAAW,KAAA,QAAA;AAAU,UAAO,OAAA,MAAA,CAAA;AACvC,QAAA,OAAO,eAAe,MAAM,CAAA,CAAA;AAAA,OAC9B;AAAA,MACA,CAAC,cAAc,CAAA;AAAA,KACjB,CAAA;AAEA,IAAA,MAAM,UAAa,GAAA,OAAA;AAAA,MACjB,MAAM,cAAc,KAAK,CAAA;AAAA,MACzB,CAAC,OAAO,aAAa,CAAA;AAAA,KACvB,CAAA;AAEA,IAAA,MAAM,YAAe,GAAA,WAAA;AAAA,MACnB,CACE,KAAA,EACA,MACA,EAAA,MAAA,EACA,OACG,KAAA;AACH,QAAQ,OAAA,CAAA,aAAA,CAAc,MAAM,CAAC,CAAA,CAAA;AAC7B,QAAS,QAAA,CAAA,KAAA,EAAO,MAAQ,EAAA,MAAA,EAAQ,OAAO,CAAA,CAAA;AAAA,OACzC;AAAA,MACA,CAAC,aAAe,EAAA,OAAA,EAAS,QAAQ,CAAA;AAAA,KACnC,CAAA;AAEA,IAAA,MAAM,WAAc,GAAA,WAAA;AAAA,MAClB,CAAC;AAAA,QACC,UAAA,EAAY,EAAE,GAAA,EAAK,YAAa,EAAA;AAAA,QAChC,eAAA;AAAA,QACG,GAAA,MAAA;AAAA,4BAEF,KAAA,CAAA,aAAA,CAAA,SAAA,EAAA;AAAA,QACE,GAAG,MAAA;AAAA,QACJ,GAAA;AAAA,QACA,WAAa,EAAA,KAAA;AAAA,QACb,KAAO,EAAA,UAAA;AAAA,QACP,WAAa,EAAA,gBAAA;AAAA,QACb,YAAc,EAAA,iBAAA;AAAA,QACd,YAAA,EACE,0BACG,KAAA,CAAA,aAAA,CAAA,gBAAA,EAAA;AAAA,UACC,aAAY,EAAA,iCAAA;AAAA,UACZ,KAAM,EAAA,SAAA;AAAA,UACN,IAAM,EAAA,EAAA;AAAA,SACR,CAEA,GAAA,YAAA;AAAA,OAGN,CAAA;AAAA,MAEF,CAAC,OAAA,EAAS,UAAY,EAAA,gBAAA,EAAkB,iBAAiB,CAAA;AAAA,KAC3D,CAAA;AAEA,IAAA,uBACG,KAAA,CAAA,aAAA,CAAA,YAAA,EAAA;AAAA,MACE,GAAG,IAAA;AAAA,MACJ,aAAa,EAAA,UAAA;AAAA,MACb,KAAA;AAAA,MACA,QAAU,EAAA,YAAA;AAAA,MACV,OAAA;AAAA,MACA,cAAA;AAAA,MACA,WAAA;AAAA,MACA,QAAA;AAAA,MACA,SAAA;AAAA,MACA,WAAA;AAAA,KACF,CAAA,CAAA;AAAA,GAEJ;AACF;;ACtHO,MAAM,kCAAkC,CAAC;AAAA,EAC9C,IAAA;AAAA,EACA,WAAA;AAAA,EACA,0BAAA;AAAA,EACA,aAAA;AAAA,EACA,4BAAA;AAAA,EACA,qBAAA;AACF,CAAA,+DAEK,IAAO,mBAAA,KAAA,CAAA,aAAA,CAAC,oBAAc,IAAK,CAAA,GAAkB,sBAC7C,KAAA,CAAA,aAAA,CAAA,YAAA,EAAA;AAAA,EACC,OAAS,EAAA,WAAA;AAAA,EACT,sBAAwB,EAAA,0BAAA;AAAA,EACxB,SAAW,EAAA,aAAA;AAAA,EACX,wBAA0B,EAAA,4BAAA;AAAA,EAC1B,iBAAmB,EAAA,qBAAA;AAAA,CACrB,CACF;;AC/BW,MAAA,oBAAA,GAAuB,CAClC,EACA,EAAA,UAAA,EACA,gBAA0B,EAAC,EAC3B,WAAmB,GAChB,KAAA;AACH,EAAM,MAAA,UAAA,GAAa,MAAqD,CAAA,EAAE,CAAA,CAAA;AAC1E,EAAA,MAAM,aAAa,EAAO,KAAA,MAAM,OAAQ,CAAA,OAAA,CAAQ,EAAE,CAAA,CAAA,CAAA;AAElD,EAAM,MAAA,CAAC,OAAO,QAAQ,CAAA,GAAI,WAAW,UAAY,EAAA,CAAC,UAAU,CAAG,EAAA;AAAA,IAC7D,OAAS,EAAA,IAAA;AAAA,GACV,CAAA,CAAA;AAGD,EAAA,WAAA;AAAA,IACE,MAAM;AAGJ,MAAI,IAAA,UAAA,CAAW,OAAQ,CAAA,UAAA,CAAA,KAAgB,KAAW,CAAA,EAAA;AAChD,QAAA,UAAA,CAAW,QAAQ,UAAc,CAAA,GAAA,QAAA,CAAS,UAAU,CAAA,CAAE,KAAK,CAAU,MAAA,KAAA;AAEnE,UAAA,UAAA,CAAW,QAAQ,UAAc,CAAA,GAAA,MAAA,CAAA;AACjC,UAAO,OAAA,MAAA,CAAA;AAAA,SACR,CAAA,CAAA;AAAA,OACH;AAAA,KACF;AAAA,IACA,QAAA;AAAA,IACA,CAAC,UAAU,UAAU,CAAA;AAAA,GACvB,CAAA;AAGA,EAAA,IAAI,cAAc,MAAQ,EAAA;AACxB,IAAO,OAAA;AAAA,MACL,OAAS,EAAA,KAAA;AAAA,MACT,KAAO,EAAA,aAAA;AAAA,KACT,CAAA;AAAA,GACF;AAGA,EAAM,MAAA,aAAA,GAAgB,WAAW,OAAQ,CAAA,UAAA,CAAA,CAAA;AACzC,EAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,aAAa,CAAG,EAAA;AAChC,IAAO,OAAA;AAAA,MACL,OAAS,EAAA,KAAA;AAAA,MACT,KAAO,EAAA,aAAA;AAAA,KACT,CAAA;AAAA,GACF;AAEA,EAAO,OAAA,KAAA,CAAA;AACT,CAAA,CAAA;AAOa,MAAA,qBAAA,GAAwB,CACnC,IAAA,EACA,YACG,KAAA;AACH,EAAM,MAAA,EAAE,UAAW,EAAA,GAAI,SAAU,EAAA,CAAA;AAEjC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,gBAAgB,CAAC,YAAY,EAAE,IAAK,EAAA,CAAE,SAAS,CAAG,EAAA;AACpD,MAAA,UAAA,CAAW,CAAgB,WAAA,MAAA;AAAA,QACzB,GAAG,WAAA;AAAA,QACH,CAAC,IAAO,GAAA,YAAA;AAAA,OACR,CAAA,CAAA,CAAA;AAAA,KACJ;AAAA,GAEF,EAAG,EAAE,CAAA,CAAA;AACP,CAAA;;AC1Da,MAAA,kBAAA,GAAqB,CAAC,KAAyC,KAAA;AAC1E,EAAM,MAAA;AAAA,IACJ,SAAA;AAAA,IACA,YAAA;AAAA,IACA,IAAA;AAAA,IACA,MAAQ,EAAA,WAAA;AAAA,IACR,gBAAA;AAAA,IACA,KAAA;AAAA,IACA,qBAAA;AAAA,IACA,SAAA;AAAA,IACA,QAAA;AAAA,GACE,GAAA,KAAA,CAAA;AACJ,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,SAAiB,EAAE,CAAA,CAAA;AACvD,EAAA,qBAAA,CAAsB,MAAM,YAAY,CAAA,CAAA;AACxC,EAAA,MAAM,WACJ,GAAA,OAAO,WAAgB,KAAA,UAAA,GAAa,WAAc,GAAA,KAAA,CAAA,CAAA;AACpD,EAAA,MAAM,aACJ,GAAA,OAAO,WAAgB,KAAA,UAAA,GAAa,KAAY,CAAA,GAAA,WAAA,CAAA;AAClD,EAAA,MAAM,EAAE,KAAA,EAAO,MAAQ,EAAA,OAAA,EAAY,GAAA,oBAAA;AAAA,IACjC,WAAA;AAAA,IACA,UAAA;AAAA,IACA,aAAA;AAAA,IACA,gBAAA;AAAA,GACF,CAAA;AACA,EAAA,MAAM,EAAE,OAAA,EAAS,UAAW,EAAA,GAAI,SAAU,EAAA,CAAA;AAC1C,EAAA,MAAM,WACH,GAAA,OAAA,CAAQ,IAA4C,CAAA,KAAA,QAAA,GAAW,EAAK,GAAA,IAAA,CAAA,CAAA;AAGvE,EAAM,MAAA,YAAA,GAAe,CACnB,CAAA,EACA,QACG,KAAA;AACH,IAAA,UAAA,CAAW,CAAa,SAAA,KAAA;AACtB,MAAA,MAAM,EAAG,CAAA,IAAA,GAAO,MAAW,EAAA,GAAA,MAAA,EAAW,GAAA,SAAA,CAAA;AAEtC,MAAA,IAAI,QAAU,EAAA;AACZ,QAAA,OAAO,EAAE,GAAG,MAAQ,EAAA,CAAC,OAAO,QAAS,EAAA,CAAA;AAAA,OACvC;AACA,MAAO,OAAA,EAAE,GAAG,MAAO,EAAA,CAAA;AAAA,KACpB,CAAA,CAAA;AAAA,GACH,CAAA;AAGA,EAAM,MAAA,WAAA,GAAc,CAAC,MAAA,qBAClB,KAAA,CAAA,aAAA,CAAA,SAAA,EAAA;AAAA,IACE,GAAG,MAAA;AAAA,IACJ,IAAK,EAAA,QAAA;AAAA,IACL,OAAQ,EAAA,UAAA;AAAA,IACR,KAAA;AAAA,IACA,SAAS,EAAA,IAAA;AAAA,GACX,CAAA,CAAA;AAIF,EAAM,MAAA,UAAA,GAAa,CACjB,QACA,EAAA,WAAA,KAEA,SAAS,GAAI,CAAA,CAAC,MAAgB,EAAA,KAAA,qBAC3B,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA;AAAA,IAAK,KAAO,EAAA,MAAA;AAAA,IAAQ,KAAM,EAAA,SAAA;AAAA,IAAW,GAAG,WAAA,CAAY,EAAE,KAAA,EAAO,CAAA;AAAA,GAAG,CAClE,CAAA,CAAA;AAEH,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,YAAA,EAAA;AAAA,IACC,qBAAA;AAAA,IACA,SAAA;AAAA,IACA,QAAA;AAAA,IACA,SAAA;AAAA,IACA,EAAI,EAAA,CAAA,EAAG,QAAW,GAAA,QAAA,GAAW,EAAmB,CAAA,cAAA,EAAA,IAAA,CAAA,QAAA,CAAA;AAAA,IAChD,OAAA,EAAS,UAAU,EAAC;AAAA,IACpB,OAAA;AAAA,IACA,KAAO,EAAA,WAAA;AAAA,IACP,QAAU,EAAA,YAAA;AAAA,IACV,aAAe,EAAA,CAAC,CAAG,EAAA,QAAA,KAAa,cAAc,QAAQ,CAAA;AAAA,IACtD,WAAA;AAAA,IACA,UAAA;AAAA,GACF,CAAA,CAAA;AAEJ;;ACpFA,MAAMF,cAAY,UAAW,CAAA;AAAA,EAC3B,KAAO,EAAA;AAAA,IACL,aAAe,EAAA,YAAA;AAAA,GACjB;AACF,CAAC,CAAA,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,gBAAA;AAAA,GACE,GAAA,KAAA,CAAA;AACJ,EAAA,MAAM,UAAUA,WAAU,EAAA,CAAA;AAC1B,EAAA,MAAM,EAAE,OAAA,EAAS,UAAW,EAAA,GAAI,SAAU,EAAA,CAAA;AAC1C,EAAA,qBAAA,CAAsB,MAAM,YAAY,CAAA,CAAA;AACxC,EAAA,MAAM,WACJ,GAAA,OAAO,WAAgB,KAAA,UAAA,GAAa,WAAc,GAAA,KAAA,CAAA,CAAA;AACpD,EAAA,MAAM,aACJ,GAAA,OAAO,WAAgB,KAAA,UAAA,GAAa,KAAY,CAAA,GAAA,WAAA,CAAA;AAClD,EAAA,MAAM,EAAE,KAAO,EAAA,MAAA,GAAS,EAAC,EAAG,SAAY,GAAA,oBAAA;AAAA,IACtC,WAAA;AAAA,IACA,EAAA;AAAA,IACA,aAAA;AAAA,IACA,gBAAA;AAAA,GACF,CAAA;AAEA,EAAM,MAAA,YAAA,GAAe,CAAC,CAAqC,KAAA;AACzD,IAAM,MAAA;AAAA,MACJ,MAAA,EAAQ,EAAE,KAAA,EAAO,OAAQ,EAAA;AAAA,KACvB,GAAA,CAAA,CAAA;AAEJ,IAAA,UAAA,CAAW,CAAe,WAAA,KAAA;AACxB,MAAA,MAAM,EAAG,CAAA,IAAA,GAAO,MAAW,EAAA,GAAA,MAAA,EAAW,GAAA,WAAA,CAAA;AACtC,MAAA,MAAM,QAAS,MAAuB,IAAA,IAAI,MAAO,CAAA,CAAA,CAAA,KAAK,MAAM,KAAK,CAAA,CAAA;AACjE,MAAA,MAAM,QAAQ,OAAU,GAAA,CAAC,GAAG,IAAA,EAAM,KAAK,CAAI,GAAA,IAAA,CAAA;AAC3C,MAAO,OAAA,KAAA,CAAM,SAAS,EAAE,GAAG,QAAQ,CAAC,IAAA,GAAO,OAAU,GAAA,MAAA,CAAA;AAAA,KACtD,CAAA,CAAA;AAAA,GACH,CAAA;AAEA,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,WAAA,EAAA;AAAA,IACC,SAAA;AAAA,IACA,QAAU,EAAA,OAAA;AAAA,IACV,SAAS,EAAA,IAAA;AAAA,IACT,aAAY,EAAA,4BAAA;AAAA,GAAA,EAEX,wBAAS,KAAA,CAAA,aAAA,CAAA,SAAA,EAAA;AAAA,IAAU,WAAW,OAAQ,CAAA,KAAA;AAAA,GAAA,EAAQ,KAAM,CAAe,GAAA,IAAA,EACnE,MAAO,CAAA,GAAA,CAAI,CAAC,KAAe,KAAA;AAtHlC,IAAA,IAAA,EAAA,CAAA;AAuHQ,IAAC,uBAAA,KAAA,CAAA,aAAA,CAAA,gBAAA,EAAA;AAAA,MACC,GAAK,EAAA,KAAA;AAAA,MACL,yBACG,KAAA,CAAA,aAAA,CAAA,QAAA,EAAA;AAAA,QACC,KAAM,EAAA,SAAA;AAAA,QACN,QAAU,EAAA,CAAA,CAAA;AAAA,QACV,UAAA,EAAY,EAAE,iBAAA,EAAmB,KAAM,EAAA;AAAA,QACvC,KAAA;AAAA,QACA,IAAM,EAAA,KAAA;AAAA,QACN,QAAU,EAAA,YAAA;AAAA,QACV,WAAW,EAAQ,GAAA,OAAA,CAAA,IAAA,CAAA,KAAR,YAA8B,EAAC,EAAG,SAAS,KAAK,CAAA;AAAA,OAC7D,CAAA;AAAA,MAEF,KAAO,EAAA,KAAA;AAAA,KACT,CAAA,CAAA;AAAA,GACD,CACH,CAAA,CAAA;AAEJ,EAAA;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,gBAAA;AAAA,GACE,GAAA,KAAA,CAAA;AACJ,EAAA,MAAM,UAAUA,WAAU,EAAA,CAAA;AAC1B,EAAA,qBAAA,CAAsB,MAAM,YAAY,CAAA,CAAA;AACxC,EAAA,MAAM,WACJ,GAAA,OAAO,WAAgB,KAAA,UAAA,GAAa,WAAc,GAAA,KAAA,CAAA,CAAA;AACpD,EAAA,MAAM,aACJ,GAAA,OAAO,WAAgB,KAAA,UAAA,GAAa,KAAY,CAAA,GAAA,WAAA,CAAA;AAClD,EAAA,MAAM,EAAE,KAAO,EAAA,MAAA,GAAS,EAAC,EAAG,SAAY,GAAA,oBAAA;AAAA,IACtC,WAAA;AAAA,IACA,EAAA;AAAA,IACA,aAAA;AAAA,IACA,gBAAA;AAAA,GACF,CAAA;AACA,EAAA,MAAM,EAAE,OAAA,EAAS,UAAW,EAAA,GAAI,SAAU,EAAA,CAAA;AAE1C,EAAM,MAAA,YAAA,GAAe,CAAC,CAAuC,KAAA;AAC3D,IAAM,MAAA;AAAA,MACJ,MAAA,EAAQ,EAAE,KAAM,EAAA;AAAA,KACd,GAAA,CAAA,CAAA;AAEJ,IAAA,UAAA,CAAW,CAAe,WAAA,KAAA;AACxB,MAAA,MAAM,EAAG,CAAA,IAAA,GAAO,MAAW,EAAA,GAAA,MAAA,EAAW,GAAA,WAAA,CAAA;AACtC,MAAA,OAAO,QAAQ,EAAE,GAAG,QAAQ,CAAC,IAAA,GAAO,OAAoB,GAAA,MAAA,CAAA;AAAA,KACzD,CAAA,CAAA;AAAA,GACH,CAAA;AAEA,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,WAAA,EAAA;AAAA,IACC,QAAU,EAAA,OAAA;AAAA,IACV,SAAA;AAAA,IACA,OAAQ,EAAA,QAAA;AAAA,IACR,SAAS,EAAA,IAAA;AAAA,IACT,aAAY,EAAA,0BAAA;AAAA,GAAA,EAEX,wBACE,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA;AAAA,IAAW,WAAW,OAAQ,CAAA,KAAA;AAAA,IAAO,MAAO,EAAA,OAAA;AAAA,GAC1C,EAAA,KACH,CACE,GAAA,IAAA,kBACH,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,IACC,OAAQ,EAAA,UAAA;AAAA,IACR,KAAA,EAAO,QAAQ,IAAS,CAAA,IAAA,EAAA;AAAA,IACxB,QAAU,EAAA,YAAA;AAAA,GAAA,kBAET,KAAA,CAAA,aAAA,CAAA,QAAA,EAAA;AAAA,IAAS,KAAM,EAAA,EAAA;AAAA,GACd,kBAAA,KAAA,CAAA,aAAA,CAAC,YAAG,KAAG,CACT,GACC,MAAO,CAAA,GAAA,CAAI,CAAC,KAAA,qBACV,KAAA,CAAA,aAAA,CAAA,QAAA,EAAA;AAAA,IAAS,GAAK,EAAA,KAAA;AAAA,IAAO,KAAA;AAAA,GACnB,EAAA,KACH,CACD,CACH,CACF,CAAA,CAAA;AAEJ,EAAA;AAKA,MAAM,eAAe,CAAC;AAAA,EACpB,SAAW,EAAA,OAAA;AAAA,EACR,GAAA,KAAA;AACL,CAAA,qBAAiC,KAAA,CAAA,aAAA,CAAA,OAAA,EAAA;AAAA,EAAS,GAAG,KAAA;AAAA,CAAO,EAAA;AAEpD,YAAa,CAAA,QAAA,GAAW,CACtB,KAAA,qBAEI,KAAA,CAAA,aAAA,CAAA,YAAA,EAAA;AAAA,EAAc,GAAG,KAAA;AAAA,EAAO,SAAW,EAAA,cAAA;AAAA,CAAgB,CAAA,CAAA;AAEzD,YAAa,CAAA,MAAA,GAAS,CACpB,KAAA,qBAEI,KAAA,CAAA,aAAA,CAAA,YAAA,EAAA;AAAA,EAAc,GAAG,KAAA;AAAA,EAAO,SAAW,EAAA,YAAA;AAAA,CAAc,CAAA,CAAA;AASvD,YAAa,CAAA,YAAA,GAAe,CAAC,KAAA,qBAC1B,KAAA,CAAA,aAAA,CAAA,YAAA,EAAA;AAAA,EAAc,GAAG,KAAA;AAAA,EAAO,SAAW,EAAA,kBAAA;AAAA,CAAoB,CAAA;;AC5K7C,MAAA,mBAAA,GAAsB,CAAC,KAAoC,KAAA;AACtE,EAAM,MAAA,EAAE,UAAa,GAAA,KAAA,CAAA;AACrB,EAAA,MAAM,UAAU,SAAU,EAAA,CAAA;AAC1B,EAAA,MAAM,QAAQ,OAAQ,CAAA,MAAA,CAAA;AACtB,EAAA,OAAO,SAAS,KAAK,CAAA,CAAA;AACvB,EAAA;AA8Ba,MAAA,eAAA,GAAkB,CAAC,KAAgC,KAAA;AAC9D,EAAM,MAAA,EAAE,KAAO,EAAA,QAAA,EAAa,GAAA,KAAA,CAAA;AAC5B,EAAM,MAAA,SAAA,GAAY,OAAO,YAAY,CAAA,CAAA;AAErC,EAAA,MAAM,KAAQ,GAAA,QAAA;AAAA,IACZ,MAAG;AArGP,MAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,CAAA;AAsGM,MAAA,OAAA,SAAA,CAAU,KAAM,CAAA;AAAA,QACd,IAAA,EAAA,CAAM,EAAM,GAAA,KAAA,CAAA,IAAA,KAAN,IAAc,GAAA,EAAA,GAAA,EAAA;AAAA,QACpB,KAAO,EAAA,CAAA,EAAA,GAAA,KAAA,CAAM,KAAN,KAAA,IAAA,GAAA,EAAA,GAAe,EAAC;AAAA,QACvB,OAAS,EAAA,CAAA,EAAA,GAAA,KAAA,CAAM,OAAN,KAAA,IAAA,GAAA,EAAA,GAAiB,EAAC;AAAA,QAC3B,YAAY,KAAM,CAAA,UAAA;AAAA,OACnB,CAAA,CAAA;AAAA,KAAA;AAAA,IACH,CAAC,KAAK,CAAA;AAAA,GACR,CAAA;AAEA,EAAA,OAAO,SAAS,KAAK,CAAA,CAAA;AACvB,EAAA;AA+Ca,MAAA,iBAAA,GAAoB,CAAC,KAAkC,KAAA;AAClE,EAAM,MAAA,EAAE,KAAO,EAAA,QAAA,EAAa,GAAA,KAAA,CAAA;AAE5B,EAAA,OAAO,wBACJ,KAAA,CAAA,aAAA,CAAA,eAAA,EAAA;AAAA,IAAgB,KAAA;AAAA,GAAA,EAAe,QAAS,CAAA,mBAExC,KAAA,CAAA,aAAA,CAAA,mBAAA,EAAA,IAAA,EAAqB,QAAS,CAAA,CAAA;AAEnC,EAAA;AAgBa,MAAA,qBAAA,GAAwB,CAAC,KAA6B,KAAA;AACjE,EAAM,MAAA,EAAE,KAAO,EAAA,QAAA,EAAa,GAAA,KAAA,CAAA;AAE5B,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,iBAAA,EAAA;AAAA,IAAkB,KAAA;AAAA,GAAA,EAChB,CAAC,EAAE,OAAS,EAAA,KAAA,EAAO,OAAY,KAAA;AAC9B,IAAA,IAAI,OAAS,EAAA;AACX,MAAA,2CAAQ,QAAS,EAAA,IAAA,CAAA,CAAA;AAAA,KACnB;AAEA,IAAA,IAAI,KAAO,EAAA;AACT,MAAA,uBACG,KAAA,CAAA,aAAA,CAAA,kBAAA,EAAA;AAAA,QACC,KAAM,EAAA,iDAAA;AAAA,QACN,KAAA;AAAA,OACF,CAAA,CAAA;AAAA,KAEJ;AAEA,IAAI,IAAA,EAAC,KAAO,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,KAAA,CAAA,OAAA,CAAQ,MAAQ,CAAA,EAAA;AAC1B,MAAA,uBACG,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA;AAAA,QAAW,OAAQ,EAAA,MAAA;AAAA,QAAO,KAAM,EAAA,8BAAA;AAAA,OAA+B,CAAA,CAAA;AAAA,KAEpE;AAEA,IAAA,OAAO,SAAS,KAAK,CAAA,CAAA;AAAA,GAEzB,CAAA,CAAA;AAEJ,EAAA;AAOa,MAAA,YAAA,GAAe,CAAC,KAAA,qBAC1B,KAAA,CAAA,aAAA,CAAA,gBAAA,EAAA;AAAA,EACC,UAAY,EAAA;AAAA,IACV,QAAU,EAAA,QAAA;AAAA,IACV,SAAW,EAAA,cAAA;AAAA,GACb;AAAA,CAAA,kBAEC,KAAA,CAAA,aAAA,CAAA,qBAAA,EAAA;AAAA,EAAuB,GAAG,KAAA;AAAA,CAAO,CACpC;;AC3MF,MAAMA,WAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,IAAM,EAAA;AAAA,IACJ,OAAS,EAAA,MAAA;AAAA,IACT,cAAgB,EAAA,eAAA;AAAA,IAChB,GAAA,EAAK,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,IACpB,MAAQ,EAAA,KAAA,CAAM,OAAQ,CAAA,CAAA,EAAG,CAAC,CAAA;AAAA,GAC5B;AACF,CAAE,CAAA,CAAA,CAAA;AAKK,MAAM,oBAAoB,MAAM;AACrC,EAAA,MAAM,EAAE,aAAA,EAAe,iBAAkB,EAAA,GAAI,SAAU,EAAA,CAAA;AACvD,EAAA,MAAM,UAAUA,WAAU,EAAA,CAAA;AAE1B,EAAI,IAAA,CAAC,aAAiB,IAAA,CAAC,iBAAmB,EAAA;AACxC,IAAA,uBAAS,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,CAAA,CAAA;AAAA,GACX;AAEA,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA;AAAA,IAAI,YAAW,EAAA,uBAAA;AAAA,IAAwB,WAAW,OAAQ,CAAA,IAAA;AAAA,GAAA,kBACxD,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,IACC,YAAW,EAAA,eAAA;AAAA,IACX,UAAU,CAAC,iBAAA;AAAA,IACX,OAAS,EAAA,iBAAA;AAAA,IACT,SAAA,sCAAY,gBAAiB,EAAA,IAAA,CAAA;AAAA,GAC9B,EAAA,UAED,mBAEC,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,IACC,YAAW,EAAA,WAAA;AAAA,IACX,UAAU,CAAC,aAAA;AAAA,IACX,OAAS,EAAA,aAAA;AAAA,IACT,OAAA,sCAAU,mBAAoB,EAAA,IAAA,CAAA;AAAA,GAAA,EAC/B,MAED,CACF,CAAA,CAAA;AAEJ;;ACdO,MAAM,iCAAiC,CAAC;AAAA,EAC7C,MAAA;AAAA,EACA,SAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,eAAA;AAAA,EACA,SAAY,GAAA,CAAA;AACd,CAAkC,KAAA;AAChC,EAAA,MAAM,YAAY,YAAa,EAAA,CAAA;AAC/B,EAAA,MAAM,cAAc,MAAM;AACxB,IAAU,SAAA,CAAA,YAAA,CAAa,UAAY,EAAA,MAAA,CAAO,KAAO,EAAA;AAAA,MAC/C,UAAY,EAAA,EAAE,EAAI,EAAA,MAAA,CAAO,QAAS,EAAA;AAAA,MAClC,KAAO,EAAA,IAAA;AAAA,KACR,CAAA,CAAA;AAAA,GACH,CAAA;AAEA,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA;AAAA,IAAK,OAAO,EAAA,IAAA;AAAA,IAAC,IAAI,MAAO,CAAA,QAAA;AAAA,IAAU,OAAS,EAAA,WAAA;AAAA,GAAA,kBACzC,KAAA,CAAA,aAAA,CAAA,QAAA,EAAA;AAAA,IAAS,UAAW,EAAA,QAAA;AAAA,GAAA,EAClB,IAAQ,oBAAA,KAAA,CAAA,aAAA,CAAC,YAAc,EAAA,IAAA,EAAA,IAAK,mBAC5B,KAAA,CAAA,aAAA,CAAA,YAAA,EAAA;AAAA,IACC,sBAAA,EAAwB,EAAE,OAAA,EAAS,IAAK,EAAA;AAAA,IACxC,OACE,EAAA,CAAA,SAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,SAAA,CAAW,MAAO,CAAA,KAAA,oBACf,KAAA,CAAA,aAAA,CAAA,2BAAA,EAAA;AAAA,MACC,IAAA,EAAM,UAAU,MAAO,CAAA,KAAA;AAAA,MACvB,QAAQ,SAAU,CAAA,MAAA;AAAA,MAClB,SAAS,SAAU,CAAA,OAAA;AAAA,KACrB,IAEA,MAAO,CAAA,KAAA;AAAA,IAGX,2BACG,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,MACC,KAAO,EAAA;AAAA,QACL,OAAS,EAAA,aAAA;AAAA,QACT,eAAiB,EAAA,UAAA;AAAA,QACjB,eAAiB,EAAA,SAAA;AAAA,QACjB,QAAU,EAAA,QAAA;AAAA,OACZ;AAAA,KAEC,EAAA,CAAA,SAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,SAAA,CAAW,MAAO,CAAA,IAAA,oBAChB,KAAA,CAAA,aAAA,CAAA,2BAAA,EAAA;AAAA,MACC,IAAA,EAAM,UAAU,MAAO,CAAA,IAAA;AAAA,MACvB,QAAQ,SAAU,CAAA,MAAA;AAAA,MAClB,SAAS,SAAU,CAAA,OAAA;AAAA,KACrB,CAAA,GAEA,OAAO,IAEX,CAAA;AAAA,GAEJ,CAAA,EACC,mCAAoB,KAAA,CAAA,aAAA,CAAA,GAAA,EAAA;AAAA,IAAI,UAAW,EAAA,UAAA;AAAA,GAAA,EAAY,eAAgB,CAClE,CACA,kBAAA,KAAA,CAAA,aAAA,CAAC,aAAQ,CACX,CAAA,CAAA;AAEJ,CAAA,CAAA;AAKM,MAAA,gCAAA,GAAmC,CACvC,KACG,KAAA;AACH,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,gBAAA,EAAA;AAAA,IACC,UAAY,EAAA;AAAA,MACV,QAAU,EAAA,QAAA;AAAA,MACV,SAAW,EAAA,uBAAA;AAAA,KACb;AAAA,GAAA,kBAEC,KAAA,CAAA,aAAA,CAAA,8BAAA,EAAA;AAAA,IAAgC,GAAG,KAAA;AAAA,GAAO,CAC7C,CAAA,CAAA;AAEJ;;ACrEa,MAAA,sBAAA,GAAyB,CAAC,KAAuC,KAAA;AAC5E,EAAA,MAAM,EAAE,OAAS,EAAA,KAAA,EAAO,WAAa,EAAA,gBAAA,EAAA,GAAqB,MAAS,GAAA,KAAA,CAAA;AAEnE,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA;AAAA,IAAM,GAAG,IAAA;AAAA,GACP,EAAA,OAAA,uCAAW,QAAS,EAAA,IAAA,CAAA,GAAK,MACzB,CAAC,OAAA,IAAW,wBACV,KAAA,CAAA,aAAA,CAAA,kBAAA,EAAA;AAAA,IACC,KAAM,EAAA,iDAAA;AAAA,IACN,KAAA;AAAA,GACF,CAAA,GACE,IACH,EAAA,CAAC,OAAW,IAAA,CAAC,UAAS,WAAa,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,WAAA,CAAA,MAAA,CAAA,GAChC,WAAY,CAAA,GAAA,CAAI,CAAW,UAAA,KAAA;AAxErC,IAAA,IAAA,EAAA,CAAA;AAwEwC,IAAA,OAAA,CAAA,EAAA,GAAA,gBAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,gBAAA,CAAmB,gBAAnB,IAAkC,GAAA,EAAA,GAAA,IAAA,CAAA;AAAA,GAAI,CAAA,GACpE,MACH,CAAC,OAAA,IAAW,CAAC,KAAS,IAAA,EAAC,WAAa,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,WAAA,CAAA,MAAA,CAAA,mBAClC,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA;AAAA,IAAW,OAAQ,EAAA,MAAA;AAAA,IAAO,KAAM,EAAA,8BAAA;AAAA,GAA+B,IAC9D,IACN,CAAA,CAAA;AAEJ,EAAA;AAqBa,MAAA,gBAAA,GAAmB,CAAC,KAAiC,KAAA;AAChE,EAAM,MAAA;AAAA,IACJ,KAAA;AAAA,IACA,gBAAmB,GAAA,CAAC,EAAE,QAAA,uBACnB,KAAA,CAAA,aAAA,CAAAG,gCAAA,EAAA;AAAA,MAAsB,KAAK,QAAS,CAAA,QAAA;AAAA,MAAU,MAAQ,EAAA,QAAA;AAAA,KAAU,CAAA;AAAA,IAEhE,GAAA,IAAA;AAAA,GACD,GAAA,KAAA,CAAA;AAEJ,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,gBAAA,EAAA;AAAA,IACC,UAAY,EAAA;AAAA,MACV,QAAU,EAAA,QAAA;AAAA,MACV,SAAW,EAAA,kBAAA;AAAA,KACb;AAAA,GAAA,kBAEC,KAAA,CAAA,aAAA,CAAA,iBAAA,EAAA;AAAA,IAAkB,KAAA;AAAA,GAAA,EAChB,CAAC,EAAE,OAAA,EAAS,KAAO,EAAA,KAAA,uBACjB,KAAA,CAAA,aAAA,CAAA,sBAAA,EAAA;AAAA,IACE,GAAG,IAAA;AAAA,IACJ,OAAA;AAAA,IACA,KAAA;AAAA,IACA,aAAa,KAAO,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,KAAA,CAAA,OAAA;AAAA,IACpB,gBAAA;AAAA,GACF,CAEJ,CACF,CAAA,CAAA;AAEJ;;ACxEA,MAAM,SAAA,GAAY,UAAW,CAAA,CAAC,KAAkB,MAAA;AAAA,EAC9C,aAAe,EAAA;AAAA,IACb,OAAS,EAAA,MAAA;AAAA,IACT,UAAY,EAAA,QAAA;AAAA,GACd;AAAA,EACA,iBAAmB,EAAA;AAAA,IACjB,UAAA,EAAY,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,IAC3B,aAAe,EAAA,WAAA;AAAA,GACjB;AAAA,EACA,iBAAmB,EAAA;AAAA,IACjB,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,IAAK,CAAA,SAAA;AAAA,IAC1B,QAAQ,KAAM,CAAA,OAAA,CAAQ,CAAG,EAAA,CAAA,EAAG,GAAG,GAAG,CAAA;AAAA,GACpC;AAAA,EACA,mBAAqB,EAAA;AAAA,IACnB,OAAS,EAAA,MAAA;AAAA,IACT,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,IAAK,CAAA,SAAA;AAAA,IAC1B,QAAQ,KAAM,CAAA,OAAA,CAAQ,CAAG,EAAA,CAAA,EAAG,GAAG,GAAG,CAAA;AAAA,GACpC;AAAA,EACA,iBAAmB,EAAA;AAAA,IACjB,UAAY,EAAA,MAAA;AAAA,IACZ,OAAS,EAAA,MAAA;AAAA,IACT,UAAY,EAAA,QAAA;AAAA,GACd;AAAA,EACA,qBAAuB,EAAA;AAAA,IACrB,QAAU,EAAA,SAAA;AAAA,IACV,UAAA,EAAY,KAAM,CAAA,OAAA,CAAQ,GAAG,CAAA;AAAA,GAC/B;AACF,CAAE,CAAA,CAAA,CAAA;AAiBW,MAAA,kCAAA,GAAqC,CAChD,KACG,KAAA;AACH,EAAA,MAAM,UAAU,SAAU,EAAA,CAAA;AAC1B,EAAA,MAAM,EAAE,KAAA,EAAO,QAAa,EAAA,GAAA,IAAA,EAAS,GAAA,KAAA,CAAA;AAErC,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA;AAAA,IACE,GAAG,IAAA;AAAA,IACJ,WAAW,OAAQ,CAAA,mBAAA;AAAA,IACnB,OAAQ,EAAA,UAAA;AAAA,IACR,KACE,kBAAA,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,EACG,KAAM,EAAA,IAAA,EAAG,QACZ,CAAA;AAAA,GAEJ,CAAA,CAAA;AAEJ,EAAA;AAEA,MAAM,WAAW,MAAM,IAAA,CAAA;AAWvB,MAAM,oCAAA,GAAuC,UAAW,CAAA,CAAC,KAAkB,MAAA;AAAA,EACzE,IAAM,EAAA;AAAA,IACJ,QAAU,EAAA,SAAA;AAAA,IACV,SAAW,EAAA;AAAA,MACT,OAAS,EAAA,MAAA;AAAA,MACT,UAAA,EAAY,KAAM,CAAA,OAAA,CAAQ,MAAO,CAAA,KAAA;AAAA,KACnC;AAAA,IACA,eAAiB,EAAA;AAAA,MACf,MAAQ,EAAA,SAAA;AAAA,MACR,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,OAAQ,CAAA,IAAA;AAAA,MAC7B,SAAW,EAAA;AAAA,QACT,cAAgB,EAAA,WAAA;AAAA,OAClB;AAAA,KACF;AAAA,GACF;AACF,CAAE,CAAA,CAAA,CAAA;AAwBW,MAAA,gCAAA,GAAmC,CAC9C,KACG,KAAA;AACH,EAAA,MAAM,UAAU,oCAAqC,EAAA,CAAA;AACrD,EAAA,MAAM,EAAE,KAAO,EAAA,KAAA,GAAQ,MAAQ,EAAA,QAAA,EAAU,UAAa,GAAA,KAAA,CAAA;AAEtD,EAAA,MAAM,YAAe,GAAA,WAAA;AAAA,IACnB,CAAC,CAAqC,KAAA;AACpC,MAAS,QAAA,CAAA,CAAA,CAAE,OAAO,KAAK,CAAA,CAAA;AAAA,KACzB;AAAA,IACA,CAAC,QAAQ,CAAA;AAAA,GACX,CAAA;AAEA,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,kCAAA,EAAA;AAAA,IAAmC,KAAA;AAAA,IAAc,QAAA;AAAA,GAAA,kBAC/C,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA;AAAA,IACC,IAAK,EAAA,SAAA;AAAA,IACL,SAAU,EAAA,MAAA;AAAA,IACV,WAAW,OAAQ,CAAA,IAAA;AAAA,IACnB,QAAU,EAAA,YAAA;AAAA,IACV,eAAe,EAAA,IAAA;AAAA,IACf,8BAA8B,EAAA,IAAA;AAAA,GAAA,EAE7B,KACH,CACF,CAAA,CAAA;AAEJ,EAAA;AAEA,MAAM,sCAAA,GAAyC,UAAW,CAAA,CAAC,KAAkB,MAAA;AAAA,EAC3E,IAAM,EAAA;AAAA,IACJ,QAAU,EAAA,SAAA;AAAA,IACV,eAAiB,EAAA;AAAA,MACf,MAAQ,EAAA,SAAA;AAAA,MACR,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,OAAQ,CAAA,IAAA;AAAA,MAC7B,SAAW,EAAA;AAAA,QACT,cAAgB,EAAA,WAAA;AAAA,OAClB;AAAA,KACF;AAAA,IACA,SAAW,EAAA;AAAA,MACT,OAAS,EAAA,MAAA;AAAA,KACX;AAAA,IACA,mBAAqB,EAAA;AAAA,MACnB,OAAS,EAAA,CAAA;AAAA,KACX;AAAA,GACF;AACF,CAAE,CAAA,CAAA,CAAA;AA6BW,MAAA,kCAAA,GAAqC,CAChD,KACG,KAAA;AACH,EAAA,MAAM,UAAU,sCAAuC,EAAA,CAAA;AACvD,EAAA,MAAM,EAAE,KAAO,EAAA,KAAA,GAAQ,QAAQ,QAAU,EAAA,QAAA,EAAU,UAAa,GAAA,KAAA,CAAA;AAEhE,EAAA,MAAM,YAAe,GAAA,WAAA;AAAA,IACnB,CAAC,CAAuC,KAAA;AACtC,MAAS,QAAA,CAAA,CAAA,CAAE,OAAO,KAAkB,CAAA,CAAA;AAAA,KACtC;AAAA,IACA,CAAC,QAAQ,CAAA;AAAA,GACX,CAAA;AAEA,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,kCAAA,EAAA;AAAA,IAAmC,KAAA;AAAA,IAAc,QAAA;AAAA,GAAA,kBAC/C,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,IACC,WAAW,OAAQ,CAAA,IAAA;AAAA,IACnB,KAAA;AAAA,IACA,QAAU,EAAA,YAAA;AAAA,IACV,KAAA,sCAAQ,SAAU,EAAA,IAAA,CAAA;AAAA,IAClB,aAAe,EAAA,QAAA;AAAA,GAAA,kBAEd,KAAA,CAAA,aAAA,CAAA,QAAA,EAAA;AAAA,IAAS,KAAM,EAAA,MAAA;AAAA,GAAO,EAAA,MAAI,CAC1B,EAAA,QACH,CACF,CAAA,CAAA;AAEJ,EAAA;AAmEO,SAAS,wBACd,KACA,EAAA;AACA,EAAA,MAAM,UAAU,SAAU,EAAA,CAAA;AAC1B,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAA6B,IAAI,CAAA,CAAA;AAEjE,EAAM,MAAA;AAAA,IACJ,OAAA;AAAA,IACA,KAAA;AAAA,IACA,IAAA;AAAA,IACA,KAAA;AAAA,IACA,aAAa,EAAC;AAAA,IACd,IAAA;AAAA,IACA,YAAY,EAAC;AAAA,IACb,aAAA;AAAA,IACA,kBAAA;AAAA,IACA,YAAA;AAAA,IACA,iBAAA;AAAA,IACA,WAAA;AAAA,IACA,gBAAA;AAAA,IACG,GAAA,IAAA;AAAA,GACD,GAAA,KAAA,CAAA;AAEJ,EAAM,MAAA,WAAA,GAAc,WAAY,CAAA,CAAC,CAA2C,KAAA;AAC1E,IAAA,WAAA,CAAY,EAAE,aAAa,CAAA,CAAA;AAAA,GAC7B,EAAG,EAAE,CAAA,CAAA;AAEL,EAAM,MAAA,WAAA,GAAc,YAAY,MAAM;AACpC,IAAA,WAAA,CAAY,IAAI,CAAA,CAAA;AAAA,GAClB,EAAG,EAAE,CAAA,CAAA;AAEL,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA;AAAA,IAAM,GAAG,IAAA;AAAA,GAAA,kBACP,KAAA,CAAA,aAAA,CAAA,aAAA,EAAA;AAAA,IAAc,WAAW,OAAQ,CAAA,aAAA;AAAA,GAAA,EAC/B,sBACA,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA;AAAA,IACC,WAAW,OAAQ,CAAA,iBAAA;AAAA,IACnB,SAAU,EAAA,QAAA;AAAA,IACT,GAAG,UAAA;AAAA,GAEH,EAAA,KACH,CACC,EAAA,aAAA,mBACE,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA;AAAA,IACC,WAAW,OAAQ,CAAA,iBAAA;AAAA,IACnB,SAAU,EAAA,QAAA;AAAA,IACV,IAAA,sCAAO,OAAQ,EAAA,IAAA,CAAA;AAAA,IACf,OAAQ,EAAA,UAAA;AAAA,IACR,KAAM,EAAA,YAAA;AAAA,IACN,eAAc,EAAA,cAAA;AAAA,IACd,eAAc,EAAA,MAAA;AAAA,IACd,OAAS,EAAA,WAAA;AAAA,GACX,CAAA,GACE,IACH,EAAA,aAAA,mBACE,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA;AAAA,IACC,EAAG,EAAA,cAAA;AAAA,IACH,QAAA;AAAA,IACA,IAAA,EAAM,QAAQ,QAAQ,CAAA;AAAA,IACtB,OAAS,EAAA,WAAA;AAAA,IACT,OAAS,EAAA,WAAA;AAAA,IACT,WAAW,EAAA,IAAA;AAAA,GAAA,EAEV,aAAc,CAAA,GAAA;AAAA,IAAI,CACjB,YAAA,KAAA,kBAAA,GACE,kBAAmB,CAAA,YAAY,oBAE9B,KAAA,CAAA,aAAA,CAAA,QAAA,EAAA;AAAA,MACC,GAAA,EAAK,OAAO,YAAY,CAAA;AAAA,MACxB,KAAA,EAAO,OAAO,YAAY,CAAA;AAAA,KAAA,EAEzB,YACH,CAAA;AAAA,GAGN,CACE,GAAA,IAAA,EACH,YAAc,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,YAAA,CAAA,GAAA;AAAA,IACb,CAAY,WAAA,KAAA;AAlatB,MAAA,IAAA,EAAA,CAAA;AAkayB,MAAA,OAAA,CAAA,EAAA,GAAA,iBAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,iBAAA,CAAoB,iBAApB,IAAoC,GAAA,EAAA,GAAA,IAAA,CAAA;AAAA,KAAA;AAAA,GAAA,kBAEpD,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA;AAAA,IAAK,WAAW,OAAQ,CAAA,iBAAA;AAAA,IAAmB,EAAG,EAAA,SAAA;AAAA,IAAW,GAAG,SAAA;AAAA,GAC1D,EAAA,IAAA,IAAA,IAAA,GAAA,IAAA,mBACG,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,EAAA,SAAA,kBAEC,KAAA,CAAA,aAAA,CAAAC,mBAAA,EAAA;AAAA,IAAe,WAAW,OAAQ,CAAA,qBAAA;AAAA,GAAuB,CAC5D,CAEJ,CACF,CAAA,EACC,OAAU,mBAAA,KAAA,CAAA,aAAA,CAAC,QAAS,EAAA,IAAA,CAAA,GAAK,IACzB,EAAA,CAAC,OAAW,IAAA,KAAA,mBACV,KAAA,CAAA,aAAA,CAAA,kBAAA,EAAA;AAAA,IACC,KAAM,EAAA,iDAAA;AAAA,IACN,KAAA;AAAA,GACF,CAAA,GACE,IACH,EAAA,CAAC,OAAW,IAAA,CAAC,UAAS,WAAa,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,WAAA,CAAA,MAAA,CAAA,GAChC,WAAY,CAAA,GAAA,CAAI,CAAW,UAAA,KAAA;AArbrC,IAAA,IAAA,EAAA,CAAA;AAqbwC,IAAA,OAAA,CAAA,EAAA,GAAA,gBAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,gBAAA,CAAmB,gBAAnB,IAAkC,GAAA,EAAA,GAAA,IAAA,CAAA;AAAA,GAAI,CAAA,GACpE,IACH,EAAA,CAAC,OAAW,IAAA,CAAC,KAAS,IAAA,EAAC,WAAa,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,WAAA,CAAA,MAAA,CAAA,mBAClC,KAAA,CAAA,aAAA,CAAA,QAAA,EAAA,IAAA,kBACE,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA;AAAA,IAAW,OAAQ,EAAA,MAAA;AAAA,IAAO,KAAM,EAAA,8BAAA;AAAA,GAA+B,CAClE,IACE,IACN,CAAA,CAAA;AAEJ,CAAA;AAqBO,SAAS,kBACd,KACA,EAAA;AACA,EAAM,MAAA;AAAA,IACJ,KAAA;AAAA,IACA,YAAY,EAAC;AAAA,IACb,gBAAmB,GAAA,CAAC,EAAE,QAAA,uBACnB,KAAA,CAAA,aAAA,CAAAD,gCAAA,EAAA;AAAA,MAAsB,KAAK,QAAS,CAAA,QAAA;AAAA,MAAU,MAAQ,EAAA,QAAA;AAAA,KAAU,CAAA;AAAA,IAEhE,GAAA,IAAA;AAAA,GACD,GAAA,KAAA,CAAA;AAEJ,EAAM,MAAA,EAAA,GAAK,WAAW,EAAG,CAAA,SAAA;AAAA,IACvB;AAAA,MACE,OAAO,KAAM,CAAA,IAAA;AAAA,MACb,OAAO,KAAM,CAAA,KAAA;AAAA,MACb,SAAS,KAAM,CAAA,OAAA;AAAA,MACf,YAAY,KAAM,CAAA,UAAA;AAAA,KACpB;AAAA,IACA,EAAE,aAAa,UAAW,EAAA;AAAA,GAC5B,CAAA,CAAA,CAAA;AAEA,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,gBAAA,EAAA;AAAA,IACC,UAAY,EAAA;AAAA,MACV,QAAU,EAAA,QAAA;AAAA,MACV,SAAW,EAAA,mBAAA;AAAA,KACb;AAAA,GAAA,kBAEC,KAAA,CAAA,aAAA,CAAA,iBAAA,EAAA;AAAA,IAAkB,KAAA;AAAA,GAAA,EAChB,CAAC,EAAE,OAAS,EAAA,KAAA,EAAO,OAAS,KAAA;AAjfrC,IAAA,IAAA,EAAA,CAAA;AAkfU,IAAC,uBAAA,KAAA,CAAA,aAAA,CAAA,uBAAA,EAAA;AAAA,MACE,GAAG,IAAA;AAAA,MACJ,OAAA;AAAA,MACA,KAAA;AAAA,MACA,SAAW,EAAA,EAAE,EAAI,EAAA,GAAG,SAAU,EAAA;AAAA,MAC9B,aAAa,KAAO,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,KAAA,CAAA,OAAA;AAAA,MACpB,gBAAA;AAAA,MACA,cAAc,MAAO,CAAA,IAAA,CAAA,CAAK,WAAM,OAAN,KAAA,IAAA,GAAA,EAAA,GAAiB,EAAE,CAAA;AAAA,KAC/C,CAAA,CAAA;AAAA,GAEJ,CACF,CAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"index.esm.js","sources":["../src/api.ts","../src/components/HighlightedSearchResultText/HighlightedSearchResultText.tsx","../src/context/SearchContext.tsx","../src/components/SearchTracker/SearchTracker.tsx","../src/components/SearchBar/SearchBar.tsx","../src/components/SearchAutocomplete/SearchAutocomplete.tsx","../src/components/SearchAutocomplete/SearchAutocompleteDefaultOption.tsx","../src/components/SearchFilter/hooks.ts","../src/components/SearchFilter/SearchFilter.Autocomplete.tsx","../src/components/SearchFilter/SearchFilter.tsx","../src/components/SearchResult/SearchResult.tsx","../src/components/SearchResultPager/SearchResultPager.tsx","../src/components/DefaultResultListItem/DefaultResultListItem.tsx","../src/components/SearchResultList/SearchResultList.tsx","../src/components/SearchResultGroup/SearchResultGroup.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 { SearchQuery, SearchResultSet } from '@backstage/plugin-search-common';\nimport { createApiRef } from '@backstage/core-plugin-api';\n\n/**\n * @public\n */\nexport const searchApiRef = createApiRef<SearchApi>({\n id: 'plugin.search.queryservice',\n});\n\n/**\n * @public\n */\nexport interface SearchApi {\n query(query: SearchQuery): Promise<SearchResultSet>;\n}\n\n/**\n * @public\n *\n * Search Api Mock that can be used in tests and storybooks\n */\nexport class MockSearchApi implements SearchApi {\n constructor(public mockedResults?: SearchResultSet) {}\n\n query(): Promise<SearchResultSet> {\n return Promise.resolve(this.mockedResults || { results: [] });\n }\n}\n","/*\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, { useMemo } from 'react';\nimport { makeStyles } from '@material-ui/core';\n\nconst useStyles = makeStyles(\n () => ({\n highlight: {},\n }),\n { name: 'BackstageHighlightedSearchResultText' },\n);\n\n/**\n * Props for {@link HighlightedSearchResultText}.\n *\n * @public\n */\nexport type HighlightedSearchResultTextProps = {\n text: string;\n preTag: string;\n postTag: string;\n};\n\n/**\n * @public\n */\nexport const HighlightedSearchResultText = ({\n text,\n preTag,\n postTag,\n}: HighlightedSearchResultTextProps) => {\n const classes = useStyles();\n const terms = useMemo(\n () => text.split(new RegExp(`(${preTag}.+?${postTag})`)),\n [postTag, preTag, text],\n );\n return (\n <>\n {terms.map((t, idx) =>\n t.includes(preTag) ? (\n <mark className={classes.highlight} key={idx}>\n {t.replace(new RegExp(`${preTag}|${postTag}`, 'g'), '')}\n </mark>\n ) : (\n t\n ),\n )}\n </>\n );\n};\n","/*\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 { isEqual } from 'lodash';\nimport React, {\n PropsWithChildren,\n useCallback,\n useContext,\n useEffect,\n useState,\n} from 'react';\nimport useAsync, { AsyncState } from 'react-use/lib/useAsync';\nimport usePrevious from 'react-use/lib/usePrevious';\n\nimport {\n createVersionedContext,\n createVersionedValueMap,\n} from '@backstage/version-bridge';\nimport { JsonObject } from '@backstage/types';\nimport { AnalyticsContext, useApi } from '@backstage/core-plugin-api';\nimport { SearchResultSet } from '@backstage/plugin-search-common';\n\nimport { searchApiRef } from '../api';\n\n/**\n *\n * @public\n */\nexport type SearchContextValue = {\n result: AsyncState<SearchResultSet>;\n setTerm: React.Dispatch<React.SetStateAction<string>>;\n setTypes: React.Dispatch<React.SetStateAction<string[]>>;\n setFilters: React.Dispatch<React.SetStateAction<JsonObject>>;\n setPageLimit: React.Dispatch<React.SetStateAction<number | undefined>>;\n setPageCursor: React.Dispatch<React.SetStateAction<string | undefined>>;\n fetchNextPage?: React.DispatchWithoutAction;\n fetchPreviousPage?: React.DispatchWithoutAction;\n} & SearchContextState;\n\n/**\n *\n * @public\n */\nexport type SearchContextState = {\n term: string;\n types: string[];\n filters: JsonObject;\n pageLimit?: number;\n pageCursor?: string;\n};\n\nconst SearchContext = createVersionedContext<{\n 1: SearchContextValue;\n}>('search-context');\n\n/**\n * @public\n *\n * React hook which provides the search context\n */\nexport const useSearch = () => {\n const context = useContext(SearchContext);\n if (!context) {\n throw new Error('useSearch must be used within a SearchContextProvider');\n }\n\n const value = context.atVersion(1);\n if (!value) {\n throw new Error('No SearchContext v1 found');\n }\n return value;\n};\n\n/**\n * @public\n *\n * React hook which checks for an existing search context\n */\nexport const useSearchContextCheck = () => {\n const context = useContext(SearchContext);\n return context !== undefined;\n};\n\n/**\n * The initial state of `SearchContextProvider`.\n *\n */\nconst searchInitialState: SearchContextState = {\n term: '',\n types: [],\n filters: {},\n pageLimit: undefined,\n pageCursor: undefined,\n};\n\nconst useSearchContextValue = (\n initialValue: SearchContextState = searchInitialState,\n) => {\n const searchApi = useApi(searchApiRef);\n\n const [term, setTerm] = useState<string>(initialValue.term);\n const [types, setTypes] = useState<string[]>(initialValue.types);\n const [filters, setFilters] = useState<JsonObject>(initialValue.filters);\n const [pageLimit, setPageLimit] = useState<number | undefined>(\n initialValue.pageLimit,\n );\n const [pageCursor, setPageCursor] = useState<string | undefined>(\n initialValue.pageCursor,\n );\n\n const prevTerm = usePrevious(term);\n const prevFilters = usePrevious(filters);\n\n const result = useAsync(\n () =>\n searchApi.query({\n term,\n types,\n filters,\n pageLimit,\n pageCursor,\n }),\n [term, types, filters, pageLimit, pageCursor],\n );\n\n const hasNextPage =\n !result.loading && !result.error && result.value?.nextPageCursor;\n const hasPreviousPage =\n !result.loading && !result.error && result.value?.previousPageCursor;\n\n const fetchNextPage = useCallback(() => {\n setPageCursor(result.value?.nextPageCursor);\n }, [result.value?.nextPageCursor]);\n\n const fetchPreviousPage = useCallback(() => {\n setPageCursor(result.value?.previousPageCursor);\n }, [result.value?.previousPageCursor]);\n\n useEffect(() => {\n // Any time a term is reset, we want to start from page 0.\n // Only reset the term if it has been modified by the user at least once, the initial state must not reset the term.\n if (prevTerm !== undefined && term !== prevTerm) {\n setPageCursor(undefined);\n }\n }, [term, prevTerm, setPageCursor]);\n\n useEffect(() => {\n // Any time filters is reset, we want to start from page 0.\n // Only reset the page if it has been modified by the user at least once, the initial state must not reset the page.\n if (prevFilters !== undefined && !isEqual(filters, prevFilters)) {\n setPageCursor(undefined);\n }\n }, [filters, prevFilters, setPageCursor]);\n\n const value: SearchContextValue = {\n result,\n term,\n setTerm,\n types,\n setTypes,\n filters,\n setFilters,\n pageLimit,\n setPageLimit,\n pageCursor,\n setPageCursor,\n fetchNextPage: hasNextPage ? fetchNextPage : undefined,\n fetchPreviousPage: hasPreviousPage ? fetchPreviousPage : undefined,\n };\n\n return value;\n};\n\nexport type LocalSearchContextProps = PropsWithChildren<{\n initialState?: SearchContextState;\n}>;\n\nconst LocalSearchContext = (props: SearchContextProviderProps) => {\n const { initialState, children } = props;\n const value = useSearchContextValue(initialState);\n\n return (\n <AnalyticsContext\n attributes={{ searchTypes: value.types.sort().join(',') }}\n >\n <SearchContext.Provider value={createVersionedValueMap({ 1: value })}>\n {children}\n </SearchContext.Provider>\n </AnalyticsContext>\n );\n};\n\n/**\n * Props for {@link SearchContextProvider}\n *\n * @public\n */\nexport type SearchContextProviderProps =\n | PropsWithChildren<{\n /**\n * State initialized by a local context.\n */\n initialState?: SearchContextState;\n /**\n * Do not create an inheritance from the parent, as a new initial state must be defined in a local context.\n */\n inheritParentContextIfAvailable?: never;\n }>\n | PropsWithChildren<{\n /**\n * Does not accept initial state since it is already initialized by parent context.\n */\n initialState?: never;\n /**\n * If true, don't create a child context if there is a parent one already defined.\n * @remarks Defaults to false.\n */\n inheritParentContextIfAvailable?: boolean;\n }>;\n\n/**\n * @public\n * Search context provider which gives you access to shared state between search components\n */\nexport const SearchContextProvider = (props: SearchContextProviderProps) => {\n const { initialState, inheritParentContextIfAvailable, children } = props;\n const hasParentContext = useSearchContextCheck();\n\n return hasParentContext && inheritParentContextIfAvailable ? (\n <>{children}</>\n ) : (\n <LocalSearchContext initialState={initialState}>\n {children}\n </LocalSearchContext>\n );\n};\n","/*\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, { useEffect } from 'react';\nimport { useAnalytics } from '@backstage/core-plugin-api';\nimport { useSearch } from '../../context';\n\n/**\n * Capture search event on term change.\n */\nexport const TrackSearch = ({ children }: { children: React.ReactChild }) => {\n const analytics = useAnalytics();\n const { term } = useSearch();\n\n useEffect(() => {\n if (term) {\n // Capture analytics search event with search term provided as value\n analytics.captureEvent('search', term);\n }\n }, [analytics, term]);\n\n return <>{children}</>;\n};\n","/*\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, {\n ChangeEvent,\n KeyboardEvent,\n useState,\n useEffect,\n useCallback,\n forwardRef,\n ComponentType,\n ForwardRefExoticComponent,\n} from 'react';\nimport useDebounce from 'react-use/lib/useDebounce';\n\nimport {\n InputBase,\n InputBaseProps,\n InputAdornment,\n IconButton,\n} from '@material-ui/core';\nimport SearchIcon from '@material-ui/icons/Search';\nimport ClearButton from '@material-ui/icons/Clear';\n\nimport {\n AnalyticsContext,\n configApiRef,\n useApi,\n} from '@backstage/core-plugin-api';\n\nimport { SearchContextProvider, useSearch } from '../../context';\nimport { TrackSearch } from '../SearchTracker';\n\nfunction withContext<T>(Component: ComponentType<T>) {\n return forwardRef<unknown, T>((props, ref) => (\n <SearchContextProvider inheritParentContextIfAvailable>\n <Component {...props} ref={ref} />\n </SearchContextProvider>\n ));\n}\n\n/**\n * Props for {@link SearchBarBase}.\n *\n * @public\n */\nexport type SearchBarBaseProps = Omit<InputBaseProps, 'onChange'> & {\n debounceTime?: number;\n clearButton?: boolean;\n onClear?: () => void;\n onSubmit?: () => void;\n onChange: (value: string) => void;\n};\n\n/**\n * All search boxes exported by the search plugin are based on the <SearchBarBase />,\n * and this one is based on the <InputBase /> component from Material UI.\n * Recommended if you don't use Search Provider or Search Context.\n *\n * @public\n */\nexport const SearchBarBase: ForwardRefExoticComponent<SearchBarBaseProps> =\n withContext(\n forwardRef((props, ref) => {\n const {\n onChange,\n onKeyDown = () => {},\n onClear = () => {},\n onSubmit = () => {},\n debounceTime = 200,\n clearButton = true,\n fullWidth = true,\n value: defaultValue,\n placeholder: defaultPlaceholder,\n inputProps: defaultInputProps = {},\n endAdornment: defaultEndAdornment,\n ...rest\n } = props;\n\n const configApi = useApi(configApiRef);\n const [value, setValue] = useState<string>('');\n\n useEffect(() => {\n setValue(prevValue =>\n prevValue !== defaultValue ? String(defaultValue) : prevValue,\n );\n }, [defaultValue]);\n\n useDebounce(() => onChange(value), debounceTime, [value]);\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n setValue(e.target.value);\n },\n [setValue],\n );\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLInputElement>) => {\n if (onKeyDown) onKeyDown(e);\n if (onSubmit && e.key === 'Enter') {\n onSubmit();\n }\n },\n [onKeyDown, onSubmit],\n );\n\n const handleClear = useCallback(() => {\n onChange('');\n if (onClear) {\n onClear();\n }\n }, [onChange, onClear]);\n\n const placeholder =\n defaultPlaceholder ??\n `Search in ${configApi.getOptionalString('app.title') || 'Backstage'}`;\n\n const startAdornment = (\n <InputAdornment position=\"start\">\n <IconButton aria-label=\"Query\" size=\"small\" disabled>\n <SearchIcon />\n </IconButton>\n </InputAdornment>\n );\n\n const endAdornment = (\n <InputAdornment position=\"end\">\n <IconButton aria-label=\"Clear\" size=\"small\" onClick={handleClear}>\n <ClearButton />\n </IconButton>\n </InputAdornment>\n );\n\n return (\n <TrackSearch>\n <InputBase\n data-testid=\"search-bar-next\"\n ref={ref}\n value={value}\n placeholder={placeholder}\n startAdornment={startAdornment}\n endAdornment={clearButton ? endAdornment : defaultEndAdornment}\n inputProps={{ 'aria-label': 'Search', ...defaultInputProps }}\n fullWidth={fullWidth}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n {...rest}\n />\n </TrackSearch>\n );\n }),\n );\n\n/**\n * Props for {@link SearchBar}.\n *\n * @public\n */\nexport type SearchBarProps = Partial<SearchBarBaseProps>;\n\n/**\n * Recommended search bar when you use the Search Provider or Search Context.\n *\n * @public\n */\nexport const SearchBar: ForwardRefExoticComponent<SearchBarProps> = withContext(\n forwardRef((props, ref) => {\n const { value: initialValue = '', onChange, ...rest } = props;\n\n const { term, setTerm } = useSearch();\n\n useEffect(() => {\n if (initialValue) {\n setTerm(String(initialValue));\n }\n }, [initialValue, setTerm]);\n\n const handleChange = useCallback(\n (newValue: string) => {\n if (onChange) {\n onChange(newValue);\n } else {\n setTerm(newValue);\n }\n },\n [onChange, setTerm],\n );\n\n return (\n <AnalyticsContext\n attributes={{ pluginId: 'search', extension: 'SearchBar' }}\n >\n <SearchBarBase\n {...rest}\n ref={ref}\n value={term}\n onChange={handleChange}\n />\n </AnalyticsContext>\n );\n }),\n);\n","/*\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, { ChangeEvent, useCallback, useMemo } from 'react';\n\nimport { CircularProgress } from '@material-ui/core';\nimport {\n Autocomplete,\n AutocompleteProps,\n AutocompleteChangeDetails,\n AutocompleteChangeReason,\n AutocompleteRenderInputParams,\n} from '@material-ui/lab';\n\nimport { SearchContextProvider, useSearch } from '../../context';\nimport { SearchBar, SearchBarProps } from '../SearchBar';\n\n/**\n * Props for {@link SearchAutocomplete}.\n *\n * @public\n */\nexport type SearchAutocompleteProps<Option> = Omit<\n AutocompleteProps<Option, undefined, undefined, boolean>,\n 'renderInput' | 'disableClearable' | 'multiple'\n> & {\n 'data-testid'?: string;\n inputPlaceholder?: SearchBarProps['placeholder'];\n inputDebounceTime?: SearchBarProps['debounceTime'];\n};\n\n/**\n * Type for {@link SearchAutocomplete}.\n *\n * @public\n */\nexport type SearchAutocompleteComponent = <Option>(\n props: SearchAutocompleteProps<Option>,\n) => JSX.Element;\n\nconst withContext = (\n Component: SearchAutocompleteComponent,\n): SearchAutocompleteComponent => {\n return props => (\n <SearchContextProvider inheritParentContextIfAvailable>\n <Component {...props} />\n </SearchContextProvider>\n );\n};\n\n/**\n * Recommended search autocomplete when you use the Search Provider or Search Context.\n *\n * @public\n */\nexport const SearchAutocomplete = withContext(\n function SearchAutocompleteComponent<Option>(\n props: SearchAutocompleteProps<Option>,\n ) {\n const {\n loading,\n value,\n onChange = () => {},\n options = [],\n getOptionLabel = (option: Option) => String(option),\n inputPlaceholder,\n inputDebounceTime,\n freeSolo = true,\n fullWidth = true,\n clearOnBlur = false,\n 'data-testid': dataTestId = 'search-autocomplete',\n ...rest\n } = props;\n\n const { setTerm } = useSearch();\n\n const getInputValue = useCallback(\n (option?: null | string | Option) => {\n if (!option) return '';\n if (typeof option === 'string') return option;\n return getOptionLabel(option);\n },\n [getOptionLabel],\n );\n\n const inputValue = useMemo(\n () => getInputValue(value),\n [value, getInputValue],\n );\n\n const handleChange = useCallback(\n (\n event: ChangeEvent<{}>,\n option: null | string | Option,\n reason: AutocompleteChangeReason,\n details?: AutocompleteChangeDetails<Option>,\n ) => {\n setTerm(getInputValue(option));\n onChange(event, option, reason, details);\n },\n [getInputValue, setTerm, onChange],\n );\n\n const renderInput = useCallback(\n ({\n InputProps: { ref, endAdornment },\n InputLabelProps,\n ...params\n }: AutocompleteRenderInputParams) => (\n <SearchBar\n {...params}\n ref={ref}\n clearButton={false}\n value={inputValue}\n placeholder={inputPlaceholder}\n debounceTime={inputDebounceTime}\n endAdornment={\n loading ? (\n <CircularProgress\n data-testid=\"search-autocomplete-progressbar\"\n color=\"inherit\"\n size={20}\n />\n ) : (\n endAdornment\n )\n }\n />\n ),\n [loading, inputValue, inputPlaceholder, inputDebounceTime],\n );\n\n return (\n <Autocomplete\n {...rest}\n data-testid={dataTestId}\n value={value}\n onChange={handleChange}\n options={options}\n getOptionLabel={getOptionLabel}\n renderInput={renderInput}\n freeSolo={freeSolo}\n fullWidth={fullWidth}\n clearOnBlur={clearOnBlur}\n />\n );\n },\n);\n","/*\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, { ReactNode } from 'react';\nimport {\n ListItemIcon,\n ListItemText,\n ListItemTextProps,\n} from '@material-ui/core';\n\n/**\n * Props for {@link SearchAutocompleteDefaultOption}.\n *\n * @public\n */\nexport type SearchAutocompleteDefaultOptionProps = {\n icon?: ReactNode;\n primaryText: ListItemTextProps['primary'];\n primaryTextTypographyProps?: ListItemTextProps['primaryTypographyProps'];\n secondaryText?: ListItemTextProps['secondary'];\n secondaryTextTypographyProps?: ListItemTextProps['secondaryTypographyProps'];\n disableTextTypography?: ListItemTextProps['disableTypography'];\n};\n\n/**\n * A default search autocomplete option component.\n *\n * @public\n */\nexport const SearchAutocompleteDefaultOption = ({\n icon,\n primaryText,\n primaryTextTypographyProps,\n secondaryText,\n secondaryTextTypographyProps,\n disableTextTypography,\n}: SearchAutocompleteDefaultOptionProps) => (\n <>\n {icon ? <ListItemIcon>{icon}</ListItemIcon> : null}\n <ListItemText\n primary={primaryText}\n primaryTypographyProps={primaryTextTypographyProps}\n secondary={secondaryText}\n secondaryTypographyProps={secondaryTextTypographyProps}\n disableTypography={disableTextTypography}\n />\n </>\n);\n","/*\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 { useEffect, useRef } from 'react';\nimport useAsyncFn from 'react-use/lib/useAsyncFn';\nimport useDebounce from 'react-use/lib/useDebounce';\n\nimport { useSearch } from '../../context';\n\n/**\n * Utility hook for either asynchronously loading filter values from a given\n * function or synchronously providing a given list of default values.\n *\n * @public\n */\nexport const useAsyncFilterValues = (\n fn: ((partial: string) => Promise<string[]>) | undefined,\n inputValue: string,\n defaultValues: string[] = [],\n debounce: number = 250,\n) => {\n const valuesMemo = useRef<Record<string, string[] | Promise<string[]>>>({});\n const definiteFn = fn || (() => Promise.resolve([]));\n\n const [state, callback] = useAsyncFn(definiteFn, [inputValue], {\n loading: true,\n });\n\n // Do not invoke the given function more than necessary.\n useDebounce(\n () => {\n // Performance optimization: only invoke the callback once per inputValue\n // for the lifetime of the hook/component.\n if (valuesMemo.current[inputValue] === undefined) {\n valuesMemo.current[inputValue] = callback(inputValue).then(values => {\n // Override the value for future immediate returns.\n valuesMemo.current[inputValue] = values;\n return values;\n });\n }\n },\n debounce,\n [callback, inputValue],\n );\n\n // Immediately return the default values if they are provided.\n if (defaultValues.length) {\n return {\n loading: false,\n value: defaultValues,\n };\n }\n\n // Immediately return a memoized value if it is set (and not a promise).\n const possibleValue = valuesMemo.current[inputValue];\n if (Array.isArray(possibleValue)) {\n return {\n loading: false,\n value: possibleValue,\n };\n }\n\n return state;\n};\n\n/**\n * Utility hook for applying a given default value to the search context.\n *\n * @public\n */\nexport const useDefaultFilterValue = (\n name: string,\n defaultValue?: string | string[] | null,\n) => {\n const { setFilters } = useSearch();\n\n useEffect(() => {\n if (defaultValue && [defaultValue].flat().length > 0) {\n setFilters(prevFilters => ({\n ...prevFilters,\n [name]: defaultValue,\n }));\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n};\n","/*\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, { ChangeEvent, useState } from 'react';\nimport { Chip, TextField } from '@material-ui/core';\nimport {\n Autocomplete,\n AutocompleteGetTagProps,\n AutocompleteRenderInputParams,\n} from '@material-ui/lab';\n\nimport { useSearch } from '../../context';\nimport { useAsyncFilterValues, useDefaultFilterValue } from './hooks';\nimport { SearchFilterComponentProps } from './SearchFilter';\n\n/**\n * @public\n */\nexport type SearchAutocompleteFilterProps = SearchFilterComponentProps & {\n filterSelectedOptions?: boolean;\n limitTags?: number;\n multiple?: boolean;\n};\n\n/**\n * @public\n */\nexport const AutocompleteFilter = (props: SearchAutocompleteFilterProps) => {\n const {\n className,\n defaultValue,\n name,\n values: givenValues,\n valuesDebounceMs,\n label,\n filterSelectedOptions,\n limitTags,\n multiple,\n } = props;\n const [inputValue, setInputValue] = useState<string>('');\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 inputValue,\n defaultValues,\n valuesDebounceMs,\n );\n const { filters, setFilters } = useSearch();\n const filterValue =\n (filters[name] as string | string[] | undefined) || (multiple ? [] : null);\n\n // Set new filter values on input change.\n const handleChange = (\n _: ChangeEvent<{}>,\n newValue: string | string[] | null,\n ) => {\n setFilters(prevState => {\n const { [name]: filter, ...others } = prevState;\n\n if (newValue) {\n return { ...others, [name]: newValue };\n }\n return { ...others };\n });\n };\n\n // Provide the input field.\n const renderInput = (params: AutocompleteRenderInputParams) => (\n <TextField\n {...params}\n name=\"search\"\n variant=\"outlined\"\n label={label}\n fullWidth\n />\n );\n\n // Render tags as primary-colored chips.\n const renderTags = (\n tagValue: string[],\n getTagProps: AutocompleteGetTagProps,\n ) =>\n tagValue.map((option: string, index: number) => (\n <Chip label={option} color=\"primary\" {...getTagProps({ index })} />\n ));\n\n return (\n <Autocomplete\n filterSelectedOptions={filterSelectedOptions}\n limitTags={limitTags}\n multiple={multiple}\n className={className}\n id={`${multiple ? 'multi-' : ''}select-filter-${name}--select`}\n options={values || []}\n loading={loading}\n value={filterValue}\n onChange={handleChange}\n onInputChange={(_, newValue) => setInputValue(newValue)}\n renderInput={renderInput}\n renderTags={renderTags}\n />\n );\n};\n","/*\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 } from 'react';\nimport {\n makeStyles,\n FormControl,\n FormControlLabel,\n InputLabel,\n Checkbox,\n Select,\n MenuItem,\n FormLabel,\n} from '@material-ui/core';\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});\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 control={\n <Checkbox\n color=\"primary\"\n tabIndex={-1}\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 label={value}\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 const classes = useStyles();\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 { filters, setFilters } = useSearch();\n\n const handleChange = (e: ChangeEvent<{ value: unknown }>) => {\n const {\n target: { value },\n } = e;\n\n setFilters(prevFilters => {\n const { [name]: filter, ...others } = prevFilters;\n return value ? { ...others, [name]: value as string } : others;\n });\n };\n\n return (\n <FormControl\n disabled={loading}\n className={className}\n variant=\"filled\"\n fullWidth\n data-testid=\"search-selectfilter-next\"\n >\n {label ? (\n <InputLabel className={classes.label} margin=\"dense\">\n {label}\n </InputLabel>\n ) : null}\n <Select\n variant=\"outlined\"\n value={filters[name] || ''}\n onChange={handleChange}\n >\n <MenuItem value=\"\">\n <em>All</em>\n </MenuItem>\n {values.map((value: string) => (\n <MenuItem key={value} value={value}>\n {value}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n );\n};\n\n/**\n * @public\n */\nconst SearchFilter = ({\n component: Element,\n ...props\n}: SearchFilterWrapperProps) => <Element {...props} />;\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","/*\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 from 'react';\nimport useAsync, { AsyncState } from 'react-use/lib/useAsync';\n\nimport {\n EmptyState,\n Progress,\n ResponseErrorPanel,\n} from '@backstage/core-components';\nimport { AnalyticsContext, useApi } from '@backstage/core-plugin-api';\nimport { SearchQuery, SearchResultSet } from '@backstage/plugin-search-common';\n\nimport { useSearch } from '../../context';\nimport { searchApiRef } from '../../api';\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: (state: AsyncState<SearchResultSet>) => 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 state = context.result;\n return children(state);\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);\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 children: (resultSet: SearchResultSet) => 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 { query, children } = 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 (\n <EmptyState missing=\"data\" title=\"Sorry, no results were found\" />\n );\n }\n\n return children(value);\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","/*\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 from 'react';\n\nimport { Button, makeStyles } from '@material-ui/core';\nimport ArrowBackIosIcon from '@material-ui/icons/ArrowBackIos';\nimport ArrowForwardIosIcon from '@material-ui/icons/ArrowForwardIos';\n\nimport { useSearch } from '../../context';\n\nconst useStyles = makeStyles(theme => ({\n root: {\n display: 'flex',\n justifyContent: 'space-between',\n gap: theme.spacing(2),\n margin: theme.spacing(2, 0),\n },\n}));\n\n/**\n * @public\n */\nexport const SearchResultPager = () => {\n const { fetchNextPage, fetchPreviousPage } = useSearch();\n const classes = useStyles();\n\n if (!fetchNextPage && !fetchPreviousPage) {\n return <></>;\n }\n\n return (\n <nav aria-label=\"pagination navigation\" className={classes.root}>\n <Button\n aria-label=\"previous page\"\n disabled={!fetchPreviousPage}\n onClick={fetchPreviousPage}\n startIcon={<ArrowBackIosIcon />}\n >\n Previous\n </Button>\n\n <Button\n aria-label=\"next page\"\n disabled={!fetchNextPage}\n onClick={fetchNextPage}\n endIcon={<ArrowForwardIosIcon />}\n >\n Next\n </Button>\n </nav>\n );\n};\n","/*\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, { ReactNode } from 'react';\nimport { AnalyticsContext, useAnalytics } from '@backstage/core-plugin-api';\nimport {\n ResultHighlight,\n SearchDocument,\n} from '@backstage/plugin-search-common';\nimport { HighlightedSearchResultText } from '../HighlightedSearchResultText';\nimport {\n ListItem,\n ListItemIcon,\n ListItemText,\n Box,\n Divider,\n} from '@material-ui/core';\nimport { Link } from '@backstage/core-components';\n\n/**\n * Props for {@link DefaultResultListItem}\n *\n * @public\n */\nexport type DefaultResultListItemProps = {\n icon?: ReactNode;\n secondaryAction?: ReactNode;\n result: SearchDocument;\n highlight?: ResultHighlight;\n rank?: number;\n lineClamp?: number;\n};\n\n/**\n * A default result list item.\n *\n * @public\n */\nexport const DefaultResultListItemComponent = ({\n result,\n highlight,\n rank,\n icon,\n secondaryAction,\n lineClamp = 5,\n}: DefaultResultListItemProps) => {\n const analytics = useAnalytics();\n const handleClick = () => {\n analytics.captureEvent('discover', result.title, {\n attributes: { to: result.location },\n value: rank,\n });\n };\n\n return (\n <Link noTrack to={result.location} onClick={handleClick}>\n <ListItem alignItems=\"center\">\n {icon && <ListItemIcon>{icon}</ListItemIcon>}\n <ListItemText\n primaryTypographyProps={{ variant: 'h6' }}\n primary={\n highlight?.fields.title ? (\n <HighlightedSearchResultText\n text={highlight.fields.title}\n preTag={highlight.preTag}\n postTag={highlight.postTag}\n />\n ) : (\n result.title\n )\n }\n secondary={\n <span\n style={{\n display: '-webkit-box',\n WebkitBoxOrient: 'vertical',\n WebkitLineClamp: lineClamp,\n overflow: 'hidden',\n }}\n >\n {highlight?.fields.text ? (\n <HighlightedSearchResultText\n text={highlight.fields.text}\n preTag={highlight.preTag}\n postTag={highlight.postTag}\n />\n ) : (\n result.text\n )}\n </span>\n }\n />\n {secondaryAction && <Box alignItems=\"flex-end\">{secondaryAction}</Box>}\n </ListItem>\n <Divider />\n </Link>\n );\n};\n\n/**\n * @public\n */\nconst HigherOrderDefaultResultListItem = (\n props: DefaultResultListItemProps,\n) => {\n return (\n <AnalyticsContext\n attributes={{\n pluginId: 'search',\n extension: 'DefaultResultListItem',\n }}\n >\n <DefaultResultListItemComponent {...props} />\n </AnalyticsContext>\n );\n};\n\nexport { HigherOrderDefaultResultListItem as DefaultResultListItem };\n","/*\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, { ReactNode } from 'react';\n\nimport { List, ListItem, ListProps } from '@material-ui/core';\n\nimport {\n EmptyState,\n Progress,\n ResponseErrorPanel,\n} from '@backstage/core-components';\nimport { AnalyticsContext } from '@backstage/core-plugin-api';\nimport { SearchQuery, SearchResult } from '@backstage/plugin-search-common';\n\nimport { DefaultResultListItem } from '../DefaultResultListItem';\nimport { SearchResultState } from '../SearchResult';\n\n/**\n * Props for {@link SearchResultListLayout}\n * @public\n */\nexport type SearchResultListLayoutProps = ListProps & {\n /**\n * Search results to be rendered as a list.\n */\n resultItems?: SearchResult[];\n /**\n * Function to customize how result items are rendered.\n */\n renderResultItem?: (\n value: SearchResult,\n index: number,\n array: SearchResult[],\n ) => JSX.Element | null;\n /**\n * If defined, will render a default error panel.\n */\n error?: Error;\n /**\n * If defined, will render a default loading progress.\n */\n loading?: boolean;\n /**\n * Optional component to render when no results. Default to <EmptyState /> component.\n */\n noResultsComponent?: ReactNode;\n};\n\n/**\n * Default layout for rendering search results in a list.\n * @param props - See {@link SearchResultListLayoutProps}.\n * @public\n */\nexport const SearchResultListLayout = (props: SearchResultListLayoutProps) => {\n const {\n loading,\n error,\n resultItems,\n renderResultItem = resultItem => (\n <DefaultResultListItem\n key={resultItem.document.location}\n result={resultItem.document}\n />\n ),\n noResultsComponent = (\n <EmptyState missing=\"data\" title=\"Sorry, no results were found\" />\n ),\n ...rest\n } = props;\n\n return (\n <List {...rest}>\n {loading ? <Progress /> : null}\n {!loading && error ? (\n <ResponseErrorPanel\n title=\"Error encountered while fetching search results\"\n error={error}\n />\n ) : null}\n {!loading && !error && resultItems?.length\n ? resultItems.map(renderResultItem)\n : null}\n {!loading && !error && !resultItems?.length ? (\n <ListItem>{noResultsComponent}</ListItem>\n ) : null}\n </List>\n );\n};\n\n/**\n * Props for {@link SearchResultList}.\n * @public\n */\nexport type SearchResultListProps = Omit<\n SearchResultListLayoutProps,\n 'loading' | 'error' | 'resultItems'\n> & {\n /**\n * A search query used for requesting the results to be listed.\n */\n query: Partial<SearchQuery>;\n /**\n * Optional property to provide if component should not render the component when no results are found.\n */\n disableRenderingWithNoResults?: boolean;\n};\n\n/**\n * Given a query, search for results and render them as a list.\n * @param props - See {@link SearchResultListProps}.\n * @public\n */\nexport const SearchResultList = (props: SearchResultListProps) => {\n const { query, disableRenderingWithNoResults, ...rest } = props;\n\n return (\n <AnalyticsContext\n attributes={{\n pluginId: 'search',\n extension: 'SearchResultList',\n }}\n >\n <SearchResultState query={query}>\n {({ loading, error, value }) => {\n if (!value?.results?.length && disableRenderingWithNoResults) {\n return null;\n }\n\n return (\n <SearchResultListLayout\n {...rest}\n loading={loading}\n error={error}\n resultItems={value?.results}\n />\n );\n }}\n </SearchResultState>\n </AnalyticsContext>\n );\n};\n","/*\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, {\n ChangeEvent,\n PropsWithChildren,\n ReactNode,\n useCallback,\n useState,\n} from 'react';\nimport qs from 'qs';\n\nimport {\n makeStyles,\n Theme,\n List,\n ListSubheader,\n ListItem,\n ListProps,\n Menu,\n MenuItem,\n InputBase,\n Select,\n Chip,\n Typography,\n TypographyProps,\n} from '@material-ui/core';\nimport AddIcon from '@material-ui/icons/Add';\nimport ArrowRightIcon from '@material-ui/icons/ArrowForwardIos';\n\nimport { JsonValue } from '@backstage/types';\nimport {\n EmptyState,\n Link,\n LinkProps,\n Progress,\n ResponseErrorPanel,\n} from '@backstage/core-components';\nimport { AnalyticsContext } from '@backstage/core-plugin-api';\nimport { SearchQuery, SearchResult } from '@backstage/plugin-search-common';\n\nimport { DefaultResultListItem } from '../DefaultResultListItem';\nimport { SearchResultState } from '../SearchResult';\n\nconst useStyles = makeStyles((theme: Theme) => ({\n listSubheader: {\n display: 'flex',\n alignItems: 'center',\n },\n listSubheaderName: {\n marginLeft: theme.spacing(1),\n textTransform: 'uppercase',\n },\n listSubheaderChip: {\n color: theme.palette.text.secondary,\n margin: theme.spacing(0, 0, 0, 1.5),\n },\n listSubheaderFilter: {\n display: 'flex',\n color: theme.palette.text.secondary,\n margin: theme.spacing(0, 0, 0, 1.5),\n },\n listSubheaderLink: {\n marginLeft: 'auto',\n display: 'flex',\n alignItems: 'center',\n },\n listSubheaderLinkIcon: {\n fontSize: 'inherit',\n marginLeft: theme.spacing(0.5),\n },\n}));\n\n/**\n * Props for {@link SearchResultGroupFilterFieldLayout}\n * @public\n */\nexport type SearchResultGroupFilterFieldLayoutProps = PropsWithChildren<{\n label: string;\n value?: JsonValue;\n onDelete: () => void;\n}>;\n\n/**\n * Default layout for a search group filter field.\n * @param props - See {@link SearchResultGroupFilterFieldLayoutProps}.\n * @public\n */\nexport const SearchResultGroupFilterFieldLayout = (\n props: SearchResultGroupFilterFieldLayoutProps,\n) => {\n const classes = useStyles();\n const { label, children, ...rest } = props;\n\n return (\n <Chip\n {...rest}\n className={classes.listSubheaderFilter}\n variant=\"outlined\"\n label={\n <>\n {label}: {children}\n </>\n }\n />\n );\n};\n\nconst NullIcon = () => null;\n\n/**\n * Common props for a result group filter field.\n * @public\n */\nexport type SearchResultGroupFilterFieldPropsWith<T> = T &\n SearchResultGroupFilterFieldLayoutProps & {\n onChange: (value: JsonValue) => void;\n };\n\nconst useSearchResultGroupTextFilterStyles = makeStyles((theme: Theme) => ({\n root: {\n fontSize: 'inherit',\n '&:focus': {\n outline: 'none',\n background: theme.palette.common.white,\n },\n '&:not(:focus)': {\n cursor: 'pointer',\n color: theme.palette.primary.main,\n '&:hover': {\n textDecoration: 'underline',\n },\n },\n },\n}));\n\n/**\n * Props for {@link SearchResultGroupTextFilterField}.\n * @public\n */\nexport type SearchResultGroupTextFilterFieldProps =\n SearchResultGroupFilterFieldPropsWith<{}>;\n\n/**\n * A text field that can be used as filter on search result groups.\n * @param props - See {@link SearchResultGroupTextFilterFieldProps}.\n * @example\n * ```\n * <SearchResultGroupTextFilterField\n * id=\"lifecycle\"\n * label=\"Lifecycle\"\n * value={value}\n * onChange={handleChangeFilter}\n * onDelete={handleDeleteFilter}\n * />\n * ```\n * @public\n */\nexport const SearchResultGroupTextFilterField = (\n props: SearchResultGroupTextFilterFieldProps,\n) => {\n const classes = useSearchResultGroupTextFilterStyles();\n const { label, value = 'None', onChange, onDelete } = props;\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n onChange(e.target.value);\n },\n [onChange],\n );\n\n return (\n <SearchResultGroupFilterFieldLayout label={label} onDelete={onDelete}>\n <Typography\n role=\"textbox\"\n component=\"span\"\n className={classes.root}\n onChange={handleChange}\n contentEditable\n suppressContentEditableWarning\n >\n {value}\n </Typography>\n </SearchResultGroupFilterFieldLayout>\n );\n};\n\nconst useSearchResultGroupSelectFilterStyles = makeStyles((theme: Theme) => ({\n root: {\n fontSize: 'inherit',\n '&:not(:focus)': {\n cursor: 'pointer',\n color: theme.palette.primary.main,\n '&:hover': {\n textDecoration: 'underline',\n },\n },\n '&:focus': {\n outline: 'none',\n },\n '&>div:first-child': {\n padding: 0,\n },\n },\n}));\n\n/**\n * Props for {@link SearchResultGroupTextFilterField}.\n * @public\n */\nexport type SearchResultGroupSelectFilterFieldProps =\n SearchResultGroupFilterFieldPropsWith<{\n children: ReactNode;\n }>;\n\n/**\n * A select field that can be used as filter on search result groups.\n * @param props - See {@link SearchResultGroupSelectFilterFieldProps}.\n * @example\n * ```\n * <SearchResultGroupSelectFilterField\n * id=\"lifecycle\"\n * label=\"Lifecycle\"\n * value={filters.lifecycle}\n * onChange={handleChangeFilter}\n * onDelete={handleDeleteFilter}\n * >\n * <MenuItem value=\"experimental\">Experimental</MenuItem>\n * <MenuItem value=\"production\">Production</MenuItem>\n * </SearchResultGroupSelectFilterField>\n * ```\n * @public\n */\nexport const SearchResultGroupSelectFilterField = (\n props: SearchResultGroupSelectFilterFieldProps,\n) => {\n const classes = useSearchResultGroupSelectFilterStyles();\n const { label, value = 'none', onChange, onDelete, children } = props;\n\n const handleChange = useCallback(\n (e: ChangeEvent<{ value: unknown }>) => {\n onChange(e.target.value as JsonValue);\n },\n [onChange],\n );\n\n return (\n <SearchResultGroupFilterFieldLayout label={label} onDelete={onDelete}>\n <Select\n className={classes.root}\n value={value}\n onChange={handleChange}\n input={<InputBase />}\n IconComponent={NullIcon}\n >\n <MenuItem value=\"none\">None</MenuItem>\n {children}\n </Select>\n </SearchResultGroupFilterFieldLayout>\n );\n};\n\n/**\n * Props for {@link SearchResultGroupLayout}\n * @public\n */\nexport type SearchResultGroupLayoutProps<FilterOption> = ListProps & {\n /**\n * Icon that representing a result group.\n */\n icon: JSX.Element;\n /**\n * The results group title content, it could be a text or an element.\n */\n title: ReactNode;\n /**\n * Props for the results group title.\n */\n titleProps?: Partial<TypographyProps>;\n /**\n * The results group link content, it could be a text or an element.\n */\n link?: ReactNode;\n /**\n * Props for the results group link, the \"to\" prop defaults to \"/search\".\n */\n linkProps?: Partial<LinkProps>;\n /**\n * A generic filter options that is rendered on the \"Add filter\" dropdown.\n */\n filterOptions?: FilterOption[];\n /**\n * Function to customize how filter options are rendered.\n * @remarks Defaults to a menu item where its value and label bounds to the option string.\n */\n renderFilterOption?: (\n value: FilterOption,\n index: number,\n array: FilterOption[],\n ) => JSX.Element | null;\n /**\n * A list of search filter keys, also known as filter field names.\n */\n filterFields?: string[];\n /**\n * Function to customize how filter chips are rendered.\n */\n renderFilterField?: (key: string) => JSX.Element | null;\n /**\n * Search results to be rendered as a group.\n */\n resultItems?: SearchResult[];\n /**\n * Function to customize how result items are rendered.\n */\n renderResultItem?: (\n value: SearchResult,\n index: number,\n array: SearchResult[],\n ) => JSX.Element | null;\n /**\n * If defined, will render a default error panel.\n */\n error?: Error;\n /**\n * If defined, will render a default loading progress.\n */\n loading?: boolean;\n /**\n * Optional component to render when no results. Default to <EmptyState /> component.\n */\n noResultsComponent?: ReactNode;\n};\n\n/**\n * Default layout for rendering search results in a group.\n * @param props - See {@link SearchResultGroupLayoutProps}.\n * @public\n */\nexport function SearchResultGroupLayout<FilterOption>(\n props: SearchResultGroupLayoutProps<FilterOption>,\n) {\n const classes = useStyles();\n const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);\n\n const {\n loading,\n error,\n icon,\n title,\n titleProps = {},\n link = (\n <>\n See all\n <ArrowRightIcon className={classes.listSubheaderLinkIcon} />\n </>\n ),\n linkProps = {},\n filterOptions,\n renderFilterOption = filterOption => (\n <MenuItem key={String(filterOption)} value={String(filterOption)}>\n {filterOption}\n </MenuItem>\n ),\n filterFields,\n renderFilterField,\n resultItems,\n renderResultItem = resultItem => (\n <DefaultResultListItem\n key={resultItem.document.location}\n result={resultItem.document}\n />\n ),\n noResultsComponent = (\n <EmptyState missing=\"data\" title=\"Sorry, no results were found\" />\n ),\n ...rest\n } = props;\n\n const handleClick = useCallback((e: React.MouseEvent<HTMLButtonElement>) => {\n setAnchorEl(e.currentTarget);\n }, []);\n\n const handleClose = useCallback(() => {\n setAnchorEl(null);\n }, []);\n\n return (\n <List {...rest}>\n <ListSubheader className={classes.listSubheader}>\n {icon}\n <Typography\n className={classes.listSubheaderName}\n component=\"strong\"\n {...titleProps}\n >\n {title}\n </Typography>\n {filterOptions ? (\n <Chip\n className={classes.listSubheaderChip}\n component=\"button\"\n icon={<AddIcon />}\n variant=\"outlined\"\n label=\"Add filter\"\n aria-controls=\"filters-menu\"\n aria-haspopup=\"true\"\n onClick={handleClick}\n />\n ) : null}\n {filterOptions ? (\n <Menu\n id=\"filters-menu\"\n anchorEl={anchorEl}\n open={Boolean(anchorEl)}\n onClose={handleClose}\n onClick={handleClose}\n keepMounted\n >\n {filterOptions.map(renderFilterOption)}\n </Menu>\n ) : null}\n {filterFields?.map(\n filterField => renderFilterField?.(filterField) ?? null,\n )}\n <Link className={classes.listSubheaderLink} to=\"/search\" {...linkProps}>\n {link}\n </Link>\n </ListSubheader>\n {loading ? <Progress /> : null}\n {!loading && error ? (\n <ResponseErrorPanel\n title=\"Error encountered while fetching search results\"\n error={error}\n />\n ) : null}\n {!loading && !error && resultItems?.length\n ? resultItems.map(renderResultItem)\n : null}\n {!loading && !error && !resultItems?.length ? (\n <ListItem>{noResultsComponent}</ListItem>\n ) : null}\n </List>\n );\n}\n\n/**\n * Props for {@link SearchResultGroup}.\n * @public\n */\nexport type SearchResultGroupProps<FilterOption> = Omit<\n SearchResultGroupLayoutProps<FilterOption>,\n 'loading' | 'error' | 'resultItems' | 'filterFields'\n> & {\n /**\n * A search query used for requesting the results to be grouped.\n */\n query: Partial<SearchQuery>;\n /**\n * Optional property to provide if component should not render the group when no results are found.\n */\n disableRenderingWithNoResults?: boolean;\n};\n\n/**\n * Given a query, search for results and render them as a group.\n * @param props - See {@link SearchResultGroupProps}.\n * @public\n */\nexport function SearchResultGroup<FilterOption>(\n props: SearchResultGroupProps<FilterOption>,\n) {\n const {\n query,\n linkProps = {},\n disableRenderingWithNoResults,\n ...rest\n } = props;\n\n const to = `/search?${qs.stringify(\n {\n query: query.term,\n types: query.types,\n filters: query.filters,\n pageCursor: query.pageCursor,\n },\n { arrayFormat: 'brackets' },\n )}`;\n\n return (\n <AnalyticsContext\n attributes={{\n pluginId: 'search',\n extension: 'SearchResultGroup',\n }}\n >\n <SearchResultState query={query}>\n {({ loading, error, value }) => {\n if (!value?.results?.length && disableRenderingWithNoResults) {\n return null;\n }\n\n return (\n <SearchResultGroupLayout\n {...rest}\n loading={loading}\n error={error}\n linkProps={{ to, ...linkProps }}\n resultItems={value?.results}\n filterFields={Object.keys(query.filters ?? {})}\n />\n );\n }}\n </SearchResultState>\n </AnalyticsContext>\n );\n}\n"],"names":["useStyles","_a","withContext","DefaultResultListItem","ArrowRightIcon"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-search-react",
3
- "version": "1.1.1-next.0",
3
+ "version": "1.2.0-next.2",
4
4
  "main": "dist/index.esm.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "license": "Apache-2.0",
@@ -31,9 +31,9 @@
31
31
  "start": "backstage-cli package start"
32
32
  },
33
33
  "dependencies": {
34
- "@backstage/core-components": "^0.11.2-next.0",
35
- "@backstage/core-plugin-api": "^1.0.7-next.0",
36
- "@backstage/plugin-search-common": "^1.0.2-next.0",
34
+ "@backstage/core-components": "^0.11.2-next.2",
35
+ "@backstage/core-plugin-api": "^1.0.7-next.2",
36
+ "@backstage/plugin-search-common": "^1.1.0-next.2",
37
37
  "@backstage/theme": "^0.2.16",
38
38
  "@backstage/types": "^1.0.0",
39
39
  "@backstage/version-bridge": "^1.0.1",
@@ -50,9 +50,9 @@
50
50
  "react-router": "6.0.0-beta.0 || ^6.3.0"
51
51
  },
52
52
  "devDependencies": {
53
- "@backstage/cli": "^0.20.0-next.0",
54
- "@backstage/core-app-api": "^1.1.1-next.0",
55
- "@backstage/test-utils": "^1.2.1-next.0",
53
+ "@backstage/cli": "^0.20.0-next.2",
54
+ "@backstage/core-app-api": "^1.1.1-next.2",
55
+ "@backstage/test-utils": "^1.2.1-next.2",
56
56
  "@testing-library/jest-dom": "^5.10.1",
57
57
  "@testing-library/react": "^12.1.3",
58
58
  "@testing-library/react-hooks": "^8.0.0",