]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-20916 Migrate project key update to the new UI
authorJeremy Davis <jeremy.davis@sonarsource.com>
Mon, 30 Oct 2023 14:12:49 +0000 (15:12 +0100)
committersonartech <sonartech@sonarsource.com>
Tue, 31 Oct 2023 20:02:42 +0000 (20:02 +0000)
server/sonar-web/src/main/js/app/components/ComponentContainer.tsx
server/sonar-web/src/main/js/app/components/GlobalContainer.tsx
server/sonar-web/src/main/js/apps/projectKey/ProjectKeyApp.tsx
server/sonar-web/src/main/js/apps/projectKey/UpdateForm.tsx
server/sonar-web/src/main/js/components/common/ProjectKeyInput.tsx [deleted file]

index 8fee8246f08efc87fd71d5a1e1fdef2ed6c03bcb..e9fedda58371dfcbace850d7fb3ad29db7cbfc92 100644 (file)
@@ -18,6 +18,7 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
+import { CenteredLayout, Spinner } from 'design-system';
 import { differenceBy } from 'lodash';
 import * as React from 'react';
 import { createPortal } from 'react-dom';
@@ -363,9 +364,9 @@ export class ComponentContainer extends React.PureComponent<Props, State> {
             this.portalAnchor,
           )}
         {loading ? (
-          <div className="page page-limited">
-            <i className="spinner" />
-          </div>
+          <CenteredLayout>
+            <Spinner className="sw-mt-10" />
+          </CenteredLayout>
         ) : (
           <ComponentContext.Provider
             value={{
index b1dc3e8552e7fa215391025b76126964c0b49735..78cad5d94103a1a68bb67ee893149ef935cd2f17 100644 (file)
@@ -59,6 +59,7 @@ const TEMP_PAGELIST_WITH_NEW_BACKGROUND_WHITE = [
   '/projects/create',
   '/project/baseline',
   '/project/branches',
+  '/project/key',
 ];
 
 export default function GlobalContainer() {
index d1f7b8e91ff689a10f1a49e7707dc67e1306e25c..4823a8265d83d092c1ba4b6ba3d804549c9526d9 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 { LargeCenteredLayout, PageContentFontWrapper, Title } from 'design-system';
 import * as React from 'react';
 import { Helmet } from 'react-helmet-async';
 import { changeKey } from '../../api/components';
-import withComponentContext from '../../app/components/componentContext/withComponentContext';
 import RecentHistory from '../../app/components/RecentHistory';
+import withComponentContext from '../../app/components/componentContext/withComponentContext';
 import { Router, withRouter } from '../../components/hoc/withRouter';
 import { translate } from '../../helpers/l10n';
 import { Component } from '../../types/types';
@@ -41,14 +42,16 @@ function ProjectKeyApp({ component, router }: Props) {
   };
 
   return (
-    <div className="page page-limited" id="project-key">
+    <LargeCenteredLayout id="project-key">
       <Helmet defer={false} title={translate('update_key.page')} />
-      <header className="page-header">
-        <h1 className="page-title">{translate('update_key.page')}</h1>
-        <div className="page-description">{translate('update_key.page.description')}</div>
-      </header>
-      <UpdateForm component={component} onKeyChange={handleChangeKey} />
-    </div>
+      <PageContentFontWrapper className="sw-my-8 sw-body-sm">
+        <header className="sw-mt-8 sw-mb-4">
+          <Title className="sw-mb-4">{translate('update_key.page')}</Title>
+          <div className="sw-mb-2">{translate('update_key.page.description')}</div>
+        </header>
+        <UpdateForm component={component} onKeyChange={handleChangeKey} />
+      </PageContentFontWrapper>
+    </LargeCenteredLayout>
   );
 }
 
index b30a0b824f9c78fffad6f43ae3032df3cf2e877d..6fd2b7e62c1997de05855ba5e02e79b2945a6f27 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 {
+  ButtonPrimary,
+  ButtonSecondary,
+  FlagMessage,
+  FormField,
+  InputField,
+  Note,
+} from 'design-system';
 import * as React from 'react';
-import ProjectKeyInput from '../../components/common/ProjectKeyInput';
 import ConfirmButton from '../../components/controls/ConfirmButton';
-import { Button, SubmitButton } from '../../components/controls/buttons';
-import MandatoryFieldsExplanation from '../../components/ui/MandatoryFieldsExplanation';
 import { translate, translateWithParameters } from '../../helpers/l10n';
 import { validateProjectKey } from '../../helpers/projects';
 import { ProjectKeyValidationResult } from '../../types/component';
@@ -43,6 +48,13 @@ export default function UpdateForm(props: UpdateFormProps) {
       ? undefined
       : translate('onboarding.create_project.project_key.error', validationResult);
 
+  const onInputChange = React.useCallback(
+    (e: React.ChangeEvent<HTMLInputElement>) => {
+      setNewKey(e.currentTarget.value);
+    },
+    [setNewKey],
+  );
+
   return (
     <ConfirmButton
       confirmButtonText={translate('update_verb')}
@@ -50,15 +62,15 @@ export default function UpdateForm(props: UpdateFormProps) {
       modalBody={
         <>
           {translateWithParameters('update_key.are_you_sure_to_change_key', component.name)}
-          <div className="spacer-top">
+          <div className="sw-mt-2">
             {translate('update_key.old_key')}
             {': '}
-            <strong>{component.key}</strong>
+            <strong className="sw-body-md-highlight">{component.key}</strong>
           </div>
-          <div className="spacer-top">
+          <div className="sw-mt-2">
             {translate('update_key.new_key')}
             {': '}
-            <strong>{newKey}</strong>
+            <strong className="sw-body-md-highlight">{newKey}</strong>
           </div>
         </>
       }
@@ -67,27 +79,41 @@ export default function UpdateForm(props: UpdateFormProps) {
     >
       {({ onFormSubmit }) => (
         <form onSubmit={onFormSubmit}>
-          <MandatoryFieldsExplanation className="spacer-bottom" />
+          <FormField label={translate('update_key.new_key')} required>
+            <InputField
+              id="project-key"
+              name="update_key.new_key"
+              required
+              isInvalid={hasChanged && error !== undefined}
+              isValid={hasChanged && error === undefined}
+              autoFocus
+              onChange={onInputChange}
+              value={newKey}
+              type="text"
+            />
 
-          <ProjectKeyInput
-            error={error}
-            label={translate('update_key.new_key')}
-            onProjectKeyChange={(e: React.ChangeEvent<HTMLInputElement>) => {
-              setNewKey(e.currentTarget.value);
-            }}
-            touched={hasChanged}
-            placeholder={translate('update_key.new_key')}
-            projectKey={newKey}
-            autofocus
-          />
+            {error && (
+              <FlagMessage className="sw-mt-2 sw-w-abs-400" variant="error">
+                {error}
+              </FlagMessage>
+            )}
 
-          <div className="spacer-top">
-            <SubmitButton disabled={!hasChanged || error !== undefined} id="update-key-submit">
+            <Note className="sw-mt-2 sw-max-w-1/2">
+              {translate('onboarding.create_project.project_key.description')}
+            </Note>
+          </FormField>
+
+          <div className="sw-mt-2">
+            <ButtonPrimary
+              disabled={!hasChanged || error !== undefined}
+              id="update-key-submit"
+              type="submit"
+            >
               {translate('update_verb')}
-            </SubmitButton>
+            </ButtonPrimary>
 
-            <Button
-              className="spacer-left"
+            <ButtonSecondary
+              className="sw-ml-2"
               disabled={!hasChanged}
               id="update-key-reset"
               onClick={() => {
@@ -96,7 +122,7 @@ export default function UpdateForm(props: UpdateFormProps) {
               type="reset"
             >
               {translate('reset_verb')}
-            </Button>
+            </ButtonSecondary>
           </div>
         </form>
       )}
diff --git a/server/sonar-web/src/main/js/components/common/ProjectKeyInput.tsx b/server/sonar-web/src/main/js/components/common/ProjectKeyInput.tsx
deleted file mode 100644 (file)
index 72f8dac..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 classNames from 'classnames';
-import * as React from 'react';
-import ValidationInput from '../../components/controls/ValidationInput';
-import { PROJECT_KEY_MAX_LEN } from '../../helpers/constants';
-import { translate } from '../../helpers/l10n';
-
-export interface ProjectKeyInputProps {
-  error?: string;
-  help?: string;
-  label?: string;
-  onProjectKeyChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
-  placeholder?: string;
-  projectKey?: string;
-  touched: boolean;
-  validating?: boolean;
-  autofocus?: boolean;
-}
-
-export default function ProjectKeyInput(props: ProjectKeyInputProps) {
-  const {
-    error,
-    help,
-    label,
-    placeholder,
-    projectKey,
-    touched,
-    validating,
-    autofocus = false,
-  } = props;
-
-  const isInvalid = touched && error !== undefined;
-  const isValid = touched && !validating && error === undefined;
-
-  return (
-    <ValidationInput
-      className="form-field"
-      description={translate('onboarding.create_project.project_key.description')}
-      error={error}
-      help={help}
-      labelHtmlFor="project-key"
-      isInvalid={isInvalid}
-      isValid={isValid}
-      label={label}
-      required={label !== undefined}
-    >
-      <input
-        name={label}
-        autoFocus={autofocus}
-        className={classNames('input-super-large', {
-          'is-invalid': isInvalid,
-          'is-valid': isValid,
-        })}
-        id="project-key"
-        maxLength={PROJECT_KEY_MAX_LEN}
-        minLength={1}
-        onChange={props.onProjectKeyChange}
-        placeholder={placeholder}
-        type="text"
-        value={projectKey}
-      />
-    </ValidationInput>
-  );
-}