@backstage/plugin-search 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # @backstage/plugin-search
2
2
 
3
+ ## 0.5.1
4
+
5
+ ### Patch Changes
6
+
7
+ - cd450844f6: Moved React dependencies to `peerDependencies` and allow both React v16 and v17 to be used.
8
+ - 382e3a94b3: Export SearchApi interface from plugin
9
+ - Updated dependencies
10
+ - @backstage/core-components@0.8.0
11
+ - @backstage/core-plugin-api@0.3.0
12
+ - @backstage/plugin-catalog-react@0.6.5
13
+
3
14
  ## 0.5.0
4
15
 
5
16
  ### Minor Changes
@@ -1,4 +1,4 @@
1
- export { S as SearchPage } from './index-8e7d7ce9.esm.js';
1
+ export { S as SearchPage } from './index-893ec2f5.esm.js';
2
2
  import '@backstage/core-plugin-api';
3
3
  import '@backstage/errors';
4
4
  import 'qs';
@@ -20,4 +20,4 @@ import '@material-ui/lab';
20
20
  import '@backstage/plugin-catalog-react';
21
21
  import '@backstage/catalog-model';
22
22
  import 'react-router-dom';
23
- //# sourceMappingURL=index-09bfa46d.esm.js.map
23
+ //# sourceMappingURL=index-04d32ed0.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-04d32ed0.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;"}
@@ -1,4 +1,4 @@
1
- export { c as SearchResult } from './index-8e7d7ce9.esm.js';
1
+ export { c as SearchResult } from './index-893ec2f5.esm.js';
2
2
  import '@backstage/core-plugin-api';
3
3
  import '@backstage/errors';
4
4
  import 'qs';
@@ -20,4 +20,4 @@ import '@material-ui/lab';
20
20
  import '@backstage/plugin-catalog-react';
21
21
  import '@backstage/catalog-model';
22
22
  import 'react-router-dom';
23
- //# sourceMappingURL=index-49a2f5d1.esm.js.map
23
+ //# sourceMappingURL=index-3cbe4558.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-3cbe4558.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;"}
@@ -35,7 +35,7 @@ class SearchClient {
35
35
  const queryString = qs.stringify(query);
36
36
  const url = `${await this.discoveryApi.getBaseUrl("search/query")}?${queryString}`;
37
37
  const response = await fetch(url, {
38
- headers: token ? {Authorization: `Bearer ${token}`} : {}
38
+ headers: token ? { Authorization: `Bearer ${token}` } : {}
39
39
  });
40
40
  if (!response.ok) {
41
41
  throw await ResponseError.fromResponse(response);
@@ -54,7 +54,7 @@ const DefaultResultListItem$1 = ({
54
54
  }, /* @__PURE__ */ React__default.createElement(ListItem, {
55
55
  alignItems: "center"
56
56
  }, icon && /* @__PURE__ */ React__default.createElement(ListItemIcon, null, icon), /* @__PURE__ */ React__default.createElement(ListItemText, {
57
- primaryTypographyProps: {variant: "h6"},
57
+ primaryTypographyProps: { variant: "h6" },
58
58
  primary: result.title,
59
59
  secondary: result.text
60
60
  }), secondaryAction && /* @__PURE__ */ React__default.createElement(Box, {
@@ -254,7 +254,7 @@ const SearchBarBase = ({
254
254
  placeholder,
255
255
  value,
256
256
  onChange: (e) => onChange(e.target.value),
257
- inputProps: {"aria-label": "Search"},
257
+ inputProps: { "aria-label": "Search" },
258
258
  startAdornment: /* @__PURE__ */ React__default.createElement(InputAdornment, {
259
259
  position: "start"
260
260
  }, /* @__PURE__ */ React__default.createElement(IconButton, {
@@ -267,8 +267,8 @@ const SearchBarBase = ({
267
267
  "aria-label": "Clear",
268
268
  onClick: handleClear
269
269
  }, /* @__PURE__ */ React__default.createElement(ClearButton, null))),
270
- ...className && {className},
271
- ...onSubmit && {onKeyDown}
270
+ ...className && { className },
271
+ ...onSubmit && { onKeyDown }
272
272
  });
273
273
  };
274
274
  const SearchBar$1 = ({
@@ -278,7 +278,7 @@ const SearchBar$1 = ({
278
278
  placeholder,
279
279
  clearButton = true
280
280
  }) => {
281
- const {term, setTerm} = useSearch();
281
+ const { term, setTerm } = useSearch();
282
282
  const [value, setValue] = useState(term);
283
283
  useEffect(() => {
284
284
  setValue((prevValue) => prevValue !== term ? term : prevValue);
@@ -311,7 +311,7 @@ const CheckboxFilter = ({
311
311
  values = []
312
312
  }) => {
313
313
  const classes = useStyles$7();
314
- const {filters, setFilters} = useSearch();
314
+ const { filters, setFilters } = useSearch();
315
315
  useEffect(() => {
316
316
  if (Array.isArray(defaultValue)) {
317
317
  setFilters((prevFilters) => ({
@@ -322,13 +322,13 @@ const CheckboxFilter = ({
322
322
  }, []);
323
323
  const handleChange = (e) => {
324
324
  const {
325
- target: {value, checked}
325
+ target: { value, checked }
326
326
  } = e;
327
327
  setFilters((prevFilters) => {
328
- const {[name]: filter, ...others} = prevFilters;
328
+ const { [name]: filter, ...others } = prevFilters;
329
329
  const rest = (filter || []).filter((i) => i !== value);
330
330
  const items = checked ? [...rest, value] : rest;
331
- return items.length ? {...others, [name]: items} : others;
331
+ return items.length ? { ...others, [name]: items } : others;
332
332
  });
333
333
  };
334
334
  return /* @__PURE__ */ React__default.createElement(FormControl, {
@@ -344,7 +344,7 @@ const CheckboxFilter = ({
344
344
  control: /* @__PURE__ */ React__default.createElement(Checkbox, {
345
345
  color: "primary",
346
346
  tabIndex: -1,
347
- inputProps: {"aria-labelledby": value},
347
+ inputProps: { "aria-labelledby": value },
348
348
  value,
349
349
  name: value,
350
350
  onChange: handleChange,
@@ -361,7 +361,7 @@ const SelectFilter = ({
361
361
  values = []
362
362
  }) => {
363
363
  const classes = useStyles$7();
364
- const {filters, setFilters} = useSearch();
364
+ const { filters, setFilters } = useSearch();
365
365
  useEffect(() => {
366
366
  if (typeof defaultValue === "string") {
367
367
  setFilters((prevFilters) => ({
@@ -372,11 +372,11 @@ const SelectFilter = ({
372
372
  }, []);
373
373
  const handleChange = (e) => {
374
374
  const {
375
- target: {value}
375
+ target: { value }
376
376
  } = e;
377
377
  setFilters((prevFilters) => {
378
- const {[name]: filter, ...others} = prevFilters;
379
- return value ? {...others, [name]: value} : others;
378
+ const { [name]: filter, ...others } = prevFilters;
379
+ return value ? { ...others, [name]: value } : others;
380
380
  });
381
381
  };
382
382
  return /* @__PURE__ */ React__default.createElement(FormControl, {
@@ -398,7 +398,7 @@ const SelectFilter = ({
398
398
  value
399
399
  }, value))));
400
400
  };
401
- const SearchFilter = ({component: Element, ...props}) => /* @__PURE__ */ React__default.createElement(Element, {
401
+ const SearchFilter = ({ component: Element, ...props }) => /* @__PURE__ */ React__default.createElement(Element, {
402
402
  ...props
403
403
  });
404
404
  SearchFilter.Checkbox = (props) => /* @__PURE__ */ React__default.createElement(SearchFilter, {
@@ -415,9 +415,9 @@ var Launch = createSvgIcon( /*#__PURE__*/React.createElement("path", {
415
415
  d: "M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z"
416
416
  }), 'Launch');
417
417
 
418
- const SearchResultComponent = ({children}) => {
418
+ const SearchResultComponent = ({ children }) => {
419
419
  const {
420
- result: {loading, error, value}
420
+ result: { loading, error, value }
421
421
  } = useSearch();
422
422
  if (loading) {
423
423
  return /* @__PURE__ */ React__default.createElement(Progress, null);
@@ -434,7 +434,7 @@ const SearchResultComponent = ({children}) => {
434
434
  title: "Sorry, no results were found"
435
435
  });
436
436
  }
437
- return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, children({results: value.results}));
437
+ return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, children({ results: value.results }));
438
438
  };
439
439
 
440
440
  const useStyles$6 = makeStyles((theme) => ({
@@ -446,7 +446,7 @@ const useStyles$6 = makeStyles((theme) => ({
446
446
  }
447
447
  }));
448
448
  const SearchResultPager = () => {
449
- const {fetchNextPage, fetchPreviousPage} = useSearch();
449
+ const { fetchNextPage, fetchPreviousPage } = useSearch();
450
450
  const classes = useStyles$6();
451
451
  if (!fetchNextPage && !fetchPreviousPage) {
452
452
  return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null);
@@ -478,9 +478,9 @@ const searchPlugin = createPlugin({
478
478
  apis: [
479
479
  createApiFactory({
480
480
  api: searchApiRef,
481
- deps: {discoveryApi: discoveryApiRef, identityApi: identityApiRef},
482
- factory: ({discoveryApi, identityApi}) => {
483
- return new SearchClient({discoveryApi, identityApi});
481
+ deps: { discoveryApi: discoveryApiRef, identityApi: identityApiRef },
482
+ factory: ({ discoveryApi, identityApi }) => {
483
+ return new SearchClient({ discoveryApi, identityApi });
484
484
  }
485
485
  })
486
486
  ],
@@ -491,54 +491,54 @@ const searchPlugin = createPlugin({
491
491
  });
492
492
  const SearchPage$1 = searchPlugin.provide(createRoutableExtension({
493
493
  name: "SearchPage",
494
- component: () => import('./index-09bfa46d.esm.js').then((m) => m.SearchPage),
494
+ component: () => import('./index-04d32ed0.esm.js').then((m) => m.SearchPage),
495
495
  mountPoint: rootRouteRef
496
496
  }));
497
497
  const SearchPageNext = searchPlugin.provide(createRoutableExtension({
498
498
  name: "SearchPageNext",
499
- component: () => import('./index-09bfa46d.esm.js').then((m) => m.SearchPage),
499
+ component: () => import('./index-04d32ed0.esm.js').then((m) => m.SearchPage),
500
500
  mountPoint: rootNextRouteRef
501
501
  }));
502
502
  searchPlugin.provide(createComponentExtension({
503
503
  name: "SearchBar",
504
504
  component: {
505
- lazy: () => import('./index-1f69649c.esm.js').then((m) => m.SearchBar)
505
+ lazy: () => import('./index-bfe6f2c6.esm.js').then((m) => m.SearchBar)
506
506
  }
507
507
  }));
508
508
  const SearchBarNext = searchPlugin.provide(createComponentExtension({
509
509
  name: "SearchBarNext",
510
510
  component: {
511
- lazy: () => import('./index-1f69649c.esm.js').then((m) => m.SearchBar)
511
+ lazy: () => import('./index-bfe6f2c6.esm.js').then((m) => m.SearchBar)
512
512
  }
513
513
  }));
514
514
  const SearchResult$1 = searchPlugin.provide(createComponentExtension({
515
515
  name: "SearchResult",
516
516
  component: {
517
- lazy: () => import('./index-49a2f5d1.esm.js').then((m) => m.SearchResult)
517
+ lazy: () => import('./index-3cbe4558.esm.js').then((m) => m.SearchResult)
518
518
  }
519
519
  }));
520
520
  searchPlugin.provide(createComponentExtension({
521
521
  name: "SearchResultNext",
522
522
  component: {
523
- lazy: () => import('./index-49a2f5d1.esm.js').then((m) => m.SearchResult)
523
+ lazy: () => import('./index-3cbe4558.esm.js').then((m) => m.SearchResult)
524
524
  }
525
525
  }));
526
526
  const SidebarSearchModal = searchPlugin.provide(createComponentExtension({
527
527
  name: "SidebarSearchModal",
528
528
  component: {
529
- lazy: () => import('./index-859ff534.esm.js').then((m) => m.SidebarSearchModal)
529
+ lazy: () => import('./index-ca07a7cd.esm.js').then((m) => m.SidebarSearchModal)
530
530
  }
531
531
  }));
532
532
  const DefaultResultListItem = searchPlugin.provide(createComponentExtension({
533
533
  name: "DefaultResultListItem",
534
534
  component: {
535
- lazy: () => import('./index-b647c19e.esm.js').then((m) => m.DefaultResultListItem)
535
+ lazy: () => import('./index-e9bf7392.esm.js').then((m) => m.DefaultResultListItem)
536
536
  }
537
537
  }));
538
538
  const HomePageSearchBar = searchPlugin.provide(createComponentExtension({
539
539
  name: "HomePageSearchBar",
540
540
  component: {
541
- lazy: () => import('./index-58cc0fcf.esm.js').then((m) => m.HomePageSearchBar)
541
+ lazy: () => import('./index-bc274d46.esm.js').then((m) => m.HomePageSearchBar)
542
542
  }
543
543
  }));
544
544
 
@@ -551,14 +551,14 @@ const useStyles$5 = makeStyles$1((theme) => ({
551
551
  input: {
552
552
  flex: 1
553
553
  },
554
- paperFullWidth: {height: "calc(100% - 128px)"},
555
- dialogActionsContainer: {padding: theme.spacing(1, 3)},
556
- viewResultsLink: {verticalAlign: "0.5em"}
554
+ paperFullWidth: { height: "calc(100% - 128px)" },
555
+ dialogActionsContainer: { padding: theme.spacing(1, 3) },
556
+ viewResultsLink: { verticalAlign: "0.5em" }
557
557
  }));
558
- const Modal = ({open = true, toggleModal}) => {
558
+ const Modal = ({ open = true, toggleModal }) => {
559
559
  const getSearchLink = useRouteRef(rootRouteRef);
560
560
  const classes = useStyles$5();
561
- const {term, setTerm} = useSearch();
561
+ const { term, setTerm } = useSearch();
562
562
  const [value, setValue] = useState(term);
563
563
  useEffect(() => {
564
564
  setValue((prevValue) => prevValue !== term ? term : prevValue);
@@ -605,7 +605,7 @@ const Modal = ({open = true, toggleModal}) => {
605
605
  className: classes.viewResultsLink
606
606
  }, "View Full Results"), /* @__PURE__ */ React__default.createElement(Launch, {
607
607
  color: "primary"
608
- })))), /* @__PURE__ */ React__default.createElement(Divider, null), /* @__PURE__ */ React__default.createElement(SearchResultComponent, null, ({results}) => /* @__PURE__ */ React__default.createElement(List, null, results.map(({document}) => /* @__PURE__ */ React__default.createElement("div", {
608
+ })))), /* @__PURE__ */ React__default.createElement(Divider, null), /* @__PURE__ */ React__default.createElement(SearchResultComponent, null, ({ results }) => /* @__PURE__ */ React__default.createElement(List, null, results.map(({ document }) => /* @__PURE__ */ React__default.createElement("div", {
609
609
  role: "button",
610
610
  tabIndex: 0,
611
611
  key: `${document.location}-btn`,
@@ -624,7 +624,7 @@ const Modal = ({open = true, toggleModal}) => {
624
624
  xs: 12
625
625
  }, /* @__PURE__ */ React__default.createElement(SearchResultPager, null)))));
626
626
  };
627
- const SearchModal = ({open = true, toggleModal}) => {
627
+ const SearchModal = ({ open = true, toggleModal }) => {
628
628
  return /* @__PURE__ */ React__default.createElement(SearchContextProvider, null, /* @__PURE__ */ React__default.createElement(Modal, {
629
629
  open,
630
630
  toggleModal
@@ -659,7 +659,7 @@ const SearchBar = ({
659
659
  placeholder: "Search in Backstage",
660
660
  value: searchQuery,
661
661
  onChange: (e) => handleSearch(e),
662
- inputProps: {"aria-label": "search backstage"}
662
+ inputProps: { "aria-label": "search backstage" }
663
663
  }), /* @__PURE__ */ React__default.createElement(IconButton$1, {
664
664
  "aria-label": "search",
665
665
  onClick: () => handleClearSearchBar()
@@ -832,7 +832,7 @@ const TableHeader = ({
832
832
  variant: "h6"
833
833
  }, `${numberOfResults} results`)));
834
834
  };
835
- const SearchResult = ({searchQuery}) => {
835
+ const SearchResult = ({ searchQuery }) => {
836
836
  const catalogApi = useApi(catalogApiRef);
837
837
  const [showFilters, toggleFilters] = useState(false);
838
838
  const [selectedFilters, setSelectedFilters] = useState({
@@ -942,7 +942,7 @@ const SearchResult = ({searchQuery}) => {
942
942
  item: true,
943
943
  xs: showFilters ? 9 : 12
944
944
  }, /* @__PURE__ */ React__default.createElement(Table, {
945
- options: {paging: true, pageSize: 20, search: false},
945
+ options: { paging: true, pageSize: 20, search: false },
946
946
  data: filteredResults,
947
947
  columns,
948
948
  title: /* @__PURE__ */ React__default.createElement(TableHeader, {
@@ -1007,7 +1007,7 @@ const UrlUpdater = () => {
1007
1007
  if (location.search === prevQueryParams) {
1008
1008
  return;
1009
1009
  }
1010
- const query = qs.parse(location.search.substring(1), {arrayLimit: 0}) || {};
1010
+ const query = qs.parse(location.search.substring(1), { arrayLimit: 0 }) || {};
1011
1011
  if (query.filters) {
1012
1012
  setFilters(query.filters);
1013
1013
  }
@@ -1027,7 +1027,7 @@ const UrlUpdater = () => {
1027
1027
  types,
1028
1028
  pageCursor,
1029
1029
  filters
1030
- }, {arrayFormat: "brackets"});
1030
+ }, { arrayFormat: "brackets" });
1031
1031
  const newUrl = `${window.location.pathname}?${newParams}`;
1032
1032
  window.history.replaceState(null, document.title, newUrl);
1033
1033
  }, [term, types, pageCursor, filters]);
@@ -1058,7 +1058,7 @@ const SearchType = ({
1058
1058
  defaultValue
1059
1059
  }) => {
1060
1060
  const classes = useStyles();
1061
- const {types, setTypes} = useSearch();
1061
+ const { types, setTypes } = useSearch();
1062
1062
  useEffectOnce(() => {
1063
1063
  if (!types.length) {
1064
1064
  if (defaultValue && Array.isArray(defaultValue)) {
@@ -1108,7 +1108,7 @@ const SidebarSearch = () => {
1108
1108
  const searchRoute = useRouteRef(rootRouteRef);
1109
1109
  const navigate = useNavigate();
1110
1110
  const handleSearch = useCallback((query) => {
1111
- const queryString = qs.stringify({query}, {addQueryPrefix: true});
1111
+ const queryString = qs.stringify({ query }, { addQueryPrefix: true });
1112
1112
  navigate(`${searchRoute()}${queryString}`);
1113
1113
  }, [navigate, searchRoute]);
1114
1114
  return /* @__PURE__ */ React__default.createElement(SidebarSearchField, {
@@ -1118,4 +1118,4 @@ const SidebarSearch = () => {
1118
1118
  };
1119
1119
 
1120
1120
  export { DefaultResultListItem$1 as D, Filters$1 as F, HomePageSearchBar as H, SearchPage as S, SearchBar$1 as a, SearchBarBase as b, SearchResultComponent as c, SearchModal as d, FiltersButton$1 as e, SearchContextProvider as f, SearchFilter as g, SearchFilterNext as h, SearchResultPager as i, SearchType as j, SidebarSearch as k, DefaultResultListItem as l, SearchBarNext as m, SearchPage$1 as n, SearchPageNext as o, searchPlugin as p, SearchResult$1 as q, rootRouteRef as r, searchApiRef as s, SidebarSearchModal as t, useSearch as u };
1121
- //# sourceMappingURL=index-8e7d7ce9.esm.js.map
1121
+ //# sourceMappingURL=index-893ec2f5.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-8e7d7ce9.esm.js","sources":["../../src/apis.ts","../../src/components/DefaultResultListItem/DefaultResultListItem.tsx","../../src/components/Filters/FiltersButton.tsx","../../src/components/Filters/Filters.tsx","../../src/components/SearchContext/SearchContext.tsx","../../src/components/SearchBar/SearchBar.tsx","../../src/components/SearchFilter/SearchFilter.tsx","../../../../node_modules/@material-ui/icons/esm/Launch.js","../../src/components/SearchResult/SearchResult.tsx","../../src/components/SearchResultPager/SearchResultPager.tsx","../../src/plugin.ts","../../src/components/SearchModal/SearchModal.tsx","../../src/components/LegacySearchPage/LegacySearchBar.tsx","../../src/components/LegacySearchPage/Filters/FiltersButton.tsx","../../src/components/LegacySearchPage/Filters/Filters.tsx","../../src/components/LegacySearchPage/LegacySearchResult.tsx","../../src/components/LegacySearchPage/LegacySearchPage.tsx","../../src/components/SearchPage/SearchPage.tsx","../../src/components/SearchType/SearchType.tsx","../../src/components/SidebarSearch/SidebarSearch.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n createApiRef,\n DiscoveryApi,\n IdentityApi,\n} from '@backstage/core-plugin-api';\nimport { ResponseError } from '@backstage/errors';\nimport { SearchQuery, SearchResultSet } from '@backstage/search-common';\nimport qs from 'qs';\n\nexport const searchApiRef = createApiRef<SearchApi>({\n id: 'plugin.search.queryservice',\n description: 'Used to make requests against the search API',\n});\n\nexport interface SearchApi {\n query(query: SearchQuery): Promise<SearchResultSet>;\n}\n\nexport class SearchClient implements SearchApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly identityApi: IdentityApi;\n\n constructor(options: {\n discoveryApi: DiscoveryApi;\n identityApi: IdentityApi;\n }) {\n this.discoveryApi = options.discoveryApi;\n this.identityApi = options.identityApi;\n }\n\n async query(query: SearchQuery): Promise<SearchResultSet> {\n const token = await this.identityApi.getIdToken();\n const queryString = qs.stringify(query);\n const url = `${await this.discoveryApi.getBaseUrl(\n 'search/query',\n )}?${queryString}`;\n const response = await fetch(url, {\n headers: token ? { Authorization: `Bearer ${token}` } : {},\n });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json();\n }\n}\n","/*\n * Copyright 2021 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 { IndexableDocument } from '@backstage/search-common';\nimport {\n ListItem,\n ListItemIcon,\n ListItemText,\n Box,\n Divider,\n} from '@material-ui/core';\nimport { Link } from '@backstage/core-components';\n\ntype Props = {\n icon?: ReactNode;\n secondaryAction?: ReactNode;\n result: IndexableDocument;\n};\n\nexport const DefaultResultListItem = ({\n result,\n icon,\n secondaryAction,\n}: Props) => {\n return (\n <Link to={result.location}>\n <ListItem alignItems=\"center\">\n {icon && <ListItemIcon>{icon}</ListItemIcon>}\n <ListItemText\n primaryTypographyProps={{ variant: 'h6' }}\n primary={result.title}\n secondary={result.text}\n />\n {secondaryAction && <Box alignItems=\"flex-end\">{secondaryAction}</Box>}\n </ListItem>\n <Divider />\n </Link>\n );\n};\n","/*\n * Copyright 2020 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 FilterListIcon from '@material-ui/icons/FilterList';\nimport { makeStyles, IconButton, Typography } from '@material-ui/core';\n\nconst useStyles = makeStyles(theme => ({\n filters: {\n width: '250px',\n display: 'flex',\n },\n icon: {\n margin: theme.spacing(-1, 0, 0, 0),\n },\n}));\n\ntype FiltersButtonProps = {\n numberOfSelectedFilters: number;\n handleToggleFilters: () => void;\n};\n\nexport const FiltersButton = ({\n numberOfSelectedFilters,\n handleToggleFilters,\n}: FiltersButtonProps) => {\n const classes = useStyles();\n\n return (\n <div className={classes.filters}>\n <IconButton\n className={classes.icon}\n aria-label=\"settings\"\n onClick={handleToggleFilters}\n >\n <FilterListIcon />\n </IconButton>\n <Typography variant=\"h6\">\n Filters ({numberOfSelectedFilters ? numberOfSelectedFilters : 0})\n </Typography>\n </div>\n );\n};\n","/*\n * Copyright 2020 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 {\n makeStyles,\n Typography,\n Divider,\n Card,\n CardHeader,\n Button,\n CardContent,\n Select,\n Checkbox,\n List,\n ListItem,\n ListItemText,\n MenuItem,\n} from '@material-ui/core';\n\nconst useStyles = makeStyles(theme => ({\n filters: {\n background: 'transparent',\n boxShadow: '0px 0px 0px 0px',\n },\n checkbox: {\n padding: theme.spacing(0, 1, 0, 1),\n },\n dropdown: {\n width: '100%',\n },\n}));\n\nexport type FiltersState = {\n selected: string;\n checked: Array<string>;\n};\n\nexport type FilterOptions = {\n kind: Array<string>;\n lifecycle: Array<string>;\n};\n\ntype FiltersProps = {\n filters: FiltersState;\n filterOptions: FilterOptions;\n resetFilters: () => void;\n updateSelected: (filter: string) => void;\n updateChecked: (filter: string) => void;\n};\n\nexport const Filters = ({\n filters,\n filterOptions,\n resetFilters,\n updateSelected,\n updateChecked,\n}: FiltersProps) => {\n const classes = useStyles();\n\n return (\n <Card className={classes.filters}>\n <CardHeader\n title={<Typography variant=\"h6\">Filters</Typography>}\n action={\n <Button color=\"primary\" onClick={() => resetFilters()}>\n CLEAR ALL\n </Button>\n }\n />\n <Divider />\n {filterOptions.kind.length === 0 && filterOptions.lifecycle.length === 0 && (\n <CardContent>\n <Typography variant=\"subtitle2\">\n Filters cannot be applied to available results\n </Typography>\n </CardContent>\n )}\n {filterOptions.kind.length > 0 && (\n <CardContent>\n <Typography variant=\"subtitle2\">Kind</Typography>\n <Select\n id=\"outlined-select\"\n onChange={(e: React.ChangeEvent<any>) =>\n updateSelected(e?.target?.value)\n }\n variant=\"outlined\"\n className={classes.dropdown}\n value={filters.selected}\n >\n {filterOptions.kind.map(filter => (\n <MenuItem\n selected={filter === ''}\n dense\n key={filter}\n value={filter}\n >\n {filter}\n </MenuItem>\n ))}\n </Select>\n </CardContent>\n )}\n {filterOptions.lifecycle.length > 0 && (\n <CardContent>\n <Typography variant=\"subtitle2\">Lifecycle</Typography>\n <List disablePadding dense>\n {filterOptions.lifecycle.map(filter => (\n <ListItem\n key={filter}\n dense\n button\n onClick={() => updateChecked(filter)}\n >\n <Checkbox\n edge=\"start\"\n disableRipple\n className={classes.checkbox}\n color=\"primary\"\n checked={filters.checked.includes(filter)}\n tabIndex={-1}\n value={filter}\n name={filter}\n />\n <ListItemText id={filter} primary={filter} />\n </ListItem>\n ))}\n </List>\n </CardContent>\n )}\n </Card>\n );\n};\n","/*\n * Copyright 2021 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 { JsonObject } from '@backstage/types';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { SearchResultSet } from '@backstage/search-common';\nimport React, {\n createContext,\n PropsWithChildren,\n useCallback,\n useContext,\n useEffect,\n useState,\n} from 'react';\nimport { useAsync, usePrevious } from 'react-use';\nimport { AsyncState } from 'react-use/lib/useAsync';\nimport { searchApiRef } from '../../apis';\n\ntype SearchContextValue = {\n result: AsyncState<SearchResultSet>;\n term: string;\n setTerm: React.Dispatch<React.SetStateAction<string>>;\n types: string[];\n setTypes: React.Dispatch<React.SetStateAction<string[]>>;\n filters: JsonObject;\n setFilters: React.Dispatch<React.SetStateAction<JsonObject>>;\n open?: boolean;\n toggleModal: () => void;\n pageCursor?: string;\n setPageCursor: React.Dispatch<React.SetStateAction<string | undefined>>;\n fetchNextPage?: React.DispatchWithoutAction;\n fetchPreviousPage?: React.DispatchWithoutAction;\n};\n\ntype SettableSearchContext = Omit<\n SearchContextValue,\n | 'result'\n | 'setTerm'\n | 'setTypes'\n | 'setFilters'\n | 'toggleModal'\n | 'setPageCursor'\n | 'fetchNextPage'\n | 'fetchPreviousPage'\n>;\n\nexport const SearchContext = createContext<SearchContextValue | undefined>(\n undefined,\n);\n\nexport const SearchContextProvider = ({\n initialState = {\n term: '',\n pageCursor: undefined,\n filters: {},\n types: [],\n },\n children,\n}: PropsWithChildren<{ initialState?: SettableSearchContext }>) => {\n const searchApi = useApi(searchApiRef);\n const [pageCursor, setPageCursor] = useState<string | undefined>(\n initialState.pageCursor,\n );\n const [filters, setFilters] = useState<JsonObject>(initialState.filters);\n const [term, setTerm] = useState<string>(initialState.term);\n const [types, setTypes] = useState<string[]>(initialState.types);\n const [open, setOpen] = useState<boolean>(false);\n const toggleModal = useCallback(\n (): void => setOpen(prevState => !prevState),\n [],\n );\n\n const prevTerm = usePrevious(term);\n\n const result = useAsync(\n () =>\n searchApi.query({\n term,\n filters,\n pageCursor: pageCursor,\n types,\n }),\n [term, filters, types, 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 if (term && prevTerm && term !== prevTerm) {\n setPageCursor(undefined);\n }\n }, [term, prevTerm, initialState.pageCursor]);\n\n const value: SearchContextValue = {\n result,\n filters,\n setFilters,\n open,\n toggleModal,\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 <SearchContext.Provider value={value} children={children} />;\n};\n\nexport const useSearch = () => {\n const context = useContext(SearchContext);\n if (context === undefined) {\n throw new Error('useSearch must be used within a SearchContextProvider');\n }\n return context;\n};\n","/*\n * Copyright 2021 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, KeyboardEvent, useState } from 'react';\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport { useDebounce } from 'react-use';\nimport { InputBase, InputAdornment, IconButton } from '@material-ui/core';\nimport SearchIcon from '@material-ui/icons/Search';\nimport ClearButton from '@material-ui/icons/Clear';\n\nimport { useSearch } from '../SearchContext';\n\ntype PresenterProps = {\n value: string;\n onChange: (value: string) => void;\n onClear?: () => void;\n onSubmit?: () => void;\n className?: string;\n placeholder?: string;\n autoFocus?: boolean;\n clearButton?: boolean;\n};\n\nexport const SearchBarBase = ({\n autoFocus,\n value,\n onChange,\n onSubmit,\n className,\n placeholder: overridePlaceholder,\n clearButton = true,\n}: PresenterProps) => {\n const configApi = useApi(configApiRef);\n\n const onKeyDown = React.useCallback(\n (e: KeyboardEvent<HTMLInputElement>) => {\n if (onSubmit && e.key === 'Enter') {\n onSubmit();\n }\n },\n [onSubmit],\n );\n\n const handleClear = React.useCallback(() => {\n onChange('');\n }, [onChange]);\n\n const placeholder =\n overridePlaceholder ??\n `Search in ${configApi.getOptionalString('app.title') || 'Backstage'}`;\n\n return (\n <InputBase\n // decision up to adopter, read https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-autofocus.md#no-autofocus\n // eslint-disable-next-line jsx-a11y/no-autofocus\n autoFocus={autoFocus}\n data-testid=\"search-bar-next\"\n fullWidth\n placeholder={placeholder}\n value={value}\n onChange={e => onChange(e.target.value)}\n inputProps={{ 'aria-label': 'Search' }}\n startAdornment={\n <InputAdornment position=\"start\">\n <IconButton aria-label=\"Query\" disabled>\n <SearchIcon />\n </IconButton>\n </InputAdornment>\n }\n endAdornment={\n clearButton && (\n <InputAdornment position=\"end\">\n <IconButton aria-label=\"Clear\" onClick={handleClear}>\n <ClearButton />\n </IconButton>\n </InputAdornment>\n )\n }\n {...(className && { className })}\n {...(onSubmit && { onKeyDown })}\n />\n );\n};\n\ntype Props = {\n autoFocus?: boolean;\n className?: string;\n debounceTime?: number;\n placeholder?: string;\n clearButton?: boolean;\n};\n\nexport const SearchBar = ({\n autoFocus,\n className,\n debounceTime = 0,\n placeholder,\n clearButton = true,\n}: Props) => {\n const { term, setTerm } = useSearch();\n const [value, setValue] = useState<string>(term);\n\n useEffect(() => {\n setValue(prevValue => (prevValue !== term ? term : prevValue));\n }, [term]);\n\n useDebounce(() => setTerm(value), debounceTime, [value]);\n\n const handleQuery = (newValue: string) => {\n setValue(newValue);\n };\n\n const handleClear = () => setValue('');\n\n return (\n <SearchBarBase\n // decision up to adopter, read https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-autofocus.md#no-autofocus\n // eslint-disable-next-line jsx-a11y/no-autofocus\n autoFocus={autoFocus}\n className={className}\n value={value}\n onChange={handleQuery}\n onClear={handleClear}\n placeholder={placeholder}\n clearButton={clearButton}\n />\n );\n};\n","/*\n * Copyright 2021 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, useEffect } 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 '../SearchContext';\n\nconst useStyles = makeStyles({\n label: {\n textTransform: 'capitalize',\n },\n});\n\nexport type Component = {\n className?: string;\n name: string;\n values?: string[];\n defaultValue?: string[] | string | null;\n};\n\nexport type Props = Component & {\n component: (props: Component) => ReactElement;\n debug?: boolean;\n};\n\nconst CheckboxFilter = ({\n className,\n name,\n defaultValue,\n values = [],\n}: Component) => {\n const classes = useStyles();\n const { filters, setFilters } = useSearch();\n\n useEffect(() => {\n if (Array.isArray(defaultValue)) {\n setFilters(prevFilters => ({\n ...prevFilters,\n [name]: defaultValue,\n }));\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\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 fullWidth\n data-testid=\"search-checkboxfilter-next\"\n >\n <FormLabel className={classes.label}>{name}</FormLabel>\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\nconst SelectFilter = ({\n className,\n name,\n defaultValue,\n values = [],\n}: Component) => {\n const classes = useStyles();\n const { filters, setFilters } = useSearch();\n\n useEffect(() => {\n if (typeof defaultValue === 'string') {\n setFilters(prevFilters => ({\n ...prevFilters,\n [name]: defaultValue,\n }));\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\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 className={className}\n variant=\"filled\"\n fullWidth\n data-testid=\"search-selectfilter-next\"\n >\n <InputLabel className={classes.label} margin=\"dense\">\n {name}\n </InputLabel>\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\nconst SearchFilter = ({ component: Element, ...props }: Props) => (\n <Element {...props} />\n);\n\nSearchFilter.Checkbox = (props: Omit<Props, 'component'> & Component) => (\n <SearchFilter {...props} component={CheckboxFilter} />\n);\n\nSearchFilter.Select = (props: Omit<Props, 'component'> & Component) => (\n <SearchFilter {...props} component={SelectFilter} />\n);\n\n/**\n * @deprecated This component was used for rapid prototyping of the Backstage\n * Search platform. Now that the API has stabilized, you should use the\n * <SearchFilter /> component instead. This component will be removed in an\n * upcoming release.\n */\nconst SearchFilterNext = SearchFilter;\n\nexport { SearchFilter, SearchFilterNext };\n","import * as React from 'react';\nimport createSvgIcon from './utils/createSvgIcon';\nexport default createSvgIcon( /*#__PURE__*/React.createElement(\"path\", {\n d: \"M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z\"\n}), 'Launch');","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n EmptyState,\n Progress,\n ResponseErrorPanel,\n} from '@backstage/core-components';\nimport { SearchResult } from '@backstage/search-common';\nimport React from 'react';\nimport { useSearch } from '../SearchContext';\n\ntype Props = {\n children: (results: { results: SearchResult[] }) => JSX.Element;\n};\n\nexport const SearchResultComponent = ({ children }: Props) => {\n const {\n result: { loading, error, value },\n } = useSearch();\n\n if (loading) {\n return <Progress />;\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 <EmptyState missing=\"data\" title=\"Sorry, no results were found\" />;\n }\n\n return <>{children({ results: value.results })}</>;\n};\n\nexport { SearchResultComponent as SearchResult };\n","/*\n * Copyright 2021 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 { Button, makeStyles } from '@material-ui/core';\nimport ArrowBackIosIcon from '@material-ui/icons/ArrowBackIos';\nimport ArrowForwardIosIcon from '@material-ui/icons/ArrowForwardIos';\nimport React from 'react';\nimport { useSearch } from '../SearchContext';\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\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 arial-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 2020 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 { SearchClient, searchApiRef } from './apis';\nimport {\n createApiFactory,\n createPlugin,\n createRouteRef,\n createRoutableExtension,\n discoveryApiRef,\n createComponentExtension,\n identityApiRef,\n} from '@backstage/core-plugin-api';\n\nexport const rootRouteRef = createRouteRef({\n id: 'search',\n});\n\nexport const rootNextRouteRef = createRouteRef({\n id: 'search:next',\n});\n\nexport const searchPlugin = createPlugin({\n id: 'search',\n apis: [\n createApiFactory({\n api: searchApiRef,\n deps: { discoveryApi: discoveryApiRef, identityApi: identityApiRef },\n factory: ({ discoveryApi, identityApi }) => {\n return new SearchClient({ discoveryApi, identityApi });\n },\n }),\n ],\n routes: {\n root: rootRouteRef,\n nextRoot: rootNextRouteRef,\n },\n});\n\nexport const SearchPage = searchPlugin.provide(\n createRoutableExtension({\n name: 'SearchPage',\n component: () => import('./components/SearchPage').then(m => m.SearchPage),\n mountPoint: rootRouteRef,\n }),\n);\n\n/**\n * @deprecated This component was used for rapid prototyping of the Backstage\n * Search platform. Now that the API has stabilized, you should use the\n * <SearchPage /> component instead. This component will be removed in an\n * upcoming release.\n */\nexport const SearchPageNext = searchPlugin.provide(\n createRoutableExtension({\n name: 'SearchPageNext',\n component: () => import('./components/SearchPage').then(m => m.SearchPage),\n mountPoint: rootNextRouteRef,\n }),\n);\n\nexport const SearchBar = searchPlugin.provide(\n createComponentExtension({\n name: 'SearchBar',\n component: {\n lazy: () => import('./components/SearchBar').then(m => m.SearchBar),\n },\n }),\n);\n\n/**\n * @deprecated This component was used for rapid prototyping of the Backstage\n * Search platform. Now that the API has stabilized, you should use the\n * <SearchBar /> component instead. This component will be removed in an\n * upcoming release.\n */\nexport const SearchBarNext = searchPlugin.provide(\n createComponentExtension({\n name: 'SearchBarNext',\n component: {\n lazy: () => import('./components/SearchBar').then(m => m.SearchBar),\n },\n }),\n);\n\nexport const SearchResult = searchPlugin.provide(\n createComponentExtension({\n name: 'SearchResult',\n component: {\n lazy: () => import('./components/SearchResult').then(m => m.SearchResult),\n },\n }),\n);\n\n/**\n * @deprecated This component was used for rapid prototyping of the Backstage\n * Search platform. Now that the API has stabilized, you should use the\n * <SearchResult /> component instead. This component will be removed in an\n * upcoming release.\n */\nexport const SearchResultNext = searchPlugin.provide(\n createComponentExtension({\n name: 'SearchResultNext',\n component: {\n lazy: () => import('./components/SearchResult').then(m => m.SearchResult),\n },\n }),\n);\n\nexport const SidebarSearchModal = searchPlugin.provide(\n createComponentExtension({\n name: 'SidebarSearchModal',\n component: {\n lazy: () =>\n import('./components/SidebarSearchModal').then(\n m => m.SidebarSearchModal,\n ),\n },\n }),\n);\n\nexport const DefaultResultListItem = searchPlugin.provide(\n createComponentExtension({\n name: 'DefaultResultListItem',\n component: {\n lazy: () =>\n import('./components/DefaultResultListItem').then(\n m => m.DefaultResultListItem,\n ),\n },\n }),\n);\n\nexport const HomePageSearchBar = searchPlugin.provide(\n createComponentExtension({\n name: 'HomePageSearchBar',\n component: {\n lazy: () =>\n import('./components/HomePageComponent').then(m => m.HomePageSearchBar),\n },\n }),\n);\n","/*\n * Copyright 2021 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 */\nimport React, { useEffect, useState } from 'react';\nimport {\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n Divider,\n Grid,\n List,\n Paper,\n} from '@material-ui/core';\nimport { Launch } from '@material-ui/icons/';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { SearchBarBase } from '../SearchBar';\nimport { DefaultResultListItem } from '../DefaultResultListItem';\nimport { SearchResult } from '../SearchResult';\nimport { SearchContextProvider, useSearch } from '../SearchContext';\nimport { SearchResultPager } from '../SearchResultPager';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport { Link } from '@backstage/core-components';\nimport { rootRouteRef } from '../../plugin';\n\nimport { useDebounce } from 'react-use';\n\nexport interface SearchModalProps {\n open?: boolean;\n toggleModal: () => void;\n}\n\nconst useStyles = makeStyles(theme => ({\n container: {\n borderRadius: 30,\n display: 'flex',\n height: '2.4em',\n },\n input: {\n flex: 1,\n },\n // Reduces default height of the modal, keeping a gap of 128px between the top and bottom of the page.\n paperFullWidth: { height: 'calc(100% - 128px)' },\n dialogActionsContainer: { padding: theme.spacing(1, 3) },\n viewResultsLink: { verticalAlign: '0.5em' },\n}));\n\nexport const Modal = ({ open = true, toggleModal }: SearchModalProps) => {\n const getSearchLink = useRouteRef(rootRouteRef);\n const classes = useStyles();\n\n const { term, setTerm } = useSearch();\n const [value, setValue] = useState<string>(term);\n\n useEffect(() => {\n setValue(prevValue => (prevValue !== term ? term : prevValue));\n }, [term]);\n\n useDebounce(() => setTerm(value), 500, [value]);\n\n const handleQuery = (newValue: string) => {\n setValue(newValue);\n };\n\n const handleClear = () => setValue('');\n\n const handleResultClick = () => {\n toggleModal();\n handleClear();\n };\n\n const handleKeyPress = () => {\n handleResultClick();\n };\n\n return (\n <Dialog\n classes={{\n paperFullWidth: classes.paperFullWidth,\n }}\n onClose={toggleModal}\n aria-labelledby=\"search-modal-title\"\n open={open}\n fullWidth\n maxWidth=\"lg\"\n >\n <DialogTitle>\n <Paper className={classes.container}>\n <SearchBarBase\n className={classes.input}\n value={value}\n onChange={handleQuery}\n onClear={handleClear}\n />\n </Paper>\n </DialogTitle>\n <DialogContent>\n <Grid\n container\n direction=\"row-reverse\"\n justifyContent=\"flex-start\"\n alignItems=\"center\"\n >\n <Grid item>\n <Link\n onClick={toggleModal}\n to={`${getSearchLink()}?query=${value}`}\n >\n <span className={classes.viewResultsLink}>View Full Results</span>\n <Launch color=\"primary\" />\n </Link>\n </Grid>\n </Grid>\n <Divider />\n <SearchResult>\n {({ results }) => (\n <List>\n {results.map(({ document }) => (\n <div\n role=\"button\"\n tabIndex={0}\n key={`${document.location}-btn`}\n onClick={handleResultClick}\n onKeyPress={handleKeyPress}\n >\n <DefaultResultListItem\n key={document.location}\n result={document}\n />\n </div>\n ))}\n </List>\n )}\n </SearchResult>\n </DialogContent>\n <DialogActions className={classes.dialogActionsContainer}>\n <Grid container direction=\"row\">\n <Grid item xs={12}>\n <SearchResultPager />\n </Grid>\n </Grid>\n </DialogActions>\n </Dialog>\n );\n};\n\nexport const SearchModal = ({ open = true, toggleModal }: SearchModalProps) => {\n return (\n <SearchContextProvider>\n <Modal open={open} toggleModal={toggleModal} />\n </SearchContextProvider>\n );\n};\n","/*\n * Copyright 2020 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 { makeStyles } from '@material-ui/core/styles';\nimport { Paper } from '@material-ui/core';\nimport InputBase from '@material-ui/core/InputBase';\nimport IconButton from '@material-ui/core/IconButton';\nimport SearchIcon from '@material-ui/icons/Search';\nimport ClearButton from '@material-ui/icons/Clear';\n\nconst useStyles = makeStyles(() => ({\n root: {\n display: 'flex',\n alignItems: 'center',\n },\n input: {\n flex: 1,\n },\n}));\n\ntype SearchBarProps = {\n searchQuery: string;\n handleSearch: any;\n handleClearSearchBar: any;\n};\n\nexport const SearchBar = ({\n searchQuery,\n handleSearch,\n handleClearSearchBar,\n}: SearchBarProps) => {\n const classes = useStyles();\n\n return (\n <Paper\n component=\"form\"\n onSubmit={e => handleSearch(e)}\n className={classes.root}\n >\n <IconButton disabled type=\"submit\" aria-label=\"search\">\n <SearchIcon />\n </IconButton>\n <InputBase\n className={classes.input}\n placeholder=\"Search in Backstage\"\n value={searchQuery}\n onChange={e => handleSearch(e)}\n inputProps={{ 'aria-label': 'search backstage' }}\n />\n <IconButton aria-label=\"search\" onClick={() => handleClearSearchBar()}>\n <ClearButton />\n </IconButton>\n </Paper>\n );\n};\n","/*\n * Copyright 2020 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 FilterListIcon from '@material-ui/icons/FilterList';\nimport { makeStyles, IconButton, Typography } from '@material-ui/core';\n\nconst useStyles = makeStyles(theme => ({\n filters: {\n width: '250px',\n display: 'flex',\n },\n icon: {\n margin: theme.spacing(-1, 0, 0, 0),\n },\n}));\n\ntype FiltersButtonProps = {\n numberOfSelectedFilters: number;\n handleToggleFilters: () => void;\n};\n\nexport const FiltersButton = ({\n numberOfSelectedFilters,\n handleToggleFilters,\n}: FiltersButtonProps) => {\n const classes = useStyles();\n\n return (\n <div className={classes.filters}>\n <IconButton\n className={classes.icon}\n aria-label=\"settings\"\n onClick={handleToggleFilters}\n >\n <FilterListIcon />\n </IconButton>\n <Typography variant=\"h6\">\n Filters ({numberOfSelectedFilters ? numberOfSelectedFilters : 0})\n </Typography>\n </div>\n );\n};\n","/*\n * Copyright 2020 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 {\n makeStyles,\n Typography,\n Divider,\n Card,\n CardHeader,\n Button,\n CardContent,\n Select,\n Checkbox,\n List,\n ListItem,\n ListItemText,\n MenuItem,\n} from '@material-ui/core';\n\nconst useStyles = makeStyles(theme => ({\n filters: {\n background: 'transparent',\n boxShadow: '0px 0px 0px 0px',\n },\n checkbox: {\n padding: theme.spacing(0, 1, 0, 1),\n },\n dropdown: {\n width: '100%',\n },\n}));\n\nexport type FiltersState = {\n selected: string;\n checked: Array<string>;\n};\n\nexport type FilterOptions = {\n kind: Array<string>;\n lifecycle: Array<string>;\n};\n\ntype FiltersProps = {\n filters: FiltersState;\n filterOptions: FilterOptions;\n resetFilters: () => void;\n updateSelected: (filter: string) => void;\n updateChecked: (filter: string) => void;\n};\n\nexport const Filters = ({\n filters,\n filterOptions,\n resetFilters,\n updateSelected,\n updateChecked,\n}: FiltersProps) => {\n const classes = useStyles();\n\n return (\n <Card className={classes.filters}>\n <CardHeader\n title={<Typography variant=\"h6\">Filters</Typography>}\n action={\n <Button color=\"primary\" onClick={() => resetFilters()}>\n CLEAR ALL\n </Button>\n }\n />\n <Divider />\n {filterOptions.kind.length === 0 && filterOptions.lifecycle.length === 0 && (\n <CardContent>\n <Typography variant=\"subtitle2\">\n Filters cannot be applied to available results\n </Typography>\n </CardContent>\n )}\n {filterOptions.kind.length > 0 && (\n <CardContent>\n <Typography variant=\"subtitle2\">Kind</Typography>\n <Select\n id=\"outlined-select\"\n onChange={(e: React.ChangeEvent<any>) =>\n updateSelected(e?.target?.value)\n }\n variant=\"outlined\"\n className={classes.dropdown}\n value={filters.selected}\n >\n {filterOptions.kind.map(filter => (\n <MenuItem\n selected={filter === ''}\n dense\n key={filter}\n value={filter}\n >\n {filter}\n </MenuItem>\n ))}\n </Select>\n </CardContent>\n )}\n {filterOptions.lifecycle.length > 0 && (\n <CardContent>\n <Typography variant=\"subtitle2\">Lifecycle</Typography>\n <List disablePadding dense>\n {filterOptions.lifecycle.map(filter => (\n <ListItem\n key={filter}\n dense\n button\n onClick={() => updateChecked(filter)}\n >\n <Checkbox\n edge=\"start\"\n disableRipple\n className={classes.checkbox}\n color=\"primary\"\n checked={filters.checked.includes(filter)}\n tabIndex={-1}\n value={filter}\n name={filter}\n />\n <ListItemText id={filter} primary={filter} />\n </ListItem>\n ))}\n </List>\n </CardContent>\n )}\n </Card>\n );\n};\n","/*\n * Copyright 2020 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 */\nimport { Divider, Grid, makeStyles, Typography } from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\nimport React, { useEffect, useState } from 'react';\nimport { useAsync } from 'react-use';\nimport { catalogApiRef } from '@backstage/plugin-catalog-react';\n\nimport { Filters, FiltersButton, FiltersState } from './Filters';\nimport { Entity, ENTITY_DEFAULT_NAMESPACE } from '@backstage/catalog-model';\n\nimport {\n EmptyState,\n Link,\n Progress,\n Table,\n TableColumn,\n} from '@backstage/core-components';\nimport { useApi } from '@backstage/core-plugin-api';\n\ntype Result = {\n name: string;\n description: string | undefined;\n owner: string | undefined;\n kind: string;\n lifecycle: string | undefined;\n url: string;\n};\ntype SearchResults = Array<Result>;\n\nconst useStyles = makeStyles(theme => ({\n searchQuery: {\n color: theme.palette.text.primary,\n background: theme.palette.background.default,\n borderRadius: '10%',\n },\n tableHeader: {\n margin: theme.spacing(1, 0, 0, 0),\n display: 'flex',\n },\n divider: {\n width: '1px',\n margin: theme.spacing(0, 2),\n padding: theme.spacing(2, 0),\n },\n}));\n\ntype SearchResultProps = {\n searchQuery?: string;\n};\n\ntype TableHeaderProps = {\n searchQuery?: string;\n numberOfSelectedFilters: number;\n numberOfResults: number;\n handleToggleFilters: () => void;\n};\n\n// TODO: move out column to make the search result component more generic\nconst columns: TableColumn[] = [\n {\n title: 'Name',\n field: 'name',\n highlight: true,\n render: (result: Partial<Result>) => (\n <Link to={result.url || ''}>{result.name}</Link>\n ),\n },\n {\n title: 'Description',\n field: 'description',\n },\n {\n title: 'Owner',\n field: 'owner',\n },\n {\n title: 'Kind',\n field: 'kind',\n },\n {\n title: 'LifeCycle',\n field: 'lifecycle',\n },\n];\n\nconst TableHeader = ({\n searchQuery,\n numberOfSelectedFilters,\n numberOfResults,\n handleToggleFilters,\n}: TableHeaderProps) => {\n const classes = useStyles();\n\n return (\n <div className={classes.tableHeader}>\n <FiltersButton\n numberOfSelectedFilters={numberOfSelectedFilters}\n handleToggleFilters={handleToggleFilters}\n />\n <Divider className={classes.divider} orientation=\"vertical\" />\n <Grid item xs={12}>\n {searchQuery ? (\n <Typography variant=\"h6\">\n {`${numberOfResults} `}\n {numberOfResults > 1 ? `results for ` : `result for `}\n <span className={classes.searchQuery}>\"{searchQuery}\"</span>{' '}\n </Typography>\n ) : (\n <Typography variant=\"h6\">{`${numberOfResults} results`}</Typography>\n )}\n </Grid>\n </div>\n );\n};\n\nexport const SearchResult = ({ searchQuery }: SearchResultProps) => {\n const catalogApi = useApi(catalogApiRef);\n\n const [showFilters, toggleFilters] = useState(false);\n const [selectedFilters, setSelectedFilters] = useState<FiltersState>({\n selected: '',\n checked: [],\n });\n\n const [filteredResults, setFilteredResults] = useState<SearchResults>([]);\n\n const {\n loading,\n error,\n value: results,\n } = useAsync(async () => {\n const entities = await catalogApi.getEntities();\n return entities.items.map((entity: Entity) => ({\n name: entity.metadata.name,\n description: entity.metadata.description,\n owner:\n typeof entity.spec?.owner === 'string' ? entity.spec?.owner : undefined,\n kind: entity.kind,\n lifecycle:\n typeof entity.spec?.lifecycle === 'string'\n ? entity.spec?.lifecycle\n : undefined,\n url: `/catalog/${\n entity.metadata.namespace?.toLocaleLowerCase('en-US') ||\n ENTITY_DEFAULT_NAMESPACE\n }/${entity.kind.toLocaleLowerCase('en-US')}/${entity.metadata.name}`,\n }));\n }, []);\n\n useEffect(() => {\n if (results) {\n let withFilters = results;\n\n // apply filters\n\n // filter on selected\n if (selectedFilters.selected !== '') {\n withFilters = results.filter((result: Result) =>\n selectedFilters.selected.includes(result.kind),\n );\n }\n\n // filter on checked\n if (selectedFilters.checked.length > 0) {\n withFilters = withFilters.filter(\n (result: Result) =>\n result.lifecycle &&\n selectedFilters.checked.includes(result.lifecycle),\n );\n }\n\n // filter on searchQuery\n if (searchQuery) {\n withFilters = withFilters.filter(\n (result: Result) =>\n result.name?.toLocaleLowerCase('en-US').includes(searchQuery) ||\n result.name\n ?.toLocaleLowerCase('en-US')\n .includes(searchQuery.split(' ').join('-')) ||\n result.description\n ?.toLocaleLowerCase('en-US')\n .includes(searchQuery),\n );\n }\n\n setFilteredResults(withFilters);\n }\n }, [selectedFilters, searchQuery, results]);\n if (loading) {\n return <Progress />;\n }\n if (error) {\n return (\n <Alert severity=\"error\">\n Error encountered while fetching search results. {error.toString()}\n </Alert>\n );\n }\n if (!results || results.length === 0) {\n return <EmptyState missing=\"data\" title=\"Sorry, no results were found\" />;\n }\n\n const resetFilters = () => {\n setSelectedFilters({\n selected: '',\n checked: [],\n });\n };\n\n const updateSelected = (filter: string) => {\n setSelectedFilters(prevState => ({\n ...prevState,\n selected: filter,\n }));\n };\n\n const updateChecked = (filter: string) => {\n if (selectedFilters.checked.includes(filter)) {\n setSelectedFilters(prevState => ({\n ...prevState,\n checked: prevState.checked.filter(item => item !== filter),\n }));\n return;\n }\n\n setSelectedFilters(prevState => ({\n ...prevState,\n checked: [...prevState.checked, filter],\n }));\n };\n\n const filterOptions = results.reduce(\n (acc, curr) => {\n if (curr.kind && acc.kind.indexOf(curr.kind) < 0) {\n acc.kind.push(curr.kind);\n }\n if (curr.lifecycle && acc.lifecycle.indexOf(curr.lifecycle) < 0) {\n acc.lifecycle.push(curr.lifecycle);\n }\n return acc;\n },\n {\n kind: [] as Array<string>,\n lifecycle: [] as Array<string>,\n },\n );\n\n return (\n <>\n <Grid container>\n {showFilters && (\n <Grid item xs={3}>\n <Filters\n filters={selectedFilters}\n filterOptions={filterOptions}\n resetFilters={resetFilters}\n updateSelected={updateSelected}\n updateChecked={updateChecked}\n />\n </Grid>\n )}\n <Grid item xs={showFilters ? 9 : 12}>\n <Table\n options={{ paging: true, pageSize: 20, search: false }}\n data={filteredResults}\n columns={columns}\n title={\n <TableHeader\n searchQuery={searchQuery}\n numberOfResults={filteredResults.length}\n numberOfSelectedFilters={\n (selectedFilters.selected !== '' ? 1 : 0) +\n selectedFilters.checked.length\n }\n handleToggleFilters={() => toggleFilters(!showFilters)}\n />\n }\n />\n </Grid>\n </Grid>\n </>\n );\n};\n","/*\n * Copyright 2020 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 */\nimport { Grid } from '@material-ui/core';\nimport React, { useEffect, useState } from 'react';\nimport { useDebounce } from 'react-use';\nimport { SearchBar } from './LegacySearchBar';\nimport { SearchResult } from './LegacySearchResult';\nimport {\n Content,\n Header,\n Page,\n useQueryParamState,\n} from '@backstage/core-components';\n\n/**\n * @deprecated This SearchPage, powered directly by the Catalog API, will be\n * removed from a future release of this plugin.\n */\nexport const LegacySearchPage = () => {\n const [queryString, setQueryString] = useQueryParamState<string>('query');\n const [searchQuery, setSearchQuery] = useState(queryString ?? '');\n\n const handleSearch = (event: React.ChangeEvent<HTMLInputElement>) => {\n event.preventDefault();\n setSearchQuery(event.target.value);\n };\n\n useEffect(() => setSearchQuery(queryString ?? ''), [queryString]);\n\n useDebounce(\n () => {\n setQueryString(searchQuery);\n },\n 200,\n [searchQuery],\n );\n\n const handleClearSearchBar = () => {\n setSearchQuery('');\n };\n\n return (\n <Page themeId=\"home\">\n <Header title=\"Search\" />\n <Content>\n <Grid container direction=\"row\">\n <Grid item xs={12}>\n <SearchBar\n handleSearch={handleSearch}\n handleClearSearchBar={handleClearSearchBar}\n searchQuery={searchQuery}\n />\n </Grid>\n <Grid item xs={12}>\n <SearchResult\n searchQuery={(queryString ?? '').toLocaleLowerCase('en-US')}\n />\n </Grid>\n </Grid>\n </Content>\n </Page>\n );\n};\n","/*\n * Copyright 2020 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 { usePrevious } from 'react-use';\nimport qs from 'qs';\nimport { useLocation, useOutlet } from 'react-router';\nimport { SearchContextProvider, useSearch } from '../SearchContext';\nimport { JsonObject } from '@backstage/types';\nimport { LegacySearchPage } from '../LegacySearchPage';\n\nexport const UrlUpdater = () => {\n const location = useLocation();\n const {\n term,\n setTerm,\n types,\n setTypes,\n pageCursor,\n setPageCursor,\n filters,\n setFilters,\n } = useSearch();\n\n const prevQueryParams = usePrevious(location.search);\n useEffect(() => {\n // Only respond to changes to url query params\n if (location.search === prevQueryParams) {\n return;\n }\n\n const query =\n qs.parse(location.search.substring(1), { arrayLimit: 0 }) || {};\n\n if (query.filters) {\n setFilters(query.filters as JsonObject);\n }\n\n if (query.query) {\n setTerm(query.query as string);\n }\n\n if (query.pageCursor) {\n setPageCursor(query.pageCursor as string);\n }\n\n if (query.types) {\n setTypes(query.types as string[]);\n }\n }, [prevQueryParams, location, setTerm, setTypes, setPageCursor, setFilters]);\n\n useEffect(() => {\n const newParams = qs.stringify(\n {\n query: term,\n types,\n pageCursor,\n filters,\n },\n { arrayFormat: 'brackets' },\n );\n const newUrl = `${window.location.pathname}?${newParams}`;\n\n // We directly manipulate window history here in order to not re-render\n // infinitely (state => location => state => etc). The intention of this\n // code is just to ensure the right query/filters are loaded when a user\n // clicks the \"back\" button after clicking a result.\n window.history.replaceState(null, document.title, newUrl);\n }, [term, types, pageCursor, filters]);\n\n return null;\n};\n\nexport const SearchPage = () => {\n const outlet = useOutlet();\n\n return (\n <SearchContextProvider>\n <UrlUpdater />\n {outlet || <LegacySearchPage />}\n </SearchContextProvider>\n );\n};\n","/*\n * Copyright 2021 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 */\nimport {\n Checkbox,\n Chip,\n FormControl,\n InputLabel,\n ListItemText,\n makeStyles,\n MenuItem,\n Select,\n} from '@material-ui/core';\nimport React, { ChangeEvent } from 'react';\nimport { useEffectOnce } from 'react-use';\nimport { useSearch } from '../SearchContext';\n\nconst useStyles = makeStyles(theme => ({\n label: {\n textTransform: 'capitalize',\n },\n chips: {\n display: 'flex',\n flexWrap: 'wrap',\n marginTop: theme.spacing(1),\n },\n chip: {\n margin: 2,\n },\n}));\n\nexport type SearchTypeProps = {\n className?: string;\n name: string;\n values?: string[];\n defaultValue?: string[] | string | null;\n};\n\nconst SearchType = ({\n values = [],\n className,\n name,\n defaultValue,\n}: SearchTypeProps) => {\n const classes = useStyles();\n const { types, setTypes } = useSearch();\n\n useEffectOnce(() => {\n if (!types.length) {\n if (defaultValue && Array.isArray(defaultValue)) {\n setTypes(defaultValue);\n } else if (defaultValue) {\n setTypes([defaultValue]);\n }\n }\n });\n\n const handleChange = (e: ChangeEvent<{ value: unknown }>) => {\n const value = e.target.value as string[];\n setTypes(value as string[]);\n };\n\n return (\n <FormControl\n className={className}\n variant=\"filled\"\n fullWidth\n data-testid=\"search-typefilter-next\"\n >\n <InputLabel className={classes.label} margin=\"dense\">\n {name}\n </InputLabel>\n <Select\n multiple\n variant=\"outlined\"\n value={types}\n onChange={handleChange}\n placeholder=\"All Results\"\n renderValue={selected => (\n <div className={classes.chips}>\n {(selected as string[]).map(value => (\n <Chip\n key={value}\n label={value}\n className={classes.chip}\n size=\"small\"\n />\n ))}\n </div>\n )}\n >\n {values.map((value: string) => (\n <MenuItem key={value} value={value}>\n <Checkbox checked={types.indexOf(value) > -1} />\n <ListItemText primary={value} />\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n );\n};\n\nexport { SearchType };\n","/*\n * Copyright 2020 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 */\nimport qs from 'qs';\nimport React, { useCallback } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { rootRouteRef } from '../../plugin';\n\nimport { SidebarSearchField } from '@backstage/core-components';\nimport { useRouteRef } from '@backstage/core-plugin-api';\n\nexport const SidebarSearch = () => {\n const searchRoute = useRouteRef(rootRouteRef);\n const navigate = useNavigate();\n const handleSearch = useCallback(\n (query: string): void => {\n const queryString = qs.stringify({ query }, { addQueryPrefix: true });\n\n navigate(`${searchRoute()}${queryString}`);\n },\n [navigate, searchRoute],\n );\n\n return <SidebarSearchField onSearch={handleSearch} to=\"/search\" />;\n};\n"],"names":["DefaultResultListItem","useStyles","FiltersButton","Filters","React","SearchBar","SearchPage","SearchResult","makeStyles","IconButton","InputBase"],"mappings":"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"}
1
+ {"version":3,"file":"index-893ec2f5.esm.js","sources":["../../src/apis.ts","../../src/components/DefaultResultListItem/DefaultResultListItem.tsx","../../src/components/Filters/FiltersButton.tsx","../../src/components/Filters/Filters.tsx","../../src/components/SearchContext/SearchContext.tsx","../../src/components/SearchBar/SearchBar.tsx","../../src/components/SearchFilter/SearchFilter.tsx","../../../../node_modules/@material-ui/icons/esm/Launch.js","../../src/components/SearchResult/SearchResult.tsx","../../src/components/SearchResultPager/SearchResultPager.tsx","../../src/plugin.ts","../../src/components/SearchModal/SearchModal.tsx","../../src/components/LegacySearchPage/LegacySearchBar.tsx","../../src/components/LegacySearchPage/Filters/FiltersButton.tsx","../../src/components/LegacySearchPage/Filters/Filters.tsx","../../src/components/LegacySearchPage/LegacySearchResult.tsx","../../src/components/LegacySearchPage/LegacySearchPage.tsx","../../src/components/SearchPage/SearchPage.tsx","../../src/components/SearchType/SearchType.tsx","../../src/components/SidebarSearch/SidebarSearch.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n createApiRef,\n DiscoveryApi,\n IdentityApi,\n} from '@backstage/core-plugin-api';\nimport { ResponseError } from '@backstage/errors';\nimport { SearchQuery, SearchResultSet } from '@backstage/search-common';\nimport qs from 'qs';\n\nexport const searchApiRef = createApiRef<SearchApi>({\n id: 'plugin.search.queryservice',\n description: 'Used to make requests against the search API',\n});\n\nexport interface SearchApi {\n query(query: SearchQuery): Promise<SearchResultSet>;\n}\n\nexport class SearchClient implements SearchApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly identityApi: IdentityApi;\n\n constructor(options: {\n discoveryApi: DiscoveryApi;\n identityApi: IdentityApi;\n }) {\n this.discoveryApi = options.discoveryApi;\n this.identityApi = options.identityApi;\n }\n\n async query(query: SearchQuery): Promise<SearchResultSet> {\n const token = await this.identityApi.getIdToken();\n const queryString = qs.stringify(query);\n const url = `${await this.discoveryApi.getBaseUrl(\n 'search/query',\n )}?${queryString}`;\n const response = await fetch(url, {\n headers: token ? { Authorization: `Bearer ${token}` } : {},\n });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json();\n }\n}\n","/*\n * Copyright 2021 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 { IndexableDocument } from '@backstage/search-common';\nimport {\n ListItem,\n ListItemIcon,\n ListItemText,\n Box,\n Divider,\n} from '@material-ui/core';\nimport { Link } from '@backstage/core-components';\n\ntype Props = {\n icon?: ReactNode;\n secondaryAction?: ReactNode;\n result: IndexableDocument;\n};\n\nexport const DefaultResultListItem = ({\n result,\n icon,\n secondaryAction,\n}: Props) => {\n return (\n <Link to={result.location}>\n <ListItem alignItems=\"center\">\n {icon && <ListItemIcon>{icon}</ListItemIcon>}\n <ListItemText\n primaryTypographyProps={{ variant: 'h6' }}\n primary={result.title}\n secondary={result.text}\n />\n {secondaryAction && <Box alignItems=\"flex-end\">{secondaryAction}</Box>}\n </ListItem>\n <Divider />\n </Link>\n );\n};\n","/*\n * Copyright 2020 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 FilterListIcon from '@material-ui/icons/FilterList';\nimport { makeStyles, IconButton, Typography } from '@material-ui/core';\n\nconst useStyles = makeStyles(theme => ({\n filters: {\n width: '250px',\n display: 'flex',\n },\n icon: {\n margin: theme.spacing(-1, 0, 0, 0),\n },\n}));\n\ntype FiltersButtonProps = {\n numberOfSelectedFilters: number;\n handleToggleFilters: () => void;\n};\n\nexport const FiltersButton = ({\n numberOfSelectedFilters,\n handleToggleFilters,\n}: FiltersButtonProps) => {\n const classes = useStyles();\n\n return (\n <div className={classes.filters}>\n <IconButton\n className={classes.icon}\n aria-label=\"settings\"\n onClick={handleToggleFilters}\n >\n <FilterListIcon />\n </IconButton>\n <Typography variant=\"h6\">\n Filters ({numberOfSelectedFilters ? numberOfSelectedFilters : 0})\n </Typography>\n </div>\n );\n};\n","/*\n * Copyright 2020 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 {\n makeStyles,\n Typography,\n Divider,\n Card,\n CardHeader,\n Button,\n CardContent,\n Select,\n Checkbox,\n List,\n ListItem,\n ListItemText,\n MenuItem,\n} from '@material-ui/core';\n\nconst useStyles = makeStyles(theme => ({\n filters: {\n background: 'transparent',\n boxShadow: '0px 0px 0px 0px',\n },\n checkbox: {\n padding: theme.spacing(0, 1, 0, 1),\n },\n dropdown: {\n width: '100%',\n },\n}));\n\nexport type FiltersState = {\n selected: string;\n checked: Array<string>;\n};\n\nexport type FilterOptions = {\n kind: Array<string>;\n lifecycle: Array<string>;\n};\n\ntype FiltersProps = {\n filters: FiltersState;\n filterOptions: FilterOptions;\n resetFilters: () => void;\n updateSelected: (filter: string) => void;\n updateChecked: (filter: string) => void;\n};\n\nexport const Filters = ({\n filters,\n filterOptions,\n resetFilters,\n updateSelected,\n updateChecked,\n}: FiltersProps) => {\n const classes = useStyles();\n\n return (\n <Card className={classes.filters}>\n <CardHeader\n title={<Typography variant=\"h6\">Filters</Typography>}\n action={\n <Button color=\"primary\" onClick={() => resetFilters()}>\n CLEAR ALL\n </Button>\n }\n />\n <Divider />\n {filterOptions.kind.length === 0 && filterOptions.lifecycle.length === 0 && (\n <CardContent>\n <Typography variant=\"subtitle2\">\n Filters cannot be applied to available results\n </Typography>\n </CardContent>\n )}\n {filterOptions.kind.length > 0 && (\n <CardContent>\n <Typography variant=\"subtitle2\">Kind</Typography>\n <Select\n id=\"outlined-select\"\n onChange={(e: React.ChangeEvent<any>) =>\n updateSelected(e?.target?.value)\n }\n variant=\"outlined\"\n className={classes.dropdown}\n value={filters.selected}\n >\n {filterOptions.kind.map(filter => (\n <MenuItem\n selected={filter === ''}\n dense\n key={filter}\n value={filter}\n >\n {filter}\n </MenuItem>\n ))}\n </Select>\n </CardContent>\n )}\n {filterOptions.lifecycle.length > 0 && (\n <CardContent>\n <Typography variant=\"subtitle2\">Lifecycle</Typography>\n <List disablePadding dense>\n {filterOptions.lifecycle.map(filter => (\n <ListItem\n key={filter}\n dense\n button\n onClick={() => updateChecked(filter)}\n >\n <Checkbox\n edge=\"start\"\n disableRipple\n className={classes.checkbox}\n color=\"primary\"\n checked={filters.checked.includes(filter)}\n tabIndex={-1}\n value={filter}\n name={filter}\n />\n <ListItemText id={filter} primary={filter} />\n </ListItem>\n ))}\n </List>\n </CardContent>\n )}\n </Card>\n );\n};\n","/*\n * Copyright 2021 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 { JsonObject } from '@backstage/types';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { SearchResultSet } from '@backstage/search-common';\nimport React, {\n createContext,\n PropsWithChildren,\n useCallback,\n useContext,\n useEffect,\n useState,\n} from 'react';\nimport { useAsync, usePrevious } from 'react-use';\nimport { AsyncState } from 'react-use/lib/useAsync';\nimport { searchApiRef } from '../../apis';\n\ntype SearchContextValue = {\n result: AsyncState<SearchResultSet>;\n term: string;\n setTerm: React.Dispatch<React.SetStateAction<string>>;\n types: string[];\n setTypes: React.Dispatch<React.SetStateAction<string[]>>;\n filters: JsonObject;\n setFilters: React.Dispatch<React.SetStateAction<JsonObject>>;\n open?: boolean;\n toggleModal: () => void;\n pageCursor?: string;\n setPageCursor: React.Dispatch<React.SetStateAction<string | undefined>>;\n fetchNextPage?: React.DispatchWithoutAction;\n fetchPreviousPage?: React.DispatchWithoutAction;\n};\n\ntype SettableSearchContext = Omit<\n SearchContextValue,\n | 'result'\n | 'setTerm'\n | 'setTypes'\n | 'setFilters'\n | 'toggleModal'\n | 'setPageCursor'\n | 'fetchNextPage'\n | 'fetchPreviousPage'\n>;\n\nexport const SearchContext = createContext<SearchContextValue | undefined>(\n undefined,\n);\n\nexport const SearchContextProvider = ({\n initialState = {\n term: '',\n pageCursor: undefined,\n filters: {},\n types: [],\n },\n children,\n}: PropsWithChildren<{ initialState?: SettableSearchContext }>) => {\n const searchApi = useApi(searchApiRef);\n const [pageCursor, setPageCursor] = useState<string | undefined>(\n initialState.pageCursor,\n );\n const [filters, setFilters] = useState<JsonObject>(initialState.filters);\n const [term, setTerm] = useState<string>(initialState.term);\n const [types, setTypes] = useState<string[]>(initialState.types);\n const [open, setOpen] = useState<boolean>(false);\n const toggleModal = useCallback(\n (): void => setOpen(prevState => !prevState),\n [],\n );\n\n const prevTerm = usePrevious(term);\n\n const result = useAsync(\n () =>\n searchApi.query({\n term,\n filters,\n pageCursor: pageCursor,\n types,\n }),\n [term, filters, types, 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 if (term && prevTerm && term !== prevTerm) {\n setPageCursor(undefined);\n }\n }, [term, prevTerm, initialState.pageCursor]);\n\n const value: SearchContextValue = {\n result,\n filters,\n setFilters,\n open,\n toggleModal,\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 <SearchContext.Provider value={value} children={children} />;\n};\n\nexport const useSearch = () => {\n const context = useContext(SearchContext);\n if (context === undefined) {\n throw new Error('useSearch must be used within a SearchContextProvider');\n }\n return context;\n};\n","/*\n * Copyright 2021 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, KeyboardEvent, useState } from 'react';\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport { useDebounce } from 'react-use';\nimport { InputBase, InputAdornment, IconButton } from '@material-ui/core';\nimport SearchIcon from '@material-ui/icons/Search';\nimport ClearButton from '@material-ui/icons/Clear';\n\nimport { useSearch } from '../SearchContext';\n\ntype PresenterProps = {\n value: string;\n onChange: (value: string) => void;\n onClear?: () => void;\n onSubmit?: () => void;\n className?: string;\n placeholder?: string;\n autoFocus?: boolean;\n clearButton?: boolean;\n};\n\nexport const SearchBarBase = ({\n autoFocus,\n value,\n onChange,\n onSubmit,\n className,\n placeholder: overridePlaceholder,\n clearButton = true,\n}: PresenterProps) => {\n const configApi = useApi(configApiRef);\n\n const onKeyDown = React.useCallback(\n (e: KeyboardEvent<HTMLInputElement>) => {\n if (onSubmit && e.key === 'Enter') {\n onSubmit();\n }\n },\n [onSubmit],\n );\n\n const handleClear = React.useCallback(() => {\n onChange('');\n }, [onChange]);\n\n const placeholder =\n overridePlaceholder ??\n `Search in ${configApi.getOptionalString('app.title') || 'Backstage'}`;\n\n return (\n <InputBase\n // decision up to adopter, read https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-autofocus.md#no-autofocus\n // eslint-disable-next-line jsx-a11y/no-autofocus\n autoFocus={autoFocus}\n data-testid=\"search-bar-next\"\n fullWidth\n placeholder={placeholder}\n value={value}\n onChange={e => onChange(e.target.value)}\n inputProps={{ 'aria-label': 'Search' }}\n startAdornment={\n <InputAdornment position=\"start\">\n <IconButton aria-label=\"Query\" disabled>\n <SearchIcon />\n </IconButton>\n </InputAdornment>\n }\n endAdornment={\n clearButton && (\n <InputAdornment position=\"end\">\n <IconButton aria-label=\"Clear\" onClick={handleClear}>\n <ClearButton />\n </IconButton>\n </InputAdornment>\n )\n }\n {...(className && { className })}\n {...(onSubmit && { onKeyDown })}\n />\n );\n};\n\ntype Props = {\n autoFocus?: boolean;\n className?: string;\n debounceTime?: number;\n placeholder?: string;\n clearButton?: boolean;\n};\n\nexport const SearchBar = ({\n autoFocus,\n className,\n debounceTime = 0,\n placeholder,\n clearButton = true,\n}: Props) => {\n const { term, setTerm } = useSearch();\n const [value, setValue] = useState<string>(term);\n\n useEffect(() => {\n setValue(prevValue => (prevValue !== term ? term : prevValue));\n }, [term]);\n\n useDebounce(() => setTerm(value), debounceTime, [value]);\n\n const handleQuery = (newValue: string) => {\n setValue(newValue);\n };\n\n const handleClear = () => setValue('');\n\n return (\n <SearchBarBase\n // decision up to adopter, read https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-autofocus.md#no-autofocus\n // eslint-disable-next-line jsx-a11y/no-autofocus\n autoFocus={autoFocus}\n className={className}\n value={value}\n onChange={handleQuery}\n onClear={handleClear}\n placeholder={placeholder}\n clearButton={clearButton}\n />\n );\n};\n","/*\n * Copyright 2021 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, useEffect } 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 '../SearchContext';\n\nconst useStyles = makeStyles({\n label: {\n textTransform: 'capitalize',\n },\n});\n\nexport type Component = {\n className?: string;\n name: string;\n values?: string[];\n defaultValue?: string[] | string | null;\n};\n\nexport type Props = Component & {\n component: (props: Component) => ReactElement;\n debug?: boolean;\n};\n\nconst CheckboxFilter = ({\n className,\n name,\n defaultValue,\n values = [],\n}: Component) => {\n const classes = useStyles();\n const { filters, setFilters } = useSearch();\n\n useEffect(() => {\n if (Array.isArray(defaultValue)) {\n setFilters(prevFilters => ({\n ...prevFilters,\n [name]: defaultValue,\n }));\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\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 fullWidth\n data-testid=\"search-checkboxfilter-next\"\n >\n <FormLabel className={classes.label}>{name}</FormLabel>\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\nconst SelectFilter = ({\n className,\n name,\n defaultValue,\n values = [],\n}: Component) => {\n const classes = useStyles();\n const { filters, setFilters } = useSearch();\n\n useEffect(() => {\n if (typeof defaultValue === 'string') {\n setFilters(prevFilters => ({\n ...prevFilters,\n [name]: defaultValue,\n }));\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\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 className={className}\n variant=\"filled\"\n fullWidth\n data-testid=\"search-selectfilter-next\"\n >\n <InputLabel className={classes.label} margin=\"dense\">\n {name}\n </InputLabel>\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\nconst SearchFilter = ({ component: Element, ...props }: Props) => (\n <Element {...props} />\n);\n\nSearchFilter.Checkbox = (props: Omit<Props, 'component'> & Component) => (\n <SearchFilter {...props} component={CheckboxFilter} />\n);\n\nSearchFilter.Select = (props: Omit<Props, 'component'> & Component) => (\n <SearchFilter {...props} component={SelectFilter} />\n);\n\n/**\n * @deprecated This component was used for rapid prototyping of the Backstage\n * Search platform. Now that the API has stabilized, you should use the\n * <SearchFilter /> component instead. This component will be removed in an\n * upcoming release.\n */\nconst SearchFilterNext = SearchFilter;\n\nexport { SearchFilter, SearchFilterNext };\n","import * as React from 'react';\nimport createSvgIcon from './utils/createSvgIcon';\nexport default createSvgIcon( /*#__PURE__*/React.createElement(\"path\", {\n d: \"M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z\"\n}), 'Launch');","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n EmptyState,\n Progress,\n ResponseErrorPanel,\n} from '@backstage/core-components';\nimport { SearchResult } from '@backstage/search-common';\nimport React from 'react';\nimport { useSearch } from '../SearchContext';\n\ntype Props = {\n children: (results: { results: SearchResult[] }) => JSX.Element;\n};\n\nexport const SearchResultComponent = ({ children }: Props) => {\n const {\n result: { loading, error, value },\n } = useSearch();\n\n if (loading) {\n return <Progress />;\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 <EmptyState missing=\"data\" title=\"Sorry, no results were found\" />;\n }\n\n return <>{children({ results: value.results })}</>;\n};\n\nexport { SearchResultComponent as SearchResult };\n","/*\n * Copyright 2021 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 { Button, makeStyles } from '@material-ui/core';\nimport ArrowBackIosIcon from '@material-ui/icons/ArrowBackIos';\nimport ArrowForwardIosIcon from '@material-ui/icons/ArrowForwardIos';\nimport React from 'react';\nimport { useSearch } from '../SearchContext';\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\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 arial-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 2020 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 { SearchClient, searchApiRef } from './apis';\nimport {\n createApiFactory,\n createPlugin,\n createRouteRef,\n createRoutableExtension,\n discoveryApiRef,\n createComponentExtension,\n identityApiRef,\n} from '@backstage/core-plugin-api';\n\nexport const rootRouteRef = createRouteRef({\n id: 'search',\n});\n\nexport const rootNextRouteRef = createRouteRef({\n id: 'search:next',\n});\n\nexport const searchPlugin = createPlugin({\n id: 'search',\n apis: [\n createApiFactory({\n api: searchApiRef,\n deps: { discoveryApi: discoveryApiRef, identityApi: identityApiRef },\n factory: ({ discoveryApi, identityApi }) => {\n return new SearchClient({ discoveryApi, identityApi });\n },\n }),\n ],\n routes: {\n root: rootRouteRef,\n nextRoot: rootNextRouteRef,\n },\n});\n\nexport const SearchPage = searchPlugin.provide(\n createRoutableExtension({\n name: 'SearchPage',\n component: () => import('./components/SearchPage').then(m => m.SearchPage),\n mountPoint: rootRouteRef,\n }),\n);\n\n/**\n * @deprecated This component was used for rapid prototyping of the Backstage\n * Search platform. Now that the API has stabilized, you should use the\n * <SearchPage /> component instead. This component will be removed in an\n * upcoming release.\n */\nexport const SearchPageNext = searchPlugin.provide(\n createRoutableExtension({\n name: 'SearchPageNext',\n component: () => import('./components/SearchPage').then(m => m.SearchPage),\n mountPoint: rootNextRouteRef,\n }),\n);\n\nexport const SearchBar = searchPlugin.provide(\n createComponentExtension({\n name: 'SearchBar',\n component: {\n lazy: () => import('./components/SearchBar').then(m => m.SearchBar),\n },\n }),\n);\n\n/**\n * @deprecated This component was used for rapid prototyping of the Backstage\n * Search platform. Now that the API has stabilized, you should use the\n * <SearchBar /> component instead. This component will be removed in an\n * upcoming release.\n */\nexport const SearchBarNext = searchPlugin.provide(\n createComponentExtension({\n name: 'SearchBarNext',\n component: {\n lazy: () => import('./components/SearchBar').then(m => m.SearchBar),\n },\n }),\n);\n\nexport const SearchResult = searchPlugin.provide(\n createComponentExtension({\n name: 'SearchResult',\n component: {\n lazy: () => import('./components/SearchResult').then(m => m.SearchResult),\n },\n }),\n);\n\n/**\n * @deprecated This component was used for rapid prototyping of the Backstage\n * Search platform. Now that the API has stabilized, you should use the\n * <SearchResult /> component instead. This component will be removed in an\n * upcoming release.\n */\nexport const SearchResultNext = searchPlugin.provide(\n createComponentExtension({\n name: 'SearchResultNext',\n component: {\n lazy: () => import('./components/SearchResult').then(m => m.SearchResult),\n },\n }),\n);\n\nexport const SidebarSearchModal = searchPlugin.provide(\n createComponentExtension({\n name: 'SidebarSearchModal',\n component: {\n lazy: () =>\n import('./components/SidebarSearchModal').then(\n m => m.SidebarSearchModal,\n ),\n },\n }),\n);\n\nexport const DefaultResultListItem = searchPlugin.provide(\n createComponentExtension({\n name: 'DefaultResultListItem',\n component: {\n lazy: () =>\n import('./components/DefaultResultListItem').then(\n m => m.DefaultResultListItem,\n ),\n },\n }),\n);\n\nexport const HomePageSearchBar = searchPlugin.provide(\n createComponentExtension({\n name: 'HomePageSearchBar',\n component: {\n lazy: () =>\n import('./components/HomePageComponent').then(m => m.HomePageSearchBar),\n },\n }),\n);\n","/*\n * Copyright 2021 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 */\nimport React, { useEffect, useState } from 'react';\nimport {\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n Divider,\n Grid,\n List,\n Paper,\n} from '@material-ui/core';\nimport { Launch } from '@material-ui/icons/';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { SearchBarBase } from '../SearchBar';\nimport { DefaultResultListItem } from '../DefaultResultListItem';\nimport { SearchResult } from '../SearchResult';\nimport { SearchContextProvider, useSearch } from '../SearchContext';\nimport { SearchResultPager } from '../SearchResultPager';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport { Link } from '@backstage/core-components';\nimport { rootRouteRef } from '../../plugin';\n\nimport { useDebounce } from 'react-use';\n\nexport interface SearchModalProps {\n open?: boolean;\n toggleModal: () => void;\n}\n\nconst useStyles = makeStyles(theme => ({\n container: {\n borderRadius: 30,\n display: 'flex',\n height: '2.4em',\n },\n input: {\n flex: 1,\n },\n // Reduces default height of the modal, keeping a gap of 128px between the top and bottom of the page.\n paperFullWidth: { height: 'calc(100% - 128px)' },\n dialogActionsContainer: { padding: theme.spacing(1, 3) },\n viewResultsLink: { verticalAlign: '0.5em' },\n}));\n\nexport const Modal = ({ open = true, toggleModal }: SearchModalProps) => {\n const getSearchLink = useRouteRef(rootRouteRef);\n const classes = useStyles();\n\n const { term, setTerm } = useSearch();\n const [value, setValue] = useState<string>(term);\n\n useEffect(() => {\n setValue(prevValue => (prevValue !== term ? term : prevValue));\n }, [term]);\n\n useDebounce(() => setTerm(value), 500, [value]);\n\n const handleQuery = (newValue: string) => {\n setValue(newValue);\n };\n\n const handleClear = () => setValue('');\n\n const handleResultClick = () => {\n toggleModal();\n handleClear();\n };\n\n const handleKeyPress = () => {\n handleResultClick();\n };\n\n return (\n <Dialog\n classes={{\n paperFullWidth: classes.paperFullWidth,\n }}\n onClose={toggleModal}\n aria-labelledby=\"search-modal-title\"\n open={open}\n fullWidth\n maxWidth=\"lg\"\n >\n <DialogTitle>\n <Paper className={classes.container}>\n <SearchBarBase\n className={classes.input}\n value={value}\n onChange={handleQuery}\n onClear={handleClear}\n />\n </Paper>\n </DialogTitle>\n <DialogContent>\n <Grid\n container\n direction=\"row-reverse\"\n justifyContent=\"flex-start\"\n alignItems=\"center\"\n >\n <Grid item>\n <Link\n onClick={toggleModal}\n to={`${getSearchLink()}?query=${value}`}\n >\n <span className={classes.viewResultsLink}>View Full Results</span>\n <Launch color=\"primary\" />\n </Link>\n </Grid>\n </Grid>\n <Divider />\n <SearchResult>\n {({ results }) => (\n <List>\n {results.map(({ document }) => (\n <div\n role=\"button\"\n tabIndex={0}\n key={`${document.location}-btn`}\n onClick={handleResultClick}\n onKeyPress={handleKeyPress}\n >\n <DefaultResultListItem\n key={document.location}\n result={document}\n />\n </div>\n ))}\n </List>\n )}\n </SearchResult>\n </DialogContent>\n <DialogActions className={classes.dialogActionsContainer}>\n <Grid container direction=\"row\">\n <Grid item xs={12}>\n <SearchResultPager />\n </Grid>\n </Grid>\n </DialogActions>\n </Dialog>\n );\n};\n\nexport const SearchModal = ({ open = true, toggleModal }: SearchModalProps) => {\n return (\n <SearchContextProvider>\n <Modal open={open} toggleModal={toggleModal} />\n </SearchContextProvider>\n );\n};\n","/*\n * Copyright 2020 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 { makeStyles } from '@material-ui/core/styles';\nimport { Paper } from '@material-ui/core';\nimport InputBase from '@material-ui/core/InputBase';\nimport IconButton from '@material-ui/core/IconButton';\nimport SearchIcon from '@material-ui/icons/Search';\nimport ClearButton from '@material-ui/icons/Clear';\n\nconst useStyles = makeStyles(() => ({\n root: {\n display: 'flex',\n alignItems: 'center',\n },\n input: {\n flex: 1,\n },\n}));\n\ntype SearchBarProps = {\n searchQuery: string;\n handleSearch: any;\n handleClearSearchBar: any;\n};\n\nexport const SearchBar = ({\n searchQuery,\n handleSearch,\n handleClearSearchBar,\n}: SearchBarProps) => {\n const classes = useStyles();\n\n return (\n <Paper\n component=\"form\"\n onSubmit={e => handleSearch(e)}\n className={classes.root}\n >\n <IconButton disabled type=\"submit\" aria-label=\"search\">\n <SearchIcon />\n </IconButton>\n <InputBase\n className={classes.input}\n placeholder=\"Search in Backstage\"\n value={searchQuery}\n onChange={e => handleSearch(e)}\n inputProps={{ 'aria-label': 'search backstage' }}\n />\n <IconButton aria-label=\"search\" onClick={() => handleClearSearchBar()}>\n <ClearButton />\n </IconButton>\n </Paper>\n );\n};\n","/*\n * Copyright 2020 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 FilterListIcon from '@material-ui/icons/FilterList';\nimport { makeStyles, IconButton, Typography } from '@material-ui/core';\n\nconst useStyles = makeStyles(theme => ({\n filters: {\n width: '250px',\n display: 'flex',\n },\n icon: {\n margin: theme.spacing(-1, 0, 0, 0),\n },\n}));\n\ntype FiltersButtonProps = {\n numberOfSelectedFilters: number;\n handleToggleFilters: () => void;\n};\n\nexport const FiltersButton = ({\n numberOfSelectedFilters,\n handleToggleFilters,\n}: FiltersButtonProps) => {\n const classes = useStyles();\n\n return (\n <div className={classes.filters}>\n <IconButton\n className={classes.icon}\n aria-label=\"settings\"\n onClick={handleToggleFilters}\n >\n <FilterListIcon />\n </IconButton>\n <Typography variant=\"h6\">\n Filters ({numberOfSelectedFilters ? numberOfSelectedFilters : 0})\n </Typography>\n </div>\n );\n};\n","/*\n * Copyright 2020 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 {\n makeStyles,\n Typography,\n Divider,\n Card,\n CardHeader,\n Button,\n CardContent,\n Select,\n Checkbox,\n List,\n ListItem,\n ListItemText,\n MenuItem,\n} from '@material-ui/core';\n\nconst useStyles = makeStyles(theme => ({\n filters: {\n background: 'transparent',\n boxShadow: '0px 0px 0px 0px',\n },\n checkbox: {\n padding: theme.spacing(0, 1, 0, 1),\n },\n dropdown: {\n width: '100%',\n },\n}));\n\nexport type FiltersState = {\n selected: string;\n checked: Array<string>;\n};\n\nexport type FilterOptions = {\n kind: Array<string>;\n lifecycle: Array<string>;\n};\n\ntype FiltersProps = {\n filters: FiltersState;\n filterOptions: FilterOptions;\n resetFilters: () => void;\n updateSelected: (filter: string) => void;\n updateChecked: (filter: string) => void;\n};\n\nexport const Filters = ({\n filters,\n filterOptions,\n resetFilters,\n updateSelected,\n updateChecked,\n}: FiltersProps) => {\n const classes = useStyles();\n\n return (\n <Card className={classes.filters}>\n <CardHeader\n title={<Typography variant=\"h6\">Filters</Typography>}\n action={\n <Button color=\"primary\" onClick={() => resetFilters()}>\n CLEAR ALL\n </Button>\n }\n />\n <Divider />\n {filterOptions.kind.length === 0 && filterOptions.lifecycle.length === 0 && (\n <CardContent>\n <Typography variant=\"subtitle2\">\n Filters cannot be applied to available results\n </Typography>\n </CardContent>\n )}\n {filterOptions.kind.length > 0 && (\n <CardContent>\n <Typography variant=\"subtitle2\">Kind</Typography>\n <Select\n id=\"outlined-select\"\n onChange={(e: React.ChangeEvent<any>) =>\n updateSelected(e?.target?.value)\n }\n variant=\"outlined\"\n className={classes.dropdown}\n value={filters.selected}\n >\n {filterOptions.kind.map(filter => (\n <MenuItem\n selected={filter === ''}\n dense\n key={filter}\n value={filter}\n >\n {filter}\n </MenuItem>\n ))}\n </Select>\n </CardContent>\n )}\n {filterOptions.lifecycle.length > 0 && (\n <CardContent>\n <Typography variant=\"subtitle2\">Lifecycle</Typography>\n <List disablePadding dense>\n {filterOptions.lifecycle.map(filter => (\n <ListItem\n key={filter}\n dense\n button\n onClick={() => updateChecked(filter)}\n >\n <Checkbox\n edge=\"start\"\n disableRipple\n className={classes.checkbox}\n color=\"primary\"\n checked={filters.checked.includes(filter)}\n tabIndex={-1}\n value={filter}\n name={filter}\n />\n <ListItemText id={filter} primary={filter} />\n </ListItem>\n ))}\n </List>\n </CardContent>\n )}\n </Card>\n );\n};\n","/*\n * Copyright 2020 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 */\nimport { Divider, Grid, makeStyles, Typography } from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\nimport React, { useEffect, useState } from 'react';\nimport { useAsync } from 'react-use';\nimport { catalogApiRef } from '@backstage/plugin-catalog-react';\n\nimport { Filters, FiltersButton, FiltersState } from './Filters';\nimport { Entity, ENTITY_DEFAULT_NAMESPACE } from '@backstage/catalog-model';\n\nimport {\n EmptyState,\n Link,\n Progress,\n Table,\n TableColumn,\n} from '@backstage/core-components';\nimport { useApi } from '@backstage/core-plugin-api';\n\ntype Result = {\n name: string;\n description: string | undefined;\n owner: string | undefined;\n kind: string;\n lifecycle: string | undefined;\n url: string;\n};\ntype SearchResults = Array<Result>;\n\nconst useStyles = makeStyles(theme => ({\n searchQuery: {\n color: theme.palette.text.primary,\n background: theme.palette.background.default,\n borderRadius: '10%',\n },\n tableHeader: {\n margin: theme.spacing(1, 0, 0, 0),\n display: 'flex',\n },\n divider: {\n width: '1px',\n margin: theme.spacing(0, 2),\n padding: theme.spacing(2, 0),\n },\n}));\n\ntype SearchResultProps = {\n searchQuery?: string;\n};\n\ntype TableHeaderProps = {\n searchQuery?: string;\n numberOfSelectedFilters: number;\n numberOfResults: number;\n handleToggleFilters: () => void;\n};\n\n// TODO: move out column to make the search result component more generic\nconst columns: TableColumn[] = [\n {\n title: 'Name',\n field: 'name',\n highlight: true,\n render: (result: Partial<Result>) => (\n <Link to={result.url || ''}>{result.name}</Link>\n ),\n },\n {\n title: 'Description',\n field: 'description',\n },\n {\n title: 'Owner',\n field: 'owner',\n },\n {\n title: 'Kind',\n field: 'kind',\n },\n {\n title: 'LifeCycle',\n field: 'lifecycle',\n },\n];\n\nconst TableHeader = ({\n searchQuery,\n numberOfSelectedFilters,\n numberOfResults,\n handleToggleFilters,\n}: TableHeaderProps) => {\n const classes = useStyles();\n\n return (\n <div className={classes.tableHeader}>\n <FiltersButton\n numberOfSelectedFilters={numberOfSelectedFilters}\n handleToggleFilters={handleToggleFilters}\n />\n <Divider className={classes.divider} orientation=\"vertical\" />\n <Grid item xs={12}>\n {searchQuery ? (\n <Typography variant=\"h6\">\n {`${numberOfResults} `}\n {numberOfResults > 1 ? `results for ` : `result for `}\n <span className={classes.searchQuery}>\"{searchQuery}\"</span>{' '}\n </Typography>\n ) : (\n <Typography variant=\"h6\">{`${numberOfResults} results`}</Typography>\n )}\n </Grid>\n </div>\n );\n};\n\nexport const SearchResult = ({ searchQuery }: SearchResultProps) => {\n const catalogApi = useApi(catalogApiRef);\n\n const [showFilters, toggleFilters] = useState(false);\n const [selectedFilters, setSelectedFilters] = useState<FiltersState>({\n selected: '',\n checked: [],\n });\n\n const [filteredResults, setFilteredResults] = useState<SearchResults>([]);\n\n const {\n loading,\n error,\n value: results,\n } = useAsync(async () => {\n const entities = await catalogApi.getEntities();\n return entities.items.map((entity: Entity) => ({\n name: entity.metadata.name,\n description: entity.metadata.description,\n owner:\n typeof entity.spec?.owner === 'string' ? entity.spec?.owner : undefined,\n kind: entity.kind,\n lifecycle:\n typeof entity.spec?.lifecycle === 'string'\n ? entity.spec?.lifecycle\n : undefined,\n url: `/catalog/${\n entity.metadata.namespace?.toLocaleLowerCase('en-US') ||\n ENTITY_DEFAULT_NAMESPACE\n }/${entity.kind.toLocaleLowerCase('en-US')}/${entity.metadata.name}`,\n }));\n }, []);\n\n useEffect(() => {\n if (results) {\n let withFilters = results;\n\n // apply filters\n\n // filter on selected\n if (selectedFilters.selected !== '') {\n withFilters = results.filter((result: Result) =>\n selectedFilters.selected.includes(result.kind),\n );\n }\n\n // filter on checked\n if (selectedFilters.checked.length > 0) {\n withFilters = withFilters.filter(\n (result: Result) =>\n result.lifecycle &&\n selectedFilters.checked.includes(result.lifecycle),\n );\n }\n\n // filter on searchQuery\n if (searchQuery) {\n withFilters = withFilters.filter(\n (result: Result) =>\n result.name?.toLocaleLowerCase('en-US').includes(searchQuery) ||\n result.name\n ?.toLocaleLowerCase('en-US')\n .includes(searchQuery.split(' ').join('-')) ||\n result.description\n ?.toLocaleLowerCase('en-US')\n .includes(searchQuery),\n );\n }\n\n setFilteredResults(withFilters);\n }\n }, [selectedFilters, searchQuery, results]);\n if (loading) {\n return <Progress />;\n }\n if (error) {\n return (\n <Alert severity=\"error\">\n Error encountered while fetching search results. {error.toString()}\n </Alert>\n );\n }\n if (!results || results.length === 0) {\n return <EmptyState missing=\"data\" title=\"Sorry, no results were found\" />;\n }\n\n const resetFilters = () => {\n setSelectedFilters({\n selected: '',\n checked: [],\n });\n };\n\n const updateSelected = (filter: string) => {\n setSelectedFilters(prevState => ({\n ...prevState,\n selected: filter,\n }));\n };\n\n const updateChecked = (filter: string) => {\n if (selectedFilters.checked.includes(filter)) {\n setSelectedFilters(prevState => ({\n ...prevState,\n checked: prevState.checked.filter(item => item !== filter),\n }));\n return;\n }\n\n setSelectedFilters(prevState => ({\n ...prevState,\n checked: [...prevState.checked, filter],\n }));\n };\n\n const filterOptions = results.reduce(\n (acc, curr) => {\n if (curr.kind && acc.kind.indexOf(curr.kind) < 0) {\n acc.kind.push(curr.kind);\n }\n if (curr.lifecycle && acc.lifecycle.indexOf(curr.lifecycle) < 0) {\n acc.lifecycle.push(curr.lifecycle);\n }\n return acc;\n },\n {\n kind: [] as Array<string>,\n lifecycle: [] as Array<string>,\n },\n );\n\n return (\n <>\n <Grid container>\n {showFilters && (\n <Grid item xs={3}>\n <Filters\n filters={selectedFilters}\n filterOptions={filterOptions}\n resetFilters={resetFilters}\n updateSelected={updateSelected}\n updateChecked={updateChecked}\n />\n </Grid>\n )}\n <Grid item xs={showFilters ? 9 : 12}>\n <Table\n options={{ paging: true, pageSize: 20, search: false }}\n data={filteredResults}\n columns={columns}\n title={\n <TableHeader\n searchQuery={searchQuery}\n numberOfResults={filteredResults.length}\n numberOfSelectedFilters={\n (selectedFilters.selected !== '' ? 1 : 0) +\n selectedFilters.checked.length\n }\n handleToggleFilters={() => toggleFilters(!showFilters)}\n />\n }\n />\n </Grid>\n </Grid>\n </>\n );\n};\n","/*\n * Copyright 2020 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 */\nimport { Grid } from '@material-ui/core';\nimport React, { useEffect, useState } from 'react';\nimport { useDebounce } from 'react-use';\nimport { SearchBar } from './LegacySearchBar';\nimport { SearchResult } from './LegacySearchResult';\nimport {\n Content,\n Header,\n Page,\n useQueryParamState,\n} from '@backstage/core-components';\n\n/**\n * @deprecated This SearchPage, powered directly by the Catalog API, will be\n * removed from a future release of this plugin.\n */\nexport const LegacySearchPage = () => {\n const [queryString, setQueryString] = useQueryParamState<string>('query');\n const [searchQuery, setSearchQuery] = useState(queryString ?? '');\n\n const handleSearch = (event: React.ChangeEvent<HTMLInputElement>) => {\n event.preventDefault();\n setSearchQuery(event.target.value);\n };\n\n useEffect(() => setSearchQuery(queryString ?? ''), [queryString]);\n\n useDebounce(\n () => {\n setQueryString(searchQuery);\n },\n 200,\n [searchQuery],\n );\n\n const handleClearSearchBar = () => {\n setSearchQuery('');\n };\n\n return (\n <Page themeId=\"home\">\n <Header title=\"Search\" />\n <Content>\n <Grid container direction=\"row\">\n <Grid item xs={12}>\n <SearchBar\n handleSearch={handleSearch}\n handleClearSearchBar={handleClearSearchBar}\n searchQuery={searchQuery}\n />\n </Grid>\n <Grid item xs={12}>\n <SearchResult\n searchQuery={(queryString ?? '').toLocaleLowerCase('en-US')}\n />\n </Grid>\n </Grid>\n </Content>\n </Page>\n );\n};\n","/*\n * Copyright 2020 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 { usePrevious } from 'react-use';\nimport qs from 'qs';\nimport { useLocation, useOutlet } from 'react-router';\nimport { SearchContextProvider, useSearch } from '../SearchContext';\nimport { JsonObject } from '@backstage/types';\nimport { LegacySearchPage } from '../LegacySearchPage';\n\nexport const UrlUpdater = () => {\n const location = useLocation();\n const {\n term,\n setTerm,\n types,\n setTypes,\n pageCursor,\n setPageCursor,\n filters,\n setFilters,\n } = useSearch();\n\n const prevQueryParams = usePrevious(location.search);\n useEffect(() => {\n // Only respond to changes to url query params\n if (location.search === prevQueryParams) {\n return;\n }\n\n const query =\n qs.parse(location.search.substring(1), { arrayLimit: 0 }) || {};\n\n if (query.filters) {\n setFilters(query.filters as JsonObject);\n }\n\n if (query.query) {\n setTerm(query.query as string);\n }\n\n if (query.pageCursor) {\n setPageCursor(query.pageCursor as string);\n }\n\n if (query.types) {\n setTypes(query.types as string[]);\n }\n }, [prevQueryParams, location, setTerm, setTypes, setPageCursor, setFilters]);\n\n useEffect(() => {\n const newParams = qs.stringify(\n {\n query: term,\n types,\n pageCursor,\n filters,\n },\n { arrayFormat: 'brackets' },\n );\n const newUrl = `${window.location.pathname}?${newParams}`;\n\n // We directly manipulate window history here in order to not re-render\n // infinitely (state => location => state => etc). The intention of this\n // code is just to ensure the right query/filters are loaded when a user\n // clicks the \"back\" button after clicking a result.\n window.history.replaceState(null, document.title, newUrl);\n }, [term, types, pageCursor, filters]);\n\n return null;\n};\n\nexport const SearchPage = () => {\n const outlet = useOutlet();\n\n return (\n <SearchContextProvider>\n <UrlUpdater />\n {outlet || <LegacySearchPage />}\n </SearchContextProvider>\n );\n};\n","/*\n * Copyright 2021 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 */\nimport {\n Checkbox,\n Chip,\n FormControl,\n InputLabel,\n ListItemText,\n makeStyles,\n MenuItem,\n Select,\n} from '@material-ui/core';\nimport React, { ChangeEvent } from 'react';\nimport { useEffectOnce } from 'react-use';\nimport { useSearch } from '../SearchContext';\n\nconst useStyles = makeStyles(theme => ({\n label: {\n textTransform: 'capitalize',\n },\n chips: {\n display: 'flex',\n flexWrap: 'wrap',\n marginTop: theme.spacing(1),\n },\n chip: {\n margin: 2,\n },\n}));\n\nexport type SearchTypeProps = {\n className?: string;\n name: string;\n values?: string[];\n defaultValue?: string[] | string | null;\n};\n\nconst SearchType = ({\n values = [],\n className,\n name,\n defaultValue,\n}: SearchTypeProps) => {\n const classes = useStyles();\n const { types, setTypes } = useSearch();\n\n useEffectOnce(() => {\n if (!types.length) {\n if (defaultValue && Array.isArray(defaultValue)) {\n setTypes(defaultValue);\n } else if (defaultValue) {\n setTypes([defaultValue]);\n }\n }\n });\n\n const handleChange = (e: ChangeEvent<{ value: unknown }>) => {\n const value = e.target.value as string[];\n setTypes(value as string[]);\n };\n\n return (\n <FormControl\n className={className}\n variant=\"filled\"\n fullWidth\n data-testid=\"search-typefilter-next\"\n >\n <InputLabel className={classes.label} margin=\"dense\">\n {name}\n </InputLabel>\n <Select\n multiple\n variant=\"outlined\"\n value={types}\n onChange={handleChange}\n placeholder=\"All Results\"\n renderValue={selected => (\n <div className={classes.chips}>\n {(selected as string[]).map(value => (\n <Chip\n key={value}\n label={value}\n className={classes.chip}\n size=\"small\"\n />\n ))}\n </div>\n )}\n >\n {values.map((value: string) => (\n <MenuItem key={value} value={value}>\n <Checkbox checked={types.indexOf(value) > -1} />\n <ListItemText primary={value} />\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n );\n};\n\nexport { SearchType };\n","/*\n * Copyright 2020 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 */\nimport qs from 'qs';\nimport React, { useCallback } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { rootRouteRef } from '../../plugin';\n\nimport { SidebarSearchField } from '@backstage/core-components';\nimport { useRouteRef } from '@backstage/core-plugin-api';\n\nexport const SidebarSearch = () => {\n const searchRoute = useRouteRef(rootRouteRef);\n const navigate = useNavigate();\n const handleSearch = useCallback(\n (query: string): void => {\n const queryString = qs.stringify({ query }, { addQueryPrefix: true });\n\n navigate(`${searchRoute()}${queryString}`);\n },\n [navigate, searchRoute],\n );\n\n return <SidebarSearchField onSearch={handleSearch} to=\"/search\" />;\n};\n"],"names":["DefaultResultListItem","useStyles","FiltersButton","Filters","React","SearchBar","SearchPage","SearchResult","makeStyles","IconButton","InputBase"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;MAyBa,eAAe,aAAwB;AAAA,EAClD,IAAI;AAAA,EACJ,aAAa;AAAA;mBAOgC;AAAA,EAI7C,YAAY,SAGT;AACD,SAAK,eAAe,QAAQ;AAC5B,SAAK,cAAc,QAAQ;AAAA;AAAA,QAGvB,MAAM,OAA8C;AACxD,UAAM,QAAQ,MAAM,KAAK,YAAY;AACrC,UAAM,cAAc,GAAG,UAAU;AACjC,UAAM,MAAM,GAAG,MAAM,KAAK,aAAa,WACrC,mBACG;AACL,UAAM,WAAW,MAAM,MAAM,KAAK;AAAA,MAChC,SAAS,QAAQ,EAAE,eAAe,UAAU,YAAY;AAAA;AAG1D,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,MAAM,cAAc,aAAa;AAAA;AAGzC,WAAO,SAAS;AAAA;AAAA;;MC3BPA,0BAAwB,CAAC;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,MACW;AACX,sDACG,MAAD;AAAA,IAAM,IAAI,OAAO;AAAA,kDACd,UAAD;AAAA,IAAU,YAAW;AAAA,KAClB,qDAAS,cAAD,MAAe,oDACvB,cAAD;AAAA,IACE,wBAAwB,EAAE,SAAS;AAAA,IACnC,SAAS,OAAO;AAAA,IAChB,WAAW,OAAO;AAAA,MAEnB,gEAAoB,KAAD;AAAA,IAAK,YAAW;AAAA,KAAY,gEAEjD,SAAD;AAAA;;AC7BN,MAAMC,cAAY,WAAW;AAAU,EACrC,SAAS;AAAA,IACP,OAAO;AAAA,IACP,SAAS;AAAA;AAAA,EAEX,MAAM;AAAA,IACJ,QAAQ,MAAM,QAAQ,IAAI,GAAG,GAAG;AAAA;AAAA;MASvBC,kBAAgB,CAAC;AAAA,EAC5B;AAAA,EACA;AAAA,MACwB;AACxB,QAAM,UAAUD;AAEhB,sDACG,OAAD;AAAA,IAAK,WAAW,QAAQ;AAAA,kDACrB,YAAD;AAAA,IACE,WAAW,QAAQ;AAAA,IACnB,cAAW;AAAA,IACX,SAAS;AAAA,kDAER,gBAAD,qDAED,YAAD;AAAA,IAAY,SAAQ;AAAA,KAAK,aACb,0BAA0B,0BAA0B,GAAE;AAAA;;AClBxE,MAAMA,cAAY,WAAW;AAAU,EACrC,SAAS;AAAA,IACP,YAAY;AAAA,IACZ,WAAW;AAAA;AAAA,EAEb,UAAU;AAAA,IACR,SAAS,MAAM,QAAQ,GAAG,GAAG,GAAG;AAAA;AAAA,EAElC,UAAU;AAAA,IACR,OAAO;AAAA;AAAA;MAsBEE,YAAU,CAAC;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,MACkB;AAClB,QAAM,UAAUF;AAEhB,sDACG,MAAD;AAAA,IAAM,WAAW,QAAQ;AAAA,kDACtB,YAAD;AAAA,IACE,oDAAQ,YAAD;AAAA,MAAY,SAAQ;AAAA,OAAK;AAAA,IAChC,qDACG,QAAD;AAAA,MAAQ,OAAM;AAAA,MAAU,SAAS,MAAM;AAAA,OAAgB;AAAA,mDAK1D,SAAD,OACC,cAAc,KAAK,WAAW,KAAK,cAAc,UAAU,WAAW,kDACpE,aAAD,mDACG,YAAD;AAAA,IAAY,SAAQ;AAAA,KAAY,oDAKnC,cAAc,KAAK,SAAS,kDAC1B,aAAD,mDACG,YAAD;AAAA,IAAY,SAAQ;AAAA,KAAY,sDAC/B,QAAD;AAAA,IACE,IAAG;AAAA,IACH,UAAU,CAAC,MAA2B;AAhGlD;AAiGc,4BAAe,6BAAG,WAAH,mBAAW;AAAA;AAAA,IAE5B,SAAQ;AAAA,IACR,WAAW,QAAQ;AAAA,IACnB,OAAO,QAAQ;AAAA,KAEd,cAAc,KAAK,IAAI,yDACrB,UAAD;AAAA,IACE,UAAU,WAAW;AAAA,IACrB,OAAK;AAAA,IACL,KAAK;AAAA,IACL,OAAO;AAAA,KAEN,YAMV,cAAc,UAAU,SAAS,kDAC/B,aAAD,mDACG,YAAD;AAAA,IAAY,SAAQ;AAAA,KAAY,2DAC/B,MAAD;AAAA,IAAM,gBAAc;AAAA,IAAC,OAAK;AAAA,KACvB,cAAc,UAAU,IAAI,yDAC1B,UAAD;AAAA,IACE,KAAK;AAAA,IACL,OAAK;AAAA,IACL,QAAM;AAAA,IACN,SAAS,MAAM,cAAc;AAAA,kDAE5B,UAAD;AAAA,IACE,MAAK;AAAA,IACL,eAAa;AAAA,IACb,WAAW,QAAQ;AAAA,IACnB,OAAM;AAAA,IACN,SAAS,QAAQ,QAAQ,SAAS;AAAA,IAClC,UAAU;AAAA,IACV,OAAO;AAAA,IACP,MAAM;AAAA,mDAEP,cAAD;AAAA,IAAc,IAAI;AAAA,IAAQ,SAAS;AAAA;AAAA;;MC9EtC,gBAAgB,cAC3B;MAGW,wBAAwB,CAAC;AAAA,EACpC,eAAe;AAAA,IACb,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,OAAO;AAAA;AAAA,EAET;AAAA,MACiE;AAvEnE;AAwEE,QAAM,YAAY,OAAO;AACzB,QAAM,CAAC,YAAY,iBAAiB,SAClC,aAAa;AAEf,QAAM,CAAC,SAAS,cAAc,SAAqB,aAAa;AAChE,QAAM,CAAC,MAAM,WAAW,SAAiB,aAAa;AACtD,QAAM,CAAC,OAAO,YAAY,SAAmB,aAAa;AAC1D,QAAM,CAAC,MAAM,WAAW,SAAkB;AAC1C,QAAM,cAAc,YAClB,MAAY,QAAQ,eAAa,CAAC,YAClC;AAGF,QAAM,WAAW,YAAY;AAE7B,QAAM,SAAS,SACb,MACE,UAAU,MAAM;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,MAEJ,CAAC,MAAM,SAAS,OAAO;AAGzB,QAAM,cACJ,CAAC,OAAO,WAAW,CAAC,OAAO,uBAAgB,UAAP,mBAAc;AACpD,QAAM,kBACJ,CAAC,OAAO,WAAW,CAAC,OAAO,uBAAgB,UAAP,mBAAc;AACpD,QAAM,gBAAgB,YAAY,MAAM;AAtG1C;AAuGI,kBAAc,cAAO,UAAP,oBAAc;AAAA,KAC3B,CAAC,aAAO,UAAP,mBAAc;AAClB,QAAM,oBAAoB,YAAY,MAAM;AAzG9C;AA0GI,kBAAc,cAAO,UAAP,oBAAc;AAAA,KAC3B,CAAC,aAAO,UAAP,mBAAc;AAElB,YAAU,MAAM;AAEd,QAAI,QAAQ,YAAY,SAAS,UAAU;AACzC,oBAAc;AAAA;AAAA,KAEf,CAAC,MAAM,UAAU,aAAa;AAEjC,QAAM,QAA4B;AAAA,IAChC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,eAAe,cAAc,gBAAgB;AAAA,IAC7C,mBAAmB,kBAAkB,oBAAoB;AAAA;AAG3D,sDAAQ,cAAc,UAAf;AAAA,IAAwB;AAAA,IAAc;AAAA;AAAA;MAGlC,YAAY,MAAM;AAC7B,QAAM,UAAU,WAAW;AAC3B,MAAI,YAAY,QAAW;AACzB,UAAM,IAAI,MAAM;AAAA;AAElB,SAAO;AAAA;;MCxGI,gBAAgB,CAAC;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb,cAAc;AAAA,MACM;AACpB,QAAM,YAAY,OAAO;AAEzB,QAAM,YAAYG,eAAM,YACtB,CAAC,MAAuC;AACtC,QAAI,YAAY,EAAE,QAAQ,SAAS;AACjC;AAAA;AAAA,KAGJ,CAAC;AAGH,QAAM,cAAcA,eAAM,YAAY,MAAM;AAC1C,aAAS;AAAA,KACR,CAAC;AAEJ,QAAM,cACJ,oDACA,aAAa,UAAU,kBAAkB,gBAAgB;AAE3D,sDACG,WAAD;AAAA,IAGE;AAAA,IACA,eAAY;AAAA,IACZ,WAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA,UAAU,OAAK,SAAS,EAAE,OAAO;AAAA,IACjC,YAAY,EAAE,cAAc;AAAA,IAC5B,6DACG,gBAAD;AAAA,MAAgB,UAAS;AAAA,oDACtB,YAAD;AAAA,MAAY,cAAW;AAAA,MAAQ,UAAQ;AAAA,oDACpC,YAAD;AAAA,IAIN,cACE,4DACG,gBAAD;AAAA,MAAgB,UAAS;AAAA,oDACtB,YAAD;AAAA,MAAY,cAAW;AAAA,MAAQ,SAAS;AAAA,oDACrC,aAAD;AAAA,OAKH,aAAa,EAAE;AAAA,OACf,YAAY,EAAE;AAAA;AAAA;MAaZC,cAAY,CAAC;AAAA,EACxB;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA,cAAc;AAAA,MACH;AACX,QAAM,EAAE,MAAM,YAAY;AAC1B,QAAM,CAAC,OAAO,YAAY,SAAiB;AAE3C,YAAU,MAAM;AACd,aAAS,eAAc,cAAc,OAAO,OAAO;AAAA,KAClD,CAAC;AAEJ,cAAY,MAAM,QAAQ,QAAQ,cAAc,CAAC;AAEjD,QAAM,cAAc,CAAC,aAAqB;AACxC,aAAS;AAAA;AAGX,QAAM,cAAc,MAAM,SAAS;AAEnC,sDACG,eAAD;AAAA,IAGE;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV,SAAS;AAAA,IACT;AAAA,IACA;AAAA;AAAA;;AC3GN,MAAMJ,cAAY,WAAW;AAAA,EAC3B,OAAO;AAAA,IACL,eAAe;AAAA;AAAA;AAgBnB,MAAM,iBAAiB,CAAC;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,MACM;AACf,QAAM,UAAUA;AAChB,QAAM,EAAE,SAAS,eAAe;AAEhC,YAAU,MAAM;AACd,QAAI,MAAM,QAAQ,eAAe;AAC/B,iBAAW;AAAgB,WACtB;AAAA,SACF,OAAO;AAAA;AAAA;AAAA,KAIX;AAEH,QAAM,eAAe,CAAC,MAAqC;AACzD,UAAM;AAAA,MACJ,QAAQ,EAAE,OAAO;AAAA,QACf;AAEJ,eAAW,iBAAe;AACxB,YAAM,GAAG,OAAO,WAAW,WAAW;AACtC,YAAM,OAAS,WAAuB,IAAI,OAAO,OAAK,MAAM;AAC5D,YAAM,QAAQ,UAAU,CAAC,GAAG,MAAM,SAAS;AAC3C,aAAO,MAAM,SAAS,KAAK,SAAS,OAAO,UAAU;AAAA;AAAA;AAIzD,sDACG,aAAD;AAAA,IACE;AAAA,IACA,WAAS;AAAA,IACT,eAAY;AAAA,kDAEX,WAAD;AAAA,IAAW,WAAW,QAAQ;AAAA,KAAQ,OACrC,OAAO,IAAI,CAAC,UAAe;AAvFlC;AAwFQ,wDAAC,kBAAD;AAAA,MACE,KAAK;AAAA,MACL,sDACG,UAAD;AAAA,QACE,OAAM;AAAA,QACN,UAAU;AAAA,QACV,YAAY,EAAE,mBAAmB;AAAA,QACjC;AAAA,QACA,MAAM;AAAA,QACN,UAAU;AAAA,QACV,SAAW,eAAQ,UAAR,YAA8B,IAAI,SAAS;AAAA;AAAA,MAG1D,OAAO;AAAA;AAAA;AAAA;AAOjB,MAAM,eAAe,CAAC;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,MACM;AACf,QAAM,UAAUA;AAChB,QAAM,EAAE,SAAS,eAAe;AAEhC,YAAU,MAAM;AACd,QAAI,OAAO,iBAAiB,UAAU;AACpC,iBAAW;AAAgB,WACtB;AAAA,SACF,OAAO;AAAA;AAAA;AAAA,KAIX;AAEH,QAAM,eAAe,CAAC,MAAuC;AAC3D,UAAM;AAAA,MACJ,QAAQ,EAAE;AAAA,QACR;AAEJ,eAAW,iBAAe;AACxB,YAAM,GAAG,OAAO,WAAW,WAAW;AACtC,aAAO,QAAQ,KAAK,SAAS,OAAO,UAAoB;AAAA;AAAA;AAI5D,sDACG,aAAD;AAAA,IACE;AAAA,IACA,SAAQ;AAAA,IACR,WAAS;AAAA,IACT,eAAY;AAAA,kDAEX,YAAD;AAAA,IAAY,WAAW,QAAQ;AAAA,IAAO,QAAO;AAAA,KAC1C,oDAEF,QAAD;AAAA,IACE,SAAQ;AAAA,IACR,OAAO,QAAQ,SAAS;AAAA,IACxB,UAAU;AAAA,kDAET,UAAD;AAAA,IAAU,OAAM;AAAA,kDACb,MAAD,MAAI,SAEL,OAAO,IAAI,CAAC,uDACV,UAAD;AAAA,IAAU,KAAK;AAAA,IAAO;AAAA,KACnB;AAAA;MAQP,eAAe,CAAC,EAAE,WAAW,YAAY,yDAC5C,SAAD;AAAA,KAAa;AAAA;AAGf,aAAa,WAAW,CAAC,uDACtB,cAAD;AAAA,KAAkB;AAAA,EAAO,WAAW;AAAA;AAGtC,aAAa,SAAS,CAAC,uDACpB,cAAD;AAAA,KAAkB;AAAA,EAAO,WAAW;AAAA;MAShC,mBAAmB;;ACtLzB,aAAe,aAAa,eAAe,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE;AACvE,EAAE,CAAC,EAAE,oIAAoI;AACzI,CAAC,CAAC,EAAE,QAAQ,CAAC;;MCyBA,wBAAwB,CAAC,EAAE,eAAsB;AAC5D,QAAM;AAAA,IACJ,QAAQ,EAAE,SAAS,OAAO;AAAA,MACxB;AAEJ,MAAI,SAAS;AACX,wDAAQ,UAAD;AAAA;AAET,MAAI,OAAO;AACT,wDACG,oBAAD;AAAA,MACE,OAAM;AAAA,MACN;AAAA;AAAA;AAKN,MAAI,iCAAQ,QAAQ,SAAQ;AAC1B,wDAAQ,YAAD;AAAA,MAAY,SAAQ;AAAA,MAAO,OAAM;AAAA;AAAA;AAG1C,qFAAU,SAAS,EAAE,SAAS,MAAM;AAAA;;AC5BtC,MAAMA,cAAY,WAAW;AAAU,EACrC,MAAM;AAAA,IACJ,SAAS;AAAA,IACT,gBAAgB;AAAA,IAChB,KAAK,MAAM,QAAQ;AAAA,IACnB,QAAQ,MAAM,QAAQ,GAAG;AAAA;AAAA;MAIhB,oBAAoB,MAAM;AACrC,QAAM,EAAE,eAAe,sBAAsB;AAC7C,QAAM,UAAUA;AAEhB,MAAI,CAAC,iBAAiB,CAAC,mBAAmB;AACxC;AAAO;AAGT,sDACG,OAAD;AAAA,IAAK,eAAY;AAAA,IAAwB,WAAW,QAAQ;AAAA,kDACzD,QAAD;AAAA,IACE,cAAW;AAAA,IACX,UAAU,CAAC;AAAA,IACX,SAAS;AAAA,IACT,wDAAY,kBAAD;AAAA,KACZ,0DAIA,QAAD;AAAA,IACE,cAAW;AAAA,IACX,UAAU,CAAC;AAAA,IACX,SAAS;AAAA,IACT,sDAAU,qBAAD;AAAA,KACV;AAAA;;MC5BM,eAAe,eAAe;AAAA,EACzC,IAAI;AAAA;MAGO,mBAAmB,eAAe;AAAA,EAC7C,IAAI;AAAA;MAGO,eAAe,aAAa;AAAA,EACvC,IAAI;AAAA,EACJ,MAAM;AAAA,IACJ,iBAAiB;AAAA,MACf,KAAK;AAAA,MACL,MAAM,EAAE,cAAc,iBAAiB,aAAa;AAAA,MACpD,SAAS,CAAC,EAAE,cAAc,kBAAkB;AAC1C,eAAO,IAAI,aAAa,EAAE,cAAc;AAAA;AAAA;AAAA;AAAA,EAI9C,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,UAAU;AAAA;AAAA;MAIDK,eAAa,aAAa,QACrC,wBAAwB;AAAA,EACtB,MAAM;AAAA,EACN,WAAW,MAAM,OAAO,2BAA2B,KAAK,OAAK,EAAE;AAAA,EAC/D,YAAY;AAAA;MAUH,iBAAiB,aAAa,QACzC,wBAAwB;AAAA,EACtB,MAAM;AAAA,EACN,WAAW,MAAM,OAAO,2BAA2B,KAAK,OAAK,EAAE;AAAA,EAC/D,YAAY;AAAA;AAIS,aAAa,QACpC,yBAAyB;AAAA,EACvB,MAAM;AAAA,EACN,WAAW;AAAA,IACT,MAAM,MAAM,OAAO,2BAA0B,KAAK,OAAK,EAAE;AAAA;AAAA;MAWlD,gBAAgB,aAAa,QACxC,yBAAyB;AAAA,EACvB,MAAM;AAAA,EACN,WAAW;AAAA,IACT,MAAM,MAAM,OAAO,2BAA0B,KAAK,OAAK,EAAE;AAAA;AAAA;MAKlDC,iBAAe,aAAa,QACvC,yBAAyB;AAAA,EACvB,MAAM;AAAA,EACN,WAAW;AAAA,IACT,MAAM,MAAM,OAAO,2BAA6B,KAAK,OAAK,EAAE;AAAA;AAAA;AAWlC,aAAa,QAC3C,yBAAyB;AAAA,EACvB,MAAM;AAAA,EACN,WAAW;AAAA,IACT,MAAM,MAAM,OAAO,2BAA6B,KAAK,OAAK,EAAE;AAAA;AAAA;MAKrD,qBAAqB,aAAa,QAC7C,yBAAyB;AAAA,EACvB,MAAM;AAAA,EACN,WAAW;AAAA,IACT,MAAM,MACJ,OAAO,2BAAmC,KACxC,OAAK,EAAE;AAAA;AAAA;MAMJ,wBAAwB,aAAa,QAChD,yBAAyB;AAAA,EACvB,MAAM;AAAA,EACN,WAAW;AAAA,IACT,MAAM,MACJ,OAAO,2BAAsC,KAC3C,OAAK,EAAE;AAAA;AAAA;MAMJ,oBAAoB,aAAa,QAC5C,yBAAyB;AAAA,EACvB,MAAM;AAAA,EACN,WAAW;AAAA,IACT,MAAM,MACJ,OAAO,2BAAkC,KAAK,OAAK,EAAE;AAAA;AAAA;;AC3G7D,MAAMN,cAAYO,aAAW;AAAU,EACrC,WAAW;AAAA,IACT,cAAc;AAAA,IACd,SAAS;AAAA,IACT,QAAQ;AAAA;AAAA,EAEV,OAAO;AAAA,IACL,MAAM;AAAA;AAAA,EAGR,gBAAgB,EAAE,QAAQ;AAAA,EAC1B,wBAAwB,EAAE,SAAS,MAAM,QAAQ,GAAG;AAAA,EACpD,iBAAiB,EAAE,eAAe;AAAA;MAGvB,QAAQ,CAAC,EAAE,OAAO,MAAM,kBAAoC;AACvE,QAAM,gBAAgB,YAAY;AAClC,QAAM,UAAUP;AAEhB,QAAM,EAAE,MAAM,YAAY;AAC1B,QAAM,CAAC,OAAO,YAAY,SAAiB;AAE3C,YAAU,MAAM;AACd,aAAS,eAAc,cAAc,OAAO,OAAO;AAAA,KAClD,CAAC;AAEJ,cAAY,MAAM,QAAQ,QAAQ,KAAK,CAAC;AAExC,QAAM,cAAc,CAAC,aAAqB;AACxC,aAAS;AAAA;AAGX,QAAM,cAAc,MAAM,SAAS;AAEnC,QAAM,oBAAoB,MAAM;AAC9B;AACA;AAAA;AAGF,QAAM,iBAAiB,MAAM;AAC3B;AAAA;AAGF,sDACG,QAAD;AAAA,IACE,SAAS;AAAA,MACP,gBAAgB,QAAQ;AAAA;AAAA,IAE1B,SAAS;AAAA,IACT,mBAAgB;AAAA,IAChB;AAAA,IACA,WAAS;AAAA,IACT,UAAS;AAAA,kDAER,aAAD,mDACG,OAAD;AAAA,IAAO,WAAW,QAAQ;AAAA,kDACvB,eAAD;AAAA,IACE,WAAW,QAAQ;AAAA,IACnB;AAAA,IACA,UAAU;AAAA,IACV,SAAS;AAAA,qDAId,eAAD,mDACG,MAAD;AAAA,IACE,WAAS;AAAA,IACT,WAAU;AAAA,IACV,gBAAe;AAAA,IACf,YAAW;AAAA,kDAEV,MAAD;AAAA,IAAM,MAAI;AAAA,kDACP,MAAD;AAAA,IACE,SAAS;AAAA,IACT,IAAI,GAAG,yBAAyB;AAAA,kDAE/B,QAAD;AAAA,IAAM,WAAW,QAAQ;AAAA,KAAiB,mEACzC,QAAD;AAAA,IAAQ,OAAM;AAAA,sDAInB,SAAD,oDACCM,uBAAD,MACG,CAAC,EAAE,2DACD,MAAD,MACG,QAAQ,IAAI,CAAC,EAAE,4DACb,OAAD;AAAA,IACE,MAAK;AAAA,IACL,UAAU;AAAA,IACV,KAAK,GAAG,SAAS;AAAA,IACjB,SAAS;AAAA,IACT,YAAY;AAAA,kDAEXP,yBAAD;AAAA,IACE,KAAK,SAAS;AAAA,IACd,QAAQ;AAAA,wDAQrB,eAAD;AAAA,IAAe,WAAW,QAAQ;AAAA,kDAC/B,MAAD;AAAA,IAAM,WAAS;AAAA,IAAC,WAAU;AAAA,kDACvB,MAAD;AAAA,IAAM,MAAI;AAAA,IAAC,IAAI;AAAA,kDACZ,mBAAD;AAAA;MAQC,cAAc,CAAC,EAAE,OAAO,MAAM,kBAAoC;AAC7E,sDACG,uBAAD,mDACG,OAAD;AAAA,IAAO;AAAA,IAAY;AAAA;AAAA;;ACzIzB,MAAMC,cAAYO,aAAW;AAAO,EAClC,MAAM;AAAA,IACJ,SAAS;AAAA,IACT,YAAY;AAAA;AAAA,EAEd,OAAO;AAAA,IACL,MAAM;AAAA;AAAA;MAUG,YAAY,CAAC;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,MACoB;AACpB,QAAM,UAAUP;AAEhB,sDACG,OAAD;AAAA,IACE,WAAU;AAAA,IACV,UAAU,OAAK,aAAa;AAAA,IAC5B,WAAW,QAAQ;AAAA,kDAElBQ,cAAD;AAAA,IAAY,UAAQ;AAAA,IAAC,MAAK;AAAA,IAAS,cAAW;AAAA,kDAC3C,YAAD,qDAEDC,aAAD;AAAA,IACE,WAAW,QAAQ;AAAA,IACnB,aAAY;AAAA,IACZ,OAAO;AAAA,IACP,UAAU,OAAK,aAAa;AAAA,IAC5B,YAAY,EAAE,cAAc;AAAA,mDAE7BD,cAAD;AAAA,IAAY,cAAW;AAAA,IAAS,SAAS,MAAM;AAAA,kDAC5C,aAAD;AAAA;;AC5CR,MAAMR,cAAY,WAAW;AAAU,EACrC,SAAS;AAAA,IACP,OAAO;AAAA,IACP,SAAS;AAAA;AAAA,EAEX,MAAM;AAAA,IACJ,QAAQ,MAAM,QAAQ,IAAI,GAAG,GAAG;AAAA;AAAA;MASvB,gBAAgB,CAAC;AAAA,EAC5B;AAAA,EACA;AAAA,MACwB;AACxB,QAAM,UAAUA;AAEhB,sDACG,OAAD;AAAA,IAAK,WAAW,QAAQ;AAAA,kDACrB,YAAD;AAAA,IACE,WAAW,QAAQ;AAAA,IACnB,cAAW;AAAA,IACX,SAAS;AAAA,kDAER,gBAAD,qDAED,YAAD;AAAA,IAAY,SAAQ;AAAA,KAAK,aACb,0BAA0B,0BAA0B,GAAE;AAAA;;AClBxE,MAAMA,cAAY,WAAW;AAAU,EACrC,SAAS;AAAA,IACP,YAAY;AAAA,IACZ,WAAW;AAAA;AAAA,EAEb,UAAU;AAAA,IACR,SAAS,MAAM,QAAQ,GAAG,GAAG,GAAG;AAAA;AAAA,EAElC,UAAU;AAAA,IACR,OAAO;AAAA;AAAA;MAsBE,UAAU,CAAC;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,MACkB;AAClB,QAAM,UAAUA;AAEhB,sDACG,MAAD;AAAA,IAAM,WAAW,QAAQ;AAAA,kDACtB,YAAD;AAAA,IACE,oDAAQ,YAAD;AAAA,MAAY,SAAQ;AAAA,OAAK;AAAA,IAChC,qDACG,QAAD;AAAA,MAAQ,OAAM;AAAA,MAAU,SAAS,MAAM;AAAA,OAAgB;AAAA,mDAK1D,SAAD,OACC,cAAc,KAAK,WAAW,KAAK,cAAc,UAAU,WAAW,kDACpE,aAAD,mDACG,YAAD;AAAA,IAAY,SAAQ;AAAA,KAAY,oDAKnC,cAAc,KAAK,SAAS,kDAC1B,aAAD,mDACG,YAAD;AAAA,IAAY,SAAQ;AAAA,KAAY,sDAC/B,QAAD;AAAA,IACE,IAAG;AAAA,IACH,UAAU,CAAC,MAA2B;AAhGlD;AAiGc,4BAAe,6BAAG,WAAH,mBAAW;AAAA;AAAA,IAE5B,SAAQ;AAAA,IACR,WAAW,QAAQ;AAAA,IACnB,OAAO,QAAQ;AAAA,KAEd,cAAc,KAAK,IAAI,yDACrB,UAAD;AAAA,IACE,UAAU,WAAW;AAAA,IACrB,OAAK;AAAA,IACL,KAAK;AAAA,IACL,OAAO;AAAA,KAEN,YAMV,cAAc,UAAU,SAAS,kDAC/B,aAAD,mDACG,YAAD;AAAA,IAAY,SAAQ;AAAA,KAAY,2DAC/B,MAAD;AAAA,IAAM,gBAAc;AAAA,IAAC,OAAK;AAAA,KACvB,cAAc,UAAU,IAAI,yDAC1B,UAAD;AAAA,IACE,KAAK;AAAA,IACL,OAAK;AAAA,IACL,QAAM;AAAA,IACN,SAAS,MAAM,cAAc;AAAA,kDAE5B,UAAD;AAAA,IACE,MAAK;AAAA,IACL,eAAa;AAAA,IACb,WAAW,QAAQ;AAAA,IACnB,OAAM;AAAA,IACN,SAAS,QAAQ,QAAQ,SAAS;AAAA,IAClC,UAAU;AAAA,IACV,OAAO;AAAA,IACP,MAAM;AAAA,mDAEP,cAAD;AAAA,IAAc,IAAI;AAAA,IAAQ,SAAS;AAAA;AAAA;;AC9FnD,MAAMA,cAAY,WAAW;AAAU,EACrC,aAAa;AAAA,IACX,OAAO,MAAM,QAAQ,KAAK;AAAA,IAC1B,YAAY,MAAM,QAAQ,WAAW;AAAA,IACrC,cAAc;AAAA;AAAA,EAEhB,aAAa;AAAA,IACX,QAAQ,MAAM,QAAQ,GAAG,GAAG,GAAG;AAAA,IAC/B,SAAS;AAAA;AAAA,EAEX,SAAS;AAAA,IACP,OAAO;AAAA,IACP,QAAQ,MAAM,QAAQ,GAAG;AAAA,IACzB,SAAS,MAAM,QAAQ,GAAG;AAAA;AAAA;AAgB9B,MAAM,UAAyB;AAAA,EAC7B;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,WAAW;AAAA,IACX,QAAQ,CAAC,wDACN,MAAD;AAAA,MAAM,IAAI,OAAO,OAAO;AAAA,OAAK,OAAO;AAAA;AAAA,EAGxC;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA;AAAA,EAET;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA;AAAA,EAET;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA;AAAA,EAET;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA;AAAA;AAIX,MAAM,cAAc,CAAC;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,MACsB;AACtB,QAAM,UAAUA;AAEhB,sDACG,OAAD;AAAA,IAAK,WAAW,QAAQ;AAAA,kDACrB,eAAD;AAAA,IACE;AAAA,IACA;AAAA,mDAED,SAAD;AAAA,IAAS,WAAW,QAAQ;AAAA,IAAS,aAAY;AAAA,mDAChD,MAAD;AAAA,IAAM,MAAI;AAAA,IAAC,IAAI;AAAA,KACZ,2DACE,YAAD;AAAA,IAAY,SAAQ;AAAA,KACjB,GAAG,oBACH,kBAAkB,IAAI,iBAAiB,4DACvC,QAAD;AAAA,IAAM,WAAW,QAAQ;AAAA,KAAa,KAAE,aAAY,MAAS,oDAG9D,YAAD;AAAA,IAAY,SAAQ;AAAA,KAAM,GAAG;AAAA;MAO1B,eAAe,CAAC,EAAE,kBAAqC;AAClE,QAAM,aAAa,OAAO;AAE1B,QAAM,CAAC,aAAa,iBAAiB,SAAS;AAC9C,QAAM,CAAC,iBAAiB,sBAAsB,SAAuB;AAAA,IACnE,UAAU;AAAA,IACV,SAAS;AAAA;AAGX,QAAM,CAAC,iBAAiB,sBAAsB,SAAwB;AAEtE,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,OAAO;AAAA,MACL,SAAS,YAAY;AACvB,UAAM,WAAW,MAAM,WAAW;AAClC,WAAO,SAAS,MAAM,IAAI,CAAC,WAAgB;AAlJ/C;AAkJmD;AAAA,QAC7C,MAAM,OAAO,SAAS;AAAA,QACtB,aAAa,OAAO,SAAS;AAAA,QAC7B,OACE,qBAAc,SAAP,mBAAa,WAAU,WAAW,aAAO,SAAP,mBAAa,QAAQ;AAAA,QAChE,MAAM,OAAO;AAAA,QACb,WACE,qBAAc,SAAP,mBAAa,eAAc,WAC9B,aAAO,SAAP,mBAAa,YACb;AAAA,QACN,KAAK,YACH,cAAO,SAAS,cAAhB,mBAA2B,kBAAkB,aAC7C,4BACE,OAAO,KAAK,kBAAkB,YAAY,OAAO,SAAS;AAAA;AAAA;AAAA,KAE/D;AAEH,YAAU,MAAM;AACd,QAAI,SAAS;AACX,UAAI,cAAc;AAKlB,UAAI,gBAAgB,aAAa,IAAI;AACnC,sBAAc,QAAQ,OAAO,CAAC,WAC5B,gBAAgB,SAAS,SAAS,OAAO;AAAA;AAK7C,UAAI,gBAAgB,QAAQ,SAAS,GAAG;AACtC,sBAAc,YAAY,OACxB,CAAC,WACC,OAAO,aACP,gBAAgB,QAAQ,SAAS,OAAO;AAAA;AAK9C,UAAI,aAAa;AACf,sBAAc,YAAY,OACxB,CAAC,WAAgB;AA5L3B;AA6LY,+BAAO,SAAP,mBAAa,kBAAkB,SAAS,SAAS,+BAC1C,SAAP,mBACI,kBAAkB,SACnB,SAAS,YAAY,MAAM,KAAK,KAAK,wBACjC,gBAAP,mBACI,kBAAkB,SACnB,SAAS;AAAA;AAAA;AAIlB,yBAAmB;AAAA;AAAA,KAEpB,CAAC,iBAAiB,aAAa;AAClC,MAAI,SAAS;AACX,wDAAQ,UAAD;AAAA;AAET,MAAI,OAAO;AACT,wDACG,OAAD;AAAA,MAAO,UAAS;AAAA,OAAQ,qDAC4B,MAAM;AAAA;AAI9D,MAAI,CAAC,WAAW,QAAQ,WAAW,GAAG;AACpC,wDAAQ,YAAD;AAAA,MAAY,SAAQ;AAAA,MAAO,OAAM;AAAA;AAAA;AAG1C,QAAM,eAAe,MAAM;AACzB,uBAAmB;AAAA,MACjB,UAAU;AAAA,MACV,SAAS;AAAA;AAAA;AAIb,QAAM,iBAAiB,CAAC,WAAmB;AACzC,uBAAmB;AAAc,SAC5B;AAAA,MACH,UAAU;AAAA;AAAA;AAId,QAAM,gBAAgB,CAAC,WAAmB;AACxC,QAAI,gBAAgB,QAAQ,SAAS,SAAS;AAC5C,yBAAmB;AAAc,WAC5B;AAAA,QACH,SAAS,UAAU,QAAQ,OAAO,UAAQ,SAAS;AAAA;AAErD;AAAA;AAGF,uBAAmB;AAAc,SAC5B;AAAA,MACH,SAAS,CAAC,GAAG,UAAU,SAAS;AAAA;AAAA;AAIpC,QAAM,gBAAgB,QAAQ,OAC5B,CAAC,KAAK,SAAS;AACb,QAAI,KAAK,QAAQ,IAAI,KAAK,QAAQ,KAAK,QAAQ,GAAG;AAChD,UAAI,KAAK,KAAK,KAAK;AAAA;AAErB,QAAI,KAAK,aAAa,IAAI,UAAU,QAAQ,KAAK,aAAa,GAAG;AAC/D,UAAI,UAAU,KAAK,KAAK;AAAA;AAE1B,WAAO;AAAA,KAET;AAAA,IACE,MAAM;AAAA,IACN,WAAW;AAAA;AAIf,kIAEK,MAAD;AAAA,IAAM,WAAS;AAAA,KACZ,4DACE,MAAD;AAAA,IAAM,MAAI;AAAA,IAAC,IAAI;AAAA,kDACZ,SAAD;AAAA,IACE,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,oDAIL,MAAD;AAAA,IAAM,MAAI;AAAA,IAAC,IAAI,cAAc,IAAI;AAAA,kDAC9B,OAAD;AAAA,IACE,SAAS,EAAE,QAAQ,MAAM,UAAU,IAAI,QAAQ;AAAA,IAC/C,MAAM;AAAA,IACN;AAAA,IACA,oDACG,aAAD;AAAA,MACE;AAAA,MACA,iBAAiB,gBAAgB;AAAA,MACjC,yBACG,iBAAgB,aAAa,KAAK,IAAI,KACvC,gBAAgB,QAAQ;AAAA,MAE1B,qBAAqB,MAAM,cAAc,CAAC;AAAA;AAAA;AAAA;;MCjQ7C,mBAAmB,MAAM;AACpC,QAAM,CAAC,aAAa,kBAAkB,mBAA2B;AACjE,QAAM,CAAC,aAAa,kBAAkB,SAAS,oCAAe;AAE9D,QAAM,eAAe,CAAC,UAA+C;AACnE,UAAM;AACN,mBAAe,MAAM,OAAO;AAAA;AAG9B,YAAU,MAAM,eAAe,oCAAe,KAAK,CAAC;AAEpD,cACE,MAAM;AACJ,mBAAe;AAAA,KAEjB,KACA,CAAC;AAGH,QAAM,uBAAuB,MAAM;AACjC,mBAAe;AAAA;AAGjB,sDACG,MAAD;AAAA,IAAM,SAAQ;AAAA,kDACX,QAAD;AAAA,IAAQ,OAAM;AAAA,mDACb,SAAD,mDACG,MAAD;AAAA,IAAM,WAAS;AAAA,IAAC,WAAU;AAAA,kDACvB,MAAD;AAAA,IAAM,MAAI;AAAA,IAAC,IAAI;AAAA,kDACZ,WAAD;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,oDAGH,MAAD;AAAA,IAAM,MAAI;AAAA,IAAC,IAAI;AAAA,kDACZ,cAAD;AAAA,IACE,aAAc,qCAAe,IAAI,kBAAkB;AAAA;AAAA;;MC5CpD,aAAa,MAAM;AAC9B,QAAM,WAAW;AACjB,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,MACE;AAEJ,QAAM,kBAAkB,YAAY,SAAS;AAC7C,YAAU,MAAM;AAEd,QAAI,SAAS,WAAW,iBAAiB;AACvC;AAAA;AAGF,UAAM,QACJ,GAAG,MAAM,SAAS,OAAO,UAAU,IAAI,EAAE,YAAY,QAAQ;AAE/D,QAAI,MAAM,SAAS;AACjB,iBAAW,MAAM;AAAA;AAGnB,QAAI,MAAM,OAAO;AACf,cAAQ,MAAM;AAAA;AAGhB,QAAI,MAAM,YAAY;AACpB,oBAAc,MAAM;AAAA;AAGtB,QAAI,MAAM,OAAO;AACf,eAAS,MAAM;AAAA;AAAA,KAEhB,CAAC,iBAAiB,UAAU,SAAS,UAAU,eAAe;AAEjE,YAAU,MAAM;AACd,UAAM,YAAY,GAAG,UACnB;AAAA,MACE,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,OAEF,EAAE,aAAa;AAEjB,UAAM,SAAS,GAAG,OAAO,SAAS,YAAY;AAM9C,WAAO,QAAQ,aAAa,MAAM,SAAS,OAAO;AAAA,KACjD,CAAC,MAAM,OAAO,YAAY;AAE7B,SAAO;AAAA;MAGI,aAAa,MAAM;AAC9B,QAAM,SAAS;AAEf,sDACG,uBAAD,mDACG,YAAD,OACC,uDAAW,kBAAD;AAAA;;AC/DjB,MAAM,YAAY,WAAW;AAAU,EACrC,OAAO;AAAA,IACL,eAAe;AAAA;AAAA,EAEjB,OAAO;AAAA,IACL,SAAS;AAAA,IACT,UAAU;AAAA,IACV,WAAW,MAAM,QAAQ;AAAA;AAAA,EAE3B,MAAM;AAAA,IACJ,QAAQ;AAAA;AAAA;MAWN,aAAa,CAAC;AAAA,EAClB,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,MACqB;AACrB,QAAM,UAAU;AAChB,QAAM,EAAE,OAAO,aAAa;AAE5B,gBAAc,MAAM;AAClB,QAAI,CAAC,MAAM,QAAQ;AACjB,UAAI,gBAAgB,MAAM,QAAQ,eAAe;AAC/C,iBAAS;AAAA,iBACA,cAAc;AACvB,iBAAS,CAAC;AAAA;AAAA;AAAA;AAKhB,QAAM,eAAe,CAAC,MAAuC;AAC3D,UAAM,QAAQ,EAAE,OAAO;AACvB,aAAS;AAAA;AAGX,sDACG,aAAD;AAAA,IACE;AAAA,IACA,SAAQ;AAAA,IACR,WAAS;AAAA,IACT,eAAY;AAAA,kDAEX,YAAD;AAAA,IAAY,WAAW,QAAQ;AAAA,IAAO,QAAO;AAAA,KAC1C,oDAEF,QAAD;AAAA,IACE,UAAQ;AAAA,IACR,SAAQ;AAAA,IACR,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAY;AAAA,IACZ,aAAa,2DACV,OAAD;AAAA,MAAK,WAAW,QAAQ;AAAA,OACpB,SAAsB,IAAI,wDACzB,MAAD;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,MACP,WAAW,QAAQ;AAAA,MACnB,MAAK;AAAA;AAAA,KAMZ,OAAO,IAAI,CAAC,uDACV,UAAD;AAAA,IAAU,KAAK;AAAA,IAAO;AAAA,kDACnB,UAAD;AAAA,IAAU,SAAS,MAAM,QAAQ,SAAS;AAAA,mDACzC,cAAD;AAAA,IAAc,SAAS;AAAA;AAAA;;MCnFtB,gBAAgB,MAAM;AACjC,QAAM,cAAc,YAAY;AAChC,QAAM,WAAW;AACjB,QAAM,eAAe,YACnB,CAAC,UAAwB;AACvB,UAAM,cAAc,GAAG,UAAU,EAAE,SAAS,EAAE,gBAAgB;AAE9D,aAAS,GAAG,gBAAgB;AAAA,KAE9B,CAAC,UAAU;AAGb,sDAAQ,oBAAD;AAAA,IAAoB,UAAU;AAAA,IAAc,IAAG;AAAA;AAAA;;;;"}
@@ -1,6 +1,6 @@
1
1
  import React__default, { useCallback } from 'react';
2
2
  import { makeStyles } from '@material-ui/core/styles';
3
- import { r as rootRouteRef, b as SearchBarBase } from './index-8e7d7ce9.esm.js';
3
+ import { r as rootRouteRef, b as SearchBarBase } from './index-893ec2f5.esm.js';
4
4
  import qs from 'qs';
5
5
  import { useNavigate } from 'react-router-dom';
6
6
  import { useRouteRef } from '@backstage/core-plugin-api';
@@ -24,8 +24,8 @@ import '@backstage/catalog-model';
24
24
  const useNavigateToQuery = () => {
25
25
  const searchRoute = useRouteRef(rootRouteRef);
26
26
  const navigate = useNavigate();
27
- return useCallback(({query}) => {
28
- const queryString = qs.stringify({query}, {addQueryPrefix: true});
27
+ return useCallback(({ query }) => {
28
+ const queryString = qs.stringify({ query }, { addQueryPrefix: true });
29
29
  navigate(`${searchRoute()}${queryString}`);
30
30
  }, [navigate, searchRoute]);
31
31
  };
@@ -37,12 +37,12 @@ const useStyles = makeStyles({
37
37
  fontSize: "1.5em"
38
38
  }
39
39
  });
40
- const HomePageSearchBar = ({placeholder}) => {
40
+ const HomePageSearchBar = ({ placeholder }) => {
41
41
  const [query, setQuery] = React__default.useState("");
42
42
  const handleSearch = useNavigateToQuery();
43
43
  const classes = useStyles();
44
44
  const handleSubmit = () => {
45
- handleSearch({query});
45
+ handleSearch({ query });
46
46
  };
47
47
  const handleChange = React__default.useCallback((value) => {
48
48
  setQuery(value);
@@ -57,4 +57,4 @@ const HomePageSearchBar = ({placeholder}) => {
57
57
  };
58
58
 
59
59
  export { HomePageSearchBar };
60
- //# sourceMappingURL=index-58cc0fcf.esm.js.map
60
+ //# sourceMappingURL=index-bc274d46.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-58cc0fcf.esm.js","sources":["../../src/components/util.ts","../../src/components/HomePageComponent/HomePageSearchBar.tsx"],"sourcesContent":["/*\n * Copyright 2021 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 */\nimport qs from 'qs';\nimport { useCallback } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { rootRouteRef } from '../plugin';\n\nimport { useRouteRef } from '@backstage/core-plugin-api';\n\nexport const useNavigateToQuery = () => {\n const searchRoute = useRouteRef(rootRouteRef);\n const navigate = useNavigate();\n return useCallback(\n ({ query }: { query: string }): void => {\n const queryString = qs.stringify({ query }, { addQueryPrefix: true });\n\n navigate(`${searchRoute()}${queryString}`);\n },\n [navigate, searchRoute],\n );\n};\n","/*\n * Copyright 2021 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 { makeStyles } from '@material-ui/core/styles';\n\nimport { SearchBarBase } from '../SearchBar';\nimport { useNavigateToQuery } from '../util';\n\nconst useStyles = makeStyles({\n searchBar: {\n border: '1px solid #555',\n borderRadius: '6px',\n fontSize: '1.5em',\n },\n});\n\ntype Props = {\n placeholder?: string;\n};\n\nexport const HomePageSearchBar = ({ placeholder }: Props) => {\n const [query, setQuery] = React.useState('');\n const handleSearch = useNavigateToQuery();\n const classes = useStyles();\n\n const handleSubmit = () => {\n handleSearch({ query });\n };\n\n const handleChange = React.useCallback(\n value => {\n setQuery(value);\n },\n [setQuery],\n );\n\n return (\n <SearchBarBase\n onSubmit={handleSubmit}\n onChange={handleChange}\n value={query}\n className={classes.searchBar}\n placeholder={placeholder}\n />\n );\n};\n"],"names":["React"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;MAsBa,qBAAqB,MAAM;AACtC,QAAM,cAAc,YAAY;AAChC,QAAM,WAAW;AACjB,SAAO,YACL,CAAC,CAAE,WAAqC;AACtC,UAAM,cAAc,GAAG,UAAU,CAAE,QAAS,CAAE,gBAAgB;AAE9D,aAAS,GAAG,gBAAgB;AAAA,KAE9B,CAAC,UAAU;AAAA;;ACTf,MAAM,YAAY,WAAW;AAAA,EAC3B,WAAW;AAAA,IACT,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,UAAU;AAAA;AAAA;MAQD,oBAAoB,CAAC,CAAE,iBAAyB;AAC3D,QAAM,CAAC,OAAO,YAAYA,eAAM,SAAS;AACzC,QAAM,eAAe;AACrB,QAAM,UAAU;AAEhB,QAAM,eAAe,MAAM;AACzB,iBAAa,CAAE;AAAA;AAGjB,QAAM,eAAeA,eAAM,YACzB,WAAS;AACP,aAAS;AAAA,KAEX,CAAC;AAGH,sDACG,eAAD;AAAA,IACE,UAAU;AAAA,IACV,UAAU;AAAA,IACV,OAAO;AAAA,IACP,WAAW,QAAQ;AAAA,IACnB;AAAA;AAAA;;;;"}
1
+ {"version":3,"file":"index-bc274d46.esm.js","sources":["../../src/components/util.ts","../../src/components/HomePageComponent/HomePageSearchBar.tsx"],"sourcesContent":["/*\n * Copyright 2021 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 */\nimport qs from 'qs';\nimport { useCallback } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { rootRouteRef } from '../plugin';\n\nimport { useRouteRef } from '@backstage/core-plugin-api';\n\nexport const useNavigateToQuery = () => {\n const searchRoute = useRouteRef(rootRouteRef);\n const navigate = useNavigate();\n return useCallback(\n ({ query }: { query: string }): void => {\n const queryString = qs.stringify({ query }, { addQueryPrefix: true });\n\n navigate(`${searchRoute()}${queryString}`);\n },\n [navigate, searchRoute],\n );\n};\n","/*\n * Copyright 2021 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 { makeStyles } from '@material-ui/core/styles';\n\nimport { SearchBarBase } from '../SearchBar';\nimport { useNavigateToQuery } from '../util';\n\nconst useStyles = makeStyles({\n searchBar: {\n border: '1px solid #555',\n borderRadius: '6px',\n fontSize: '1.5em',\n },\n});\n\ntype Props = {\n placeholder?: string;\n};\n\nexport const HomePageSearchBar = ({ placeholder }: Props) => {\n const [query, setQuery] = React.useState('');\n const handleSearch = useNavigateToQuery();\n const classes = useStyles();\n\n const handleSubmit = () => {\n handleSearch({ query });\n };\n\n const handleChange = React.useCallback(\n value => {\n setQuery(value);\n },\n [setQuery],\n );\n\n return (\n <SearchBarBase\n onSubmit={handleSubmit}\n onChange={handleChange}\n value={query}\n className={classes.searchBar}\n placeholder={placeholder}\n />\n );\n};\n"],"names":["React"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;MAsBa,qBAAqB,MAAM;AACtC,QAAM,cAAc,YAAY;AAChC,QAAM,WAAW;AACjB,SAAO,YACL,CAAC,EAAE,YAAqC;AACtC,UAAM,cAAc,GAAG,UAAU,EAAE,SAAS,EAAE,gBAAgB;AAE9D,aAAS,GAAG,gBAAgB;AAAA,KAE9B,CAAC,UAAU;AAAA;;ACTf,MAAM,YAAY,WAAW;AAAA,EAC3B,WAAW;AAAA,IACT,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,UAAU;AAAA;AAAA;MAQD,oBAAoB,CAAC,EAAE,kBAAyB;AAC3D,QAAM,CAAC,OAAO,YAAYA,eAAM,SAAS;AACzC,QAAM,eAAe;AACrB,QAAM,UAAU;AAEhB,QAAM,eAAe,MAAM;AACzB,iBAAa,EAAE;AAAA;AAGjB,QAAM,eAAeA,eAAM,YACzB,WAAS;AACP,aAAS;AAAA,KAEX,CAAC;AAGH,sDACG,eAAD;AAAA,IACE,UAAU;AAAA,IACV,UAAU;AAAA,IACV,OAAO;AAAA,IACP,WAAW,QAAQ;AAAA,IACnB;AAAA;AAAA;;;;"}
@@ -1,4 +1,4 @@
1
- export { a as SearchBar, b as SearchBarBase } from './index-8e7d7ce9.esm.js';
1
+ export { a as SearchBar, b as SearchBarBase } from './index-893ec2f5.esm.js';
2
2
  import '@backstage/core-plugin-api';
3
3
  import '@backstage/errors';
4
4
  import 'qs';
@@ -20,4 +20,4 @@ import '@material-ui/lab';
20
20
  import '@backstage/plugin-catalog-react';
21
21
  import '@backstage/catalog-model';
22
22
  import 'react-router-dom';
23
- //# sourceMappingURL=index-1f69649c.esm.js.map
23
+ //# sourceMappingURL=index-bfe6f2c6.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-bfe6f2c6.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;"}
@@ -1,7 +1,7 @@
1
1
  import React__default from 'react';
2
2
  import SearchIcon from '@material-ui/icons/Search';
3
3
  import { SidebarItem } from '@backstage/core-components';
4
- import { u as useSearch, d as SearchModal } from './index-8e7d7ce9.esm.js';
4
+ import { u as useSearch, d as SearchModal } from './index-893ec2f5.esm.js';
5
5
  import '@backstage/core-plugin-api';
6
6
  import '@backstage/errors';
7
7
  import 'qs';
@@ -22,7 +22,7 @@ import '@backstage/catalog-model';
22
22
  import 'react-router-dom';
23
23
 
24
24
  const SidebarSearchModal = () => {
25
- const {open, toggleModal} = useSearch();
25
+ const { open, toggleModal } = useSearch();
26
26
  return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(SidebarItem, {
27
27
  className: "search-icon",
28
28
  icon: SearchIcon,
@@ -35,4 +35,4 @@ const SidebarSearchModal = () => {
35
35
  };
36
36
 
37
37
  export { SidebarSearchModal };
38
- //# sourceMappingURL=index-859ff534.esm.js.map
38
+ //# sourceMappingURL=index-ca07a7cd.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-859ff534.esm.js","sources":["../../src/components/SidebarSearchModal/SidebarSearchModal.tsx"],"sourcesContent":["/*\n * Copyright 2021 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 */\nimport React from 'react';\nimport SearchIcon from '@material-ui/icons/Search';\nimport { SidebarItem } from '@backstage/core-components';\nimport { SearchModal } from '../SearchModal';\nimport { useSearch } from '../SearchContext';\n\nexport const SidebarSearchModal = () => {\n const { open, toggleModal } = useSearch();\n\n return (\n <>\n <SidebarItem\n className=\"search-icon\"\n icon={SearchIcon}\n text=\"Search\"\n onClick={toggleModal}\n />\n <SearchModal open={open} toggleModal={toggleModal} />\n </>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;MAqBa,qBAAqB,MAAM;AACtC,QAAM,CAAE,MAAM,eAAgB;AAE9B,kIAEK,aAAD;AAAA,IACE,WAAU;AAAA,IACV,MAAM;AAAA,IACN,MAAK;AAAA,IACL,SAAS;AAAA,mDAEV,aAAD;AAAA,IAAa;AAAA,IAAY;AAAA;AAAA;;;;"}
1
+ {"version":3,"file":"index-ca07a7cd.esm.js","sources":["../../src/components/SidebarSearchModal/SidebarSearchModal.tsx"],"sourcesContent":["/*\n * Copyright 2021 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 */\nimport React from 'react';\nimport SearchIcon from '@material-ui/icons/Search';\nimport { SidebarItem } from '@backstage/core-components';\nimport { SearchModal } from '../SearchModal';\nimport { useSearch } from '../SearchContext';\n\nexport const SidebarSearchModal = () => {\n const { open, toggleModal } = useSearch();\n\n return (\n <>\n <SidebarItem\n className=\"search-icon\"\n icon={SearchIcon}\n text=\"Search\"\n onClick={toggleModal}\n />\n <SearchModal open={open} toggleModal={toggleModal} />\n </>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;MAqBa,qBAAqB,MAAM;AACtC,QAAM,EAAE,MAAM,gBAAgB;AAE9B,kIAEK,aAAD;AAAA,IACE,WAAU;AAAA,IACV,MAAM;AAAA,IACN,MAAK;AAAA,IACL,SAAS;AAAA,mDAEV,aAAD;AAAA,IAAa;AAAA,IAAY;AAAA;AAAA;;;;"}
@@ -1,4 +1,4 @@
1
- export { D as DefaultResultListItem } from './index-8e7d7ce9.esm.js';
1
+ export { D as DefaultResultListItem } from './index-893ec2f5.esm.js';
2
2
  import '@backstage/core-plugin-api';
3
3
  import '@backstage/errors';
4
4
  import 'qs';
@@ -20,4 +20,4 @@ import '@material-ui/lab';
20
20
  import '@backstage/plugin-catalog-react';
21
21
  import '@backstage/catalog-model';
22
22
  import 'react-router-dom';
23
- //# sourceMappingURL=index-b647c19e.esm.js.map
23
+ //# sourceMappingURL=index-e9bf7392.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-e9bf7392.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;"}
package/dist/index.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- export { l as DefaultResultListItem, F as Filters, e as FiltersButton, H as HomePageSearchBar, S as Router, a as SearchBar, m as SearchBarNext, f as SearchContextProvider, g as SearchFilter, h as SearchFilterNext, d as SearchModal, n as SearchPage, o as SearchPageNext, q as SearchResult, i as SearchResultPager, j as SearchType, k as SidebarSearch, t as SidebarSearchModal, p as plugin, s as searchApiRef, p as searchPlugin, u as useSearch } from './esm/index-8e7d7ce9.esm.js';
1
+ export { l as DefaultResultListItem, F as Filters, e as FiltersButton, H as HomePageSearchBar, S as Router, a as SearchBar, m as SearchBarNext, f as SearchContextProvider, g as SearchFilter, h as SearchFilterNext, d as SearchModal, n as SearchPage, o as SearchPageNext, q as SearchResult, i as SearchResultPager, j as SearchType, k as SidebarSearch, t as SidebarSearchModal, p as plugin, s as searchApiRef, p as searchPlugin, u as useSearch } from './esm/index-893ec2f5.esm.js';
2
2
  import 'react';
3
3
  import '@material-ui/core';
4
4
  import '@backstage/core-components';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@backstage/plugin-search",
3
3
  "description": "The Backstage plugin that provides your backstage app with search",
4
- "version": "0.5.0",
4
+ "version": "0.5.1",
5
5
  "main": "dist/index.esm.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "license": "Apache-2.0",
@@ -32,29 +32,30 @@
32
32
  "dependencies": {
33
33
  "@backstage/catalog-model": "^0.9.7",
34
34
  "@backstage/config": "^0.1.11",
35
- "@backstage/core-components": "^0.7.6",
36
- "@backstage/core-plugin-api": "^0.2.2",
35
+ "@backstage/core-components": "^0.8.0",
36
+ "@backstage/core-plugin-api": "^0.3.0",
37
37
  "@backstage/errors": "^0.1.4",
38
- "@backstage/plugin-catalog-react": "^0.6.4",
38
+ "@backstage/plugin-catalog-react": "^0.6.5",
39
39
  "@backstage/search-common": "^0.2.1",
40
40
  "@backstage/theme": "^0.2.14",
41
41
  "@backstage/types": "^0.1.1",
42
42
  "@material-ui/core": "^4.12.2",
43
43
  "@material-ui/icons": "^4.9.1",
44
44
  "@material-ui/lab": "4.0.0-alpha.57",
45
- "@types/react": "*",
46
45
  "qs": "^6.9.4",
47
- "react": "^16.13.1",
48
- "react-dom": "^16.13.1",
49
46
  "react-router": "6.0.0-beta.0",
50
47
  "react-router-dom": "6.0.0-beta.0",
51
48
  "react-use": "^17.2.4"
52
49
  },
50
+ "peerDependencies": {
51
+ "@types/react": "^16.13.1 || ^17.0.0",
52
+ "react": "^16.13.1 || ^17.0.0"
53
+ },
53
54
  "devDependencies": {
54
- "@backstage/cli": "^0.10.0",
55
- "@backstage/core-app-api": "^0.1.24",
56
- "@backstage/dev-utils": "^0.2.13",
57
- "@backstage/test-utils": "^0.1.23",
55
+ "@backstage/cli": "^0.10.1",
56
+ "@backstage/core-app-api": "^0.2.0",
57
+ "@backstage/dev-utils": "^0.2.14",
58
+ "@backstage/test-utils": "^0.1.24",
58
59
  "@testing-library/jest-dom": "^5.10.1",
59
60
  "@testing-library/react": "^11.2.5",
60
61
  "@testing-library/react-hooks": "^7.0.2",
@@ -67,5 +68,5 @@
67
68
  "files": [
68
69
  "dist"
69
70
  ],
70
- "gitHead": "a05e7081b805006e3f0b2960a08a7753357f532f"
71
+ "gitHead": "562be0b43016294e27af3ad024191bb86b13b1c1"
71
72
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-09bfa46d.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-1f69649c.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-49a2f5d1.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-b647c19e.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;"}