diff options
author | David Cho-Lerat <david.cho-lerat@sonarsource.com> | 2024-05-30 08:45:19 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2024-05-30 20:02:37 +0000 |
commit | a640894218f96025a7a79337d54b88bacc0dbafc (patch) | |
tree | 6b56fe6679ca835536351c286d7748fffa601fcc | |
parent | c2d51c83a63b4c490576bbb80daa74c8ed5e7685 (diff) | |
download | sonarqube-a640894218f96025a7a79337d54b88bacc0dbafc.tar.gz sonarqube-a640894218f96025a7a79337d54b88bacc0dbafc.zip |
SONAR-22253 Extract all documentation link URLs to a separate module
129 files changed, 590 insertions, 490 deletions
diff --git a/server/sonar-web/src/main/js/app/components/DocumentationRedirect.tsx b/server/sonar-web/src/main/js/app/components/DocumentationRedirect.tsx index ce07d94d59d..ebfdf4c0cc9 100644 --- a/server/sonar-web/src/main/js/app/components/DocumentationRedirect.tsx +++ b/server/sonar-web/src/main/js/app/components/DocumentationRedirect.tsx @@ -17,17 +17,18 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { Link } from 'design-system'; + +import { LinkStandalone } from '@sonarsource/echoes-react'; import * as React from 'react'; import { Helmet } from 'react-helmet-async'; import { useLocation } from 'react-router-dom'; -import { useDocUrl } from '../../helpers/docs'; +import { useUncataloguedDocUrl } from '../../helpers/docs'; const PAUSE_REDIRECT = 1; export default function DocumentationRedirect() { const location = useLocation(); - const url = useDocUrl(location.pathname.replace(/^\/documentation/, '')); + const url = useUncataloguedDocUrl(location.pathname.replace(/^\/documentation/, '')) as string; return ( <> @@ -40,7 +41,9 @@ export default function DocumentationRedirect() { <span className="global-loading-text">Redirecting...</span> </div> <div> - <Link to={url}>Click here if you're not being redirected automatically</Link> + <LinkStandalone to={url}> + Click here if you're not being redirected automatically + </LinkStandalone> </div> </div> </> diff --git a/server/sonar-web/src/main/js/app/components/GlobalFooter.tsx b/server/sonar-web/src/main/js/app/components/GlobalFooter.tsx index 098292751bf..88cc3c86170 100644 --- a/server/sonar-web/src/main/js/app/components/GlobalFooter.tsx +++ b/server/sonar-web/src/main/js/app/components/GlobalFooter.tsx @@ -31,6 +31,7 @@ import React from 'react'; import { useIntl } from 'react-intl'; import InstanceMessage from '../../components/common/InstanceMessage'; import AppVersionStatus from '../../components/shared/AppVersionStatus'; +import { DocLink } from '../../helpers/doc-links'; import { useDocUrl } from '../../helpers/docs'; import { getEdition } from '../../helpers/editions'; import GlobalFooterBranding from './GlobalFooterBranding'; @@ -97,7 +98,7 @@ export default function GlobalFooter({ hideLoggedInInfo }: Readonly<GlobalFooter </li> <li> - <LinkStandalone highlight={LinkHighlight.CurrentColor} to={docUrl('/')}> + <LinkStandalone highlight={LinkHighlight.CurrentColor} to={docUrl(DocLink.Root)}> {intl.formatMessage({ id: 'footer.documentation' })} </LinkStandalone> </li> @@ -105,7 +106,7 @@ export default function GlobalFooter({ hideLoggedInInfo }: Readonly<GlobalFooter <li> <LinkStandalone highlight={LinkHighlight.CurrentColor} - to={docUrl('/instance-administration/plugin-version-matrix/')} + to={docUrl(DocLink.InstanceAdminPluginVersionMatrix)} > {intl.formatMessage({ id: 'footer.plugins' })} </LinkStandalone> diff --git a/server/sonar-web/src/main/js/app/components/app-state/AppStateContext.tsx b/server/sonar-web/src/main/js/app/components/app-state/AppStateContext.tsx index 4492d1c18d6..1d88b1d220e 100644 --- a/server/sonar-web/src/main/js/app/components/app-state/AppStateContext.tsx +++ b/server/sonar-web/src/main/js/app/components/app-state/AppStateContext.tsx @@ -17,7 +17,9 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import * as React from 'react'; +import { DOC_URL } from '../../../helpers/doc-links'; import { AppState } from '../../../types/appstate'; export const DEFAULT_APP_STATE = { @@ -29,6 +31,6 @@ export const DEFAULT_APP_STATE = { settings: {}, version: '', versionEOL: '', - documentationUrl: 'https://docs.sonarsource.com/sonarqube/latest', + documentationUrl: DOC_URL, }; export const AppStateContext = React.createContext<AppState>(DEFAULT_APP_STATE); diff --git a/server/sonar-web/src/main/js/app/components/indexation/IndexationNotificationRenderer.tsx b/server/sonar-web/src/main/js/app/components/indexation/IndexationNotificationRenderer.tsx index 72561a3e5b9..63d1429414a 100644 --- a/server/sonar-web/src/main/js/app/components/indexation/IndexationNotificationRenderer.tsx +++ b/server/sonar-web/src/main/js/app/components/indexation/IndexationNotificationRenderer.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + /* eslint-disable react/no-unused-prop-types */ import styled from '@emotion/styled'; import { @@ -33,6 +34,7 @@ import * as React from 'react'; import { FormattedMessage } from 'react-intl'; import { queryToSearchString } from '~sonar-aligned/helpers/urls'; import DocumentationLink from '../../../components/common/DocumentationLink'; +import { DocLink } from '../../../helpers/doc-links'; import { translate, translateWithParameters } from '../../../helpers/l10n'; import { IndexationNotificationType } from '../../../types/indexation'; import { TaskStatuses, TaskTypes } from '../../../types/tasks'; @@ -215,7 +217,7 @@ function renderBackgroundTasksPageLink(hasError: boolean, text: string) { function renderIndexationDocPageLink() { return ( - <DocumentationLink className="sw-whitespace-nowrap" to="/instance-administration/reindexing/"> + <DocumentationLink className="sw-whitespace-nowrap" to={DocLink.InstanceAdminReindexation}> <FormattedMessage id="indexation.features_partly_available.link" /> </DocumentationLink> ); diff --git a/server/sonar-web/src/main/js/app/components/nav/component/branch-like/BranchHelpTooltip.tsx b/server/sonar-web/src/main/js/app/components/nav/component/branch-like/BranchHelpTooltip.tsx index 7f97acc9051..6d6f4aa61d5 100644 --- a/server/sonar-web/src/main/js/app/components/nav/component/branch-like/BranchHelpTooltip.tsx +++ b/server/sonar-web/src/main/js/app/components/nav/component/branch-like/BranchHelpTooltip.tsx @@ -17,11 +17,13 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { Link } from '@sonarsource/echoes-react'; import { HelperHintIcon } from 'design-system'; import React from 'react'; import DocHelpTooltip from '~sonar-aligned/components/controls/DocHelpTooltip'; import HelpTooltip from '~sonar-aligned/components/controls/HelpTooltip'; +import { DocLink } from '../../../../../helpers/doc-links'; import { translate, translateWithParameters } from '../../../../../helpers/l10n'; import { getApplicationAdminUrl } from '../../../../../helpers/urls'; import { useProjectBindingQuery } from '../../../../../queries/devops-integration'; @@ -103,18 +105,18 @@ export default function BranchHelpTooltip({ data-test="only-one-branch-like" links={[ { - href: '/analyzing-source-code/branches/branch-analysis/', + href: DocLink.BranchAnalysis, label: translate('branch_like_navigation.only_one_branch.documentation'), }, { - href: '/analyzing-source-code/pull-request-analysis', + href: DocLink.PullRequestAnalysis, label: translate('branch_like_navigation.only_one_branch.pr_analysis'), }, { + doc: false, href: `/tutorials?id=${component.key}`, - label: translate('branch_like_navigation.tutorial_for_ci'), inPlace: true, - doc: false, + label: translate('branch_like_navigation.tutorial_for_ci'), }, ]} title={translate('branch_like_navigation.only_one_branch.title')} diff --git a/server/sonar-web/src/main/js/apps/account/Account.tsx b/server/sonar-web/src/main/js/apps/account/Account.tsx index 8521ac7a0b8..84a1b46b1f5 100644 --- a/server/sonar-web/src/main/js/apps/account/Account.tsx +++ b/server/sonar-web/src/main/js/apps/account/Account.tsx @@ -25,7 +25,6 @@ import { Helmet } from 'react-helmet-async'; import { Outlet } from 'react-router-dom'; import A11ySkipTarget from '~sonar-aligned/components/a11y/A11ySkipTarget'; import { useCurrentLoginUser } from '../../app/components/current-user/CurrentUserContext'; -import Suggestions from '../../components/embed-docs-modal/Suggestions'; import { translate, translateWithParameters } from '../../helpers/l10n'; import Nav from './components/Nav'; import UserCard from './components/UserCard'; @@ -59,8 +58,6 @@ export default function Account() { <LargeCenteredLayout as="main"> <PageContentFontWrapper className="sw-body-sm sw-py-8"> - <Suggestions suggestions="account" /> - <Helmet defaultTitle={title} defer={false} diff --git a/server/sonar-web/src/main/js/apps/audit-logs/components/AuditAppRenderer.tsx b/server/sonar-web/src/main/js/apps/audit-logs/components/AuditAppRenderer.tsx index 4b4dfd81586..1ba1ff7fe1c 100644 --- a/server/sonar-web/src/main/js/apps/audit-logs/components/AuditAppRenderer.tsx +++ b/server/sonar-web/src/main/js/apps/audit-logs/components/AuditAppRenderer.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { Link, RadioButtonGroup } from '@sonarsource/echoes-react'; import { subDays } from 'date-fns'; import { @@ -30,7 +31,6 @@ import * as React from 'react'; import { Helmet } from 'react-helmet-async'; import { FormattedMessage } from 'react-intl'; import { queryToSearchString } from '~sonar-aligned/helpers/urls'; -import Suggestions from '../../../components/embed-docs-modal/Suggestions'; import { now } from '../../../helpers/dates'; import { translate } from '../../../helpers/l10n'; import '../style.css'; @@ -79,7 +79,6 @@ export default function AuditAppRenderer(props: Readonly<AuditAppRendererProps>) return ( <LargeCenteredLayout as="main" id="audit-logs-page"> <PageContentFontWrapper className="sw-body-sm sw-my-8"> - <Suggestions suggestions="audit-logs" /> <Helmet title={translate('audit_logs.page')} /> <Title>{translate('audit_logs.page')}</Title> diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/BackgroundTasksApp.tsx b/server/sonar-web/src/main/js/apps/background-tasks/components/BackgroundTasksApp.tsx index b5539eb3fcc..c5b584c14ea 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/BackgroundTasksApp.tsx +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/BackgroundTasksApp.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { Spinner } from '@sonarsource/echoes-react'; import { LargeCenteredLayout, PageContentFontWrapper } from 'design-system'; import { debounce } from 'lodash'; @@ -35,6 +36,7 @@ import withComponentContext from '../../../app/components/componentContext/withC import ListFooter from '../../../components/controls/ListFooter'; import Suggestions from '../../../components/embed-docs-modal/Suggestions'; import { toShortISO8601String } from '../../../helpers/dates'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; import { parseAsDate } from '../../../helpers/query'; import { Task, TaskStatuses } from '../../../types/tasks'; @@ -227,7 +229,7 @@ export class BackgroundTasksApp extends React.PureComponent<Props, State> { return ( <LargeCenteredLayout id="background-tasks"> <PageContentFontWrapper className="sw-my-4 sw-body-sm"> - <Suggestions suggestions="background_tasks" /> + <Suggestions suggestion={DocLink.BackgroundTasks} /> <Helmet defer={false} title={translate('background_tasks.page')} /> <Spinner isLoading={!types}> <Header component={component} /> diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/Header.tsx b/server/sonar-web/src/main/js/apps/background-tasks/components/Header.tsx index 821621de0ff..275e3adf8f6 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/Header.tsx +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/Header.tsx @@ -17,9 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { Title } from 'design-system'; import * as React from 'react'; import DocumentationLink from '../../../components/common/DocumentationLink'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; import { Component } from '../../../types/types'; import Workers from './Workers'; @@ -35,7 +37,7 @@ export default function Header(props: Readonly<Props>) { <Title className="sw-mb-4">{translate('background_tasks.page')}</Title> <p className="sw-max-w-3/4"> {translate('background_tasks.page.description')} - <DocumentationLink className="sw-ml-2" to="/analyzing-source-code/background-tasks/"> + <DocumentationLink className="sw-ml-2" to={DocLink.BackgroundTasks}> {translate('learn_more')} </DocumentationLink> </p> diff --git a/server/sonar-web/src/main/js/apps/code/components/CodeAppRenderer.tsx b/server/sonar-web/src/main/js/apps/code/components/CodeAppRenderer.tsx index 3f514a8e076..9072e7221c7 100644 --- a/server/sonar-web/src/main/js/apps/code/components/CodeAppRenderer.tsx +++ b/server/sonar-web/src/main/js/apps/code/components/CodeAppRenderer.tsx @@ -35,7 +35,6 @@ import { isPortfolioLike } from '~sonar-aligned/helpers/component'; import { Breadcrumb } from '~sonar-aligned/types/component'; import { Location } from '~sonar-aligned/types/router'; import ListFooter from '../../../components/controls/ListFooter'; -import Suggestions from '../../../components/embed-docs-modal/Suggestions'; import AnalysisMissingInfoMessage from '../../../components/shared/AnalysisMissingInfoMessage'; import { CCT_SOFTWARE_QUALITY_METRICS, OLD_TAXONOMY_METRICS } from '../../../helpers/constants'; import { KeyboardKeys } from '../../../helpers/keycodes'; @@ -125,7 +124,6 @@ export default function CodeAppRenderer(props: Readonly<Props>) { return ( <LargeCenteredLayout className="sw-py-8 sw-body-md" id="code-page"> - <Suggestions suggestions="code" /> <Helmet defer={false} title={sourceViewer !== undefined ? sourceViewer.name : defaultTitle} /> <A11ySkipTarget anchor="code_main" /> diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/ActivationFormModal.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/ActivationFormModal.tsx index 087d44a1086..f5af3a12738 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/components/ActivationFormModal.tsx +++ b/server/sonar-web/src/main/js/apps/coding-rules/components/ActivationFormModal.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { ButtonPrimary, FlagMessage, @@ -31,6 +32,7 @@ import { import * as React from 'react'; import { Profile } from '../../../api/quality-profiles'; import DocumentationLink from '../../../components/common/DocumentationLink'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; import { sanitizeString } from '../../../helpers/sanitize'; import { useActivateRuleMutation } from '../../../queries/quality-profiles'; @@ -119,7 +121,7 @@ export default function ActivationFormModal(props: Readonly<Props>) { {translate('coding_rules.severity_deprecated')} <DocumentationLink className="sw-ml-2 sw-whitespace-nowrap" - to="/user-guide/clean-code/introduction/" + to={DocLink.CleanCodeIntroduction} > {translate('learn_more')} </DocumentationLink> diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/CodingRulesApp.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/CodingRulesApp.tsx index 5c1e289b151..970b3a959e6 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/components/CodingRulesApp.tsx +++ b/server/sonar-web/src/main/js/apps/coding-rules/components/CodingRulesApp.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import styled from '@emotion/styled'; import { InputSearch, @@ -40,6 +41,7 @@ import withCurrentUserContext from '../../../app/components/current-user/withCur import ListFooter from '../../../components/controls/ListFooter'; import Suggestions from '../../../components/embed-docs-modal/Suggestions'; import '../../../components/search-navigator.css'; +import { DocLink } from '../../../helpers/doc-links'; import { isInput, isShortcut } from '../../../helpers/keyboardEventHelpers'; import { KeyboardKeys } from '../../../helpers/keycodes'; import { translate, translateWithParameters } from '../../../helpers/l10n'; @@ -566,7 +568,7 @@ export class CodingRulesApp extends React.PureComponent<Props, State> { return ( <> - <Suggestions suggestions="coding_rules" /> + <Suggestions suggestion={DocLink.InstanceAdminQualityProfiles} /> {openRule ? ( <Helmet defer={false} diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/ProfileFacet.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/ProfileFacet.tsx index 480ba05fb86..4d16aa93642 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/components/ProfileFacet.tsx +++ b/server/sonar-web/src/main/js/apps/coding-rules/components/ProfileFacet.tsx @@ -17,12 +17,14 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import styled from '@emotion/styled'; import { FacetBox, FacetItem, HelperHintIcon, Note, themeColor } from 'design-system'; import { sortBy } from 'lodash'; import * as React from 'react'; import DocHelpTooltip from '~sonar-aligned/components/controls/DocHelpTooltip'; import { Profile } from '../../../api/quality-profiles'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; import { Dict } from '../../../types/types'; import { FacetItemsList } from '../../issues/sidebar/FacetItemsList'; @@ -179,7 +181,7 @@ export default class ProfileFacet extends React.PureComponent<Props> { content={translate('coding_rules.facet.qprofile.help')} links={[ { - href: '/instance-administration/quality-profiles/', + href: DocLink.InstanceAdminQualityProfiles, label: translate('coding_rules.facet.qprofile.link'), }, ]} diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsHeaderActions.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsHeaderActions.tsx index 46d82b187b4..e9b3835e384 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsHeaderActions.tsx +++ b/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsHeaderActions.tsx @@ -17,12 +17,14 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { Note, SeparatorCircleIcon, TextSubdued } from 'design-system'; import * as React from 'react'; import DocHelpTooltip from '~sonar-aligned/components/controls/DocHelpTooltip'; import IssueSeverityIcon from '../../../components/icon-mappers/IssueSeverityIcon'; import IssueTypeIcon from '../../../components/icon-mappers/IssueTypeIcon'; import TagsList from '../../../components/tags/TagsList'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; import { IssueSeverity } from '../../../types/issues'; import { Dict, RuleDetails } from '../../../types/types'; @@ -53,7 +55,7 @@ export default function RuleDetailsHeaderActions(props: Readonly<Props>) { } links={[ { - href: '/user-guide/rules/overview', + href: DocLink.RulesOverview, label: translate('learn_more'), }, ]} @@ -84,7 +86,7 @@ export default function RuleDetailsHeaderActions(props: Readonly<Props>) { } links={[ { - href: '/user-guide/rules/overview', + href: DocLink.RulesOverview, label: translate('learn_more'), }, ]} diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/RuleListItem.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/RuleListItem.tsx index 81aba54fac1..8351a52a534 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/components/RuleListItem.tsx +++ b/server/sonar-web/src/main/js/apps/coding-rules/components/RuleListItem.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import styled from '@emotion/styled'; import { Badge, @@ -37,6 +38,7 @@ import { CleanCodeAttributePill } from '../../../components/shared/CleanCodeAttr import SoftwareImpactPillList from '../../../components/shared/SoftwareImpactPillList'; import TypeHelper from '../../../components/shared/TypeHelper'; import TagsList from '../../../components/tags/TagsList'; +import { DocLink } from '../../../helpers/doc-links'; import { translate, translateWithParameters } from '../../../helpers/l10n'; import { getRuleUrl } from '../../../helpers/urls'; import { Rule } from '../../../types/types'; @@ -254,7 +256,7 @@ export default class RuleListItem extends React.PureComponent<Props> { } links={[ { - href: '/user-guide/clean-code/introduction', + href: DocLink.CleanCodeIntroduction, label: translate('learn_more'), }, ]} diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/SeverityFacet.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/SeverityFacet.tsx index 7e6e1d124e9..6acfbcc3871 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/components/SeverityFacet.tsx +++ b/server/sonar-web/src/main/js/apps/coding-rules/components/SeverityFacet.tsx @@ -17,11 +17,13 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { HelperHintIcon } from 'design-system'; import * as React from 'react'; import DocHelpTooltip from '~sonar-aligned/components/controls/DocHelpTooltip'; import SoftwareImpactSeverityIcon from '../../../components/icon-mappers/SoftwareImpactSeverityIcon'; import { IMPACT_SEVERITIES } from '../../../helpers/constants'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; import Facet, { BasicProps } from './Facet'; @@ -59,7 +61,7 @@ export default function SeverityFacet(props: BasicProps) { } links={[ { - href: '/user-guide/clean-code/introduction', + href: DocLink.CleanCodeIntroduction, label: translate('learn_more'), }, ]} diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/ComponentMeasuresApp.tsx b/server/sonar-web/src/main/js/apps/component-measures/components/ComponentMeasuresApp.tsx index 9eccd8c6154..343b6cd4acc 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/components/ComponentMeasuresApp.tsx +++ b/server/sonar-web/src/main/js/apps/component-measures/components/ComponentMeasuresApp.tsx @@ -287,7 +287,7 @@ class ComponentMeasuresApp extends React.PureComponent<Props, State> { return ( <LargeCenteredLayout id="component-measures" className="sw-pt-8"> - <Suggestions suggestions="component_measures" /> + <Suggestions suggestionGroup="component_measures" /> <Helmet defer={false} title={translate('layout.measures')} /> <PageContentFontWrapper className="sw-body-sm"> <Spinner isLoading={this.state.loading} /> diff --git a/server/sonar-web/src/main/js/apps/create/project/components/NewCodeDefinitionSelection.tsx b/server/sonar-web/src/main/js/apps/create/project/components/NewCodeDefinitionSelection.tsx index 12389b26b7c..43e1b37568f 100644 --- a/server/sonar-web/src/main/js/apps/create/project/components/NewCodeDefinitionSelection.tsx +++ b/server/sonar-web/src/main/js/apps/create/project/components/NewCodeDefinitionSelection.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { ButtonPrimary, ButtonSecondary, @@ -37,6 +38,7 @@ import { useNavigate, unstable_usePrompt as usePrompt } from 'react-router-dom'; import { useLocation } from '~sonar-aligned/components/hoc/withRouter'; import { queryToSearchString } from '~sonar-aligned/helpers/urls'; import NewCodeDefinitionSelector from '../../../../components/new-code-definition/NewCodeDefinitionSelector'; +import { DocLink } from '../../../../helpers/doc-links'; import { useDocUrl } from '../../../../helpers/docs'; import { translate } from '../../../../helpers/l10n'; import { getProjectUrl } from '../../../../helpers/urls'; @@ -69,7 +71,7 @@ export default function NewCodeDefinitionSelection(props: Props) { const intl = useIntl(); const location = useLocation(); const navigate = useNavigate(); - const getDocUrl = useDocUrl(); + const docUrl = useDocUrl(DocLink.NewCodeDefinition); usePrompt({ when: isImporting, message: translate('onboarding.create_project.please_dont_leave'), @@ -215,11 +217,7 @@ export default function NewCodeDefinitionSelection(props: Props) { id="onboarding.create_project.new_code_definition.description" values={{ link: ( - <Link - to={getDocUrl( - '/project-administration/clean-as-you-code-settings/defining-new-code/', - )} - > + <Link to={docUrl}> {translate('onboarding.create_project.new_code_definition.description.link')} </Link> ), diff --git a/server/sonar-web/src/main/js/apps/create/project/manual/ManualProjectCreate.tsx b/server/sonar-web/src/main/js/apps/create/project/manual/ManualProjectCreate.tsx index 6804fc11ddf..3663ddbd302 100644 --- a/server/sonar-web/src/main/js/apps/create/project/manual/ManualProjectCreate.tsx +++ b/server/sonar-web/src/main/js/apps/create/project/manual/ManualProjectCreate.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import classNames from 'classnames'; import { ButtonPrimary, @@ -36,6 +37,7 @@ import { isEmpty } from 'lodash'; import * as React from 'react'; import { FormattedMessage, useIntl } from 'react-intl'; import { getValue } from '../../../../api/settings'; +import { DocLink } from '../../../../helpers/doc-links'; import { useDocUrl } from '../../../../helpers/docs'; import { translate } from '../../../../helpers/l10n'; import { GlobalSettingKeys } from '../../../../types/settings'; @@ -70,7 +72,7 @@ export default function ManualProjectCreate(props: Readonly<Props>) { }); const intl = useIntl(); - const docUrl = useDocUrl(); + const docUrl = useDocUrl(DocLink.BranchAnalysis); React.useEffect(() => { async function fetchMainBranchName() { @@ -194,11 +196,7 @@ export default function ManualProjectCreate(props: Readonly<Props>) { id="onboarding.create_project.main_branch_name.description" defaultMessage={translate('onboarding.create_project.main_branch_name.description')} values={{ - learn_more: ( - <Link to={docUrl('/analyzing-source-code/branches/branch-analysis')}> - {translate('learn_more')} - </Link> - ), + learn_more: <Link to={docUrl}>{translate('learn_more')}</Link>, }} /> </Note> diff --git a/server/sonar-web/src/main/js/apps/create/project/monorepo/MonorepoConnectionSelector.tsx b/server/sonar-web/src/main/js/apps/create/project/monorepo/MonorepoConnectionSelector.tsx index db6ac2b47bc..9025f7e7391 100644 --- a/server/sonar-web/src/main/js/apps/create/project/monorepo/MonorepoConnectionSelector.tsx +++ b/server/sonar-web/src/main/js/apps/create/project/monorepo/MonorepoConnectionSelector.tsx @@ -17,7 +17,8 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { Title } from 'design-system/lib'; + +import { Title } from 'design-system'; import React from 'react'; import { FormattedMessage } from 'react-intl'; import { GroupBase } from 'react-select'; diff --git a/server/sonar-web/src/main/js/apps/create/project/monorepo/MonorepoProjectHeader.tsx b/server/sonar-web/src/main/js/apps/create/project/monorepo/MonorepoProjectHeader.tsx index 1c1dad76528..ae8fc6f4182 100644 --- a/server/sonar-web/src/main/js/apps/create/project/monorepo/MonorepoProjectHeader.tsx +++ b/server/sonar-web/src/main/js/apps/create/project/monorepo/MonorepoProjectHeader.tsx @@ -17,11 +17,13 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { LinkStandalone } from '@sonarsource/echoes-react'; -import { LightPrimary, Title } from 'design-system/lib'; +import { LightPrimary, Title } from 'design-system'; import React from 'react'; import { FormattedMessage, useIntl } from 'react-intl'; import { useLocation } from '~sonar-aligned/components/hoc/withRouter'; +import { DocLink } from '../../../../helpers/doc-links'; import { useDocUrl } from '../../../../helpers/docs'; export function MonorepoProjectHeader() { @@ -45,7 +47,7 @@ export function MonorepoProjectHeader() { </LightPrimary> </div> <div className="sw-mt-3"> - <LinkStandalone isExternal to={useDocUrl('/project-administration/monorepos/')}> + <LinkStandalone isExternal to={useDocUrl(DocLink.Monorepos)}> <FormattedMessage id="onboarding.create_project.monorepo.doc_link" /> </LinkStandalone> </div> diff --git a/server/sonar-web/src/main/js/apps/groups/GroupsApp.tsx b/server/sonar-web/src/main/js/apps/groups/GroupsApp.tsx index 952985e7ece..6e79893b4eb 100644 --- a/server/sonar-web/src/main/js/apps/groups/GroupsApp.tsx +++ b/server/sonar-web/src/main/js/apps/groups/GroupsApp.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { InputSearch, LargeCenteredLayout, PageContentFontWrapper } from 'design-system'; import * as React from 'react'; import { useState } from 'react'; @@ -25,7 +26,6 @@ import GitHubSynchronisationWarning from '../../app/components/GitHubSynchronisa import GitLabSynchronisationWarning from '../../app/components/GitLabSynchronisationWarning'; import ListFooter from '../../components/controls/ListFooter'; import { ManagedFilter } from '../../components/controls/ManagedFilter'; -import Suggestions from '../../components/embed-docs-modal/Suggestions'; import { translate } from '../../helpers/l10n'; import { useGroupsQueries } from '../../queries/groups'; import { useIdentityProviderQuery } from '../../queries/identity-provider/common'; @@ -48,7 +48,6 @@ export default function GroupsApp() { return ( <LargeCenteredLayout> <PageContentFontWrapper className="sw-my-8 sw-body-sm"> - <Suggestions suggestions="user_groups" /> <Helmet defer={false} title={translate('user_groups.page')} /> <main> <Header manageProvider={manageProvider?.provider} /> diff --git a/server/sonar-web/src/main/js/apps/groups/components/Header.tsx b/server/sonar-web/src/main/js/apps/groups/components/Header.tsx index b65ef05e028..b2adc904b51 100644 --- a/server/sonar-web/src/main/js/apps/groups/components/Header.tsx +++ b/server/sonar-web/src/main/js/apps/groups/components/Header.tsx @@ -17,10 +17,12 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { ButtonPrimary, FlagMessage, Title } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; import DocumentationLink from '../../../components/common/DocumentationLink'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; import { Provider } from '../../../types/types'; import GroupForm from './GroupForm'; @@ -57,7 +59,7 @@ export default function Header({ manageProvider }: Readonly<HeaderProps>) { values={{ provider: manageProvider, link: ( - <DocumentationLink to="/instance-administration/authentication/overview/"> + <DocumentationLink to={DocLink.AuthOverview}> {translate('documentation')} </DocumentationLink> ), diff --git a/server/sonar-web/src/main/js/apps/issues/components/IssueGuide.tsx b/server/sonar-web/src/main/js/apps/issues/components/IssueGuide.tsx index 32e94ac3f4b..adab9244364 100644 --- a/server/sonar-web/src/main/js/apps/issues/components/IssueGuide.tsx +++ b/server/sonar-web/src/main/js/apps/issues/components/IssueGuide.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { SpotlightTour, SpotlightTourStep } from 'design-system'; import React, { useState } from 'react'; import { FormattedMessage } from 'react-intl'; @@ -25,6 +26,7 @@ import { dismissNotice } from '../../../api/users'; import { CurrentUserContext } from '../../../app/components/current-user/CurrentUserContext'; import DocumentationLink from '../../../components/common/DocumentationLink'; import { SCREEN_POSITION_COMPUTE_DELAY } from '../../../components/common/ScreenPositionHelper'; +import { DocLink } from '../../../helpers/doc-links'; import { translate, translateWithParameters } from '../../../helpers/l10n'; import { NoticeType } from '../../../types/users'; @@ -153,7 +155,7 @@ export default function IssueGuide({ run }: Props) { defaultMessage={translate('guiding.issue_list.5.content')} values={{ link: ( - <DocumentationLink to="/user-guide/clean-code/introduction" className="sw-capitalize"> + <DocumentationLink to={DocLink.CleanCodeIntroduction} className="sw-capitalize"> {translate('documentation')} </DocumentationLink> ), diff --git a/server/sonar-web/src/main/js/apps/issues/components/IssueNewStatusAndTransitionGuide.tsx b/server/sonar-web/src/main/js/apps/issues/components/IssueNewStatusAndTransitionGuide.tsx index e6864f98730..7f83156f91a 100644 --- a/server/sonar-web/src/main/js/apps/issues/components/IssueNewStatusAndTransitionGuide.tsx +++ b/server/sonar-web/src/main/js/apps/issues/components/IssueNewStatusAndTransitionGuide.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { SpotlightTour, SpotlightTourStep } from 'design-system'; import React, { useState } from 'react'; import { useIntl } from 'react-intl'; @@ -24,6 +25,7 @@ import { CallBackProps } from 'react-joyride'; import { useCurrentUser } from '../../../app/components/current-user/CurrentUserContext'; import DocumentationLink from '../../../components/common/DocumentationLink'; import { SCREEN_POSITION_COMPUTE_DELAY } from '../../../components/common/ScreenPositionHelper'; +import { DocLink } from '../../../helpers/doc-links'; import { useDismissNoticeMutation } from '../../../queries/users'; import { IssueTransition } from '../../../types/issues'; import { Issue } from '../../../types/types'; @@ -36,7 +38,6 @@ interface Props { } const PLACEMENT_RIGHT = 'right'; -const DOC_LINK = '/user-guide/issues/#statuses'; export const SESSION_STORAGE_TRANSITION_GUIDE_KEY = 'issueNewStatusAndTransitionGuideStep'; const EXTRA_DELAY = 100; const GUIDE_WIDTH = 360; @@ -145,7 +146,7 @@ export default function IssueNewStatusAndTransitionGuide(props: Readonly<Props>) <span>{intl.formatMessage({ id: `guiding.issue_accept.${stepIndex}.content.1` })}</span> <span>{intl.formatMessage({ id: `guiding.issue_accept.${stepIndex}.content.2` })}</span> </div> - <DocumentationLink to={DOC_LINK} className="sw-mt-1 sw-inline-block"> + <DocumentationLink to={DocLink.IssueStatuses} className="sw-mt-1 sw-inline-block"> {intl.formatMessage({ id: `guiding.issue_accept.${stepIndex}.content.link` })} </DocumentationLink> </> diff --git a/server/sonar-web/src/main/js/apps/issues/components/IssueOpenInIdeButton.tsx b/server/sonar-web/src/main/js/apps/issues/components/IssueOpenInIdeButton.tsx index 8a1ab07731c..63852374650 100644 --- a/server/sonar-web/src/main/js/apps/issues/components/IssueOpenInIdeButton.tsx +++ b/server/sonar-web/src/main/js/apps/issues/components/IssueOpenInIdeButton.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { ButtonSecondary, DropdownMenu, @@ -30,6 +31,7 @@ import { import * as React from 'react'; import { FormattedMessage } from 'react-intl'; import DocumentationLink from '../../../components/common/DocumentationLink'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; import { generateSonarLintUserToken, @@ -58,7 +60,7 @@ const showError = () => id="issues.open_in_ide.failure" values={{ link: ( - <DocumentationLink to="user-guide/sonarlint-connected-mode/"> + <DocumentationLink to={DocLink.SonarLintConnectedMode}> {translate('sonarlint-connected-mode-doc')} </DocumentationLink> ), diff --git a/server/sonar-web/src/main/js/apps/issues/components/IssuesApp.tsx b/server/sonar-web/src/main/js/apps/issues/components/IssuesApp.tsx index 3ba705f36a2..60df939d6d0 100644 --- a/server/sonar-web/src/main/js/apps/issues/components/IssuesApp.tsx +++ b/server/sonar-web/src/main/js/apps/issues/components/IssuesApp.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import styled from '@emotion/styled'; import { Checkbox, Spinner } from '@sonarsource/echoes-react'; import classNames from 'classnames'; @@ -47,7 +48,6 @@ import withCurrentUserContext from '../../../app/components/current-user/withCur import EmptySearch from '../../../components/common/EmptySearch'; import ScreenPositionHelper from '../../../components/common/ScreenPositionHelper'; import ListFooter from '../../../components/controls/ListFooter'; -import Suggestions from '../../../components/embed-docs-modal/Suggestions'; import withIndexationContext, { WithIndexationContextProps, } from '../../../components/hoc/withIndexationContext'; @@ -1299,8 +1299,6 @@ export class App extends React.PureComponent<Props, State> { <LargeCenteredLayout> <PageContentFontWrapper className="sw-body-sm"> <div className="sw-w-full sw-flex" id="issues-page"> - <Suggestions suggestions="issues" /> - {openIssue ? ( <Helmet defer={false} diff --git a/server/sonar-web/src/main/js/apps/issues/components/__tests__/IssueOpenInIdeButton-test.tsx b/server/sonar-web/src/main/js/apps/issues/components/__tests__/IssueOpenInIdeButton-test.tsx index 3dc7783093f..7fe54312832 100644 --- a/server/sonar-web/src/main/js/apps/issues/components/__tests__/IssueOpenInIdeButton-test.tsx +++ b/server/sonar-web/src/main/js/apps/issues/components/__tests__/IssueOpenInIdeButton-test.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { addGlobalErrorMessage, addGlobalSuccessMessage } from 'design-system'; @@ -24,6 +25,7 @@ import * as React from 'react'; import { FormattedMessage } from 'react-intl'; import UserTokensMock from '../../../../api/mocks/UserTokensMock'; import DocumentationLink from '../../../../components/common/DocumentationLink'; +import { DocLink } from '../../../../helpers/doc-links'; import { openIssue as openSonarLintIssue, probeSonarLintServers, @@ -97,7 +99,7 @@ it('handles button click with no ide found', async () => { id="issues.open_in_ide.failure" values={{ link: ( - <DocumentationLink to="user-guide/sonarlint-connected-mode/"> + <DocumentationLink to={DocLink.SonarLintConnectedMode}> sonarlint-connected-mode-doc </DocumentationLink> ), diff --git a/server/sonar-web/src/main/js/apps/issues/sidebar/SeverityFacet.tsx b/server/sonar-web/src/main/js/apps/issues/sidebar/SeverityFacet.tsx index 68d0102e30d..d4be7b73af1 100644 --- a/server/sonar-web/src/main/js/apps/issues/sidebar/SeverityFacet.tsx +++ b/server/sonar-web/src/main/js/apps/issues/sidebar/SeverityFacet.tsx @@ -17,11 +17,13 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { HelperHintIcon } from 'design-system'; import * as React from 'react'; import DocHelpTooltip from '~sonar-aligned/components/controls/DocHelpTooltip'; import SoftwareImpactSeverityIcon from '../../../components/icon-mappers/SoftwareImpactSeverityIcon'; import { IMPACT_SEVERITIES } from '../../../helpers/constants'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; import { SoftwareImpactSeverity } from '../../../types/clean-code-taxonomy'; import { CommonProps, SimpleListStyleFacet } from './SimpleListStyleFacet'; @@ -53,7 +55,7 @@ export function SeverityFacet(props: Props) { } links={[ { - href: '/user-guide/clean-code/introduction', + href: DocLink.CleanCodeIntroduction, label: translate('learn_more'), }, ]} diff --git a/server/sonar-web/src/main/js/apps/maintenance/components/App.tsx b/server/sonar-web/src/main/js/apps/maintenance/components/App.tsx index 90a89d048fd..57b0e4383da 100644 --- a/server/sonar-web/src/main/js/apps/maintenance/components/App.tsx +++ b/server/sonar-web/src/main/js/apps/maintenance/components/App.tsx @@ -29,6 +29,7 @@ import DocumentationLink from '../../../components/common/DocumentationLink'; import InstanceMessage from '../../../components/common/InstanceMessage'; import DateFromNow from '../../../components/intl/DateFromNow'; import TimeFormatter from '../../../components/intl/TimeFormatter'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; import { getBaseUrl } from '../../../helpers/system'; import { isDefined } from '../../../helpers/types'; @@ -264,7 +265,7 @@ export default class App extends React.PureComponent<Props, State> { id="maintenance.sonarqube_is_under_maintenance.2" values={{ link: ( - <DocumentationLink to="/setup-and-upgrade/upgrade-the-server/roadmap/"> + <DocumentationLink to={DocLink.ServerUpgradeRoadmap}> {translate('maintenance.sonarqube_is_under_maintenance_link.2')} </DocumentationLink> ), diff --git a/server/sonar-web/src/main/js/apps/marketplace/App.tsx b/server/sonar-web/src/main/js/apps/marketplace/App.tsx index 2046602b6d7..87e7faaaaf0 100644 --- a/server/sonar-web/src/main/js/apps/marketplace/App.tsx +++ b/server/sonar-web/src/main/js/apps/marketplace/App.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { BasicSeparator, FlagMessage, @@ -35,7 +36,7 @@ import { getAvailablePlugins, getInstalledPlugins } from '../../api/plugins'; import { getValue, setSimpleSettingValue } from '../../api/settings'; import DocumentationLink from '../../components/common/DocumentationLink'; import ListFooter from '../../components/controls/ListFooter'; -import Suggestions from '../../components/embed-docs-modal/Suggestions'; +import { DocLink } from '../../helpers/doc-links'; import { translate } from '../../helpers/l10n'; import { EditionKey } from '../../types/editions'; import { PendingPluginResult, Plugin, RiskConsent } from '../../types/plugins'; @@ -167,7 +168,6 @@ class App extends React.PureComponent<Props, State> { return ( <LargeCenteredLayout as="main" id="marketplace-page"> <PageContentFontWrapper className="sw-body-sm sw-py-8"> - <Suggestions suggestions="marketplace" /> <Helmet title={translate('marketplace.page')} /> <Header currentEdition={currentEdition} /> <EditionBoxes currentEdition={currentEdition} /> @@ -186,7 +186,7 @@ class App extends React.PureComponent<Props, State> { defaultMessage={translate('marketplace.page.plugins.description2')} values={{ link: ( - <DocumentationLink to="/instance-administration/marketplace/"> + <DocumentationLink to={DocLink.InstanceAdminMarketplace}> {translate('marketplace.page.plugins.description2.link')} </DocumentationLink> ), diff --git a/server/sonar-web/src/main/js/apps/overview/branches/ApplicationNonCaycProjectWarning.tsx b/server/sonar-web/src/main/js/apps/overview/branches/ApplicationNonCaycProjectWarning.tsx index 3ac624b1b81..454a9774483 100644 --- a/server/sonar-web/src/main/js/apps/overview/branches/ApplicationNonCaycProjectWarning.tsx +++ b/server/sonar-web/src/main/js/apps/overview/branches/ApplicationNonCaycProjectWarning.tsx @@ -17,9 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { Card, FlagMessage, Link } from 'design-system'; import * as React from 'react'; import { getBranchLikeQuery } from '~sonar-aligned/helpers/branch-like'; +import { DocLink } from '../../../helpers/doc-links'; import { useDocUrl } from '../../../helpers/docs'; import { translate, translateWithParameters } from '../../../helpers/l10n'; import { getProjectQueryUrl } from '../../../helpers/urls'; @@ -30,7 +32,7 @@ interface Props { } export default function ApplicationNonCaycProjectWarning({ projects }: Props) { - const caycUrl = useDocUrl('/user-guide/clean-as-you-code/'); + const caycUrl = useDocUrl(DocLink.CaYC); return ( <Card className="sw-mt-4 sw-body-sm"> diff --git a/server/sonar-web/src/main/js/apps/overview/branches/CleanAsYouCodeWarning.tsx b/server/sonar-web/src/main/js/apps/overview/branches/CleanAsYouCodeWarning.tsx index 80329d7672b..b18f457346e 100644 --- a/server/sonar-web/src/main/js/apps/overview/branches/CleanAsYouCodeWarning.tsx +++ b/server/sonar-web/src/main/js/apps/overview/branches/CleanAsYouCodeWarning.tsx @@ -17,9 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { DiscreetLink, FlagMessage, Link } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; +import { DocLink } from '../../../helpers/doc-links'; import { useDocUrl } from '../../../helpers/docs'; import { translate } from '../../../helpers/l10n'; import { getQualityGateUrl } from '../../../helpers/urls'; @@ -30,7 +32,7 @@ interface Props { } export default function CleanAsYouCodeWarning({ component }: Props) { - const caycUrl = useDocUrl('/user-guide/clean-as-you-code/'); + const caycUrl = useDocUrl(DocLink.CaYC); return ( <> diff --git a/server/sonar-web/src/main/js/apps/overview/branches/MeasuresPanelNoNewCode.tsx b/server/sonar-web/src/main/js/apps/overview/branches/MeasuresPanelNoNewCode.tsx index f83bfb0f858..ee764a4f15d 100644 --- a/server/sonar-web/src/main/js/apps/overview/branches/MeasuresPanelNoNewCode.tsx +++ b/server/sonar-web/src/main/js/apps/overview/branches/MeasuresPanelNoNewCode.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { Link } from '@sonarsource/echoes-react'; import { Note, getTabPanelId } from 'design-system'; import * as React from 'react'; @@ -26,6 +27,7 @@ import { queryToSearchString } from '~sonar-aligned/helpers/urls'; import { ComponentQualifier } from '~sonar-aligned/types/component'; import DocumentationLink from '../../../components/common/DocumentationLink'; import { Image } from '../../../components/common/Image'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; import { CodeScope } from '../../../helpers/urls'; import { Branch } from '../../../types/branch-like'; @@ -109,9 +111,7 @@ export default function MeasuresPanelNoNewCode(props: MeasuresPanelNoNewCodeProp id="overview.measures.empty_link" values={{ learn_more_link: ( - <DocumentationLink to="/user-guide/clean-as-you-code/"> - {translate('learn_more')} - </DocumentationLink> + <DocumentationLink to={DocLink.CaYC}>{translate('learn_more')}</DocumentationLink> ), }} /> diff --git a/server/sonar-web/src/main/js/apps/overview/branches/ReplayTour.tsx b/server/sonar-web/src/main/js/apps/overview/branches/ReplayTour.tsx index 5ea043a93a1..14de43615a9 100644 --- a/server/sonar-web/src/main/js/apps/overview/branches/ReplayTour.tsx +++ b/server/sonar-web/src/main/js/apps/overview/branches/ReplayTour.tsx @@ -17,8 +17,10 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { SpotlightTour, SpotlightTourStep } from 'design-system'; import React from 'react'; +import { DocLink } from '../../../helpers/doc-links'; import { useDocUrl } from '../../../helpers/docs'; import { translate } from '../../../helpers/l10n'; @@ -37,7 +39,7 @@ export default function ReplayTourGuide({ run, closeTour, tourCompleted }: Reado const constructContent = (first: string) => <p className="sw-mt-2">{translate(first)}</p>; - const docUrl = useDocUrl('improving/clean-as-you-code/'); + const docUrl = useDocUrl(DocLink.CaYC); const steps: SpotlightTourStep[] = [ { diff --git a/server/sonar-web/src/main/js/apps/overview/branches/TabsPanel.tsx b/server/sonar-web/src/main/js/apps/overview/branches/TabsPanel.tsx index 72b3839f8a2..a7f6537c34e 100644 --- a/server/sonar-web/src/main/js/apps/overview/branches/TabsPanel.tsx +++ b/server/sonar-web/src/main/js/apps/overview/branches/TabsPanel.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { Spinner } from '@sonarsource/echoes-react'; import { isBefore, sub } from 'date-fns'; import { ButtonLink, FlagMessage, LightLabel, Tabs } from 'design-system'; @@ -24,6 +25,7 @@ import * as React from 'react'; import { FormattedMessage } from 'react-intl'; import { ComponentQualifier } from '~sonar-aligned/types/component'; import DocumentationLink from '../../../components/common/DocumentationLink'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; import { isDiffMetric } from '../../../helpers/measures'; import { CodeScope } from '../../../helpers/urls'; @@ -174,7 +176,7 @@ export function TabsPanel(props: React.PropsWithChildren<MeasuresPanelProps>) { )}`} <DocumentationLink className="sw-ml-1 sw-whitespace-nowrap" - to="/instance-administration/reindexing/" + to={DocLink.InstanceAdminReindexation} > {translate('learn_more')} </DocumentationLink> diff --git a/server/sonar-web/src/main/js/apps/overview/components/App.tsx b/server/sonar-web/src/main/js/apps/overview/components/App.tsx index a4920fc60c8..ead3f2d259e 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/App.tsx +++ b/server/sonar-web/src/main/js/apps/overview/components/App.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import * as React from 'react'; import { Helmet } from 'react-helmet-async'; import { isPullRequest } from '~sonar-aligned/helpers/branch-like'; @@ -54,12 +55,12 @@ export function App(props: AppProps) { <Helmet defer={false} title={translate('overview.page')} /> {isPullRequest(branchLike) ? ( <main> - <Suggestions suggestions="pull_requests" /> + <Suggestions suggestionGroup="pull_requests" /> <PullRequestOverview pullRequest={branchLike} component={component} /> </main> ) : ( <main> - <Suggestions suggestions="overview" /> + <Suggestions suggestionGroup="overview" /> {!component.analysisDate && ( <EmptyOverview diff --git a/server/sonar-web/src/main/js/apps/permission-templates/components/PermissionTemplatesApp.tsx b/server/sonar-web/src/main/js/apps/permission-templates/components/PermissionTemplatesApp.tsx index 451c29772d8..e9305f632b8 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/components/PermissionTemplatesApp.tsx +++ b/server/sonar-web/src/main/js/apps/permission-templates/components/PermissionTemplatesApp.tsx @@ -17,13 +17,13 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import * as React from 'react'; import { Helmet } from 'react-helmet-async'; import { withRouter } from '~sonar-aligned/components/hoc/withRouter'; import { Location } from '~sonar-aligned/types/router'; import { getPermissionTemplates } from '../../../api/permissions'; import withAppStateContext from '../../../app/components/app-state/withAppStateContext'; -import Suggestions from '../../../components/embed-docs-modal/Suggestions'; import { translate } from '../../../helpers/l10n'; import { AppState } from '../../../types/appstate'; import { Permission, PermissionTemplate } from '../../../types/types'; @@ -102,7 +102,6 @@ class PermissionTemplatesApp extends React.PureComponent<Props, State> { const { permissionTemplates, permissions, ready } = this.state; return ( <> - <Suggestions suggestions="permission_templates" /> <Helmet defer={false} title={translate('permission_templates.page')} /> {id === undefined ? ( diff --git a/server/sonar-web/src/main/js/apps/permissions/global/components/PermissionsGlobalApp.tsx b/server/sonar-web/src/main/js/apps/permissions/global/components/PermissionsGlobalApp.tsx index d3d91fd2a1b..c22a320554e 100644 --- a/server/sonar-web/src/main/js/apps/permissions/global/components/PermissionsGlobalApp.tsx +++ b/server/sonar-web/src/main/js/apps/permissions/global/components/PermissionsGlobalApp.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { LargeCenteredLayout, PageContentFontWrapper } from 'design-system'; import { without } from 'lodash'; import * as React from 'react'; @@ -26,7 +27,6 @@ import * as api from '../../../../api/permissions'; import withAppStateContext, { WithAppStateContextProps, } from '../../../../app/components/app-state/withAppStateContext'; -import Suggestions from '../../../../components/embed-docs-modal/Suggestions'; import AllHoldersList from '../../../../components/permissions/AllHoldersList'; import { FilterOption } from '../../../../components/permissions/SearchForm'; import { translate } from '../../../../helpers/l10n'; @@ -259,7 +259,6 @@ class PermissionsGlobalApp extends React.PureComponent<Props, State> { return ( <LargeCenteredLayout id="project-permissions-page"> <PageContentFontWrapper className="sw-my-8 sw-body-sm"> - <Suggestions suggestions="global_permissions" /> <Helmet defer={false} title={translate('global_permissions.permission')} /> <PageHeader /> <AllHoldersList diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAppRenderer.tsx b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAppRenderer.tsx index c42b8d6ba67..781cd0bbb17 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAppRenderer.tsx +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAppRenderer.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import styled from '@emotion/styled'; import { LargeCenteredLayout, @@ -28,7 +29,6 @@ import * as React from 'react'; import { Helmet } from 'react-helmet-async'; import A11ySkipTarget from '~sonar-aligned/components/a11y/A11ySkipTarget'; import { ComponentQualifier } from '~sonar-aligned/types/component'; -import Suggestions from '../../../components/embed-docs-modal/Suggestions'; import { translate } from '../../../helpers/l10n'; import { MeasureHistory, ParsedAnalysis } from '../../../types/project-activity'; import { Component, Metric } from '../../../types/types'; @@ -69,7 +69,6 @@ export default function ProjectActivityAppRenderer(props: Props) { const canDeleteAnalyses = configuration?.showHistory; return ( <main className="sw-p-5" id="project-activity"> - <Suggestions suggestions="project_activity" /> <Helmet defer={false} title={translate('project_activity.page')} /> <A11ySkipTarget anchor="activity_main" /> diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityGraphs.tsx b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityGraphs.tsx index a286a1ba593..c3eb54a28ab 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityGraphs.tsx +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityGraphs.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { FlagMessage } from 'design-system'; import { debounce, findLast, maxBy, minBy, sortBy } from 'lodash'; import * as React from 'react'; @@ -35,6 +36,7 @@ import { } from '../../../components/activity-graph/utils'; import DocumentationLink from '../../../components/common/DocumentationLink'; import { CCT_SOFTWARE_QUALITY_METRICS } from '../../../helpers/constants'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; import { GraphType, @@ -229,10 +231,7 @@ export default class ProjectActivityGraphs extends React.PureComponent<Props, St tagName="div" values={{ learn_more: ( - <DocumentationLink - className="sw-whitespace-nowrap" - to="/user-guide/clean-code/code-analysis/" - > + <DocumentationLink className="sw-whitespace-nowrap" to={DocLink.CodeAnalysis}> {translate('learn_more')} </DocumentationLink> ), diff --git a/server/sonar-web/src/main/js/apps/projectBranches/components/SetAsMainBranchModal.tsx b/server/sonar-web/src/main/js/apps/projectBranches/components/SetAsMainBranchModal.tsx index e57ba4a2d10..e2965ad022f 100644 --- a/server/sonar-web/src/main/js/apps/projectBranches/components/SetAsMainBranchModal.tsx +++ b/server/sonar-web/src/main/js/apps/projectBranches/components/SetAsMainBranchModal.tsx @@ -17,10 +17,12 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { ButtonPrimary, FlagMessage, Modal } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; import DocumentationLink from '../../../components/common/DocumentationLink'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; import { useSetMainBranchMutation } from '../../../queries/branch'; import { Branch } from '../../../types/branch-like'; @@ -70,7 +72,7 @@ export default function SetAsMainBranchModal(props: SetAsMainBranchModalProps) { id="project_branch_pull_request.branch.main_branch.learn_more" values={{ documentation: ( - <DocumentationLink to="/analyzing-source-code/branches/branch-analysis/#main-branch"> + <DocumentationLink to={DocLink.MainBranchAnalysis}> {translate('documentation')} </DocumentationLink> ), diff --git a/server/sonar-web/src/main/js/apps/projectInformation/projectRegulatoryReport/RegulatoryReport.tsx b/server/sonar-web/src/main/js/apps/projectInformation/projectRegulatoryReport/RegulatoryReport.tsx index 24729625d74..bcac8e01fc5 100644 --- a/server/sonar-web/src/main/js/apps/projectInformation/projectRegulatoryReport/RegulatoryReport.tsx +++ b/server/sonar-web/src/main/js/apps/projectInformation/projectRegulatoryReport/RegulatoryReport.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { BasicSeparator, DownloadButton, @@ -34,6 +35,7 @@ import { getBranches } from '../../../api/branches'; import { getRegulatoryReportUrl } from '../../../api/regulatory-report'; import DocumentationLink from '../../../components/common/DocumentationLink'; import { getBranchLikeDisplayName, getBranchLikeKey } from '../../../helpers/branch-like'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; import { LabelValueSelectOption } from '../../../helpers/search'; import { BranchLike } from '../../../types/branch-like'; @@ -140,7 +142,7 @@ export default function RegulatoryReport({ component, branchLike }: Props) { defaultMessage={translate('regulatory_page.available_branches_info.more_info')} values={{ doc_link: ( - <DocumentationLink to="/analyzing-source-code/branches/branch-analysis/#inactive-branches"> + <DocumentationLink to={DocLink.InactiveBranches}> {translate('regulatory_page.available_branches_info.more_info.doc_link')} </DocumentationLink> ), diff --git a/server/sonar-web/src/main/js/apps/projectNewCode/components/AppHeader.tsx b/server/sonar-web/src/main/js/apps/projectNewCode/components/AppHeader.tsx index c8be13dc973..bd9d0cc49c2 100644 --- a/server/sonar-web/src/main/js/apps/projectNewCode/components/AppHeader.tsx +++ b/server/sonar-web/src/main/js/apps/projectNewCode/components/AppHeader.tsx @@ -17,9 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { HeadingDark, Link, Title } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; +import { DocLink } from '../../../helpers/doc-links'; import { useDocUrl } from '../../../helpers/docs'; import { translate } from '../../../helpers/l10n'; @@ -29,7 +31,7 @@ export interface AppHeaderProps { export default function AppHeader(props: AppHeaderProps) { const { canAdmin } = props; - const toUrl = useDocUrl('/project-administration/clean-as-you-code-settings/defining-new-code/'); + const toUrl = useDocUrl(DocLink.NewCodeDefinition); return ( <header className="sw-mt-8 sw-mb-4"> diff --git a/server/sonar-web/src/main/js/apps/projectNewCode/components/ProjectNewCodeDefinitionApp.tsx b/server/sonar-web/src/main/js/apps/projectNewCode/components/ProjectNewCodeDefinitionApp.tsx index 8905321c0c8..1d56019cc44 100644 --- a/server/sonar-web/src/main/js/apps/projectNewCode/components/ProjectNewCodeDefinitionApp.tsx +++ b/server/sonar-web/src/main/js/apps/projectNewCode/components/ProjectNewCodeDefinitionApp.tsx @@ -29,6 +29,7 @@ import withAvailableFeatures, { import withComponentContext from '../../../app/components/componentContext/withComponentContext'; import Suggestions from '../../../components/embed-docs-modal/Suggestions'; import { sortBranches } from '../../../helpers/branch-like'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; import { DEFAULT_NEW_CODE_DEFINITION_TYPE, @@ -192,7 +193,7 @@ function ProjectNewCodeDefinitionApp(props: Readonly<ProjectNewCodeDefinitionApp return ( <LargeCenteredLayout id="new-code-rules-page"> - <Suggestions suggestions="project_baseline" /> + <Suggestions suggestion={DocLink.NewCodeDefinition} /> <Helmet defer={false} title={translate('project_baseline.page')} /> diff --git a/server/sonar-web/src/main/js/apps/projectQualityGate/ProjectQualityGateAppRenderer.tsx b/server/sonar-web/src/main/js/apps/projectQualityGate/ProjectQualityGateAppRenderer.tsx index cafa4b943a9..50528c55e9b 100644 --- a/server/sonar-web/src/main/js/apps/projectQualityGate/ProjectQualityGateAppRenderer.tsx +++ b/server/sonar-web/src/main/js/apps/projectQualityGate/ProjectQualityGateAppRenderer.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { ButtonPrimary, FlagMessage, @@ -39,6 +40,7 @@ import A11ySkipTarget from '~sonar-aligned/components/a11y/A11ySkipTarget'; import HelpTooltip from '~sonar-aligned/components/controls/HelpTooltip'; import DisableableSelectOption from '../../components/common/DisableableSelectOption'; import Suggestions from '../../components/embed-docs-modal/Suggestions'; +import { DocLink } from '../../helpers/doc-links'; import { translate } from '../../helpers/l10n'; import { isDiffMetric } from '../../helpers/measures'; import { LabelValueSelectOption } from '../../helpers/search'; @@ -127,7 +129,7 @@ export default function ProjectQualityGateAppRenderer(props: ProjectQualityGateA return ( <LargeCenteredLayout id="project-quality-gate"> <PageContentFontWrapper className="sw-my-8 sw-body-sm"> - <Suggestions suggestions="project_quality_gate" /> + <Suggestions suggestion={DocLink.CaYC} /> <Helmet defer={false} title={translate('project_quality_gate.page')} /> <A11ySkipTarget anchor="qg_main" /> diff --git a/server/sonar-web/src/main/js/apps/projectQualityProfiles/ProjectQualityProfilesAppRenderer.tsx b/server/sonar-web/src/main/js/apps/projectQualityProfiles/ProjectQualityProfilesAppRenderer.tsx index 42a80d32cb1..c256af2ee11 100644 --- a/server/sonar-web/src/main/js/apps/projectQualityProfiles/ProjectQualityProfilesAppRenderer.tsx +++ b/server/sonar-web/src/main/js/apps/projectQualityProfiles/ProjectQualityProfilesAppRenderer.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { ActionCell, ButtonPrimary, @@ -40,6 +41,7 @@ import A11ySkipTarget from '~sonar-aligned/components/a11y/A11ySkipTarget'; import HelpTooltip from '~sonar-aligned/components/controls/HelpTooltip'; import { Profile } from '../../api/quality-profiles'; import Suggestions from '../../components/embed-docs-modal/Suggestions'; +import { DocLink } from '../../helpers/doc-links'; import { translate } from '../../helpers/l10n'; import { getRulesUrl } from '../../helpers/urls'; import { Component } from '../../types/types'; @@ -91,7 +93,7 @@ export default function ProjectQualityProfilesAppRenderer( return ( <LargeCenteredLayout id="project-quality-profiles"> <PageContentFontWrapper className="sw-my-8 sw-body-sm"> - <Suggestions suggestions="project_quality_profiles" /> + <Suggestions suggestion={DocLink.InstanceAdminQualityProfiles} /> <Helmet defer={false} title={translate('project_quality_profiles.page')} /> <A11ySkipTarget anchor="profiles_main" /> diff --git a/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx b/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx index 5da6829970f..18518ea0133 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx @@ -34,13 +34,11 @@ import { useSearchParams } from 'react-router-dom'; import A11ySkipTarget from '~sonar-aligned/components/a11y/A11ySkipTarget'; import { withRouter } from '~sonar-aligned/components/hoc/withRouter'; import { ComponentQualifier } from '~sonar-aligned/types/component'; -import { MetricKey } from '~sonar-aligned/types/metrics'; import { Location, RawQuery, Router } from '~sonar-aligned/types/router'; import { searchProjects } from '../../../api/components'; import withAppStateContext from '../../../app/components/app-state/withAppStateContext'; import withCurrentUserContext from '../../../app/components/current-user/withCurrentUserContext'; import ScreenPositionHelper from '../../../components/common/ScreenPositionHelper'; -import Suggestions from '../../../components/embed-docs-modal/Suggestions'; import '../../../components/search-navigator.css'; import handleRequiredAuthentication from '../../../helpers/handleRequiredAuthentication'; import { translate } from '../../../helpers/l10n'; @@ -307,7 +305,6 @@ export class AllProjects extends React.PureComponent<Props, State> { render() { return ( <StyledWrapper id="projects-page"> - <Suggestions suggestions={MetricKey.projects} /> <Helmet defer={false} title={translate('projects.page')} /> <h1 className="sw-sr-only">{translate('projects.page')}</h1> diff --git a/server/sonar-web/src/main/js/apps/projectsManagement/ProjectManagementApp.tsx b/server/sonar-web/src/main/js/apps/projectsManagement/ProjectManagementApp.tsx index aa3412d0a13..8447e0d8dae 100644 --- a/server/sonar-web/src/main/js/apps/projectsManagement/ProjectManagementApp.tsx +++ b/server/sonar-web/src/main/js/apps/projectsManagement/ProjectManagementApp.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { LargeCenteredLayout, PageContentFontWrapper } from 'design-system'; import { debounce, uniq } from 'lodash'; import * as React from 'react'; @@ -31,7 +32,6 @@ import { import { getValue } from '../../api/settings'; import withCurrentUserContext from '../../app/components/current-user/withCurrentUserContext'; import ListFooter from '../../components/controls/ListFooter'; -import Suggestions from '../../components/embed-docs-modal/Suggestions'; import { toShortISO8601String } from '../../helpers/dates'; import { translate } from '../../helpers/l10n'; import { hasGlobalPermission } from '../../helpers/users'; @@ -205,7 +205,6 @@ class ProjectManagementApp extends React.PureComponent<Props, State> { return ( <LargeCenteredLayout as="main" id="projects-management-page"> <PageContentFontWrapper className="sw-body-sm sw-my-8"> - <Suggestions suggestions="projects_management" /> <Helmet defer={false} title={translate('projects_management')} /> <Header diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/App.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/App.tsx index 020f38b8e95..cb7f7bf5492 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/App.tsx +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/App.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { withTheme } from '@emotion/react'; import styled from '@emotion/styled'; import { @@ -35,6 +36,7 @@ import { Helmet } from 'react-helmet-async'; import { useNavigate, useParams } from 'react-router-dom'; import Suggestions from '../../../components/embed-docs-modal/Suggestions'; import '../../../components/search-navigator.css'; +import { DocLink } from '../../../helpers/doc-links'; import { translate, translateWithParameters } from '../../../helpers/l10n'; import { getQualityGateUrl } from '../../../helpers/urls'; import { useQualityGatesQuery } from '../../../queries/quality-gates'; @@ -84,7 +86,7 @@ export default function App() { )} /> <div className="sw-grid sw-gap-x-12 sw-gap-y-6 sw-grid-cols-12 sw-w-full"> - <Suggestions suggestions="quality_gates" /> + <Suggestions suggestion={DocLink.CaYC} /> <StyledContentWrapper className="sw-col-span-3 sw-px-4 sw-py-6 sw-border-y-0" diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/CaYCConditionsSimplificationGuide.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/CaYCConditionsSimplificationGuide.tsx index 0ea24e58a14..5ccb7aad5a5 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/CaYCConditionsSimplificationGuide.tsx +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/CaYCConditionsSimplificationGuide.tsx @@ -17,11 +17,13 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { SpotlightTour, SpotlightTourStep } from 'design-system'; import React from 'react'; import { dismissNotice } from '../../../api/users'; import { CurrentUserContext } from '../../../app/components/current-user/CurrentUserContext'; import DocumentationLink from '../../../components/common/DocumentationLink'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; import { QualityGate } from '../../../types/types'; import { NoticeType } from '../../../types/users'; @@ -65,7 +67,7 @@ export default function CaYCConditionsSimplificationGuide({ qualityGate }: Props <p className="sw-mb-4"> {translate('quality_gates.cayc.condition_simplification_tour.page_3.content1')} </p> - <DocumentationLink to="/user-guide/issues/#resolutions"> + <DocumentationLink to={DocLink.IssueResolutions}> {translate('quality_gates.cayc.condition_simplification_tour.page_3.content2')} </DocumentationLink> </> diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/CaycCompliantBanner.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/CaycCompliantBanner.tsx index c86aa008d71..7ef1a49af76 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/CaycCompliantBanner.tsx +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/CaycCompliantBanner.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { CardWithPrimaryBackground, CheckIcon, @@ -26,6 +27,7 @@ import { import React from 'react'; import { FormattedMessage } from 'react-intl'; import DocumentationLink from '../../../components/common/DocumentationLink'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; import { OPTIMIZED_CAYC_CONDITIONS } from '../utils'; import QGRecommendedIcon from './QGRecommendedIcon'; @@ -45,7 +47,7 @@ export default function CaycCompliantBanner() { id="quality_gates.cayc.banner.description1" values={{ cayc_link: ( - <DocumentationLink to="/user-guide/clean-as-you-code/"> + <DocumentationLink to={DocLink.CaYC}> {translate('quality_gates.cayc')} </DocumentationLink> ), diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/CaycFixOptimizeBanner.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/CaycFixOptimizeBanner.tsx index 49fc4f43c04..68532aff7e5 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/CaycFixOptimizeBanner.tsx +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/CaycFixOptimizeBanner.tsx @@ -17,11 +17,13 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { ButtonPrimary, CardWithPrimaryBackground, SubHeadingHighlight } from 'design-system'; import React from 'react'; import { FormattedMessage } from 'react-intl'; import DocumentationLink from '../../../components/common/DocumentationLink'; import ModalButton from '../../../components/controls/ModalButton'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; interface Props { @@ -48,7 +50,7 @@ export default function CaycNonCompliantBanner({ renderCaycModal, isOptimizing } } values={{ cayc_link: ( - <DocumentationLink to="/user-guide/clean-as-you-code/"> + <DocumentationLink to={DocLink.CaYC}> {translate('quality_gates.cayc')} </DocumentationLink> ), diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/ConditionReviewAndUpdateModal.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/ConditionReviewAndUpdateModal.tsx index 40f4988504a..cc5e8ba28f1 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/ConditionReviewAndUpdateModal.tsx +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/ConditionReviewAndUpdateModal.tsx @@ -17,10 +17,12 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { ButtonPrimary, Link, Modal, SubHeading, Title } from 'design-system'; import { sortBy } from 'lodash'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; +import { DocLink } from '../../../helpers/doc-links'; import { useDocUrl } from '../../../helpers/docs'; import { translate, translateWithParameters } from '../../../helpers/l10n'; import { useFixQualityGateMutation } from '../../../queries/quality-gates'; @@ -54,7 +56,7 @@ export default function CaycReviewUpdateConditionsModal(props: Readonly<Props>) (condition) => metrics[condition.metric]?.name, ); - const getDocUrl = useDocUrl(); + const docUrl = useDocUrl(DocLink.CaYC); const updateCaycQualityGate = React.useCallback(async () => { await fixQualityGate({ weakConditions, missingConditions }); @@ -71,11 +73,7 @@ export default function CaycReviewUpdateConditionsModal(props: Readonly<Props>) : 'quality_gates.cayc.review_update_modal.description1' } values={{ - cayc_link: ( - <Link to={getDocUrl('/user-guide/clean-as-you-code/')}> - {translate('quality_gates.cayc')} - </Link> - ), + cayc_link: <Link to={docUrl}>{translate('quality_gates.cayc')}</Link>, }} /> </SubHeading> diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.tsx index 2db45668ea6..dfc691dc57a 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.tsx +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { ButtonSecondary, FlagMessage, @@ -39,6 +40,7 @@ import { useAvailableFeatures } from '../../../app/components/available-features import { useMetrics } from '../../../app/components/metrics/withMetricsContext'; import DocumentationLink from '../../../components/common/DocumentationLink'; import ModalButton, { ModalProps } from '../../../components/controls/ModalButton'; +import { DocLink } from '../../../helpers/doc-links'; import { useDocUrl } from '../../../helpers/docs'; import { getLocalizedMetricName, translate } from '../../../helpers/l10n'; import { Feature } from '../../../types/features'; @@ -119,7 +121,7 @@ export default function Conditions({ qualityGate, isFetching }: Readonly<Props>) [metrics, qualityGate], ); - const getDocUrl = useDocUrl(); + const docUrl = useDocUrl(DocLink.CaYC); const isCompliantCustomQualityGate = qualityGate.caycStatus !== CaycStatus.NonCompliant && !qualityGate.isBuiltIn; const isOptimizing = isCompliantCustomQualityGate && !isQualityGateOptimized(qualityGate); @@ -157,7 +159,7 @@ export default function Conditions({ qualityGate, isFetching }: Readonly<Props>) id="quality_gates.is_built_in.cayc.description" values={{ link: ( - <DocumentationLink to="/user-guide/clean-as-you-code/"> + <DocumentationLink to={DocLink.CaYC}> {translate('clean_as_you_code')} </DocumentationLink> ), @@ -186,7 +188,7 @@ export default function Conditions({ qualityGate, isFetching }: Readonly<Props>) content={translate('quality_gates.conditions.help')} links={[ { - href: '/user-guide/clean-as-you-code/', + href: DocLink.CaYC, label: translate('quality_gates.conditions.help.link'), }, ]} @@ -311,11 +313,7 @@ export default function Conditions({ qualityGate, isFetching }: Readonly<Props>) id="quality_gates.cayc_unfollow.description" defaultMessage={translate('quality_gates.cayc_unfollow.description')} values={{ - cayc_link: ( - <Link to={getDocUrl('/user-guide/clean-as-you-code/')}> - {translate('quality_gates.cayc')} - </Link> - ), + cayc_link: <Link to={docUrl}>{translate('quality_gates.cayc')}</Link>, }} /> </SubHeading> diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/ListHeader.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/ListHeader.tsx index 54458ab50d5..dd33243d83b 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/ListHeader.tsx +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/ListHeader.tsx @@ -17,10 +17,12 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { ButtonPrimary, HelperHintIcon, Title } from 'design-system'; import * as React from 'react'; import DocHelpTooltip from '~sonar-aligned/components/controls/DocHelpTooltip'; import ModalButton, { ModalProps } from '../../../components/controls/ModalButton'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; import CreateQualityGateForm from './CreateQualityGateForm'; @@ -59,7 +61,7 @@ export default function ListHeader({ canCreate }: Readonly<Props>) { content={translate('quality_gates.help')} links={[ { - href: '/user-guide/quality-gates/', + href: DocLink.QualityGates, label: translate('learn_more'), }, ]} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/QualityProfilesApp.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/QualityProfilesApp.tsx index 35937d20772..76231c544cc 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/QualityProfilesApp.tsx +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/QualityProfilesApp.tsx @@ -24,6 +24,7 @@ import { Outlet } from 'react-router-dom'; import { Actions, getExporters, searchQualityProfiles } from '../../../api/quality-profiles'; import withLanguagesContext from '../../../app/components/languages/withLanguagesContext'; import Suggestions from '../../../components/embed-docs-modal/Suggestions'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; import { Languages } from '../../../types/languages'; import { QualityProfilesContextProps } from '../qualityProfilesContext'; @@ -109,7 +110,7 @@ export class QualityProfilesApp extends React.PureComponent<Props, State> { render() { return ( <LargeCenteredLayout className="sw-my-8"> - <Suggestions suggestions="quality_profiles" /> + <Suggestions suggestion={DocLink.InstanceAdminQualityProfiles} /> <Helmet defer={false} title={translate('quality_profiles.page')} /> {this.renderChild()} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.tsx index 6edfcedc602..46746dd69a2 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.tsx +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.tsx @@ -22,6 +22,7 @@ import * as React from 'react'; import { useIntl } from 'react-intl'; import { useLocation, useRouter } from '~sonar-aligned/components/hoc/withRouter'; import { Actions } from '../../../api/quality-profiles'; +import { DocLink } from '../../../helpers/doc-links'; import { useDocUrl } from '../../../helpers/docs'; import { translate } from '../../../helpers/l10n'; import { Profile } from '../types'; @@ -41,7 +42,7 @@ export default function PageHeader(props: Readonly<Props>) { const intl = useIntl(); const location = useLocation(); const router = useRouter(); - const docUrl = useDocUrl(); + const docUrl = useDocUrl(DocLink.InstanceAdminQualityProfiles); const [modal, setModal] = React.useState<'' | 'createProfile' | 'restoreProfile'>(''); @@ -63,7 +64,7 @@ export default function PageHeader(props: Readonly<Props>) { <div className="sw-body-sm"> {intl.formatMessage({ id: 'quality_profiles.intro' })} - <Link className="sw-ml-2" to={docUrl('/instance-administration/quality-profiles/')}> + <Link className="sw-ml-2" to={docUrl}> {intl.formatMessage({ id: 'learn_more' })} </Link> </div> diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/SecurityHotspotsAppRenderer.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/SecurityHotspotsAppRenderer.tsx index a8abe63617b..cfb76f48202 100644 --- a/server/sonar-web/src/main/js/apps/security-hotspots/SecurityHotspotsAppRenderer.tsx +++ b/server/sonar-web/src/main/js/apps/security-hotspots/SecurityHotspotsAppRenderer.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { withTheme } from '@emotion/react'; import styled from '@emotion/styled'; import { @@ -35,7 +36,6 @@ import A11ySkipTarget from '~sonar-aligned/components/a11y/A11ySkipTarget'; import { isBranch } from '~sonar-aligned/helpers/branch-like'; import { ComponentQualifier } from '~sonar-aligned/types/component'; import { MetricKey } from '~sonar-aligned/types/metrics'; -import Suggestions from '../../components/embed-docs-modal/Suggestions'; import { translate } from '../../helpers/l10n'; import useFollowScroll from '../../hooks/useFollowScroll'; import { BranchLike } from '../../types/branch-like'; @@ -115,8 +115,6 @@ export default function SecurityHotspotsAppRenderer(props: SecurityHotspotsAppRe return ( <> - <Suggestions suggestions={MetricKey.security_hotspots} /> - <Helmet title={translate('hotspots.page')} /> <A11ySkipTarget anchor="security_hotspots_main" /> diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/EmptyHotspotsPage.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/EmptyHotspotsPage.tsx index 8a989fae4b1..2becfc24363 100644 --- a/server/sonar-web/src/main/js/apps/security-hotspots/components/EmptyHotspotsPage.tsx +++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/EmptyHotspotsPage.tsx @@ -22,6 +22,7 @@ import { Note } from 'design-system'; import * as React from 'react'; import DocumentationLink from '../../../components/common/DocumentationLink'; import { Image } from '../../../components/common/Image'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; export interface EmptyHotspotsPageProps { @@ -59,7 +60,7 @@ export default function EmptyHotspotsPage(props: EmptyHotspotsPageProps) { {translate(`hotspots.${translationRoot}.description`)} </Note> {!(filtered || isStaticListOfHotspots) && ( - <DocumentationLink className="sw-mt-4" to="/user-guide/security-hotspots/"> + <DocumentationLink className="sw-mt-4" to={DocLink.SecurityHotspots}> {translate('hotspots.learn_more')} </DocumentationLink> )} diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotDisabledFilterTooltip.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotDisabledFilterTooltip.tsx index 48accb664f1..a2531185977 100644 --- a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotDisabledFilterTooltip.tsx +++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotDisabledFilterTooltip.tsx @@ -17,11 +17,16 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +import { Link } from 'design-system'; import * as React from 'react'; -import DocumentationLink from '../../../components/common/DocumentationLink'; +import { DocLink } from '../../../helpers/doc-links'; +import { useDocUrl } from '../../../helpers/docs'; import { translate } from '../../../helpers/l10n'; export function HotspotDisabledFilterTooltip() { + const docUrl = useDocUrl(DocLink.InstanceAdminReindexation); + return ( <div className="sw-body-sm sw-w-[190px]"> <p> @@ -30,7 +35,7 @@ export function HotspotDisabledFilterTooltip() { </p> <hr className="sw-mx-0 sw-my-3 sw-p-0 sw-w-full" /> <span className="sw-body-sm-highlight">{translate('indexation.learn_more')}</span> - <DocumentationLink + <Link className="sw-ml-1" onMouseDown={(e) => { // This tooltip content is rendered in the context of a <Dropdown>, and <DropdownToggler> @@ -38,10 +43,10 @@ export function HotspotDisabledFilterTooltip() { // this link. We preventDefault() to avoid this behavior. e.preventDefault(); }} - to="/instance-administration/reindexing/" + to={docUrl} > {translate('indexation.reindexing')} - </DocumentationLink> + </Link> </div> ); } diff --git a/server/sonar-web/src/main/js/apps/settings/components/AnalysisScope.tsx b/server/sonar-web/src/main/js/apps/settings/components/AnalysisScope.tsx index 47fe27f2bf1..f60b393aa82 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/AnalysisScope.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/AnalysisScope.tsx @@ -22,6 +22,7 @@ import styled from '@emotion/styled'; import { LightLabel } from 'design-system'; import * as React from 'react'; import DocumentationLink from '../../../components/common/DocumentationLink'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; import { AdditionalCategoryComponentProps } from './AdditionalCategories'; import CategoryDefinitionsList from './CategoryDefinitionsList'; @@ -46,7 +47,7 @@ export function AnalysisScope(props: AdditionalCategoryComponentProps) { <LightLabel>{translate('settings.analysis_scope.wildcards.single_char')}</LightLabel> <div className="sw-col-span-2"> - <DocumentationLink to="/project-administration/analysis-scope/"> + <DocumentationLink to={DocLink.AnalysisScope}> {translate('learn_more')} </DocumentationLink> </div> diff --git a/server/sonar-web/src/main/js/apps/settings/components/NewCodeDefinition.tsx b/server/sonar-web/src/main/js/apps/settings/components/NewCodeDefinition.tsx index 77f8b8ef96e..a574b35d2e3 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/NewCodeDefinition.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/NewCodeDefinition.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { Spinner } from '@sonarsource/echoes-react'; import classNames from 'classnames'; import { ButtonPrimary, ButtonSecondary } from 'design-system'; @@ -26,6 +27,7 @@ import DocumentationLink from '../../../components/common/DocumentationLink'; import NewCodeDefinitionDaysOption from '../../../components/new-code-definition/NewCodeDefinitionDaysOption'; import NewCodeDefinitionPreviousVersionOption from '../../../components/new-code-definition/NewCodeDefinitionPreviousVersionOption'; import { NewCodeDefinitionLevels } from '../../../components/new-code-definition/utils'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; import { getNumberOfDaysDefaultValue, @@ -102,7 +104,7 @@ export default function NewCodeDefinition() { id="settings.new_code_period.description3" values={{ link: ( - <DocumentationLink to="/project-administration/clean-as-you-code-settings/defining-new-code/"> + <DocumentationLink to={DocLink.NewCodeDefinition}> {translate('settings.new_code_period.description3.link')} </DocumentationLink> ), diff --git a/server/sonar-web/src/main/js/apps/settings/components/SettingsAppRenderer.tsx b/server/sonar-web/src/main/js/apps/settings/components/SettingsAppRenderer.tsx index b93fae4b819..361dd3306a8 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/SettingsAppRenderer.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/SettingsAppRenderer.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import styled from '@emotion/styled'; import { LargeCenteredLayout, PageContentFontWrapper, themeBorder } from 'design-system'; import { uniqBy } from 'lodash'; @@ -24,7 +25,6 @@ import * as React from 'react'; import { Helmet } from 'react-helmet-async'; import { withRouter } from '~sonar-aligned/components/hoc/withRouter'; import { Location } from '~sonar-aligned/types/router'; -import Suggestions from '../../../components/embed-docs-modal/Suggestions'; import { translate } from '../../../helpers/l10n'; import { ExtendedSettingDefinition } from '../../../types/settings'; import { Component } from '../../../types/types'; @@ -70,7 +70,6 @@ function SettingsAppRenderer(props: Readonly<SettingsAppRendererProps>) { return ( <LargeCenteredLayout id="settings-page"> - <Suggestions suggestions="settings" /> <Helmet defer={false} title={translate('settings.page')} /> <PageContentFontWrapper className="sw-my-8"> diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionBox.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionBox.tsx index 9b54225ab2f..f9aa868d3d0 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionBox.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionBox.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { BasicSeparator, ButtonSecondary, @@ -32,7 +33,8 @@ import { FormattedMessage } from 'react-intl'; import HelpTooltip from '~sonar-aligned/components/controls/HelpTooltip'; import DocumentationLink from '../../../../components/common/DocumentationLink'; import Tooltip from '../../../../components/controls/Tooltip'; -import { ALM_DOCUMENTATION_PATHS, IMPORT_COMPATIBLE_ALMS } from '../../../../helpers/constants'; +import { IMPORT_COMPATIBLE_ALMS } from '../../../../helpers/constants'; +import { DocLink } from '../../../../helpers/doc-links'; import { getEdition, getEditionUrl } from '../../../../helpers/editions'; import { translate, translateWithParameters } from '../../../../helpers/l10n'; import { @@ -232,7 +234,7 @@ export default function AlmBindingDefinitionBox(props: AlmBindingDefinitionBoxPr )} values={{ link: ( - <DocumentationLink to={ALM_DOCUMENTATION_PATHS[AlmKeys.GitHub]}> + <DocumentationLink to={DocLink.AlmGitHubIntegration}> {translate('learn_more')} </DocumentationLink> ), diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionFormField.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionFormField.tsx index 6d714459fd6..0d0429fd133 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionFormField.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionFormField.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { ButtonSecondary, FlagMessage, @@ -27,6 +28,7 @@ import { } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; +import { DocLink } from '../../../../helpers/doc-links'; import { useDocUrl } from '../../../../helpers/docs'; import { translate, translateWithParameters } from '../../../../helpers/l10n'; import { AlmBindingDefinitionBase } from '../../../../types/alm-settings'; @@ -65,7 +67,7 @@ export function AlmBindingDefinitionFormField<B extends AlmBindingDefinitionBase } = props; const [showField, setShowField] = React.useState(!overwriteOnly); - const toStatic = useDocUrl('/instance-administration/security/#settings-encryption'); + const toStatic = useDocUrl(DocLink.InstanceAdminEncryption); return ( <FormField diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AzureForm.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AzureForm.tsx index d80d0f8d5d8..6d4c3ae9c4f 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AzureForm.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AzureForm.tsx @@ -17,13 +17,14 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { Link } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; -import { ALM_DOCUMENTATION_PATHS } from '../../../../helpers/constants'; +import { DocLink } from '../../../../helpers/doc-links'; import { useDocUrl } from '../../../../helpers/docs'; import { translate } from '../../../../helpers/l10n'; -import { AlmKeys, AzureBindingDefinition } from '../../../../types/alm-settings'; +import { AzureBindingDefinition } from '../../../../types/alm-settings'; import { AlmBindingDefinitionFormField } from './AlmBindingDefinitionFormField'; export interface AzureFormProps { @@ -33,7 +34,7 @@ export interface AzureFormProps { export default function AzureForm(props: AzureFormProps) { const { formData, onFieldChange } = props; - const toStatic = useDocUrl(ALM_DOCUMENTATION_PATHS[AlmKeys.Azure]); + const toStatic = useDocUrl(DocLink.AlmAzureIntegration); return ( <> <AlmBindingDefinitionFormField diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/BitbucketCloudForm.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/BitbucketCloudForm.tsx index aa1e5d75ea5..b24bedb3748 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/BitbucketCloudForm.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/BitbucketCloudForm.tsx @@ -17,13 +17,14 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { FlagMessage, Link } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; -import { ALM_DOCUMENTATION_PATHS } from '../../../../helpers/constants'; -import { useDocUrl } from '../../../../helpers/docs'; +import DocumentationLink from '../../../../components/common/DocumentationLink'; +import { DocLink } from '../../../../helpers/doc-links'; import { translate } from '../../../../helpers/l10n'; -import { AlmKeys, BitbucketCloudBindingDefinition } from '../../../../types/alm-settings'; +import { BitbucketCloudBindingDefinition } from '../../../../types/alm-settings'; import { BITBUCKET_CLOUD_WORKSPACE_ID_FORMAT } from '../../constants'; import { AlmBindingDefinitionFormField } from './AlmBindingDefinitionFormField'; @@ -38,8 +39,6 @@ export default function BitbucketCloudForm(props: BitbucketCloudFormProps) { formData.workspace && !BITBUCKET_CLOUD_WORKSPACE_ID_FORMAT.test(formData.workspace), ); - const toStatic = useDocUrl(ALM_DOCUMENTATION_PATHS[AlmKeys.BitbucketCloud]); - return ( <> <FlagMessage variant="info" className="sw-mb-8"> @@ -57,7 +56,11 @@ export default function BitbucketCloudForm(props: BitbucketCloudFormProps) { </Link> ), permission: <strong>Pull Requests: Read</strong>, - doc_link: <Link to={toStatic}>{translate('learn_more')}</Link>, + doc_link: ( + <DocumentationLink to={DocLink.AlmBitBucketCloudIntegration}> + {translate('learn_more')} + </DocumentationLink> + ), }} /> </div> diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/BitbucketServerForm.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/BitbucketServerForm.tsx index f5c7587793f..06d1221029b 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/BitbucketServerForm.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/BitbucketServerForm.tsx @@ -17,13 +17,14 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { Link } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; -import { ALM_DOCUMENTATION_PATHS } from '../../../../helpers/constants'; +import { DocLink } from '../../../../helpers/doc-links'; import { useDocUrl } from '../../../../helpers/docs'; import { translate } from '../../../../helpers/l10n'; -import { AlmKeys, BitbucketServerBindingDefinition } from '../../../../types/alm-settings'; +import { BitbucketServerBindingDefinition } from '../../../../types/alm-settings'; import { AlmBindingDefinitionFormField } from './AlmBindingDefinitionFormField'; export interface BitbucketServerFormProps { @@ -33,7 +34,7 @@ export interface BitbucketServerFormProps { export default function BitbucketServerForm(props: BitbucketServerFormProps) { const { formData } = props; - const toStatic = useDocUrl(ALM_DOCUMENTATION_PATHS[AlmKeys.BitbucketServer]); + const toStatic = useDocUrl(DocLink.AlmBitBucketServerIntegration); return ( <> <AlmBindingDefinitionFormField diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/GithubForm.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/GithubForm.tsx index e48a6271841..bced3853838 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/GithubForm.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/GithubForm.tsx @@ -17,13 +17,14 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { FlagMessage, Link } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; -import { ALM_DOCUMENTATION_PATHS } from '../../../../helpers/constants'; +import { DocLink } from '../../../../helpers/doc-links'; import { useDocUrl } from '../../../../helpers/docs'; import { translate } from '../../../../helpers/l10n'; -import { AlmKeys, GithubBindingDefinition } from '../../../../types/alm-settings'; +import { GithubBindingDefinition } from '../../../../types/alm-settings'; import { AlmBindingDefinitionFormField } from './AlmBindingDefinitionFormField'; export interface GithubFormProps { @@ -33,7 +34,7 @@ export interface GithubFormProps { export default function GithubForm(props: GithubFormProps) { const { formData, onFieldChange } = props; - const toStatic = useDocUrl(ALM_DOCUMENTATION_PATHS[AlmKeys.GitHub]); + const toStatic = useDocUrl(DocLink.AlmGitHubIntegration); return ( <> <FlagMessage variant="info" className="sw-mb-8"> diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/GitlabForm.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/GitlabForm.tsx index 0cec69dece7..89793ac4df6 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/GitlabForm.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/GitlabForm.tsx @@ -17,13 +17,14 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { Link } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; -import { ALM_DOCUMENTATION_PATHS } from '../../../../helpers/constants'; +import { DocLink } from '../../../../helpers/doc-links'; import { useDocUrl } from '../../../../helpers/docs'; import { translate } from '../../../../helpers/l10n'; -import { AlmKeys, GitlabBindingDefinition } from '../../../../types/alm-settings'; +import { GitlabBindingDefinition } from '../../../../types/alm-settings'; import { AlmBindingDefinitionFormField } from './AlmBindingDefinitionFormField'; export interface GitlabFormProps { @@ -33,7 +34,7 @@ export interface GitlabFormProps { export default function GitlabForm(props: GitlabFormProps) { const { formData, onFieldChange } = props; - const toStatic = useDocUrl(ALM_DOCUMENTATION_PATHS[AlmKeys.GitLab]); + const toStatic = useDocUrl(DocLink.AlmGitLabIntegration); return ( <> <AlmBindingDefinitionFormField diff --git a/server/sonar-web/src/main/js/apps/settings/components/authentication/Authentication.tsx b/server/sonar-web/src/main/js/apps/settings/components/authentication/Authentication.tsx index 9ca2271d965..a227ebae99e 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/authentication/Authentication.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/authentication/Authentication.tsx @@ -48,13 +48,6 @@ export type AuthenticationTabs = | AlmKeys.GitLab | AlmKeys.BitbucketServer; -export const DOCUMENTATION_LINK_SUFFIXES = { - [SAML]: 'saml/overview', - [AlmKeys.GitHub]: 'github', - [AlmKeys.GitLab]: 'gitlab', - [AlmKeys.BitbucketServer]: 'bitbucket-cloud', -}; - function renderDevOpsIcon(key: string) { return <Image alt={key} className="sw-mr-2" height={16} src={`/images/alm/${key}.svg`} />; } diff --git a/server/sonar-web/src/main/js/apps/settings/components/authentication/AutoProvisionningConsent.tsx b/server/sonar-web/src/main/js/apps/settings/components/authentication/AutoProvisionningConsent.tsx index f41125fd67f..6eb8740005e 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/authentication/AutoProvisionningConsent.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/authentication/AutoProvisionningConsent.tsx @@ -17,11 +17,13 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { ButtonSecondary, Modal } from 'design-system'; import { noop } from 'lodash'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; import DocumentationLink from '../../../../components/common/DocumentationLink'; +import { DocLink } from '../../../../helpers/doc-links'; import { translate } from '../../../../helpers/l10n'; import { useToggleGithubProvisioningMutation } from '../../../../queries/identity-provider/github'; import { useGetValueQuery, useResetSettingsMutation } from '../../../../queries/settings'; @@ -67,7 +69,7 @@ export default function AutoProvisioningConsent() { tagName="p" values={{ documentation: ( - <DocumentationLink to="/instance-administration/authentication/github/"> + <DocumentationLink to={DocLink.AlmGitHubAuth}> <FormattedMessage id="documentation" /> </DocumentationLink> ), diff --git a/server/sonar-web/src/main/js/apps/settings/components/authentication/BitbucketAuthenticationTab.tsx b/server/sonar-web/src/main/js/apps/settings/components/authentication/BitbucketAuthenticationTab.tsx index 6716e498fc3..138817182b1 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/authentication/BitbucketAuthenticationTab.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/authentication/BitbucketAuthenticationTab.tsx @@ -17,10 +17,12 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { FlagMessage } from 'design-system'; import React from 'react'; import { FormattedMessage } from 'react-intl'; import DocumentationLink from '../../../../components/common/DocumentationLink'; +import { DocLink } from '../../../../helpers/doc-links'; import { translate } from '../../../../helpers/l10n'; import { useGetValueQuery } from '../../../../queries/settings'; import { AlmKeys } from '../../../../types/alm-settings'; @@ -53,7 +55,7 @@ export default function BitbucketAuthenticationTab(props: Readonly<Props>) { id="settings.authentication.gitlab.configuration.insecure" values={{ documentation: ( - <DocumentationLink to="/instance-administration/authentication/bitbucket-cloud/#setting-your-authentication-settings-in-sonarqube"> + <DocumentationLink to={DocLink.AlmBitBucketCloudSettings}> {translate('documentation')} </DocumentationLink> ), @@ -69,7 +71,7 @@ export default function BitbucketAuthenticationTab(props: Readonly<Props>) { defaultMessage={translate('settings.authentication.help')} values={{ link: ( - <DocumentationLink to="/instance-administration/authentication/bitbucket-cloud/"> + <DocumentationLink to={DocLink.AlmBitBucketCloudAuth}> {translate('settings.authentication.help.link')} </DocumentationLink> ), diff --git a/server/sonar-web/src/main/js/apps/settings/components/authentication/ConfigurationForm.tsx b/server/sonar-web/src/main/js/apps/settings/components/authentication/ConfigurationForm.tsx index 6655ddaedb2..45e72b06693 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/authentication/ConfigurationForm.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/authentication/ConfigurationForm.tsx @@ -24,12 +24,13 @@ import { keyBy } from 'lodash'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; import DocumentationLink from '../../../../components/common/DocumentationLink'; +import { AlmAuthDocLinkKeys } from '../../../../helpers/doc-links'; import { translate } from '../../../../helpers/l10n'; import { useSaveValuesMutation } from '../../../../queries/settings'; import { AlmKeys } from '../../../../types/alm-settings'; import { ProvisioningType } from '../../../../types/provisioning'; import { Dict, Provider } from '../../../../types/types'; -import { AuthenticationTabs, DOCUMENTATION_LINK_SUFFIXES } from './Authentication'; +import { AuthenticationTabs } from './Authentication'; import AuthenticationFormField from './AuthenticationFormField'; import ConfirmProvisioningModal from './ConfirmProvisioningModal'; import { SettingValue } from './hook/useConfiguration'; @@ -125,9 +126,7 @@ export default function ConfigurationForm(props: Readonly<Props>) { id={`settings.authentication.${helpMessage}`} values={{ link: ( - <DocumentationLink - to={`/instance-administration/authentication/${DOCUMENTATION_LINK_SUFFIXES[tab]}/`} - > + <DocumentationLink to={AlmAuthDocLinkKeys[tab]}> {translate('settings.authentication.help.link')} </DocumentationLink> ), diff --git a/server/sonar-web/src/main/js/apps/settings/components/authentication/GitLabAuthenticationTab.tsx b/server/sonar-web/src/main/js/apps/settings/components/authentication/GitLabAuthenticationTab.tsx index 829b9007e7e..3ec7e17a066 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/authentication/GitLabAuthenticationTab.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/authentication/GitLabAuthenticationTab.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { Spinner } from 'design-system'; import { isEmpty, omitBy } from 'lodash'; import React, { FormEvent, useContext } from 'react'; @@ -24,6 +25,7 @@ import { FormattedMessage } from 'react-intl'; import GitLabSynchronisationWarning from '../../../../app/components/GitLabSynchronisationWarning'; import { AvailableFeaturesContext } from '../../../../app/components/available-features/AvailableFeaturesContext'; import DocumentationLink from '../../../../components/common/DocumentationLink'; +import { DocLink } from '../../../../helpers/doc-links'; import { translate, translateWithParameters } from '../../../../helpers/l10n'; import { useIdentityProviderQuery } from '../../../../queries/identity-provider/common'; import { @@ -32,12 +34,10 @@ import { useSyncWithGitLabNow, useUpdateGitLabConfigurationMutation, } from '../../../../queries/identity-provider/gitlab'; -import { AlmKeys } from '../../../../types/alm-settings'; import { Feature } from '../../../../types/features'; import { GitLabConfigurationUpdateBody, ProvisioningType } from '../../../../types/provisioning'; import { DefinitionV2, SettingType } from '../../../../types/settings'; import { Provider } from '../../../../types/types'; -import { DOCUMENTATION_LINK_SUFFIXES } from './Authentication'; import AuthenticationFormField from './AuthenticationFormField'; import ConfigurationDetails from './ConfigurationDetails'; import ConfirmProvisioningModal from './ConfirmProvisioningModal'; @@ -273,11 +273,7 @@ export default function GitLabAuthenticationTab() { id="settings.authentication.gitlab.provisioning_at_login.description" values={{ documentation: ( - <DocumentationLink - to={`/instance-administration/authentication/${ - DOCUMENTATION_LINK_SUFFIXES[AlmKeys.GitLab] - }/#choosing-the-provisioning-method`} - > + <DocumentationLink to={DocLink.AlmGitLabAuthProvisioningMethod}> {translate(`learn_more`)} </DocumentationLink> ), @@ -323,7 +319,7 @@ export default function GitLabAuthenticationTab() { )} values={{ documentation: ( - <DocumentationLink to="/instance-administration/authentication/gitlab"> + <DocumentationLink to={DocLink.AlmGitLabAuth}> {translate('documentation')} </DocumentationLink> ), @@ -335,11 +331,7 @@ export default function GitLabAuthenticationTab() { id="settings.authentication.gitlab.form.provisioning_with_gitlab.description" values={{ documentation: ( - <DocumentationLink - to={`/instance-administration/authentication/${ - DOCUMENTATION_LINK_SUFFIXES[AlmKeys.GitLab] - }/#choosing-the-provisioning-method`} - > + <DocumentationLink to={DocLink.AlmGitLabAuthProvisioningMethod}> {translate(`learn_more`)} </DocumentationLink> ), diff --git a/server/sonar-web/src/main/js/apps/settings/components/authentication/GitLabConfigurationForm.tsx b/server/sonar-web/src/main/js/apps/settings/components/authentication/GitLabConfigurationForm.tsx index 41845a5b896..b14f2999d8c 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/authentication/GitLabConfigurationForm.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/authentication/GitLabConfigurationForm.tsx @@ -23,6 +23,7 @@ import { keyBy } from 'lodash'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; import DocumentationLink from '../../../../components/common/DocumentationLink'; +import { DocLink } from '../../../../helpers/doc-links'; import { translate } from '../../../../helpers/l10n'; import { useCreateGitLabConfigurationMutation, @@ -30,7 +31,6 @@ import { } from '../../../../queries/identity-provider/gitlab'; import { GitLabConfigurationCreateBody, GitlabConfiguration } from '../../../../types/provisioning'; import { DefinitionV2, SettingType } from '../../../../types/settings'; -import { DOCUMENTATION_LINK_SUFFIXES } from './Authentication'; import AuthenticationFormField from './AuthenticationFormField'; interface Props { @@ -149,9 +149,7 @@ export default function GitLabConfigurationForm(props: Readonly<Props>) { id="settings.authentication.help" values={{ link: ( - <DocumentationLink - to={`/instance-administration/authentication/${DOCUMENTATION_LINK_SUFFIXES.gitlab}/`} - > + <DocumentationLink to={DocLink.AlmGitLabAuth}> {translate('settings.authentication.help.link')} </DocumentationLink> ), diff --git a/server/sonar-web/src/main/js/apps/settings/components/authentication/GithubAuthenticationTab.tsx b/server/sonar-web/src/main/js/apps/settings/components/authentication/GithubAuthenticationTab.tsx index e9da422d772..99b3caffb8d 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/authentication/GithubAuthenticationTab.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/authentication/GithubAuthenticationTab.tsx @@ -17,11 +17,13 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { ButtonSecondary, FlagMessage, Highlight, Note, Spinner } from 'design-system'; import React, { FormEvent, useState } from 'react'; import { FormattedMessage } from 'react-intl'; import GitHubSynchronisationWarning from '../../../../app/components/GitHubSynchronisationWarning'; import DocumentationLink from '../../../../components/common/DocumentationLink'; +import { DocLink } from '../../../../helpers/doc-links'; import { translate, translateWithParameters } from '../../../../helpers/l10n'; import { useIdentityProviderQuery } from '../../../../queries/identity-provider/common'; import { @@ -32,7 +34,7 @@ import { AlmKeys } from '../../../../types/alm-settings'; import { ProvisioningType } from '../../../../types/provisioning'; import { ExtendedSettingDefinition } from '../../../../types/settings'; import { Provider } from '../../../../types/types'; -import { AuthenticationTabs, DOCUMENTATION_LINK_SUFFIXES } from './Authentication'; +import { AuthenticationTabs } from './Authentication'; import AuthenticationFormField from './AuthenticationFormField'; import AutoProvisioningConsent from './AutoProvisionningConsent'; import ConfigurationDetails from './ConfigurationDetails'; @@ -155,7 +157,7 @@ export default function GithubAuthenticationTab(props: GithubAuthenticationProps defaultMessage={translate('settings.authentication.github.form.legacy_configured')} values={{ documentation: ( - <DocumentationLink to="/instance-administration/authentication/github"> + <DocumentationLink to={DocLink.AlmGitHubAuth}> {translate('settings.authentication.github.form.legacy_configured.link')} </DocumentationLink> ), @@ -198,11 +200,7 @@ export default function GithubAuthenticationTab(props: GithubAuthenticationProps id="settings.authentication.github.form.provisioning_at_login.description" values={{ documentation: ( - <DocumentationLink - to={`/instance-administration/authentication/${ - DOCUMENTATION_LINK_SUFFIXES[AlmKeys.GitHub] - }/`} - > + <DocumentationLink to={DocLink.AlmGitHubAuth}> {translate('learn_more')} </DocumentationLink> ), @@ -239,7 +237,7 @@ export default function GithubAuthenticationTab(props: GithubAuthenticationProps )} values={{ documentation: ( - <DocumentationLink to="/instance-administration/authentication/github"> + <DocumentationLink to={DocLink.AlmGitHubAuth}> {translate('documentation')} </DocumentationLink> ), @@ -251,11 +249,7 @@ export default function GithubAuthenticationTab(props: GithubAuthenticationProps id="settings.authentication.github.form.provisioning_with_github.description" values={{ documentation: ( - <DocumentationLink - to={`/instance-administration/authentication/${ - DOCUMENTATION_LINK_SUFFIXES[AlmKeys.GitHub] - }/`} - > + <DocumentationLink to={DocLink.AlmGitHubAuth}> {translate('learn_more')} </DocumentationLink> ), diff --git a/server/sonar-web/src/main/js/apps/settings/components/authentication/SamlAuthenticationTab.tsx b/server/sonar-web/src/main/js/apps/settings/components/authentication/SamlAuthenticationTab.tsx index cb0c2b6c9eb..42550d1ab9d 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/authentication/SamlAuthenticationTab.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/authentication/SamlAuthenticationTab.tsx @@ -17,11 +17,13 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { ButtonSecondary, Spinner } from 'design-system'; import React, { FormEvent } from 'react'; import { FormattedMessage } from 'react-intl'; import DocumentationLink from '../../../../components/common/DocumentationLink'; import ConfirmModal from '../../../../components/controls/ConfirmModal'; +import { DocLink } from '../../../../helpers/doc-links'; import { translate } from '../../../../helpers/l10n'; import { useIdentityProviderQuery } from '../../../../queries/identity-provider/common'; import { useToggleScimMutation } from '../../../../queries/identity-provider/scim'; @@ -167,7 +169,7 @@ export default function SamlAuthenticationTab(props: SamlAuthenticationProps) { id="settings.authentication.saml.form.provisioning.disabled" values={{ documentation: ( - <DocumentationLink to="/instance-administration/authentication/saml/scim/overview"> + <DocumentationLink to={DocLink.AlmSamlScimAuth}> {translate('documentation')} </DocumentationLink> ), @@ -192,7 +194,7 @@ export default function SamlAuthenticationTab(props: SamlAuthenticationProps) { )} values={{ documentation: ( - <DocumentationLink to="/instance-administration/authentication/saml/scim/overview"> + <DocumentationLink to={DocLink.AlmSamlScimAuth}> {translate('documentation')} </DocumentationLink> ), diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/AlmSpecificForm.tsx b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/AlmSpecificForm.tsx index 0e3fa7f9235..80b4f8caeb5 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/AlmSpecificForm.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/AlmSpecificForm.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { FlagMessage, InputField, Note, RequiredIcon, SubHeading, Switch } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; @@ -24,6 +25,7 @@ import withAvailableFeatures, { WithAvailableFeaturesProps, } from '../../../../app/components/available-features/withAvailableFeatures'; import DocumentationLink from '../../../../components/common/DocumentationLink'; +import { DocLink } from '../../../../helpers/doc-links'; import { translate } from '../../../../helpers/l10n'; import { convertGithubApiUrlToLink, stripTrailingSlash } from '../../../../helpers/urls'; import { @@ -293,7 +295,7 @@ export function AlmSpecificForm(props: AlmSpecificFormProps) { help: true, helpParams: { doc_link: ( - <DocumentationLink to="/project-administration/monorepos/"> + <DocumentationLink to={DocLink.Monorepos}> {translate('learn_more')} </DocumentationLink> ), diff --git a/server/sonar-web/src/main/js/apps/settings/encryption/EncryptionForm.tsx b/server/sonar-web/src/main/js/apps/settings/encryption/EncryptionForm.tsx index f1c82578164..4617a15b86b 100644 --- a/server/sonar-web/src/main/js/apps/settings/encryption/EncryptionForm.tsx +++ b/server/sonar-web/src/main/js/apps/settings/encryption/EncryptionForm.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { ButtonPrimary, ButtonSecondary, @@ -30,6 +31,7 @@ import { useCallback, useState } from 'react'; import { FormattedMessage } from 'react-intl'; import { encryptValue } from '../../../api/settings'; import DocumentationLink from '../../../components/common/DocumentationLink'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; interface Props { @@ -122,7 +124,7 @@ export default function EncryptionForm({ generateSecretKey }: Readonly<Props>) { id="encryption.form_note" values={{ moreInformationLink: ( - <DocumentationLink to="/instance-administration/security/"> + <DocumentationLink to={DocLink.InstanceAdminSecurity}> {translate('more_information')} </DocumentationLink> ), diff --git a/server/sonar-web/src/main/js/apps/settings/encryption/GenerateSecretKeyForm.tsx b/server/sonar-web/src/main/js/apps/settings/encryption/GenerateSecretKeyForm.tsx index b120142bb20..6d64b7ad4ad 100644 --- a/server/sonar-web/src/main/js/apps/settings/encryption/GenerateSecretKeyForm.tsx +++ b/server/sonar-web/src/main/js/apps/settings/encryption/GenerateSecretKeyForm.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { ButtonPrimary, ClipboardIconButton, @@ -30,6 +31,7 @@ import * as React from 'react'; import { useCallback, useState } from 'react'; import { FormattedMessage } from 'react-intl'; import DocumentationLink from '../../../components/common/DocumentationLink'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; interface Props { @@ -107,7 +109,7 @@ export default function GenerateSecretKeyForm({ secretKey, generateSecretKey }: id="encryption.secret_key_description" values={{ moreInformationLink: ( - <DocumentationLink to="/instance-administration/security/"> + <DocumentationLink to={DocLink.InstanceAdminSecurity}> {translate('more_information')} </DocumentationLink> ), diff --git a/server/sonar-web/src/main/js/apps/system/components/SystemApp.tsx b/server/sonar-web/src/main/js/apps/system/components/SystemApp.tsx index 664c36e0cb5..0e901c5fc50 100644 --- a/server/sonar-web/src/main/js/apps/system/components/SystemApp.tsx +++ b/server/sonar-web/src/main/js/apps/system/components/SystemApp.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { LargeCenteredLayout, PageContentFontWrapper } from 'design-system'; import * as React from 'react'; import { Helmet } from 'react-helmet-async'; @@ -24,7 +25,6 @@ import { withRouter } from '~sonar-aligned/components/hoc/withRouter'; import { Location, Router } from '~sonar-aligned/types/router'; import { getSystemInfo } from '../../../api/system'; import UpdateNotification from '../../../app/components/update-notification/UpdateNotification'; -import Suggestions from '../../../components/embed-docs-modal/Suggestions'; import { translate } from '../../../helpers/l10n'; import { SysInfoCluster, SysInfoStandalone } from '../../../types/types'; import '../styles.css'; @@ -126,7 +126,6 @@ class SystemApp extends React.PureComponent<Props, State> { const { loading, sysInfoData } = this.state; return ( <LargeCenteredLayout as="main"> - <Suggestions suggestions="system_info" /> <Helmet defer={false} title={translate('system_info.page')} /> <PageContentFontWrapper className="sw-body-sm sw-pb-8"> <div> diff --git a/server/sonar-web/src/main/js/apps/users/Header.tsx b/server/sonar-web/src/main/js/apps/users/Header.tsx index 99693e98db4..1b4c87b33f5 100644 --- a/server/sonar-web/src/main/js/apps/users/Header.tsx +++ b/server/sonar-web/src/main/js/apps/users/Header.tsx @@ -17,9 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { ButtonPrimary, FlagMessage, Link, Title } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; +import { DocLink } from '../../helpers/doc-links'; import { useDocUrl } from '../../helpers/docs'; import { translate } from '../../helpers/l10n'; import UserForm from './components/UserForm'; @@ -29,7 +31,7 @@ interface Props { } export default function Header(props: Props) { - const getDocUrl = useDocUrl(); + const docUrl = useDocUrl(DocLink.AuthOverview); const [openUserForm, setOpenUserForm] = React.useState(false); const { manageProvider } = props; @@ -57,11 +59,7 @@ export default function Header(props: Props) { id="users.page.managed_description" values={{ provider: manageProvider, - link: ( - <Link to={getDocUrl('/instance-administration/authentication/overview/')}> - {translate('documentation')} - </Link> - ), + link: <Link to={docUrl}>{translate('documentation')}</Link>, }} /> </span> diff --git a/server/sonar-web/src/main/js/apps/users/UsersApp.tsx b/server/sonar-web/src/main/js/apps/users/UsersApp.tsx index c40d1ce5865..713bcef1726 100644 --- a/server/sonar-web/src/main/js/apps/users/UsersApp.tsx +++ b/server/sonar-web/src/main/js/apps/users/UsersApp.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { subDays, subSeconds } from 'date-fns'; import { HelperHintIcon, @@ -35,7 +36,6 @@ import GitHubSynchronisationWarning from '../../app/components/GitHubSynchronisa import GitLabSynchronisationWarning from '../../app/components/GitLabSynchronisationWarning'; import ListFooter from '../../components/controls/ListFooter'; import { ManagedFilter } from '../../components/controls/ManagedFilter'; -import Suggestions from '../../components/embed-docs-modal/Suggestions'; import { now, toISO8601WithOffsetString } from '../../helpers/dates'; import { translate } from '../../helpers/l10n'; import { LabelValueSelectOption } from '../../helpers/search'; @@ -98,7 +98,6 @@ export default function UsersApp() { return ( <LargeCenteredLayout as="main" id="users-page"> <PageContentFontWrapper className="sw-my-8 sw-body-sm"> - <Suggestions suggestions="users" /> <Helmet defer={false} title={translate('users.page')} /> <Header manageProvider={manageProvider?.provider} /> {manageProvider?.provider === Provider.Github && <GitHubSynchronisationWarning short />} diff --git a/server/sonar-web/src/main/js/apps/users/components/DeactivateForm.tsx b/server/sonar-web/src/main/js/apps/users/components/DeactivateForm.tsx index c681a0dc0ac..e1d1c68417c 100644 --- a/server/sonar-web/src/main/js/apps/users/components/DeactivateForm.tsx +++ b/server/sonar-web/src/main/js/apps/users/components/DeactivateForm.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { Checkbox, DangerButtonPrimary, @@ -27,6 +28,7 @@ import { } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; +import { DocLink } from '../../../helpers/doc-links'; import { useDocUrl } from '../../../helpers/docs'; import { translate, translateWithParameters } from '../../../helpers/l10n'; import { useDeactivateUserMutation } from '../../../queries/users'; @@ -56,7 +58,7 @@ export default function DeactivateForm(props: Props) { }; const header = translate('users.deactivate_user'); - const docUrl = useDocUrl('/instance-administration/authentication/overview/'); + const docUrl = useDocUrl(DocLink.AuthOverview); return ( <Modal diff --git a/server/sonar-web/src/main/js/apps/web-api/components/WebApiApp.tsx b/server/sonar-web/src/main/js/apps/web-api/components/WebApiApp.tsx index f61afe7235a..6ee0e211f05 100644 --- a/server/sonar-web/src/main/js/apps/web-api/components/WebApiApp.tsx +++ b/server/sonar-web/src/main/js/apps/web-api/components/WebApiApp.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import styled from '@emotion/styled'; import { LAYOUT_FOOTER_HEIGHT, @@ -33,7 +34,6 @@ import A11ySkipTarget from '~sonar-aligned/components/a11y/A11ySkipTarget'; import { withRouter } from '~sonar-aligned/components/hoc/withRouter'; import { Location, Router } from '~sonar-aligned/types/router'; import { fetchWebApi } from '../../../api/web-api'; -import Suggestions from '../../../components/embed-docs-modal/Suggestions'; import { translate } from '../../../helpers/l10n'; import { WebApi } from '../../../types/types'; import '../styles/web-api.css'; @@ -168,7 +168,6 @@ export class WebApiApp extends React.PureComponent<Props, State> { return ( <LargeCenteredLayout> <PageContentFontWrapper className="sw-body-sm sw-w-full sw-flex"> - <Suggestions suggestions="api_documentation" /> <Helmet defer={false} title={translate('api_documentation.page')} /> <div className="sw-w-full sw-flex"> <NavContainer diff --git a/server/sonar-web/src/main/js/apps/webhooks/components/App.tsx b/server/sonar-web/src/main/js/apps/webhooks/components/App.tsx index 50e723ebf89..30065446856 100644 --- a/server/sonar-web/src/main/js/apps/webhooks/components/App.tsx +++ b/server/sonar-web/src/main/js/apps/webhooks/components/App.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { LargeCenteredLayout, PageContentFontWrapper, Spinner } from 'design-system'; import * as React from 'react'; import { useCallback, useEffect, useState } from 'react'; @@ -24,6 +25,7 @@ import { Helmet } from 'react-helmet-async'; import { createWebhook, deleteWebhook, searchWebhooks, updateWebhook } from '../../../api/webhooks'; import withComponentContext from '../../../app/components/componentContext/withComponentContext'; import Suggestions from '../../../components/embed-docs-modal/Suggestions'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; import { Component } from '../../../types/types'; import { WebhookResponse } from '../../../types/webhook'; @@ -100,7 +102,7 @@ export function App({ component }: AppProps) { return ( <LargeCenteredLayout id="project-webhooks"> <PageContentFontWrapper className="sw-my-8 sw-body-sm"> - <Suggestions suggestions="webhooks" /> + <Suggestions suggestion={DocLink.Webhooks} /> <Helmet defer={false} title={translate('webhooks.page')} /> <PageHeader> <PageActions loading={loading} onCreate={handleCreate} webhooksCount={webhooks.length} /> diff --git a/server/sonar-web/src/main/js/apps/webhooks/components/PageHeader.tsx b/server/sonar-web/src/main/js/apps/webhooks/components/PageHeader.tsx index 672f76b8b86..61db225664d 100644 --- a/server/sonar-web/src/main/js/apps/webhooks/components/PageHeader.tsx +++ b/server/sonar-web/src/main/js/apps/webhooks/components/PageHeader.tsx @@ -17,9 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { Link, Title } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; +import { DocLink } from '../../../helpers/doc-links'; import { useDocUrl } from '../../../helpers/docs'; import { translate } from '../../../helpers/l10n'; @@ -28,7 +30,7 @@ interface Props { } export default function PageHeader({ children }: Readonly<Props>) { - const toUrl = useDocUrl('/project-administration/webhooks/'); + const toUrl = useDocUrl(DocLink.Webhooks); return ( <header className="sw-mb-2 sw-flex sw-items-center sw-justify-between"> diff --git a/server/sonar-web/src/main/js/components/common/DocumentationLink.tsx b/server/sonar-web/src/main/js/components/common/DocumentationLink.tsx index cf5ba0114a2..b6cdc6a26f8 100644 --- a/server/sonar-web/src/main/js/components/common/DocumentationLink.tsx +++ b/server/sonar-web/src/main/js/components/common/DocumentationLink.tsx @@ -17,13 +17,16 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { Link, LinkProps } from 'design-system'; + +import { Link, LinkProps } from '@sonarsource/echoes-react'; import * as React from 'react'; +import { DocLink } from '../../helpers/doc-links'; import { useDocUrl } from '../../helpers/docs'; -type Props = Omit<LinkProps, 'to'> & { to: string; innerRef?: React.Ref<HTMLAnchorElement> }; +type Props = Omit<LinkProps, 'to'> & { to: DocLink; innerRef?: React.Ref<HTMLAnchorElement> }; export default function DocumentationLink({ to, innerRef, ...props }: Props) { const toStatic = useDocUrl(to); - return <Link ref={innerRef} to={toStatic} target="_blank" {...props} />; + + return <Link ref={innerRef} to={toStatic} {...props} />; } diff --git a/server/sonar-web/src/main/js/components/embed-docs-modal/DocItemLink.tsx b/server/sonar-web/src/main/js/components/embed-docs-modal/DocItemLink.tsx index 0d8e07e4412..0ca48ab3ac7 100644 --- a/server/sonar-web/src/main/js/components/embed-docs-modal/DocItemLink.tsx +++ b/server/sonar-web/src/main/js/components/embed-docs-modal/DocItemLink.tsx @@ -17,14 +17,16 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { ItemLink, OpenNewTabIcon } from 'design-system'; import * as React from 'react'; +import { DocLink } from '../../helpers/doc-links'; import { useDocUrl } from '../../helpers/docs'; interface Props { - to: string; - innerRef?: React.Ref<HTMLAnchorElement>; children: React.ReactNode; + innerRef?: React.Ref<HTMLAnchorElement>; + to: DocLink; } export function DocItemLink({ to, innerRef, children }: Props) { diff --git a/server/sonar-web/src/main/js/components/embed-docs-modal/EmbedDocsPopup.tsx b/server/sonar-web/src/main/js/components/embed-docs-modal/EmbedDocsPopup.tsx index 8f613d698e5..15276793770 100644 --- a/server/sonar-web/src/main/js/components/embed-docs-modal/EmbedDocsPopup.tsx +++ b/server/sonar-web/src/main/js/components/embed-docs-modal/EmbedDocsPopup.tsx @@ -20,6 +20,7 @@ import { ItemDivider, ItemHeader, ItemLink, OpenNewTabIcon } from 'design-system'; import * as React from 'react'; +import { DocLink } from '../../helpers/doc-links'; import { translate } from '../../helpers/l10n'; import { SuggestionLink } from '../../types/types'; import { Image } from '../common/Image'; @@ -87,7 +88,7 @@ export function EmbedDocsPopup() { {suggestions.length !== 0 && ( <Suggestions firstItemRef={firstItemRef} suggestions={suggestions} /> )} - <DocItemLink innerRef={suggestions.length === 0 ? firstItemRef : undefined} to="/"> + <DocItemLink innerRef={suggestions.length === 0 ? firstItemRef : undefined} to={DocLink.Root}> {translate('docs.documentation')} </DocItemLink> <ItemLink to="/web_api">{translate('api_documentation.page')}</ItemLink> diff --git a/server/sonar-web/src/main/js/components/embed-docs-modal/EmbedDocsSuggestions.json b/server/sonar-web/src/main/js/components/embed-docs-modal/EmbedDocsSuggestions.json deleted file mode 100644 index 8901c50403c..00000000000 --- a/server/sonar-web/src/main/js/components/embed-docs-modal/EmbedDocsSuggestions.json +++ /dev/null @@ -1,118 +0,0 @@ -{ - "account": [], - "api_documentation": [], - "background_tasks": [ - { - "link": "/analyzing-source-code/background-tasks/", - "text": "About Background Tasks" - } - ], - "code": [], - "coding_rules": [ - { - "link": "/instance-administration/quality-profiles/", - "text": "Quality Profiles" - } - ], - "component_measures": [ - { - "link": "/user-guide/clean-as-you-code/", - "text": "Clean as You Code" - }, - { - "link": "/user-guide/metric-definitions/", - "text": "Metric Definitions" - } - ], - "global_permissions": [], - "issues": [], - "marketplace": [], - "overview": [ - { - "link": "/analyzing-source-code/pull-request-analysis", - "text": "Enable Pull Request Decoration" - }, - { - "link": "/analyzing-source-code/ci-integration/overview/", - "text": "Set up CI analysis" - }, - { - "link": "/user-guide/clean-as-you-code/", - "text": "Clean as You Code" - }, - { - "link": "/user-guide/sonarlint-connected-mode/", - "text": "SonarLint Connected Mode" - } - ], - "permission_templates": [], - "profiles": [ - { - "link": "/instance-administration/quality-profiles/", - "text": "Quality Profiles" - } - ], - "project_activity": [], - "project_baseline": [ - { - "link": "/project-administration/clean-as-you-code-settings/defining-new-code/", - "text": "Defining New Code" - } - ], - "project_quality_gate": [ - { - "link": "/user-guide/clean-as-you-code/", - "text": "Clean as You Code" - } - ], - "project_quality_profiles": [ - { - "link": "/instance-administration/quality-profiles/", - "text": "About Quality Profiles" - } - ], - "projects_management": [], - "projects": [], - "pull_requests": [ - { - "link": "/user-guide/clean-as-you-code/", - "text": "Clean as You Code" - }, - { - "link": "/analyzing-source-code/pull-request-analysis", - "text": "Analyzing Pull Requests" - }, - { - "link": "/user-guide/sonarlint-connected-mode/", - "text": "SonarLint connected mode" - } - ], - "quality_gates": [ - { - "link": "/user-guide/clean-as-you-code/", - "text": "Clean as You Code" - } - ], - "quality_profiles": [ - { - "link": "/instance-administration/quality-profiles/", - "text": "Quality Profiles" - } - ], - "security_reports": [ - { - "link": "/user-guide/security-reports/", - "text": "About Security Reports" - } - ], - "settings": [], - "system_info": [], - "user_groups": [], - "users": [], - "webhooks": [ - { - "link": "/project-administration/webhooks/", - "text": "About Webhooks" - } - ] -} diff --git a/server/sonar-web/src/main/js/components/embed-docs-modal/Suggestions.tsx b/server/sonar-web/src/main/js/components/embed-docs-modal/Suggestions.tsx index 1fdad708224..7a02556e3b9 100644 --- a/server/sonar-web/src/main/js/components/embed-docs-modal/Suggestions.tsx +++ b/server/sonar-web/src/main/js/components/embed-docs-modal/Suggestions.tsx @@ -17,21 +17,31 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import * as React from 'react'; -import { SuggestionsContext } from './SuggestionsContext'; +import { DocSection, DocSectionKey, DocTitleKey } from '../../helpers/doc-links'; +import { isDefined } from '../../helpers/types'; +import { SuggestionsContext, SuggestionsContextShape } from './SuggestionsContext'; -interface Props { - suggestions: string; -} +type Props = + | { + suggestion: DocTitleKey; + suggestionGroup?: never; + } + | { + suggestion?: never; + suggestionGroup: DocSectionKey; + }; -export default function Suggestions({ suggestions }: Props) { +export default function Suggestions({ suggestion, suggestionGroup }: Readonly<Props>) { return ( <SuggestionsContext.Consumer> {({ addSuggestions, removeSuggestions }) => ( <SuggestionsInner addSuggestions={addSuggestions} removeSuggestions={removeSuggestions} - suggestions={suggestions} + suggestion={suggestion} + suggestionGroup={suggestionGroup} /> )} </SuggestionsContext.Consumer> @@ -39,25 +49,31 @@ export default function Suggestions({ suggestions }: Props) { } interface SuggestionsInnerProps { - addSuggestions: (key: string) => void; - removeSuggestions: (key: string) => void; - suggestions: string; + addSuggestions: SuggestionsContextShape['addSuggestions']; + removeSuggestions: SuggestionsContextShape['removeSuggestions']; + suggestion: Props['suggestion']; + suggestionGroup: Props['suggestionGroup']; } class SuggestionsInner extends React.PureComponent<SuggestionsInnerProps> { componentDidMount() { - this.props.addSuggestions(this.props.suggestions); + this.props.addSuggestions(this.getSuggestionListFromProps()); } - componentDidUpdate(prevProps: Props) { - if (prevProps.suggestions !== this.props.suggestions) { - this.props.removeSuggestions(this.props.suggestions); - this.props.addSuggestions(prevProps.suggestions); - } + componentWillUnmount() { + this.props.removeSuggestions(this.getSuggestionListFromProps()); } - componentWillUnmount() { - this.props.removeSuggestions(this.props.suggestions); + getSuggestionListFromProps() { + const { suggestion, suggestionGroup } = this.props; + + const suggestions: DocTitleKey[] = isDefined(suggestion) ? [suggestion] : []; + + if (suggestionGroup) { + suggestions.push(...DocSection[suggestionGroup]); + } + + return suggestions; } render() { diff --git a/server/sonar-web/src/main/js/components/embed-docs-modal/SuggestionsContext.ts b/server/sonar-web/src/main/js/components/embed-docs-modal/SuggestionsContext.ts index 7dc73b62d7c..d71d4cef5c9 100644 --- a/server/sonar-web/src/main/js/components/embed-docs-modal/SuggestionsContext.ts +++ b/server/sonar-web/src/main/js/components/embed-docs-modal/SuggestionsContext.ts @@ -17,12 +17,14 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { createContext } from 'react'; +import { DocTitleKey } from '../../helpers/doc-links'; import { SuggestionLink } from '../../types/types'; -interface SuggestionsContextShape { - addSuggestions: (key: string) => void; - removeSuggestions: (key: string) => void; +export interface SuggestionsContextShape { + addSuggestions: (keys: DocTitleKey[]) => void; + removeSuggestions: (keys: DocTitleKey[]) => void; suggestions: SuggestionLink[]; } diff --git a/server/sonar-web/src/main/js/components/embed-docs-modal/SuggestionsProvider.tsx b/server/sonar-web/src/main/js/components/embed-docs-modal/SuggestionsProvider.tsx index b09f8aefa9d..c0d680938c7 100644 --- a/server/sonar-web/src/main/js/components/embed-docs-modal/SuggestionsProvider.tsx +++ b/server/sonar-web/src/main/js/components/embed-docs-modal/SuggestionsProvider.tsx @@ -17,40 +17,45 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import * as React from 'react'; -import { Dict, SuggestionLink } from '../../types/types'; -import suggestionsJson from './EmbedDocsSuggestions.json'; +import { DocTitle, DocTitleKey } from '../../helpers/doc-links'; +import { SuggestionLink } from '../../types/types'; import { SuggestionsContext } from './SuggestionsContext'; -type SuggestionsJson = Dict<SuggestionLink[]>; - interface State { suggestions: SuggestionLink[]; } export default class SuggestionsProvider extends React.Component<React.PropsWithChildren, State> { - keys: string[] = []; + keys: Array<DocTitleKey> = []; state: State = { suggestions: [] }; fetchSuggestions = () => { - const jsonList = suggestionsJson as SuggestionsJson; let suggestions: SuggestionLink[] = []; + this.keys.forEach((key) => { - if (jsonList[key]) { - suggestions = [...jsonList[key], ...suggestions]; - } + suggestions = [{ link: key, text: DocTitle[key] }, ...suggestions]; }); this.setState({ suggestions }); }; - addSuggestions = (newKey: string) => { - this.keys = [...this.keys, newKey]; + addSuggestions = (newKeys: DocTitleKey[]) => { + newKeys.forEach((newKey) => { + if (!this.keys.includes(newKey)) { + this.keys = [...this.keys, newKey]; + } + }); + this.fetchSuggestions(); }; - removeSuggestions = (oldKey: string) => { - this.keys = this.keys.filter((key) => key !== oldKey); + removeSuggestions = (oldKeys: DocTitleKey[]) => { + oldKeys.forEach((oldKey) => { + this.keys = this.keys.filter((key) => key !== oldKey); + }); + this.fetchSuggestions(); }; diff --git a/server/sonar-web/src/main/js/components/embed-docs-modal/__tests__/EmbedDocsPopup-test.tsx b/server/sonar-web/src/main/js/components/embed-docs-modal/__tests__/EmbedDocsPopup-test.tsx index 6b7c48e73a0..ef09bf7b4b0 100644 --- a/server/sonar-web/src/main/js/components/embed-docs-modal/__tests__/EmbedDocsPopup-test.tsx +++ b/server/sonar-web/src/main/js/components/embed-docs-modal/__tests__/EmbedDocsPopup-test.tsx @@ -17,9 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import * as React from 'react'; +import { DocLink, DocTitleKey } from '../../../helpers/doc-links'; import { renderComponent } from '../../../helpers/testReactTestingUtils'; import EmbedDocsPopupHelper from '../EmbedDocsPopupHelper'; import Suggestions from '../Suggestions'; @@ -60,10 +62,10 @@ it('should be able to render with suggestions and remove them', async () => { function renderEmbedDocsPopup() { function Test() { - const [suggestions, setSuggestions] = React.useState<string[]>(['account']); + const [suggestions, setSuggestions] = React.useState<DocTitleKey[]>([]); const addSuggestion = () => { - setSuggestions([...suggestions, 'background_tasks']); + setSuggestions([...suggestions, DocLink.BackgroundTasks]); }; return ( @@ -81,7 +83,7 @@ function renderEmbedDocsPopup() { </button> <EmbedDocsPopupHelper /> {suggestions.map((suggestion) => ( - <Suggestions key={suggestion} suggestions={suggestion} /> + <Suggestions key={suggestion} suggestion={suggestion} /> ))} </SuggestionsProvider> ); diff --git a/server/sonar-web/src/main/js/components/issue/components/IssueSeverity.tsx b/server/sonar-web/src/main/js/components/issue/components/IssueSeverity.tsx index 9dff3ce2bdc..8fd429cd424 100644 --- a/server/sonar-web/src/main/js/components/issue/components/IssueSeverity.tsx +++ b/server/sonar-web/src/main/js/components/issue/components/IssueSeverity.tsx @@ -21,6 +21,7 @@ import { IconProps, TextSubdued } from 'design-system'; import * as React from 'react'; import DocHelpTooltip from '~sonar-aligned/components/controls/DocHelpTooltip'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; import { IssueSeverity as IssueSeverityType } from '../../../types/issues'; import { Issue } from '../../../types/types'; @@ -37,7 +38,7 @@ export default function IssueSeverity({ issue, ...iconProps }: Readonly<Props>) content={<DeprecatedFieldTooltip field="severity" />} links={[ { - href: '/user-guide/issues', + href: DocLink.Issues, label: translate('learn_more'), }, ]} diff --git a/server/sonar-web/src/main/js/components/issue/components/IssueType.tsx b/server/sonar-web/src/main/js/components/issue/components/IssueType.tsx index 892d6c37025..4932bb33cc1 100644 --- a/server/sonar-web/src/main/js/components/issue/components/IssueType.tsx +++ b/server/sonar-web/src/main/js/components/issue/components/IssueType.tsx @@ -21,6 +21,7 @@ import { IconProps, TextSubdued } from 'design-system'; import * as React from 'react'; import DocHelpTooltip from '~sonar-aligned/components/controls/DocHelpTooltip'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; import { Issue } from '../../../types/types'; import IssueTypeIcon from '../../icon-mappers/IssueTypeIcon'; @@ -36,7 +37,7 @@ export default function IssueType({ issue, ...iconProps }: Readonly<Props>) { content={<DeprecatedFieldTooltip field="type" />} links={[ { - href: '/user-guide/issues', + href: DocLink.Issues, label: translate('learn_more'), }, ]} diff --git a/server/sonar-web/src/main/js/components/new-code-definition/BranchNCDAutoUpdateMessage.tsx b/server/sonar-web/src/main/js/components/new-code-definition/BranchNCDAutoUpdateMessage.tsx index 65eafc89f26..f77f9224414 100644 --- a/server/sonar-web/src/main/js/components/new-code-definition/BranchNCDAutoUpdateMessage.tsx +++ b/server/sonar-web/src/main/js/components/new-code-definition/BranchNCDAutoUpdateMessage.tsx @@ -17,10 +17,12 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { DismissableFlagMessage, Link } from 'design-system'; import React, { useCallback, useEffect, useState } from 'react'; import { FormattedMessage, useIntl } from 'react-intl'; import { MessageTypes, checkMessageDismissed, setMessageDismissed } from '../../api/messages'; +import { DocLink } from '../../helpers/doc-links'; import { useDocUrl } from '../../helpers/docs'; import { Component } from '../../types/types'; import { PreviouslyNonCompliantBranchNCD } from './utils'; @@ -33,9 +35,7 @@ interface NCDAutoUpdateMessageProps { export default function NCDAutoUpdateMessage(props: NCDAutoUpdateMessageProps) { const { component, previouslyNonCompliantBranchNCDs } = props; const intl = useIntl(); - const toUrl = useDocUrl( - '/project-administration/clean-as-you-code-settings/defining-new-code/#new-code-definition-options', - ); + const toUrl = useDocUrl(DocLink.NewCodeDefinitionOptions); const [dismissed, setDismissed] = useState(true); diff --git a/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionAnalysisWarning.tsx b/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionAnalysisWarning.tsx index 95fe198617c..855eccd3754 100644 --- a/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionAnalysisWarning.tsx +++ b/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionAnalysisWarning.tsx @@ -17,15 +17,15 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { FlagMessage, Link } from 'design-system'; import * as React from 'react'; +import { DocLink } from '../../helpers/doc-links'; import { useDocUrl } from '../../helpers/docs'; import { translate } from '../../helpers/l10n'; export default function NewCodeDefinitionAnalysisWarning() { - const toStatic = useDocUrl( - '/project-administration/clean-as-you-code-settings/defining-new-code/', - ); + const toStatic = useDocUrl(DocLink.NewCodeDefinition); return ( <FlagMessage variant="warning" className="sw-mb-4 sw-max-w-[800px]"> <div> diff --git a/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionDaysOption.tsx b/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionDaysOption.tsx index b47d9bb154e..923953e56e9 100644 --- a/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionDaysOption.tsx +++ b/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionDaysOption.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { DismissableFlagMessage, FlagErrorIcon, @@ -29,6 +30,7 @@ import * as React from 'react'; import { useCallback, useEffect, useMemo, useState } from 'react'; import { FormattedMessage } from 'react-intl'; import { MessageTypes, checkMessageDismissed, setMessageDismissed } from '../../api/messages'; +import { DocLink } from '../../helpers/doc-links'; import { translate, translateWithParameters } from '../../helpers/l10n'; import { NUMBER_OF_DAYS_MAX_VALUE, @@ -165,7 +167,7 @@ export default function NewCodeDefinitionDaysOption(props: Props) { days: currentDaysValue, date: isDefined(updatedAt) && new Date(updatedAt).toLocaleDateString(), link: ( - <DocumentationLink to="/project-administration/clean-as-you-code-settings/defining-new-code/#new-code-definition-options"> + <DocumentationLink to={DocLink.NewCodeDefinitionOptions}> {translate('learn_more')} </DocumentationLink> ), diff --git a/server/sonar-web/src/main/js/components/shared/AnalysisMissingInfoMessage.tsx b/server/sonar-web/src/main/js/components/shared/AnalysisMissingInfoMessage.tsx index dbbd066e0e0..c1d0c4ea32e 100644 --- a/server/sonar-web/src/main/js/components/shared/AnalysisMissingInfoMessage.tsx +++ b/server/sonar-web/src/main/js/components/shared/AnalysisMissingInfoMessage.tsx @@ -17,9 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { FlagMessage } from 'design-system'; import * as React from 'react'; import { FormattedMessage, useIntl } from 'react-intl'; +import { DocLink } from '../../helpers/doc-links'; import DocumentationLink from '../common/DocumentationLink'; interface AnalysisMissingInfoMessageProps { @@ -47,10 +49,7 @@ export default function AnalysisMissingInfoMessage({ values={{ qualifier, learn_more: ( - <DocumentationLink - className="sw-whitespace-nowrap" - to="/user-guide/clean-code/code-analysis/" - > + <DocumentationLink className="sw-whitespace-nowrap" to={DocLink.CodeAnalysis}> {intl.formatMessage({ id: 'learn_more' })} </DocumentationLink> ), diff --git a/server/sonar-web/src/main/js/components/shared/AppVersionStatus.tsx b/server/sonar-web/src/main/js/components/shared/AppVersionStatus.tsx index 49d8f811c41..a22ec5113d3 100644 --- a/server/sonar-web/src/main/js/components/shared/AppVersionStatus.tsx +++ b/server/sonar-web/src/main/js/components/shared/AppVersionStatus.tsx @@ -22,6 +22,7 @@ import { LinkHighlight, LinkStandalone } from '@sonarsource/echoes-react'; import React, { useMemo } from 'react'; import { FormattedMessage, useIntl } from 'react-intl'; import { useAppState } from '../../app/components/app-state/withAppStateContext'; +import { DocLink } from '../../helpers/doc-links'; import { useDocUrl } from '../../helpers/docs'; import { getInstanceVersionNumber } from '../../helpers/strings'; import { isCurrentVersionEOLActive } from '../../helpers/system'; @@ -39,7 +40,7 @@ export default function AppVersionStatus() { return isCurrentVersionEOLActive(versionEOL); }, [data?.installedVersionActive, versionEOL]); - const docUrl = useDocUrl(); + const docUrl = useDocUrl(DocLink.ActiveVersions); const intl = useIntl(); return intl.formatMessage( @@ -47,11 +48,7 @@ export default function AppVersionStatus() { { version: getInstanceVersionNumber(version), status: ( - <LinkStandalone - className="sw-ml-1" - highlight={LinkHighlight.CurrentColor} - to={docUrl('/setup-and-upgrade/upgrade-the-server/active-versions/')} - > + <LinkStandalone className="sw-ml-1" highlight={LinkHighlight.CurrentColor} to={docUrl}> <FormattedMessage id={`footer.version.status.${isActiveVersion ? 'active' : 'inactive'}`} /> diff --git a/server/sonar-web/src/main/js/components/shared/CleanCodeAttributePill.tsx b/server/sonar-web/src/main/js/components/shared/CleanCodeAttributePill.tsx index 2576467c00f..ca2aed6d416 100644 --- a/server/sonar-web/src/main/js/components/shared/CleanCodeAttributePill.tsx +++ b/server/sonar-web/src/main/js/components/shared/CleanCodeAttributePill.tsx @@ -17,9 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { Pill } from 'design-system'; import React from 'react'; import DocHelpTooltip from '~sonar-aligned/components/controls/DocHelpTooltip'; +import { DocLink } from '../../helpers/doc-links'; import { translate } from '../../helpers/l10n'; import { CleanCodeAttribute, CleanCodeAttributeCategory } from '../../types/clean-code-taxonomy'; @@ -57,7 +59,7 @@ export function CleanCodeAttributePill(props: Readonly<Props>) { } links={[ { - href: '/user-guide/clean-code/introduction', + href: DocLink.CleanCodeIntroduction, label: translate('learn_more'), }, ]} diff --git a/server/sonar-web/src/main/js/components/shared/SoftwareImpactPill.tsx b/server/sonar-web/src/main/js/components/shared/SoftwareImpactPill.tsx index 4cc8a0ba848..c40f58220b2 100644 --- a/server/sonar-web/src/main/js/components/shared/SoftwareImpactPill.tsx +++ b/server/sonar-web/src/main/js/components/shared/SoftwareImpactPill.tsx @@ -17,11 +17,13 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import classNames from 'classnames'; import { Pill } from 'design-system'; import React from 'react'; import { FormattedMessage } from 'react-intl'; import DocHelpTooltip from '~sonar-aligned/components/controls/DocHelpTooltip'; +import { DocLink } from '../../helpers/doc-links'; import { translate } from '../../helpers/l10n'; import { SoftwareImpactSeverity } from '../../types/clean-code-taxonomy'; import SoftwareImpactSeverityIcon from '../icon-mappers/SoftwareImpactSeverityIcon'; @@ -56,7 +58,7 @@ export default function SoftwareImpactPill(props: Props) { } links={[ { - href: '/user-guide/clean-code/introduction', + href: DocLink.CleanCodeIntroduction, label: translate('learn_more'), }, ]} diff --git a/server/sonar-web/src/main/js/components/tutorials/__tests__/TutorialSelection-it.tsx b/server/sonar-web/src/main/js/components/tutorials/__tests__/TutorialSelection-it.tsx index 518ed91fc82..194d057137a 100644 --- a/server/sonar-web/src/main/js/components/tutorials/__tests__/TutorialSelection-it.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/__tests__/TutorialSelection-it.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { UserEvent } from '@testing-library/user-event/dist/types/setup/setup'; @@ -74,7 +75,7 @@ const ui = { 'onboarding.tutorial.with.github_action.create_secret.monorepo_project_level_token_info.link', ), monoRepoYamlDocLink: byRole('link', { - name: 'onboarding.tutorial.with.github_action.monorepo.see_yaml_instructions', + name: /^onboarding\.tutorial\.with\.github_action\.monorepo\.see_yaml_instructions\b/, }), chooseTutorialLink: (mode: TutorialModes) => byRole('link', { name: `onboarding.tutorial.choose_method.${mode}` }), diff --git a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/AlertClassicEditor.tsx b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/AlertClassicEditor.tsx index 516cb52de8a..2124f129f3f 100644 --- a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/AlertClassicEditor.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/AlertClassicEditor.tsx @@ -17,16 +17,16 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { FlagMessage, Link } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; -import { ALM_DOCUMENTATION_PATHS } from '../../../../helpers/constants'; +import { DocLink } from '../../../../helpers/doc-links'; import { useDocUrl } from '../../../../helpers/docs'; import { translate } from '../../../../helpers/l10n'; -import { AlmKeys } from '../../../../types/alm-settings'; export default function AlertClassicEditor() { - const docUrl = useDocUrl(); + const docUrl = useDocUrl(DocLink.AlmAzureIntegration); return ( <FlagMessage variant="info" className="sw-mt-4"> @@ -36,7 +36,7 @@ export default function AlertClassicEditor() { defaultMessage={translate('onboarding.tutorial.with.azure_pipelines.BranchAnalysis.info')} values={{ doc_link: ( - <Link to={docUrl(ALM_DOCUMENTATION_PATHS[AlmKeys.Azure])}> + <Link to={docUrl}> {translate('onboarding.tutorial.with.azure_pipelines.BranchAnalysis.info.doc_link')} </Link> ), diff --git a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/PublishSteps.tsx b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/PublishSteps.tsx index ceb1e9286f1..74a9c5fcaee 100644 --- a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/PublishSteps.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/PublishSteps.tsx @@ -17,16 +17,16 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { BasicSeparator, FlagMessage, Link, NumberedListItem } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; import withAvailableFeatures, { WithAvailableFeaturesProps, } from '../../../../app/components/available-features/withAvailableFeatures'; -import { ALM_DOCUMENTATION_PATHS } from '../../../../helpers/constants'; +import { DocLink } from '../../../../helpers/doc-links'; import { useDocUrl } from '../../../../helpers/docs'; import { translate } from '../../../../helpers/l10n'; -import { AlmKeys } from '../../../../types/alm-settings'; import { Feature } from '../../../../types/features'; import SentenceWithHighlights from '../../components/SentenceWithHighlights'; @@ -35,7 +35,7 @@ export interface PublishStepsProps extends WithAvailableFeaturesProps {} export function PublishSteps(props: PublishStepsProps) { const branchSupportEnabled = props.hasFeature(Feature.BranchSupport); - const docUrl = useDocUrl(); + const docUrl = useDocUrl(DocLink.AlmAzureIntegration); return ( <> @@ -71,7 +71,7 @@ export function PublishSteps(props: PublishStepsProps) { )} values={{ link: ( - <Link to={docUrl(ALM_DOCUMENTATION_PATHS[AlmKeys.Azure])}> + <Link to={docUrl}> {translate( 'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.branch_protection.link', )} diff --git a/server/sonar-web/src/main/js/components/tutorials/components/CompilationInfo.tsx b/server/sonar-web/src/main/js/components/tutorials/components/CompilationInfo.tsx index ad40eaf80b3..3b5e5aeea41 100644 --- a/server/sonar-web/src/main/js/components/tutorials/components/CompilationInfo.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/components/CompilationInfo.tsx @@ -17,9 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { FlagMessage, Link } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; +import { DocLink } from '../../../helpers/doc-links'; import { useDocUrl } from '../../../helpers/docs'; import { translate } from '../../../helpers/l10n'; @@ -39,7 +41,7 @@ export function CompilationInfo({ className = 'sw-my-2' }: CompilationInfoProps) defaultMessage={translate('onboarding.tutorial.cfamilly.compilation_database_info')} values={{ link: ( - <Link to={docUrl('/analyzing-source-code/languages/c-family/')}> + <Link to={docUrl(DocLink.CFamily)}> {translate('onboarding.tutorial.cfamilly.compilation_database_info.link')} </Link> ), @@ -52,7 +54,7 @@ export function CompilationInfo({ className = 'sw-my-2' }: CompilationInfoProps) defaultMessage={translate('onboarding.tutorial.cfamilly.speed_caching')} values={{ link: ( - <Link to={docUrl('/analyzing-source-code/languages/c-family/#analysis-cache')}> + <Link to={docUrl(DocLink.CFamilyAnalysisCache)}> {translate('onboarding.tutorial.cfamilly.speed_caching.link')} </Link> ), diff --git a/server/sonar-web/src/main/js/components/tutorials/components/ProjectTokenScopeInfo.tsx b/server/sonar-web/src/main/js/components/tutorials/components/ProjectTokenScopeInfo.tsx index dd1718918cd..8d3ba1de36c 100644 --- a/server/sonar-web/src/main/js/components/tutorials/components/ProjectTokenScopeInfo.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/components/ProjectTokenScopeInfo.tsx @@ -17,10 +17,12 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import classNames from 'classnames'; import { FlagMessage, Link } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; +import { DocLink } from '../../../helpers/doc-links'; import { useDocUrl } from '../../../helpers/docs'; import { translate } from '../../../helpers/l10n'; @@ -29,7 +31,7 @@ export interface ProjectTokenScopeInfoProps { } export default function ProjectTokenScopeInfo({ className }: ProjectTokenScopeInfoProps) { - const docUrl = useDocUrl('/user-guide/user-account/generating-and-using-tokens/'); + const docUrl = useDocUrl(DocLink.AccountTokens); return ( <FlagMessage variant="info" className={classNames('sw-mt-2', className)}> diff --git a/server/sonar-web/src/main/js/components/tutorials/github-action/commands/MonorepoDocLinkFallback.tsx b/server/sonar-web/src/main/js/components/tutorials/github-action/commands/MonorepoDocLinkFallback.tsx index 0ae8b529271..5a6cd34cf3c 100644 --- a/server/sonar-web/src/main/js/components/tutorials/github-action/commands/MonorepoDocLinkFallback.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/github-action/commands/MonorepoDocLinkFallback.tsx @@ -17,18 +17,17 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { NumberedListItem } from 'design-system'; import * as React from 'react'; +import { DocLink } from '../../../../helpers/doc-links'; import { translate } from '../../../../helpers/l10n'; import DocumentationLink from '../../../common/DocumentationLink'; -const MONOREPO_DOC = - '/devops-platform-integration/github-integration/monorepo/#workflow-file-example'; - export default function MonorepoDocLinkFallback() { return ( <NumberedListItem> - <DocumentationLink className="sw-mt-4" to={MONOREPO_DOC}> + <DocumentationLink className="sw-mt-4" to={DocLink.AlmGitHubMonorepoWorkfileExample}> {translate('onboarding.tutorial.with.github_action.monorepo.see_yaml_instructions')} </DocumentationLink> </NumberedListItem> diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/PreRequisitesStep.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/PreRequisitesStep.tsx index 97d1ec558cb..da01cd504e5 100644 --- a/server/sonar-web/src/main/js/components/tutorials/jenkins/PreRequisitesStep.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/PreRequisitesStep.tsx @@ -17,9 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { FlagMessage, Link, ListItem, TutorialStep, UnorderedList } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; +import { DocLink } from '../../../helpers/doc-links'; import { useDocUrl } from '../../../helpers/docs'; import { translate } from '../../../helpers/l10n'; import { AlmKeys } from '../../../types/alm-settings'; @@ -33,7 +35,7 @@ export interface PreRequisitesStepProps { export default function PreRequisitesStep(props: PreRequisitesStepProps) { const { alm, branchesEnabled } = props; - const docUrl = useDocUrl(); + const docUrl = useDocUrl(DocLink.CIJenkins); return ( <TutorialStep title={translate('onboarding.tutorial.with.jenkins.prereqs.title')}> @@ -66,7 +68,7 @@ export default function PreRequisitesStep(props: PreRequisitesStepProps) { id="onboarding.tutorial.with.jenkins.prereqs.step_by_step_guide" values={{ link: ( - <Link to={docUrl('/analyzing-source-code/ci-integration/jenkins-integration/')}> + <Link to={docUrl}> {translate('onboarding.tutorial.with.jenkins.prereqs.step_by_step_guide.link')} </Link> ), diff --git a/server/sonar-web/src/main/js/components/tutorials/other/DoneNextSteps.tsx b/server/sonar-web/src/main/js/components/tutorials/other/DoneNextSteps.tsx index e5f536ac0ac..f97fca6d662 100644 --- a/server/sonar-web/src/main/js/components/tutorials/other/DoneNextSteps.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/other/DoneNextSteps.tsx @@ -17,10 +17,12 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import styled from '@emotion/styled'; import { animated, config, useSpring } from '@react-spring/web'; import { BasicSeparator, FlagVisual, Link } from 'design-system'; import * as React from 'react'; +import { DocLink } from '../../../helpers/doc-links'; import { useDocUrl } from '../../../helpers/docs'; import { translate } from '../../../helpers/l10n'; import useIntersectionObserver from '../../../hooks/useIntersectionObserver'; @@ -75,7 +77,7 @@ export default function DoneNextSteps({ component }: DoneNextStepsProps) { </span> <ul className="sw-flex sw-flex-col sw-gap-2 sw-mt-2"> <li> - <Link to={docUrl('/analyzing-source-code/branches/branch-analysis/')}> + <Link to={docUrl(DocLink.BranchAnalysis)}> {translate( 'onboarding.analysis.auto_refresh_after_analysis.check_these_links.branches', )} @@ -83,7 +85,7 @@ export default function DoneNextSteps({ component }: DoneNextStepsProps) { </li> <li> - <Link to={docUrl('/analyzing-source-code/pull-request-analysis')}> + <Link to={docUrl(DocLink.PullRequestAnalysis)}> {translate( 'onboarding.analysis.auto_refresh_after_analysis.check_these_links.pr_analysis', )} diff --git a/server/sonar-web/src/main/js/components/tutorials/other/TokenStep.tsx b/server/sonar-web/src/main/js/components/tutorials/other/TokenStep.tsx index 452c30a01e9..417e999a5f1 100644 --- a/server/sonar-web/src/main/js/components/tutorials/other/TokenStep.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/other/TokenStep.tsx @@ -43,6 +43,7 @@ import { FormattedMessage } from 'react-intl'; import { SingleValue } from 'react-select'; import DocHelpTooltip from '~sonar-aligned/components/controls/DocHelpTooltip'; import { generateToken, getTokens, revokeToken } from '../../../api/user-tokens'; +import { DocLink } from '../../../helpers/doc-links'; import { translate } from '../../../helpers/l10n'; import { EXPIRATION_OPTIONS, @@ -218,7 +219,7 @@ export default class TokenStep extends React.PureComponent<Props, State> { content={translate('onboarding.token.name.help')} links={[ { - href: '/user-guide/user-account/generating-and-using-tokens/', + href: DocLink.AccountTokens, label: translate('learn_more'), }, ]} @@ -281,7 +282,7 @@ export default class TokenStep extends React.PureComponent<Props, State> { content={translate('onboarding.token.use_existing_token.help')} links={[ { - href: '/user-guide/user-account/generating-and-using-tokens/', + href: DocLink.AccountTokens, label: translate('learn_more'), }, ]} diff --git a/server/sonar-web/src/main/js/components/tutorials/other/commands/DotNetExecute.tsx b/server/sonar-web/src/main/js/components/tutorials/other/commands/DotNetExecute.tsx index 4266c35def5..ca6335d88d2 100644 --- a/server/sonar-web/src/main/js/components/tutorials/other/commands/DotNetExecute.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/other/commands/DotNetExecute.tsx @@ -17,9 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { CodeSnippet, Link, SubHeading } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; +import { DocLink } from '../../../../helpers/doc-links'; import { useDocUrl } from '../../../../helpers/docs'; import { translate } from '../../../../helpers/l10n'; import { Component } from '../../../../types/types'; @@ -32,7 +34,7 @@ export interface DotNetExecuteProps { } export default function DotNetExecute({ commands, component }: DotNetExecuteProps) { - const docUrl = useDocUrl(); + const docUrl = useDocUrl(DocLink.SonarScannerDotNet); return ( <> @@ -58,11 +60,7 @@ export default function DotNetExecute({ commands, component }: DotNetExecuteProp defaultMessage={translate('onboarding.analysis.docs')} id="onboarding.analysis.docs" values={{ - link: ( - <Link to={docUrl('/analyzing-source-code/scanners/sonarscanner-for-dotnet/')}> - {translate('onboarding.analysis.msbuild.docs_link')} - </Link> - ), + link: <Link to={docUrl}>{translate('onboarding.analysis.msbuild.docs_link')}</Link>, }} /> </p> diff --git a/server/sonar-web/src/main/js/components/tutorials/other/commands/DotNetFramework.tsx b/server/sonar-web/src/main/js/components/tutorials/other/commands/DotNetFramework.tsx index 7c0020a4ecc..fd9ef57f29b 100644 --- a/server/sonar-web/src/main/js/components/tutorials/other/commands/DotNetFramework.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/other/commands/DotNetFramework.tsx @@ -17,9 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { Link, SubHeading } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; +import { DocLink } from '../../../../helpers/doc-links'; import { useDocUrl } from '../../../../helpers/docs'; import { translate } from '../../../../helpers/l10n'; import { InlineSnippet } from '../../components/InlineSnippet'; @@ -29,7 +31,7 @@ import DotNetExecute from './DotNetExecute'; export default function DotNetFramework(props: DotNetProps) { const { baseUrl, component, token } = props; - const docUrl = useDocUrl(); + const docUrl = useDocUrl(DocLink.SonarScannerDotNet); const commands = [ `SonarScanner.MSBuild.exe begin /k:"${component.key}" /d:sonar.host.url="${baseUrl}" /d:sonar.token="${token}"`, @@ -49,11 +51,7 @@ export default function DotNetFramework(props: DotNetProps) { id="onboarding.analysis.msbuild.text" values={{ code: <InlineSnippet snippet="%PATH%" />, - link: ( - <Link to={docUrl('/analyzing-source-code/scanners/sonarscanner-for-dotnet/')}> - {translate('onboarding.analysis.msbuild.docs_link')} - </Link> - ), + link: <Link to={docUrl}>{translate('onboarding.analysis.msbuild.docs_link')}</Link>, }} /> </p> diff --git a/server/sonar-web/src/main/js/components/tutorials/other/commands/DownloadScanner.tsx b/server/sonar-web/src/main/js/components/tutorials/other/commands/DownloadScanner.tsx index 29f2772cd48..b914eaa4960 100644 --- a/server/sonar-web/src/main/js/components/tutorials/other/commands/DownloadScanner.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/other/commands/DownloadScanner.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { ClipboardIconButton, CodeSnippet, @@ -27,6 +28,7 @@ import { } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; +import { DocLink } from '../../../../helpers/doc-links'; import { useDocUrl } from '../../../../helpers/docs'; import { translate } from '../../../../helpers/l10n'; import { InlineSnippet } from '../../components/InlineSnippet'; @@ -41,7 +43,7 @@ export interface DownloadScannerProps { export default function DownloadScanner(props: DownloadScannerProps) { const { os, isLocal, token } = props; - const docUrl = useDocUrl(); + const docUrl = useDocUrl(DocLink.SonarScanner); return ( <div className="sw-mb-4"> @@ -57,9 +59,7 @@ export default function DownloadScanner(props: DownloadScannerProps) { dir: <InlineSnippet snippet="bin" />, env_var: <InlineSnippet snippet={os === OSs.Windows ? '%PATH%' : 'PATH'} />, link: ( - <Link to={docUrl('/analyzing-source-code/scanners/sonarscanner/')}> - {translate('onboarding.analysis.sq_scanner.docs_link')} - </Link> + <Link to={docUrl}>{translate('onboarding.analysis.sq_scanner.docs_link')}</Link> ), }} /> diff --git a/server/sonar-web/src/main/js/components/tutorials/other/commands/ExecBuildWrapper.tsx b/server/sonar-web/src/main/js/components/tutorials/other/commands/ExecBuildWrapper.tsx index 52913bcf66e..1ac8372adf0 100644 --- a/server/sonar-web/src/main/js/components/tutorials/other/commands/ExecBuildWrapper.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/other/commands/ExecBuildWrapper.tsx @@ -17,9 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { CodeSnippet, Link, SubHeading } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; +import { DocLink } from '../../../../helpers/doc-links'; import { useDocUrl } from '../../../../helpers/docs'; import { translate } from '../../../../helpers/l10n'; import { OSs } from '../../types'; @@ -37,7 +39,7 @@ const executables: { [x in OSs]: string } = { export default function ExecBuildWrapper(props: ExecBuildWrapperProps) { const { os } = props; - const docUrl = useDocUrl(); + const docUrl = useDocUrl(DocLink.CFamily); return ( <> @@ -58,9 +60,7 @@ export default function ExecBuildWrapper(props: ExecBuildWrapperProps) { id="onboarding.analysis.build_wrapper.docs" values={{ link: ( - <Link to={docUrl('/analyzing-source-code/languages/c-family/')}> - {translate('onboarding.analysis.build_wrapper.docs_link')} - </Link> + <Link to={docUrl}>{translate('onboarding.analysis.build_wrapper.docs_link')}</Link> ), }} /> diff --git a/server/sonar-web/src/main/js/components/tutorials/other/commands/ExecScanner.tsx b/server/sonar-web/src/main/js/components/tutorials/other/commands/ExecScanner.tsx index 2a99c8fb01d..c208abb4b73 100644 --- a/server/sonar-web/src/main/js/components/tutorials/other/commands/ExecScanner.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/other/commands/ExecScanner.tsx @@ -17,9 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { CodeSnippet, Link, SubHeading } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; +import { DocLink } from '../../../../helpers/doc-links'; import { useDocUrl } from '../../../../helpers/docs'; import { translate } from '../../../../helpers/l10n'; import { Component } from '../../../../types/types'; @@ -40,7 +42,7 @@ export interface ExecScannerProps { export default function ExecScanner(props: ExecScannerProps) { const { baseUrl, os, isLocal, component, token, cfamily } = props; - const docUrl = useDocUrl(); + const docUrl = useDocUrl(DocLink.SonarScanner); const q = quote(os); const command = [ @@ -66,11 +68,7 @@ export default function ExecScanner(props: ExecScannerProps) { defaultMessage={translate('onboarding.analysis.sq_scanner.docs')} id="onboarding.analysis.sq_scanner.docs" values={{ - link: ( - <Link to={docUrl('/analyzing-source-code/scanners/sonarscanner/')}> - {translate('onboarding.analysis.sq_scanner.docs_link')} - </Link> - ), + link: <Link to={docUrl}>{translate('onboarding.analysis.sq_scanner.docs_link')}</Link>, }} /> </p> diff --git a/server/sonar-web/src/main/js/components/tutorials/other/commands/JavaGradle.tsx b/server/sonar-web/src/main/js/components/tutorials/other/commands/JavaGradle.tsx index d707c099e48..858302848b4 100644 --- a/server/sonar-web/src/main/js/components/tutorials/other/commands/JavaGradle.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/other/commands/JavaGradle.tsx @@ -17,10 +17,12 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { CodeSnippet, Link, Note, SubHeading } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; import { GRADLE_SCANNER_VERSION } from '../../../../helpers/constants'; +import { DocLink } from '../../../../helpers/doc-links'; import { useDocUrl } from '../../../../helpers/docs'; import { translate } from '../../../../helpers/l10n'; import { Component } from '../../../../types/types'; @@ -54,7 +56,7 @@ const config = { export default function JavaGradle(props: JavaGradleProps) { const { baseUrl, component, token } = props; - const docUrl = useDocUrl(); + const docUrl = useDocUrl(DocLink.SonarScannerGradle); const command = [ './gradlew sonar', @@ -99,11 +101,7 @@ export default function JavaGradle(props: JavaGradleProps) { defaultMessage={translate('onboarding.analysis.java.gradle.latest_version')} id="onboarding.analysis.java.gradle.latest_version" values={{ - link: ( - <Link to={docUrl('/analyzing-source-code/scanners/sonarscanner-for-gradle/')}> - {translate('here')} - </Link> - ), + link: <Link to={docUrl}>{translate('here')}</Link>, }} /> </Note> @@ -115,11 +113,7 @@ export default function JavaGradle(props: JavaGradleProps) { defaultMessage={translate('onboarding.analysis.docs')} id="onboarding.analysis.docs" values={{ - link: ( - <Link to={docUrl('/analyzing-source-code/scanners/sonarscanner-for-gradle/')}> - {translate('onboarding.analysis.java.gradle.docs_link')} - </Link> - ), + link: <Link to={docUrl}>{translate('onboarding.analysis.java.gradle.docs_link')}</Link>, }} /> </p> diff --git a/server/sonar-web/src/main/js/components/tutorials/other/commands/JavaMaven.tsx b/server/sonar-web/src/main/js/components/tutorials/other/commands/JavaMaven.tsx index b1452e271bb..9fb6c716943 100644 --- a/server/sonar-web/src/main/js/components/tutorials/other/commands/JavaMaven.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/other/commands/JavaMaven.tsx @@ -17,9 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { CodeSnippet, Link, SubHeading } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; +import { DocLink } from '../../../../helpers/doc-links'; import { useDocUrl } from '../../../../helpers/docs'; import { translate } from '../../../../helpers/l10n'; import { Component } from '../../../../types/types'; @@ -42,7 +44,7 @@ export default function JavaMaven(props: JavaMavenProps) { `-Dsonar.token=${token}`, ]; - const docUrl = useDocUrl(); + const docUrl = useDocUrl(DocLink.SonarScannerMaven); return ( <div> @@ -58,11 +60,7 @@ export default function JavaMaven(props: JavaMavenProps) { defaultMessage={translate('onboarding.analysis.docs')} id="onboarding.analysis.docs" values={{ - link: ( - <Link to={docUrl('/analyzing-source-code/scanners/sonarscanner-for-maven/')}> - {translate('onboarding.analysis.java.maven.docs_link')} - </Link> - ), + link: <Link to={docUrl}>{translate('onboarding.analysis.java.maven.docs_link')}</Link>, }} /> </p> diff --git a/server/sonar-web/src/main/js/components/upgrade/SystemUpgradeItem.tsx b/server/sonar-web/src/main/js/components/upgrade/SystemUpgradeItem.tsx index 9a3e5e5118b..8ad9a91bb50 100644 --- a/server/sonar-web/src/main/js/components/upgrade/SystemUpgradeItem.tsx +++ b/server/sonar-web/src/main/js/components/upgrade/SystemUpgradeItem.tsx @@ -17,9 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { DownloadButton, Link, SubHeading } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; +import { DocLink } from '../../helpers/doc-links'; import { getEdition, getEditionDownloadFilename, @@ -94,7 +96,7 @@ export default function SystemUpgradeItem(props: SystemUpgradeItemProps) { {translateWithParameters('system.download_x', lastUpgrade.version)} </DownloadButton> - <DocumentationLink className="sw-ml-2" to="/setup-and-upgrade/upgrade-the-server/roadmap/"> + <DocumentationLink className="sw-ml-2" to={DocLink.ServerUpgradeRoadmap}> {translate('system.how_to_upgrade')} </DocumentationLink> </div> diff --git a/server/sonar-web/src/main/js/helpers/constants.ts b/server/sonar-web/src/main/js/helpers/constants.ts index 1d236dad89c..1878e24ba20 100644 --- a/server/sonar-web/src/main/js/helpers/constants.ts +++ b/server/sonar-web/src/main/js/helpers/constants.ts @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { ComponentQualifier } from '~sonar-aligned/types/component'; import { MetricKey } from '~sonar-aligned/types/metrics'; import { colors } from '../app/theme'; @@ -167,16 +168,6 @@ export const DEPRECATED_ACTIVITY_METRICS = [ export const PROJECT_KEY_MAX_LEN = 400; -export const ALM_DOCUMENTATION_PATHS = { - [AlmKeys.Azure]: '/devops-platform-integration/azure-devops-integration/', - [AlmKeys.BitbucketServer]: - '/devops-platform-integration/bitbucket-integration/bitbucket-server-integration/', - [AlmKeys.BitbucketCloud]: - '/devops-platform-integration/bitbucket-integration/bitbucket-cloud-integration/', - [AlmKeys.GitHub]: '/devops-platform-integration/github-integration/', - [AlmKeys.GitLab]: '/devops-platform-integration/gitlab-integration/', -}; - export const IMPORT_COMPATIBLE_ALMS = [ AlmKeys.Azure, AlmKeys.BitbucketServer, diff --git a/server/sonar-web/src/main/js/helpers/doc-links.ts b/server/sonar-web/src/main/js/helpers/doc-links.ts new file mode 100644 index 00000000000..271234d3628 --- /dev/null +++ b/server/sonar-web/src/main/js/helpers/doc-links.ts @@ -0,0 +1,120 @@ +/* + * SonarQube + * Copyright (C) 2009-2024 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import { AlmKeys } from '../types/alm-settings'; + +export const DOC_URL = 'https://docs.sonarsource.com/sonarqube/latest'; + +export enum DocLink { + AccountTokens = '/user-guide/user-account/generating-and-using-tokens/', + ActiveVersions = '/setup-and-upgrade/upgrade-the-server/active-versions/', + AlmAzureIntegration = '/devops-platform-integration/azure-devops-integration/', + AlmBitBucketCloudAuth = '/instance-administration/authentication/bitbucket-cloud/', + AlmBitBucketCloudIntegration = '/devops-platform-integration/bitbucket-integration/bitbucket-cloud-integration/', + AlmBitBucketCloudSettings = '/instance-administration/authentication/bitbucket-cloud/#setting-your-authentication-settings-in-sonarqube', + AlmBitBucketServerIntegration = '/devops-platform-integration/bitbucket-integration/bitbucket-server-integration/', + AlmGitHubAuth = '/instance-administration/authentication/github/', + AlmGitHubIntegration = '/devops-platform-integration/github-integration/', + AlmGitHubMonorepoWorkfileExample = '/devops-platform-integration/github-integration/monorepo/#workflow-file-example', + AlmGitLabAuth = '/instance-administration/authentication/gitlab/', + AlmGitLabAuthProvisioningMethod = '/instance-administration/authentication/gitlab/#choosing-the-provisioning-method', + AlmGitLabIntegration = '/devops-platform-integration/gitlab-integration/', + AlmSamlAuth = '/instance-administration/authentication/saml/overview/', + AlmSamlScimAuth = '/instance-administration/authentication/saml/scim/overview/', + AnalysisScope = '/project-administration/analysis-scope/', + AuthOverview = '/instance-administration/authentication/overview/', + BackgroundTasks = '/analyzing-source-code/background-tasks/', + BranchAnalysis = '/analyzing-source-code/branches/branch-analysis/', + CaYC = '/user-guide/clean-as-you-code/', + CFamily = '/analyzing-source-code/languages/c-family/', + CFamilyAnalysisCache = '/analyzing-source-code/languages/c-family/#analysis-cache', + CIAnalysisSetup = '/analyzing-source-code/ci-integration/overview/', + CIJenkins = '/analyzing-source-code/ci-integration/jenkins-integration/', + CleanCodeIntroduction = '/user-guide/clean-code/introduction/', + CodeAnalysis = '/user-guide/clean-code/code-analysis/', + InactiveBranches = '/analyzing-source-code/branches/branch-analysis/#inactive-branches', + InstanceAdminEncryption = '/instance-administration/security/#settings-encryption', + InstanceAdminLicense = '/instance-administration/license-administration/', + InstanceAdminLoC = '/instance-administration/monitoring/lines-of-code/', + InstanceAdminMarketplace = '/instance-administration/marketplace/', + InstanceAdminPluginVersionMatrix = '/instance-administration/plugin-version-matrix/', + InstanceAdminQualityProfiles = '/instance-administration/quality-profiles/', + InstanceAdminReindexation = '/instance-administration/reindexing/', + InstanceAdminSecurity = '/instance-administration/security/', + IssueResolutions = '/user-guide/issues/#resolutions-deprecated', + Issues = '/user-guide/issues', + IssueStatuses = '/user-guide/issues/#statuses', + MainBranchAnalysis = '/analyzing-source-code/branches/branch-analysis/#main-branch', + MetricDefinitions = '/user-guide/metric-definitions/', + Monorepos = '/project-administration/monorepos/', + NewCodeDefinition = '/project-administration/clean-as-you-code-settings/defining-new-code/', + NewCodeDefinitionOptions = '/project-administration/clean-as-you-code-settings/defining-new-code/#new-code-definition-options', + Portfolios = '/user-guide/portfolios/', + PullRequestAnalysis = '/analyzing-source-code/pull-request-analysis', + QualityGates = '/user-guide/quality-gates/', + Root = '/', + RulesOverview = '/user-guide/rules/overview', + SecurityHotspots = '/user-guide/security-hotspots/', + SecurityReports = '/user-guide/security-reports/', + ServerUpgradeRoadmap = '/setup-and-upgrade/upgrade-the-server/roadmap/', + SonarLintConnectedMode = '/user-guide/sonarlint-connected-mode/', + SonarScanner = '/analyzing-source-code/scanners/sonarscanner/', + SonarScannerDotNet = '/analyzing-source-code/scanners/sonarscanner-for-dotnet/', + SonarScannerGradle = '/analyzing-source-code/scanners/sonarscanner-for-gradle/', + SonarScannerMaven = '/analyzing-source-code/scanners/sonarscanner-for-maven/', + Webhooks = '/project-administration/webhooks/', +} + +export const DocTitle = { + [DocLink.BackgroundTasks]: 'About Background Tasks', + [DocLink.CaYC]: 'Clean as You Code', + [DocLink.CIAnalysisSetup]: 'Set up CI analysis', + [DocLink.InstanceAdminQualityProfiles]: 'About Quality Profiles', + [DocLink.MetricDefinitions]: 'Metric Definitions', + [DocLink.NewCodeDefinition]: 'Defining New Code', + [DocLink.PullRequestAnalysis]: 'Analyzing Pull Requests', + [DocLink.SecurityReports]: 'About Security Reports', + [DocLink.SonarLintConnectedMode]: 'SonarLint Connected Mode', + [DocLink.Webhooks]: 'About Webhooks', +}; + +export type DocTitleKey = keyof typeof DocTitle; + +const asDocSections = <T>(element: { [K in keyof T]: DocTitleKey[] }) => element; + +export const DocSection = asDocSections({ + component_measures: [DocLink.CaYC, DocLink.MetricDefinitions], + overview: [ + DocLink.PullRequestAnalysis, + DocLink.CIAnalysisSetup, + DocLink.CaYC, + DocLink.SonarLintConnectedMode, + ], + pull_requests: [DocLink.CaYC, DocLink.PullRequestAnalysis, DocLink.SonarLintConnectedMode], +}); + +export type DocSectionKey = keyof typeof DocSection; + +export const AlmAuthDocLinkKeys = { + [AlmKeys.BitbucketServer]: DocLink.AlmBitBucketCloudAuth, + [AlmKeys.GitHub]: DocLink.AlmGitHubAuth, + [AlmKeys.GitLab]: DocLink.AlmGitLabAuth, + saml: DocLink.AlmSamlAuth, +}; diff --git a/server/sonar-web/src/main/js/helpers/docs.ts b/server/sonar-web/src/main/js/helpers/docs.ts index 31f34ecbb30..ac32f8e5005 100644 --- a/server/sonar-web/src/main/js/helpers/docs.ts +++ b/server/sonar-web/src/main/js/helpers/docs.ts @@ -17,26 +17,34 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import React from 'react'; import { AppStateContext } from '../app/components/app-state/AppStateContext'; +import { DocLink } from './doc-links'; -export function getUrlForDoc(url: string, version: string, to: string) { - const isSnapshot = version.indexOf('SNAPSHOT') !== -1; - const path = to.replace(/^\//, ''); +// This is only meant to be used directly for DocumentationRedirect. For all other uses, +// please use useDocUrl instead (it forces the use of a catalogued documentation link) +export function useUncataloguedDocUrl(to?: string) { + const { version, documentationUrl: docUrl } = React.useContext(AppStateContext); - return isSnapshot - ? `${url.replace(url.slice(url.lastIndexOf('/')), '/latest')}/${path}` - : `${url}/${path}`; -} + const formatDocUrl = React.useCallback( + (href: string) => { + const isSnapshot = version.indexOf('SNAPSHOT') !== -1; -export function useDocUrl(to: string): string; -export function useDocUrl(): (to: string) => string; -export function useDocUrl(to?: string) { - const { version, documentationUrl } = React.useContext(AppStateContext); + const path = href.replace(/^\//, ''); - if (to) { - return getUrlForDoc(documentationUrl, version, to); - } + return isSnapshot + ? `${docUrl.replace(docUrl.slice(docUrl.lastIndexOf('/')), '/latest')}/${path}` + : `${docUrl}/${path}`; + }, + [docUrl, version], + ); + + return to ? formatDocUrl(to) : formatDocUrl; +} - return (to: string) => getUrlForDoc(documentationUrl, version, to); +export function useDocUrl(to: DocLink): string; +export function useDocUrl(): (to: DocLink) => string; +export function useDocUrl(to?: DocLink) { + return useUncataloguedDocUrl(to); } diff --git a/server/sonar-web/src/main/js/sonar-aligned/components/controls/DocHelpTooltip.tsx b/server/sonar-web/src/main/js/sonar-aligned/components/controls/DocHelpTooltip.tsx index 19d0e4f0ab2..70b391f9ef6 100644 --- a/server/sonar-web/src/main/js/sonar-aligned/components/controls/DocHelpTooltip.tsx +++ b/server/sonar-web/src/main/js/sonar-aligned/components/controls/DocHelpTooltip.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import classNames from 'classnames'; import { HelperHintIcon } from 'design-system'; import { first, last } from 'lodash'; @@ -24,6 +25,7 @@ import * as React from 'react'; import DocumentationLink from '../../../components/common/DocumentationLink'; import Link from '../../../components/common/Link'; import Tooltip, { Placement } from '../../../components/controls/Tooltip'; +import { DocLink } from '../../../helpers/doc-links'; import { KeyboardKeys } from '../../../helpers/keycodes'; import { translate } from '../../../helpers/l10n'; @@ -32,7 +34,12 @@ export interface DocHelpTooltipProps { className?: string; content?: React.ReactNode; linkTextLabel?: string; - links?: Array<{ href: string; label?: string; inPlace?: boolean; doc?: boolean }>; + links?: Array< + { label?: string; inPlace?: boolean } & ( + | { doc?: true; href: DocLink } + | { doc: false; href: string } + ) + >; placement?: Placement; title?: string; } @@ -91,7 +98,10 @@ export default function DocHelpTooltip(props: Readonly<DocHelpTooltipProps>) { <div className="sw-mb-1" key={label}> {index === 0 && linkTextLabel && `${linkTextLabel}: `} {doc ? ( - <DocumentationLink to={href} innerRef={(ref) => (linksRef.current[index] = ref)}> + <DocumentationLink + to={href as DocLink} // the map above messed up type inference + innerRef={(ref) => (linksRef.current[index] = ref)} + > {label} </DocumentationLink> ) : ( diff --git a/server/sonar-web/src/main/js/sonar-aligned/components/controls/__tests__/DocHelpTooltip-test.tsx b/server/sonar-web/src/main/js/sonar-aligned/components/controls/__tests__/DocHelpTooltip-test.tsx index 1f58f3d7db8..e9cc67e6798 100644 --- a/server/sonar-web/src/main/js/sonar-aligned/components/controls/__tests__/DocHelpTooltip-test.tsx +++ b/server/sonar-web/src/main/js/sonar-aligned/components/controls/__tests__/DocHelpTooltip-test.tsx @@ -17,11 +17,13 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import userEvent from '@testing-library/user-event'; import * as React from 'react'; import { byRole, byTestId } from '../../../helpers/testSelector'; import Link from '../../../../components/common/Link'; +import { DocLink } from '../../../../helpers/doc-links'; import { renderComponent } from '../../../../helpers/testReactTestingUtils'; import DocHelpTooltip, { DocHelpTooltipProps } from '../DocHelpTooltip'; @@ -31,7 +33,7 @@ const ui = { helpIcon: byTestId('help-tooltip-activator'), helpLink: byRole('link', { name: 'Icon' }), linkInTooltip: byRole('link', { name: 'Label' }), - linkInTooltip2: byRole('link', { name: 'Label2' }), + linkInTooltip2: byRole('link', { name: /^Label2\b/ }), afterLink: byRole('link', { name: 'Interactive element after' }), }; @@ -70,15 +72,15 @@ function renderDocHelpTooltip(props: Partial<DocHelpTooltipProps> = {}) { content="Tooltip content" links={[ { - href: '/user-guide/clean-as-you-code/', - label: 'Label', doc: false, + href: '/user-guide/clean-as-you-code2/', + label: 'Label', }, { - href: '/user-guide/clean-as-you-code2/', - label: 'Label2', doc: true, + href: DocLink.CaYC, inPlace: true, + label: 'Label2', }, ]} {...props} diff --git a/server/sonar-web/src/main/js/types/types.ts b/server/sonar-web/src/main/js/types/types.ts index 4737531b462..ae90f771e9a 100644 --- a/server/sonar-web/src/main/js/types/types.ts +++ b/server/sonar-web/src/main/js/types/types.ts @@ -17,8 +17,10 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import { ComponentBase, ComponentQualifier } from '~sonar-aligned/types/component'; import { RuleDescriptionSection } from '../apps/coding-rules/rule'; +import { DocTitleKey } from '../helpers/doc-links'; import { CleanCodeAttribute, CleanCodeAttributeCategory, @@ -685,8 +687,7 @@ export interface SubscriptionPlan { } export interface SuggestionLink { - link: string; - scope?: 'sonarcloud'; + link: DocTitleKey; text: string; } |