@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 +98 -0
- package/dist/index.d.ts +24 -6
- package/dist/index.esm.js +70 -68
- package/dist/index.esm.js.map +1 -1
- package/package.json +7 -7
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?: (
|
|
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?: (
|
|
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?: (
|
|
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
|
-
|
|
73
|
+
types: [],
|
|
74
74
|
filters: {},
|
|
75
|
-
|
|
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
|
-
|
|
93
|
-
|
|
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
|
-
|
|
619
|
-
|
|
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 {
|
|
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((
|
|
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 }) =>
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
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
|
|
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((
|
|
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
|
-
|
|
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
|
-
|
|
1020
|
-
filterFields: Object.keys((_a = query.filters) != null ? _a : {})
|
|
1022
|
+
filterFields: Object.keys((_b = query.filters) != null ? _b : {})
|
|
1021
1023
|
});
|
|
1022
1024
|
}));
|
|
1023
1025
|
}
|
package/dist/index.esm.js.map
CHANGED
|
@@ -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":"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"}
|
|
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.
|
|
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.
|
|
35
|
-
"@backstage/core-plugin-api": "^1.0.7-next.
|
|
36
|
-
"@backstage/plugin-search-common": "^1.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.
|
|
54
|
-
"@backstage/core-app-api": "^1.1.1-next.
|
|
55
|
-
"@backstage/test-utils": "^1.2.1-next.
|
|
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",
|