]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-20769 Correcting input and alert for other ALM's modal
authorRevanshu Paliwal <revanshu.paliwal@sonarsource.com>
Wed, 18 Oct 2023 08:49:49 +0000 (10:49 +0200)
committersonartech <sonartech@sonarsource.com>
Wed, 18 Oct 2023 20:03:06 +0000 (20:03 +0000)
server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionForm.tsx
server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionFormField.tsx
server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionFormRenderer.tsx
server/sonar-web/src/main/js/apps/settings/components/almIntegration/AzureForm.tsx
server/sonar-web/src/main/js/apps/settings/components/almIntegration/BitbucketCloudForm.tsx
server/sonar-web/src/main/js/apps/settings/components/almIntegration/BitbucketForm.tsx
server/sonar-web/src/main/js/apps/settings/components/almIntegration/BitbucketServerForm.tsx
server/sonar-web/src/main/js/apps/settings/components/almIntegration/GithubForm.tsx
server/sonar-web/src/main/js/apps/settings/components/almIntegration/GitlabForm.tsx
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmIntegration-it.tsx

index c58a2d424337f796a97d4f850d2513030568a445..0629cffc700e49cc98baaa9bf8c1723174bdde6e 100644 (file)
@@ -126,6 +126,8 @@ export default class AlmBindingDefinitionForm extends React.PureComponent<
   State
 > {
   mounted = false;
+  errorListElement = React.createRef<HTMLDivElement>();
+
   constructor(props: AlmBindingDefinitionFormProps) {
     super(props);
 
@@ -211,6 +213,9 @@ export default class AlmBindingDefinitionForm extends React.PureComponent<
 
       if (error) {
         this.setState({ validationError: error });
+        if (this.errorListElement?.current) {
+          this.errorListElement.current.scrollIntoView({ block: 'start' });
+        }
       } else {
         this.props.afterSubmit(formData);
       }
@@ -280,6 +285,7 @@ export default class AlmBindingDefinitionForm extends React.PureComponent<
         bitbucketVariant={bitbucketVariant}
         onBitbucketVariantChange={this.handleBitbucketVariantChange}
         validationError={validationError}
+        errorListElementRef={this.errorListElement}
       />
     );
   }
index 9fc63fc29120940164568c30f54ea587aed5028b..220efa166498cf19344d7d39d8f98848d1e30cd3 100644 (file)
@@ -92,31 +92,31 @@ export function AlmBindingDefinitionFormField<B extends AlmBindingDefinitionBase
           </ButtonSecondary>
         </div>
       )}
-      {showField && isTextArea && (
-        <InputTextArea
-          id={id}
-          maxLength={maxLength || 2000}
-          onChange={(e) => props.onFieldChange(propKey, e.currentTarget.value)}
-          required={!optional}
-          rows={5}
-          size="full"
-          value={value}
-          isInvalid={isInvalid}
-        />
-      )}
-      {showField && !isTextArea && (
-        <InputField
-          autoFocus={autoFocus}
-          id={id}
-          maxLength={maxLength || 100}
-          name={id}
-          onChange={(e) => props.onFieldChange(propKey, e.currentTarget.value)}
-          type="text"
-          size="full"
-          value={value}
-          isInvalid={isInvalid}
-        />
-      )}
+      {showField &&
+        (isTextArea ? (
+          <InputTextArea
+            id={id}
+            maxLength={maxLength || 2000}
+            onChange={(e) => props.onFieldChange(propKey, e.currentTarget.value)}
+            required={!optional}
+            rows={5}
+            size="full"
+            value={value}
+            isInvalid={isInvalid}
+          />
+        ) : (
+          <InputField
+            autoFocus={autoFocus}
+            id={id}
+            maxLength={maxLength || 100}
+            name={id}
+            onChange={(e) => props.onFieldChange(propKey, e.currentTarget.value)}
+            type="text"
+            size="full"
+            value={value}
+            isInvalid={isInvalid}
+          />
+        ))}
       {showField && isSecret && (
         <FlagMessage variant="info" className="sw-mt-2">
           <span>
index 873275c6990ef010b4eaa477970afbb431746a6c..d439e1c655f40d32fc9e7eb529df0147524e1545 100644 (file)
@@ -17,7 +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, Modal, Spinner } from 'design-system';
+import { ButtonPrimary, FlagMessage, Modal, PageContentFontWrapper, Spinner } from 'design-system';
 import * as React from 'react';
 import { translate } from '../../../../helpers/l10n';
 import {
@@ -48,6 +48,7 @@ export interface Props {
     bitbucketVariant: AlmKeys.BitbucketServer | AlmKeys.BitbucketCloud,
   ) => void;
   validationError?: string;
+  errorListElementRef: React.RefObject<HTMLDivElement>;
 }
 
 export default class AlmBindingDefinitionFormRenderer extends React.PureComponent<Readonly<Props>> {
@@ -94,7 +95,7 @@ export default class AlmBindingDefinitionFormRenderer extends React.PureComponen
   };
 
   render() {
-    const { isUpdate, canSubmit, submitting, validationError } = this.props;
+    const { isUpdate, canSubmit, submitting, validationError, errorListElementRef } = this.props;
     const header = translate('settings.almintegration.form.header', isUpdate ? 'edit' : 'create');
     const FORM_ID = `settings.almintegration.form.${isUpdate ? 'edit' : 'create'}`;
 
@@ -105,17 +106,19 @@ export default class AlmBindingDefinitionFormRenderer extends React.PureComponen
 
     const formBody = (
       <form id={FORM_ID} onSubmit={handleSubmit}>
-        {this.renderForm()}
-        {validationError && !canSubmit && (
-          <FlagMessage variant="error" className="sw-w-full">
-            <div>
-              <p>{translate('settings.almintegration.configuration_invalid')}</p>
-              <ul>
-                <li>{validationError}</li>
-              </ul>
-            </div>
-          </FlagMessage>
-        )}
+        <PageContentFontWrapper className="sw-body-sm" ref={errorListElementRef}>
+          {validationError && !canSubmit && (
+            <FlagMessage variant="error" className="sw-w-full sw-mb-2">
+              <div>
+                <p>{translate('settings.almintegration.configuration_invalid')}</p>
+                <ul>
+                  <li>{validationError}</li>
+                </ul>
+              </div>
+            </FlagMessage>
+          )}
+          {this.renderForm()}
+        </PageContentFontWrapper>
       </form>
     );
 
index 4ac3331a53c506fb43787dcd9a4113e10365e0ba..0e776c4597ee633beb7f8614d7e882096e3efd4a 100644 (file)
  * 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 DocLink from '../../../../components/common/DocLink';
-import Link from '../../../../components/common/Link';
 import { ALM_DOCUMENTATION_PATHS } from '../../../../helpers/constants';
+import { useDocUrl } from '../../../../helpers/docs';
 import { translate } from '../../../../helpers/l10n';
 import { AlmKeys, AzureBindingDefinition } from '../../../../types/alm-settings';
 import { AlmBindingDefinitionFormField } from './AlmBindingDefinitionFormField';
@@ -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]);
   return (
     <>
       <AlmBindingDefinitionFormField
@@ -81,11 +82,7 @@ export default function AzureForm(props: AzureFormProps) {
                 </Link>
               ),
               permission: <strong>{'Code > Read & Write'}</strong>,
-              doc_link: (
-                <DocLink to={ALM_DOCUMENTATION_PATHS[AlmKeys.Azure]}>
-                  {translate('learn_more')}
-                </DocLink>
-              ),
+              doc_link: <Link to={toStatic}>{translate('learn_more')}</Link>,
             }}
           />
         }
index a7abd2914b38bb2940c4456e43e2f196722a9a69..948d575f83c04fa51a6ab27cbd80326981bdda9a 100644 (file)
  * 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 '../../../../components/common/DocLink';
-import Link from '../../../../components/common/Link';
-import { Alert } from '../../../../components/ui/Alert';
 import { ALM_DOCUMENTATION_PATHS } from '../../../../helpers/constants';
+import { useDocUrl } from '../../../../helpers/docs';
 import { translate } from '../../../../helpers/l10n';
 import { AlmKeys, BitbucketCloudBindingDefinition } from '../../../../types/alm-settings';
 import { BITBUCKET_CLOUD_WORKSPACE_ID_FORMAT } from '../../constants';
@@ -39,8 +38,31 @@ 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">
+        <div>
+          <FormattedMessage
+            defaultMessage={translate(`settings.almintegration.bitbucketcloud.info`)}
+            id="settings.almintegration.bitbucketcloud.info"
+            values={{
+              oauth: (
+                <Link
+                  to="https://support.atlassian.com/bitbucket-cloud/docs/use-oauth-on-bitbucket-cloud/"
+                  target="_blank"
+                >
+                  {translate('settings.almintegration.bitbucketcloud.oauth')}
+                </Link>
+              ),
+              permission: <strong>Pull Requests: Read</strong>,
+              doc_link: <Link to={toStatic}>{translate('learn_more')}</Link>,
+            }}
+          />
+        </div>
+      </FlagMessage>
+
       <AlmBindingDefinitionFormField
         autoFocus
         help={translate('settings.almintegration.form.name.bitbucketcloud.help')}
@@ -52,19 +74,24 @@ export default function BitbucketCloudForm(props: BitbucketCloudFormProps) {
       />
       <AlmBindingDefinitionFormField
         help={
-          <FormattedMessage
-            defaultMessage={translate('settings.almintegration.form.workspace.bitbucketcloud.help')}
-            id="settings.almintegration.form.workspace.bitbucketcloud.help"
-            values={{
-              example: (
-                <>
-                  {'https://bitbucket.org/'}
-                  <strong>{'{workspace}'}</strong>
-                  {'/{repository}'}
-                </>
-              ),
-            }}
-          />
+          <>
+            <FormattedMessage
+              defaultMessage={translate(
+                'settings.almintegration.form.workspace.bitbucketcloud.help',
+              )}
+              id="settings.almintegration.form.workspace.bitbucketcloud.help"
+              values={{
+                example: (
+                  <>
+                    {'https://bitbucket.org/'}
+                    <strong>{'{workspace}'}</strong>
+                    {'/{repository}'}
+                  </>
+                ),
+              }}
+            />
+            <p>{translate('settings.almintegration.form.workspace.bitbucketcloud.error')}</p>
+          </>
         }
         id="workspace.bitbucketcloud"
         isInvalid={workspaceIDIsInvalid}
@@ -73,28 +100,6 @@ export default function BitbucketCloudForm(props: BitbucketCloudFormProps) {
         propKey="workspace"
         value={formData.workspace || ''}
       />
-      <Alert className="big-spacer-top" variant="info">
-        <FormattedMessage
-          defaultMessage={translate(`settings.almintegration.bitbucketcloud.info`)}
-          id="settings.almintegration.bitbucketcloud.info"
-          values={{
-            oauth: (
-              <Link
-                to="https://support.atlassian.com/bitbucket-cloud/docs/use-oauth-on-bitbucket-cloud/"
-                target="_blank"
-              >
-                {translate('settings.almintegration.bitbucketcloud.oauth')}
-              </Link>
-            ),
-            permission: <strong>Pull Requests: Read</strong>,
-            doc_link: (
-              <DocLink to={ALM_DOCUMENTATION_PATHS[AlmKeys.BitbucketCloud]}>
-                {translate('learn_more')}
-              </DocLink>
-            ),
-          }}
-        />
-      </Alert>
       <AlmBindingDefinitionFormField
         id="client_id.bitbucketcloud"
         help={translate('settings.almintegration.form.oauth_key.bitbucketcloud.help')}
index e19213d20796645eed59057b9cc79b9e22f0dfa6..36607f04ad6f2e986a1ddbd5813d41f8744f88a4 100644 (file)
@@ -17,8 +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 { FormField, ToggleButton } from 'design-system';
 import * as React from 'react';
-import ButtonToggle from '../../../../components/controls/ButtonToggle';
 import { translate } from '../../../../helpers/l10n';
 import {
   AlmKeys,
@@ -45,12 +45,11 @@ export default function BitbucketForm(props: Readonly<BitbucketFormProps>) {
   return (
     <>
       {!isUpdate && (
-        <div className="display-flex-column">
-          <strong>{translate('settings.almintegration.form.choose_bitbucket_variant')}</strong>
-          <div className="little-spacer-top big-spacer-bottom">
-            <ButtonToggle
+        <FormField label={translate('settings.almintegration.form.choose_bitbucket_variant')}>
+          <div>
+            <ToggleButton
               label={translate('settings.almintegration.form.choose_bitbucket_variant')}
-              onCheck={props.onVariantChange}
+              onChange={props.onVariantChange}
               options={[
                 {
                   label: translate('alm.bitbucket.long'),
@@ -61,7 +60,7 @@ export default function BitbucketForm(props: Readonly<BitbucketFormProps>) {
               value={variant}
             />
           </div>
-        </div>
+        </FormField>
       )}
 
       {variant !== undefined && (
index 649377183cfe455507becb48621e81184d30170c..130ddbadefa9828860148111b724e6cd2365fb43 100644 (file)
  * 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 DocLink from '../../../../components/common/DocLink';
-import Link from '../../../../components/common/Link';
 import { ALM_DOCUMENTATION_PATHS } from '../../../../helpers/constants';
+import { useDocUrl } from '../../../../helpers/docs';
 import { translate } from '../../../../helpers/l10n';
 import { AlmKeys, BitbucketServerBindingDefinition } from '../../../../types/alm-settings';
 import { AlmBindingDefinitionFormField } from './AlmBindingDefinitionFormField';
@@ -33,7 +34,7 @@ export interface BitbucketServerFormProps {
 
 export default function BitbucketServerForm(props: BitbucketServerFormProps) {
   const { formData } = props;
-
+  const toStatic = useDocUrl(ALM_DOCUMENTATION_PATHS[AlmKeys.BitbucketServer]);
   return (
     <>
       <AlmBindingDefinitionFormField
@@ -79,11 +80,7 @@ export default function BitbucketServerForm(props: BitbucketServerFormProps) {
                 </Link>
               ),
               permission: <strong>Read</strong>,
-              doc_link: (
-                <DocLink to={ALM_DOCUMENTATION_PATHS[AlmKeys.BitbucketServer]}>
-                  {translate('learn_more')}
-                </DocLink>
-              ),
+              doc_link: <Link to={toStatic}>{translate('learn_more')}</Link>,
             }}
           />
         }
index be6675494436db1e6e00defbe9d74bfdc61b6ab2..183619a0244fa38cc983b85b59384d4c01e83996 100644 (file)
@@ -17,7 +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, Link, PageContentFontWrapper } from 'design-system';
+import { FlagMessage, Link } from 'design-system';
 import * as React from 'react';
 import { FormattedMessage } from 'react-intl';
 import { ALM_DOCUMENTATION_PATHS } from '../../../../helpers/constants';
@@ -35,7 +35,7 @@ export default function GithubForm(props: GithubFormProps) {
   const { formData, onFieldChange } = props;
   const toStatic = useDocUrl(ALM_DOCUMENTATION_PATHS[AlmKeys.GitHub]);
   return (
-    <PageContentFontWrapper className="sw-body-sm">
+    <>
       <FlagMessage variant="info" className="sw-mb-8">
         <span>
           <FormattedMessage
@@ -124,6 +124,6 @@ export default function GithubForm(props: GithubFormProps) {
         isSecret
         optional
       />
-    </PageContentFontWrapper>
+    </>
   );
 }
index 8d7c425d23db56f600ee65554279ef5c7a8d87d7..4ceca5261c959b7a09eeee09efdea0f4f501e5e4 100644 (file)
  * 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 DocLink from '../../../../components/common/DocLink';
-import Link from '../../../../components/common/Link';
 import { ALM_DOCUMENTATION_PATHS } from '../../../../helpers/constants';
+import { useDocUrl } from '../../../../helpers/docs';
 import { translate } from '../../../../helpers/l10n';
 import { AlmKeys, GitlabBindingDefinition } from '../../../../types/alm-settings';
 import { AlmBindingDefinitionFormField } from './AlmBindingDefinitionFormField';
@@ -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]);
   return (
     <>
       <AlmBindingDefinitionFormField
@@ -77,11 +78,7 @@ export default function GitlabForm(props: GitlabFormProps) {
               ),
               permission: <strong>Reporter</strong>,
               scope: <strong>api</strong>,
-              doc_link: (
-                <DocLink to={ALM_DOCUMENTATION_PATHS[AlmKeys.GitLab]}>
-                  {translate('learn_more')}
-                </DocLink>
-              ),
+              doc_link: <Link to={toStatic}>{translate('learn_more')}</Link>,
             }}
           />
         }
index d73192194c0cb0262020395b1b4f94c6b08e1b3b..22c9226e1af21e0dca8c2bd66d24e4f9284cf292 100644 (file)
@@ -189,7 +189,7 @@ function getPageObjects() {
     tab: (almKey: AlmKeys) =>
       byRole('tab', { name: `${almKey} settings.almintegration.tab.${almKey}` }),
     bitbucketConfiguration: (almKey: AlmKeys.BitbucketCloud | AlmKeys.BitbucketServer) =>
-      byRole('button', { name: `alm.${almKey}.long` }),
+      byRole('radio', { name: `alm.${almKey}.long` }),
     configurationInput: (id: string) =>
       byRole('textbox', { name: `settings.almintegration.form.${id} required` }),
     updateSecretValueButton: (key: string) =>