From: Revanshu Paliwal Date: Fri, 11 Aug 2023 14:16:42 +0000 (+0200) Subject: SONAR-20086 Updating Azure PAT form to use custom hook X-Git-Tag: 10.2.0.77647~222 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=813bc9b7dc048471e7462e5698654039d260a10e;p=sonarqube.git SONAR-20086 Updating Azure PAT form to use custom hook --- diff --git a/server/sonar-web/src/main/js/apps/create/project/Azure/AzurePersonalAccessTokenForm.tsx b/server/sonar-web/src/main/js/apps/create/project/Azure/AzurePersonalAccessTokenForm.tsx index 3f71739e892..55a12b730d4 100644 --- a/server/sonar-web/src/main/js/apps/create/project/Azure/AzurePersonalAccessTokenForm.tsx +++ b/server/sonar-web/src/main/js/apps/create/project/Azure/AzurePersonalAccessTokenForm.tsx @@ -31,51 +31,52 @@ import * as React from 'react'; import { FormattedMessage } from 'react-intl'; import { translate } from '../../../../helpers/l10n'; import { AlmSettingsInstance } from '../../../../types/alm-settings'; +import { usePersonalAccessToken } from '../usePersonalAccessToken'; export interface AzurePersonalAccessTokenFormProps { almSetting: AlmSettingsInstance; - onPersonalAccessTokenCreate: (token: string) => void; - submitting?: boolean; - validationFailed: boolean; - firstConnection?: boolean; + onPersonalAccessTokenCreate: () => void; + resetPat: boolean; } function getAzurePatUrl(url: string) { return `${url.replace(/\/$/, '')}/_usersSettings/tokens`; } -export default function AzurePersonalAccessTokenForm(props: AzurePersonalAccessTokenFormProps) { +export default function AzurePersonalAccessTokenForm({ + almSetting, + resetPat, + onPersonalAccessTokenCreate, +}: AzurePersonalAccessTokenFormProps) { const { - almSetting: { url }, - submitting = false, - validationFailed, + password, firstConnection, - } = props; - - const [touched, setTouched] = React.useState(false); - React.useEffect(() => { - setTouched(false); - }, [submitting]); + validationFailed, + touched, + submitting, + validationErrorMessage, + checkingPat, + handlePasswordChange, + handleSubmit, + } = usePersonalAccessToken(almSetting, resetPat, onPersonalAccessTokenCreate); - const [token, setToken] = React.useState(''); + if (checkingPat) { + return ; + } - const isInvalid = (validationFailed && !touched) || (touched && !token); + const isInvalid = (validationFailed && !touched) || (touched && !password); + const { url } = almSetting; let errorMessage; - if (!token) { + if (!password) { errorMessage = translate('onboarding.create_project.pat_form.pat_required'); } else if (isInvalid) { - errorMessage = translate('onboarding.create_project.pat_incorrect.azure'); + errorMessage = + validationErrorMessage ?? translate('onboarding.create_project.pat_incorrect.azure'); } return ( -
) => { - e.preventDefault(); - props.onPersonalAccessTokenCreate(token); - }} - > + {translate('onboarding.create_project.pat_form.title')} @@ -112,12 +113,9 @@ export default function AzurePersonalAccessTokenForm(props: AzurePersonalAccessT id="personal_access_token" minLength={1} name="personal_access_token" - onChange={(e: React.ChangeEvent) => { - setToken(e.target.value); - setTouched(true); - }} + onChange={handlePasswordChange} type="text" - value={token} + value={password} size="large" isInvalid={isInvalid} /> diff --git a/server/sonar-web/src/main/js/apps/create/project/Azure/AzureProjectCreate.tsx b/server/sonar-web/src/main/js/apps/create/project/Azure/AzureProjectCreate.tsx index 3dfad9a6ed9..1ed1577464c 100644 --- a/server/sonar-web/src/main/js/apps/create/project/Azure/AzureProjectCreate.tsx +++ b/server/sonar-web/src/main/js/apps/create/project/Azure/AzureProjectCreate.tsx @@ -19,11 +19,9 @@ */ import * as React from 'react'; import { - checkPersonalAccessTokenIsValid, getAzureProjects, getAzureRepositories, searchAzureRepositories, - setAlmPersonalAccessToken, setupAzureProjectCreation, } from '../../../../api/alm-integrations'; import { Location, Router } from '../../../../components/hoc/withRouter'; @@ -31,7 +29,6 @@ import { AzureProject, AzureRepository } from '../../../../types/alm-integration import { AlmSettingsInstance } from '../../../../types/alm-settings'; import { Dict } from '../../../../types/types'; import { CreateProjectApiCallback } from '../types'; -import { tokenExistedBefore } from '../utils'; import AzureCreateProjectRenderer from './AzureProjectCreateRenderer'; interface Props { @@ -46,16 +43,13 @@ interface Props { interface State { loading: boolean; loadingRepositories: Dict; - patIsValid?: boolean; projects?: AzureProject[]; repositories: Dict; searching?: boolean; searchResults?: AzureRepository[]; searchQuery?: string; selectedAlmInstance?: AlmSettingsInstance; - submittingToken?: boolean; - tokenValidationFailed: boolean; - firstConnection?: boolean; + showPersonalAccessTokenForm: boolean; } export default class AzureProjectCreate extends React.PureComponent { @@ -66,10 +60,9 @@ export default class AzureProjectCreate extends React.PureComponent { - this.setState({ loading: true }); - - const { patIsValid, error } = await this.checkPersonalAccessToken(); - - let projects: AzureProject[] | undefined; - if (patIsValid) { - projects = await this.fetchAzureProjects(); - } - - const { repositories } = this.state; + const { showPersonalAccessTokenForm } = this.state; + + if (!showPersonalAccessTokenForm) { + this.setState({ loading: true }); + let projects: AzureProject[] | undefined; + try { + projects = await this.fetchAzureProjects(); + } catch (_) { + if (this.mounted) { + this.setState({ showPersonalAccessTokenForm: true, loading: false }); + } + } - let firstProjectName: string; + const { repositories } = this.state; - if (projects && projects.length > 0) { - firstProjectName = projects[0].name; + let firstProjectName: string; - this.setState(({ loadingRepositories }) => ({ - loadingRepositories: { ...loadingRepositories, [firstProjectName]: true }, - })); + if (projects && projects.length > 0) { + firstProjectName = projects[0].name; - const repos = await this.fetchAzureRepositories(firstProjectName); - repositories[firstProjectName] = repos; - } + this.setState(({ loadingRepositories }) => ({ + loadingRepositories: { ...loadingRepositories, [firstProjectName]: true }, + })); - if (this.mounted) { - this.setState(({ loadingRepositories }) => { - if (firstProjectName) { - loadingRepositories[firstProjectName] = false; - } + const repos = await this.fetchAzureRepositories(firstProjectName); + repositories[firstProjectName] = repos; + } - return { - patIsValid, - loading: false, - loadingRepositories: { ...loadingRepositories }, - projects, - repositories, - firstConnection: tokenExistedBefore(error), - }; - }); + if (this.mounted) { + this.setState(({ loadingRepositories }) => { + if (firstProjectName !== '') { + loadingRepositories[firstProjectName] = false; + } + + return { + loading: false, + loadingRepositories: { ...loadingRepositories }, + projects, + repositories, + }; + }); + } } }; @@ -224,53 +220,20 @@ export default class AzureProjectCreate extends React.PureComponent { - const { selectedAlmInstance } = this.state; - - if (!selectedAlmInstance) { - return Promise.resolve({ patIsValid: false, error: '' }); - } - - return checkPersonalAccessTokenIsValid(selectedAlmInstance.key).then(({ status, error }) => { - return { patIsValid: status, error }; - }); - }; - - handlePersonalAccessTokenCreate = async (token: string) => { - const { selectedAlmInstance } = this.state; - - if (!selectedAlmInstance || token.length < 1) { - return; - } - - this.setState({ submittingToken: true, tokenValidationFailed: false }); - - try { - await setAlmPersonalAccessToken(selectedAlmInstance.key, token); - const { patIsValid } = await this.checkPersonalAccessToken(); - - if (this.mounted) { - this.setState({ - submittingToken: false, - patIsValid, - tokenValidationFailed: !patIsValid, - }); - - if (patIsValid) { - this.cleanUrl(); - this.fetchData(); - } - } - } catch (e) { - if (this.mounted) { - this.setState({ submittingToken: false }); - } - } + handlePersonalAccessTokenCreate = async () => { + this.setState({ showPersonalAccessTokenForm: false }); + this.cleanUrl(); + await this.fetchData(); }; onSelectedAlmInstanceChange = (instance: AlmSettingsInstance) => { this.setState( - { selectedAlmInstance: instance, searchResults: undefined, searchQuery: '' }, + { + selectedAlmInstance: instance, + searchResults: undefined, + searchQuery: '', + showPersonalAccessTokenForm: true, + }, () => { this.fetchData().catch(() => { /* noop */ @@ -284,16 +247,13 @@ export default class AzureProjectCreate extends React.PureComponent ); } diff --git a/server/sonar-web/src/main/js/apps/create/project/Azure/AzureProjectCreateRenderer.tsx b/server/sonar-web/src/main/js/apps/create/project/Azure/AzureProjectCreateRenderer.tsx index a6e4fb2ef26..94c4ec746cd 100644 --- a/server/sonar-web/src/main/js/apps/create/project/Azure/AzureProjectCreateRenderer.tsx +++ b/server/sonar-web/src/main/js/apps/create/project/Azure/AzureProjectCreateRenderer.tsx @@ -45,7 +45,7 @@ export interface AzureProjectCreateRendererProps { loadingRepositories: Dict; onImportRepository: (resository: AzureRepository) => void; onOpenProject: (key: string) => void; - onPersonalAccessTokenCreate: (token: string) => void; + onPersonalAccessTokenCreate: () => void; onSearch: (query: string) => void; projects?: AzureProject[]; repositories: Dict; @@ -55,10 +55,8 @@ export interface AzureProjectCreateRendererProps { almInstances?: AlmSettingsInstance[]; selectedAlmInstance?: AlmSettingsInstance; showPersonalAccessTokenForm?: boolean; - submittingToken?: boolean; - tokenValidationFailed: boolean; + resetPat: boolean; onSelectedAlmInstanceChange: (instance: AlmSettingsInstance) => void; - firstConnection?: boolean; } export default function AzureProjectCreateRenderer(props: AzureProjectCreateRendererProps) { @@ -73,10 +71,8 @@ export default function AzureProjectCreateRenderer(props: AzureProjectCreateRend searchQuery, almInstances, showPersonalAccessTokenForm, - submittingToken, - tokenValidationFailed, + resetPat, selectedAlmInstance, - firstConnection, } = props; const showCountError = !loading && (!almInstances || almInstances?.length === 0); @@ -131,9 +127,7 @@ export default function AzureProjectCreateRenderer(props: AzureProjectCreateRend ) : (