@backstage/plugin-techdocs 1.18.2 → 1.19.0-next.0
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 +21 -2
- package/dist/EntityPageDocs.esm.js +3 -1
- package/dist/EntityPageDocs.esm.js.map +1 -1
- package/dist/Router.esm.js +11 -4
- package/dist/Router.esm.js.map +1 -1
- package/dist/alpha/addonsApi.esm.js.map +1 -1
- package/dist/alpha/components/TechDocsIndexPageContent.esm.js.map +1 -1
- package/dist/alpha/components/TechDocsReaderContent.esm.js +2 -1
- package/dist/alpha/components/TechDocsReaderContent.esm.js.map +1 -1
- package/dist/alpha/components/TechDocsReaderEntityCard.esm.js.map +1 -1
- package/dist/alpha/components/TechDocsReaderEntityCard.module.css.esm.js.map +1 -1
- package/dist/alpha/components/TechDocsReaderHeader.esm.js.map +1 -1
- package/dist/alpha/components/TechDocsReaderLayout.esm.js +2 -2
- package/dist/alpha/components/TechDocsReaderLayout.esm.js.map +1 -1
- package/dist/alpha/components/TechDocsReaderPage.esm.js +10 -2
- package/dist/alpha/components/TechDocsReaderPage.esm.js.map +1 -1
- package/dist/alpha/components/TechDocsReaderSearch.esm.js.map +1 -1
- package/dist/alpha/hooks/useTechdocsReaderIconLinkProps.esm.js.map +1 -1
- package/dist/alpha.d.ts +4 -0
- package/dist/alpha.esm.js +9 -3
- package/dist/alpha.esm.js.map +1 -1
- package/dist/api.esm.js.map +1 -1
- package/dist/client.esm.js.map +1 -1
- package/dist/helpers.esm.js.map +1 -1
- package/dist/home/components/DefaultTechDocsHome.esm.js.map +1 -1
- package/dist/home/components/Grids/DocsCardGrid.esm.js.map +1 -1
- package/dist/home/components/Grids/EntityListDocsGrid.esm.js.map +1 -1
- package/dist/home/components/Grids/InfoCardGrid.esm.js.map +1 -1
- package/dist/home/components/Tables/CursorPaginatedDocsTable.esm.js.map +1 -1
- package/dist/home/components/Tables/DocsTable.esm.js.map +1 -1
- package/dist/home/components/Tables/EntityListDocsTable.esm.js.map +1 -1
- package/dist/home/components/Tables/OffsetPaginatedDocsTable.esm.js.map +1 -1
- package/dist/home/components/Tables/actions.esm.js.map +1 -1
- package/dist/home/components/Tables/columns.esm.js.map +1 -1
- package/dist/home/components/Tables/helpers.esm.js.map +1 -1
- package/dist/home/components/TechDocsCustomHome.esm.js.map +1 -1
- package/dist/home/components/TechDocsIndexPage.esm.js.map +1 -1
- package/dist/home/components/TechDocsPageWrapper.esm.js.map +1 -1
- package/dist/home/components/TechDocsPicker.esm.js.map +1 -1
- package/dist/hooks/useTechDocsReaderContentData.esm.js +5 -2
- package/dist/hooks/useTechDocsReaderContentData.esm.js.map +1 -1
- package/dist/hooks/useTechDocsReaderHeaderData.esm.js.map +1 -1
- package/dist/hooks/useTechDocsSearch.esm.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/node_modules_dist/style-inject/dist/style-inject.es.esm.js.map +1 -1
- package/dist/plugin.esm.js +2 -2
- package/dist/plugin.esm.js.map +1 -1
- package/dist/plugins/techdocs/package.json.esm.js +1 -1
- package/dist/plugins/techdocs/package.json.esm.js.map +1 -1
- package/dist/reader/components/TechDocsBuildLogs.esm.js.map +1 -1
- package/dist/reader/components/TechDocsNotFound.esm.js.map +1 -1
- package/dist/reader/components/TechDocsReaderPage/TechDocsReaderPage.esm.js +2 -2
- package/dist/reader/components/TechDocsReaderPage/TechDocsReaderPage.esm.js.map +1 -1
- package/dist/reader/components/TechDocsReaderPage/useExternalRedirect.esm.js.map +1 -1
- package/dist/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContent.esm.js +2 -1
- package/dist/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContent.esm.js.map +1 -1
- package/dist/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContentAddons.esm.js.map +1 -1
- package/dist/reader/components/TechDocsReaderPageContent/dom.esm.js +5 -3
- package/dist/reader/components/TechDocsReaderPageContent/dom.esm.js.map +1 -1
- package/dist/reader/components/TechDocsReaderPageContent/useNavigateUrl.esm.js.map +1 -1
- package/dist/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.esm.js.map +1 -1
- package/dist/reader/components/TechDocsReaderPageSubheader/TechDocsReaderPageSubheader.esm.js.map +1 -1
- package/dist/reader/components/TechDocsReaderProvider.esm.js.map +1 -1
- package/dist/reader/components/TechDocsRedirectNotification/TechDocsRedirectNotification.esm.js.map +1 -1
- package/dist/reader/components/TechDocsStateIndicator.esm.js.map +1 -1
- package/dist/reader/components/useReaderState.esm.js.map +1 -1
- package/dist/reader/transformers/addBaseUrl.esm.js.map +1 -1
- package/dist/reader/transformers/addGitFeedbackLink.esm.js.map +1 -1
- package/dist/reader/transformers/addLinkClickListener.esm.js.map +1 -1
- package/dist/reader/transformers/addNavLinkKeyboardToggle.esm.js.map +1 -1
- package/dist/reader/transformers/addSidebarToggle.esm.js.map +1 -1
- package/dist/reader/transformers/copyToClipboard.esm.js.map +1 -1
- package/dist/reader/transformers/handleMetaRedirects.esm.js.map +1 -1
- package/dist/reader/transformers/html/hooks/attributes.esm.js.map +1 -1
- package/dist/reader/transformers/html/hooks/iframes.esm.js.map +1 -1
- package/dist/reader/transformers/html/hooks/links.esm.js.map +1 -1
- package/dist/reader/transformers/html/hooks/metatags.esm.js.map +1 -1
- package/dist/reader/transformers/html/transformer.esm.js.map +1 -1
- package/dist/reader/transformers/html/utils.esm.js.map +1 -1
- package/dist/reader/transformers/onCssReady.esm.js.map +1 -1
- package/dist/reader/transformers/removeMkdocsHeader.esm.js.map +1 -1
- package/dist/reader/transformers/renderReactElement.esm.js.map +1 -1
- package/dist/reader/transformers/rewriteDocLinks.esm.js.map +1 -1
- package/dist/reader/transformers/scrollIntoNavigation.esm.js.map +1 -1
- package/dist/reader/transformers/simplifyMkdocsFooter.esm.js.map +1 -1
- package/dist/reader/transformers/styles/rules/animations.esm.js.map +1 -1
- package/dist/reader/transformers/styles/rules/extensions.esm.js.map +1 -1
- package/dist/reader/transformers/styles/rules/layout.esm.js.map +1 -1
- package/dist/reader/transformers/styles/rules/palette.esm.js.map +1 -1
- package/dist/reader/transformers/styles/rules/reset.esm.js.map +1 -1
- package/dist/reader/transformers/styles/rules/rules.esm.js.map +1 -1
- package/dist/reader/transformers/styles/rules/typeset.esm.js.map +1 -1
- package/dist/reader/transformers/styles/rules/variables.esm.js.map +1 -1
- package/dist/reader/transformers/styles/transformer.esm.js.map +1 -1
- package/dist/reader/transformers/transformer.esm.js.map +1 -1
- package/dist/routes.esm.js.map +1 -1
- package/dist/search/components/TechDocsSearch.esm.js.map +1 -1
- package/dist/search/components/TechDocsSearchResultListItem.esm.js.map +1 -1
- package/dist/search/hooks/useTechDocsLocation.esm.js.map +1 -1
- package/dist/translation.esm.js.map +1 -1
- package/package.json +24 -24
|
@@ -1 +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
|
|
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":"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"}
|
|
@@ -1 +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
|
|
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;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -272,6 +272,10 @@ type TechDocsReaderPageContentProps = {
|
|
|
272
272
|
* Show or hide the search bar, defaults to true.
|
|
273
273
|
*/
|
|
274
274
|
withSearch?: boolean;
|
|
275
|
+
/**
|
|
276
|
+
* Show or hide the feedback button, defaults to true.
|
|
277
|
+
*/
|
|
278
|
+
withFeedbackLink?: boolean;
|
|
275
279
|
/**
|
|
276
280
|
* If {@link TechDocsReaderPageContentProps.withSearch | withSearch} is true,
|
|
277
281
|
* this will redirect the search result urls, e.g. turn search results into
|
|
@@ -1 +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
|
|
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]}
|
package/dist/plugin.esm.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { techdocsStorageApiRef, techdocsApiRef } from '@backstage/plugin-techdocs-react';
|
|
2
2
|
import { TechDocsStorageClient, TechDocsClient } from './client.esm.js';
|
|
3
|
-
import {
|
|
4
|
-
import { createPlugin, createApiFactory, fetchApiRef, discoveryApiRef, configApiRef
|
|
3
|
+
import { rootDocsRouteRef, rootCatalogDocsRouteRef, rootRouteRef } from './routes.esm.js';
|
|
4
|
+
import { createRoutableExtension, createPlugin, createApiFactory, fetchApiRef, discoveryApiRef, configApiRef } from '@backstage/core-plugin-api';
|
|
5
5
|
import { createSearchResultListItemExtension } from '@backstage/plugin-search-react';
|
|
6
6
|
|
|
7
7
|
const techdocsPlugin = createPlugin({
|
package/dist/plugin.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.esm.js","sources":["../src/plugin.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n techdocsApiRef,\n techdocsStorageApiRef,\n} from '@backstage/plugin-techdocs-react';\nimport { TechDocsClient, TechDocsStorageClient } from './client';\nimport {\n rootDocsRouteRef,\n rootRouteRef,\n rootCatalogDocsRouteRef,\n} from './routes';\nimport {\n configApiRef,\n createApiFactory,\n createPlugin,\n createRoutableExtension,\n discoveryApiRef,\n fetchApiRef,\n} from '@backstage/core-plugin-api';\nimport {\n createSearchResultListItemExtension,\n SearchResultListItemExtensionProps,\n} from '@backstage/plugin-search-react';\nimport { TechDocsSearchResultListItemProps } from './search/components/TechDocsSearchResultListItem';\n\n/**\n * The Backstage plugin that renders technical documentation for your components\n *\n * @public\n */\nexport const techdocsPlugin = createPlugin({\n id: 'techdocs',\n apis: [\n createApiFactory({\n api: techdocsStorageApiRef,\n deps: {\n configApi: configApiRef,\n discoveryApi: discoveryApiRef,\n fetchApi: fetchApiRef,\n },\n factory: ({ configApi, discoveryApi, fetchApi }) =>\n new TechDocsStorageClient({\n configApi,\n discoveryApi,\n fetchApi,\n }),\n }),\n createApiFactory({\n api: techdocsApiRef,\n deps: {\n configApi: configApiRef,\n discoveryApi: discoveryApiRef,\n fetchApi: fetchApiRef,\n },\n factory: ({ configApi, discoveryApi, fetchApi }) =>\n new TechDocsClient({\n configApi,\n discoveryApi,\n fetchApi,\n }),\n }),\n ],\n routes: {\n root: rootRouteRef,\n docRoot: rootDocsRouteRef,\n entityContent: rootCatalogDocsRouteRef,\n },\n});\n\n/**\n * Routable extension used to render docs\n *\n * @public\n */\nexport const TechdocsPage = techdocsPlugin.provide(\n createRoutableExtension({\n name: 'TechdocsPage',\n component: () => import('./Router').then(m => m.Router),\n mountPoint: rootRouteRef,\n }),\n);\n\n/**\n * Routable extension used to render docs on Entity page\n *\n * @public\n */\nexport const EntityTechdocsContent = techdocsPlugin.provide(\n createRoutableExtension({\n name: 'EntityTechdocsContent',\n component: () => import('./Router').then(m => m.LegacyEmbeddedDocsRouter),\n mountPoint: rootCatalogDocsRouteRef,\n }),\n);\n\n/**\n * Component which takes a custom tabs config object and renders a documentation landing page.\n *\n * @public\n */\nexport const TechDocsCustomHome = techdocsPlugin.provide(\n createRoutableExtension({\n name: 'TechDocsCustomHome',\n component: () =>\n import('./home/components/TechDocsCustomHome').then(\n m => m.TechDocsCustomHome,\n ),\n mountPoint: rootRouteRef,\n }),\n);\n\n/**\n * Responsible for rendering the provided router element\n *\n * @public\n */\nexport const TechDocsIndexPage = techdocsPlugin.provide(\n createRoutableExtension({\n name: 'TechDocsIndexPage',\n component: () =>\n import('./home/components/TechDocsIndexPage').then(\n m => m.TechDocsIndexPage,\n ),\n mountPoint: rootRouteRef,\n }),\n);\n\n/**\n * Component responsible for composing a TechDocs reader page experience\n *\n * @public\n */\nexport const TechDocsReaderPage = techdocsPlugin.provide(\n createRoutableExtension({\n name: 'TechDocsReaderPage',\n component: () =>\n import('./reader/components/TechDocsReaderPage').then(\n m => m.TechDocsReaderPage,\n ),\n mountPoint: rootDocsRouteRef,\n }),\n);\n\n/**\n * React extension used to render results on Search page or modal\n *\n * @public\n */\nexport const TechDocsSearchResultListItem: (\n props: SearchResultListItemExtensionProps<TechDocsSearchResultListItemProps>,\n) => JSX.Element | null = techdocsPlugin.provide(\n createSearchResultListItemExtension({\n name: 'TechDocsSearchResultListItem',\n component: () =>\n import('./search/components/TechDocsSearchResultListItem').then(\n m => m.TechDocsSearchResultListItem,\n ),\n predicate: result => result.type === 'techdocs',\n }),\n);\n"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"plugin.esm.js","sources":["../src/plugin.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n techdocsApiRef,\n techdocsStorageApiRef,\n} from '@backstage/plugin-techdocs-react';\nimport { TechDocsClient, TechDocsStorageClient } from './client';\nimport {\n rootDocsRouteRef,\n rootRouteRef,\n rootCatalogDocsRouteRef,\n} from './routes';\nimport {\n configApiRef,\n createApiFactory,\n createPlugin,\n createRoutableExtension,\n discoveryApiRef,\n fetchApiRef,\n} from '@backstage/core-plugin-api';\nimport {\n createSearchResultListItemExtension,\n SearchResultListItemExtensionProps,\n} from '@backstage/plugin-search-react';\nimport { TechDocsSearchResultListItemProps } from './search/components/TechDocsSearchResultListItem';\n\n/**\n * The Backstage plugin that renders technical documentation for your components\n *\n * @public\n */\nexport const techdocsPlugin = createPlugin({\n id: 'techdocs',\n apis: [\n createApiFactory({\n api: techdocsStorageApiRef,\n deps: {\n configApi: configApiRef,\n discoveryApi: discoveryApiRef,\n fetchApi: fetchApiRef,\n },\n factory: ({ configApi, discoveryApi, fetchApi }) =>\n new TechDocsStorageClient({\n configApi,\n discoveryApi,\n fetchApi,\n }),\n }),\n createApiFactory({\n api: techdocsApiRef,\n deps: {\n configApi: configApiRef,\n discoveryApi: discoveryApiRef,\n fetchApi: fetchApiRef,\n },\n factory: ({ configApi, discoveryApi, fetchApi }) =>\n new TechDocsClient({\n configApi,\n discoveryApi,\n fetchApi,\n }),\n }),\n ],\n routes: {\n root: rootRouteRef,\n docRoot: rootDocsRouteRef,\n entityContent: rootCatalogDocsRouteRef,\n },\n});\n\n/**\n * Routable extension used to render docs\n *\n * @public\n */\nexport const TechdocsPage = techdocsPlugin.provide(\n createRoutableExtension({\n name: 'TechdocsPage',\n component: () => import('./Router').then(m => m.Router),\n mountPoint: rootRouteRef,\n }),\n);\n\n/**\n * Routable extension used to render docs on Entity page\n *\n * @public\n */\nexport const EntityTechdocsContent = techdocsPlugin.provide(\n createRoutableExtension({\n name: 'EntityTechdocsContent',\n component: () => import('./Router').then(m => m.LegacyEmbeddedDocsRouter),\n mountPoint: rootCatalogDocsRouteRef,\n }),\n);\n\n/**\n * Component which takes a custom tabs config object and renders a documentation landing page.\n *\n * @public\n */\nexport const TechDocsCustomHome = techdocsPlugin.provide(\n createRoutableExtension({\n name: 'TechDocsCustomHome',\n component: () =>\n import('./home/components/TechDocsCustomHome').then(\n m => m.TechDocsCustomHome,\n ),\n mountPoint: rootRouteRef,\n }),\n);\n\n/**\n * Responsible for rendering the provided router element\n *\n * @public\n */\nexport const TechDocsIndexPage = techdocsPlugin.provide(\n createRoutableExtension({\n name: 'TechDocsIndexPage',\n component: () =>\n import('./home/components/TechDocsIndexPage').then(\n m => m.TechDocsIndexPage,\n ),\n mountPoint: rootRouteRef,\n }),\n);\n\n/**\n * Component responsible for composing a TechDocs reader page experience\n *\n * @public\n */\nexport const TechDocsReaderPage = techdocsPlugin.provide(\n createRoutableExtension({\n name: 'TechDocsReaderPage',\n component: () =>\n import('./reader/components/TechDocsReaderPage').then(\n m => m.TechDocsReaderPage,\n ),\n mountPoint: rootDocsRouteRef,\n }),\n);\n\n/**\n * React extension used to render results on Search page or modal\n *\n * @public\n */\nexport const TechDocsSearchResultListItem: (\n props: SearchResultListItemExtensionProps<TechDocsSearchResultListItemProps>,\n) => JSX.Element | null = techdocsPlugin.provide(\n createSearchResultListItemExtension({\n name: 'TechDocsSearchResultListItem',\n component: () =>\n import('./search/components/TechDocsSearchResultListItem').then(\n m => m.TechDocsSearchResultListItem,\n ),\n predicate: result => result.type === 'techdocs',\n }),\n);\n"],"names":[],"mappings":"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"}
|
|
@@ -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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TechDocsBuildLogs.esm.js","sources":["../../../src/reader/components/TechDocsBuildLogs.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 { LogViewer } from '@backstage/core-components';\nimport Button from '@material-ui/core/Button';\nimport Drawer from '@material-ui/core/Drawer';\nimport Grid from '@material-ui/core/Grid';\nimport IconButton from '@material-ui/core/IconButton';\nimport Typography from '@material-ui/core/Typography';\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\nimport Close from '@material-ui/icons/Close';\nimport { useState } from 'react';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { techdocsTranslationRef } from '../../translation';\n\nconst useDrawerStyles = makeStyles((theme: Theme) =>\n createStyles({\n paper: {\n width: '100%',\n [theme.breakpoints.up('sm')]: {\n width: '75%',\n },\n [theme.breakpoints.up('md')]: {\n width: '50%',\n },\n padding: theme.spacing(2.5),\n },\n root: {\n height: '100%',\n overflow: 'hidden',\n },\n logs: {\n background: theme.palette.background.default,\n },\n }),\n);\n\nexport const TechDocsBuildLogsDrawerContent = ({\n buildLog,\n onClose,\n}: {\n buildLog: string[];\n onClose: () => void;\n}) => {\n const classes = useDrawerStyles();\n const { t } = useTranslationRef(techdocsTranslationRef);\n const logText =\n buildLog.length === 0 ? t('buildLogs.waitingForLogs') : buildLog.join('\\n');\n return (\n <Grid\n container\n direction=\"column\"\n className={classes.root}\n spacing={0}\n wrap=\"nowrap\"\n >\n <Grid\n item\n container\n justifyContent=\"space-between\"\n alignItems=\"center\"\n spacing={0}\n wrap=\"nowrap\"\n >\n <Typography variant=\"h5\">{t('buildLogs.title')}</Typography>\n <IconButton\n key=\"dismiss\"\n title={t('buildLogs.closeDrawer')}\n onClick={onClose}\n color=\"inherit\"\n >\n <Close />\n </IconButton>\n </Grid>\n <Grid item xs>\n <LogViewer text={logText} classes={{ root: classes.logs }} />\n </Grid>\n </Grid>\n );\n};\n\nexport const TechDocsBuildLogs = ({ buildLog }: { buildLog: string[] }) => {\n const classes = useDrawerStyles();\n const [open, setOpen] = useState(false);\n const { t } = useTranslationRef(techdocsTranslationRef);\n\n return (\n <>\n <Button color=\"inherit\" onClick={() => setOpen(true)}>\n {t('buildLogs.showBuildLogs')}\n </Button>\n <Drawer\n classes={{ paper: classes.paper }}\n anchor=\"right\"\n open={open}\n onClose={() => setOpen(false)}\n >\n <TechDocsBuildLogsDrawerContent\n buildLog={buildLog}\n onClose={() => setOpen(false)}\n />\n </Drawer>\n </>\n );\n};\n"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"TechDocsBuildLogs.esm.js","sources":["../../../src/reader/components/TechDocsBuildLogs.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 { LogViewer } from '@backstage/core-components';\nimport Button from '@material-ui/core/Button';\nimport Drawer from '@material-ui/core/Drawer';\nimport Grid from '@material-ui/core/Grid';\nimport IconButton from '@material-ui/core/IconButton';\nimport Typography from '@material-ui/core/Typography';\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\nimport Close from '@material-ui/icons/Close';\nimport { useState } from 'react';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { techdocsTranslationRef } from '../../translation';\n\nconst useDrawerStyles = makeStyles((theme: Theme) =>\n createStyles({\n paper: {\n width: '100%',\n [theme.breakpoints.up('sm')]: {\n width: '75%',\n },\n [theme.breakpoints.up('md')]: {\n width: '50%',\n },\n padding: theme.spacing(2.5),\n },\n root: {\n height: '100%',\n overflow: 'hidden',\n },\n logs: {\n background: theme.palette.background.default,\n },\n }),\n);\n\nexport const TechDocsBuildLogsDrawerContent = ({\n buildLog,\n onClose,\n}: {\n buildLog: string[];\n onClose: () => void;\n}) => {\n const classes = useDrawerStyles();\n const { t } = useTranslationRef(techdocsTranslationRef);\n const logText =\n buildLog.length === 0 ? t('buildLogs.waitingForLogs') : buildLog.join('\\n');\n return (\n <Grid\n container\n direction=\"column\"\n className={classes.root}\n spacing={0}\n wrap=\"nowrap\"\n >\n <Grid\n item\n container\n justifyContent=\"space-between\"\n alignItems=\"center\"\n spacing={0}\n wrap=\"nowrap\"\n >\n <Typography variant=\"h5\">{t('buildLogs.title')}</Typography>\n <IconButton\n key=\"dismiss\"\n title={t('buildLogs.closeDrawer')}\n onClick={onClose}\n color=\"inherit\"\n >\n <Close />\n </IconButton>\n </Grid>\n <Grid item xs>\n <LogViewer text={logText} classes={{ root: classes.logs }} />\n </Grid>\n </Grid>\n );\n};\n\nexport const TechDocsBuildLogs = ({ buildLog }: { buildLog: string[] }) => {\n const classes = useDrawerStyles();\n const [open, setOpen] = useState(false);\n const { t } = useTranslationRef(techdocsTranslationRef);\n\n return (\n <>\n <Button color=\"inherit\" onClick={() => setOpen(true)}>\n {t('buildLogs.showBuildLogs')}\n </Button>\n <Drawer\n classes={{ paper: classes.paper }}\n anchor=\"right\"\n open={open}\n onClose={() => setOpen(false)}\n >\n <TechDocsBuildLogsDrawerContent\n buildLog={buildLog}\n onClose={() => setOpen(false)}\n />\n </Drawer>\n </>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;AA4BA,MAAM,eAAA,GAAkB,UAAA;AAAA,EAAW,CAAC,UAClC,YAAA,CAAa;AAAA,IACX,KAAA,EAAO;AAAA,MACL,KAAA,EAAO,MAAA;AAAA,MACP,CAAC,KAAA,CAAM,WAAA,CAAY,EAAA,CAAG,IAAI,CAAC,GAAG;AAAA,QAC5B,KAAA,EAAO;AAAA,OACT;AAAA,MACA,CAAC,KAAA,CAAM,WAAA,CAAY,EAAA,CAAG,IAAI,CAAC,GAAG;AAAA,QAC5B,KAAA,EAAO;AAAA,OACT;AAAA,MACA,OAAA,EAAS,KAAA,CAAM,OAAA,CAAQ,GAAG;AAAA,KAC5B;AAAA,IACA,IAAA,EAAM;AAAA,MACJ,MAAA,EAAQ,MAAA;AAAA,MACR,QAAA,EAAU;AAAA,KACZ;AAAA,IACA,IAAA,EAAM;AAAA,MACJ,UAAA,EAAY,KAAA,CAAM,OAAA,CAAQ,UAAA,CAAW;AAAA;AACvC,GACD;AACH,CAAA;AAEO,MAAM,iCAAiC,CAAC;AAAA,EAC7C,QAAA;AAAA,EACA;AACF,CAAA,KAGM;AACJ,EAAA,MAAM,UAAU,eAAA,EAAgB;AAChC,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,iBAAA,CAAkB,sBAAsB,CAAA;AACtD,EAAA,MAAM,OAAA,GACJ,SAAS,MAAA,KAAW,CAAA,GAAI,EAAE,0BAA0B,CAAA,GAAI,QAAA,CAAS,IAAA,CAAK,IAAI,CAAA;AAC5E,EAAA,uBACE,IAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAS,IAAA;AAAA,MACT,SAAA,EAAU,QAAA;AAAA,MACV,WAAW,OAAA,CAAQ,IAAA;AAAA,MACnB,OAAA,EAAS,CAAA;AAAA,MACT,IAAA,EAAK,QAAA;AAAA,MAEL,QAAA,EAAA;AAAA,wBAAA,IAAA;AAAA,UAAC,IAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAI,IAAA;AAAA,YACJ,SAAA,EAAS,IAAA;AAAA,YACT,cAAA,EAAe,eAAA;AAAA,YACf,UAAA,EAAW,QAAA;AAAA,YACX,OAAA,EAAS,CAAA;AAAA,YACT,IAAA,EAAK,QAAA;AAAA,YAEL,QAAA,EAAA;AAAA,8BAAA,GAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,IAAA,EAAM,QAAA,EAAA,CAAA,CAAE,iBAAiB,CAAA,EAAE,CAAA;AAAA,8BAC/C,GAAA;AAAA,gBAAC,UAAA;AAAA,gBAAA;AAAA,kBAEC,KAAA,EAAO,EAAE,uBAAuB,CAAA;AAAA,kBAChC,OAAA,EAAS,OAAA;AAAA,kBACT,KAAA,EAAM,SAAA;AAAA,kBAEN,8BAAC,KAAA,EAAA,EAAM;AAAA,iBAAA;AAAA,gBALH;AAAA;AAMN;AAAA;AAAA,SACF;AAAA,4BACC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,EAAA,EAAE,MACX,QAAA,kBAAA,GAAA,CAAC,SAAA,EAAA,EAAU,IAAA,EAAM,OAAA,EAAS,SAAS,EAAE,IAAA,EAAM,OAAA,CAAQ,IAAA,IAAQ,CAAA,EAC7D;AAAA;AAAA;AAAA,GACF;AAEJ;AAEO,MAAM,iBAAA,GAAoB,CAAC,EAAE,QAAA,EAAS,KAA8B;AACzE,EAAA,MAAM,UAAU,eAAA,EAAgB;AAChC,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAAS,KAAK,CAAA;AACtC,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,iBAAA,CAAkB,sBAAsB,CAAA;AAEtD,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,MAAA,EAAA,EAAO,KAAA,EAAM,SAAA,EAAU,OAAA,EAAS,MAAM,QAAQ,IAAI,CAAA,EAChD,QAAA,EAAA,CAAA,CAAE,yBAAyB,CAAA,EAC9B,CAAA;AAAA,oBACA,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAS,EAAE,KAAA,EAAO,OAAA,CAAQ,KAAA,EAAM;AAAA,QAChC,MAAA,EAAO,OAAA;AAAA,QACP,IAAA;AAAA,QACA,OAAA,EAAS,MAAM,OAAA,CAAQ,KAAK,CAAA;AAAA,QAE5B,QAAA,kBAAA,GAAA;AAAA,UAAC,8BAAA;AAAA,UAAA;AAAA,YACC,QAAA;AAAA,YACA,OAAA,EAAS,MAAM,OAAA,CAAQ,KAAK;AAAA;AAAA;AAC9B;AAAA;AACF,GAAA,EACF,CAAA;AAEJ;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TechDocsNotFound.esm.js","sources":["../../../src/reader/components/TechDocsNotFound.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useEffect } from 'react';\nimport { useApi, configApiRef, useAnalytics } from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { ErrorPage } from '@backstage/core-components';\nimport { useTechDocsReaderPage } from '@backstage/plugin-techdocs-react';\nimport { useLocation } from 'react-router-dom';\nimport { techdocsTranslationRef } from '../../translation';\n\ntype Props = {\n errorMessage?: string;\n};\n\nexport const TechDocsNotFound = ({ errorMessage }: Props) => {\n const techdocsBuilder =\n useApi(configApiRef).getOptionalString('techdocs.builder');\n const analyticsApi = useAnalytics();\n const { entityRef } = useTechDocsReaderPage();\n const location = useLocation();\n const { t } = useTranslationRef(techdocsTranslationRef);\n\n useEffect(() => {\n const { pathname, search, hash } = location;\n analyticsApi.captureEvent('not-found', `${pathname}${search}${hash}`, {\n attributes: entityRef,\n });\n }, [analyticsApi, entityRef, location]);\n\n let additionalInfo = '';\n if (![undefined, 'local'].includes(techdocsBuilder)) {\n additionalInfo = t('notFound.builderNote');\n }\n\n return (\n <ErrorPage\n status=\"404\"\n statusMessage={errorMessage || t('notFound.title')}\n additionalInfo={additionalInfo}\n />\n );\n};\n"],"names":[],"mappings":";;;;;;;;;AA4BO,MAAM,gBAAA,GAAmB,CAAC,EAAE,YAAA,EAAa,KAAa;AAC3D,EAAA,MAAM,eAAA,GACJ,MAAA,CAAO,YAAY,CAAA,CAAE,kBAAkB,kBAAkB,CAAA;AAC3D,EAAA,MAAM,eAAe,YAAA,EAAa;AAClC,EAAA,MAAM,EAAE,SAAA,EAAU,GAAI,qBAAA,EAAsB;AAC5C,EAAA,MAAM,WAAW,WAAA,EAAY;AAC7B,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,iBAAA,CAAkB,sBAAsB,CAAA;AAEtD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,EAAE,QAAA,EAAU,MAAA,EAAQ,IAAA,EAAK,GAAI,QAAA;AACnC,IAAA,YAAA,CAAa,YAAA,CAAa,aAAa,CAAA,EAAG,QAAQ,GAAG,MAAM,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI;AAAA,MACpE,UAAA,EAAY;AAAA,KACb,CAAA;AAAA,EACH,CAAA,EAAG,CAAC,YAAA,EAAc,SAAA,EAAW,QAAQ,CAAC,CAAA;AAEtC,EAAA,IAAI,cAAA,GAAiB,EAAA;AACrB,EAAA,IAAI,CAAC,CAAC,MAAA,EAAW,OAAO,CAAA,CAAE,QAAA,CAAS,eAAe,CAAA,EAAG;AACnD,IAAA,cAAA,GAAiB,EAAE,sBAAsB,CAAA;AAAA,EAC3C;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,MAAA,EAAO,KAAA;AAAA,MACP,aAAA,EAAe,YAAA,IAAgB,CAAA,CAAE,gBAAgB,CAAA;AAAA,MACjD;AAAA;AAAA,GACF;AAEJ
|
|
1
|
+
{"version":3,"file":"TechDocsNotFound.esm.js","sources":["../../../src/reader/components/TechDocsNotFound.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useEffect } from 'react';\nimport { useApi, configApiRef, useAnalytics } from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { ErrorPage } from '@backstage/core-components';\nimport { useTechDocsReaderPage } from '@backstage/plugin-techdocs-react';\nimport { useLocation } from 'react-router-dom';\nimport { techdocsTranslationRef } from '../../translation';\n\ntype Props = {\n errorMessage?: string;\n};\n\nexport const TechDocsNotFound = ({ errorMessage }: Props) => {\n const techdocsBuilder =\n useApi(configApiRef).getOptionalString('techdocs.builder');\n const analyticsApi = useAnalytics();\n const { entityRef } = useTechDocsReaderPage();\n const location = useLocation();\n const { t } = useTranslationRef(techdocsTranslationRef);\n\n useEffect(() => {\n const { pathname, search, hash } = location;\n analyticsApi.captureEvent('not-found', `${pathname}${search}${hash}`, {\n attributes: entityRef,\n });\n }, [analyticsApi, entityRef, location]);\n\n let additionalInfo = '';\n if (![undefined, 'local'].includes(techdocsBuilder)) {\n additionalInfo = t('notFound.builderNote');\n }\n\n return (\n <ErrorPage\n status=\"404\"\n statusMessage={errorMessage || t('notFound.title')}\n additionalInfo={additionalInfo}\n />\n );\n};\n"],"names":[],"mappings":";;;;;;;;;AA4BO,MAAM,gBAAA,GAAmB,CAAC,EAAE,YAAA,EAAa,KAAa;AAC3D,EAAA,MAAM,eAAA,GACJ,MAAA,CAAO,YAAY,CAAA,CAAE,kBAAkB,kBAAkB,CAAA;AAC3D,EAAA,MAAM,eAAe,YAAA,EAAa;AAClC,EAAA,MAAM,EAAE,SAAA,EAAU,GAAI,qBAAA,EAAsB;AAC5C,EAAA,MAAM,WAAW,WAAA,EAAY;AAC7B,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,iBAAA,CAAkB,sBAAsB,CAAA;AAEtD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,EAAE,QAAA,EAAU,MAAA,EAAQ,IAAA,EAAK,GAAI,QAAA;AACnC,IAAA,YAAA,CAAa,YAAA,CAAa,aAAa,CAAA,EAAG,QAAQ,GAAG,MAAM,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI;AAAA,MACpE,UAAA,EAAY;AAAA,KACb,CAAA;AAAA,EACH,CAAA,EAAG,CAAC,YAAA,EAAc,SAAA,EAAW,QAAQ,CAAC,CAAA;AAEtC,EAAA,IAAI,cAAA,GAAiB,EAAA;AACrB,EAAA,IAAI,CAAC,CAAC,MAAA,EAAW,OAAO,CAAA,CAAE,QAAA,CAAS,eAAe,CAAA,EAAG;AACnD,IAAA,cAAA,GAAiB,EAAE,sBAAsB,CAAA;AAAA,EAC3C;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,MAAA,EAAO,KAAA;AAAA,MACP,aAAA,EAAe,YAAA,IAAgB,CAAA,CAAE,gBAAgB,CAAA;AAAA,MACjD;AAAA;AAAA,GACF;AAEJ;;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import { useMemo, Children } from 'react';
|
|
3
3
|
import { useOutlet } from 'react-router-dom';
|
|
4
|
-
import {
|
|
4
|
+
import { Progress, Page } from '@backstage/core-components';
|
|
5
5
|
import { TECHDOCS_ADDONS_WRAPPER_KEY, TECHDOCS_ADDONS_KEY, TechDocsReaderPageProvider } from '@backstage/plugin-techdocs-react';
|
|
6
6
|
import { TechDocsReaderPageContent } from '../TechDocsReaderPageContent/TechDocsReaderPageContent.esm.js';
|
|
7
7
|
import { TechDocsReaderPageHeader } from '../TechDocsReaderPageHeader/TechDocsReaderPageHeader.esm.js';
|
|
@@ -9,7 +9,7 @@ import { TechDocsReaderPageSubheader } from '../TechDocsReaderPageSubheader/Tech
|
|
|
9
9
|
import { rootDocsRouteRef } from '../../../routes.esm.js';
|
|
10
10
|
import { useRouteRefParams, getComponentData } from '@backstage/core-plugin-api';
|
|
11
11
|
import { CookieAuthRefreshProvider } from '@backstage/plugin-auth-react';
|
|
12
|
-
import {
|
|
12
|
+
import { useTheme, createTheme, ThemeProvider, styled } from '@material-ui/core/styles';
|
|
13
13
|
import { useExternalRedirect } from './useExternalRedirect.esm.js';
|
|
14
14
|
|
|
15
15
|
const TechDocsReaderLayout = (props) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TechDocsReaderPage.esm.js","sources":["../../../../src/reader/components/TechDocsReaderPage/TechDocsReaderPage.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 { Children, ReactElement, ReactNode, useMemo } from 'react';\nimport { useOutlet } from 'react-router-dom';\nimport { Page, Progress } from '@backstage/core-components';\nimport { CompoundEntityRef } from '@backstage/catalog-model';\nimport {\n TECHDOCS_ADDONS_KEY,\n TECHDOCS_ADDONS_WRAPPER_KEY,\n TechDocsReaderPageProvider,\n} from '@backstage/plugin-techdocs-react';\nimport { TechDocsReaderPageRenderFunction } from '../../../types';\nimport { TechDocsReaderPageContent } from '../TechDocsReaderPageContent';\nimport { TechDocsReaderPageHeader } from '../TechDocsReaderPageHeader';\nimport { TechDocsReaderPageSubheader } from '../TechDocsReaderPageSubheader';\nimport { rootDocsRouteRef } from '../../../routes';\nimport {\n getComponentData,\n useRouteRefParams,\n} from '@backstage/core-plugin-api';\nimport { CookieAuthRefreshProvider } from '@backstage/plugin-auth-react';\nimport {\n createTheme,\n styled,\n ThemeOptions,\n ThemeProvider,\n useTheme,\n} from '@material-ui/core/styles';\nimport { useExternalRedirect } from './useExternalRedirect';\n\n/* An explanation for the multiple ways of customizing the TechDocs reader page\n\nPlease refer to this page on the microsite for the latest recommended approach:\nhttps://backstage.io/docs/features/techdocs/how-to-guides#how-to-customize-the-techdocs-reader-page\n\nThe <TechDocsReaderPage> component is responsible for rendering the <TechDocsReaderPageProvider> and\nits contained version of a <Page>, which in turn renders the <TechDocsReaderPageContent>.\n\nHistorically, there have been different approaches on how this <Page> can be customized, and how the\n<TechDocsReaderPageContent> inside could be exchanged for a custom implementation (which was not\npossible before). Also, the current implementation supports every scenario to avoid breaking default\nconfigurations of TechDocs.\n\nIn particular, there are 4 different TechDocs page configurations:\n\nCONFIGURATION 1: <TechDocsReaderPage> only, no children\n\n<Route path=\"/docs/:namespace/:kind/:name/*\" element={<TechDocsReaderPage />} >\n\nThis is the simplest way to use TechDocs. Only a full page is passed, assuming that it comes with\nits content inside. Since we allowed customizing it, we started providing <TechDocsReaderLayout> as\na default implementation (which contains <TechDocsReaderPageContent>).\n\nCONFIGURATION 2 (not advised): <TechDocsReaderPage> with element children\n\n<Route\n path=\"/docs/:namespace/:kind/:name/*\"\n element={\n <TechDocsReaderPage>\n {techdocsPage}\n </TechDocsReaderPage>\n }\n/>\n\nPreviously, there were two ways of passing children to <TechDocsReaderPage>: either as elements (as\nshown above), or as a render function (described below in CONFIGURATION 3). The \"techdocsPage\" is\nlocated in packages/app/src/components/techdocs and is the default implementation of the content\ninside.\n\nCONFIGURATION 3 (not advised): <TechDocsReaderPage> with render function as child\n\n<Route\n path=\"/docs/:namespace/:kind/:name/*\"\n element={\n <TechDocsReaderPage>\n {({ metadata, entityMetadata, onReady }) => (\n techdocsPage\n )}\n </TechDocsReaderPage>\n }\n/>\n\nSimilar to CONFIGURATION 2, the direct children will be passed to the <TechDocsReaderPage> but in\nthis case interpreted as render prop.\n\nCONFIGURATION 4: <TechDocsReaderPage> and provided content in <Route>\n\n<Route\n path=\"/docs/:namespace/:kind/:name/*\"\n element={<TechDocsReaderPage />}\n>\n {techDocsPage}\n <TechDocsAddons>\n <ExpandableNavigation />\n <ReportIssue />\n <TextSize />\n <LightBox />\n </TechDocsAddons>\n</Route>\n\nThis is the current state in packages/app/src/App.tsx and moved the location of children from inside\nthe element prop in the <Route> to the children of the <Route>. Then, in <TechDocsReaderPage> they\nare retrieved using the useOutlet hook from React Router.\n\nNOTE: Render functions are no longer supported in this approach.\n*/\n\n/**\n * Props for {@link TechDocsReaderLayout}\n * @public\n */\nexport type TechDocsReaderLayoutProps = {\n /**\n * Show or hide the header, defaults to true.\n */\n withHeader?: boolean;\n /**\n * Show or hide the content search bar, defaults to true.\n */\n withSearch?: boolean;\n};\n\n/**\n * Default TechDocs reader page structure composed with a header and content\n * @public\n */\nexport const TechDocsReaderLayout = (props: TechDocsReaderLayoutProps) => {\n const { withSearch, withHeader = true } = props;\n return (\n <Page themeId=\"documentation\">\n {withHeader && <TechDocsReaderPageHeader />}\n <TechDocsReaderPageSubheader />\n <TechDocsReaderPageContent withSearch={withSearch} />\n </Page>\n );\n};\n\n/**\n * @public\n */\nexport type TechDocsReaderPageProps = {\n entityRef?: CompoundEntityRef;\n children?: TechDocsReaderPageRenderFunction | ReactNode;\n overrideThemeOptions?: Partial<ThemeOptions>;\n};\n\n/**\n * Styled Backstage Page that fills available vertical space\n */\nconst StyledPage = styled(Page)({\n height: 'inherit',\n overflowY: 'visible',\n});\n\n/**\n * An addon-aware implementation of the TechDocsReaderPage.\n *\n * @public\n */\nexport const TechDocsReaderPage = (props: TechDocsReaderPageProps) => {\n const currentTheme = useTheme();\n\n const readerPageTheme = useMemo(\n () =>\n createTheme({\n ...currentTheme,\n ...(props.overrideThemeOptions || {}),\n }),\n [currentTheme, props.overrideThemeOptions],\n );\n\n const { kind, name, namespace } = useRouteRefParams(rootDocsRouteRef);\n const { children, entityRef = { kind, name, namespace } } = props;\n\n const outlet = useOutlet();\n\n const memoizedEntityRef = useMemo(\n () => ({\n kind: entityRef.kind,\n name: entityRef.name,\n namespace: entityRef.namespace,\n }),\n [entityRef.kind, entityRef.name, entityRef.namespace],\n );\n\n // Check for external TechDocs redirects and handle navigation\n const { shouldShowProgress } = useExternalRedirect(memoizedEntityRef);\n\n const page: ReactNode = useMemo(() => {\n if (children) {\n return null;\n }\n\n const childrenList = outlet ? Children.toArray(outlet.props.children) : [];\n\n const grandChildren = childrenList.flatMap<ReactElement>(\n child => (child as ReactElement)?.props?.children ?? [],\n );\n\n return grandChildren.find(\n grandChild =>\n !getComponentData(grandChild, TECHDOCS_ADDONS_WRAPPER_KEY) &&\n !getComponentData(grandChild, TECHDOCS_ADDONS_KEY),\n );\n }, [children, outlet]);\n\n // Show full-page loading spinner when checking for external redirects or about to redirect.\n // This replaces the entire page content (header, sidebar, and documentation).\n if (shouldShowProgress) {\n return <Progress />;\n }\n\n // As explained above, \"page\" is configuration 4 and <TechDocsReaderLayout> is 1\n if (!children) {\n return (\n <ThemeProvider theme={readerPageTheme}>\n <CookieAuthRefreshProvider pluginId=\"techdocs\">\n <TechDocsReaderPageProvider entityRef={memoizedEntityRef}>\n {(page as JSX.Element) || <TechDocsReaderLayout />}\n </TechDocsReaderPageProvider>\n </CookieAuthRefreshProvider>\n </ThemeProvider>\n );\n }\n\n // As explained above, a render function is configuration 3 and React element is 2\n return (\n <ThemeProvider theme={readerPageTheme}>\n <CookieAuthRefreshProvider pluginId=\"techdocs\">\n <TechDocsReaderPageProvider entityRef={memoizedEntityRef}>\n {({ metadata, entityMetadata, onReady }) => (\n <StyledPage\n themeId=\"documentation\"\n className=\"techdocs-reader-page\"\n >\n {children instanceof Function\n ? children({\n entityRef: memoizedEntityRef,\n techdocsMetadataValue: metadata.value,\n entityMetadataValue: entityMetadata.value,\n onReady,\n })\n : children}\n </StyledPage>\n )}\n </TechDocsReaderPageProvider>\n </CookieAuthRefreshProvider>\n </ThemeProvider>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TechDocsReaderPage.esm.js","sources":["../../../../src/reader/components/TechDocsReaderPage/TechDocsReaderPage.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 { Children, ReactElement, ReactNode, useMemo } from 'react';\nimport { useOutlet } from 'react-router-dom';\nimport { Page, Progress } from '@backstage/core-components';\nimport { CompoundEntityRef } from '@backstage/catalog-model';\nimport {\n TECHDOCS_ADDONS_KEY,\n TECHDOCS_ADDONS_WRAPPER_KEY,\n TechDocsReaderPageProvider,\n} from '@backstage/plugin-techdocs-react';\nimport { TechDocsReaderPageRenderFunction } from '../../../types';\nimport { TechDocsReaderPageContent } from '../TechDocsReaderPageContent';\nimport { TechDocsReaderPageHeader } from '../TechDocsReaderPageHeader';\nimport { TechDocsReaderPageSubheader } from '../TechDocsReaderPageSubheader';\nimport { rootDocsRouteRef } from '../../../routes';\nimport {\n getComponentData,\n useRouteRefParams,\n} from '@backstage/core-plugin-api';\nimport { CookieAuthRefreshProvider } from '@backstage/plugin-auth-react';\nimport {\n createTheme,\n styled,\n ThemeOptions,\n ThemeProvider,\n useTheme,\n} from '@material-ui/core/styles';\nimport { useExternalRedirect } from './useExternalRedirect';\n\n/* An explanation for the multiple ways of customizing the TechDocs reader page\n\nPlease refer to this page on the microsite for the latest recommended approach:\nhttps://backstage.io/docs/features/techdocs/how-to-guides#how-to-customize-the-techdocs-reader-page\n\nThe <TechDocsReaderPage> component is responsible for rendering the <TechDocsReaderPageProvider> and\nits contained version of a <Page>, which in turn renders the <TechDocsReaderPageContent>.\n\nHistorically, there have been different approaches on how this <Page> can be customized, and how the\n<TechDocsReaderPageContent> inside could be exchanged for a custom implementation (which was not\npossible before). Also, the current implementation supports every scenario to avoid breaking default\nconfigurations of TechDocs.\n\nIn particular, there are 4 different TechDocs page configurations:\n\nCONFIGURATION 1: <TechDocsReaderPage> only, no children\n\n<Route path=\"/docs/:namespace/:kind/:name/*\" element={<TechDocsReaderPage />} >\n\nThis is the simplest way to use TechDocs. Only a full page is passed, assuming that it comes with\nits content inside. Since we allowed customizing it, we started providing <TechDocsReaderLayout> as\na default implementation (which contains <TechDocsReaderPageContent>).\n\nCONFIGURATION 2 (not advised): <TechDocsReaderPage> with element children\n\n<Route\n path=\"/docs/:namespace/:kind/:name/*\"\n element={\n <TechDocsReaderPage>\n {techdocsPage}\n </TechDocsReaderPage>\n }\n/>\n\nPreviously, there were two ways of passing children to <TechDocsReaderPage>: either as elements (as\nshown above), or as a render function (described below in CONFIGURATION 3). The \"techdocsPage\" is\nlocated in packages/app/src/components/techdocs and is the default implementation of the content\ninside.\n\nCONFIGURATION 3 (not advised): <TechDocsReaderPage> with render function as child\n\n<Route\n path=\"/docs/:namespace/:kind/:name/*\"\n element={\n <TechDocsReaderPage>\n {({ metadata, entityMetadata, onReady }) => (\n techdocsPage\n )}\n </TechDocsReaderPage>\n }\n/>\n\nSimilar to CONFIGURATION 2, the direct children will be passed to the <TechDocsReaderPage> but in\nthis case interpreted as render prop.\n\nCONFIGURATION 4: <TechDocsReaderPage> and provided content in <Route>\n\n<Route\n path=\"/docs/:namespace/:kind/:name/*\"\n element={<TechDocsReaderPage />}\n>\n {techDocsPage}\n <TechDocsAddons>\n <ExpandableNavigation />\n <ReportIssue />\n <TextSize />\n <LightBox />\n </TechDocsAddons>\n</Route>\n\nThis is the current state in packages/app/src/App.tsx and moved the location of children from inside\nthe element prop in the <Route> to the children of the <Route>. Then, in <TechDocsReaderPage> they\nare retrieved using the useOutlet hook from React Router.\n\nNOTE: Render functions are no longer supported in this approach.\n*/\n\n/**\n * Props for {@link TechDocsReaderLayout}\n * @public\n */\nexport type TechDocsReaderLayoutProps = {\n /**\n * Show or hide the header, defaults to true.\n */\n withHeader?: boolean;\n /**\n * Show or hide the content search bar, defaults to true.\n */\n withSearch?: boolean;\n};\n\n/**\n * Default TechDocs reader page structure composed with a header and content\n * @public\n */\nexport const TechDocsReaderLayout = (props: TechDocsReaderLayoutProps) => {\n const { withSearch, withHeader = true } = props;\n return (\n <Page themeId=\"documentation\">\n {withHeader && <TechDocsReaderPageHeader />}\n <TechDocsReaderPageSubheader />\n <TechDocsReaderPageContent withSearch={withSearch} />\n </Page>\n );\n};\n\n/**\n * @public\n */\nexport type TechDocsReaderPageProps = {\n entityRef?: CompoundEntityRef;\n children?: TechDocsReaderPageRenderFunction | ReactNode;\n overrideThemeOptions?: Partial<ThemeOptions>;\n};\n\n/**\n * Styled Backstage Page that fills available vertical space\n */\nconst StyledPage = styled(Page)({\n height: 'inherit',\n overflowY: 'visible',\n});\n\n/**\n * An addon-aware implementation of the TechDocsReaderPage.\n *\n * @public\n */\nexport const TechDocsReaderPage = (props: TechDocsReaderPageProps) => {\n const currentTheme = useTheme();\n\n const readerPageTheme = useMemo(\n () =>\n createTheme({\n ...currentTheme,\n ...(props.overrideThemeOptions || {}),\n }),\n [currentTheme, props.overrideThemeOptions],\n );\n\n const { kind, name, namespace } = useRouteRefParams(rootDocsRouteRef);\n const { children, entityRef = { kind, name, namespace } } = props;\n\n const outlet = useOutlet();\n\n const memoizedEntityRef = useMemo(\n () => ({\n kind: entityRef.kind,\n name: entityRef.name,\n namespace: entityRef.namespace,\n }),\n [entityRef.kind, entityRef.name, entityRef.namespace],\n );\n\n // Check for external TechDocs redirects and handle navigation\n const { shouldShowProgress } = useExternalRedirect(memoizedEntityRef);\n\n const page: ReactNode = useMemo(() => {\n if (children) {\n return null;\n }\n\n const childrenList = outlet ? Children.toArray(outlet.props.children) : [];\n\n const grandChildren = childrenList.flatMap<ReactElement>(\n child => (child as ReactElement)?.props?.children ?? [],\n );\n\n return grandChildren.find(\n grandChild =>\n !getComponentData(grandChild, TECHDOCS_ADDONS_WRAPPER_KEY) &&\n !getComponentData(grandChild, TECHDOCS_ADDONS_KEY),\n );\n }, [children, outlet]);\n\n // Show full-page loading spinner when checking for external redirects or about to redirect.\n // This replaces the entire page content (header, sidebar, and documentation).\n if (shouldShowProgress) {\n return <Progress />;\n }\n\n // As explained above, \"page\" is configuration 4 and <TechDocsReaderLayout> is 1\n if (!children) {\n return (\n <ThemeProvider theme={readerPageTheme}>\n <CookieAuthRefreshProvider pluginId=\"techdocs\">\n <TechDocsReaderPageProvider entityRef={memoizedEntityRef}>\n {(page as JSX.Element) || <TechDocsReaderLayout />}\n </TechDocsReaderPageProvider>\n </CookieAuthRefreshProvider>\n </ThemeProvider>\n );\n }\n\n // As explained above, a render function is configuration 3 and React element is 2\n return (\n <ThemeProvider theme={readerPageTheme}>\n <CookieAuthRefreshProvider pluginId=\"techdocs\">\n <TechDocsReaderPageProvider entityRef={memoizedEntityRef}>\n {({ metadata, entityMetadata, onReady }) => (\n <StyledPage\n themeId=\"documentation\"\n className=\"techdocs-reader-page\"\n >\n {children instanceof Function\n ? children({\n entityRef: memoizedEntityRef,\n techdocsMetadataValue: metadata.value,\n entityMetadataValue: entityMetadata.value,\n onReady,\n })\n : children}\n </StyledPage>\n )}\n </TechDocsReaderPageProvider>\n </CookieAuthRefreshProvider>\n </ThemeProvider>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;AA4IO,MAAM,oBAAA,GAAuB,CAAC,KAAA,KAAqC;AACxE,EAAA,MAAM,EAAE,UAAA,EAAY,UAAA,GAAa,IAAA,EAAK,GAAI,KAAA;AAC1C,EAAA,uBACE,IAAA,CAAC,IAAA,EAAA,EAAK,OAAA,EAAQ,eAAA,EACX,QAAA,EAAA;AAAA,IAAA,UAAA,wBAAe,wBAAA,EAAA,EAAyB,CAAA;AAAA,wBACxC,2BAAA,EAAA,EAA4B,CAAA;AAAA,oBAC7B,GAAA,CAAC,6BAA0B,UAAA,EAAwB;AAAA,GAAA,EACrD,CAAA;AAEJ;AAcA,MAAM,UAAA,GAAa,MAAA,CAAO,IAAI,CAAA,CAAE;AAAA,EAC9B,MAAA,EAAQ,SAAA;AAAA,EACR,SAAA,EAAW;AACb,CAAC,CAAA;AAOM,MAAM,kBAAA,GAAqB,CAAC,KAAA,KAAmC;AACpE,EAAA,MAAM,eAAe,QAAA,EAAS;AAE9B,EAAA,MAAM,eAAA,GAAkB,OAAA;AAAA,IACtB,MACE,WAAA,CAAY;AAAA,MACV,GAAG,YAAA;AAAA,MACH,GAAI,KAAA,CAAM,oBAAA,IAAwB;AAAC,KACpC,CAAA;AAAA,IACH,CAAC,YAAA,EAAc,KAAA,CAAM,oBAAoB;AAAA,GAC3C;AAEA,EAAA,MAAM,EAAE,IAAA,EAAM,IAAA,EAAM,SAAA,EAAU,GAAI,kBAAkB,gBAAgB,CAAA;AACpE,EAAA,MAAM,EAAE,UAAU,SAAA,GAAY,EAAE,MAAM,IAAA,EAAM,SAAA,IAAY,GAAI,KAAA;AAE5D,EAAA,MAAM,SAAS,SAAA,EAAU;AAEzB,EAAA,MAAM,iBAAA,GAAoB,OAAA;AAAA,IACxB,OAAO;AAAA,MACL,MAAM,SAAA,CAAU,IAAA;AAAA,MAChB,MAAM,SAAA,CAAU,IAAA;AAAA,MAChB,WAAW,SAAA,CAAU;AAAA,KACvB,CAAA;AAAA,IACA,CAAC,SAAA,CAAU,IAAA,EAAM,SAAA,CAAU,IAAA,EAAM,UAAU,SAAS;AAAA,GACtD;AAGA,EAAA,MAAM,EAAE,kBAAA,EAAmB,GAAI,mBAAA,CAAoB,iBAAiB,CAAA;AAEpE,EAAA,MAAM,IAAA,GAAkB,QAAQ,MAAM;AACpC,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,YAAA,GAAe,SAAS,QAAA,CAAS,OAAA,CAAQ,OAAO,KAAA,CAAM,QAAQ,IAAI,EAAC;AAEzE,IAAA,MAAM,gBAAgB,YAAA,CAAa,OAAA;AAAA,MACjC,CAAA,KAAA,KAAU,KAAA,EAAwB,KAAA,EAAO,QAAA,IAAY;AAAC,KACxD;AAEA,IAAA,OAAO,aAAA,CAAc,IAAA;AAAA,MACnB,CAAA,UAAA,KACE,CAAC,gBAAA,CAAiB,UAAA,EAAY,2BAA2B,CAAA,IACzD,CAAC,gBAAA,CAAiB,UAAA,EAAY,mBAAmB;AAAA,KACrD;AAAA,EACF,CAAA,EAAG,CAAC,QAAA,EAAU,MAAM,CAAC,CAAA;AAIrB,EAAA,IAAI,kBAAA,EAAoB;AACtB,IAAA,2BAAQ,QAAA,EAAA,EAAS,CAAA;AAAA,EACnB;AAGA,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,2BACG,aAAA,EAAA,EAAc,KAAA,EAAO,eAAA,EACpB,QAAA,kBAAA,GAAA,CAAC,6BAA0B,QAAA,EAAS,UAAA,EAClC,QAAA,kBAAA,GAAA,CAAC,0BAAA,EAAA,EAA2B,WAAW,iBAAA,EACnC,QAAA,EAAA,IAAA,wBAAyB,oBAAA,EAAA,EAAqB,CAAA,EAClD,GACF,CAAA,EACF,CAAA;AAAA,EAEJ;AAGA,EAAA,2BACG,aAAA,EAAA,EAAc,KAAA,EAAO,eAAA,EACpB,QAAA,kBAAA,GAAA,CAAC,6BAA0B,QAAA,EAAS,UAAA,EAClC,QAAA,kBAAA,GAAA,CAAC,0BAAA,EAAA,EAA2B,WAAW,iBAAA,EACpC,QAAA,EAAA,CAAC,EAAE,QAAA,EAAU,cAAA,EAAgB,SAAQ,qBACpC,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,OAAA,EAAQ,eAAA;AAAA,MACR,SAAA,EAAU,sBAAA;AAAA,MAET,QAAA,EAAA,QAAA,YAAoB,WACjB,QAAA,CAAS;AAAA,QACP,SAAA,EAAW,iBAAA;AAAA,QACX,uBAAuB,QAAA,CAAS,KAAA;AAAA,QAChC,qBAAqB,cAAA,CAAe,KAAA;AAAA,QACpC;AAAA,OACD,CAAA,GACD;AAAA;AAAA,GACN,EAEJ,GACF,CAAA,EACF,CAAA;AAEJ;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useExternalRedirect.esm.js","sources":["../../../../src/reader/components/TechDocsReaderPage/useExternalRedirect.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useEffect, useRef } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport useAsync from 'react-use/esm/useAsync';\nimport { useApi, useRouteRef } from '@backstage/core-plugin-api';\nimport { catalogApiRef } from '@backstage/plugin-catalog-react';\nimport {\n CompoundEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { buildTechDocsURL } from '@backstage/plugin-techdocs-react';\nimport { TECHDOCS_EXTERNAL_ANNOTATION } from '@backstage/plugin-techdocs-common';\nimport { rootDocsRouteRef } from '../../../routes';\n\n/**\n * Hook to handle external TechDocs redirects based on entity annotations.\n * Checks if an entity has the `backstage.io/techdocs-entity` annotation and\n * redirects to the external TechDocs URL if present.\n *\n * @param entityRef - The entity reference to check for external redirects\n * @returns Object containing loading state and whether a redirect is in progress\n *\n * @internal\n */\nexport function useExternalRedirect(entityRef: CompoundEntityRef): {\n loading: boolean;\n shouldShowProgress: boolean;\n} {\n const catalogApi = useApi(catalogApiRef);\n const navigate = useNavigate();\n const viewTechdocLink = useRouteRef(rootDocsRouteRef);\n\n // Create a stable string key for the entity to use as a dependency.\n // This ensures the useAsync hook only re-runs when the entity changes,\n // preventing redundant API calls during sub-page navigation within the same entity's documentation.\n const entityKey = stringifyEntityRef(entityRef);\n // Track which entity we've already checked to avoid redundant checks\n // when navigating between pages within the same entity's documentation.\n const checkedEntityRef = useRef<string | null>(null);\n const shouldCheckForRedirect = checkedEntityRef.current !== entityKey;\n\n // Check if this entity should redirect to external TechDocs\n const externalRedirectResult = useAsync(async () => {\n try {\n const catalogEntity = await catalogApi.getEntityByRef(entityRef);\n\n if (\n catalogEntity?.metadata?.annotations?.[TECHDOCS_EXTERNAL_ANNOTATION]\n ) {\n return buildTechDocsURL(catalogEntity, viewTechdocLink);\n }\n } catch (error) {\n // Ignore errors and allow the current entity's TechDocs to load.\n // This handles cases where the catalog API is unavailable or the entity doesn't exist.\n }\n\n return undefined;\n }, [entityKey, catalogApi]);\n\n useEffect(() => {\n // Navigate to external TechDocs if a redirect URL is available\n if (!externalRedirectResult.loading && externalRedirectResult.value) {\n navigate(externalRedirectResult.value, { replace: true });\n }\n\n // Mark entity as checked once we've determined there's no redirect needed.\n // This prevents the entire page from unmounting/remounting (showing Progress spinner)\n // on subsequent sub-page navigation within the same entity.\n if (!externalRedirectResult.loading && !externalRedirectResult.value) {\n checkedEntityRef.current = entityKey;\n }\n }, [\n externalRedirectResult.loading,\n externalRedirectResult.value,\n navigate,\n entityKey,\n ]);\n\n // Determine if we should show a loading indicator (which replaces the entire page with a Progress spinner).\n // Only show it when: 1) checking a new/unchecked entity, or 2) we have a redirect URL and are navigating.\n const shouldShowProgress =\n (shouldCheckForRedirect && externalRedirectResult.loading) ||\n !!externalRedirectResult.value;\n\n return {\n loading: externalRedirectResult.loading,\n shouldShowProgress,\n };\n}\n"],"names":[],"mappings":";;;;;;;;;;AAuCO,SAAS,oBAAoB,SAAA,EAGlC;AACA,EAAA,MAAM,UAAA,GAAa,OAAO,aAAa,CAAA;AACvC,EAAA,MAAM,WAAW,WAAA,EAAY;AAC7B,EAAA,MAAM,eAAA,GAAkB,YAAY,gBAAgB,CAAA;AAKpD,EAAA,MAAM,SAAA,GAAY,mBAAmB,SAAS,CAAA;AAG9C,EAAA,MAAM,gBAAA,GAAmB,OAAsB,IAAI,CAAA;AACnD,EAAA,MAAM,sBAAA,GAAyB,iBAAiB,OAAA,KAAY,SAAA;AAG5D,EAAA,MAAM,sBAAA,GAAyB,SAAS,YAAY;AAClD,IAAA,IAAI;AACF,MAAA,MAAM,aAAA,GAAgB,MAAM,UAAA,CAAW,cAAA,CAAe,SAAS,CAAA;AAE/D,MAAA,IACE,aAAA,EAAe,QAAA,EAAU,WAAA,GAAc,4BAA4B,CAAA,EACnE;AACA,QAAA,OAAO,gBAAA,CAAiB,eAAe,eAAe,CAAA;AAAA,MACxD;AAAA,IACF,SAAS,KAAA,EAAO;AAAA,IAGhB;AAEA,IAAA,OAAO,MAAA;AAAA,EACT,CAAA,EAAG,CAAC,SAAA,EAAW,UAAU,CAAC,CAAA;AAE1B,EAAA,SAAA,CAAU,MAAM;AAEd,IAAA,IAAI,CAAC,sBAAA,CAAuB,OAAA,IAAW,sBAAA,CAAuB,KAAA,EAAO;AACnE,MAAA,QAAA,CAAS,sBAAA,CAAuB,KAAA,EAAO,EAAE,OAAA,EAAS,MAAM,CAAA;AAAA,IAC1D;AAKA,IAAA,IAAI,CAAC,sBAAA,CAAuB,OAAA,IAAW,CAAC,uBAAuB,KAAA,EAAO;AACpE,MAAA,gBAAA,CAAiB,OAAA,GAAU,SAAA;AAAA,IAC7B;AAAA,EACF,CAAA,EAAG;AAAA,IACD,sBAAA,CAAuB,OAAA;AAAA,IACvB,sBAAA,CAAuB,KAAA;AAAA,IACvB,QAAA;AAAA,IACA;AAAA,GACD,CAAA;AAID,EAAA,MAAM,qBACH,sBAAA,IAA0B,sBAAA,CAAuB,OAAA,IAClD,CAAC,CAAC,sBAAA,CAAuB,KAAA;AAE3B,EAAA,OAAO;AAAA,IACL,SAAS,sBAAA,CAAuB,OAAA;AAAA,IAChC;AAAA,GACF;AACF
|
|
1
|
+
{"version":3,"file":"useExternalRedirect.esm.js","sources":["../../../../src/reader/components/TechDocsReaderPage/useExternalRedirect.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useEffect, useRef } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport useAsync from 'react-use/esm/useAsync';\nimport { useApi, useRouteRef } from '@backstage/core-plugin-api';\nimport { catalogApiRef } from '@backstage/plugin-catalog-react';\nimport {\n CompoundEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { buildTechDocsURL } from '@backstage/plugin-techdocs-react';\nimport { TECHDOCS_EXTERNAL_ANNOTATION } from '@backstage/plugin-techdocs-common';\nimport { rootDocsRouteRef } from '../../../routes';\n\n/**\n * Hook to handle external TechDocs redirects based on entity annotations.\n * Checks if an entity has the `backstage.io/techdocs-entity` annotation and\n * redirects to the external TechDocs URL if present.\n *\n * @param entityRef - The entity reference to check for external redirects\n * @returns Object containing loading state and whether a redirect is in progress\n *\n * @internal\n */\nexport function useExternalRedirect(entityRef: CompoundEntityRef): {\n loading: boolean;\n shouldShowProgress: boolean;\n} {\n const catalogApi = useApi(catalogApiRef);\n const navigate = useNavigate();\n const viewTechdocLink = useRouteRef(rootDocsRouteRef);\n\n // Create a stable string key for the entity to use as a dependency.\n // This ensures the useAsync hook only re-runs when the entity changes,\n // preventing redundant API calls during sub-page navigation within the same entity's documentation.\n const entityKey = stringifyEntityRef(entityRef);\n // Track which entity we've already checked to avoid redundant checks\n // when navigating between pages within the same entity's documentation.\n const checkedEntityRef = useRef<string | null>(null);\n const shouldCheckForRedirect = checkedEntityRef.current !== entityKey;\n\n // Check if this entity should redirect to external TechDocs\n const externalRedirectResult = useAsync(async () => {\n try {\n const catalogEntity = await catalogApi.getEntityByRef(entityRef);\n\n if (\n catalogEntity?.metadata?.annotations?.[TECHDOCS_EXTERNAL_ANNOTATION]\n ) {\n return buildTechDocsURL(catalogEntity, viewTechdocLink);\n }\n } catch (error) {\n // Ignore errors and allow the current entity's TechDocs to load.\n // This handles cases where the catalog API is unavailable or the entity doesn't exist.\n }\n\n return undefined;\n }, [entityKey, catalogApi]);\n\n useEffect(() => {\n // Navigate to external TechDocs if a redirect URL is available\n if (!externalRedirectResult.loading && externalRedirectResult.value) {\n navigate(externalRedirectResult.value, { replace: true });\n }\n\n // Mark entity as checked once we've determined there's no redirect needed.\n // This prevents the entire page from unmounting/remounting (showing Progress spinner)\n // on subsequent sub-page navigation within the same entity.\n if (!externalRedirectResult.loading && !externalRedirectResult.value) {\n checkedEntityRef.current = entityKey;\n }\n }, [\n externalRedirectResult.loading,\n externalRedirectResult.value,\n navigate,\n entityKey,\n ]);\n\n // Determine if we should show a loading indicator (which replaces the entire page with a Progress spinner).\n // Only show it when: 1) checking a new/unchecked entity, or 2) we have a redirect URL and are navigating.\n const shouldShowProgress =\n (shouldCheckForRedirect && externalRedirectResult.loading) ||\n !!externalRedirectResult.value;\n\n return {\n loading: externalRedirectResult.loading,\n shouldShowProgress,\n };\n}\n"],"names":[],"mappings":";;;;;;;;;;AAuCO,SAAS,oBAAoB,SAAA,EAGlC;AACA,EAAA,MAAM,UAAA,GAAa,OAAO,aAAa,CAAA;AACvC,EAAA,MAAM,WAAW,WAAA,EAAY;AAC7B,EAAA,MAAM,eAAA,GAAkB,YAAY,gBAAgB,CAAA;AAKpD,EAAA,MAAM,SAAA,GAAY,mBAAmB,SAAS,CAAA;AAG9C,EAAA,MAAM,gBAAA,GAAmB,OAAsB,IAAI,CAAA;AACnD,EAAA,MAAM,sBAAA,GAAyB,iBAAiB,OAAA,KAAY,SAAA;AAG5D,EAAA,MAAM,sBAAA,GAAyB,SAAS,YAAY;AAClD,IAAA,IAAI;AACF,MAAA,MAAM,aAAA,GAAgB,MAAM,UAAA,CAAW,cAAA,CAAe,SAAS,CAAA;AAE/D,MAAA,IACE,aAAA,EAAe,QAAA,EAAU,WAAA,GAAc,4BAA4B,CAAA,EACnE;AACA,QAAA,OAAO,gBAAA,CAAiB,eAAe,eAAe,CAAA;AAAA,MACxD;AAAA,IACF,SAAS,KAAA,EAAO;AAAA,IAGhB;AAEA,IAAA,OAAO,MAAA;AAAA,EACT,CAAA,EAAG,CAAC,SAAA,EAAW,UAAU,CAAC,CAAA;AAE1B,EAAA,SAAA,CAAU,MAAM;AAEd,IAAA,IAAI,CAAC,sBAAA,CAAuB,OAAA,IAAW,sBAAA,CAAuB,KAAA,EAAO;AACnE,MAAA,QAAA,CAAS,sBAAA,CAAuB,KAAA,EAAO,EAAE,OAAA,EAAS,MAAM,CAAA;AAAA,IAC1D;AAKA,IAAA,IAAI,CAAC,sBAAA,CAAuB,OAAA,IAAW,CAAC,uBAAuB,KAAA,EAAO;AACpE,MAAA,gBAAA,CAAiB,OAAA,GAAU,SAAA;AAAA,IAC7B;AAAA,EACF,CAAA,EAAG;AAAA,IACD,sBAAA,CAAuB,OAAA;AAAA,IACvB,sBAAA,CAAuB,KAAA;AAAA,IACvB,QAAA;AAAA,IACA;AAAA,GACD,CAAA;AAID,EAAA,MAAM,qBACH,sBAAA,IAA0B,sBAAA,CAAuB,OAAA,IAClD,CAAC,CAAC,sBAAA,CAAuB,KAAA;AAE3B,EAAA,OAAO;AAAA,IACL,SAAS,sBAAA,CAAuB,OAAA;AAAA,IAChC;AAAA,GACF;AACF;;"}
|
|
@@ -36,7 +36,8 @@ const TechDocsReaderPageContent = withTechDocsReaderProvider(
|
|
|
36
36
|
NotFoundErrorPage
|
|
37
37
|
} = useTechDocsReaderContentData({
|
|
38
38
|
defaultPath: props.defaultPath,
|
|
39
|
-
onReady: props.onReady
|
|
39
|
+
onReady: props.onReady,
|
|
40
|
+
withFeedbackLink: props.withFeedbackLink
|
|
40
41
|
});
|
|
41
42
|
if (isNotFound) return /* @__PURE__ */ jsx(NotFoundErrorPage, {});
|
|
42
43
|
if (!isDomReady) {
|
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 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;
|
|
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 * Show or hide the feedback button, defaults to true.\n */\n withFeedbackLink?: 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 withFeedbackLink: props.withFeedbackLink,\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;AAyCM,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,OAAA;AAAA,MACf,kBAAkB,KAAA,CAAM;AAAA,KACzB,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;;"}
|
package/dist/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContentAddons.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TechDocsReaderPageContentAddons.esm.js","sources":["../../../../src/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContentAddons.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 Portal from '@material-ui/core/Portal';\nimport {\n useTechDocsAddons,\n TechDocsAddonLocations as locations,\n useTechDocsReaderPage,\n} from '@backstage/plugin-techdocs-react';\n\nexport const TechDocsReaderPageContentAddons = () => {\n const addons = useTechDocsAddons();\n\n const { shadowRoot } = useTechDocsReaderPage();\n\n const contentElement = shadowRoot?.querySelector(\n '[data-md-component=\"content\"]',\n );\n\n const primarySidebarElement = shadowRoot?.querySelector(\n 'div[data-md-component=\"sidebar\"][data-md-type=\"navigation\"], div[data-md-component=\"navigation\"]',\n );\n let primarySidebarAddonLocation = primarySidebarElement?.querySelector(\n '[data-techdocs-addons-location=\"primary sidebar\"]',\n );\n if (!primarySidebarAddonLocation) {\n primarySidebarAddonLocation = document.createElement('div');\n primarySidebarAddonLocation.setAttribute(\n 'data-techdocs-addons-location',\n 'primary sidebar',\n );\n primarySidebarElement?.prepend(primarySidebarAddonLocation);\n }\n\n const secondarySidebarElement = shadowRoot?.querySelector(\n 'div[data-md-component=\"sidebar\"][data-md-type=\"toc\"], div[data-md-component=\"toc\"]',\n );\n let secondarySidebarAddonLocation = secondarySidebarElement?.querySelector(\n '[data-techdocs-addons-location=\"secondary sidebar\"]',\n );\n if (!secondarySidebarAddonLocation) {\n secondarySidebarAddonLocation = document.createElement('div');\n secondarySidebarAddonLocation.setAttribute(\n 'data-techdocs-addons-location',\n 'secondary sidebar',\n );\n secondarySidebarElement?.prepend(secondarySidebarAddonLocation);\n }\n\n return (\n <>\n <Portal container={primarySidebarAddonLocation}>\n {addons.renderComponentsByLocation(locations.PrimarySidebar)}\n </Portal>\n <Portal container={contentElement}>\n {addons.renderComponentsByLocation(locations.Content)}\n </Portal>\n <Portal container={secondarySidebarAddonLocation}>\n {addons.renderComponentsByLocation(locations.SecondarySidebar)}\n </Portal>\n </>\n );\n};\n"],"names":["locations"],"mappings":";;;;AAuBO,MAAM,kCAAkC,MAAM;AACnD,EAAA,MAAM,SAAS,iBAAA,EAAkB;AAEjC,EAAA,MAAM,EAAE,UAAA,EAAW,GAAI,qBAAA,EAAsB;AAE7C,EAAA,MAAM,iBAAiB,UAAA,EAAY,aAAA;AAAA,IACjC;AAAA,GACF;AAEA,EAAA,MAAM,wBAAwB,UAAA,EAAY,aAAA;AAAA,IACxC;AAAA,GACF;AACA,EAAA,IAAI,8BAA8B,qBAAA,EAAuB,aAAA;AAAA,IACvD;AAAA,GACF;AACA,EAAA,IAAI,CAAC,2BAAA,EAA6B;AAChC,IAAA,2BAAA,GAA8B,QAAA,CAAS,cAAc,KAAK,CAAA;AAC1D,IAAA,2BAAA,CAA4B,YAAA;AAAA,MAC1B,+BAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,qBAAA,EAAuB,QAAQ,2BAA2B,CAAA;AAAA,EAC5D;AAEA,EAAA,MAAM,0BAA0B,UAAA,EAAY,aAAA;AAAA,IAC1C;AAAA,GACF;AACA,EAAA,IAAI,gCAAgC,uBAAA,EAAyB,aAAA;AAAA,IAC3D;AAAA,GACF;AACA,EAAA,IAAI,CAAC,6BAAA,EAA+B;AAClC,IAAA,6BAAA,GAAgC,QAAA,CAAS,cAAc,KAAK,CAAA;AAC5D,IAAA,6BAAA,CAA8B,YAAA;AAAA,MAC5B,+BAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,uBAAA,EAAyB,QAAQ,6BAA6B,CAAA;AAAA,EAChE;AAEA,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,UAAO,SAAA,EAAW,2BAAA,EAChB,iBAAO,0BAAA,CAA2BA,sBAAA,CAAU,cAAc,CAAA,EAC7D,CAAA;AAAA,oBACA,GAAA,CAAC,UAAO,SAAA,EAAW,cAAA,EAChB,iBAAO,0BAAA,CAA2BA,sBAAA,CAAU,OAAO,CAAA,EACtD,CAAA;AAAA,oBACA,GAAA,CAAC,UAAO,SAAA,EAAW,6BAAA,EAChB,iBAAO,0BAAA,CAA2BA,sBAAA,CAAU,gBAAgB,CAAA,EAC/D;AAAA,GAAA,EACF,CAAA;AAEJ
|
|
1
|
+
{"version":3,"file":"TechDocsReaderPageContentAddons.esm.js","sources":["../../../../src/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContentAddons.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 Portal from '@material-ui/core/Portal';\nimport {\n useTechDocsAddons,\n TechDocsAddonLocations as locations,\n useTechDocsReaderPage,\n} from '@backstage/plugin-techdocs-react';\n\nexport const TechDocsReaderPageContentAddons = () => {\n const addons = useTechDocsAddons();\n\n const { shadowRoot } = useTechDocsReaderPage();\n\n const contentElement = shadowRoot?.querySelector(\n '[data-md-component=\"content\"]',\n );\n\n const primarySidebarElement = shadowRoot?.querySelector(\n 'div[data-md-component=\"sidebar\"][data-md-type=\"navigation\"], div[data-md-component=\"navigation\"]',\n );\n let primarySidebarAddonLocation = primarySidebarElement?.querySelector(\n '[data-techdocs-addons-location=\"primary sidebar\"]',\n );\n if (!primarySidebarAddonLocation) {\n primarySidebarAddonLocation = document.createElement('div');\n primarySidebarAddonLocation.setAttribute(\n 'data-techdocs-addons-location',\n 'primary sidebar',\n );\n primarySidebarElement?.prepend(primarySidebarAddonLocation);\n }\n\n const secondarySidebarElement = shadowRoot?.querySelector(\n 'div[data-md-component=\"sidebar\"][data-md-type=\"toc\"], div[data-md-component=\"toc\"]',\n );\n let secondarySidebarAddonLocation = secondarySidebarElement?.querySelector(\n '[data-techdocs-addons-location=\"secondary sidebar\"]',\n );\n if (!secondarySidebarAddonLocation) {\n secondarySidebarAddonLocation = document.createElement('div');\n secondarySidebarAddonLocation.setAttribute(\n 'data-techdocs-addons-location',\n 'secondary sidebar',\n );\n secondarySidebarElement?.prepend(secondarySidebarAddonLocation);\n }\n\n return (\n <>\n <Portal container={primarySidebarAddonLocation}>\n {addons.renderComponentsByLocation(locations.PrimarySidebar)}\n </Portal>\n <Portal container={contentElement}>\n {addons.renderComponentsByLocation(locations.Content)}\n </Portal>\n <Portal container={secondarySidebarAddonLocation}>\n {addons.renderComponentsByLocation(locations.SecondarySidebar)}\n </Portal>\n </>\n );\n};\n"],"names":["locations"],"mappings":";;;;AAuBO,MAAM,kCAAkC,MAAM;AACnD,EAAA,MAAM,SAAS,iBAAA,EAAkB;AAEjC,EAAA,MAAM,EAAE,UAAA,EAAW,GAAI,qBAAA,EAAsB;AAE7C,EAAA,MAAM,iBAAiB,UAAA,EAAY,aAAA;AAAA,IACjC;AAAA,GACF;AAEA,EAAA,MAAM,wBAAwB,UAAA,EAAY,aAAA;AAAA,IACxC;AAAA,GACF;AACA,EAAA,IAAI,8BAA8B,qBAAA,EAAuB,aAAA;AAAA,IACvD;AAAA,GACF;AACA,EAAA,IAAI,CAAC,2BAAA,EAA6B;AAChC,IAAA,2BAAA,GAA8B,QAAA,CAAS,cAAc,KAAK,CAAA;AAC1D,IAAA,2BAAA,CAA4B,YAAA;AAAA,MAC1B,+BAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,qBAAA,EAAuB,QAAQ,2BAA2B,CAAA;AAAA,EAC5D;AAEA,EAAA,MAAM,0BAA0B,UAAA,EAAY,aAAA;AAAA,IAC1C;AAAA,GACF;AACA,EAAA,IAAI,gCAAgC,uBAAA,EAAyB,aAAA;AAAA,IAC3D;AAAA,GACF;AACA,EAAA,IAAI,CAAC,6BAAA,EAA+B;AAClC,IAAA,6BAAA,GAAgC,QAAA,CAAS,cAAc,KAAK,CAAA;AAC5D,IAAA,6BAAA,CAA8B,YAAA;AAAA,MAC5B,+BAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,uBAAA,EAAyB,QAAQ,6BAA6B,CAAA;AAAA,EAChE;AAEA,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,UAAO,SAAA,EAAW,2BAAA,EAChB,iBAAO,0BAAA,CAA2BA,sBAAA,CAAU,cAAc,CAAA,EAC7D,CAAA;AAAA,oBACA,GAAA,CAAC,UAAO,SAAA,EAAW,cAAA,EAChB,iBAAO,0BAAA,CAA2BA,sBAAA,CAAU,OAAO,CAAA,EACtD,CAAA;AAAA,oBACA,GAAA,CAAC,UAAO,SAAA,EAAW,6BAAA,EAChB,iBAAO,0BAAA,CAA2BA,sBAAA,CAAU,gBAAgB,CAAA,EAC/D;AAAA,GAAA,EACF,CAAA;AAEJ;;"}
|
|
@@ -34,7 +34,8 @@ const useInitialRedirect = (defaultPath) => {
|
|
|
34
34
|
}
|
|
35
35
|
}, []);
|
|
36
36
|
};
|
|
37
|
-
const useTechDocsReaderDom = (entityRef,
|
|
37
|
+
const useTechDocsReaderDom = (entityRef, options) => {
|
|
38
|
+
const { defaultPath, withFeedbackLink = true } = options ?? {};
|
|
38
39
|
const navigate = useNavigateUrl();
|
|
39
40
|
const theme = useTheme();
|
|
40
41
|
const isMobileMedia = useMediaQuery(MOBILE_MEDIA_QUERY);
|
|
@@ -121,7 +122,7 @@ const useTechDocsReaderDom = (entityRef, defaultPath) => {
|
|
|
121
122
|
addSidebarToggle(),
|
|
122
123
|
removeMkdocsHeader(),
|
|
123
124
|
simplifyMkdocsFooter(),
|
|
124
|
-
addGitFeedbackLink(scmIntegrationsApi),
|
|
125
|
+
...withFeedbackLink ? [addGitFeedbackLink(scmIntegrationsApi)] : [],
|
|
125
126
|
stylesTransformer
|
|
126
127
|
]),
|
|
127
128
|
[
|
|
@@ -130,7 +131,8 @@ const useTechDocsReaderDom = (entityRef, defaultPath) => {
|
|
|
130
131
|
scmIntegrationsApi,
|
|
131
132
|
techdocsStorageApi,
|
|
132
133
|
sanitizerTransformer,
|
|
133
|
-
stylesTransformer
|
|
134
|
+
stylesTransformer,
|
|
135
|
+
withFeedbackLink
|
|
134
136
|
]
|
|
135
137
|
);
|
|
136
138
|
const postRender = useCallback(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dom.esm.js","sources":["../../../../src/reader/components/TechDocsReaderPageContent/dom.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 {\n useCallback,\n useEffect,\n useLayoutEffect,\n // useRef,\n useState,\n} from 'react';\n\nimport useMediaQuery from '@material-ui/core/useMediaQuery';\nimport { useTheme } from '@material-ui/core/styles';\n\nimport { CompoundEntityRef } from '@backstage/catalog-model';\nimport { configApiRef, useAnalytics, useApi } from '@backstage/core-plugin-api';\nimport { scmIntegrationsApiRef } from '@backstage/integration-react';\n\nimport {\n techdocsStorageApiRef,\n useShadowDomStylesLoading,\n} from '@backstage/plugin-techdocs-react';\n\nimport { useTechDocsReader } from '../TechDocsReaderProvider';\n\nimport {\n addBaseUrl,\n addGitFeedbackLink,\n addLinkClickListener,\n addSidebarToggle,\n onCssReady,\n removeMkdocsHeader,\n rewriteDocLinks,\n simplifyMkdocsFooter,\n scrollIntoNavigation,\n transform as transformer,\n copyToClipboard,\n useSanitizerTransformer,\n useStylesTransformer,\n handleMetaRedirects,\n addNavLinkKeyboardToggle,\n} from '../../transformers';\nimport { useNavigateUrl } from './useNavigateUrl';\nimport { useLocation, useNavigate, useParams } from 'react-router-dom';\n\nconst MOBILE_MEDIA_QUERY = 'screen and (max-width: 76.1875em)';\n\n// If a defaultPath is specified then we should navigate to that path replacing the\n// current location in the history. This should only happen on the initial load so\n// navigating to the root of the docs doesn't also redirect.\nexport const useInitialRedirect = (defaultPath?: string) => {\n const location = useLocation();\n const navigate = useNavigate();\n const { '*': currPath = '' } = useParams();\n\n useLayoutEffect(() => {\n if (currPath === '' && defaultPath) {\n navigate(`${location.pathname}${defaultPath}`, { replace: true });\n }\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n};\n\n/**\n * Hook that encapsulates the behavior of getting raw HTML and applying\n * transforms to it in order to make it function at a basic level in the\n * Backstage UI.\n */\nexport const useTechDocsReaderDom = (\n entityRef: CompoundEntityRef,\n defaultPath?: string,\n): Element | null => {\n const navigate = useNavigateUrl();\n const theme = useTheme();\n const isMobileMedia = useMediaQuery(MOBILE_MEDIA_QUERY);\n const sanitizerTransformer = useSanitizerTransformer();\n const stylesTransformer = useStylesTransformer();\n const analytics = useAnalytics();\n\n const techdocsStorageApi = useApi(techdocsStorageApiRef);\n const scmIntegrationsApi = useApi(scmIntegrationsApiRef);\n const configApi = useApi(configApiRef);\n\n const { state, path, content: rawPage } = useTechDocsReader();\n const { '*': currPath = '' } = useParams();\n\n const [dom, setDom] = useState<HTMLElement | null>(null);\n const isStyleLoading = useShadowDomStylesLoading(dom);\n\n useInitialRedirect(defaultPath);\n\n const updateSidebarPositionAndHeight = useCallback(() => {\n if (!dom) return;\n\n const sidebars = dom.querySelectorAll<HTMLElement>('.md-sidebar');\n\n sidebars.forEach(element => {\n // set sidebar position to render in correct position\n if (isMobileMedia) {\n element.style.top = '0px';\n } else {\n const page = document?.querySelector('.techdocs-reader-page');\n const pageTop = page?.getBoundingClientRect().top ?? 0;\n let domTop = dom.getBoundingClientRect().top ?? 0;\n\n const tabs = dom.querySelector('.md-container > .md-tabs');\n const tabsHeight = tabs?.getBoundingClientRect().height ?? 0;\n\n // the sidebars should not scroll beyond the total height of the header and tabs\n if (domTop < pageTop) {\n domTop = pageTop;\n }\n\n const scrollbarTopPx = Math.max(domTop, 0) + tabsHeight;\n\n element.style.top = `${scrollbarTopPx}px`;\n\n // set scrollbar height to ensure all links can be seen when content is small\n const footer = dom.querySelector('.md-container > .md-footer');\n // if no footer, fallback to using the bottom of the window\n const scrollbarEndPx =\n footer?.getBoundingClientRect().top ?? window.innerHeight;\n\n element.style.height = `${scrollbarEndPx - scrollbarTopPx}px`;\n }\n\n // show the sidebar only after updating its position\n element.style.setProperty('opacity', '1');\n });\n }, [dom, isMobileMedia]);\n\n useEffect(() => {\n window.addEventListener('resize', updateSidebarPositionAndHeight);\n window.addEventListener('scroll', updateSidebarPositionAndHeight, true);\n return () => {\n window.removeEventListener('resize', updateSidebarPositionAndHeight);\n window.removeEventListener(\n 'scroll',\n updateSidebarPositionAndHeight,\n true,\n );\n };\n }, [dom, updateSidebarPositionAndHeight]);\n\n // dynamically set width of footer to accommodate for pinning of the sidebar\n const updateFooterWidth = useCallback(() => {\n if (!dom) return;\n const footer = dom.querySelector<HTMLElement>('.md-footer');\n if (footer) {\n footer.style.width = `${dom.getBoundingClientRect().width}px`;\n }\n }, [dom]);\n\n useEffect(() => {\n window.addEventListener('resize', updateFooterWidth);\n return () => {\n window.removeEventListener('resize', updateFooterWidth);\n };\n }, [dom, updateFooterWidth]);\n\n // an update to \"state\" might lead to an updated UI so we include it as a trigger\n useEffect(() => {\n if (!isStyleLoading) {\n updateFooterWidth();\n updateSidebarPositionAndHeight();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n state,\n isStyleLoading,\n updateFooterWidth,\n updateSidebarPositionAndHeight,\n ]);\n\n // a function that performs transformations that are executed prior to adding it to the DOM\n const preRender = useCallback(\n (rawContent: string, contentPath: string) =>\n transformer(rawContent, [\n sanitizerTransformer,\n addBaseUrl({\n techdocsStorageApi,\n entityId: entityRef,\n path: contentPath,\n }),\n rewriteDocLinks(),\n addSidebarToggle(),\n removeMkdocsHeader(),\n simplifyMkdocsFooter(),\n addGitFeedbackLink(scmIntegrationsApi),\n stylesTransformer,\n ]),\n [\n // only add dependencies that are in state or memorized variables to avoid unnecessary calls between re-renders\n entityRef,\n scmIntegrationsApi,\n techdocsStorageApi,\n sanitizerTransformer,\n stylesTransformer,\n ],\n );\n\n // a function that performs transformations that are executed after adding it to the DOM\n const postRender = useCallback(\n async (transformedElement: Element) =>\n transformer(transformedElement, [\n handleMetaRedirects(navigate, entityRef.name),\n scrollIntoNavigation(),\n copyToClipboard(theme),\n addLinkClickListener({\n baseUrl:\n configApi.getOptionalString('app.baseUrl') ||\n window.location.origin,\n onClick: (event: MouseEvent, url: string) => {\n // detect if CTRL or META keys are pressed so that links can be opened in a new tab with `window.open`\n const modifierActive = event.ctrlKey || event.metaKey;\n const parsedUrl = new URL(url);\n\n // capture link clicks within documentation\n const linkText =\n (event.target as HTMLAnchorElement | undefined)?.innerText || url;\n const to = url.replace(window.location.origin, '');\n analytics.captureEvent('click', linkText, { attributes: { to } });\n\n // hash exists when anchor is clicked on secondary sidebar\n if (parsedUrl.hash) {\n if (modifierActive) {\n window.open(url, '_blank');\n } else {\n // If it's in a different page, we navigate to it\n if (window.location.pathname !== parsedUrl.pathname) {\n navigate(url);\n } else {\n // If it's in the same page we avoid using navigate that causes\n // the page to rerender.\n window.history.pushState(\n null,\n document.title,\n parsedUrl.hash,\n );\n }\n // Scroll to hash if it's on the current page\n transformedElement\n ?.querySelector(`[id=\"${parsedUrl.hash.slice(1)}\"]`)\n ?.scrollIntoView();\n\n // Focus first focusable element in the target section\n (\n transformedElement\n ?.querySelector(`[id=\"${parsedUrl.hash.slice(1)}\"]`)\n ?.querySelector('a, button, [tabindex]') as HTMLElement\n )?.focus();\n }\n } else {\n if (modifierActive) {\n window.open(url, '_blank');\n } else {\n navigate(url);\n }\n }\n },\n }),\n // disable MkDocs drawer toggling ('for' attribute => checkbox mechanism)\n onCssReady({\n onLoading: () => {},\n onLoaded: () => {\n transformedElement\n .querySelector('.md-nav__title')\n ?.removeAttribute('for');\n },\n }),\n // hide sidebars until their positions are updated\n onCssReady({\n onLoading: () => {\n const sidebars = Array.from(\n transformedElement.querySelectorAll<HTMLElement>('.md-sidebar'),\n );\n sidebars.forEach(element => {\n element.style.setProperty('opacity', '0');\n });\n },\n onLoaded: () => {},\n }),\n addNavLinkKeyboardToggle(),\n ]),\n [theme, navigate, analytics, entityRef.name, configApi],\n );\n\n useEffect(() => {\n if (!rawPage) return () => {};\n\n // if false, there is already a newer execution of this effect\n let shouldReplaceContent = true;\n\n // Pre-render\n preRender(rawPage, path).then(async preTransformedDomElement => {\n if (!preTransformedDomElement?.innerHTML) {\n return; // An unexpected error occurred\n }\n\n // don't manipulate the shadow dom if this isn't the latest effect execution\n if (!shouldReplaceContent) {\n return;\n }\n\n // Skip this update if the location's path has changed but the state\n // contains a page that isn't loaded yet.\n if (currPath !== path) {\n return;\n }\n\n // Scroll to top after render\n window.scroll({ top: 0 });\n\n // Post-render\n const postTransformedDomElement = await postRender(\n preTransformedDomElement,\n );\n\n setDom(postTransformedDomElement as HTMLElement);\n });\n\n // cancel this execution\n return () => {\n shouldReplaceContent = false;\n };\n }, [rawPage, currPath, path, preRender, postRender]);\n\n return dom;\n};\n"],"names":["transformer"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dom.esm.js","sources":["../../../../src/reader/components/TechDocsReaderPageContent/dom.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 {\n useCallback,\n useEffect,\n useLayoutEffect,\n // useRef,\n useState,\n} from 'react';\n\nimport useMediaQuery from '@material-ui/core/useMediaQuery';\nimport { useTheme } from '@material-ui/core/styles';\n\nimport { CompoundEntityRef } from '@backstage/catalog-model';\nimport { configApiRef, useAnalytics, useApi } from '@backstage/core-plugin-api';\nimport { scmIntegrationsApiRef } from '@backstage/integration-react';\n\nimport {\n techdocsStorageApiRef,\n useShadowDomStylesLoading,\n} from '@backstage/plugin-techdocs-react';\n\nimport { useTechDocsReader } from '../TechDocsReaderProvider';\n\nimport {\n addBaseUrl,\n addGitFeedbackLink,\n addLinkClickListener,\n addSidebarToggle,\n onCssReady,\n removeMkdocsHeader,\n rewriteDocLinks,\n simplifyMkdocsFooter,\n scrollIntoNavigation,\n transform as transformer,\n copyToClipboard,\n useSanitizerTransformer,\n useStylesTransformer,\n handleMetaRedirects,\n addNavLinkKeyboardToggle,\n} from '../../transformers';\nimport { useNavigateUrl } from './useNavigateUrl';\nimport { useLocation, useNavigate, useParams } from 'react-router-dom';\n\nconst MOBILE_MEDIA_QUERY = 'screen and (max-width: 76.1875em)';\n\n// If a defaultPath is specified then we should navigate to that path replacing the\n// current location in the history. This should only happen on the initial load so\n// navigating to the root of the docs doesn't also redirect.\nexport const useInitialRedirect = (defaultPath?: string) => {\n const location = useLocation();\n const navigate = useNavigate();\n const { '*': currPath = '' } = useParams();\n\n useLayoutEffect(() => {\n if (currPath === '' && defaultPath) {\n navigate(`${location.pathname}${defaultPath}`, { replace: true });\n }\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n};\n\n/**\n * Hook that encapsulates the behavior of getting raw HTML and applying\n * transforms to it in order to make it function at a basic level in the\n * Backstage UI.\n */\nexport const useTechDocsReaderDom = (\n entityRef: CompoundEntityRef,\n options?: { defaultPath?: string; withFeedbackLink?: boolean },\n): Element | null => {\n const { defaultPath, withFeedbackLink = true } = options ?? {};\n\n const navigate = useNavigateUrl();\n const theme = useTheme();\n const isMobileMedia = useMediaQuery(MOBILE_MEDIA_QUERY);\n const sanitizerTransformer = useSanitizerTransformer();\n const stylesTransformer = useStylesTransformer();\n const analytics = useAnalytics();\n\n const techdocsStorageApi = useApi(techdocsStorageApiRef);\n const scmIntegrationsApi = useApi(scmIntegrationsApiRef);\n const configApi = useApi(configApiRef);\n\n const { state, path, content: rawPage } = useTechDocsReader();\n const { '*': currPath = '' } = useParams();\n\n const [dom, setDom] = useState<HTMLElement | null>(null);\n const isStyleLoading = useShadowDomStylesLoading(dom);\n\n useInitialRedirect(defaultPath);\n\n const updateSidebarPositionAndHeight = useCallback(() => {\n if (!dom) return;\n\n const sidebars = dom.querySelectorAll<HTMLElement>('.md-sidebar');\n\n sidebars.forEach(element => {\n // set sidebar position to render in correct position\n if (isMobileMedia) {\n element.style.top = '0px';\n } else {\n const page = document?.querySelector('.techdocs-reader-page');\n const pageTop = page?.getBoundingClientRect().top ?? 0;\n let domTop = dom.getBoundingClientRect().top ?? 0;\n\n const tabs = dom.querySelector('.md-container > .md-tabs');\n const tabsHeight = tabs?.getBoundingClientRect().height ?? 0;\n\n // the sidebars should not scroll beyond the total height of the header and tabs\n if (domTop < pageTop) {\n domTop = pageTop;\n }\n\n const scrollbarTopPx = Math.max(domTop, 0) + tabsHeight;\n\n element.style.top = `${scrollbarTopPx}px`;\n\n // set scrollbar height to ensure all links can be seen when content is small\n const footer = dom.querySelector('.md-container > .md-footer');\n // if no footer, fallback to using the bottom of the window\n const scrollbarEndPx =\n footer?.getBoundingClientRect().top ?? window.innerHeight;\n\n element.style.height = `${scrollbarEndPx - scrollbarTopPx}px`;\n }\n\n // show the sidebar only after updating its position\n element.style.setProperty('opacity', '1');\n });\n }, [dom, isMobileMedia]);\n\n useEffect(() => {\n window.addEventListener('resize', updateSidebarPositionAndHeight);\n window.addEventListener('scroll', updateSidebarPositionAndHeight, true);\n return () => {\n window.removeEventListener('resize', updateSidebarPositionAndHeight);\n window.removeEventListener(\n 'scroll',\n updateSidebarPositionAndHeight,\n true,\n );\n };\n }, [dom, updateSidebarPositionAndHeight]);\n\n // dynamically set width of footer to accommodate for pinning of the sidebar\n const updateFooterWidth = useCallback(() => {\n if (!dom) return;\n const footer = dom.querySelector<HTMLElement>('.md-footer');\n if (footer) {\n footer.style.width = `${dom.getBoundingClientRect().width}px`;\n }\n }, [dom]);\n\n useEffect(() => {\n window.addEventListener('resize', updateFooterWidth);\n return () => {\n window.removeEventListener('resize', updateFooterWidth);\n };\n }, [dom, updateFooterWidth]);\n\n // an update to \"state\" might lead to an updated UI so we include it as a trigger\n useEffect(() => {\n if (!isStyleLoading) {\n updateFooterWidth();\n updateSidebarPositionAndHeight();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n state,\n isStyleLoading,\n updateFooterWidth,\n updateSidebarPositionAndHeight,\n ]);\n\n // a function that performs transformations that are executed prior to adding it to the DOM\n const preRender = useCallback(\n (rawContent: string, contentPath: string) =>\n transformer(rawContent, [\n sanitizerTransformer,\n addBaseUrl({\n techdocsStorageApi,\n entityId: entityRef,\n path: contentPath,\n }),\n rewriteDocLinks(),\n addSidebarToggle(),\n removeMkdocsHeader(),\n simplifyMkdocsFooter(),\n ...(withFeedbackLink ? [addGitFeedbackLink(scmIntegrationsApi)] : []),\n stylesTransformer,\n ]),\n [\n // only add dependencies that are in state or memorized variables to avoid unnecessary calls between re-renders\n entityRef,\n scmIntegrationsApi,\n techdocsStorageApi,\n sanitizerTransformer,\n stylesTransformer,\n withFeedbackLink,\n ],\n );\n\n // a function that performs transformations that are executed after adding it to the DOM\n const postRender = useCallback(\n async (transformedElement: Element) =>\n transformer(transformedElement, [\n handleMetaRedirects(navigate, entityRef.name),\n scrollIntoNavigation(),\n copyToClipboard(theme),\n addLinkClickListener({\n baseUrl:\n configApi.getOptionalString('app.baseUrl') ||\n window.location.origin,\n onClick: (event: MouseEvent, url: string) => {\n // detect if CTRL or META keys are pressed so that links can be opened in a new tab with `window.open`\n const modifierActive = event.ctrlKey || event.metaKey;\n const parsedUrl = new URL(url);\n\n // capture link clicks within documentation\n const linkText =\n (event.target as HTMLAnchorElement | undefined)?.innerText || url;\n const to = url.replace(window.location.origin, '');\n analytics.captureEvent('click', linkText, { attributes: { to } });\n\n // hash exists when anchor is clicked on secondary sidebar\n if (parsedUrl.hash) {\n if (modifierActive) {\n window.open(url, '_blank');\n } else {\n // If it's in a different page, we navigate to it\n if (window.location.pathname !== parsedUrl.pathname) {\n navigate(url);\n } else {\n // If it's in the same page we avoid using navigate that causes\n // the page to rerender.\n window.history.pushState(\n null,\n document.title,\n parsedUrl.hash,\n );\n }\n // Scroll to hash if it's on the current page\n transformedElement\n ?.querySelector(`[id=\"${parsedUrl.hash.slice(1)}\"]`)\n ?.scrollIntoView();\n\n // Focus first focusable element in the target section\n (\n transformedElement\n ?.querySelector(`[id=\"${parsedUrl.hash.slice(1)}\"]`)\n ?.querySelector('a, button, [tabindex]') as HTMLElement\n )?.focus();\n }\n } else {\n if (modifierActive) {\n window.open(url, '_blank');\n } else {\n navigate(url);\n }\n }\n },\n }),\n // disable MkDocs drawer toggling ('for' attribute => checkbox mechanism)\n onCssReady({\n onLoading: () => {},\n onLoaded: () => {\n transformedElement\n .querySelector('.md-nav__title')\n ?.removeAttribute('for');\n },\n }),\n // hide sidebars until their positions are updated\n onCssReady({\n onLoading: () => {\n const sidebars = Array.from(\n transformedElement.querySelectorAll<HTMLElement>('.md-sidebar'),\n );\n sidebars.forEach(element => {\n element.style.setProperty('opacity', '0');\n });\n },\n onLoaded: () => {},\n }),\n addNavLinkKeyboardToggle(),\n ]),\n [theme, navigate, analytics, entityRef.name, configApi],\n );\n\n useEffect(() => {\n if (!rawPage) return () => {};\n\n // if false, there is already a newer execution of this effect\n let shouldReplaceContent = true;\n\n // Pre-render\n preRender(rawPage, path).then(async preTransformedDomElement => {\n if (!preTransformedDomElement?.innerHTML) {\n return; // An unexpected error occurred\n }\n\n // don't manipulate the shadow dom if this isn't the latest effect execution\n if (!shouldReplaceContent) {\n return;\n }\n\n // Skip this update if the location's path has changed but the state\n // contains a page that isn't loaded yet.\n if (currPath !== path) {\n return;\n }\n\n // Scroll to top after render\n window.scroll({ top: 0 });\n\n // Post-render\n const postTransformedDomElement = await postRender(\n preTransformedDomElement,\n );\n\n setDom(postTransformedDomElement as HTMLElement);\n });\n\n // cancel this execution\n return () => {\n shouldReplaceContent = false;\n };\n }, [rawPage, currPath, path, preRender, postRender]);\n\n return dom;\n};\n"],"names":["transformer"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useNavigateUrl.esm.js","sources":["../../../../src/reader/components/TechDocsReaderPageContent/useNavigateUrl.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport { useCallback, useRef } from 'react';\nimport { useNavigate } from 'react-router-dom';\n\n/**\n * Resolve a URL to a relative URL given a base URL that may or may not include subpaths.\n * @param url - URL to parse into a relative url based on the baseUrl.\n * @param baseUrl - Application base url, where the application is currently hosted.\n * @returns relative path without any subpaths from website config.\n */\nexport function resolveUrlToRelative(url: string, baseUrl: string) {\n const parsedAppUrl = new URL(baseUrl);\n const appUrlPath = `${parsedAppUrl.origin}${parsedAppUrl.pathname.replace(\n /\\/$/,\n '',\n )}`;\n\n const relativeUrl = url\n .replace(appUrlPath, '')\n // Remove any leading slashes.\n .replace(/^\\/+/, '');\n const parsedUrl = new URL(`http://localhost/${relativeUrl}`);\n return `${parsedUrl.pathname}${parsedUrl.search}${parsedUrl.hash}`;\n}\n\n/**\n * A helper hook that allows for full internal website urls to be processed through the navigate\n * hook provided by `react-router-dom`.\n *\n * NOTE: This does not support routing to external URLs. That should be done with a `Link` or `a`\n * element instead, or just `window.location.href`.\n *\n * TODO: Update this to use `useRouteRef` instead of `useApi`.\n *\n * @returns Navigation function that is a wrapper over `react-router-dom`'s\n * to support passing full URLs for navigation.\n *\n * @public\n */\nexport function useNavigateUrl() {\n // useRef prevents useNavigate from causing unnecessary re-renders\n const navigate = useRef(useNavigate());\n const configApi = useApi(configApiRef);\n const appBaseUrl = configApi.getOptionalString('app.baseUrl');\n const navigateFn = useCallback(\n (to: string) => {\n let url = to;\n /**\n * This should always be true when running the application, this just allows\n * test cases that do not have the configApi set up to run still.\n */\n if (appBaseUrl) {\n try {\n url = resolveUrlToRelative(to, appBaseUrl);\n } catch (err) {\n // URL passed in was relative.\n }\n }\n navigate.current(url);\n },\n [appBaseUrl],\n );\n return navigateFn;\n}\n"],"names":[],"mappings":";;;;AAyBO,SAAS,oBAAA,CAAqB,KAAa,OAAA,EAAiB;AACjE,EAAA,MAAM,YAAA,GAAe,IAAI,GAAA,CAAI,OAAO,CAAA;AACpC,EAAA,MAAM,aAAa,CAAA,EAAG,YAAA,CAAa,MAAM,CAAA,EAAG,aAAa,QAAA,CAAS,OAAA;AAAA,IAChE,KAAA;AAAA,IACA;AAAA,GACD,CAAA,CAAA;AAED,EAAA,MAAM,WAAA,GAAc,IACjB,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAA,CAEtB,OAAA,CAAQ,QAAQ,EAAE,CAAA;AACrB,EAAA,MAAM,SAAA,GAAY,IAAI,GAAA,CAAI,CAAA,iBAAA,EAAoB,WAAW,CAAA,CAAE,CAAA;AAC3D,EAAA,OAAO,CAAA,EAAG,UAAU,QAAQ,CAAA,EAAG,UAAU,MAAM,CAAA,EAAG,UAAU,IAAI,CAAA,CAAA;AAClE;AAgBO,SAAS,cAAA,GAAiB;AAE/B,EAAA,MAAM,QAAA,GAAW,MAAA,CAAO,WAAA,EAAa,CAAA;AACrC,EAAA,MAAM,SAAA,GAAY,OAAO,YAAY,CAAA;AACrC,EAAA,MAAM,UAAA,GAAa,SAAA,CAAU,iBAAA,CAAkB,aAAa,CAAA;AAC5D,EAAA,MAAM,UAAA,GAAa,WAAA;AAAA,IACjB,CAAC,EAAA,KAAe;AACd,MAAA,IAAI,GAAA,GAAM,EAAA;AAKV,MAAA,IAAI,UAAA,EAAY;AACd,QAAA,IAAI;AACF,UAAA,GAAA,GAAM,oBAAA,CAAqB,IAAI,UAAU,CAAA;AAAA,QAC3C,SAAS,GAAA,EAAK;AAAA,QAEd;AAAA,MACF;AACA,MAAA,QAAA,CAAS,QAAQ,GAAG,CAAA;AAAA,IACtB,CAAA;AAAA,IACA,CAAC,UAAU;AAAA,GACb;AACA,EAAA,OAAO,UAAA;AACT
|
|
1
|
+
{"version":3,"file":"useNavigateUrl.esm.js","sources":["../../../../src/reader/components/TechDocsReaderPageContent/useNavigateUrl.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport { useCallback, useRef } from 'react';\nimport { useNavigate } from 'react-router-dom';\n\n/**\n * Resolve a URL to a relative URL given a base URL that may or may not include subpaths.\n * @param url - URL to parse into a relative url based on the baseUrl.\n * @param baseUrl - Application base url, where the application is currently hosted.\n * @returns relative path without any subpaths from website config.\n */\nexport function resolveUrlToRelative(url: string, baseUrl: string) {\n const parsedAppUrl = new URL(baseUrl);\n const appUrlPath = `${parsedAppUrl.origin}${parsedAppUrl.pathname.replace(\n /\\/$/,\n '',\n )}`;\n\n const relativeUrl = url\n .replace(appUrlPath, '')\n // Remove any leading slashes.\n .replace(/^\\/+/, '');\n const parsedUrl = new URL(`http://localhost/${relativeUrl}`);\n return `${parsedUrl.pathname}${parsedUrl.search}${parsedUrl.hash}`;\n}\n\n/**\n * A helper hook that allows for full internal website urls to be processed through the navigate\n * hook provided by `react-router-dom`.\n *\n * NOTE: This does not support routing to external URLs. That should be done with a `Link` or `a`\n * element instead, or just `window.location.href`.\n *\n * TODO: Update this to use `useRouteRef` instead of `useApi`.\n *\n * @returns Navigation function that is a wrapper over `react-router-dom`'s\n * to support passing full URLs for navigation.\n *\n * @public\n */\nexport function useNavigateUrl() {\n // useRef prevents useNavigate from causing unnecessary re-renders\n const navigate = useRef(useNavigate());\n const configApi = useApi(configApiRef);\n const appBaseUrl = configApi.getOptionalString('app.baseUrl');\n const navigateFn = useCallback(\n (to: string) => {\n let url = to;\n /**\n * This should always be true when running the application, this just allows\n * test cases that do not have the configApi set up to run still.\n */\n if (appBaseUrl) {\n try {\n url = resolveUrlToRelative(to, appBaseUrl);\n } catch (err) {\n // URL passed in was relative.\n }\n }\n navigate.current(url);\n },\n [appBaseUrl],\n );\n return navigateFn;\n}\n"],"names":[],"mappings":";;;;AAyBO,SAAS,oBAAA,CAAqB,KAAa,OAAA,EAAiB;AACjE,EAAA,MAAM,YAAA,GAAe,IAAI,GAAA,CAAI,OAAO,CAAA;AACpC,EAAA,MAAM,aAAa,CAAA,EAAG,YAAA,CAAa,MAAM,CAAA,EAAG,aAAa,QAAA,CAAS,OAAA;AAAA,IAChE,KAAA;AAAA,IACA;AAAA,GACD,CAAA,CAAA;AAED,EAAA,MAAM,WAAA,GAAc,IACjB,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAA,CAEtB,OAAA,CAAQ,QAAQ,EAAE,CAAA;AACrB,EAAA,MAAM,SAAA,GAAY,IAAI,GAAA,CAAI,CAAA,iBAAA,EAAoB,WAAW,CAAA,CAAE,CAAA;AAC3D,EAAA,OAAO,CAAA,EAAG,UAAU,QAAQ,CAAA,EAAG,UAAU,MAAM,CAAA,EAAG,UAAU,IAAI,CAAA,CAAA;AAClE;AAgBO,SAAS,cAAA,GAAiB;AAE/B,EAAA,MAAM,QAAA,GAAW,MAAA,CAAO,WAAA,EAAa,CAAA;AACrC,EAAA,MAAM,SAAA,GAAY,OAAO,YAAY,CAAA;AACrC,EAAA,MAAM,UAAA,GAAa,SAAA,CAAU,iBAAA,CAAkB,aAAa,CAAA;AAC5D,EAAA,MAAM,UAAA,GAAa,WAAA;AAAA,IACjB,CAAC,EAAA,KAAe;AACd,MAAA,IAAI,GAAA,GAAM,EAAA;AAKV,MAAA,IAAI,UAAA,EAAY;AACd,QAAA,IAAI;AACF,UAAA,GAAA,GAAM,oBAAA,CAAqB,IAAI,UAAU,CAAA;AAAA,QAC3C,SAAS,GAAA,EAAK;AAAA,QAEd;AAAA,MACF;AACA,MAAA,QAAA,CAAS,QAAQ,GAAG,CAAA;AAAA,IACtB,CAAA;AAAA,IACA,CAAC,UAAU;AAAA,GACb;AACA,EAAA,OAAO,UAAA;AACT;;"}
|
|
@@ -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 } 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 { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport capitalize from 'lodash/capitalize';\n\nimport { rootRouteRef } from '../../../routes';\nimport { techdocsTranslationRef } from '../../../translation';\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 { t } = useTranslationRef(techdocsTranslationRef);\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 defaultKind=\"Component\"\n />\n }\n />\n {ownedByRelations.length > 0 && (\n <HeaderLabel\n label={t('readerPageHeader.owner')}\n value={\n <EntityRefLinks\n color=\"inherit\"\n entityRefs={ownedByRelations}\n defaultKind=\"group\"\n />\n }\n />\n )}\n {lifecycle ? (\n <HeaderLabel\n label={t('readerPageHeader.lifecycle')}\n value={String(lifecycle)}\n />\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 {t('readerPageHeader.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
|
+
{"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 { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport capitalize from 'lodash/capitalize';\n\nimport { rootRouteRef } from '../../../routes';\nimport { techdocsTranslationRef } from '../../../translation';\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 { t } = useTranslationRef(techdocsTranslationRef);\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 defaultKind=\"Component\"\n />\n }\n />\n {ownedByRelations.length > 0 && (\n <HeaderLabel\n label={t('readerPageHeader.owner')}\n value={\n <EntityRefLinks\n color=\"inherit\"\n entityRefs={ownedByRelations}\n defaultKind=\"group\"\n />\n }\n />\n )}\n {lifecycle ? (\n <HeaderLabel\n label={t('readerPageHeader.lifecycle')}\n value={String(lifecycle)}\n />\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 {t('readerPageHeader.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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"}
|