diff options
10 files changed, 62 insertions, 9 deletions
diff --git a/server/sonar-web/design-system/src/components/CodeSnippet.tsx b/server/sonar-web/design-system/src/components/CodeSnippet.tsx index 8281a1242f9..c5c6e863dcd 100644 --- a/server/sonar-web/design-system/src/components/CodeSnippet.tsx +++ b/server/sonar-web/design-system/src/components/CodeSnippet.tsx @@ -34,7 +34,7 @@ interface Props { noCopy?: boolean; render?: string; snippet: string | Array<string | undefined>; - wrap?: boolean; + wrap?: boolean | 'words'; } // keep this "useless" concatenation for the readability reason diff --git a/server/sonar-web/design-system/src/components/CodeSyntaxHighlighter.tsx b/server/sonar-web/design-system/src/components/CodeSyntaxHighlighter.tsx index bf2ca3d5ced..e500fa239cf 100644 --- a/server/sonar-web/design-system/src/components/CodeSyntaxHighlighter.tsx +++ b/server/sonar-web/design-system/src/components/CodeSyntaxHighlighter.tsx @@ -43,7 +43,7 @@ interface Props { className?: string; htmlAsString: string; language?: string; - wrap?: boolean; + wrap?: boolean | 'words'; } const CODE_REGEXP = '<(code|pre)\\b([^>]*?)>(.+?)<\\/\\1>'; @@ -93,7 +93,11 @@ export function CodeSyntaxHighlighter(props: Props) { return ( <StyledSpan - className={classNames(`hljs ${className ?? ''}`, { 'code-wrap': wrap })} + className={classNames( + `hljs ${className ?? ''}`, + { 'code-wrap': wrap }, + { 'wrap-words': wrap === 'words' }, + )} // Safe: value is escaped by highlight.js // eslint-disable-next-line react/no-danger dangerouslySetInnerHTML={{ __html: highlightedHtmlAsString }} @@ -153,6 +157,11 @@ const StyledSpan = styled.span` &.code-wrap { ${tw`sw-whitespace-pre-wrap`} ${tw`sw-break-all`} + + &.wrap-words { + word-break: normal; + ${tw`sw-break-words`} + } } mark { diff --git a/server/sonar-web/design-system/src/components/__tests__/__snapshots__/CodeSnippet-test.tsx.snap b/server/sonar-web/design-system/src/components/__tests__/__snapshots__/CodeSnippet-test.tsx.snap index 20b9a394505..6d2f58112e9 100644 --- a/server/sonar-web/design-system/src/components/__tests__/__snapshots__/CodeSnippet-test.tsx.snap +++ b/server/sonar-web/design-system/src/components/__tests__/__snapshots__/CodeSnippet-test.tsx.snap @@ -158,6 +158,11 @@ exports[`should highlight code content correctly 1`] = ` word-break: break-all; } +.emotion-6.code-wrap.wrap-words { + word-break: normal; + overflow-wrap: break-word; +} + .emotion-6 mark { font-weight: 400; padding: 0.25rem; @@ -365,6 +370,11 @@ exports[`should show full size when multiline with no editing 1`] = ` word-break: break-all; } +.emotion-6.code-wrap.wrap-words { + word-break: normal; + overflow-wrap: break-word; +} + .emotion-6 mark { font-weight: 400; padding: 0.25rem; @@ -576,6 +586,11 @@ exports[`should show reduced size when single line with no editing 1`] = ` word-break: break-all; } +.emotion-6.code-wrap.wrap-words { + word-break: normal; + overflow-wrap: break-word; +} + .emotion-6 mark { font-weight: 400; padding: 0.25rem; diff --git a/server/sonar-web/src/main/js/apps/web-api-v2/__tests__/WebApiApp-it.tsx b/server/sonar-web/src/main/js/apps/web-api-v2/__tests__/WebApiApp-it.tsx index 5f6fd8ed667..5944543fcf7 100644 --- a/server/sonar-web/src/main/js/apps/web-api-v2/__tests__/WebApiApp-it.tsx +++ b/server/sonar-web/src/main/js/apps/web-api-v2/__tests__/WebApiApp-it.tsx @@ -155,7 +155,9 @@ it('should navigate between apis', async () => { expect(ui.requestHeader.query()).not.toBeInTheDocument(); expect(ui.requestBody.query()).not.toBeInTheDocument(); expect(ui.queryParameter.getAll()).toHaveLength(1); - expect(ui.queryParameter.getAt(0)).toHaveTextContent('status ["available","pending","sold"]'); + expect(ui.queryParameter.getAt(0)).toHaveTextContent( + 'status Enum (string): available, pending, sold', + ); expect(ui.queryParameter.getAt(0)).not.toHaveTextContent('default: available'); await user.click(ui.queryParameter.byRole('button').getAt(0)); expect(ui.queryParameter.getAt(0)).toHaveTextContent('default: available'); diff --git a/server/sonar-web/src/main/js/apps/web-api-v2/__tests__/utils-test.ts b/server/sonar-web/src/main/js/apps/web-api-v2/__tests__/utils-test.ts index 5ffd0aa7bfb..2e59ab44900 100644 --- a/server/sonar-web/src/main/js/apps/web-api-v2/__tests__/utils-test.ts +++ b/server/sonar-web/src/main/js/apps/web-api-v2/__tests__/utils-test.ts @@ -235,5 +235,5 @@ it('should map open api response schema', () => { type: 'string', enum: ['GREEN', 'YELLOW', 'RED'], }), - ).toStrictEqual(['GREEN', 'YELLOW', 'RED']); + ).toStrictEqual('Enum (string): GREEN, YELLOW, RED'); }); diff --git a/server/sonar-web/src/main/js/apps/web-api-v2/components/ApiParameters.tsx b/server/sonar-web/src/main/js/apps/web-api-v2/components/ApiParameters.tsx index 61165198841..5d29e8fa652 100644 --- a/server/sonar-web/src/main/js/apps/web-api-v2/components/ApiParameters.tsx +++ b/server/sonar-web/src/main/js/apps/web-api-v2/components/ApiParameters.tsx @@ -22,6 +22,7 @@ import { Accordion, Badge, SubHeading, SubTitle, TextMuted } from 'design-system import { groupBy } from 'lodash'; import { OpenAPIV3 } from 'openapi-types'; import React from 'react'; +import { FormattedMessage } from 'react-intl'; import { translate } from '../../../helpers/l10n'; import { ExcludeReferences } from '../types'; import { mapOpenAPISchema } from '../utils'; @@ -89,6 +90,20 @@ export default function ApiParameters({ data }: Props) { open={openParameters.includes(parameter.name)} > <div>{parameter.description}</div> + {parameter.schema?.enum && ( + <div className="sw-mt-2"> + <FormattedMessage + id="api_documentation.v2.enum_description" + values={{ + values: ( + <div className="sw-body-sm-highlight"> + {parameter.schema.enum.join(', ')} + </div> + ), + }} + /> + </div> + )} {parameter.schema?.maximum && ( <TextMuted className="sw-mt-2 sw-block" diff --git a/server/sonar-web/src/main/js/apps/web-api-v2/components/ApiRequestParameters.tsx b/server/sonar-web/src/main/js/apps/web-api-v2/components/ApiRequestParameters.tsx index 1888bd7847c..742d083a951 100644 --- a/server/sonar-web/src/main/js/apps/web-api-v2/components/ApiRequestParameters.tsx +++ b/server/sonar-web/src/main/js/apps/web-api-v2/components/ApiRequestParameters.tsx @@ -22,6 +22,7 @@ import { Accordion, Badge, TextMuted } from 'design-system'; import { isEmpty } from 'lodash'; import { OpenAPIV3 } from 'openapi-types'; import React from 'react'; +import { FormattedMessage } from 'react-intl'; import { translate } from '../../../helpers/l10n'; import { ExcludeReferences } from '../types'; @@ -86,6 +87,16 @@ export default function ApiRequestBodyParameters({ content }: Readonly<Props>) { open={openParameters.includes(key)} > <div>{parameters[key].description}</div> + {parameters[key].enum && ( + <div className="sw-mt-2"> + <FormattedMessage + id="api_documentation.v2.enum_description" + values={{ + values: <i>{parameters[key].enum?.join(', ')}</i>, + }} + /> + </div> + )} {parameters[key].maxLength && ( <TextMuted className="sw-mt-2 sw-block" diff --git a/server/sonar-web/src/main/js/apps/web-api-v2/components/ApiResponseSchema.tsx b/server/sonar-web/src/main/js/apps/web-api-v2/components/ApiResponseSchema.tsx index ffa716429c5..b028123ea9f 100644 --- a/server/sonar-web/src/main/js/apps/web-api-v2/components/ApiResponseSchema.tsx +++ b/server/sonar-web/src/main/js/apps/web-api-v2/components/ApiResponseSchema.tsx @@ -29,7 +29,7 @@ interface Props extends Omit<HtmlHTMLAttributes<HTMLDivElement>, 'content'> { content?: Exclude<ExcludeReferences<OpenAPIV3.ResponseObject>['content'], undefined>; } -export default function ApiResponseSchema(props: Props) { +export default function ApiResponseSchema(props: Readonly<Props>) { const { content, ...other } = props; const schema = content && @@ -43,7 +43,7 @@ export default function ApiResponseSchema(props: Props) { language="json" className="sw-p-6" snippet={JSON.stringify(mapOpenAPISchema(schema), null, 2)} - wrap + wrap="words" {...other} /> ); diff --git a/server/sonar-web/src/main/js/apps/web-api-v2/utils.ts b/server/sonar-web/src/main/js/apps/web-api-v2/utils.ts index 49732b04d7a..2949976f13c 100644 --- a/server/sonar-web/src/main/js/apps/web-api-v2/utils.ts +++ b/server/sonar-web/src/main/js/apps/web-api-v2/utils.ts @@ -36,8 +36,8 @@ export const mapOpenAPISchema = ( if (schema.type === 'array') { return [mapOpenAPISchema(schema.items)]; } - if (schema.type === 'string' && schema.enum) { - return schema.enum as ConvertedSchema; + if (schema.enum) { + return `Enum (${schema.type}): ${(schema.enum as ConvertedSchema[]).join(', ')}`; } if (schema.format) { return `${schema.type} (${schema.format})`; diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index 3a6bf83af90..f2f4cbb63d0 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -4045,6 +4045,7 @@ api_documentation.v2.request_subheader.query=Query Parameters api_documentation.v2.request_subheader.path=Path Parameters api_documentation.v2.request_subheader.header=Headers api_documentation.v2.request_subheader.request_body=Request Body +api_documentation.v2.enum_description=Valid values: {values} #------------------------------------------------------------------------------ |