@backstage/plugin-techdocs 0.12.1 → 0.12.5

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/dist/index.esm.js CHANGED
@@ -1,31 +1,29 @@
1
1
  import { createApiRef, createRouteRef, useRouteRef, useApi, configApiRef, createPlugin, createApiFactory, discoveryApiRef, identityApiRef, createRoutableExtension, createComponentExtension } from '@backstage/core-plugin-api';
2
2
  import { ResponseError, NotFoundError } from '@backstage/errors';
3
3
  import { EventSourcePolyfill } from 'event-source-polyfill';
4
- import * as React from 'react';
5
- import React__default, { useEffect, useState, useReducer, useRef, useMemo, useCallback } from 'react';
4
+ import React, { useEffect, useState, Suspense, useReducer, useRef, useMemo, useContext, createContext, useCallback } from 'react';
5
+ import { makeStyles, ListItemText, ListItem, Divider, Card, CardMedia, CardContent, CardActions, Grid, TextField, InputAdornment, IconButton, CircularProgress, createStyles, Button as Button$1, Drawer, Typography, useTheme } from '@material-ui/core';
6
+ import { Link, SubvalueCell, Table, EmptyState, Button, WarningPanel, CodeSnippet, PageWithHeader, Content, ContentHeader, SupportButton, ItemCardGrid, ItemCardHeader, Progress, ErrorPage, HeaderLabel, Header, Page, HeaderTabs, MissingAnnotationEmptyState } from '@backstage/core-components';
7
+ import TextTruncate from 'react-text-truncate';
8
+ import { FilteredEntityLayout, FilterContainer, EntityListContainer } from '@backstage/plugin-catalog';
9
+ import { favoriteEntityIcon, favoriteEntityTooltip, EntityRefLinks, getEntityRelations, formatEntityRefTitle, useEntityListProvider, useStarredEntities, CATALOG_FILTER_EXISTS, EntityListProvider, UserListPicker, EntityOwnerPicker, EntityTagPicker, EntityRefLink, catalogApiRef, useOwnUser, isOwnerOf, useEntity } from '@backstage/plugin-catalog-react';
6
10
  import { useCopyToClipboard, useDebounce, useAsyncRetry, useAsync } from 'react-use';
7
11
  import { capitalize } from 'lodash';
8
- import { SubvalueCell, Link, Table, EmptyState, Button, WarningPanel, CodeSnippet, PageWithHeader, Content, ContentHeader, SupportButton, ErrorPage, Progress, HeaderLabel, Header, Page, ItemCardGrid, ItemCardHeader, HeaderTabs, MissingAnnotationEmptyState } from '@backstage/core-components';
9
- import { favoriteEntityIcon, favoriteEntityTooltip, EntityRefLinks, getEntityRelations, formatEntityRefTitle, useEntityListProvider, useStarredEntities, CATALOG_FILTER_EXISTS, EntityListProvider, UserListPicker, EntityOwnerPicker, EntityTagPicker, EntityRefLink, catalogApiRef, useOwnUser, isOwnerOf, useEntity } from '@backstage/plugin-catalog-react';
10
12
  import { RELATION_OWNED_BY } from '@backstage/catalog-model';
11
13
  import ShareIcon from '@material-ui/icons/Share';
12
- import { FilteredEntityLayout, FilterContainer, EntityListContainer } from '@backstage/plugin-catalog';
13
- import { makeStyles, ListItemText, ListItem, Divider, createStyles, Button as Button$1, Drawer, Grid, Typography, IconButton, TextField, InputAdornment, CircularProgress, useTheme, Card, CardMedia, CardContent, CardActions } from '@material-ui/core';
14
- import TextTruncate from 'react-text-truncate';
14
+ import { useNavigate as useNavigate$1, useParams, Routes, Route } from 'react-router-dom';
15
15
  import { scmIntegrationsApiRef } from '@backstage/integration-react';
16
- import { Alert } from '@material-ui/lab';
17
- import { useParams, useNavigate as useNavigate$1, Routes, Route } from 'react-router-dom';
18
16
  import { replaceGitHubUrlType } from '@backstage/integration';
19
17
  import FeedbackOutlinedIcon from '@material-ui/icons/FeedbackOutlined';
20
18
  import ReactDOM from 'react-dom';
21
19
  import parseGitUrl from 'git-url-parse';
22
20
  import DOMPurify from 'dompurify';
23
- import Close from '@material-ui/icons/Close';
24
- import { LazyLog } from 'react-lazylog';
25
- import Autocomplete from '@material-ui/lab/Autocomplete';
26
21
  import { SearchContextProvider, useSearch } from '@backstage/plugin-search';
27
22
  import SearchIcon from '@material-ui/icons/Search';
23
+ import Autocomplete from '@material-ui/lab/Autocomplete';
28
24
  import { useNavigate, useOutlet } from 'react-router';
25
+ import { Alert } from '@material-ui/lab';
26
+ import Close from '@material-ui/icons/Close';
29
27
  import CodeIcon from '@material-ui/icons/Code';
30
28
 
31
29
  const techdocsStorageApiRef = createApiRef({
@@ -164,6 +162,49 @@ class TechDocsStorageClient {
164
162
  }
165
163
  }
166
164
 
165
+ const useStyles$2 = makeStyles({
166
+ flexContainer: {
167
+ flexWrap: "wrap"
168
+ },
169
+ itemText: {
170
+ width: "100%",
171
+ marginBottom: "1rem"
172
+ }
173
+ });
174
+ const DocsResultListItem = ({
175
+ result,
176
+ lineClamp = 5,
177
+ asListItem = true,
178
+ asLink = true,
179
+ title
180
+ }) => {
181
+ const classes = useStyles$2();
182
+ const TextItem = () => {
183
+ var _a;
184
+ return /* @__PURE__ */ React.createElement(ListItemText, {
185
+ className: classes.itemText,
186
+ primaryTypographyProps: {variant: "h6"},
187
+ primary: title ? title : `${result.title} | ${(_a = result.entityTitle) != null ? _a : result.name} docs`,
188
+ secondary: /* @__PURE__ */ React.createElement(TextTruncate, {
189
+ line: lineClamp,
190
+ truncateText: "\u2026",
191
+ text: result.text,
192
+ element: "span"
193
+ })
194
+ });
195
+ };
196
+ const LinkWrapper = ({children}) => asLink ? /* @__PURE__ */ React.createElement(Link, {
197
+ to: result.location
198
+ }, children) : /* @__PURE__ */ React.createElement(React.Fragment, null, children);
199
+ const ListItemWrapper = ({children}) => asListItem ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ListItem, {
200
+ alignItems: "flex-start",
201
+ className: classes.flexContainer
202
+ }, children), /* @__PURE__ */ React.createElement(Divider, {
203
+ component: "li"
204
+ })) : /* @__PURE__ */ React.createElement(React.Fragment, null, children);
205
+ return /* @__PURE__ */ React.createElement(LinkWrapper, null, /* @__PURE__ */ React.createElement(ListItemWrapper, null, /* @__PURE__ */ React.createElement(TextItem, null)));
206
+ };
207
+
167
208
  const rootRouteRef = createRouteRef({
168
209
  id: "techdocs-index-page",
169
210
  title: "TechDocs Landing Page"
@@ -181,7 +222,7 @@ const rootCatalogDocsRouteRef = createRouteRef({
181
222
  function createCopyDocsUrlAction(copyToClipboard) {
182
223
  return (row) => {
183
224
  return {
184
- icon: () => /* @__PURE__ */ React__default.createElement(ShareIcon, {
225
+ icon: () => /* @__PURE__ */ React.createElement(ShareIcon, {
185
226
  fontSize: "small"
186
227
  }),
187
228
  tooltip: "Click to copy documentation link to clipboard",
@@ -215,8 +256,8 @@ function createNameColumn() {
215
256
  title: "Document",
216
257
  field: "entity.metadata.name",
217
258
  highlight: true,
218
- render: (row) => /* @__PURE__ */ React__default.createElement(SubvalueCell, {
219
- value: /* @__PURE__ */ React__default.createElement(Link, {
259
+ render: (row) => /* @__PURE__ */ React.createElement(SubvalueCell, {
260
+ value: /* @__PURE__ */ React.createElement(Link, {
220
261
  to: row.resolved.docsUrl
221
262
  }, customTitle(row.entity)),
222
263
  subvalue: row.entity.metadata.description
@@ -227,7 +268,7 @@ function createOwnerColumn() {
227
268
  return {
228
269
  title: "Owner",
229
270
  field: "resolved.ownedByRelationsTitle",
230
- render: ({resolved}) => /* @__PURE__ */ React__default.createElement(EntityRefLinks, {
271
+ render: ({resolved}) => /* @__PURE__ */ React.createElement(EntityRefLinks, {
231
272
  entityRefs: resolved.ownedByRelations,
232
273
  defaultKind: "group"
233
274
  })
@@ -283,7 +324,7 @@ const DocsTable$1 = ({
283
324
  const defaultActions = [
284
325
  createCopyDocsUrlAction(copyToClipboard)
285
326
  ];
286
- return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, loading || documents && documents.length > 0 ? /* @__PURE__ */ React__default.createElement(Table, {
327
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, loading || documents && documents.length > 0 ? /* @__PURE__ */ React.createElement(Table, {
287
328
  isLoading: loading,
288
329
  options: {
289
330
  paging: true,
@@ -295,11 +336,11 @@ const DocsTable$1 = ({
295
336
  columns: columns || defaultColumns,
296
337
  actions: actions || defaultActions,
297
338
  title: title ? `${title} (${documents.length})` : `All (${documents.length})`
298
- }) : /* @__PURE__ */ React__default.createElement(EmptyState, {
339
+ }) : /* @__PURE__ */ React.createElement(EmptyState, {
299
340
  missing: "data",
300
341
  title: "No documents to show",
301
342
  description: "Create your own document. Check out our Getting Started Information",
302
- action: /* @__PURE__ */ React__default.createElement(Button, {
343
+ action: /* @__PURE__ */ React.createElement(Button, {
303
344
  color: "primary",
304
345
  to: "https://backstage.io/docs/features/techdocs/getting-started",
305
346
  variant: "contained"
@@ -326,15 +367,15 @@ const EntityListDocsTable = ({
326
367
  createStarEntityAction(isStarredEntity, toggleStarredEntity)
327
368
  ];
328
369
  if (error) {
329
- return /* @__PURE__ */ React__default.createElement(WarningPanel, {
370
+ return /* @__PURE__ */ React.createElement(WarningPanel, {
330
371
  severity: "error",
331
372
  title: "Could not load available documentation."
332
- }, /* @__PURE__ */ React__default.createElement(CodeSnippet, {
373
+ }, /* @__PURE__ */ React.createElement(CodeSnippet, {
333
374
  language: "text",
334
375
  text: error.toString()
335
376
  }));
336
377
  }
337
- return /* @__PURE__ */ React__default.createElement(DocsTable$1, {
378
+ return /* @__PURE__ */ React.createElement(DocsTable$1, {
338
379
  title,
339
380
  entities,
340
381
  loading,
@@ -349,7 +390,7 @@ const TechDocsPageWrapper = ({children}) => {
349
390
  var _a;
350
391
  const configApi = useApi(configApiRef);
351
392
  const generatedSubtitle = `Documentation available in ${(_a = configApi.getOptionalString("organization.name")) != null ? _a : "Backstage"}`;
352
- return /* @__PURE__ */ React__default.createElement(PageWithHeader, {
393
+ return /* @__PURE__ */ React.createElement(PageWithHeader, {
353
394
  title: "Documentation",
354
395
  subtitle: generatedSubtitle,
355
396
  themeId: "documentation"
@@ -378,54 +419,69 @@ const DefaultTechDocsHome = ({
378
419
  columns,
379
420
  actions
380
421
  }) => {
381
- return /* @__PURE__ */ React__default.createElement(TechDocsPageWrapper, null, /* @__PURE__ */ React__default.createElement(Content, null, /* @__PURE__ */ React__default.createElement(ContentHeader, {
422
+ return /* @__PURE__ */ React.createElement(TechDocsPageWrapper, null, /* @__PURE__ */ React.createElement(Content, null, /* @__PURE__ */ React.createElement(ContentHeader, {
382
423
  title: ""
383
- }, /* @__PURE__ */ React__default.createElement(SupportButton, null, "Discover documentation in your ecosystem.")), /* @__PURE__ */ React__default.createElement(EntityListProvider, null, /* @__PURE__ */ React__default.createElement(FilteredEntityLayout, null, /* @__PURE__ */ React__default.createElement(FilterContainer, null, /* @__PURE__ */ React__default.createElement(TechDocsPicker, null), /* @__PURE__ */ React__default.createElement(UserListPicker, {
424
+ }, /* @__PURE__ */ React.createElement(SupportButton, null, "Discover documentation in your ecosystem.")), /* @__PURE__ */ React.createElement(EntityListProvider, null, /* @__PURE__ */ React.createElement(FilteredEntityLayout, null, /* @__PURE__ */ React.createElement(FilterContainer, null, /* @__PURE__ */ React.createElement(TechDocsPicker, null), /* @__PURE__ */ React.createElement(UserListPicker, {
384
425
  initialFilter
385
- }), /* @__PURE__ */ React__default.createElement(EntityOwnerPicker, null), /* @__PURE__ */ React__default.createElement(EntityTagPicker, null)), /* @__PURE__ */ React__default.createElement(EntityListContainer, null, /* @__PURE__ */ React__default.createElement(EntityListDocsTable, {
426
+ }), /* @__PURE__ */ React.createElement(EntityOwnerPicker, null), /* @__PURE__ */ React.createElement(EntityTagPicker, null)), /* @__PURE__ */ React.createElement(EntityListContainer, null, /* @__PURE__ */ React.createElement(EntityListDocsTable, {
386
427
  actions,
387
428
  columns
388
429
  }))))));
389
430
  };
390
431
 
391
- const useStyles$1 = makeStyles({
392
- flexContainer: {
393
- flexWrap: "wrap"
394
- },
395
- itemText: {
396
- width: "100%",
397
- marginBottom: "1rem"
398
- }
399
- });
400
- const DocsResultListItem = ({
401
- result,
402
- lineClamp = 5,
403
- asListItem = true,
404
- asLink = true,
405
- title
432
+ const DocsCardGrid$1 = ({
433
+ entities
406
434
  }) => {
407
- const classes = useStyles$1();
408
- const TextItem = () => /* @__PURE__ */ React__default.createElement(ListItemText, {
409
- className: classes.itemText,
410
- primaryTypographyProps: {variant: "h6"},
411
- primary: title ? title : `${result.title} | ${result.name} docs`,
412
- secondary: /* @__PURE__ */ React__default.createElement(TextTruncate, {
413
- line: lineClamp,
414
- truncateText: "\u2026",
415
- text: result.text,
416
- element: "span"
417
- })
435
+ const getRouteToReaderPageFor = useRouteRef(rootDocsRouteRef);
436
+ const toLowerMaybe = useApi(configApiRef).getOptionalBoolean("techdocs.legacyUseCaseSensitiveTripletPaths") ? (str) => str : (str) => str.toLocaleLowerCase();
437
+ if (!entities)
438
+ return null;
439
+ return /* @__PURE__ */ React.createElement(ItemCardGrid, {
440
+ "data-testid": "docs-explore"
441
+ }, !(entities == null ? void 0 : entities.length) ? null : entities.map((entity, index) => {
442
+ var _a, _b;
443
+ return /* @__PURE__ */ React.createElement(Card, {
444
+ key: index
445
+ }, /* @__PURE__ */ React.createElement(CardMedia, null, /* @__PURE__ */ React.createElement(ItemCardHeader, {
446
+ title: (_a = entity.metadata.title) != null ? _a : entity.metadata.name
447
+ })), /* @__PURE__ */ React.createElement(CardContent, null, entity.metadata.description), /* @__PURE__ */ React.createElement(CardActions, null, /* @__PURE__ */ React.createElement(Button, {
448
+ to: getRouteToReaderPageFor({
449
+ namespace: toLowerMaybe((_b = entity.metadata.namespace) != null ? _b : "default"),
450
+ kind: toLowerMaybe(entity.kind),
451
+ name: toLowerMaybe(entity.metadata.name)
452
+ }),
453
+ color: "primary",
454
+ "data-testid": "read_docs"
455
+ }, "Read Docs")));
456
+ }));
457
+ };
458
+
459
+ var DocsCardGrid$2 = /*#__PURE__*/Object.freeze({
460
+ __proto__: null,
461
+ DocsCardGrid: DocsCardGrid$1
462
+ });
463
+
464
+ const EntityListDocsGrid = () => {
465
+ const {loading, error, entities} = useEntityListProvider();
466
+ if (error) {
467
+ return /* @__PURE__ */ React.createElement(WarningPanel, {
468
+ severity: "error",
469
+ title: "Could not load available documentation."
470
+ }, /* @__PURE__ */ React.createElement(CodeSnippet, {
471
+ language: "text",
472
+ text: error.toString()
473
+ }));
474
+ }
475
+ if (loading || !entities) {
476
+ return /* @__PURE__ */ React.createElement(Progress, null);
477
+ }
478
+ entities.sort((a, b) => {
479
+ var _a, _b;
480
+ return ((_a = a.metadata.title) != null ? _a : a.metadata.name).localeCompare((_b = b.metadata.title) != null ? _b : b.metadata.name);
481
+ });
482
+ return /* @__PURE__ */ React.createElement(DocsCardGrid$1, {
483
+ entities
418
484
  });
419
- const LinkWrapper = ({children}) => asLink ? /* @__PURE__ */ React__default.createElement(Link, {
420
- to: result.location
421
- }, children) : /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, children);
422
- const ListItemWrapper = ({children}) => asListItem ? /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(ListItem, {
423
- alignItems: "flex-start",
424
- className: classes.flexContainer
425
- }, children), /* @__PURE__ */ React__default.createElement(Divider, {
426
- component: "li"
427
- })) : /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, children);
428
- return /* @__PURE__ */ React__default.createElement(LinkWrapper, null, /* @__PURE__ */ React__default.createElement(ListItemWrapper, null, /* @__PURE__ */ React__default.createElement(TextItem, null)));
429
485
  };
430
486
 
431
487
  const techdocsPlugin = createPlugin({
@@ -474,10 +530,10 @@ const EntityTechdocsContent = techdocsPlugin.provide(createRoutableExtension({
474
530
  component: () => Promise.resolve().then(function () { return Router$1; }).then((m) => m.EmbeddedDocsRouter),
475
531
  mountPoint: rootCatalogDocsRouteRef
476
532
  }));
477
- const DocsCardGrid$2 = techdocsPlugin.provide(createComponentExtension({
533
+ const DocsCardGrid = techdocsPlugin.provide(createComponentExtension({
478
534
  name: "DocsCardGrid",
479
535
  component: {
480
- lazy: () => Promise.resolve().then(function () { return DocsCardGrid$1; }).then((m) => m.DocsCardGrid)
536
+ lazy: () => Promise.resolve().then(function () { return DocsCardGrid$2; }).then((m) => m.DocsCardGrid)
481
537
  }
482
538
  }));
483
539
  const DocsTable = techdocsPlugin.provide(createComponentExtension({
@@ -577,7 +633,7 @@ Feedback:`);
577
633
  default:
578
634
  return dom;
579
635
  }
580
- ReactDOM.render(React__default.createElement(FeedbackOutlinedIcon), feedbackLink);
636
+ ReactDOM.render(React.createElement(FeedbackOutlinedIcon), feedbackLink);
581
637
  feedbackLink.style.paddingLeft = "5px";
582
638
  feedbackLink.title = "Leave feedback for this page";
583
639
  feedbackLink.id = "git-feedback-link";
@@ -714,6 +770,19 @@ const injectCss = ({css}) => {
714
770
  };
715
771
  };
716
772
 
773
+ const scrollIntoAnchor = () => {
774
+ return (dom) => {
775
+ setTimeout(() => {
776
+ var _a;
777
+ if (window.location.hash) {
778
+ const hash = window.location.hash.slice(1);
779
+ (_a = dom == null ? void 0 : dom.querySelector(`#${hash}`)) == null ? void 0 : _a.scrollIntoView();
780
+ }
781
+ }, 200);
782
+ return dom;
783
+ };
784
+ };
785
+
717
786
  const transform = async (html, transformers) => {
718
787
  let dom;
719
788
  if (typeof html === "string") {
@@ -729,90 +798,6 @@ const transform = async (html, transformers) => {
729
798
  return dom;
730
799
  };
731
800
 
732
- const useDrawerStyles = makeStyles((theme) => createStyles({
733
- paper: {
734
- width: "100%",
735
- [theme.breakpoints.up("sm")]: {
736
- width: "75%"
737
- },
738
- [theme.breakpoints.up("md")]: {
739
- width: "50%"
740
- },
741
- padding: theme.spacing(2.5)
742
- },
743
- root: {
744
- height: "100%",
745
- overflow: "hidden"
746
- }
747
- }));
748
- const TechDocsBuildLogsDrawerContent = ({
749
- buildLog,
750
- onClose
751
- }) => {
752
- const classes = useDrawerStyles();
753
- return /* @__PURE__ */ React.createElement(Grid, {
754
- container: true,
755
- direction: "column",
756
- className: classes.root,
757
- spacing: 0,
758
- wrap: "nowrap"
759
- }, /* @__PURE__ */ React.createElement(Grid, {
760
- item: true,
761
- container: true,
762
- justifyContent: "space-between",
763
- alignItems: "center",
764
- spacing: 0,
765
- wrap: "nowrap"
766
- }, /* @__PURE__ */ React.createElement(Typography, {
767
- variant: "h5"
768
- }, "Build Details"), /* @__PURE__ */ React.createElement(IconButton, {
769
- key: "dismiss",
770
- title: "Close the drawer",
771
- onClick: onClose,
772
- color: "inherit"
773
- }, /* @__PURE__ */ React.createElement(Close, null))), /* @__PURE__ */ React.createElement(LazyLog, {
774
- text: buildLog.length === 0 ? "Waiting for logs..." : buildLog.join("\n"),
775
- extraLines: 1,
776
- follow: true,
777
- selectableLines: true,
778
- enableSearch: true
779
- }));
780
- };
781
- const TechDocsBuildLogs = ({buildLog}) => {
782
- const classes = useDrawerStyles();
783
- const [open, setOpen] = useState(false);
784
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Button$1, {
785
- color: "inherit",
786
- onClick: () => setOpen(true)
787
- }, "Show Build Logs"), /* @__PURE__ */ React.createElement(Drawer, {
788
- classes: {paper: classes.paper},
789
- anchor: "right",
790
- open,
791
- onClose: () => setOpen(false)
792
- }, /* @__PURE__ */ React.createElement(TechDocsBuildLogsDrawerContent, {
793
- buildLog,
794
- onClose: () => setOpen(false)
795
- })));
796
- };
797
-
798
- const TechDocsNotFound = ({errorMessage}) => {
799
- const techdocsBuilder = useApi(configApiRef).getOptionalString("techdocs.builder");
800
- let additionalInfo = "";
801
- if (techdocsBuilder !== "local") {
802
- additionalInfo = "Note that techdocs.builder is not set to 'local' in your config, which means this Backstage app will not generate docs if they are not found. Make sure the project's docs are generated and published by some external process (e.g. CI/CD pipeline). Or change techdocs.builder to 'local' to generate docs from this Backstage instance.";
803
- }
804
- return /* @__PURE__ */ React__default.createElement(ErrorPage, {
805
- status: "404",
806
- statusMessage: errorMessage || "Documentation not found",
807
- additionalInfo
808
- });
809
- };
810
-
811
- const buildInitialFilters = (legacyPaths, entityId) => {
812
- return legacyPaths ? entityId : Object.entries(entityId).reduce((acc, [key, value]) => {
813
- return {...acc, [key]: value.toLocaleLowerCase("en-US")};
814
- }, {});
815
- };
816
801
  const TechDocsSearchBar = ({
817
802
  entityId,
818
803
  debounceTime = 150
@@ -849,10 +834,10 @@ const TechDocsSearchBar = ({
849
834
  navigate(location);
850
835
  }
851
836
  };
852
- return /* @__PURE__ */ React__default.createElement(Grid, {
837
+ return /* @__PURE__ */ React.createElement(Grid, {
853
838
  item: true,
854
839
  xs: 12
855
- }, /* @__PURE__ */ React__default.createElement(Autocomplete, {
840
+ }, /* @__PURE__ */ React.createElement(Autocomplete, {
856
841
  "data-testid": "techdocs-search-bar",
857
842
  size: "small",
858
843
  open,
@@ -871,7 +856,7 @@ const TechDocsSearchBar = ({
871
856
  noOptionsText: "No results found",
872
857
  value: null,
873
858
  options,
874
- renderOption: ({document}) => /* @__PURE__ */ React__default.createElement(DocsResultListItem, {
859
+ renderOption: ({document}) => /* @__PURE__ */ React.createElement(DocsResultListItem, {
875
860
  result: document,
876
861
  lineClamp: 3,
877
862
  asListItem: false,
@@ -879,7 +864,7 @@ const TechDocsSearchBar = ({
879
864
  title: document.title
880
865
  }),
881
866
  loading,
882
- renderInput: (params) => /* @__PURE__ */ React__default.createElement(TextField, {
867
+ renderInput: (params) => /* @__PURE__ */ React.createElement(TextField, {
883
868
  ...params,
884
869
  "data-testid": "techdocs-search-bar-input",
885
870
  variant: "outlined",
@@ -889,13 +874,13 @@ const TechDocsSearchBar = ({
889
874
  onChange: handleQuery,
890
875
  InputProps: {
891
876
  ...params.InputProps,
892
- startAdornment: /* @__PURE__ */ React__default.createElement(InputAdornment, {
877
+ startAdornment: /* @__PURE__ */ React.createElement(InputAdornment, {
893
878
  position: "start"
894
- }, /* @__PURE__ */ React__default.createElement(IconButton, {
879
+ }, /* @__PURE__ */ React.createElement(IconButton, {
895
880
  "aria-label": "Query",
896
881
  disabled: true
897
- }, /* @__PURE__ */ React__default.createElement(SearchIcon, null))),
898
- endAdornment: /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, loading ? /* @__PURE__ */ React__default.createElement(CircularProgress, {
882
+ }, /* @__PURE__ */ React.createElement(SearchIcon, null))),
883
+ endAdornment: /* @__PURE__ */ React.createElement(React.Fragment, null, loading ? /* @__PURE__ */ React.createElement(CircularProgress, {
899
884
  color: "inherit",
900
885
  size: 20
901
886
  }) : null, params.InputProps.endAdornment)
@@ -904,21 +889,177 @@ const TechDocsSearchBar = ({
904
889
  }));
905
890
  };
906
891
  const TechDocsSearch = (props) => {
907
- const configApi = useApi(configApiRef);
908
- const legacyPaths = configApi.getOptionalBoolean("techdocs.legacyUseCaseSensitiveTripletPaths");
909
892
  const initialState = {
910
893
  term: "",
911
894
  types: ["techdocs"],
912
895
  pageCursor: "",
913
- filters: buildInitialFilters(legacyPaths || false, props.entityId)
896
+ filters: props.entityId
914
897
  };
915
- return /* @__PURE__ */ React__default.createElement(SearchContextProvider, {
898
+ return /* @__PURE__ */ React.createElement(SearchContextProvider, {
916
899
  initialState
917
- }, /* @__PURE__ */ React__default.createElement(TechDocsSearchBar, {
900
+ }, /* @__PURE__ */ React.createElement(TechDocsSearchBar, {
918
901
  ...props
919
902
  }));
920
903
  };
921
904
 
905
+ const LazyLog = React.lazy(() => import('react-lazylog/build/LazyLog'));
906
+ const useDrawerStyles = makeStyles((theme) => createStyles({
907
+ paper: {
908
+ width: "100%",
909
+ [theme.breakpoints.up("sm")]: {
910
+ width: "75%"
911
+ },
912
+ [theme.breakpoints.up("md")]: {
913
+ width: "50%"
914
+ },
915
+ padding: theme.spacing(2.5)
916
+ },
917
+ root: {
918
+ height: "100%",
919
+ overflow: "hidden"
920
+ }
921
+ }));
922
+ const TechDocsBuildLogsDrawerContent = ({
923
+ buildLog,
924
+ onClose
925
+ }) => {
926
+ const classes = useDrawerStyles();
927
+ return /* @__PURE__ */ React.createElement(Grid, {
928
+ container: true,
929
+ direction: "column",
930
+ className: classes.root,
931
+ spacing: 0,
932
+ wrap: "nowrap"
933
+ }, /* @__PURE__ */ React.createElement(Grid, {
934
+ item: true,
935
+ container: true,
936
+ justifyContent: "space-between",
937
+ alignItems: "center",
938
+ spacing: 0,
939
+ wrap: "nowrap"
940
+ }, /* @__PURE__ */ React.createElement(Typography, {
941
+ variant: "h5"
942
+ }, "Build Details"), /* @__PURE__ */ React.createElement(IconButton, {
943
+ key: "dismiss",
944
+ title: "Close the drawer",
945
+ onClick: onClose,
946
+ color: "inherit"
947
+ }, /* @__PURE__ */ React.createElement(Close, null))), /* @__PURE__ */ React.createElement(Suspense, {
948
+ fallback: /* @__PURE__ */ React.createElement(Progress, null)
949
+ }, /* @__PURE__ */ React.createElement(LazyLog, {
950
+ text: buildLog.length === 0 ? "Waiting for logs..." : buildLog.join("\n"),
951
+ extraLines: 1,
952
+ follow: true,
953
+ selectableLines: true,
954
+ enableSearch: true
955
+ })));
956
+ };
957
+ const TechDocsBuildLogs = ({buildLog}) => {
958
+ const classes = useDrawerStyles();
959
+ const [open, setOpen] = useState(false);
960
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Button$1, {
961
+ color: "inherit",
962
+ onClick: () => setOpen(true)
963
+ }, "Show Build Logs"), /* @__PURE__ */ React.createElement(Drawer, {
964
+ classes: {paper: classes.paper},
965
+ anchor: "right",
966
+ open,
967
+ onClose: () => setOpen(false)
968
+ }, /* @__PURE__ */ React.createElement(TechDocsBuildLogsDrawerContent, {
969
+ buildLog,
970
+ onClose: () => setOpen(false)
971
+ })));
972
+ };
973
+
974
+ const TechDocsNotFound = ({errorMessage}) => {
975
+ const techdocsBuilder = useApi(configApiRef).getOptionalString("techdocs.builder");
976
+ let additionalInfo = "";
977
+ if (techdocsBuilder !== "local") {
978
+ additionalInfo = "Note that techdocs.builder is not set to 'local' in your config, which means this Backstage app will not generate docs if they are not found. Make sure the project's docs are generated and published by some external process (e.g. CI/CD pipeline). Or change techdocs.builder to 'local' to generate docs from this Backstage instance.";
979
+ }
980
+ return /* @__PURE__ */ React.createElement(ErrorPage, {
981
+ status: "404",
982
+ statusMessage: errorMessage || "Documentation not found",
983
+ additionalInfo
984
+ });
985
+ };
986
+
987
+ const useStyles$1 = makeStyles(() => ({
988
+ message: {
989
+ wordBreak: "break-word",
990
+ overflowWrap: "anywhere"
991
+ }
992
+ }));
993
+ const TechDocsStateIndicator = () => {
994
+ let StateAlert = null;
995
+ const classes = useStyles$1();
996
+ const {
997
+ state,
998
+ contentReload,
999
+ contentErrorMessage,
1000
+ syncErrorMessage,
1001
+ buildLog
1002
+ } = useTechDocsReader();
1003
+ const ReaderProgress = state === "CHECKING" ? /* @__PURE__ */ React.createElement(Progress, null) : null;
1004
+ if (state === "INITIAL_BUILD") {
1005
+ StateAlert = /* @__PURE__ */ React.createElement(Alert, {
1006
+ variant: "outlined",
1007
+ severity: "info",
1008
+ icon: /* @__PURE__ */ React.createElement(CircularProgress, {
1009
+ size: "24px"
1010
+ }),
1011
+ action: /* @__PURE__ */ React.createElement(TechDocsBuildLogs, {
1012
+ buildLog
1013
+ })
1014
+ }, "Documentation is accessed for the first time and is being prepared. The subsequent loads are much faster.");
1015
+ }
1016
+ if (state === "CONTENT_STALE_REFRESHING") {
1017
+ StateAlert = /* @__PURE__ */ React.createElement(Alert, {
1018
+ variant: "outlined",
1019
+ severity: "info",
1020
+ icon: /* @__PURE__ */ React.createElement(CircularProgress, {
1021
+ size: "24px"
1022
+ }),
1023
+ action: /* @__PURE__ */ React.createElement(TechDocsBuildLogs, {
1024
+ buildLog
1025
+ })
1026
+ }, "A newer version of this documentation is being prepared and will be available shortly.");
1027
+ }
1028
+ if (state === "CONTENT_STALE_READY") {
1029
+ StateAlert = /* @__PURE__ */ React.createElement(Alert, {
1030
+ variant: "outlined",
1031
+ severity: "success",
1032
+ action: /* @__PURE__ */ React.createElement(Button$1, {
1033
+ color: "inherit",
1034
+ onClick: () => contentReload()
1035
+ }, "Refresh")
1036
+ }, "A newer version of this documentation is now available, please refresh to view.");
1037
+ }
1038
+ if (state === "CONTENT_STALE_ERROR") {
1039
+ StateAlert = /* @__PURE__ */ React.createElement(Alert, {
1040
+ variant: "outlined",
1041
+ severity: "error",
1042
+ action: /* @__PURE__ */ React.createElement(TechDocsBuildLogs, {
1043
+ buildLog
1044
+ }),
1045
+ classes: {message: classes.message}
1046
+ }, "Building a newer version of this documentation failed.", " ", syncErrorMessage);
1047
+ }
1048
+ if (state === "CONTENT_NOT_FOUND") {
1049
+ StateAlert = /* @__PURE__ */ React.createElement(React.Fragment, null, syncErrorMessage && /* @__PURE__ */ React.createElement(Alert, {
1050
+ variant: "outlined",
1051
+ severity: "error",
1052
+ action: /* @__PURE__ */ React.createElement(TechDocsBuildLogs, {
1053
+ buildLog
1054
+ }),
1055
+ classes: {message: classes.message}
1056
+ }, "Building a newer version of this documentation failed.", " ", syncErrorMessage), /* @__PURE__ */ React.createElement(TechDocsNotFound, {
1057
+ errorMessage: contentErrorMessage
1058
+ }));
1059
+ }
1060
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, ReaderProgress, StateAlert);
1061
+ };
1062
+
922
1063
  function calculateDisplayState({
923
1064
  contentLoading,
924
1065
  content,
@@ -1066,10 +1207,6 @@ function useReaderState(kind, namespace, name, path) {
1066
1207
  }
1067
1208
 
1068
1209
  const useStyles = makeStyles((theme) => ({
1069
- message: {
1070
- wordBreak: "break-word",
1071
- overflowWrap: "anywhere"
1072
- },
1073
1210
  searchBar: {
1074
1211
  marginLeft: "20rem",
1075
1212
  maxWidth: "calc(100% - 20rem * 2 - 3rem)",
@@ -1080,36 +1217,36 @@ const useStyles = makeStyles((theme) => ({
1080
1217
  }
1081
1218
  }
1082
1219
  }));
1083
- const Reader = ({entityRef, onReady, withSearch = true}) => {
1084
- var _a, _b;
1085
- const {kind, namespace, name} = entityRef;
1220
+ const TechDocsReaderContext = createContext({});
1221
+ const TechDocsReaderProvider = ({children}) => {
1222
+ const {namespace = "", kind = "", name = "", "*": path} = useParams();
1223
+ const value = useReaderState(kind, namespace, name, path);
1224
+ return /* @__PURE__ */ React.createElement(TechDocsReaderContext.Provider, {
1225
+ value
1226
+ }, children);
1227
+ };
1228
+ const withTechDocsReaderProvider = (Component) => (props) => /* @__PURE__ */ React.createElement(TechDocsReaderProvider, null, /* @__PURE__ */ React.createElement(Component, {
1229
+ ...props
1230
+ }));
1231
+ const useTechDocsReader = () => useContext(TechDocsReaderContext);
1232
+ const useTechDocsReaderDom = () => {
1233
+ const navigate = useNavigate$1();
1086
1234
  const theme = useTheme();
1087
- const classes = useStyles();
1088
- const {
1089
- state,
1090
- path,
1091
- contentReload,
1092
- content: rawPage,
1093
- contentErrorMessage,
1094
- syncErrorMessage,
1095
- buildLog
1096
- } = useReaderState(kind, namespace, name, useParams()["*"]);
1097
1235
  const techdocsStorageApi = useApi(techdocsStorageApiRef);
1098
- const [sidebars, setSidebars] = useState();
1099
- const navigate = useNavigate$1();
1100
- const shadowDomRef = useRef(null);
1101
1236
  const scmIntegrationsApi = useApi(scmIntegrationsApiRef);
1237
+ const {namespace = "", kind = "", name = ""} = useParams();
1238
+ const {state, path, content: rawPage} = useTechDocsReader();
1239
+ const [sidebars, setSidebars] = useState();
1240
+ const [dom, setDom] = useState(null);
1102
1241
  const updateSidebarPosition = useCallback(() => {
1103
- if (!!shadowDomRef.current && !!sidebars) {
1104
- const shadowDiv = shadowDomRef.current;
1105
- const shadowRoot = shadowDiv.shadowRoot || shadowDiv.attachShadow({mode: "open"});
1106
- const mdTabs = shadowRoot.querySelector(".md-container > .md-tabs");
1107
- sidebars.forEach((sidebar) => {
1108
- const newTop = Math.max(shadowDomRef.current.getBoundingClientRect().top, 0);
1109
- sidebar.style.top = mdTabs ? `${newTop + mdTabs.getBoundingClientRect().height}px` : `${newTop}px`;
1110
- });
1111
- }
1112
- }, [shadowDomRef, sidebars]);
1242
+ if (!dom || !sidebars)
1243
+ return;
1244
+ const mdTabs = dom.querySelector(".md-container > .md-tabs");
1245
+ sidebars.forEach((sidebar) => {
1246
+ const newTop = Math.max(dom.getBoundingClientRect().top, 0);
1247
+ sidebar.style.top = mdTabs ? `${newTop + mdTabs.getBoundingClientRect().height}px` : `${newTop}px`;
1248
+ });
1249
+ }, [dom, sidebars]);
1113
1250
  useEffect(() => {
1114
1251
  updateSidebarPosition();
1115
1252
  window.addEventListener("scroll", updateSidebarPosition, true);
@@ -1136,106 +1273,107 @@ const Reader = ({entityRef, onReady, withSearch = true}) => {
1136
1273
  addGitFeedbackLink(scmIntegrationsApi),
1137
1274
  injectCss({
1138
1275
  css: `
1139
- body {
1140
- font-family: ${theme.typography.fontFamily};
1141
- --md-text-color: ${theme.palette.text.primary};
1142
- --md-text-link-color: ${theme.palette.primary.main};
1276
+ body {
1277
+ font-family: ${theme.typography.fontFamily};
1278
+ --md-text-color: ${theme.palette.text.primary};
1279
+ --md-text-link-color: ${theme.palette.primary.main};
1143
1280
 
1144
- --md-code-fg-color: ${theme.palette.text.primary};
1145
- --md-code-bg-color: ${theme.palette.background.paper};
1146
- }
1147
- .md-main__inner { margin-top: 0; }
1148
- .md-sidebar { position: fixed; bottom: 100px; width: 20rem; }
1149
- .md-sidebar--secondary { right: 2rem; }
1150
- .md-content { margin-bottom: 50px }
1151
- .md-footer { position: fixed; bottom: 0px; width: 100vw; }
1152
- .md-footer-nav__link { width: 20rem;}
1153
- .md-content { margin-left: 20rem; max-width: calc(100% - 20rem * 2 - 3rem); }
1154
- .md-typeset { font-size: 1rem; }
1155
- .md-nav { font-size: 1rem; }
1156
- .md-grid { max-width: 90vw; margin: 0 }
1157
- .md-typeset table:not([class]) {
1158
- font-size: 1rem;
1159
- border: 1px solid ${theme.palette.text.primary};
1160
- border-bottom: none;
1161
- border-collapse: collapse;
1162
- }
1163
- .md-typeset table:not([class]) td, .md-typeset table:not([class]) th {
1164
- border-bottom: 1px solid ${theme.palette.text.primary};
1165
- }
1166
- .md-typeset table:not([class]) th { font-weight: bold; }
1167
- .md-typeset .admonition, .md-typeset details {
1168
- font-size: 1rem;
1169
- }
1170
- @media screen and (max-width: 76.1875em) {
1171
- .md-nav {
1172
- background-color: ${theme.palette.background.default};
1173
- transition: none !important
1281
+ --md-code-fg-color: ${theme.palette.text.primary};
1282
+ --md-code-bg-color: ${theme.palette.background.paper};
1174
1283
  }
1175
- .md-sidebar--secondary { display: none; }
1176
- .md-sidebar--primary { left: 72px; width: 10rem }
1177
- .md-content { margin-left: 10rem; max-width: calc(100% - 10rem); }
1178
- .md-content__inner { font-size: 0.9rem }
1179
- .md-footer {
1180
- position: static;
1181
- margin-left: 10rem;
1182
- width: calc(100% - 10rem);
1284
+ .md-main__inner { margin-top: 0; }
1285
+ .md-sidebar { position: fixed; bottom: 100px; width: 20rem; }
1286
+ .md-sidebar--secondary { right: 2rem; }
1287
+ .md-content { margin-bottom: 50px }
1288
+ .md-footer { position: fixed; bottom: 0px; width: 100vw; }
1289
+ .md-footer-nav__link { width: 20rem;}
1290
+ .md-content { margin-left: 20rem; max-width: calc(100% - 20rem * 2 - 3rem); }
1291
+ .md-typeset { font-size: 1rem; }
1292
+ .md-typeset h1, .md-typeset h2, .md-typeset h3 { font-weight: bold; }
1293
+ .md-nav { font-size: 1rem; }
1294
+ .md-grid { max-width: 90vw; margin: 0 }
1295
+ .md-typeset table:not([class]) {
1296
+ font-size: 1rem;
1297
+ border: 1px solid ${theme.palette.text.primary};
1298
+ border-bottom: none;
1299
+ border-collapse: collapse;
1183
1300
  }
1184
- .md-nav--primary .md-nav__title {
1185
- white-space: normal;
1186
- height: auto;
1187
- line-height: 1rem;
1188
- cursor: auto;
1301
+ .md-typeset table:not([class]) td, .md-typeset table:not([class]) th {
1302
+ border-bottom: 1px solid ${theme.palette.text.primary};
1189
1303
  }
1190
- .md-nav--primary > .md-nav__title [for="none"] {
1191
- padding-top: 0;
1304
+ .md-typeset table:not([class]) th { font-weight: bold; }
1305
+ .md-typeset .admonition, .md-typeset details {
1306
+ font-size: 1rem;
1192
1307
  }
1193
- }
1194
- `
1308
+ @media screen and (max-width: 76.1875em) {
1309
+ .md-nav {
1310
+ background-color: ${theme.palette.background.default};
1311
+ transition: none !important
1312
+ }
1313
+ .md-sidebar--secondary { display: none; }
1314
+ .md-sidebar--primary { left: 72px; width: 10rem }
1315
+ .md-content { margin-left: 10rem; max-width: calc(100% - 10rem); }
1316
+ .md-content__inner { font-size: 0.9rem }
1317
+ .md-footer {
1318
+ position: static;
1319
+ margin-left: 10rem;
1320
+ width: calc(100% - 10rem);
1321
+ }
1322
+ .md-nav--primary .md-nav__title {
1323
+ white-space: normal;
1324
+ height: auto;
1325
+ line-height: 1rem;
1326
+ cursor: auto;
1327
+ }
1328
+ .md-nav--primary > .md-nav__title [for="none"] {
1329
+ padding-top: 0;
1330
+ }
1331
+ }
1332
+ `
1195
1333
  }),
1196
1334
  injectCss({
1197
1335
  css: `
1198
- .md-nav__link, .md-typeset a, .md-typeset a::before, .md-typeset .headerlink {
1199
- transition: none;
1200
- }
1201
- `
1336
+ .md-nav__link, .md-typeset a, .md-typeset a::before, .md-typeset .headerlink {
1337
+ transition: none;
1338
+ }
1339
+ `
1202
1340
  }),
1203
1341
  injectCss({
1204
1342
  css: `
1205
- .md-typeset pre > code::-webkit-scrollbar-thumb {
1206
- background-color: hsla(0, 0%, 0%, 0.32);
1207
- }
1208
- .md-typeset pre > code::-webkit-scrollbar-thumb:hover {
1209
- background-color: hsla(0, 0%, 0%, 0.87);
1210
- }
1343
+ .md-typeset pre > code::-webkit-scrollbar-thumb {
1344
+ background-color: hsla(0, 0%, 0%, 0.32);
1345
+ }
1346
+ .md-typeset pre > code::-webkit-scrollbar-thumb:hover {
1347
+ background-color: hsla(0, 0%, 0%, 0.87);
1348
+ }
1211
1349
  `
1212
1350
  }),
1213
1351
  injectCss({
1214
1352
  css: `
1215
- :host {
1216
- --md-admonition-icon--note: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20.71 7.04c.39-.39.39-1.04 0-1.41l-2.34-2.34c-.37-.39-1.02-.39-1.41 0l-1.84 1.83 3.75 3.75M3 17.25V21h3.75L17.81 9.93l-3.75-3.75L3 17.25z"/></svg>');
1217
- --md-admonition-icon--abstract: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 5h16v2H4V5m0 4h16v2H4V9m0 4h16v2H4v-2m0 4h10v2H4v-2z"/></svg>');
1218
- --md-admonition-icon--info: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 9h-2V7h2m0 10h-2v-6h2m-1-9A10 10 0 002 12a10 10 0 0010 10 10 10 0 0010-10A10 10 0 0012 2z"/></svg>');
1219
- --md-admonition-icon--tip: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17.55 11.2c-.23-.3-.5-.56-.76-.82-.65-.6-1.4-1.03-2.03-1.66C13.3 7.26 13 4.85 13.91 3c-.91.23-1.75.75-2.45 1.32-2.54 2.08-3.54 5.75-2.34 8.9.04.1.08.2.08.33 0 .22-.15.42-.35.5-.22.1-.46.04-.64-.12a.83.83 0 01-.15-.17c-1.1-1.43-1.28-3.48-.53-5.12C5.89 10 5 12.3 5.14 14.47c.04.5.1 1 .27 1.5.14.6.4 1.2.72 1.73 1.04 1.73 2.87 2.97 4.84 3.22 2.1.27 4.35-.12 5.96-1.6 1.8-1.66 2.45-4.32 1.5-6.6l-.13-.26c-.2-.46-.47-.87-.8-1.25l.05-.01m-3.1 6.3c-.28.24-.73.5-1.08.6-1.1.4-2.2-.16-2.87-.82 1.19-.28 1.89-1.16 2.09-2.05.17-.8-.14-1.46-.27-2.23-.12-.74-.1-1.37.18-2.06.17.38.37.76.6 1.06.76 1 1.95 1.44 2.2 2.8.04.14.06.28.06.43.03.82-.32 1.72-.92 2.27h.01z"/></svg>');
1220
- --md-admonition-icon--success: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2m-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/></svg>');
1221
- --md-admonition-icon--question: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.07 11.25l-.9.92C13.45 12.89 13 13.5 13 15h-2v-.5c0-1.11.45-2.11 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41a2 2 0 00-2-2 2 2 0 00-2 2H8a4 4 0 014-4 4 4 0 014 4 3.2 3.2 0 01-.93 2.25M13 19h-2v-2h2M12 2A10 10 0 002 12a10 10 0 0010 10 10 10 0 0010-10c0-5.53-4.5-10-10-10z"/></svg>');
1222
- --md-admonition-icon--warning: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 14h-2v-4h2m0 8h-2v-2h2M1 21h22L12 2 1 21z"/></svg>');
1223
- --md-admonition-icon--failure: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2c5.53 0 10 4.47 10 10s-4.47 10-10 10S2 17.53 2 12 6.47 2 12 2m3.59 5L12 10.59 8.41 7 7 8.41 10.59 12 7 15.59 8.41 17 12 13.41 15.59 17 17 15.59 13.41 12 17 8.41 15.59 7z"/></svg>');
1224
- --md-admonition-icon--danger: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M11.5 20l4.86-9.73H13V4l-5 9.73h3.5V20M12 2c2.75 0 5.1 1 7.05 2.95C21 6.9 22 9.25 22 12s-1 5.1-2.95 7.05C17.1 21 14.75 22 12 22s-5.1-1-7.05-2.95C3 17.1 2 14.75 2 12s1-5.1 2.95-7.05C6.9 3 9.25 2 12 2z"/></svg>');
1225
- --md-admonition-icon--bug: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 12h-4v-2h4m0 6h-4v-2h4m6-6h-2.81a5.985 5.985 0 00-1.82-1.96L17 4.41 15.59 3l-2.17 2.17a6.002 6.002 0 00-2.83 0L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8z"/></svg>');
1226
- --md-admonition-icon--example: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 13v-2h14v2H7m0 6v-2h14v2H7M7 7V5h14v2H7M3 8V5H2V4h2v4H3m-1 9v-1h3v4H2v-1h2v-.5H3v-1h1V17H2m2.25-7a.75.75 0 01.75.75c0 .2-.08.39-.21.52L3.12 13H5v1H2v-.92L4 11H2v-1h2.25z"/></svg>');
1227
- --md-admonition-icon--quote: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 17h3l2-4V7h-6v6h3M6 17h3l2-4V7H5v6h3l-2 4z"/></svg>');
1228
- }
1229
- :host {
1230
- --md-footnotes-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.42L5.83 13H21V7h-2z"/></svg>');
1231
- }
1232
- :host {
1233
- --md-details-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8.59 16.58L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.42z"/></svg>');
1234
- }
1235
- :host {
1236
- --md-tasklist-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2A10 10 0 002 12a10 10 0 0010 10 10 10 0 0010-10A10 10 0 0012 2z"/></svg>');
1237
- --md-tasklist-icon--checked: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2m-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/></svg>');
1238
- }
1353
+ :host {
1354
+ --md-admonition-icon--note: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20.71 7.04c.39-.39.39-1.04 0-1.41l-2.34-2.34c-.37-.39-1.02-.39-1.41 0l-1.84 1.83 3.75 3.75M3 17.25V21h3.75L17.81 9.93l-3.75-3.75L3 17.25z"/></svg>');
1355
+ --md-admonition-icon--abstract: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 5h16v2H4V5m0 4h16v2H4V9m0 4h16v2H4v-2m0 4h10v2H4v-2z"/></svg>');
1356
+ --md-admonition-icon--info: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 9h-2V7h2m0 10h-2v-6h2m-1-9A10 10 0 002 12a10 10 0 0010 10 10 10 0 0010-10A10 10 0 0012 2z"/></svg>');
1357
+ --md-admonition-icon--tip: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17.55 11.2c-.23-.3-.5-.56-.76-.82-.65-.6-1.4-1.03-2.03-1.66C13.3 7.26 13 4.85 13.91 3c-.91.23-1.75.75-2.45 1.32-2.54 2.08-3.54 5.75-2.34 8.9.04.1.08.2.08.33 0 .22-.15.42-.35.5-.22.1-.46.04-.64-.12a.83.83 0 01-.15-.17c-1.1-1.43-1.28-3.48-.53-5.12C5.89 10 5 12.3 5.14 14.47c.04.5.1 1 .27 1.5.14.6.4 1.2.72 1.73 1.04 1.73 2.87 2.97 4.84 3.22 2.1.27 4.35-.12 5.96-1.6 1.8-1.66 2.45-4.32 1.5-6.6l-.13-.26c-.2-.46-.47-.87-.8-1.25l.05-.01m-3.1 6.3c-.28.24-.73.5-1.08.6-1.1.4-2.2-.16-2.87-.82 1.19-.28 1.89-1.16 2.09-2.05.17-.8-.14-1.46-.27-2.23-.12-.74-.1-1.37.18-2.06.17.38.37.76.6 1.06.76 1 1.95 1.44 2.2 2.8.04.14.06.28.06.43.03.82-.32 1.72-.92 2.27h.01z"/></svg>');
1358
+ --md-admonition-icon--success: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2m-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/></svg>');
1359
+ --md-admonition-icon--question: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.07 11.25l-.9.92C13.45 12.89 13 13.5 13 15h-2v-.5c0-1.11.45-2.11 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41a2 2 0 00-2-2 2 2 0 00-2 2H8a4 4 0 014-4 4 4 0 014 4 3.2 3.2 0 01-.93 2.25M13 19h-2v-2h2M12 2A10 10 0 002 12a10 10 0 0010 10 10 10 0 0010-10c0-5.53-4.5-10-10-10z"/></svg>');
1360
+ --md-admonition-icon--warning: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 14h-2v-4h2m0 8h-2v-2h2M1 21h22L12 2 1 21z"/></svg>');
1361
+ --md-admonition-icon--failure: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2c5.53 0 10 4.47 10 10s-4.47 10-10 10S2 17.53 2 12 6.47 2 12 2m3.59 5L12 10.59 8.41 7 7 8.41 10.59 12 7 15.59 8.41 17 12 13.41 15.59 17 17 15.59 13.41 12 17 8.41 15.59 7z"/></svg>');
1362
+ --md-admonition-icon--danger: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M11.5 20l4.86-9.73H13V4l-5 9.73h3.5V20M12 2c2.75 0 5.1 1 7.05 2.95C21 6.9 22 9.25 22 12s-1 5.1-2.95 7.05C17.1 21 14.75 22 12 22s-5.1-1-7.05-2.95C3 17.1 2 14.75 2 12s1-5.1 2.95-7.05C6.9 3 9.25 2 12 2z"/></svg>');
1363
+ --md-admonition-icon--bug: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 12h-4v-2h4m0 6h-4v-2h4m6-6h-2.81a5.985 5.985 0 00-1.82-1.96L17 4.41 15.59 3l-2.17 2.17a6.002 6.002 0 00-2.83 0L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8z"/></svg>');
1364
+ --md-admonition-icon--example: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 13v-2h14v2H7m0 6v-2h14v2H7M7 7V5h14v2H7M3 8V5H2V4h2v4H3m-1 9v-1h3v4H2v-1h2v-.5H3v-1h1V17H2m2.25-7a.75.75 0 01.75.75c0 .2-.08.39-.21.52L3.12 13H5v1H2v-.92L4 11H2v-1h2.25z"/></svg>');
1365
+ --md-admonition-icon--quote: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 17h3l2-4V7h-6v6h3M6 17h3l2-4V7H5v6h3l-2 4z"/></svg>');
1366
+ }
1367
+ :host {
1368
+ --md-footnotes-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.42L5.83 13H21V7h-2z"/></svg>');
1369
+ }
1370
+ :host {
1371
+ --md-details-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8.59 16.58L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.42z"/></svg>');
1372
+ }
1373
+ :host {
1374
+ --md-tasklist-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2A10 10 0 002 12a10 10 0 0010 10 10 10 0 0010-10A10 10 0 0012 2z"/></svg>');
1375
+ --md-tasklist-icon--checked: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2m-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/></svg>');
1376
+ }
1239
1377
  `
1240
1378
  })
1241
1379
  ]), [
@@ -1250,131 +1388,100 @@ const Reader = ({entityRef, onReady, withSearch = true}) => {
1250
1388
  theme.palette.text.primary,
1251
1389
  theme.typography.fontFamily
1252
1390
  ]);
1253
- const postRender = useCallback(async (shadowRoot) => transform(shadowRoot.children[0], [
1254
- (dom) => {
1255
- setTimeout(() => {
1256
- var _a2;
1257
- if (window.location.hash) {
1258
- const hash = window.location.hash.slice(1);
1259
- (_a2 = shadowRoot == null ? void 0 : shadowRoot.getElementById(hash)) == null ? void 0 : _a2.scrollIntoView();
1260
- }
1261
- }, 200);
1262
- return dom;
1263
- },
1391
+ const postRender = useCallback(async (transformedElement) => transform(transformedElement, [
1392
+ scrollIntoAnchor(),
1264
1393
  addLinkClickListener({
1265
1394
  baseUrl: window.location.origin,
1266
1395
  onClick: (_, url) => {
1267
- var _a2;
1396
+ var _a, _b;
1268
1397
  const parsedUrl = new URL(url);
1269
1398
  if (parsedUrl.hash) {
1270
1399
  navigate(`${parsedUrl.pathname}${parsedUrl.hash}`);
1271
- (_a2 = shadowRoot == null ? void 0 : shadowRoot.getElementById(parsedUrl.hash.slice(1))) == null ? void 0 : _a2.scrollIntoView();
1400
+ (_a = transformedElement == null ? void 0 : transformedElement.querySelector(`#${parsedUrl.hash.slice(1)}`)) == null ? void 0 : _a.scrollIntoView();
1272
1401
  } else {
1273
1402
  navigate(parsedUrl.pathname);
1403
+ (_b = transformedElement == null ? void 0 : transformedElement.querySelector(".md-content__inner")) == null ? void 0 : _b.scrollIntoView();
1274
1404
  }
1275
1405
  }
1276
1406
  }),
1277
1407
  onCssReady({
1278
1408
  docStorageUrl: await techdocsStorageApi.getApiOrigin(),
1279
- onLoading: (dom) => {
1280
- dom.style.setProperty("opacity", "0");
1409
+ onLoading: (renderedElement) => {
1410
+ renderedElement.style.setProperty("opacity", "0");
1281
1411
  },
1282
- onLoaded: (dom) => {
1283
- var _a2;
1284
- dom.style.removeProperty("opacity");
1285
- (_a2 = dom.querySelector(".md-nav__title")) == null ? void 0 : _a2.removeAttribute("for");
1286
- const sideDivs = Array.from(shadowRoot.querySelectorAll(".md-sidebar"));
1287
- setSidebars(sideDivs);
1288
- const docTopPosition = dom.getBoundingClientRect().top;
1289
- const mdTabs = dom.querySelector(".md-container > .md-tabs");
1290
- sideDivs.forEach((sidebar) => {
1291
- sidebar.style.top = mdTabs ? `${docTopPosition + mdTabs.getBoundingClientRect().height}px` : `${docTopPosition}px`;
1292
- });
1412
+ onLoaded: (renderedElement) => {
1413
+ var _a;
1414
+ renderedElement.style.removeProperty("opacity");
1415
+ (_a = renderedElement.querySelector(".md-nav__title")) == null ? void 0 : _a.removeAttribute("for");
1416
+ setSidebars(Array.from(renderedElement.querySelectorAll(".md-sidebar")));
1293
1417
  }
1294
1418
  })
1295
1419
  ]), [navigate, techdocsStorageApi]);
1296
1420
  useEffect(() => {
1297
- var _a2;
1298
- if (!rawPage || !shadowDomRef.current) {
1299
- if ((_a2 = shadowDomRef.current) == null ? void 0 : _a2.shadowRoot) {
1300
- shadowDomRef.current.shadowRoot.innerHTML = "";
1301
- }
1421
+ if (!rawPage)
1302
1422
  return () => {
1303
1423
  };
1304
- }
1305
- if (onReady) {
1306
- onReady();
1307
- }
1308
1424
  let shouldReplaceContent = true;
1309
- preRender(rawPage, path).then(async (transformedElement) => {
1310
- if (!(transformedElement == null ? void 0 : transformedElement.innerHTML)) {
1425
+ preRender(rawPage, path).then(async (preTransformedDomElement) => {
1426
+ if (!(preTransformedDomElement == null ? void 0 : preTransformedDomElement.innerHTML)) {
1311
1427
  return;
1312
1428
  }
1313
1429
  if (!shouldReplaceContent) {
1314
1430
  return;
1315
1431
  }
1316
- const shadowDiv = shadowDomRef.current;
1317
- const shadowRoot = shadowDiv.shadowRoot || shadowDiv.attachShadow({mode: "open"});
1318
- Array.from(shadowRoot.children).forEach((child) => shadowRoot.removeChild(child));
1319
- shadowRoot.appendChild(transformedElement);
1320
1432
  window.scroll({top: 0});
1321
- await postRender(shadowRoot);
1433
+ const postTransformedDomElement = await postRender(preTransformedDomElement);
1434
+ setDom(postTransformedDomElement);
1322
1435
  });
1323
1436
  return () => {
1324
1437
  shouldReplaceContent = false;
1325
1438
  };
1326
- }, [onReady, path, postRender, preRender, rawPage]);
1327
- return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, state === "CHECKING" && /* @__PURE__ */ React__default.createElement(Progress, null), state === "INITIAL_BUILD" && /* @__PURE__ */ React__default.createElement(Alert, {
1328
- variant: "outlined",
1329
- severity: "info",
1330
- icon: /* @__PURE__ */ React__default.createElement(CircularProgress, {
1331
- size: "24px"
1332
- }),
1333
- action: /* @__PURE__ */ React__default.createElement(TechDocsBuildLogs, {
1334
- buildLog
1335
- })
1336
- }, "Documentation is accessed for the first time and is being prepared. The subsequent loads are much faster."), state === "CONTENT_STALE_REFRESHING" && /* @__PURE__ */ React__default.createElement(Alert, {
1337
- variant: "outlined",
1338
- severity: "info",
1339
- icon: /* @__PURE__ */ React__default.createElement(CircularProgress, {
1340
- size: "24px"
1341
- }),
1342
- action: /* @__PURE__ */ React__default.createElement(TechDocsBuildLogs, {
1343
- buildLog
1344
- })
1345
- }, "A newer version of this documentation is being prepared and will be available shortly."), state === "CONTENT_STALE_READY" && /* @__PURE__ */ React__default.createElement(Alert, {
1346
- variant: "outlined",
1347
- severity: "success",
1348
- action: /* @__PURE__ */ React__default.createElement(Button$1, {
1349
- color: "inherit",
1350
- onClick: () => contentReload()
1351
- }, "Refresh")
1352
- }, "A newer version of this documentation is now available, please refresh to view."), state === "CONTENT_STALE_ERROR" && /* @__PURE__ */ React__default.createElement(Alert, {
1353
- variant: "outlined",
1354
- severity: "error",
1355
- action: /* @__PURE__ */ React__default.createElement(TechDocsBuildLogs, {
1356
- buildLog
1357
- }),
1358
- classes: {message: classes.message}
1359
- }, "Building a newer version of this documentation failed.", " ", syncErrorMessage), state === "CONTENT_NOT_FOUND" && /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, syncErrorMessage && /* @__PURE__ */ React__default.createElement(Alert, {
1360
- variant: "outlined",
1361
- severity: "error",
1362
- action: /* @__PURE__ */ React__default.createElement(TechDocsBuildLogs, {
1363
- buildLog
1364
- }),
1365
- classes: {message: classes.message}
1366
- }, "Building a newer version of this documentation failed.", " ", syncErrorMessage), /* @__PURE__ */ React__default.createElement(TechDocsNotFound, {
1367
- errorMessage: contentErrorMessage
1368
- })), withSearch && ((_b = (_a = shadowDomRef == null ? void 0 : shadowDomRef.current) == null ? void 0 : _a.shadowRoot) == null ? void 0 : _b.innerHTML) && /* @__PURE__ */ React__default.createElement(Grid, {
1439
+ }, [rawPage, path, preRender, postRender]);
1440
+ return dom;
1441
+ };
1442
+ const TheReader = ({
1443
+ entityRef,
1444
+ onReady = () => {
1445
+ },
1446
+ withSearch = true
1447
+ }) => {
1448
+ var _a, _b;
1449
+ const classes = useStyles();
1450
+ const dom = useTechDocsReaderDom();
1451
+ const shadowDomRef = useRef(null);
1452
+ const onReadyRef = useRef(onReady);
1453
+ useEffect(() => {
1454
+ onReadyRef.current = onReady;
1455
+ }, [onReady]);
1456
+ useEffect(() => {
1457
+ if (!dom || !shadowDomRef.current)
1458
+ return;
1459
+ const shadowDiv = shadowDomRef.current;
1460
+ const shadowRoot = shadowDiv.shadowRoot || shadowDiv.attachShadow({mode: "open"});
1461
+ Array.from(shadowRoot.children).forEach((child) => shadowRoot.removeChild(child));
1462
+ shadowRoot.appendChild(dom);
1463
+ onReadyRef.current();
1464
+ }, [dom]);
1465
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(TechDocsStateIndicator, null), withSearch && ((_b = (_a = shadowDomRef == null ? void 0 : shadowDomRef.current) == null ? void 0 : _a.shadowRoot) == null ? void 0 : _b.innerHTML) && /* @__PURE__ */ React.createElement(Grid, {
1369
1466
  container: true,
1370
1467
  className: classes.searchBar
1371
- }, /* @__PURE__ */ React__default.createElement(TechDocsSearch, {
1468
+ }, /* @__PURE__ */ React.createElement(TechDocsSearch, {
1372
1469
  entityId: entityRef
1373
- })), /* @__PURE__ */ React__default.createElement("div", {
1470
+ })), /* @__PURE__ */ React.createElement("div", {
1374
1471
  "data-testid": "techdocs-content-shadowroot",
1375
1472
  ref: shadowDomRef
1376
1473
  }));
1377
1474
  };
1475
+ const Reader = ({
1476
+ entityRef,
1477
+ onReady = () => {
1478
+ },
1479
+ withSearch = true
1480
+ }) => /* @__PURE__ */ React.createElement(TechDocsReaderProvider, null, /* @__PURE__ */ React.createElement(TheReader, {
1481
+ entityRef,
1482
+ onReady,
1483
+ withSearch
1484
+ }));
1378
1485
 
1379
1486
  const TechDocsPageHeader = ({
1380
1487
  entityRef,
@@ -1387,34 +1494,34 @@ const TechDocsPageHeader = ({
1387
1494
  const lifecycle = spec == null ? void 0 : spec.lifecycle;
1388
1495
  const ownedByRelations = entityMetadata ? getEntityRelations(entityMetadata, RELATION_OWNED_BY) : [];
1389
1496
  const docsRootLink = useRouteRef(rootRouteRef)();
1390
- const labels = /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(HeaderLabel, {
1497
+ const labels = /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(HeaderLabel, {
1391
1498
  label: "Component",
1392
- value: /* @__PURE__ */ React__default.createElement(EntityRefLink, {
1499
+ value: /* @__PURE__ */ React.createElement(EntityRefLink, {
1393
1500
  color: "inherit",
1394
1501
  entityRef,
1395
1502
  defaultKind: "Component"
1396
1503
  })
1397
- }), ownedByRelations.length > 0 && /* @__PURE__ */ React__default.createElement(HeaderLabel, {
1504
+ }), ownedByRelations.length > 0 && /* @__PURE__ */ React.createElement(HeaderLabel, {
1398
1505
  label: "Owner",
1399
- value: /* @__PURE__ */ React__default.createElement(EntityRefLinks, {
1506
+ value: /* @__PURE__ */ React.createElement(EntityRefLinks, {
1400
1507
  color: "inherit",
1401
1508
  entityRefs: ownedByRelations,
1402
1509
  defaultKind: "group"
1403
1510
  })
1404
- }), lifecycle ? /* @__PURE__ */ React__default.createElement(HeaderLabel, {
1511
+ }), lifecycle ? /* @__PURE__ */ React.createElement(HeaderLabel, {
1405
1512
  label: "Lifecycle",
1406
1513
  value: lifecycle
1407
- }) : null, locationMetadata && locationMetadata.type !== "dir" && locationMetadata.type !== "file" ? /* @__PURE__ */ React__default.createElement(HeaderLabel, {
1514
+ }) : null, locationMetadata && locationMetadata.type !== "dir" && locationMetadata.type !== "file" ? /* @__PURE__ */ React.createElement(HeaderLabel, {
1408
1515
  label: "",
1409
- value: /* @__PURE__ */ React__default.createElement("a", {
1516
+ value: /* @__PURE__ */ React.createElement("a", {
1410
1517
  href: locationMetadata.target,
1411
1518
  target: "_blank",
1412
1519
  rel: "noopener noreferrer"
1413
- }, /* @__PURE__ */ React__default.createElement(CodeIcon, {
1520
+ }, /* @__PURE__ */ React.createElement(CodeIcon, {
1414
1521
  style: {marginTop: "-25px", fill: "#fff"}
1415
1522
  }))
1416
1523
  }) : null);
1417
- return /* @__PURE__ */ React__default.createElement(Header, {
1524
+ return /* @__PURE__ */ React.createElement(Header, {
1418
1525
  title: siteName ? siteName : ".",
1419
1526
  pageTitleOverride: siteName || name,
1420
1527
  subtitle: siteDescription && siteDescription !== "None" ? siteDescription : "",
@@ -1440,13 +1547,13 @@ const LegacyTechDocsPage = () => {
1440
1547
  setDocumentReady(true);
1441
1548
  }, [setDocumentReady]);
1442
1549
  if (entityMetadataError) {
1443
- return /* @__PURE__ */ React__default.createElement(TechDocsNotFound, {
1550
+ return /* @__PURE__ */ React.createElement(TechDocsNotFound, {
1444
1551
  errorMessage: entityMetadataError.message
1445
1552
  });
1446
1553
  }
1447
- return /* @__PURE__ */ React__default.createElement(Page, {
1554
+ return /* @__PURE__ */ React.createElement(Page, {
1448
1555
  themeId: "documentation"
1449
- }, /* @__PURE__ */ React__default.createElement(TechDocsPageHeader, {
1556
+ }, /* @__PURE__ */ React.createElement(TechDocsPageHeader, {
1450
1557
  techDocsMetadata: techdocsMetadataValue,
1451
1558
  entityMetadata: entityMetadataValue,
1452
1559
  entityRef: {
@@ -1454,9 +1561,9 @@ const LegacyTechDocsPage = () => {
1454
1561
  namespace,
1455
1562
  name
1456
1563
  }
1457
- }), /* @__PURE__ */ React__default.createElement(Content, {
1564
+ }), /* @__PURE__ */ React.createElement(Content, {
1458
1565
  "data-testid": "techdocs-content"
1459
- }, /* @__PURE__ */ React__default.createElement(Reader, {
1566
+ }, /* @__PURE__ */ React.createElement(Reader, {
1460
1567
  onReady,
1461
1568
  entityRef: {
1462
1569
  kind,
@@ -1484,13 +1591,13 @@ const TechDocsPage = ({children}) => {
1484
1591
  setDocumentReady(true);
1485
1592
  }, [setDocumentReady]);
1486
1593
  if (entityMetadataError) {
1487
- return /* @__PURE__ */ React__default.createElement(TechDocsNotFound, {
1594
+ return /* @__PURE__ */ React.createElement(TechDocsNotFound, {
1488
1595
  errorMessage: entityMetadataError.message
1489
1596
  });
1490
1597
  }
1491
1598
  if (!children)
1492
- return outlet || /* @__PURE__ */ React__default.createElement(LegacyTechDocsPage, null);
1493
- return /* @__PURE__ */ React__default.createElement(Page, {
1599
+ return outlet || /* @__PURE__ */ React.createElement(LegacyTechDocsPage, null);
1600
+ return /* @__PURE__ */ React.createElement(Page, {
1494
1601
  themeId: "documentation"
1495
1602
  }, children instanceof Function ? children({
1496
1603
  techdocsMetadataValue,
@@ -1505,41 +1612,9 @@ var TechDocsPage$1 = /*#__PURE__*/Object.freeze({
1505
1612
  TechDocsPage: TechDocsPage
1506
1613
  });
1507
1614
 
1508
- const DocsCardGrid = ({
1509
- entities
1510
- }) => {
1511
- const getRouteToReaderPageFor = useRouteRef(rootDocsRouteRef);
1512
- const toLowerMaybe = useApi(configApiRef).getOptionalBoolean("techdocs.legacyUseCaseSensitiveTripletPaths") ? (str) => str : (str) => str.toLocaleLowerCase();
1513
- if (!entities)
1514
- return null;
1515
- return /* @__PURE__ */ React__default.createElement(ItemCardGrid, {
1516
- "data-testid": "docs-explore"
1517
- }, !(entities == null ? void 0 : entities.length) ? null : entities.map((entity, index) => {
1518
- var _a;
1519
- return /* @__PURE__ */ React__default.createElement(Card, {
1520
- key: index
1521
- }, /* @__PURE__ */ React__default.createElement(CardMedia, null, /* @__PURE__ */ React__default.createElement(ItemCardHeader, {
1522
- title: entity.metadata.name
1523
- })), /* @__PURE__ */ React__default.createElement(CardContent, null, entity.metadata.description), /* @__PURE__ */ React__default.createElement(CardActions, null, /* @__PURE__ */ React__default.createElement(Button, {
1524
- to: getRouteToReaderPageFor({
1525
- namespace: toLowerMaybe((_a = entity.metadata.namespace) != null ? _a : "default"),
1526
- kind: toLowerMaybe(entity.kind),
1527
- name: toLowerMaybe(entity.metadata.name)
1528
- }),
1529
- color: "primary",
1530
- "data-testid": "read_docs"
1531
- }, "Read Docs")));
1532
- }));
1533
- };
1534
-
1535
- var DocsCardGrid$1 = /*#__PURE__*/Object.freeze({
1536
- __proto__: null,
1537
- DocsCardGrid: DocsCardGrid
1538
- });
1539
-
1540
1615
  const panels = {
1541
1616
  DocsTable: DocsTable$1,
1542
- DocsCardGrid
1617
+ DocsCardGrid: DocsCardGrid$1
1543
1618
  };
1544
1619
  const CustomPanel = ({
1545
1620
  config,
@@ -1564,12 +1639,12 @@ const CustomPanel = ({
1564
1639
  }
1565
1640
  return typeof config.filterPredicate === "function" && config.filterPredicate(entity);
1566
1641
  });
1567
- return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(ContentHeader, {
1642
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ContentHeader, {
1568
1643
  title: config.title,
1569
1644
  description: config.description
1570
- }, index === 0 ? /* @__PURE__ */ React__default.createElement(SupportButton, null, "Discover documentation in your ecosystem.") : null), /* @__PURE__ */ React__default.createElement("div", {
1645
+ }, index === 0 ? /* @__PURE__ */ React.createElement(SupportButton, null, "Discover documentation in your ecosystem.") : null), /* @__PURE__ */ React.createElement("div", {
1571
1646
  className: classes.panelContainer
1572
- }, /* @__PURE__ */ React__default.createElement(Panel, {
1647
+ }, /* @__PURE__ */ React.createElement(Panel, {
1573
1648
  "data-testid": "techdocs-custom-panel",
1574
1649
  entities: shownEntities
1575
1650
  })));
@@ -1604,27 +1679,27 @@ const TechDocsCustomHome = ({
1604
1679
  });
1605
1680
  const currentTabConfig = tabsConfig[selectedTab];
1606
1681
  if (loading) {
1607
- return /* @__PURE__ */ React__default.createElement(TechDocsPageWrapper, null, /* @__PURE__ */ React__default.createElement(Content, null, /* @__PURE__ */ React__default.createElement(Progress, null)));
1682
+ return /* @__PURE__ */ React.createElement(TechDocsPageWrapper, null, /* @__PURE__ */ React.createElement(Content, null, /* @__PURE__ */ React.createElement(Progress, null)));
1608
1683
  }
1609
1684
  if (error) {
1610
- return /* @__PURE__ */ React__default.createElement(TechDocsPageWrapper, null, /* @__PURE__ */ React__default.createElement(Content, null, /* @__PURE__ */ React__default.createElement(WarningPanel, {
1685
+ return /* @__PURE__ */ React.createElement(TechDocsPageWrapper, null, /* @__PURE__ */ React.createElement(Content, null, /* @__PURE__ */ React.createElement(WarningPanel, {
1611
1686
  severity: "error",
1612
1687
  title: "Could not load available documentation."
1613
- }, /* @__PURE__ */ React__default.createElement(CodeSnippet, {
1688
+ }, /* @__PURE__ */ React.createElement(CodeSnippet, {
1614
1689
  language: "text",
1615
1690
  text: error.toString()
1616
1691
  }))));
1617
1692
  }
1618
- return /* @__PURE__ */ React__default.createElement(TechDocsPageWrapper, null, /* @__PURE__ */ React__default.createElement(HeaderTabs, {
1693
+ return /* @__PURE__ */ React.createElement(TechDocsPageWrapper, null, /* @__PURE__ */ React.createElement(HeaderTabs, {
1619
1694
  selectedIndex: selectedTab,
1620
1695
  onChange: (index) => setSelectedTab(index),
1621
1696
  tabs: tabsConfig.map(({label}, index) => ({
1622
1697
  id: index.toString(),
1623
1698
  label
1624
1699
  }))
1625
- }), /* @__PURE__ */ React__default.createElement(Content, {
1700
+ }), /* @__PURE__ */ React.createElement(Content, {
1626
1701
  "data-testid": "techdocs-content"
1627
- }, currentTabConfig.panels.map((config, index) => /* @__PURE__ */ React__default.createElement(CustomPanel, {
1702
+ }, currentTabConfig.panels.map((config, index) => /* @__PURE__ */ React.createElement(CustomPanel, {
1628
1703
  key: index,
1629
1704
  config,
1630
1705
  entities: !!entities ? entities : [],
@@ -1662,14 +1737,14 @@ const LegacyTechDocsHome = () => {
1662
1737
  ]
1663
1738
  }
1664
1739
  ];
1665
- return /* @__PURE__ */ React__default.createElement(TechDocsCustomHome, {
1740
+ return /* @__PURE__ */ React.createElement(TechDocsCustomHome, {
1666
1741
  tabsConfig
1667
1742
  });
1668
1743
  };
1669
1744
 
1670
1745
  const TechDocsIndexPage = () => {
1671
1746
  const outlet = useOutlet();
1672
- return outlet || /* @__PURE__ */ React__default.createElement(LegacyTechDocsHome, null);
1747
+ return outlet || /* @__PURE__ */ React.createElement(LegacyTechDocsHome, null);
1673
1748
  };
1674
1749
 
1675
1750
  var TechDocsIndexPage$1 = /*#__PURE__*/Object.freeze({
@@ -1679,7 +1754,7 @@ var TechDocsIndexPage$1 = /*#__PURE__*/Object.freeze({
1679
1754
 
1680
1755
  const EntityPageDocs = ({entity}) => {
1681
1756
  var _a;
1682
- return /* @__PURE__ */ React__default.createElement(Reader, {
1757
+ return /* @__PURE__ */ React.createElement(Reader, {
1683
1758
  withSearch: false,
1684
1759
  entityRef: {
1685
1760
  kind: entity.kind,
@@ -1695,12 +1770,12 @@ const isTechDocsAvailable = (entity) => {
1695
1770
  return Boolean((_b = (_a = entity == null ? void 0 : entity.metadata) == null ? void 0 : _a.annotations) == null ? void 0 : _b[TECHDOCS_ANNOTATION]);
1696
1771
  };
1697
1772
  const Router = () => {
1698
- return /* @__PURE__ */ React__default.createElement(Routes, null, /* @__PURE__ */ React__default.createElement(Route, {
1773
+ return /* @__PURE__ */ React.createElement(Routes, null, /* @__PURE__ */ React.createElement(Route, {
1699
1774
  path: "/",
1700
- element: /* @__PURE__ */ React__default.createElement(TechDocsIndexPage, null)
1701
- }), /* @__PURE__ */ React__default.createElement(Route, {
1775
+ element: /* @__PURE__ */ React.createElement(TechDocsIndexPage, null)
1776
+ }), /* @__PURE__ */ React.createElement(Route, {
1702
1777
  path: "/:namespace/:kind/:name/*",
1703
- element: /* @__PURE__ */ React__default.createElement(TechDocsPage, null)
1778
+ element: /* @__PURE__ */ React.createElement(TechDocsPage, null)
1704
1779
  }));
1705
1780
  };
1706
1781
  const EmbeddedDocsRouter = (_props) => {
@@ -1708,13 +1783,13 @@ const EmbeddedDocsRouter = (_props) => {
1708
1783
  const {entity} = useEntity();
1709
1784
  const projectId = (_a = entity.metadata.annotations) == null ? void 0 : _a[TECHDOCS_ANNOTATION];
1710
1785
  if (!projectId) {
1711
- return /* @__PURE__ */ React__default.createElement(MissingAnnotationEmptyState, {
1786
+ return /* @__PURE__ */ React.createElement(MissingAnnotationEmptyState, {
1712
1787
  annotation: TECHDOCS_ANNOTATION
1713
1788
  });
1714
1789
  }
1715
- return /* @__PURE__ */ React__default.createElement(Routes, null, /* @__PURE__ */ React__default.createElement(Route, {
1790
+ return /* @__PURE__ */ React.createElement(Routes, null, /* @__PURE__ */ React.createElement(Route, {
1716
1791
  path: "/*",
1717
- element: /* @__PURE__ */ React__default.createElement(EntityPageDocs, {
1792
+ element: /* @__PURE__ */ React.createElement(EntityPageDocs, {
1718
1793
  entity
1719
1794
  })
1720
1795
  }));
@@ -1727,5 +1802,5 @@ var Router$1 = /*#__PURE__*/Object.freeze({
1727
1802
  EmbeddedDocsRouter: EmbeddedDocsRouter
1728
1803
  });
1729
1804
 
1730
- export { DefaultTechDocsHome, DocsCardGrid$2 as DocsCardGrid, DocsResultListItem, DocsTable, EmbeddedDocsRouter, EntityListDocsTable, EntityTechdocsContent, Reader, Router, TechDocsClient, TechDocsCustomHome$2 as TechDocsCustomHome, TechDocsIndexPage$2 as TechDocsIndexPage, TechDocsPage, TechDocsPageHeader, TechDocsPageWrapper, TechDocsPicker, TechDocsReaderPage, TechDocsStorageClient, TechdocsPage, isTechDocsAvailable, techdocsPlugin as plugin, techdocsApiRef, techdocsPlugin, techdocsStorageApiRef };
1805
+ export { DefaultTechDocsHome, DocsCardGrid, DocsResultListItem, DocsTable, EmbeddedDocsRouter, EntityListDocsGrid, EntityListDocsTable, EntityTechdocsContent, Reader, Router, TechDocsClient, TechDocsCustomHome$2 as TechDocsCustomHome, TechDocsIndexPage$2 as TechDocsIndexPage, TechDocsPage, TechDocsPageHeader, TechDocsPageWrapper, TechDocsPicker, TechDocsReaderPage, TechDocsSearch, TechDocsStateIndicator, TechDocsStorageClient, TechdocsPage, isTechDocsAvailable, techdocsPlugin as plugin, techdocsApiRef, techdocsPlugin, techdocsStorageApiRef, useTechDocsReader, useTechDocsReaderDom, withTechDocsReaderProvider };
1731
1806
  //# sourceMappingURL=index.esm.js.map