@backstage/plugin-techdocs 1.1.2-next.1 → 1.2.1-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,74 @@
1
1
  # @backstage/plugin-techdocs
2
2
 
3
+ ## 1.2.1-next.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 726577958f: Remove the 60% factor from the font size calculation of headers to use the exact size defined in BackstageTheme.
8
+ - Updated dependencies
9
+ - @backstage/core-components@0.9.6-next.1
10
+ - @backstage/catalog-model@1.1.0-next.1
11
+ - @backstage/errors@1.1.0-next.0
12
+ - @backstage/theme@0.2.16-next.0
13
+ - @backstage/integration@1.2.2-next.1
14
+ - @backstage/integration-react@1.1.2-next.1
15
+ - @backstage/plugin-catalog-react@1.1.2-next.1
16
+ - @backstage/plugin-search-common@0.3.6-next.0
17
+ - @backstage/plugin-search-react@0.2.2-next.1
18
+
19
+ ## 1.2.1-next.0
20
+
21
+ ### Patch Changes
22
+
23
+ - 3cbebf710e: Reorder browser tab title in Techdocs pages to have the site name first.
24
+ - Updated dependencies
25
+ - @backstage/catalog-model@1.1.0-next.0
26
+ - @backstage/core-components@0.9.6-next.0
27
+ - @backstage/plugin-techdocs-react@1.0.2-next.0
28
+ - @backstage/integration@1.2.2-next.0
29
+ - @backstage/plugin-catalog-react@1.1.2-next.0
30
+ - @backstage/integration-react@1.1.2-next.0
31
+ - @backstage/plugin-search-react@0.2.2-next.0
32
+
33
+ ## 1.2.0
34
+
35
+ ### Minor Changes
36
+
37
+ - fe7614ea54: Add an optional icon to the Catalog and TechDocs search results
38
+
39
+ ### Patch Changes
40
+
41
+ - d047d81295: Use entity title as label in `TechDocsReaderPageHeader` if available
42
+ - 8f7b1835df: Updated dependency `msw` to `^0.41.0`.
43
+ - bff65e6958: Updated sidebar-related logic to use `<SidebarPinStateProvider>` + `useSidebarPinState()` and/or `<SidebarOpenStateProvider>` + `useSidebarOpenState()` from `@backstage/core-components`.
44
+ - 915700f64f: In order to simplify analytics on top of the search experience in Backstage, the provided `<*ResultListItem />` component now captures a `discover` analytics event instead of a `click` event. This event includes the result rank as its `value` and, like a click, the URL/path clicked to as its `to` attribute.
45
+ - 881fbd7e8d: Fix `EntityTechdocsContent` component to use objects instead of `<Route>` elements, otherwise "outlet" will be null on sub-pages and add-ons won't render.
46
+ - 17c059dfd0: Restructures reader style transformations to improve code readability:
47
+
48
+ - Extracts the style rules to separate files;
49
+ - Creates a hook that processes each rule;
50
+ - And creates another hook that returns a transformer responsible for injecting them into the head tag of a given element.
51
+
52
+ - 3b45ad701f: Packages a set of tweaks to the TechDocs addons rendering process:
53
+
54
+ - Prevents displaying sidebars until page styles are loaded and the sidebar position is updated;
55
+ - Prevents new sidebar locations from being created every time the reader page is rendered if these locations already exist;
56
+ - Centers the styles loaded event to avoid having multiple locations setting the opacity style in Shadow Dom causing the screen to flash multiple times.
57
+
58
+ - 9b94ade898: Use entity title in `TechDocsSearch` placeholder if available.
59
+ - 816f7475ec: Convert `sanitizeDOM` transformer to hook as part of code readability improvements in dom file.
60
+ - 50ff56a80f: Change the `EntityDocsPage` path to be more specific and also add integration tests for `sub-routes` on this page.
61
+ - Updated dependencies
62
+ - @backstage/plugin-catalog-react@1.1.1
63
+ - @backstage/plugin-search-common@0.3.5
64
+ - @backstage/plugin-search-react@0.2.1
65
+ - @backstage/core-components@0.9.5
66
+ - @backstage/integration@1.2.1
67
+ - @backstage/core-plugin-api@1.0.3
68
+ - @backstage/integration-react@1.1.1
69
+ - @backstage/catalog-model@1.0.3
70
+ - @backstage/plugin-techdocs-react@1.0.1
71
+
3
72
  ## 1.1.2-next.1
4
73
 
5
74
  ### Patch Changes
@@ -2,7 +2,7 @@ import React, { useState } from 'react';
2
2
  import useAsync from 'react-use/lib/useAsync';
3
3
  import { makeStyles } from '@material-ui/core';
4
4
  import { catalogApiRef, CATALOG_FILTER_EXISTS, useEntityOwnership } from '@backstage/plugin-catalog-react';
5
- import { T as TechDocsPageWrapper, D as DocsTable, a as DocsCardGrid } from './index-a5aa1ac0.esm.js';
5
+ import { T as TechDocsPageWrapper, D as DocsTable, a as DocsCardGrid } from './index-596c5b9c.esm.js';
6
6
  import { Content, Progress, WarningPanel, CodeSnippet, HeaderTabs, ContentHeader, SupportButton } from '@backstage/core-components';
7
7
  import { useApi } from '@backstage/core-plugin-api';
8
8
  import '@backstage/errors';
@@ -130,4 +130,4 @@ const TechDocsCustomHome = (props) => {
130
130
  };
131
131
 
132
132
  export { TechDocsCustomHome };
133
- //# sourceMappingURL=TechDocsCustomHome-38c20d17.esm.js.map
133
+ //# sourceMappingURL=TechDocsCustomHome-7626ac38.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TechDocsCustomHome-38c20d17.esm.js","sources":["../../src/home/components/TechDocsCustomHome.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 */\n\nimport React, { useState } from 'react';\nimport useAsync from 'react-use/lib/useAsync';\nimport { makeStyles } from '@material-ui/core';\nimport { CSSProperties } from '@material-ui/styles';\nimport {\n CATALOG_FILTER_EXISTS,\n catalogApiRef,\n CatalogApi,\n useEntityOwnership,\n} from '@backstage/plugin-catalog-react';\nimport { Entity } from '@backstage/catalog-model';\nimport { DocsTable } from './Tables';\nimport { DocsCardGrid } from './Grids';\nimport { TechDocsPageWrapper } from './TechDocsPageWrapper';\n\nimport {\n CodeSnippet,\n Content,\n HeaderTabs,\n Progress,\n WarningPanel,\n SupportButton,\n ContentHeader,\n} from '@backstage/core-components';\nimport { useApi } from '@backstage/core-plugin-api';\n\nconst panels = {\n DocsTable: DocsTable,\n DocsCardGrid: DocsCardGrid,\n};\n\n/**\n * Available panel types\n *\n * @public\n */\nexport type PanelType = 'DocsCardGrid' | 'DocsTable';\n\n/**\n * Type representing a TechDocsCustomHome panel.\n *\n * @public\n */\nexport interface PanelConfig {\n title: string;\n description: string;\n panelType: PanelType;\n panelCSS?: CSSProperties;\n filterPredicate: ((entity: Entity) => boolean) | string;\n}\n\n/**\n * Type representing a TechDocsCustomHome tab.\n *\n * @public\n */\nexport interface TabConfig {\n label: string;\n panels: PanelConfig[];\n}\n\n/**\n * Type representing a list of TechDocsCustomHome tabs.\n *\n * @public\n */\nexport type TabsConfig = TabConfig[];\n\nconst CustomPanel = ({\n config,\n entities,\n index,\n}: {\n config: PanelConfig;\n entities: Entity[];\n index: number;\n}) => {\n const useStyles = makeStyles({\n panelContainer: {\n marginBottom: '2rem',\n ...(config.panelCSS ? config.panelCSS : {}),\n },\n });\n const classes = useStyles();\n const { loading: loadingOwnership, isOwnedEntity } = useEntityOwnership();\n\n const Panel = panels[config.panelType];\n\n const shownEntities = entities.filter(entity => {\n if (config.filterPredicate === 'ownedByUser') {\n if (loadingOwnership) {\n return false;\n }\n return isOwnedEntity(entity);\n }\n\n return (\n typeof config.filterPredicate === 'function' &&\n config.filterPredicate(entity)\n );\n });\n\n return (\n <>\n <ContentHeader title={config.title} description={config.description}>\n {index === 0 ? (\n <SupportButton>\n Discover documentation in your ecosystem.\n </SupportButton>\n ) : null}\n </ContentHeader>\n <div className={classes.panelContainer}>\n <Panel data-testid=\"techdocs-custom-panel\" entities={shownEntities} />\n </div>\n </>\n );\n};\n\n/**\n * Props for {@link TechDocsCustomHome}\n *\n * @public\n */\nexport type TechDocsCustomHomeProps = {\n tabsConfig: TabsConfig;\n};\n\nexport const TechDocsCustomHome = (props: TechDocsCustomHomeProps) => {\n const { tabsConfig } = props;\n const [selectedTab, setSelectedTab] = useState<number>(0);\n const catalogApi: CatalogApi = useApi(catalogApiRef);\n\n const {\n value: entities,\n loading,\n error,\n } = useAsync(async () => {\n const response = await catalogApi.getEntities({\n filter: {\n 'metadata.annotations.backstage.io/techdocs-ref': CATALOG_FILTER_EXISTS,\n },\n fields: [\n 'apiVersion',\n 'kind',\n 'metadata',\n 'relations',\n 'spec.owner',\n 'spec.type',\n ],\n });\n return response.items.filter((entity: Entity) => {\n return !!entity.metadata.annotations?.['backstage.io/techdocs-ref'];\n });\n });\n\n const currentTabConfig = tabsConfig[selectedTab];\n\n if (loading) {\n return (\n <TechDocsPageWrapper>\n <Content>\n <Progress />\n </Content>\n </TechDocsPageWrapper>\n );\n }\n\n if (error) {\n return (\n <TechDocsPageWrapper>\n <Content>\n <WarningPanel\n severity=\"error\"\n title=\"Could not load available documentation.\"\n >\n <CodeSnippet language=\"text\" text={error.toString()} />\n </WarningPanel>\n </Content>\n </TechDocsPageWrapper>\n );\n }\n\n return (\n <TechDocsPageWrapper>\n <HeaderTabs\n selectedIndex={selectedTab}\n onChange={index => setSelectedTab(index)}\n tabs={tabsConfig.map(({ label }, index) => ({\n id: index.toString(),\n label,\n }))}\n />\n <Content data-testid=\"techdocs-content\">\n {currentTabConfig.panels.map((config, index) => (\n <CustomPanel\n key={index}\n config={config}\n entities={!!entities ? entities : []}\n index={index}\n />\n ))}\n </Content>\n </TechDocsPageWrapper>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TechDocsCustomHome-7626ac38.esm.js","sources":["../../src/home/components/TechDocsCustomHome.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 */\n\nimport React, { useState } from 'react';\nimport useAsync from 'react-use/lib/useAsync';\nimport { makeStyles } from '@material-ui/core';\nimport { CSSProperties } from '@material-ui/styles';\nimport {\n CATALOG_FILTER_EXISTS,\n catalogApiRef,\n CatalogApi,\n useEntityOwnership,\n} from '@backstage/plugin-catalog-react';\nimport { Entity } from '@backstage/catalog-model';\nimport { DocsTable } from './Tables';\nimport { DocsCardGrid } from './Grids';\nimport { TechDocsPageWrapper } from './TechDocsPageWrapper';\n\nimport {\n CodeSnippet,\n Content,\n HeaderTabs,\n Progress,\n WarningPanel,\n SupportButton,\n ContentHeader,\n} from '@backstage/core-components';\nimport { useApi } from '@backstage/core-plugin-api';\n\nconst panels = {\n DocsTable: DocsTable,\n DocsCardGrid: DocsCardGrid,\n};\n\n/**\n * Available panel types\n *\n * @public\n */\nexport type PanelType = 'DocsCardGrid' | 'DocsTable';\n\n/**\n * Type representing a TechDocsCustomHome panel.\n *\n * @public\n */\nexport interface PanelConfig {\n title: string;\n description: string;\n panelType: PanelType;\n panelCSS?: CSSProperties;\n filterPredicate: ((entity: Entity) => boolean) | string;\n}\n\n/**\n * Type representing a TechDocsCustomHome tab.\n *\n * @public\n */\nexport interface TabConfig {\n label: string;\n panels: PanelConfig[];\n}\n\n/**\n * Type representing a list of TechDocsCustomHome tabs.\n *\n * @public\n */\nexport type TabsConfig = TabConfig[];\n\nconst CustomPanel = ({\n config,\n entities,\n index,\n}: {\n config: PanelConfig;\n entities: Entity[];\n index: number;\n}) => {\n const useStyles = makeStyles({\n panelContainer: {\n marginBottom: '2rem',\n ...(config.panelCSS ? config.panelCSS : {}),\n },\n });\n const classes = useStyles();\n const { loading: loadingOwnership, isOwnedEntity } = useEntityOwnership();\n\n const Panel = panels[config.panelType];\n\n const shownEntities = entities.filter(entity => {\n if (config.filterPredicate === 'ownedByUser') {\n if (loadingOwnership) {\n return false;\n }\n return isOwnedEntity(entity);\n }\n\n return (\n typeof config.filterPredicate === 'function' &&\n config.filterPredicate(entity)\n );\n });\n\n return (\n <>\n <ContentHeader title={config.title} description={config.description}>\n {index === 0 ? (\n <SupportButton>\n Discover documentation in your ecosystem.\n </SupportButton>\n ) : null}\n </ContentHeader>\n <div className={classes.panelContainer}>\n <Panel data-testid=\"techdocs-custom-panel\" entities={shownEntities} />\n </div>\n </>\n );\n};\n\n/**\n * Props for {@link TechDocsCustomHome}\n *\n * @public\n */\nexport type TechDocsCustomHomeProps = {\n tabsConfig: TabsConfig;\n};\n\nexport const TechDocsCustomHome = (props: TechDocsCustomHomeProps) => {\n const { tabsConfig } = props;\n const [selectedTab, setSelectedTab] = useState<number>(0);\n const catalogApi: CatalogApi = useApi(catalogApiRef);\n\n const {\n value: entities,\n loading,\n error,\n } = useAsync(async () => {\n const response = await catalogApi.getEntities({\n filter: {\n 'metadata.annotations.backstage.io/techdocs-ref': CATALOG_FILTER_EXISTS,\n },\n fields: [\n 'apiVersion',\n 'kind',\n 'metadata',\n 'relations',\n 'spec.owner',\n 'spec.type',\n ],\n });\n return response.items.filter((entity: Entity) => {\n return !!entity.metadata.annotations?.['backstage.io/techdocs-ref'];\n });\n });\n\n const currentTabConfig = tabsConfig[selectedTab];\n\n if (loading) {\n return (\n <TechDocsPageWrapper>\n <Content>\n <Progress />\n </Content>\n </TechDocsPageWrapper>\n );\n }\n\n if (error) {\n return (\n <TechDocsPageWrapper>\n <Content>\n <WarningPanel\n severity=\"error\"\n title=\"Could not load available documentation.\"\n >\n <CodeSnippet language=\"text\" text={error.toString()} />\n </WarningPanel>\n </Content>\n </TechDocsPageWrapper>\n );\n }\n\n return (\n <TechDocsPageWrapper>\n <HeaderTabs\n selectedIndex={selectedTab}\n onChange={index => setSelectedTab(index)}\n tabs={tabsConfig.map(({ label }, index) => ({\n id: index.toString(),\n label,\n }))}\n />\n <Content data-testid=\"techdocs-content\">\n {currentTabConfig.panels.map((config, index) => (\n <CustomPanel\n key={index}\n config={config}\n entities={!!entities ? entities : []}\n index={index}\n />\n ))}\n </Content>\n </TechDocsPageWrapper>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { createApiRef, useApi, configApiRef, createRouteRef, useRouteRef, createPlugin, createApiFactory, discoveryApiRef, identityApiRef, fetchApiRef, createRoutableExtension } from '@backstage/core-plugin-api';
1
+ import { createApiRef, useApi, useAnalytics, configApiRef, createRouteRef, useRouteRef, createPlugin, createApiFactory, discoveryApiRef, identityApiRef, fetchApiRef, createRoutableExtension } from '@backstage/core-plugin-api';
2
2
  import { ResponseError, NotFoundError } from '@backstage/errors';
3
3
  import { EventSourcePolyfill } from 'event-source-polyfill';
4
4
  import React, { useReducer, useRef, useMemo, createContext, useContext, useState, useEffect, useCallback, Children } from 'react';
@@ -7,7 +7,7 @@ import { techdocsStorageApiRef as techdocsStorageApiRef$1, useTechDocsReaderPage
7
7
  import useAsync from 'react-use/lib/useAsync';
8
8
  import useAsyncRetry from 'react-use/lib/useAsyncRetry';
9
9
  import { Link, LogViewer, ErrorPage, useSidebarPinState, Content, HeaderLabel, Header, Page, ItemCardGrid, ItemCardHeader, Button as Button$1, WarningPanel, CodeSnippet, Progress, SubvalueCell, Table, EmptyState, PageWithHeader, ContentHeader, SupportButton, MissingAnnotationEmptyState } from '@backstage/core-components';
10
- import { makeStyles, ListItemText, ListItem, Divider, TextField, InputAdornment, IconButton, CircularProgress, createStyles, Button, Drawer, Grid, Typography, lighten, alpha, useTheme, withStyles, Tooltip, ThemeProvider, SvgIcon, useMediaQuery, Portal, Toolbar, Box, Menu, Card, CardMedia, CardContent, CardActions } from '@material-ui/core';
10
+ import { makeStyles, ListItemText, ListItem, ListItemIcon, Divider, TextField, InputAdornment, IconButton, CircularProgress, createStyles, Button, Drawer, Grid, Typography, lighten, alpha, useTheme, withStyles, Tooltip, ThemeProvider, SvgIcon, useMediaQuery, Portal, Toolbar, Box, Menu, Card, CardMedia, CardContent, CardActions } from '@material-ui/core';
11
11
  import { HighlightedSearchResultText, SearchContextProvider, useSearch } from '@backstage/plugin-search-react';
12
12
  import SearchIcon from '@material-ui/icons/Search';
13
13
  import Autocomplete from '@material-ui/lab/Autocomplete';
@@ -327,12 +327,21 @@ const TechDocsSearchResultListItem = (props) => {
327
327
  const {
328
328
  result,
329
329
  highlight,
330
+ rank,
330
331
  lineClamp = 5,
331
332
  asListItem = true,
332
333
  asLink = true,
333
- title
334
+ title,
335
+ icon
334
336
  } = props;
335
337
  const classes = useStyles$4();
338
+ const analytics = useAnalytics();
339
+ const handleClick = () => {
340
+ analytics.captureEvent("discover", result.title, {
341
+ attributes: { to: result.location },
342
+ value: rank
343
+ });
344
+ };
336
345
  const TextItem = () => {
337
346
  const resultTitle = (highlight == null ? void 0 : highlight.fields.title) ? /* @__PURE__ */ React.createElement(HighlightedSearchResultText, {
338
347
  text: highlight.fields.title,
@@ -368,12 +377,15 @@ const TechDocsSearchResultListItem = (props) => {
368
377
  });
369
378
  };
370
379
  const LinkWrapper = ({ children }) => asLink ? /* @__PURE__ */ React.createElement(Link, {
371
- to: result.location
380
+ noTrack: true,
381
+ to: result.location,
382
+ onClick: handleClick
372
383
  }, children) : /* @__PURE__ */ React.createElement(React.Fragment, null, children);
373
384
  const ListItemWrapper = ({ children }) => asListItem ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ListItem, {
374
- alignItems: "flex-start",
385
+ alignItems: "flex-start"
386
+ }, icon && /* @__PURE__ */ React.createElement(ListItemIcon, null, icon), /* @__PURE__ */ React.createElement("div", {
375
387
  className: classes.flexContainer
376
- }, children), /* @__PURE__ */ React.createElement(Divider, {
388
+ }, children)), /* @__PURE__ */ React.createElement(Divider, {
377
389
  component: "li"
378
390
  })) : /* @__PURE__ */ React.createElement(React.Fragment, null, children);
379
391
  return /* @__PURE__ */ React.createElement(LinkWrapper, null, /* @__PURE__ */ React.createElement(ListItemWrapper, null, /* @__PURE__ */ React.createElement(TextItem, null)));
@@ -385,7 +397,7 @@ const useStyles$3 = makeStyles({
385
397
  }
386
398
  });
387
399
  const TechDocsSearchBar = (props) => {
388
- const { entityId, debounceTime = 150 } = props;
400
+ const { entityId, entityTitle, debounceTime = 150 } = props;
389
401
  const [open, setOpen] = useState(false);
390
402
  const navigate = useNavigate();
391
403
  const {
@@ -465,7 +477,7 @@ const TechDocsSearchBar = (props) => {
465
477
  "data-testid": "techdocs-search-bar-input",
466
478
  variant: "outlined",
467
479
  fullWidth: true,
468
- placeholder: `Search ${entityId.name} docs`,
480
+ placeholder: `Search ${entityTitle || entityId.name} docs`,
469
481
  value,
470
482
  onChange: handleQuery,
471
483
  InputProps: {
@@ -1041,12 +1053,14 @@ var typeset = ({ theme }) => `
1041
1053
  }
1042
1054
 
1043
1055
  ${headings.reduce((style, heading) => {
1056
+ var _a;
1057
+ const htmlFontSize = (_a = theme.typography.htmlFontSize) != null ? _a : 16;
1044
1058
  const styles = theme.typography[heading];
1045
1059
  const { lineHeight, fontFamily, fontWeight, fontSize } = styles;
1046
1060
  const calculate = (value) => {
1047
1061
  let factor = 1;
1048
1062
  if (typeof value === "number") {
1049
- factor = value / 16 * 0.6;
1063
+ factor = value / htmlFontSize;
1050
1064
  }
1051
1065
  if (typeof value === "string") {
1052
1066
  factor = value.replace("rem", "");
@@ -1669,6 +1683,7 @@ const useStyles$1 = makeStyles({
1669
1683
  }
1670
1684
  });
1671
1685
  const TechDocsReaderPageContent = withTechDocsReaderProvider((props) => {
1686
+ var _a;
1672
1687
  const { withSearch = true, onReady } = props;
1673
1688
  const classes = useStyles$1();
1674
1689
  const {
@@ -1706,7 +1721,8 @@ const TechDocsReaderPageContent = withTechDocsReaderProvider((props) => {
1706
1721
  xs: "auto",
1707
1722
  item: true
1708
1723
  }, /* @__PURE__ */ React.createElement(TechDocsSearch, {
1709
- entityId: entityRef
1724
+ entityId: entityRef,
1725
+ entityTitle: (_a = entityMetadata == null ? void 0 : entityMetadata.metadata) == null ? void 0 : _a.title
1710
1726
  })), /* @__PURE__ */ React.createElement(Grid, {
1711
1727
  xs: 12,
1712
1728
  item: true
@@ -1762,7 +1778,7 @@ const TechDocsReaderPageHeader = (props) => {
1762
1778
  });
1763
1779
  }, [metadata, setTitle, setSubtitle]);
1764
1780
  const appTitle = configApi.getOptional("app.title") || "Backstage";
1765
- const tabTitle = [subtitle, title, appTitle].filter(Boolean).join(" | ");
1781
+ const tabTitle = [title, subtitle, appTitle].filter(Boolean).join(" | ");
1766
1782
  const { locationMetadata, spec } = entityMetadata || {};
1767
1783
  const lifecycle = spec == null ? void 0 : spec.lifecycle;
1768
1784
  const ownedByRelations = entityMetadata ? getEntityRelations(entityMetadata, RELATION_OWNED_BY) : [];
@@ -1772,6 +1788,7 @@ const TechDocsReaderPageHeader = (props) => {
1772
1788
  value: /* @__PURE__ */ React.createElement(EntityRefLink, {
1773
1789
  color: "inherit",
1774
1790
  entityRef,
1791
+ title: entityMetadata == null ? void 0 : entityMetadata.metadata.title,
1775
1792
  defaultKind: "Component"
1776
1793
  })
1777
1794
  }), ownedByRelations.length > 0 && /* @__PURE__ */ React.createElement(HeaderLabel, {
@@ -2196,7 +2213,7 @@ const EntityTechdocsContent = techdocsPlugin.provide(createRoutableExtension({
2196
2213
  }));
2197
2214
  const TechDocsCustomHome = techdocsPlugin.provide(createRoutableExtension({
2198
2215
  name: "TechDocsCustomHome",
2199
- component: () => import('./TechDocsCustomHome-38c20d17.esm.js').then((m) => m.TechDocsCustomHome),
2216
+ component: () => import('./TechDocsCustomHome-7626ac38.esm.js').then((m) => m.TechDocsCustomHome),
2200
2217
  mountPoint: rootRouteRef
2201
2218
  }));
2202
2219
  const TechDocsIndexPage$2 = techdocsPlugin.provide(createRoutableExtension({
@@ -2206,7 +2223,7 @@ const TechDocsIndexPage$2 = techdocsPlugin.provide(createRoutableExtension({
2206
2223
  }));
2207
2224
  const TechDocsReaderPage = techdocsPlugin.provide(createRoutableExtension({
2208
2225
  name: "TechDocsReaderPage",
2209
- component: () => import('./index-779d10dc.esm.js').then((m) => m.TechDocsReaderPage),
2226
+ component: () => import('./index-5f094544.esm.js').then((m) => m.TechDocsReaderPage),
2210
2227
  mountPoint: rootDocsRouteRef
2211
2228
  }));
2212
2229
 
@@ -2278,4 +2295,4 @@ var Router$1 = /*#__PURE__*/Object.freeze({
2278
2295
  });
2279
2296
 
2280
2297
  export { DocsTable as D, EntityTechdocsContent as E, Reader as R, TechDocsPageWrapper as T, DocsCardGrid as a, TechDocsReaderPage$1 as b, TechDocsReaderLayout as c, TechDocsCustomHome as d, TechDocsIndexPage$2 as e, TechdocsPage as f, TechDocsReaderPage as g, techdocsStorageApiRef as h, techdocsApiRef as i, TechDocsClient as j, TechDocsStorageClient as k, TechDocsReaderProvider as l, TechDocsReaderPageHeader as m, TechDocsReaderPageContent as n, TechDocsReaderPageSubheader as o, TechDocsSearchResultListItem as p, TechDocsSearch as q, EntityListDocsGrid as r, EntityListDocsTable as s, techdocsPlugin as t, DefaultTechDocsHome as u, TechDocsPicker as v, isTechDocsAvailable as w, Router as x, EmbeddedDocsRouter as y };
2281
- //# sourceMappingURL=index-a5aa1ac0.esm.js.map
2298
+ //# sourceMappingURL=index-596c5b9c.esm.js.map