import React from 'react'; import { makeStyles } from '@material-ui/core/styles'; import Container from '@material-ui/core/Container'; import Typography from '@material-ui/core/Typography'; import Tabs from '@material-ui/core/Tabs'; import Tab from '@material-ui/core/Tab'; import Box from '@material-ui/core/Box'; import { Link } from '@material-ui/core'; import { useHistory } from "react-router-dom"; import { useRuleCoverage } from './utils/useRuleCoverage'; import { useFetch } from './utils/useFetch'; import { RuleMetadata } from './types'; const useStyles = makeStyles((theme) => ({ ruleBar: { borderBottom: '1px solid lightgrey', }, ruleid: { textAlign: 'center', marginTop: theme.spacing(3), marginBottom: theme.spacing(3), }, title: { textAlign: 'justify', marginTop: theme.spacing(4), marginBottom: theme.spacing(4), }, coverage: { marginBottom: theme.spacing(3), }, description: { textAlign: 'justify', // marginBottom: theme.spacing(3), }, // style used to center the tabs when there too few of them to fill the container tabRoot: { justifyContent: "center" }, tabScroller: { flexGrow: 0 }, unimplemented: { color: 'red' } })); const languageToJiraProject = new Map(Object.entries({ "PYTHON": "SONARPY", "ABAP": "SONARABAP", "CFAMILY": "CPP", "JAVA": "SONARJAVA", "COBOL": "SONARCOBOL", "FLEX": "SONARFLEX", "HTML": "SONARHTML", "PHP": "SONARPHP", "PLI": "SONARPLI", "PLSQL": "SONARPLSQL", "RPG": "SONARRPG", "APEX": "SONARSLANG", "RUBY": "SONARSLANG", "KOTLIN": "SONARSLANG", "SCALA": "SONARSLANG", "GO": "SONARSLANG", "SWIFT": "SONARSWIFT", "TSQL": "SONARTSQL", "VB6": "SONARVBSIX", "XML": "SONARXML", "CLOUDFORMATION": "SONARIAC", "TERRAFORM": "SONARIAC", })); const languageToGithubProject = new Map(Object.entries({ "ABAP": "sonar-abap", "CSHARP": "sonar-dotnet", "VBNET": "sonar-dotnet", "JAVASCRIPT": "SonarJS", "TYPESCRIPT": "SonarJS", "SWIFT": "sonar-swift", "KOTLIN": "slang-enterprise", "GO": "slang-enterprise", "SCALA": "slang-enterprise", "RUBY": "slang-enterprise", "APEX": "slang-enterprise", "HTML": "sonar-html", "COBOL": "sonar-cobol", "VB6": "sonar-vb", "JAVA": "sonar-java", "PLI": "sonar-pli", "CFAMILY": "sonar-cpp", "CSS": "sonar-css", "FLEX": "sonar-flex", "PHP": "sonar-php", "PLSQL": "sonar-plsql", "PYTHON": "sonar-python", "RPG": "sonar-rpg", "TSQL": "sonar-tsql", "XML": "sonar-xml", "CLOUDFORMATION": "sonar-iac", "TERRAFORM": "sonar-iac", })); export function RulePage(props: any) { const ruleid = props.match.params.ruleid; const language = props.match.params.language; const history = useHistory(); function handleLanguageChange(event: any, lang: string) { history.push(`/${ruleid}/${lang}`); } const classes = useStyles(); let descUrl = process.env.PUBLIC_URL + '/rules/' + ruleid + "/" + language + "-description.html"; let metadataUrl = process.env.PUBLIC_URL + '/rules/' + ruleid + "/" + language + "-metadata.json"; let editOnGithubUrl = 'https://github.com/SonarSource/rspec/tree/master/rules/' + ruleid + '/' + language; let [descHTML, descError, descIsLoading] = useFetch(descUrl, false); let [metadataJSON, metadataError, metadataIsLoading] = useFetch(metadataUrl); const ruleCoverage = useRuleCoverage(); let coverage: any = "Loading..."; let title = "Loading..." let metadataJSONString; let languagesTabs = null; let prUrl: string | undefined = undefined; if (metadataJSON && !metadataIsLoading && !metadataError) { title = metadataJSON.title; if ('prUrl' in metadataJSON) { prUrl = metadataJSON.prUrl; } metadataJSON.all_languages.sort(); languagesTabs = metadataJSON.all_languages.map(lang => ); metadataJSONString = JSON.stringify(metadataJSON, null, 2); coverage = ruleCoverage(language, metadataJSON.allKeys, (key: any, version: any) => { return (
  • {key}: {version}
  • ) }); } let description =
    Loading...
    ; if (descHTML !== null && !descIsLoading && !descError) { description =

    Edit on Github

    {metadataJSONString}
    ; } let prLink = <>; if (prUrl) { prLink =
    Not implemented (see PR)
    } const ruleNumber = ruleid.substring(1) const upperCaseLanguage = language.toUpperCase(); const jiraProject = languageToJiraProject.get(upperCaseLanguage); const githubProject = languageToGithubProject.get(upperCaseLanguage); let ticketsLink; if (jiraProject !== undefined) { ticketsLink = ( Implementation tickets on Jira ); } else { ticketsLink = ( Implementation issues on GitHub ); } const specificationPRsLink = ( Specification Pull Requests ); const implementationPRsLink = ( Implementation Pull Requests ); return (
    {ruleid} {prLink} {languagesTabs}
    {title} Covered Since
      {coverage}
    Related Tickets and Pull Requests
      {specificationPRsLink}
      {implementationPRsLink}
      {ticketsLink}
    Description {description}
    ); }