{"version":3,"sources":["datatypes/Pages.ts","datatypes/Common.ts","pagetypes/TopicPage.tsx"],"names":["buildPageUrl","pageId","sanitizeId","getPage","id","locale","url","fetchServerUrl","then","response","json","page","navbarIcon","iconId","iconStringToIdConversions","transformIconLocatorStringId","catch","reason","console","log","link","faLink","question","faQuestion","industry","faIndustry","faClipboardCheck","getSectionNameForContentType","contentType","key","toLowerCase","i18n","exists","t","getTooltipForContentType","toString","getPageTitleForContentType","getContentTypeSectionIndex","getIconForContentType","iconType","IconType","FontAwesome","faTasks","faInfoCircle","faFileAlt","faBook","replace","TopicPage","props","setPageTitle","useDDHPageContext","pageUrl","match","params","useState","pageContent","setPageContent","useTranslation","language","hash","window","location","queryString","parseQueryString","search","searchTermParam","split","useEffect","navbarText","title","keywords","contentMarkdown","libraries","collapseSectionsByDefault","source","highlightedTerms","scrollTo"],"mappings":"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","file":"static/js/8.db32182c.chunk.js","sourcesContent":["import { sanitizeId } from \"./Common\";\r\nimport { i18n } from \"../ddh-translations\";\r\nimport { fetchServerUrl } from \"../util\";\r\nimport { IconLocator, IconType } from \"../components/IconRenderer\";\r\nimport {\r\n faTasks,\r\n faInfoCircle,\r\n faBook,\r\n faFileAlt,\r\n faLink,\r\n faQuestion,\r\n faIndustry,\r\n faClipboardCheck,\r\n} from \"@fortawesome/free-solid-svg-icons\";\r\nimport { IconProp } from \"@fortawesome/fontawesome-svg-core\";\r\n\r\nexport function buildPageUrl(pageId: string): string {\r\n return `/page/${sanitizeId(pageId)}`;\r\n}\r\n\r\n/**\r\n * Defines the header data and content for a page in the system.\r\n */\r\nexport interface DDHPage {\r\n /** The unique content ID used to retrieve this page. */\r\n id: string;\r\n\r\n /** The title of the page. Should be displayed at the top of the page and in link text to this page. */\r\n title: string;\r\n\r\n /** The type of page. Used to style and group links to this page. */\r\n contentType: string;\r\n\r\n navbarText?: string | undefined;\r\n\r\n navbarIcon?: IconLocator | undefined;\r\n\r\n /** The content of the page in markdown. */\r\n contentMarkdown: string;\r\n\r\n keywords: string[];\r\n\r\n libraries: string[] | null;\r\n\r\n collapseSectionsByDefault: boolean;\r\n}\r\n\r\n/**\r\n * Retrieves the complete contents of the page by doing a GET request to the API and returning the\r\n * resulting JSON. Returns a promise that resolves when the request is complete.\r\n * @param id The unique page content ID to retrieve.\r\n */\r\nexport function getPage(id: string, locale: string): Promise<DDHPage | null> {\r\n var url = `/api/page/${sanitizeId(id)}?locale=${locale}`;\r\n return fetchServerUrl(url)\r\n .then((response) => response.json())\r\n .then((page) => transformIconLocatorStringId(page))\r\n .catch((reason) => {\r\n console.log(`Error retrieving page ${url}`);\r\n console.log(reason);\r\n return null;\r\n });\r\n}\r\n\r\nconst iconStringToIdConversions: { [id: string]: IconProp } = {\r\n link: faLink,\r\n question: faQuestion,\r\n industry: faIndustry,\r\n \"clipboard-check\": faClipboardCheck,\r\n};\r\n\r\nfunction transformIconLocatorStringId(page: DDHPage | null) {\r\n if (\r\n page &&\r\n page.navbarIcon &&\r\n typeof page.navbarIcon.iconId === \"string\" &&\r\n iconStringToIdConversions[page.navbarIcon.iconId]\r\n ) {\r\n page.navbarIcon.iconId =\r\n iconStringToIdConversions[page.navbarIcon.iconId];\r\n }\r\n return page;\r\n}\r\n\r\n/**\r\n * Converts a page content type ID into a friendly name to show the user.\r\n * @param contentType The ID of the content type.\r\n */\r\nexport function getSectionNameForContentType(contentType: string): string {\r\n const key = `ContentTypeSectionName_${contentType.toLowerCase()}`;\r\n if (i18n.exists(key)) {\r\n return i18n.t(key);\r\n } else {\r\n return i18n.t(`ContentTypeSectionName_(default)`);\r\n }\r\n}\r\n\r\nexport function getTooltipForContentType(contentType: string): string | null {\r\n const key = `ContentTypeTooltip_${contentType.toLowerCase()}`;\r\n if (i18n.exists(key)) {\r\n return i18n.t(key).toString();\r\n } else {\r\n return null;\r\n }\r\n}\r\n\r\nexport function getPageTitleForContentType(contentType: string): string {\r\n const key = `ContentTypePageTitle_${contentType.toLowerCase()}`;\r\n if (i18n.exists(key)) {\r\n return i18n.t(key);\r\n } else {\r\n return i18n.t(`ContentTypePageTitle_(default)`);\r\n }\r\n}\r\n\r\n/** Defines the order in which contentTypes should be displayed in results. Higher weights are displayed first. */\r\nexport function getContentTypeSectionIndex(contentType: string): number {\r\n switch (contentType.toLowerCase()) {\r\n case \"requirement\":\r\n return 1000;\r\n case \"citation\":\r\n return 999;\r\n case \"document\":\r\n return 998;\r\n default:\r\n return 0;\r\n }\r\n}\r\n\r\nexport function getIconForContentType(contentType: string) {\r\n switch (contentType) {\r\n case \"requirement\":\r\n return {\r\n iconType: IconType.FontAwesome,\r\n iconId: faTasks,\r\n };\r\n case \"guidance\":\r\n return {\r\n iconType: IconType.FontAwesome,\r\n iconId: faInfoCircle,\r\n };\r\n case \"document\":\r\n return {\r\n iconType: IconType.FontAwesome,\r\n iconId: faFileAlt,\r\n };\r\n case \"glossary\":\r\n return {\r\n iconType: IconType.FontAwesome,\r\n iconId: faBook,\r\n };\r\n default:\r\n return null;\r\n }\r\n}\r\n","/**\r\n * Strips all characters other than a-z, A-Z, 0-9, and dashes (-) from a string.\r\n * @param id The ID to be sanitized.\r\n */\r\nexport function sanitizeId(id: string) {\r\n return id.replace(/[^a-zA-Z0-9-]/g, \"-\");\r\n}\r\n","import React, { useEffect, useState } from \"react\";\r\nimport ContentMarkdown from \"../components/ContentMarkdown\";\r\nimport { useDDHPageContext } from \"../components/DDHPageContext\";\r\nimport Loading from \"../components/Loading\";\r\nimport {\r\n DDHPage,\r\n getIconForContentType,\r\n getPage,\r\n getPageTitleForContentType,\r\n} from \"../datatypes/Pages\";\r\nimport { parseQueryString } from \"../util\";\r\nimport { useTranslation } from \"react-i18next\";\r\n\r\nfunction getIconForPage(page: DDHPage) {\r\n if (page.navbarIcon != null) {\r\n return page.navbarIcon;\r\n } else {\r\n return getIconForContentType(page.contentType);\r\n }\r\n}\r\n\r\nexport default function TopicPage(props: any) {\r\n const { setPageTitle } = useDDHPageContext();\r\n const pageUrl: string = props.match.params[0];\r\n const [pageContent, setPageContent] = useState<DDHPage | null>(null);\r\n const {\r\n t,\r\n i18n: { language: locale },\r\n } = useTranslation();\r\n\r\n // Update window.location hash (/page#anchor)\r\n var hash =\r\n (window.location.hash && window.location.hash.replace(\"#\", \"\")) || null;\r\n\r\n var queryString = parseQueryString(window.location.search);\r\n var searchTermParam =\r\n (queryString[\"searchTerm\"] &&\r\n queryString[\"searchTerm\"].split(/\\s+/g)) ||\r\n null;\r\n\r\n useEffect(() => {\r\n getPage(pageUrl, locale).then((pageContent) => {\r\n if (pageContent != null) {\r\n setPageContent(pageContent);\r\n setPageTitle(\r\n pageContent.navbarText ||\r\n getPageTitleForContentType(pageContent.contentType),\r\n pageContent.title,\r\n getIconForPage(pageContent)\r\n );\r\n } else {\r\n setPageContent({\r\n id: \"404\",\r\n contentType: \"\",\r\n keywords: [],\r\n contentMarkdown: `${t(\"NoPage\")} \"${pageUrl}\"`,\r\n title: t(\"PageNotFound\"),\r\n libraries: null,\r\n collapseSectionsByDefault: false,\r\n });\r\n }\r\n });\r\n }, [pageUrl, setPageTitle, t, locale]);\r\n\r\n return pageContent === null ? (\r\n <Loading />\r\n ) : (\r\n <div id=\"content\">\r\n <h1>{pageContent.title}</h1>\r\n <ContentMarkdown\r\n source={pageContent.contentMarkdown}\r\n collapseSectionsByDefault={\r\n pageContent.collapseSectionsByDefault\r\n }\r\n highlightedTerms={searchTermParam}\r\n scrollTo={hash || null}\r\n />\r\n </div>\r\n );\r\n}\r\n"],"sourceRoot":""}