@backstage/plugin-techdocs 1.17.1-next.2 → 1.17.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/dist/alpha/components/TechDocsIndexPageContent.esm.js +36 -0
- package/dist/alpha/components/TechDocsIndexPageContent.esm.js.map +1 -0
- package/dist/alpha/components/TechDocsReaderContent.esm.js +35 -0
- package/dist/alpha/components/TechDocsReaderContent.esm.js.map +1 -0
- package/dist/alpha/components/TechDocsReaderEntityCard.esm.js +59 -0
- package/dist/alpha/components/TechDocsReaderEntityCard.esm.js.map +1 -0
- package/dist/alpha/components/TechDocsReaderEntityCard.module.css.esm.js +8 -0
- package/dist/alpha/components/TechDocsReaderEntityCard.module.css.esm.js.map +1 -0
- package/dist/alpha/components/TechDocsReaderHeader.esm.js +49 -0
- package/dist/alpha/components/TechDocsReaderHeader.esm.js.map +1 -0
- package/dist/alpha/components/TechDocsReaderLayout.esm.js +21 -0
- package/dist/alpha/components/TechDocsReaderLayout.esm.js.map +1 -0
- package/dist/alpha/components/TechDocsReaderSearch.esm.js +82 -0
- package/dist/alpha/components/TechDocsReaderSearch.esm.js.map +1 -0
- package/dist/alpha.d.ts +13 -0
- package/dist/alpha.esm.js +15 -20
- package/dist/alpha.esm.js.map +1 -1
- package/dist/hooks/useTechDocsReaderContentData.esm.js +63 -0
- package/dist/hooks/useTechDocsReaderContentData.esm.js.map +1 -0
- package/dist/hooks/useTechDocsReaderHeaderData.esm.js +70 -0
- package/dist/hooks/useTechDocsReaderHeaderData.esm.js.map +1 -0
- package/dist/hooks/useTechDocsSearch.esm.js +46 -0
- package/dist/hooks/useTechDocsSearch.esm.js.map +1 -0
- package/dist/node_modules_dist/style-inject/dist/style-inject.es.esm.js +29 -0
- package/dist/node_modules_dist/style-inject/dist/style-inject.es.esm.js.map +1 -0
- package/dist/{package.json.esm.js → plugins/techdocs/package.json.esm.js} +3 -1
- package/dist/{package.json.esm.js.map → plugins/techdocs/package.json.esm.js.map} +1 -1
- package/dist/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContent.esm.js +18 -40
- package/dist/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContent.esm.js.map +1 -1
- package/dist/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.esm.js +17 -43
- package/dist/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.esm.js.map +1 -1
- package/dist/search/components/TechDocsSearch.esm.js +5 -30
- package/dist/search/components/TechDocsSearch.esm.js.map +1 -1
- package/package.json +25 -23
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { useEffect, useCallback } from 'react';
|
|
2
|
+
import { useLocation } from 'react-router-dom';
|
|
3
|
+
import { useTechDocsReaderPage, useShadowDomStylesLoading, useShadowRootElements } from '@backstage/plugin-techdocs-react';
|
|
4
|
+
import { useApp } from '@backstage/core-plugin-api';
|
|
5
|
+
import { useTechDocsReaderDom } from '../reader/components/TechDocsReaderPageContent/dom.esm.js';
|
|
6
|
+
import { useTechDocsReader } from '../reader/components/TechDocsReaderProvider.esm.js';
|
|
7
|
+
|
|
8
|
+
function useTechDocsReaderContentData(options) {
|
|
9
|
+
const { defaultPath, onReady } = options;
|
|
10
|
+
const {
|
|
11
|
+
entityMetadata: { value: entityMetadata, loading: entityMetadataLoading },
|
|
12
|
+
entityRef,
|
|
13
|
+
setShadowRoot
|
|
14
|
+
} = useTechDocsReaderPage();
|
|
15
|
+
const { state } = useTechDocsReader();
|
|
16
|
+
const dom = useTechDocsReaderDom(entityRef, defaultPath);
|
|
17
|
+
const location = useLocation();
|
|
18
|
+
const path = location.pathname;
|
|
19
|
+
const hash = location.hash;
|
|
20
|
+
const isStyleLoading = useShadowDomStylesLoading(dom);
|
|
21
|
+
const [hashElement] = useShadowRootElements([`[id="${hash.slice(1)}"]`]);
|
|
22
|
+
const app = useApp();
|
|
23
|
+
const { NotFoundErrorPage } = app.getComponents();
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
if (isStyleLoading) return;
|
|
26
|
+
if (hash) {
|
|
27
|
+
if (hashElement) {
|
|
28
|
+
hashElement.scrollIntoView();
|
|
29
|
+
const link = hashElement.querySelector("a.headerlink");
|
|
30
|
+
if (link) {
|
|
31
|
+
link.focus();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
} else {
|
|
35
|
+
document?.querySelector("header")?.scrollIntoView();
|
|
36
|
+
}
|
|
37
|
+
}, [path, hash, hashElement, isStyleLoading]);
|
|
38
|
+
const handleAppend = useCallback(
|
|
39
|
+
(newShadowRoot) => {
|
|
40
|
+
setShadowRoot(newShadowRoot);
|
|
41
|
+
if (onReady instanceof Function) {
|
|
42
|
+
onReady();
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
[setShadowRoot, onReady]
|
|
46
|
+
);
|
|
47
|
+
const isNotFound = entityMetadataLoading === false && !entityMetadata;
|
|
48
|
+
const isDomReady = !!dom;
|
|
49
|
+
const showProgress = state === "CHECKING" || isStyleLoading;
|
|
50
|
+
return {
|
|
51
|
+
entityRef,
|
|
52
|
+
entityMetadata,
|
|
53
|
+
dom,
|
|
54
|
+
handleAppend,
|
|
55
|
+
isNotFound,
|
|
56
|
+
isDomReady,
|
|
57
|
+
showProgress,
|
|
58
|
+
NotFoundErrorPage
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export { useTechDocsReaderContentData };
|
|
63
|
+
//# sourceMappingURL=useTechDocsReaderContentData.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTechDocsReaderContentData.esm.js","sources":["../../src/hooks/useTechDocsReaderContentData.ts"],"sourcesContent":["/*\n * Copyright 2026 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 { useCallback, useEffect } from 'react';\nimport { useLocation } from 'react-router-dom';\nimport {\n useShadowDomStylesLoading,\n useShadowRootElements,\n useTechDocsReaderPage,\n} from '@backstage/plugin-techdocs-react';\nimport { useApp } from '@backstage/core-plugin-api';\nimport { useTechDocsReaderDom } from '../reader/components/TechDocsReaderPageContent/dom';\nimport { useTechDocsReader } from '../reader/components/TechDocsReaderProvider';\n\n/**\n * Shared hook for TechDocs reader content data.\n * Encapsulates DOM setup, hash scrolling, shadow root handling,\n * 404 detection, and loading state.\n */\nexport function useTechDocsReaderContentData(options: {\n defaultPath?: string;\n onReady?: () => void;\n}) {\n const { defaultPath, onReady } = options;\n\n const {\n entityMetadata: { value: entityMetadata, loading: entityMetadataLoading },\n entityRef,\n setShadowRoot,\n } = useTechDocsReaderPage();\n const { state } = useTechDocsReader();\n const dom = useTechDocsReaderDom(entityRef, defaultPath);\n const location = useLocation();\n const path = location.pathname;\n const hash = location.hash;\n const isStyleLoading = useShadowDomStylesLoading(dom);\n const [hashElement] = useShadowRootElements([`[id=\"${hash.slice(1)}\"]`]);\n const app = useApp();\n const { NotFoundErrorPage } = app.getComponents();\n\n useEffect(() => {\n if (isStyleLoading) return;\n\n if (hash) {\n if (hashElement) {\n hashElement.scrollIntoView();\n const link = hashElement.querySelector<HTMLElement>('a.headerlink');\n if (link) {\n link.focus();\n }\n }\n } else {\n document?.querySelector('header')?.scrollIntoView();\n }\n }, [path, hash, hashElement, isStyleLoading]);\n\n const handleAppend = useCallback(\n (newShadowRoot: ShadowRoot) => {\n setShadowRoot(newShadowRoot);\n if (onReady instanceof Function) {\n onReady();\n }\n },\n [setShadowRoot, onReady],\n );\n\n const isNotFound = entityMetadataLoading === false && !entityMetadata;\n const isDomReady = !!dom;\n const showProgress = state === 'CHECKING' || isStyleLoading;\n\n return {\n entityRef,\n entityMetadata,\n dom,\n handleAppend,\n isNotFound,\n isDomReady,\n showProgress,\n NotFoundErrorPage,\n };\n}\n"],"names":[],"mappings":";;;;;;;AAgCO,SAAS,6BAA6B,OAAA,EAG1C;AACD,EAAA,MAAM,EAAE,WAAA,EAAa,OAAA,EAAQ,GAAI,OAAA;AAEjC,EAAA,MAAM;AAAA,IACJ,cAAA,EAAgB,EAAE,KAAA,EAAO,cAAA,EAAgB,SAAS,qBAAA,EAAsB;AAAA,IACxE,SAAA;AAAA,IACA;AAAA,MACE,qBAAA,EAAsB;AAC1B,EAAA,MAAM,EAAE,KAAA,EAAM,GAAI,iBAAA,EAAkB;AACpC,EAAA,MAAM,GAAA,GAAM,oBAAA,CAAqB,SAAA,EAAW,WAAW,CAAA;AACvD,EAAA,MAAM,WAAW,WAAA,EAAY;AAC7B,EAAA,MAAM,OAAO,QAAA,CAAS,QAAA;AACtB,EAAA,MAAM,OAAO,QAAA,CAAS,IAAA;AACtB,EAAA,MAAM,cAAA,GAAiB,0BAA0B,GAAG,CAAA;AACpD,EAAA,MAAM,CAAC,WAAW,CAAA,GAAI,qBAAA,CAAsB,CAAC,CAAA,KAAA,EAAQ,IAAA,CAAK,KAAA,CAAM,CAAC,CAAC,CAAA,EAAA,CAAI,CAAC,CAAA;AACvE,EAAA,MAAM,MAAM,MAAA,EAAO;AACnB,EAAA,MAAM,EAAE,iBAAA,EAAkB,GAAI,GAAA,CAAI,aAAA,EAAc;AAEhD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,cAAA,EAAgB;AAEpB,IAAA,IAAI,IAAA,EAAM;AACR,MAAA,IAAI,WAAA,EAAa;AACf,QAAA,WAAA,CAAY,cAAA,EAAe;AAC3B,QAAA,MAAM,IAAA,GAAO,WAAA,CAAY,aAAA,CAA2B,cAAc,CAAA;AAClE,QAAA,IAAI,IAAA,EAAM;AACR,UAAA,IAAA,CAAK,KAAA,EAAM;AAAA,QACb;AAAA,MACF;AAAA,IACF,CAAA,MAAO;AACL,MAAA,QAAA,EAAU,aAAA,CAAc,QAAQ,CAAA,EAAG,cAAA,EAAe;AAAA,IACpD;AAAA,EACF,GAAG,CAAC,IAAA,EAAM,IAAA,EAAM,WAAA,EAAa,cAAc,CAAC,CAAA;AAE5C,EAAA,MAAM,YAAA,GAAe,WAAA;AAAA,IACnB,CAAC,aAAA,KAA8B;AAC7B,MAAA,aAAA,CAAc,aAAa,CAAA;AAC3B,MAAA,IAAI,mBAAmB,QAAA,EAAU;AAC/B,QAAA,OAAA,EAAQ;AAAA,MACV;AAAA,IACF,CAAA;AAAA,IACA,CAAC,eAAe,OAAO;AAAA,GACzB;AAEA,EAAA,MAAM,UAAA,GAAa,qBAAA,KAA0B,KAAA,IAAS,CAAC,cAAA;AACvD,EAAA,MAAM,UAAA,GAAa,CAAC,CAAC,GAAA;AACrB,EAAA,MAAM,YAAA,GAAe,UAAU,UAAA,IAAc,cAAA;AAE7C,EAAA,OAAO;AAAA,IACL,SAAA;AAAA,IACA,cAAA;AAAA,IACA,GAAA;AAAA,IACA,YAAA;AAAA,IACA,UAAA;AAAA,IACA,UAAA;AAAA,IACA,YAAA;AAAA,IACA;AAAA,GACF;AACF;;;;"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import { useParams } from 'react-router-dom';
|
|
3
|
+
import { stringifyEntityRef } from '@backstage/catalog-model';
|
|
4
|
+
import { useApi, configApiRef } from '@backstage/core-plugin-api';
|
|
5
|
+
import { useTechDocsAddons, useTechDocsReaderPage } from '@backstage/plugin-techdocs-react';
|
|
6
|
+
import { entityPresentationApiRef } from '@backstage/plugin-catalog-react';
|
|
7
|
+
import capitalize from 'lodash/capitalize';
|
|
8
|
+
|
|
9
|
+
function useTechDocsReaderHeaderData() {
|
|
10
|
+
const addons = useTechDocsAddons();
|
|
11
|
+
const configApi = useApi(configApiRef);
|
|
12
|
+
const entityPresentationApi = useApi(entityPresentationApiRef);
|
|
13
|
+
const { "*": path = "" } = useParams();
|
|
14
|
+
const {
|
|
15
|
+
title,
|
|
16
|
+
setTitle,
|
|
17
|
+
subtitle,
|
|
18
|
+
setSubtitle,
|
|
19
|
+
entityRef,
|
|
20
|
+
metadata: { value: metadata, loading: metadataLoading },
|
|
21
|
+
entityMetadata: { value: entityMetadata, loading: entityMetadataLoading }
|
|
22
|
+
} = useTechDocsReaderPage();
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
if (!metadata) return;
|
|
25
|
+
setTitle(metadata.site_name);
|
|
26
|
+
setSubtitle(() => {
|
|
27
|
+
let { site_description } = metadata;
|
|
28
|
+
if (!site_description || site_description === "None") {
|
|
29
|
+
site_description = "";
|
|
30
|
+
}
|
|
31
|
+
return site_description;
|
|
32
|
+
});
|
|
33
|
+
}, [metadata, setTitle, setSubtitle]);
|
|
34
|
+
const appTitle = configApi.getOptionalString("app.title") || "Backstage";
|
|
35
|
+
const locationMetadata = entityMetadata?.locationMetadata;
|
|
36
|
+
const showSourceLink = !!locationMetadata && locationMetadata.type !== "dir" && locationMetadata.type !== "file";
|
|
37
|
+
const noEntMetadata = !entityMetadataLoading && entityMetadata === void 0;
|
|
38
|
+
const noTdMetadata = !metadataLoading && metadata === void 0;
|
|
39
|
+
const hidden = noEntMetadata || noTdMetadata;
|
|
40
|
+
const removeTrailingSlash = (str) => str.replace(/\/$/, "");
|
|
41
|
+
const normalizeAndSpace = (str) => str.replace(/[-_]/g, " ").split(" ").map(capitalize).join(" ");
|
|
42
|
+
let tabTitle = appTitle;
|
|
43
|
+
if (!hidden) {
|
|
44
|
+
const stringEntityRef = stringifyEntityRef(entityRef);
|
|
45
|
+
const entityDisplayName = entityPresentationApi.forEntity(stringEntityRef).snapshot.primaryTitle;
|
|
46
|
+
let techdocsTabTitleItems = [];
|
|
47
|
+
if (path !== "")
|
|
48
|
+
techdocsTabTitleItems = removeTrailingSlash(path).split("/").map(normalizeAndSpace);
|
|
49
|
+
const tabTitleItems = [
|
|
50
|
+
entityDisplayName,
|
|
51
|
+
...techdocsTabTitleItems,
|
|
52
|
+
appTitle
|
|
53
|
+
];
|
|
54
|
+
tabTitle = tabTitleItems.join(" | ");
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
title,
|
|
58
|
+
subtitle,
|
|
59
|
+
entityRef,
|
|
60
|
+
entityMetadata,
|
|
61
|
+
tabTitle,
|
|
62
|
+
hidden,
|
|
63
|
+
showSourceLink,
|
|
64
|
+
sourceLink: locationMetadata?.target,
|
|
65
|
+
addons
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export { useTechDocsReaderHeaderData };
|
|
70
|
+
//# sourceMappingURL=useTechDocsReaderHeaderData.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTechDocsReaderHeaderData.esm.js","sources":["../../src/hooks/useTechDocsReaderHeaderData.ts"],"sourcesContent":["/*\n * Copyright 2026 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useEffect } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { stringifyEntityRef } from '@backstage/catalog-model';\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport {\n useTechDocsAddons,\n useTechDocsReaderPage,\n} from '@backstage/plugin-techdocs-react';\nimport { entityPresentationApiRef } from '@backstage/plugin-catalog-react';\nimport capitalize from 'lodash/capitalize';\n\n/**\n * Shared hook for TechDocs reader header data.\n * Encapsulates title/subtitle sync, tab title computation,\n * 404 detection, and source link visibility.\n */\nexport function useTechDocsReaderHeaderData() {\n const addons = useTechDocsAddons();\n const configApi = useApi(configApiRef);\n const entityPresentationApi = useApi(entityPresentationApiRef);\n const { '*': path = '' } = useParams();\n\n const {\n title,\n setTitle,\n subtitle,\n setSubtitle,\n entityRef,\n metadata: { value: metadata, loading: metadataLoading },\n entityMetadata: { value: entityMetadata, loading: entityMetadataLoading },\n } = useTechDocsReaderPage();\n\n useEffect(() => {\n if (!metadata) return;\n setTitle(metadata.site_name);\n setSubtitle(() => {\n let { site_description } = metadata;\n if (!site_description || site_description === 'None') {\n site_description = '';\n }\n return site_description;\n });\n }, [metadata, setTitle, setSubtitle]);\n\n const appTitle = configApi.getOptionalString('app.title') || 'Backstage';\n const locationMetadata = entityMetadata?.locationMetadata;\n const showSourceLink =\n !!locationMetadata &&\n locationMetadata.type !== 'dir' &&\n locationMetadata.type !== 'file';\n\n const noEntMetadata = !entityMetadataLoading && entityMetadata === undefined;\n const noTdMetadata = !metadataLoading && metadata === undefined;\n const hidden = noEntMetadata || noTdMetadata;\n\n const removeTrailingSlash = (str: string) => str.replace(/\\/$/, '');\n const normalizeAndSpace = (str: string) =>\n str.replace(/[-_]/g, ' ').split(' ').map(capitalize).join(' ');\n\n let tabTitle = appTitle;\n if (!hidden) {\n const stringEntityRef = stringifyEntityRef(entityRef);\n const entityDisplayName =\n entityPresentationApi.forEntity(stringEntityRef).snapshot.primaryTitle;\n\n let techdocsTabTitleItems: string[] = [];\n if (path !== '')\n techdocsTabTitleItems = removeTrailingSlash(path)\n .split('/')\n .map(normalizeAndSpace);\n\n const tabTitleItems = [\n entityDisplayName,\n ...techdocsTabTitleItems,\n appTitle,\n ];\n tabTitle = tabTitleItems.join(' | ');\n }\n\n return {\n title,\n subtitle,\n entityRef,\n entityMetadata,\n tabTitle,\n hidden,\n showSourceLink,\n sourceLink: locationMetadata?.target,\n addons,\n };\n}\n"],"names":[],"mappings":";;;;;;;;AAgCO,SAAS,2BAAA,GAA8B;AAC5C,EAAA,MAAM,SAAS,iBAAA,EAAkB;AACjC,EAAA,MAAM,SAAA,GAAY,OAAO,YAAY,CAAA;AACrC,EAAA,MAAM,qBAAA,GAAwB,OAAO,wBAAwB,CAAA;AAC7D,EAAA,MAAM,EAAE,GAAA,EAAK,IAAA,GAAO,EAAA,KAAO,SAAA,EAAU;AAErC,EAAA,MAAM;AAAA,IACJ,KAAA;AAAA,IACA,QAAA;AAAA,IACA,QAAA;AAAA,IACA,WAAA;AAAA,IACA,SAAA;AAAA,IACA,QAAA,EAAU,EAAE,KAAA,EAAO,QAAA,EAAU,SAAS,eAAA,EAAgB;AAAA,IACtD,cAAA,EAAgB,EAAE,KAAA,EAAO,cAAA,EAAgB,SAAS,qBAAA;AAAsB,MACtE,qBAAA,EAAsB;AAE1B,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,QAAA,EAAU;AACf,IAAA,QAAA,CAAS,SAAS,SAAS,CAAA;AAC3B,IAAA,WAAA,CAAY,MAAM;AAChB,MAAA,IAAI,EAAE,kBAAiB,GAAI,QAAA;AAC3B,MAAA,IAAI,CAAC,gBAAA,IAAoB,gBAAA,KAAqB,MAAA,EAAQ;AACpD,QAAA,gBAAA,GAAmB,EAAA;AAAA,MACrB;AACA,MAAA,OAAO,gBAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACH,CAAA,EAAG,CAAC,QAAA,EAAU,QAAA,EAAU,WAAW,CAAC,CAAA;AAEpC,EAAA,MAAM,QAAA,GAAW,SAAA,CAAU,iBAAA,CAAkB,WAAW,CAAA,IAAK,WAAA;AAC7D,EAAA,MAAM,mBAAmB,cAAA,EAAgB,gBAAA;AACzC,EAAA,MAAM,cAAA,GACJ,CAAC,CAAC,gBAAA,IACF,iBAAiB,IAAA,KAAS,KAAA,IAC1B,iBAAiB,IAAA,KAAS,MAAA;AAE5B,EAAA,MAAM,aAAA,GAAgB,CAAC,qBAAA,IAAyB,cAAA,KAAmB,MAAA;AACnE,EAAA,MAAM,YAAA,GAAe,CAAC,eAAA,IAAmB,QAAA,KAAa,MAAA;AACtD,EAAA,MAAM,SAAS,aAAA,IAAiB,YAAA;AAEhC,EAAA,MAAM,sBAAsB,CAAC,GAAA,KAAgB,GAAA,CAAI,OAAA,CAAQ,OAAO,EAAE,CAAA;AAClE,EAAA,MAAM,iBAAA,GAAoB,CAAC,GAAA,KACzB,GAAA,CAAI,QAAQ,OAAA,EAAS,GAAG,CAAA,CAAE,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,CAAI,UAAU,CAAA,CAAE,KAAK,GAAG,CAAA;AAE/D,EAAA,IAAI,QAAA,GAAW,QAAA;AACf,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,MAAM,eAAA,GAAkB,mBAAmB,SAAS,CAAA;AACpD,IAAA,MAAM,iBAAA,GACJ,qBAAA,CAAsB,SAAA,CAAU,eAAe,EAAE,QAAA,CAAS,YAAA;AAE5D,IAAA,IAAI,wBAAkC,EAAC;AACvC,IAAA,IAAI,IAAA,KAAS,EAAA;AACX,MAAA,qBAAA,GAAwB,oBAAoB,IAAI,CAAA,CAC7C,MAAM,GAAG,CAAA,CACT,IAAI,iBAAiB,CAAA;AAE1B,IAAA,MAAM,aAAA,GAAgB;AAAA,MACpB,iBAAA;AAAA,MACA,GAAG,qBAAA;AAAA,MACH;AAAA,KACF;AACA,IAAA,QAAA,GAAW,aAAA,CAAc,KAAK,KAAK,CAAA;AAAA,EACrC;AAEA,EAAA,OAAO;AAAA,IACL,KAAA;AAAA,IACA,QAAA;AAAA,IACA,SAAA;AAAA,IACA,cAAA;AAAA,IACA,QAAA;AAAA,IACA,MAAA;AAAA,IACA,cAAA;AAAA,IACA,YAAY,gBAAA,EAAkB,MAAA;AAAA,IAC9B;AAAA,GACF;AACF;;;;"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { useState, useRef, useEffect } from 'react';
|
|
2
|
+
import { useSearch } from '@backstage/plugin-search-react';
|
|
3
|
+
|
|
4
|
+
function useTechDocsSearch(entityId) {
|
|
5
|
+
const {
|
|
6
|
+
setFilters,
|
|
7
|
+
setTerm,
|
|
8
|
+
term,
|
|
9
|
+
result: { loading, value: searchVal }
|
|
10
|
+
} = useSearch();
|
|
11
|
+
const [results, setResults] = useState([]);
|
|
12
|
+
const [deferredLoading, setDeferredLoading] = useState(false);
|
|
13
|
+
const loadingTimer = useRef();
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
if (searchVal) {
|
|
16
|
+
setResults(searchVal.results.slice(0, 10));
|
|
17
|
+
}
|
|
18
|
+
}, [loading, searchVal]);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
clearTimeout(loadingTimer.current);
|
|
21
|
+
setDeferredLoading(false);
|
|
22
|
+
if (loading) {
|
|
23
|
+
loadingTimer.current = setTimeout(() => setDeferredLoading(true), 200);
|
|
24
|
+
}
|
|
25
|
+
return () => clearTimeout(loadingTimer.current);
|
|
26
|
+
}, [term, loading]);
|
|
27
|
+
const { kind, name, namespace } = entityId;
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
setFilters((prevFilters) => ({
|
|
30
|
+
...prevFilters,
|
|
31
|
+
kind,
|
|
32
|
+
namespace,
|
|
33
|
+
name
|
|
34
|
+
}));
|
|
35
|
+
}, [kind, namespace, name, setFilters]);
|
|
36
|
+
return {
|
|
37
|
+
results,
|
|
38
|
+
term,
|
|
39
|
+
setTerm,
|
|
40
|
+
loading,
|
|
41
|
+
deferredLoading
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export { useTechDocsSearch };
|
|
46
|
+
//# sourceMappingURL=useTechDocsSearch.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTechDocsSearch.esm.js","sources":["../../src/hooks/useTechDocsSearch.ts"],"sourcesContent":["/*\n * Copyright 2026 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useEffect, useRef, useState } from 'react';\nimport { useSearch } from '@backstage/plugin-search-react';\nimport { CompoundEntityRef } from '@backstage/catalog-model';\nimport { ResultHighlight } from '@backstage/plugin-search-common';\n\nexport type TechDocsDoc = {\n namespace: string;\n kind: string;\n name: string;\n path: string;\n location: string;\n title: string;\n text: string;\n};\n\nexport type TechDocsSearchResult = {\n type: string;\n document: TechDocsDoc;\n highlight?: ResultHighlight;\n};\n\n/**\n * Shared hook for TechDocs search logic.\n * Encapsulates entity filter sync, results slicing,\n * and deferred loading state.\n */\nexport function useTechDocsSearch(entityId: CompoundEntityRef) {\n const {\n setFilters,\n setTerm,\n term,\n result: { loading, value: searchVal },\n } = useSearch();\n const [results, setResults] = useState<TechDocsSearchResult[]>([]);\n const [deferredLoading, setDeferredLoading] = useState(false);\n const loadingTimer = useRef<ReturnType<typeof setTimeout>>();\n\n useEffect(() => {\n if (searchVal) {\n setResults(searchVal.results.slice(0, 10) as TechDocsSearchResult[]);\n }\n }, [loading, searchVal]);\n\n useEffect(() => {\n clearTimeout(loadingTimer.current);\n setDeferredLoading(false);\n if (loading) {\n loadingTimer.current = setTimeout(() => setDeferredLoading(true), 200);\n }\n return () => clearTimeout(loadingTimer.current);\n }, [term, loading]);\n\n const { kind, name, namespace } = entityId;\n useEffect(() => {\n setFilters(prevFilters => ({\n ...prevFilters,\n kind,\n namespace,\n name,\n }));\n }, [kind, namespace, name, setFilters]);\n\n return {\n results,\n term,\n setTerm,\n loading,\n deferredLoading,\n };\n}\n"],"names":[],"mappings":";;;AA0CO,SAAS,kBAAkB,QAAA,EAA6B;AAC7D,EAAA,MAAM;AAAA,IACJ,UAAA;AAAA,IACA,OAAA;AAAA,IACA,IAAA;AAAA,IACA,MAAA,EAAQ,EAAE,OAAA,EAAS,KAAA,EAAO,SAAA;AAAU,MAClC,SAAA,EAAU;AACd,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,QAAA,CAAiC,EAAE,CAAA;AACjE,EAAA,MAAM,CAAC,eAAA,EAAiB,kBAAkB,CAAA,GAAI,SAAS,KAAK,CAAA;AAC5D,EAAA,MAAM,eAAe,MAAA,EAAsC;AAE3D,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,UAAA,CAAW,SAAA,CAAU,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,EAAE,CAA2B,CAAA;AAAA,IACrE;AAAA,EACF,CAAA,EAAG,CAAC,OAAA,EAAS,SAAS,CAAC,CAAA;AAEvB,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,YAAA,CAAa,aAAa,OAAO,CAAA;AACjC,IAAA,kBAAA,CAAmB,KAAK,CAAA;AACxB,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,YAAA,CAAa,UAAU,UAAA,CAAW,MAAM,kBAAA,CAAmB,IAAI,GAAG,GAAG,CAAA;AAAA,IACvE;AACA,IAAA,OAAO,MAAM,YAAA,CAAa,YAAA,CAAa,OAAO,CAAA;AAAA,EAChD,CAAA,EAAG,CAAC,IAAA,EAAM,OAAO,CAAC,CAAA;AAElB,EAAA,MAAM,EAAE,IAAA,EAAM,IAAA,EAAM,SAAA,EAAU,GAAI,QAAA;AAClC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,UAAA,CAAW,CAAA,WAAA,MAAgB;AAAA,MACzB,GAAG,WAAA;AAAA,MACH,IAAA;AAAA,MACA,SAAA;AAAA,MACA;AAAA,KACF,CAAE,CAAA;AAAA,EACJ,GAAG,CAAC,IAAA,EAAM,SAAA,EAAW,IAAA,EAAM,UAAU,CAAC,CAAA;AAEtC,EAAA,OAAO;AAAA,IACL,OAAA;AAAA,IACA,IAAA;AAAA,IACA,OAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,GACF;AACF;;;;"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
function styleInject(css, ref) {
|
|
2
|
+
if ( ref === void 0 ) ref = {};
|
|
3
|
+
var insertAt = ref.insertAt;
|
|
4
|
+
|
|
5
|
+
if (typeof document === 'undefined') { return; }
|
|
6
|
+
|
|
7
|
+
var head = document.head || document.getElementsByTagName('head')[0];
|
|
8
|
+
var style = document.createElement('style');
|
|
9
|
+
style.type = 'text/css';
|
|
10
|
+
|
|
11
|
+
if (insertAt === 'top') {
|
|
12
|
+
if (head.firstChild) {
|
|
13
|
+
head.insertBefore(style, head.firstChild);
|
|
14
|
+
} else {
|
|
15
|
+
head.appendChild(style);
|
|
16
|
+
}
|
|
17
|
+
} else {
|
|
18
|
+
head.appendChild(style);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (style.styleSheet) {
|
|
22
|
+
style.styleSheet.cssText = css;
|
|
23
|
+
} else {
|
|
24
|
+
style.appendChild(document.createTextNode(css));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export { styleInject as default };
|
|
29
|
+
//# sourceMappingURL=style-inject.es.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"style-inject.es.esm.js","sources":["../../../../../../node_modules/style-inject/dist/style-inject.es.js"],"sourcesContent":["function styleInject(css, ref) {\n if ( ref === void 0 ) ref = {};\n var insertAt = ref.insertAt;\n\n if (!css || typeof document === 'undefined') { return; }\n\n var head = document.head || document.getElementsByTagName('head')[0];\n var style = document.createElement('style');\n style.type = 'text/css';\n\n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild);\n } else {\n head.appendChild(style);\n }\n } else {\n head.appendChild(style);\n }\n\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n}\n\nexport default styleInject;\n"],"names":[],"mappings":"AAAA,SAAS,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE;AAC/B,EAAE,KAAK,GAAG,KAAK,MAAM,GAAG,GAAG,GAAG,EAAE;AAChC,EAAE,IAAI,QAAQ,GAAG,GAAG,CAAC,QAAQ;;AAE7B,EAAE,IAAY,OAAO,QAAQ,KAAK,WAAW,EAAE,EAAE,OAAO,CAAC;;AAEzD,EAAE,IAAI,IAAI,GAAG,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACtE,EAAE,IAAI,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC;AAC7C,EAAE,KAAK,CAAC,IAAI,GAAG,UAAU;;AAEzB,EAAE,IAAI,QAAQ,KAAK,KAAK,EAAE;AAC1B,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE;AACzB,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC;AAC/C,IAAI,CAAC,MAAM;AACX,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;AAC7B,IAAI;AACJ,EAAE,CAAC,MAAM;AACT,IAAI,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;AAC3B,EAAE;;AAEF,EAAE,IAAI,KAAK,CAAC,UAAU,EAAE;AACxB,IAAI,KAAK,CAAC,UAAU,CAAC,OAAO,GAAG,GAAG;AAClC,EAAE,CAAC,MAAM;AACT,IAAI,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;AACnD,EAAE;AACF;;;;","x_google_ignoreList":[0]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
var name = "@backstage/plugin-techdocs";
|
|
2
|
-
var version = "1.17.
|
|
2
|
+
var version = "1.17.2";
|
|
3
3
|
var description = "The Backstage plugin that renders technical documentation for your components";
|
|
4
4
|
var backstage = {
|
|
5
5
|
role: "frontend-plugin",
|
|
@@ -74,11 +74,13 @@ var dependencies = {
|
|
|
74
74
|
"@backstage/plugin-techdocs-common": "workspace:^",
|
|
75
75
|
"@backstage/plugin-techdocs-react": "workspace:^",
|
|
76
76
|
"@backstage/theme": "workspace:^",
|
|
77
|
+
"@backstage/ui": "workspace:^",
|
|
77
78
|
"@material-ui/core": "^4.12.2",
|
|
78
79
|
"@material-ui/icons": "^4.9.1",
|
|
79
80
|
"@material-ui/lab": "4.0.0-alpha.61",
|
|
80
81
|
"@material-ui/styles": "^4.10.0",
|
|
81
82
|
"@microsoft/fetch-event-source": "^2.0.1",
|
|
83
|
+
"@remixicon/react": "^4.6.0",
|
|
82
84
|
dompurify: "^3.3.2",
|
|
83
85
|
"git-url-parse": "^15.0.0",
|
|
84
86
|
lodash: "^4.17.21",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package.json.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"package.json.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
-
import { useEffect, useCallback } from 'react';
|
|
3
2
|
import Grid from '@material-ui/core/Grid';
|
|
4
3
|
import { makeStyles } from '@material-ui/core/styles';
|
|
5
|
-
import {
|
|
4
|
+
import { TechDocsShadowDom } from '@backstage/plugin-techdocs-react';
|
|
6
5
|
import { Content, Progress } from '@backstage/core-components';
|
|
7
6
|
import { TechDocsSearch } from '../../../search/components/TechDocsSearch.esm.js';
|
|
8
7
|
import { TechDocsStateIndicator } from '../TechDocsStateIndicator.esm.js';
|
|
9
|
-
import {
|
|
10
|
-
import { withTechDocsReaderProvider, useTechDocsReader } from '../TechDocsReaderProvider.esm.js';
|
|
8
|
+
import { withTechDocsReaderProvider } from '../TechDocsReaderProvider.esm.js';
|
|
11
9
|
import { TechDocsReaderPageContentAddons } from './TechDocsReaderPageContentAddons.esm.js';
|
|
12
|
-
import {
|
|
10
|
+
import { useTechDocsReaderContentData } from '../../../hooks/useTechDocsReaderContentData.esm.js';
|
|
13
11
|
|
|
14
12
|
const useStyles = makeStyles({
|
|
15
13
|
search: {
|
|
@@ -25,43 +23,23 @@ const useStyles = makeStyles({
|
|
|
25
23
|
});
|
|
26
24
|
const TechDocsReaderPageContent = withTechDocsReaderProvider(
|
|
27
25
|
(props) => {
|
|
28
|
-
const { withSearch = true, searchResultUrlMapper
|
|
26
|
+
const { withSearch = true, searchResultUrlMapper } = props;
|
|
29
27
|
const classes = useStyles();
|
|
30
28
|
const {
|
|
31
|
-
entityMetadata: { value: entityMetadata, loading: entityMetadataLoading },
|
|
32
29
|
entityRef,
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if (hashElement) {
|
|
47
|
-
hashElement.scrollIntoView();
|
|
48
|
-
}
|
|
49
|
-
} else {
|
|
50
|
-
document?.querySelector("header")?.scrollIntoView();
|
|
51
|
-
}
|
|
52
|
-
}, [path, hash, hashElement, isStyleLoading]);
|
|
53
|
-
const handleAppend = useCallback(
|
|
54
|
-
(newShadowRoot) => {
|
|
55
|
-
setShadowRoot(newShadowRoot);
|
|
56
|
-
if (onReady instanceof Function) {
|
|
57
|
-
onReady();
|
|
58
|
-
}
|
|
59
|
-
},
|
|
60
|
-
[setShadowRoot, onReady]
|
|
61
|
-
);
|
|
62
|
-
if (entityMetadataLoading === false && !entityMetadata)
|
|
63
|
-
return /* @__PURE__ */ jsx(NotFoundErrorPage, {});
|
|
64
|
-
if (!dom) {
|
|
30
|
+
entityMetadata,
|
|
31
|
+
dom,
|
|
32
|
+
handleAppend,
|
|
33
|
+
isNotFound,
|
|
34
|
+
isDomReady,
|
|
35
|
+
showProgress,
|
|
36
|
+
NotFoundErrorPage
|
|
37
|
+
} = useTechDocsReaderContentData({
|
|
38
|
+
defaultPath: props.defaultPath,
|
|
39
|
+
onReady: props.onReady
|
|
40
|
+
});
|
|
41
|
+
if (isNotFound) return /* @__PURE__ */ jsx(NotFoundErrorPage, {});
|
|
42
|
+
if (!isDomReady) {
|
|
65
43
|
return /* @__PURE__ */ jsx(Content, { children: /* @__PURE__ */ jsx(Grid, { container: true, children: /* @__PURE__ */ jsx(Grid, { xs: 12, item: true, children: /* @__PURE__ */ jsx(TechDocsStateIndicator, {}) }) }) });
|
|
66
44
|
}
|
|
67
45
|
return /* @__PURE__ */ jsx(Content, { children: /* @__PURE__ */ jsxs(Grid, { container: true, children: [
|
|
@@ -75,7 +53,7 @@ const TechDocsReaderPageContent = withTechDocsReaderProvider(
|
|
|
75
53
|
}
|
|
76
54
|
) }),
|
|
77
55
|
/* @__PURE__ */ jsxs(Grid, { xs: 12, item: true, children: [
|
|
78
|
-
|
|
56
|
+
showProgress && /* @__PURE__ */ jsx(Progress, {}),
|
|
79
57
|
/* @__PURE__ */ jsx(TechDocsShadowDom, { element: dom, onAppend: handleAppend, children: /* @__PURE__ */ jsx(TechDocsReaderPageContentAddons, {}) })
|
|
80
58
|
] })
|
|
81
59
|
] }) });
|
package/dist/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContent.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TechDocsReaderPageContent.esm.js","sources":["../../../../src/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContent.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport
|
|
1
|
+
{"version":3,"file":"TechDocsReaderPageContent.esm.js","sources":["../../../../src/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContent.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Grid from '@material-ui/core/Grid';\nimport { makeStyles } from '@material-ui/core/styles';\n\nimport { TechDocsShadowDom } from '@backstage/plugin-techdocs-react';\nimport { CompoundEntityRef } from '@backstage/catalog-model';\nimport { Content, Progress } from '@backstage/core-components';\n\nimport { TechDocsSearch } from '../../../search';\nimport { TechDocsStateIndicator } from '../TechDocsStateIndicator';\n\nimport { withTechDocsReaderProvider } from '../TechDocsReaderProvider';\nimport { TechDocsReaderPageContentAddons } from './TechDocsReaderPageContentAddons';\nimport { useTechDocsReaderContentData } from '../../../hooks/useTechDocsReaderContentData';\n\nconst useStyles = makeStyles({\n search: {\n width: '100%',\n '@media (min-width: 76.1875em)': {\n width: 'calc(100% - 34.4rem)',\n margin: '0 auto',\n },\n '@media print': {\n display: 'none',\n },\n },\n});\n\n/**\n * Props for {@link TechDocsReaderPageContent}\n * @public\n */\nexport type TechDocsReaderPageContentProps = {\n /**\n * @deprecated No need to pass down entityRef as property anymore. Consumes the entityName from `TechDocsReaderPageContext`. Use the {@link @backstage/plugin-techdocs-react#useTechDocsReaderPage} hook for custom reader page content.\n */\n entityRef?: CompoundEntityRef;\n /**\n * Path in the docs to render by default. This should be used when rendering docs for an entity that specifies the\n * \"backstage.io/techdocs-entity-path\" annotation for deep linking into another entities docs.\n */\n defaultPath?: string;\n /**\n * Show or hide the search bar, defaults to true.\n */\n withSearch?: boolean;\n /**\n * If {@link TechDocsReaderPageContentProps.withSearch | withSearch} is true,\n * this will redirect the search result urls, e.g. turn search results into\n * links within the \"Docs\" tab of the entity page, instead of the global docs\n * page.\n */\n searchResultUrlMapper?: (url: string) => string;\n /**\n * Callback called when the content is rendered.\n */\n onReady?: () => void;\n};\n\n/**\n * Renders the reader page content\n * @public\n */\nexport const TechDocsReaderPageContent = withTechDocsReaderProvider(\n (props: TechDocsReaderPageContentProps) => {\n const { withSearch = true, searchResultUrlMapper } = props;\n const classes = useStyles();\n\n const {\n entityRef,\n entityMetadata,\n dom,\n handleAppend,\n isNotFound,\n isDomReady,\n showProgress,\n NotFoundErrorPage,\n } = useTechDocsReaderContentData({\n defaultPath: props.defaultPath,\n onReady: props.onReady,\n });\n\n if (isNotFound) return <NotFoundErrorPage />;\n\n if (!isDomReady) {\n return (\n <Content>\n <Grid container>\n <Grid xs={12} item>\n <TechDocsStateIndicator />\n </Grid>\n </Grid>\n </Content>\n );\n }\n\n return (\n <Content>\n <Grid container>\n <Grid xs={12} item>\n <TechDocsStateIndicator />\n </Grid>\n {withSearch && (\n <Grid className={classes.search} xs=\"auto\" item>\n <TechDocsSearch\n entityId={entityRef}\n entityTitle={entityMetadata?.metadata?.title}\n searchResultUrlMapper={searchResultUrlMapper}\n />\n </Grid>\n )}\n <Grid xs={12} item>\n {showProgress && <Progress />}\n\n <TechDocsShadowDom element={dom!} onAppend={handleAppend}>\n <TechDocsReaderPageContentAddons />\n </TechDocsShadowDom>\n </Grid>\n </Grid>\n </Content>\n );\n },\n);\n\n/**\n * Props for {@link Reader}\n *\n * @public\n * @deprecated use `TechDocsReaderPageContentProps` instead.\n */\nexport type ReaderProps = TechDocsReaderPageContentProps;\n\n/**\n * Component responsible for rendering TechDocs documentation\n * @public\n * @deprecated use `TechDocsReaderPageContent` component instead.\n */\nexport const Reader = TechDocsReaderPageContent;\n"],"names":[],"mappings":";;;;;;;;;;;AA8BA,MAAM,YAAY,UAAA,CAAW;AAAA,EAC3B,MAAA,EAAQ;AAAA,IACN,KAAA,EAAO,MAAA;AAAA,IACP,+BAAA,EAAiC;AAAA,MAC/B,KAAA,EAAO,sBAAA;AAAA,MACP,MAAA,EAAQ;AAAA,KACV;AAAA,IACA,cAAA,EAAgB;AAAA,MACd,OAAA,EAAS;AAAA;AACX;AAEJ,CAAC,CAAA;AAqCM,MAAM,yBAAA,GAA4B,0BAAA;AAAA,EACvC,CAAC,KAAA,KAA0C;AACzC,IAAA,MAAM,EAAE,UAAA,GAAa,IAAA,EAAM,qBAAA,EAAsB,GAAI,KAAA;AACrD,IAAA,MAAM,UAAU,SAAA,EAAU;AAE1B,IAAA,MAAM;AAAA,MACJ,SAAA;AAAA,MACA,cAAA;AAAA,MACA,GAAA;AAAA,MACA,YAAA;AAAA,MACA,UAAA;AAAA,MACA,UAAA;AAAA,MACA,YAAA;AAAA,MACA;AAAA,QACE,4BAAA,CAA6B;AAAA,MAC/B,aAAa,KAAA,CAAM,WAAA;AAAA,MACnB,SAAS,KAAA,CAAM;AAAA,KAChB,CAAA;AAED,IAAA,IAAI,UAAA,EAAY,uBAAO,GAAA,CAAC,iBAAA,EAAA,EAAkB,CAAA;AAE1C,IAAA,IAAI,CAAC,UAAA,EAAY;AACf,MAAA,2BACG,OAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAS,MACb,QAAA,kBAAA,GAAA,CAAC,IAAA,EAAA,EAAK,EAAA,EAAI,EAAA,EAAI,MAAI,IAAA,EAChB,QAAA,kBAAA,GAAA,CAAC,sBAAA,EAAA,EAAuB,CAAA,EAC1B,GACF,CAAA,EACF,CAAA;AAAA,IAEJ;AAEA,IAAA,uBACE,GAAA,CAAC,OAAA,EAAA,EACC,QAAA,kBAAA,IAAA,CAAC,IAAA,EAAA,EAAK,WAAS,IAAA,EACb,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,QAAK,EAAA,EAAI,EAAA,EAAI,MAAI,IAAA,EAChB,QAAA,kBAAA,GAAA,CAAC,0BAAuB,CAAA,EAC1B,CAAA;AAAA,MACC,UAAA,wBACE,IAAA,EAAA,EAAK,SAAA,EAAW,QAAQ,MAAA,EAAQ,EAAA,EAAG,MAAA,EAAO,IAAA,EAAI,IAAA,EAC7C,QAAA,kBAAA,GAAA;AAAA,QAAC,cAAA;AAAA,QAAA;AAAA,UACC,QAAA,EAAU,SAAA;AAAA,UACV,WAAA,EAAa,gBAAgB,QAAA,EAAU,KAAA;AAAA,UACvC;AAAA;AAAA,OACF,EACF,CAAA;AAAA,sBAEF,IAAA,CAAC,IAAA,EAAA,EAAK,EAAA,EAAI,EAAA,EAAI,MAAI,IAAA,EACf,QAAA,EAAA;AAAA,QAAA,YAAA,wBAAiB,QAAA,EAAA,EAAS,CAAA;AAAA,wBAE3B,GAAA,CAAC,qBAAkB,OAAA,EAAS,GAAA,EAAM,UAAU,YAAA,EAC1C,QAAA,kBAAA,GAAA,CAAC,mCAAgC,CAAA,EACnC;AAAA,OAAA,EACF;AAAA,KAAA,EACF,CAAA,EACF,CAAA;AAAA,EAEJ;AACF;AAeO,MAAM,MAAA,GAAS;;;;"}
|
|
@@ -1,50 +1,36 @@
|
|
|
1
1
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { useEffect } from 'react';
|
|
3
2
|
import Helmet from 'react-helmet';
|
|
4
3
|
import Grid from '@material-ui/core/Grid';
|
|
5
4
|
import Skeleton from '@material-ui/lab/Skeleton';
|
|
6
5
|
import CodeIcon from '@material-ui/icons/Code';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { RELATION_OWNED_BY
|
|
6
|
+
import { TechDocsAddonLocations } from '@backstage/plugin-techdocs-react';
|
|
7
|
+
import { getEntityRelations, EntityRefLink, EntityRefLinks } from '@backstage/plugin-catalog-react';
|
|
8
|
+
import { RELATION_OWNED_BY } from '@backstage/catalog-model';
|
|
10
9
|
import { HeaderLabel, Header } from '@backstage/core-components';
|
|
11
|
-
import {
|
|
10
|
+
import { useRouteRef } from '@backstage/core-plugin-api';
|
|
12
11
|
import capitalize from 'lodash/capitalize';
|
|
13
12
|
import { rootRouteRef } from '../../../routes.esm.js';
|
|
14
|
-
import {
|
|
13
|
+
import { useTechDocsReaderHeaderData } from '../../../hooks/useTechDocsReaderHeaderData.esm.js';
|
|
15
14
|
|
|
16
15
|
const skeleton = /* @__PURE__ */ jsx(Skeleton, { animation: "wave", variant: "text", height: 40 });
|
|
17
16
|
const TechDocsReaderPageHeader = (props) => {
|
|
18
17
|
const { children } = props;
|
|
19
|
-
const addons = useTechDocsAddons();
|
|
20
|
-
const configApi = useApi(configApiRef);
|
|
21
|
-
const entityPresentationApi = useApi(entityPresentationApiRef);
|
|
22
|
-
const { "*": path = "" } = useParams();
|
|
23
18
|
const {
|
|
24
19
|
title,
|
|
25
|
-
setTitle,
|
|
26
20
|
subtitle,
|
|
27
|
-
setSubtitle,
|
|
28
21
|
entityRef,
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
return site_description;
|
|
41
|
-
});
|
|
42
|
-
}, [metadata, setTitle, setSubtitle]);
|
|
43
|
-
const appTitle = configApi.getOptional("app.title") || "Backstage";
|
|
44
|
-
const { locationMetadata, spec } = entityMetadata || {};
|
|
22
|
+
entityMetadata,
|
|
23
|
+
tabTitle,
|
|
24
|
+
hidden,
|
|
25
|
+
showSourceLink,
|
|
26
|
+
sourceLink,
|
|
27
|
+
addons
|
|
28
|
+
} = useTechDocsReaderHeaderData();
|
|
29
|
+
const docsRootLink = useRouteRef(rootRouteRef)();
|
|
30
|
+
if (hidden) return null;
|
|
31
|
+
const { spec } = entityMetadata || {};
|
|
45
32
|
const lifecycle = spec?.lifecycle;
|
|
46
33
|
const ownedByRelations = entityMetadata ? getEntityRelations(entityMetadata, RELATION_OWNED_BY) : [];
|
|
47
|
-
const docsRootLink = useRouteRef(rootRouteRef)();
|
|
48
34
|
const labels = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
49
35
|
/* @__PURE__ */ jsx(
|
|
50
36
|
HeaderLabel,
|
|
@@ -76,7 +62,7 @@ const TechDocsReaderPageHeader = (props) => {
|
|
|
76
62
|
}
|
|
77
63
|
),
|
|
78
64
|
lifecycle ? /* @__PURE__ */ jsx(HeaderLabel, { label: "Lifecycle", value: String(lifecycle) }) : null,
|
|
79
|
-
|
|
65
|
+
showSourceLink ? /* @__PURE__ */ jsx(
|
|
80
66
|
HeaderLabel,
|
|
81
67
|
{
|
|
82
68
|
label: "",
|
|
@@ -84,22 +70,10 @@ const TechDocsReaderPageHeader = (props) => {
|
|
|
84
70
|
/* @__PURE__ */ jsx(Grid, { style: { padding: 0 }, item: true, children: /* @__PURE__ */ jsx(CodeIcon, { style: { marginTop: "-25px" } }) }),
|
|
85
71
|
/* @__PURE__ */ jsx(Grid, { style: { padding: 0 }, item: true, children: "Source" })
|
|
86
72
|
] }),
|
|
87
|
-
url:
|
|
73
|
+
url: sourceLink
|
|
88
74
|
}
|
|
89
75
|
) : null
|
|
90
76
|
] });
|
|
91
|
-
const noEntMetadata = !entityMetadataLoading && entityMetadata === void 0;
|
|
92
|
-
const noTdMetadata = !metadataLoading && metadata === void 0;
|
|
93
|
-
if (noEntMetadata || noTdMetadata) return null;
|
|
94
|
-
const stringEntityRef = stringifyEntityRef(entityRef);
|
|
95
|
-
const entityDisplayName = entityPresentationApi.forEntity(stringEntityRef).snapshot.primaryTitle;
|
|
96
|
-
const removeTrailingSlash = (str) => str.replace(/\/$/, "");
|
|
97
|
-
const normalizeAndSpace = (str) => str.replace(/[-_]/g, " ").split(" ").map(capitalize).join(" ");
|
|
98
|
-
let techdocsTabTitleItems = [];
|
|
99
|
-
if (path !== "")
|
|
100
|
-
techdocsTabTitleItems = removeTrailingSlash(path).split("/").map(normalizeAndSpace);
|
|
101
|
-
const tabTitleItems = [entityDisplayName, ...techdocsTabTitleItems, appTitle];
|
|
102
|
-
const tabTitle = tabTitleItems.join(" | ");
|
|
103
77
|
return /* @__PURE__ */ jsxs(
|
|
104
78
|
Header,
|
|
105
79
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TechDocsReaderPageHeader.esm.js","sources":["../../../../src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { PropsWithChildren, useEffect } from 'react';\nimport Helmet from 'react-helmet';\n\nimport Grid from '@material-ui/core/Grid';\nimport Skeleton from '@material-ui/lab/Skeleton';\nimport CodeIcon from '@material-ui/icons/Code';\n\nimport {\n TechDocsAddonLocations as locations,\n useTechDocsAddons,\n useTechDocsReaderPage,\n TechDocsEntityMetadata,\n TechDocsMetadata,\n} from '@backstage/plugin-techdocs-react';\nimport {\n entityPresentationApiRef,\n EntityRefLink,\n EntityRefLinks,\n getEntityRelations,\n} from '@backstage/plugin-catalog-react';\nimport {\n RELATION_OWNED_BY,\n CompoundEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { Header, HeaderLabel } from '@backstage/core-components';\nimport { useRouteRef, configApiRef, useApi } from '@backstage/core-plugin-api';\n\nimport capitalize from 'lodash/capitalize';\n\nimport { rootRouteRef } from '../../../routes';\nimport { useParams } from 'react-router-dom';\n\nconst skeleton = <Skeleton animation=\"wave\" variant=\"text\" height={40} />;\n\n/**\n * Props for {@link TechDocsReaderPageHeader}\n *\n * @public\n * @deprecated No need to pass down properties anymore. The component consumes data from `TechDocsReaderPageContext` instead. Use the {@link @backstage/plugin-techdocs-react#useTechDocsReaderPage} hook for custom header.\n */\nexport type TechDocsReaderPageHeaderProps = PropsWithChildren<{\n entityRef?: CompoundEntityRef;\n entityMetadata?: TechDocsEntityMetadata;\n techDocsMetadata?: TechDocsMetadata;\n}>;\n\n/**\n * Renders the reader page header.\n * This component does not accept props, please use\n * the Tech Docs add-ons to customize it\n * @public\n */\nexport const TechDocsReaderPageHeader = (\n props: TechDocsReaderPageHeaderProps,\n) => {\n const { children } = props;\n const addons = useTechDocsAddons();\n const configApi = useApi(configApiRef);\n\n const entityPresentationApi = useApi(entityPresentationApiRef);\n const { '*': path = '' } = useParams();\n\n const {\n title,\n setTitle,\n subtitle,\n setSubtitle,\n entityRef,\n metadata: { value: metadata, loading: metadataLoading },\n entityMetadata: { value: entityMetadata, loading: entityMetadataLoading },\n } = useTechDocsReaderPage();\n\n useEffect(() => {\n if (!metadata) return;\n setTitle(metadata.site_name);\n setSubtitle(() => {\n let { site_description } = metadata;\n if (!site_description || site_description === 'None') {\n site_description = '';\n }\n return site_description;\n });\n }, [metadata, setTitle, setSubtitle]);\n\n const appTitle = configApi.getOptional('app.title') || 'Backstage';\n\n const { locationMetadata, spec } = entityMetadata || {};\n const lifecycle = spec?.lifecycle;\n\n const ownedByRelations = entityMetadata\n ? getEntityRelations(entityMetadata, RELATION_OWNED_BY)\n : [];\n\n const docsRootLink = useRouteRef(rootRouteRef)();\n\n const labels = (\n <>\n <HeaderLabel\n label={capitalize(entityMetadata?.kind || 'entity')}\n value={\n <EntityRefLink\n color=\"inherit\"\n entityRef={entityRef}\n title={entityMetadata?.metadata.title}\n defaultKind=\"Component\"\n />\n }\n />\n {ownedByRelations.length > 0 && (\n <HeaderLabel\n label=\"Owner\"\n value={\n <EntityRefLinks\n color=\"inherit\"\n entityRefs={ownedByRelations}\n defaultKind=\"group\"\n />\n }\n />\n )}\n {lifecycle ? (\n <HeaderLabel label=\"Lifecycle\" value={String(lifecycle)} />\n ) : null}\n {locationMetadata &&\n locationMetadata.type !== 'dir' &&\n locationMetadata.type !== 'file' ? (\n <HeaderLabel\n label=\"\"\n value={\n <Grid container direction=\"column\" alignItems=\"center\">\n <Grid style={{ padding: 0 }} item>\n <CodeIcon style={{ marginTop: '-25px' }} />\n </Grid>\n <Grid style={{ padding: 0 }} item>\n Source\n </Grid>\n </Grid>\n }\n url={locationMetadata.target}\n />\n ) : null}\n </>\n );\n\n // If there is no entity or techdocs metadata, there's no reason to show the\n // header (hides the header on 404 error pages).\n const noEntMetadata = !entityMetadataLoading && entityMetadata === undefined;\n const noTdMetadata = !metadataLoading && metadata === undefined;\n if (noEntMetadata || noTdMetadata) return null;\n\n const stringEntityRef = stringifyEntityRef(entityRef);\n\n const entityDisplayName =\n entityPresentationApi.forEntity(stringEntityRef).snapshot.primaryTitle;\n\n const removeTrailingSlash = (str: string) => str.replace(/\\/$/, '');\n const normalizeAndSpace = (str: string) =>\n str.replace(/[-_]/g, ' ').split(' ').map(capitalize).join(' ');\n\n let techdocsTabTitleItems: string[] = [];\n\n if (path !== '')\n techdocsTabTitleItems = removeTrailingSlash(path)\n .split('/')\n .map(normalizeAndSpace);\n\n const tabTitleItems = [entityDisplayName, ...techdocsTabTitleItems, appTitle];\n const tabTitle = tabTitleItems.join(' | ');\n\n return (\n <Header\n type=\"Documentation\"\n typeLink={docsRootLink}\n title={title || skeleton}\n subtitle={subtitle === '' ? undefined : subtitle || skeleton}\n >\n <Helmet titleTemplate=\"%s\">\n <title>{tabTitle}</title>\n </Helmet>\n {labels}\n {children}\n {addons.renderComponentsByLocation(locations.Header)}\n </Header>\n );\n};\n"],"names":["locations"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TechDocsReaderPageHeader.esm.js","sources":["../../../../src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { PropsWithChildren } from 'react';\nimport Helmet from 'react-helmet';\n\nimport Grid from '@material-ui/core/Grid';\nimport Skeleton from '@material-ui/lab/Skeleton';\nimport CodeIcon from '@material-ui/icons/Code';\n\nimport {\n TechDocsAddonLocations as locations,\n TechDocsEntityMetadata,\n TechDocsMetadata,\n} from '@backstage/plugin-techdocs-react';\nimport {\n EntityRefLink,\n EntityRefLinks,\n getEntityRelations,\n} from '@backstage/plugin-catalog-react';\nimport { RELATION_OWNED_BY, CompoundEntityRef } from '@backstage/catalog-model';\nimport { Header, HeaderLabel } from '@backstage/core-components';\nimport { useRouteRef } from '@backstage/core-plugin-api';\n\nimport capitalize from 'lodash/capitalize';\n\nimport { rootRouteRef } from '../../../routes';\nimport { useTechDocsReaderHeaderData } from '../../../hooks/useTechDocsReaderHeaderData';\n\nconst skeleton = <Skeleton animation=\"wave\" variant=\"text\" height={40} />;\n\n/**\n * Props for {@link TechDocsReaderPageHeader}\n *\n * @public\n * @deprecated No need to pass down properties anymore. The component consumes data from `TechDocsReaderPageContext` instead. Use the {@link @backstage/plugin-techdocs-react#useTechDocsReaderPage} hook for custom header.\n */\nexport type TechDocsReaderPageHeaderProps = PropsWithChildren<{\n entityRef?: CompoundEntityRef;\n entityMetadata?: TechDocsEntityMetadata;\n techDocsMetadata?: TechDocsMetadata;\n}>;\n\n/**\n * Renders the reader page header.\n * This component does not accept props, please use\n * the Tech Docs add-ons to customize it\n * @public\n */\nexport const TechDocsReaderPageHeader = (\n props: TechDocsReaderPageHeaderProps,\n) => {\n const { children } = props;\n const {\n title,\n subtitle,\n entityRef,\n entityMetadata,\n tabTitle,\n hidden,\n showSourceLink,\n sourceLink,\n addons,\n } = useTechDocsReaderHeaderData();\n\n const docsRootLink = useRouteRef(rootRouteRef)();\n\n if (hidden) return null;\n\n const { spec } = entityMetadata || {};\n const lifecycle = spec?.lifecycle;\n\n const ownedByRelations = entityMetadata\n ? getEntityRelations(entityMetadata, RELATION_OWNED_BY)\n : [];\n\n const labels = (\n <>\n <HeaderLabel\n label={capitalize(entityMetadata?.kind || 'entity')}\n value={\n <EntityRefLink\n color=\"inherit\"\n entityRef={entityRef}\n title={entityMetadata?.metadata.title}\n defaultKind=\"Component\"\n />\n }\n />\n {ownedByRelations.length > 0 && (\n <HeaderLabel\n label=\"Owner\"\n value={\n <EntityRefLinks\n color=\"inherit\"\n entityRefs={ownedByRelations}\n defaultKind=\"group\"\n />\n }\n />\n )}\n {lifecycle ? (\n <HeaderLabel label=\"Lifecycle\" value={String(lifecycle)} />\n ) : null}\n {showSourceLink ? (\n <HeaderLabel\n label=\"\"\n value={\n <Grid container direction=\"column\" alignItems=\"center\">\n <Grid style={{ padding: 0 }} item>\n <CodeIcon style={{ marginTop: '-25px' }} />\n </Grid>\n <Grid style={{ padding: 0 }} item>\n Source\n </Grid>\n </Grid>\n }\n url={sourceLink}\n />\n ) : null}\n </>\n );\n\n return (\n <Header\n type=\"Documentation\"\n typeLink={docsRootLink}\n title={title || skeleton}\n subtitle={subtitle === '' ? undefined : subtitle || skeleton}\n >\n <Helmet titleTemplate=\"%s\">\n <title>{tabTitle}</title>\n </Helmet>\n {labels}\n {children}\n {addons.renderComponentsByLocation(locations.Header)}\n </Header>\n );\n};\n"],"names":["locations"],"mappings":"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"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { SearchContextProvider,
|
|
3
|
-
import { useState
|
|
2
|
+
import { SearchContextProvider, SearchAutocomplete } from '@backstage/plugin-search-react';
|
|
3
|
+
import { useState } from 'react';
|
|
4
4
|
import { useNavigate } from 'react-router-dom';
|
|
5
5
|
import { TechDocsSearchResultListItem } from './TechDocsSearchResultListItem.esm.js';
|
|
6
|
+
import { useTechDocsSearch } from '../../hooks/useTechDocsSearch.esm.js';
|
|
6
7
|
|
|
7
8
|
const isTechDocsSearchResult = (option) => {
|
|
8
9
|
return option?.document;
|
|
@@ -16,33 +17,7 @@ const TechDocsSearchBar = (props) => {
|
|
|
16
17
|
} = props;
|
|
17
18
|
const [open, setOpen] = useState(false);
|
|
18
19
|
const navigate = useNavigate();
|
|
19
|
-
const {
|
|
20
|
-
setFilters,
|
|
21
|
-
term,
|
|
22
|
-
result: { loading, value: searchVal }
|
|
23
|
-
} = useSearch();
|
|
24
|
-
const [options, setOptions] = useState([]);
|
|
25
|
-
useEffect(() => {
|
|
26
|
-
let mounted = true;
|
|
27
|
-
if (mounted && searchVal) {
|
|
28
|
-
const searchResults = searchVal.results.slice(0, 10);
|
|
29
|
-
setOptions(searchResults);
|
|
30
|
-
}
|
|
31
|
-
return () => {
|
|
32
|
-
mounted = false;
|
|
33
|
-
};
|
|
34
|
-
}, [loading, searchVal]);
|
|
35
|
-
const { kind, name, namespace } = entityId;
|
|
36
|
-
useEffect(() => {
|
|
37
|
-
setFilters((prevFilters) => {
|
|
38
|
-
return {
|
|
39
|
-
...prevFilters,
|
|
40
|
-
kind,
|
|
41
|
-
namespace,
|
|
42
|
-
name
|
|
43
|
-
};
|
|
44
|
-
});
|
|
45
|
-
}, [kind, namespace, name, setFilters]);
|
|
20
|
+
const { results, term, loading } = useTechDocsSearch(entityId);
|
|
46
21
|
const handleSelection = (_, selection) => {
|
|
47
22
|
if (isTechDocsSearchResult(selection)) {
|
|
48
23
|
const { location } = selection.document;
|
|
@@ -71,7 +46,7 @@ const TechDocsSearchBar = (props) => {
|
|
|
71
46
|
blurOnSelect: true,
|
|
72
47
|
noOptionsText: "No results found",
|
|
73
48
|
value: null,
|
|
74
|
-
options,
|
|
49
|
+
options: results,
|
|
75
50
|
renderOption: ({ document, highlight }) => /* @__PURE__ */ jsx(
|
|
76
51
|
TechDocsSearchResultListItem,
|
|
77
52
|
{
|