aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWouter Admiraal <wouter.admiraal@sonarsource.com>2022-01-25 11:25:46 +0100
committersonartech <sonartech@sonarsource.com>2022-01-27 20:03:05 +0000
commit1d409d5db753fe003513f4e1a8d99a0fe6c1becc (patch)
tree55d7b7f5637d017d70175072ec209c68353d8d34
parentaf68aa7b419e675aaa903b8a77070b727aa71383 (diff)
downloadsonarqube-1d409d5db753fe003513f4e1a8d99a0fe6c1becc.tar.gz
sonarqube-1d409d5db753fe003513f4e1a8d99a0fe6c1becc.zip
SONAR-15782 Move application console code to core extensions
-rw-r--r--.cirrus.yml2
-rw-r--r--server/sonar-web/src/main/js/api/application.ts53
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/component/Menu.tsx15
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/Menu-test.tsx.snap34
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/component/branch-like/__tests__/__snapshots__/CurrentBranchLike-test.tsx.snap2
-rw-r--r--server/sonar-web/src/main/js/app/utils/startReactApp.tsx12
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/ApplicationBranches.tsx128
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/ApplicationConsoleApp.tsx137
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/ApplicationConsoleAppRenderer.tsx104
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/ApplicationProjectBranch.tsx59
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/ApplicationProjects.tsx233
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/BranchRowActions.tsx107
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/BranchSelectItem.tsx75
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/CreateBranchForm.tsx303
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/EditForm.tsx111
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/ProjectBranchRow.tsx138
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/__tests__/ApplicationBranches-test.tsx65
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/__tests__/ApplicationConsoleApp-test.tsx136
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/__tests__/ApplicationConsoleAppRenderer-test.tsx61
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/__tests__/ApplicationProjectBranch-test.tsx44
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/__tests__/ApplicationProjects-test.tsx105
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/__tests__/BranchRowActions-test.tsx39
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/__tests__/BranchSelectItem-test.tsx37
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/__tests__/CreateBranchForm-test.tsx132
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/__tests__/EditForm-test.tsx61
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/__tests__/ProjectBranchRow-test.tsx41
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/ApplicationBranches-test.tsx.snap217
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/ApplicationConsoleApp-test.tsx.snap73
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/ApplicationConsoleAppRenderer-test.tsx.snap265
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/ApplicationProjectBranch-test.tsx.snap83
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/ApplicationProjects-test.tsx.snap75
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/BranchRowActions-test.tsx.snap15
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/BranchSelectItem-test.tsx.snap22
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/CreateBranchForm-test.tsx.snap12
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/EditForm-test.tsx.snap77
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/ProjectBranchRow-test.tsx.snap59
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/routes.ts28
-rw-r--r--server/sonar-web/src/main/js/apps/application-console/utils.ts28
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/__tests__/ApplicationCreation-test.tsx2
-rw-r--r--server/sonar-web/src/main/js/helpers/mocks/application.ts27
-rw-r--r--server/sonar-web/src/main/js/helpers/urls.ts5
-rw-r--r--sonar-core/src/main/resources/org/sonar/l10n/core.properties21
42 files changed, 20 insertions, 3223 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index d49d2fd4d00..b50b600b491 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -122,6 +122,7 @@ eslint_report_cache_template: &ESLINT_REPORT_CACHE_TEMPLATE
- private/core-extension-securityreport/eslint-report/
- private/core-extension-license/eslint-report/
- private/core-extension-governance/eslint-report/
+ - private/core-extension-developer-server/eslint-report/
fingerprint_script: echo $CIRRUS_BUILD_ID
jest_report_cache_template: &JEST_REPORT_CACHE_TEMPLATE
@@ -131,6 +132,7 @@ jest_report_cache_template: &JEST_REPORT_CACHE_TEMPLATE
- private/core-extension-securityreport/coverage/
- private/core-extension-license/coverage/
- private/core-extension-governance/coverage/
+ - private/core-extension-developer-server/coverage/
fingerprint_script: echo $CIRRUS_BUILD_ID
junit_report_cache_template: &JUNIT_REPORT_CACHE_TEMPLATE
diff --git a/server/sonar-web/src/main/js/api/application.ts b/server/sonar-web/src/main/js/api/application.ts
index 42518728ba0..209c67af262 100644
--- a/server/sonar-web/src/main/js/api/application.ts
+++ b/server/sonar-web/src/main/js/api/application.ts
@@ -19,7 +19,7 @@
*/
import throwGlobalError from '../app/utils/throwGlobalError';
import { getJSON, post, postJSON } from '../helpers/request';
-import { Application, ApplicationPeriod, ApplicationProject } from '../types/application';
+import { Application, ApplicationPeriod } from '../types/application';
import { Visibility } from '../types/component';
export function getApplicationLeak(
@@ -39,51 +39,6 @@ export function getApplicationDetails(application: string, branch?: string): Pro
);
}
-export function addApplicationBranch(data: {
- application: string;
- branch: string;
- project: string[];
- projectBranch: string[];
-}) {
- return post('/api/applications/create_branch', data).catch(throwGlobalError);
-}
-
-export function updateApplicationBranch(data: {
- application: string;
- branch: string;
- name: string;
- project: string[];
- projectBranch: string[];
-}) {
- return post('/api/applications/update_branch', data).catch(throwGlobalError);
-}
-
-export function deleteApplicationBranch(application: string, branch: string) {
- return post('/api/applications/delete_branch', { application, branch }).catch(throwGlobalError);
-}
-
-export function getApplicationProjects(data: {
- application: string;
- p?: number;
- ps?: number;
- q?: string;
- selected: string;
-}): Promise<{ paging: T.Paging; projects: ApplicationProject[] }> {
- return getJSON('/api/applications/search_projects', data).catch(throwGlobalError);
-}
-
-export function addProjectToApplication(application: string, project: string) {
- return post('/api/applications/add_project', { application, project }).catch(throwGlobalError);
-}
-
-export function removeProjectFromApplication(application: string, project: string) {
- return post('/api/applications/remove_project', { application, project }).catch(throwGlobalError);
-}
-
-export function refreshApplication(key: string) {
- return post('/api/applications/refresh', { key }).catch(throwGlobalError);
-}
-
export function createApplication(
name: string,
description: string,
@@ -105,9 +60,3 @@ export function createApplication(
export function deleteApplication(application: string) {
return post('/api/applications/delete', { application }).catch(throwGlobalError);
}
-
-export function editApplication(application: string, name: string, description: string) {
- return post('/api/applications/update', { name, description, application }).catch(
- throwGlobalError
- );
-}
diff --git a/server/sonar-web/src/main/js/app/components/nav/component/Menu.tsx b/server/sonar-web/src/main/js/app/components/nav/component/Menu.tsx
index 4cb44009b46..dead2fed58b 100644
--- a/server/sonar-web/src/main/js/app/components/nav/component/Menu.tsx
+++ b/server/sonar-web/src/main/js/app/components/nav/component/Menu.tsx
@@ -36,7 +36,6 @@ import { ComponentQualifier, isPortfolioLike } from '../../../../types/component
import './Menu.css';
const SETTINGS_URLS = [
- '/application/console',
'/project/admin',
'/project/baseline',
'/project/branches',
@@ -319,7 +318,6 @@ export class Menu extends React.PureComponent<Props> {
this.renderSettingsLink(query, isApplication, isPortfolio),
this.renderBranchesLink(query, isProject),
this.renderBaselineLink(query, isApplication, isPortfolio),
- this.renderConsoleAppLink(query, isApplication),
this.renderReportSettingsLink(query, isApplication),
...this.renderAdminExtensions(query, isApplication),
this.renderImportExportLink(query, isProject),
@@ -412,19 +410,6 @@ export class Menu extends React.PureComponent<Props> {
);
};
- renderConsoleAppLink = (query: Query, isApplication: boolean) => {
- if (!isApplication) {
- return null;
- }
- return (
- <li key="app-console">
- <Link activeClassName="active" to={{ pathname: '/application/console', query }}>
- {translate('application_console.page')}
- </Link>
- </li>
- );
- };
-
renderReportSettingsLink = (query: Query, isApplication: boolean) => {
const extensions = this.getConfiguration().extensions || [];
const hasGovernance = extensions.find(e => e.key === 'governance/console');
diff --git a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/Menu-test.tsx.snap b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/Menu-test.tsx.snap
index e97e4aa5b53..87467c85c81 100644
--- a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/Menu-test.tsx.snap
+++ b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/Menu-test.tsx.snap
@@ -92,23 +92,6 @@ exports[`should disable links if application has inaccessible projects 1`] = `
style={Object {}}
to={
Object {
- "pathname": "/application/console",
- "query": Object {
- "id": "foo",
- },
- }
- }
- >
- application_console.page
- </Link>
- </li>
- <li>
- <Link
- activeClassName="active"
- onlyActiveOnIndex={false}
- style={Object {}}
- to={
- Object {
"pathname": "/project/deletion",
"query": Object {
"id": "foo",
@@ -1112,23 +1095,6 @@ exports[`should work for qualifier: APP, false 1`] = `
style={Object {}}
to={
Object {
- "pathname": "/application/console",
- "query": Object {
- "id": "foo",
- },
- }
- }
- >
- application_console.page
- </Link>
- </li>
- <li>
- <Link
- activeClassName="active"
- onlyActiveOnIndex={false}
- style={Object {}}
- to={
- Object {
"pathname": "/project/deletion",
"query": Object {
"id": "foo",
diff --git a/server/sonar-web/src/main/js/app/components/nav/component/branch-like/__tests__/__snapshots__/CurrentBranchLike-test.tsx.snap b/server/sonar-web/src/main/js/app/components/nav/component/branch-like/__tests__/__snapshots__/CurrentBranchLike-test.tsx.snap
index 231a3776bc6..1548a5317c3 100644
--- a/server/sonar-web/src/main/js/app/components/nav/component/branch-like/__tests__/__snapshots__/CurrentBranchLike-test.tsx.snap
+++ b/server/sonar-web/src/main/js/app/components/nav/component/branch-like/__tests__/__snapshots__/CurrentBranchLike-test.tsx.snap
@@ -81,7 +81,7 @@ exports[`applications should render correctly when there is only one branch and
style={Object {}}
to={
Object {
- "pathname": "/application/console",
+ "pathname": "/project/admin/extension/developer-server/application-console",
"query": Object {
"id": "my-project",
},
diff --git a/server/sonar-web/src/main/js/app/utils/startReactApp.tsx b/server/sonar-web/src/main/js/app/utils/startReactApp.tsx
index c9b4d492a54..40c777ca892 100644
--- a/server/sonar-web/src/main/js/app/utils/startReactApp.tsx
+++ b/server/sonar-web/src/main/js/app/utils/startReactApp.tsx
@@ -27,7 +27,6 @@ import { IntlProvider } from 'react-intl';
import { Provider } from 'react-redux';
import { IndexRoute, Redirect, Route, RouteConfig, RouteProps, Router } from 'react-router';
import accountRoutes from '../../apps/account/routes';
-import applicationConsoleRoutes from '../../apps/application-console/routes';
import applicationSettingsRoutes from '../../apps/application-settings/routes';
import auditLogsRoutes from '../../apps/audit-logs/routes';
import backgroundTasksRoutes from '../../apps/background-tasks/routes';
@@ -115,6 +114,16 @@ function renderRedirects() {
/>
<Route
+ path="/application/console"
+ onEnter={(nextState, replace) => {
+ replace({
+ pathname: '/project/admin/extension/developer-server/application-console',
+ query: { id: nextState.location.query.id }
+ });
+ }}
+ />
+
+ <Route
path="/issues/search"
onEnter={(_, replace) => {
replace(`/issues${window.location.hash}`);
@@ -217,7 +226,6 @@ function renderComponentRoutes() {
<RouteWithChildRoutes path="project/import_export" childRoutes={projectDumpRoutes} />
<RouteWithChildRoutes path="project/settings" childRoutes={settingsRoutes} />
<RouteWithChildRoutes path="project_roles" childRoutes={projectPermissionsRoutes} />
- <RouteWithChildRoutes path="application/console" childRoutes={applicationConsoleRoutes} />
<RouteWithChildRoutes path="application/settings" childRoutes={applicationSettingsRoutes} />
<RouteWithChildRoutes path="project/webhooks" childRoutes={webhooksRoutes} />
<Route
diff --git a/server/sonar-web/src/main/js/apps/application-console/ApplicationBranches.tsx b/server/sonar-web/src/main/js/apps/application-console/ApplicationBranches.tsx
deleted file mode 100644
index 70360060872..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/ApplicationBranches.tsx
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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 * as React from 'react';
-import { Button } from '../../components/controls/buttons';
-import { Alert } from '../../components/ui/Alert';
-import { translate } from '../../helpers/l10n';
-import { Application } from '../../types/application';
-import ApplicationProjectBranch from './ApplicationProjectBranch';
-import CreateBranchForm from './CreateBranchForm';
-import { ApplicationBranch } from './utils';
-
-interface Props {
- application: Application;
- canBrowseAllChildProjects: boolean;
- onUpdateBranches: (branches: ApplicationBranch[]) => void;
-}
-
-interface State {
- creating: boolean;
-}
-
-export default class ApplicationBranches extends React.PureComponent<Props, State> {
- state: State = { creating: false };
-
- handleCreate = (branch: ApplicationBranch) => {
- this.props.onUpdateBranches([...this.props.application.branches, branch]);
- };
-
- handleCreateFormClose = () => {
- this.setState({ creating: false });
- };
-
- handleCreateClick = () => {
- this.setState({ creating: true });
- };
-
- canCreateBranches = () => {
- return (
- this.props.application.projects &&
- this.props.application.projects.some(p => Boolean(p.enabled))
- );
- };
-
- renderBranches(createEnable: boolean, readonly: boolean) {
- const { application } = this.props;
- if (!createEnable) {
- return (
- <div className="app-branches-list">
- <p className="text-center big-spacer-top">
- {translate('application_console.branches.no_branches')}
- </p>
- </div>
- );
- }
- return (
- <div className="app-branches-list">
- <table className="data zebra">
- <tbody>
- {application.branches.map(branch => (
- <ApplicationProjectBranch
- application={application}
- branch={branch}
- key={branch.name}
- onUpdateBranches={this.props.onUpdateBranches}
- readonly={readonly}
- />
- ))}
- </tbody>
- </table>
- </div>
- );
- }
-
- render() {
- const { application, canBrowseAllChildProjects } = this.props;
- const createEnable = this.canCreateBranches();
- const readonly = !canBrowseAllChildProjects;
- return (
- <div className="app-branches-console">
- {readonly && (
- <Alert className="huge-spacer-top" variant="warning">
- {translate('application_console.branches.cannot_access_all_child_projects')}
- </Alert>
- )}
-
- <div className="boxed-group-actions">
- <Button disabled={!createEnable || readonly} onClick={this.handleCreateClick}>
- {translate('application_console.branches.create')}
- </Button>
- </div>
- <h2
- className="text-limited big-spacer-top"
- title={translate('application_console.branches')}>
- {translate('application_console.branches')}
- </h2>
- <p>{translate('application_console.branches.help')}</p>
-
- {this.renderBranches(createEnable, readonly)}
-
- {this.state.creating && (
- <CreateBranchForm
- application={application}
- enabledProjectsKey={application.projects.map(p => p.key)}
- onClose={this.handleCreateFormClose}
- onCreate={this.handleCreate}
- />
- )}
- </div>
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/apps/application-console/ApplicationConsoleApp.tsx b/server/sonar-web/src/main/js/apps/application-console/ApplicationConsoleApp.tsx
deleted file mode 100644
index 21b7bac88ee..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/ApplicationConsoleApp.tsx
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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 { Location } from 'history';
-import * as React from 'react';
-import { InjectedRouter } from 'react-router';
-import { editApplication, getApplicationDetails, refreshApplication } from '../../api/application';
-import addGlobalSuccessMessage from '../../app/utils/addGlobalSuccessMessage';
-import { translate } from '../../helpers/l10n';
-import { Application, ApplicationProject } from '../../types/application';
-import ApplicationConsoleAppRenderer from './ApplicationConsoleAppRenderer';
-import { ApplicationBranch } from './utils';
-
-interface Props {
- component: Pick<T.Component, 'key' | 'canBrowseAllChildProjects'>;
- location: Location;
- router: Pick<InjectedRouter, 'replace'>;
-}
-
-interface State {
- application?: Application;
- loading: boolean;
-}
-
-export default class ApplicationConsoleApp extends React.PureComponent<Props, State> {
- mounted = false;
-
- state: State = {
- loading: false
- };
-
- componentDidMount() {
- this.mounted = true;
- this.fetchDetails();
- }
-
- componentDidUpdate(prevProps: Props) {
- if (prevProps.component.key !== this.props.component.key) {
- this.fetchDetails();
- }
- }
-
- componentWillUnmount() {
- this.mounted = false;
- }
-
- updateApplicationState = (buildNewFields: (prevApp: Application) => Partial<Application>) => {
- this.setState(state => {
- if (state.application) {
- return { application: { ...state.application, ...buildNewFields(state.application) } };
- }
-
- return null;
- });
- };
-
- fetchDetails = async () => {
- try {
- const application = await getApplicationDetails(this.props.component.key);
- if (this.mounted) {
- this.setState({ application, loading: false });
- }
- } catch {
- if (this.mounted) {
- this.setState({ loading: false });
- }
- }
- };
-
- handleRefreshClick = async () => {
- if (this.state.application) {
- await refreshApplication(this.state.application.key);
- addGlobalSuccessMessage(translate('application_console.refresh_started'));
- }
- };
-
- handleEdit = async (name: string, description: string) => {
- if (this.state.application) {
- await editApplication(this.state.application.key, name, description);
- }
- if (this.mounted) {
- this.updateApplicationState(() => ({ name, description }));
- }
- };
-
- handleAddProject = (project: ApplicationProject) => {
- this.updateApplicationState(prevApp => ({ projects: [...prevApp.projects, project] }));
- };
-
- handleRemoveProject = (projectKey: string) => {
- this.updateApplicationState(prevApp => ({
- projects: prevApp.projects.filter(p => p.key !== projectKey)
- }));
- };
-
- handleUpdateBranches = (branches: ApplicationBranch[]) => {
- this.updateApplicationState(() => ({ branches }));
- };
-
- render() {
- const { component } = this.props;
- const { application, loading } = this.state;
- if (!application) {
- // when application is not found
- return null;
- }
-
- return (
- <ApplicationConsoleAppRenderer
- loading={loading}
- application={application}
- canBrowseAllChildProjects={Boolean(component.canBrowseAllChildProjects)}
- onAddProject={this.handleAddProject}
- onEdit={this.handleEdit}
- onRefresh={this.handleRefreshClick}
- onRemoveProject={this.handleRemoveProject}
- onUpdateBranches={this.handleUpdateBranches}
- />
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/apps/application-console/ApplicationConsoleAppRenderer.tsx b/server/sonar-web/src/main/js/apps/application-console/ApplicationConsoleAppRenderer.tsx
deleted file mode 100644
index 207ee55edc6..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/ApplicationConsoleAppRenderer.tsx
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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 * as React from 'react';
-import { Button } from '../../components/controls/buttons';
-import { translate } from '../../helpers/l10n';
-import { Application, ApplicationProject } from '../../types/application';
-import { Branch } from '../../types/branch-like';
-import ApplicationBranches from './ApplicationBranches';
-import ApplicationProjects from './ApplicationProjects';
-import EditForm from './EditForm';
-
-export interface ApplicationConsoleAppRendererProps {
- loading: boolean;
- application: Application;
- canBrowseAllChildProjects: boolean;
- onAddProject: (project: ApplicationProject) => void;
- onRefresh: () => void;
- onEdit: (name: string, description: string) => Promise<void>;
- onRemoveProject: (projectKey: string) => void;
- onUpdateBranches: (branches: Branch[]) => void;
-}
-
-export default function ApplicationConsoleAppRenderer(props: ApplicationConsoleAppRendererProps) {
- const [editing, setEditing] = React.useState(false);
-
- const { application, canBrowseAllChildProjects, loading } = props;
-
- if (loading) {
- return <i className="spinner spacer" />;
- }
-
- return (
- <div className="page page-limited">
- <div className="boxed-group" id="view-details">
- <div className="boxed-group-actions">
- <Button
- className="little-spacer-right"
- id="view-details-edit"
- onClick={() => setEditing(true)}>
- {translate('edit')}
- </Button>
- <Button className="little-spacer-right" onClick={props.onRefresh}>
- {translate('application_console.recompute')}
- </Button>
- </div>
-
- <header className="boxed-group-header" id="view-details-header">
- <h2 className="text-limited" title={application.name}>
- {application.name}
- </h2>
- </header>
-
- <div className="boxed-group-inner" id="view-details-content">
- <div className="big-spacer-bottom">
- {application.description && (
- <div className="little-spacer-bottom">{application.description}</div>
- )}
- <div className="subtitle">
- {translate('key')}: {application.key}
- </div>
- </div>
-
- <ApplicationProjects
- onAddProject={props.onAddProject}
- onRemoveProject={props.onRemoveProject}
- application={application}
- />
-
- <ApplicationBranches
- application={application}
- canBrowseAllChildProjects={canBrowseAllChildProjects}
- onUpdateBranches={props.onUpdateBranches}
- />
- </div>
-
- {editing && (
- <EditForm
- header={translate('application_console.edit')}
- onClose={() => setEditing(false)}
- onEdit={props.onEdit}
- application={application}
- />
- )}
- </div>
- </div>
- );
-}
diff --git a/server/sonar-web/src/main/js/apps/application-console/ApplicationProjectBranch.tsx b/server/sonar-web/src/main/js/apps/application-console/ApplicationProjectBranch.tsx
deleted file mode 100644
index 15b74069735..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/ApplicationProjectBranch.tsx
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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 * as React from 'react';
-import BranchIcon from '../../components/icons/BranchIcon';
-import { translate } from '../../helpers/l10n';
-import { Application } from '../../types/application';
-import BranchRowActions from './BranchRowActions';
-import { ApplicationBranch } from './utils';
-
-export interface ApplicationProjectBranchProps {
- application: Application;
- branch: ApplicationBranch;
- onUpdateBranches: (branches: Array<ApplicationBranch>) => void;
- readonly: boolean;
-}
-
-export default function ApplicationProjectBranch(props: ApplicationProjectBranchProps) {
- const { application, branch, readonly } = props;
-
- return (
- <tr>
- <td>
- <BranchIcon className="little-spacer-right" />
- {branch.name}
- {branch.isMain && (
- <span className="badge spacer-left">
- {translate('application_console.branches.main_branch')}
- </span>
- )}
- </td>
- <td className="thin nowrap">
- {!branch.isMain && !readonly && (
- <BranchRowActions
- application={application}
- branch={branch}
- onUpdateBranches={props.onUpdateBranches}
- />
- )}
- </td>
- </tr>
- );
-}
diff --git a/server/sonar-web/src/main/js/apps/application-console/ApplicationProjects.tsx b/server/sonar-web/src/main/js/apps/application-console/ApplicationProjects.tsx
deleted file mode 100644
index c7ca29443b0..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/ApplicationProjects.tsx
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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 { find, without } from 'lodash';
-import * as React from 'react';
-import {
- addProjectToApplication,
- getApplicationProjects,
- removeProjectFromApplication
-} from '../../api/application';
-import SelectList, {
- SelectListFilter,
- SelectListSearchParams
-} from '../../components/controls/SelectList';
-import Tooltip from '../../components/controls/Tooltip';
-import QualifierIcon from '../../components/icons/QualifierIcon';
-import WarningIcon from '../../components/icons/WarningIcon';
-import { translate } from '../../helpers/l10n';
-import { Application, ApplicationProject } from '../../types/application';
-
-interface Props {
- onAddProject?: (project: ApplicationProject) => void;
- onRemoveProject?: (projectKey: string) => void;
- application: Application;
-}
-
-interface State {
- disabledProjects: string[];
- lastSearchParams: SelectListSearchParams & { applicationKey: string };
- needToReload: boolean;
- projects: Array<ApplicationProject>;
- projectsTotalCount?: number;
- selectedProjects: string[];
-}
-
-export default class ApplicationProjects extends React.PureComponent<Props, State> {
- mounted = false;
-
- constructor(props: Props) {
- super(props);
-
- this.state = {
- disabledProjects: [],
- lastSearchParams: {
- applicationKey: props.application.key,
- query: '',
- filter: SelectListFilter.Selected
- },
- needToReload: false,
- projects: [],
- selectedProjects: []
- };
- }
-
- componentDidMount() {
- this.mounted = true;
- }
-
- componentDidUpdate(prevProps: Props) {
- if (prevProps.application.key !== this.props.application.key) {
- this.setState(
- prevState => {
- return {
- lastSearchParams: {
- ...prevState.lastSearchParams,
- applicationKey: this.props.application.key
- }
- };
- },
- () => this.fetchProjects(this.state.lastSearchParams)
- );
- }
- }
-
- componentWillUnmount() {
- this.mounted = false;
- }
-
- loadApplicationProjects = (searchParams: SelectListSearchParams) =>
- getApplicationProjects({
- application: this.state.lastSearchParams.applicationKey,
- p: searchParams.page,
- ps: searchParams.pageSize,
- q: searchParams.query !== '' ? searchParams.query : undefined,
- selected: searchParams.filter
- });
-
- fetchProjects = (searchParams: SelectListSearchParams) =>
- this.loadApplicationProjects(searchParams).then(data => {
- if (this.mounted) {
- this.setState(prevState => {
- const more = searchParams.page != null && searchParams.page > 1;
-
- const { projects, selectedProjects, disabledProjects } = this.dealWithProjects(
- data,
- more,
- prevState
- );
-
- return {
- disabledProjects,
- lastSearchParams: { ...prevState.lastSearchParams, ...searchParams },
- needToReload: false,
- projects,
- projectsTotalCount: data.paging.total,
- selectedProjects
- };
- });
- }
- });
-
- dealWithProjects = (
- data: { projects: Array<ApplicationProject>; paging: T.Paging },
- more: boolean,
- prevState: Readonly<State>
- ) => {
- const projects = more ? [...prevState.projects, ...data.projects] : data.projects;
-
- const newSelectedProjects = data.projects
- .filter(project => project.selected)
- .map(project => project.key);
- const selectedProjects = more
- ? [...prevState.selectedProjects, ...newSelectedProjects]
- : newSelectedProjects;
-
- const disabledProjects = more ? [...prevState.disabledProjects] : [];
-
- return {
- disabledProjects,
- projects,
- selectedProjects
- };
- };
-
- handleSelect = (projectKey: string) => {
- return addProjectToApplication(this.props.application.key, projectKey).then(() => {
- if (this.mounted) {
- this.setState(state => {
- const project = state.projects.find(p => p.key === projectKey);
- if (project && this.props.onAddProject) {
- this.props.onAddProject(project);
- }
- return {
- needToReload: true,
- selectedProjects: [...state.selectedProjects, projectKey]
- };
- });
- }
- });
- };
-
- handleUnselect = (projectKey: string) => {
- return removeProjectFromApplication(this.props.application.key, projectKey).then(() => {
- if (this.mounted) {
- this.setState(state => {
- if (this.props.onRemoveProject) {
- this.props.onRemoveProject(projectKey);
- }
- return {
- needToReload: true,
- selectedProjects: without(state.selectedProjects, projectKey)
- };
- });
- }
- });
- };
-
- renderElement = (projectKey: string) => {
- const project = find(this.state.projects, { key: projectKey });
- if (project === undefined) {
- return '';
- }
-
- return (
- <div
- className={classNames('views-project-item display-flex-center little-padded', {
- 'bg-warning': !project.accessible
- })}>
- {!project.accessible ? (
- <Tooltip overlay={translate('application_console.project_inaccessible')}>
- <WarningIcon className="spacer-right" />
- </Tooltip>
- ) : (
- <QualifierIcon className="spacer-right" qualifier="TRK" />
- )}
- <div>
- <div title={project.name}>{project.name}</div>
- <div className="note">{project.key}</div>
- </div>
- </div>
- );
- };
-
- render() {
- const { projects, selectedProjects } = this.state;
-
- return (
- <SelectList
- disabledElements={this.state.disabledProjects}
- elements={projects.map(project => project.key)}
- elementsTotalCount={this.state.projectsTotalCount}
- needToReload={
- this.state.needToReload &&
- this.state.lastSearchParams &&
- this.state.lastSearchParams.filter !== SelectListFilter.All
- }
- onSearch={this.fetchProjects}
- onSelect={this.handleSelect}
- onUnselect={this.handleUnselect}
- renderElement={this.renderElement}
- selectedElements={selectedProjects}
- withPaging={true}
- />
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/apps/application-console/BranchRowActions.tsx b/server/sonar-web/src/main/js/apps/application-console/BranchRowActions.tsx
deleted file mode 100644
index c62245f90e2..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/BranchRowActions.tsx
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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 { without } from 'lodash';
-import * as React from 'react';
-import { deleteApplicationBranch } from '../../api/application';
-import ActionsDropdown, { ActionsDropdownItem } from '../../components/controls/ActionsDropdown';
-import ConfirmButton from '../../components/controls/ConfirmButton';
-import { translate, translateWithParameters } from '../../helpers/l10n';
-import { Application } from '../../types/application';
-import CreateBranchForm from './CreateBranchForm';
-import { ApplicationBranch } from './utils';
-
-interface Props {
- application: Application;
- branch: ApplicationBranch;
- onUpdateBranches: (branches: Array<ApplicationBranch>) => void;
-}
-
-interface State {
- isUpdating: boolean;
-}
-
-export default class BranchRowActions extends React.PureComponent<Props, State> {
- state: State = { isUpdating: false };
-
- handleDelete = () => {
- const { application, branch } = this.props;
- return deleteApplicationBranch(application.key, branch.name).then(() => {
- this.props.onUpdateBranches(without(application.branches, branch));
- });
- };
-
- handleUpdate = (newBranchName: string) => {
- this.props.onUpdateBranches(
- this.props.application.branches.map(branch => {
- if (branch.name === this.props.branch.name) {
- branch.name = newBranchName;
- }
- return branch;
- })
- );
- };
-
- handleCloseForm = () => {
- this.setState({ isUpdating: false });
- };
-
- handleUpdateClick = () => {
- this.setState({ isUpdating: true });
- };
-
- render() {
- return (
- <>
- <ConfirmButton
- confirmButtonText={translate('delete')}
- isDestructive={true}
- modalBody={translateWithParameters(
- 'application_console.branches.delete.warning_x',
- this.props.branch.name
- )}
- modalHeader={translate('application_console.branches.delete')}
- onConfirm={this.handleDelete}>
- {({ onClick }) => (
- <ActionsDropdown>
- <ActionsDropdownItem onClick={this.handleUpdateClick}>
- {translate('edit')}
- </ActionsDropdownItem>
- <ActionsDropdownItem destructive={true} onClick={onClick}>
- {translate('delete')}
- </ActionsDropdownItem>
- </ActionsDropdown>
- )}
- </ConfirmButton>
-
- {this.state.isUpdating && (
- <CreateBranchForm
- application={this.props.application}
- branch={this.props.branch}
- enabledProjectsKey={this.props.application.projects
- .filter(p => p.enabled)
- .map(p => p.key)}
- onClose={this.handleCloseForm}
- onUpdate={this.handleUpdate}
- />
- )}
- </>
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/apps/application-console/BranchSelectItem.tsx b/server/sonar-web/src/main/js/apps/application-console/BranchSelectItem.tsx
deleted file mode 100644
index 439bc4d742c..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/BranchSelectItem.tsx
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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 * as React from 'react';
-import Tooltip from '../../components/controls/Tooltip';
-import BranchIcon from '../../components/icons/BranchIcon';
-
-export interface Option {
- label: string;
- type: string;
- value: string;
-}
-
-interface Props {
- option: Option;
- children?: React.ReactNode;
- className?: string;
- isFocused?: boolean;
- onFocus: (option: Option, event: React.SyntheticEvent<HTMLElement>) => void;
- onSelect: (option: Option, event: React.SyntheticEvent<HTMLElement>) => void;
-}
-
-export default class BranchSelectItem extends React.PureComponent<Props> {
- handleMouseDown = (event: React.MouseEvent<HTMLElement>) => {
- event.preventDefault();
- event.stopPropagation();
- this.props.onSelect(this.props.option, event);
- };
-
- handleMouseEnter = (event: React.MouseEvent<HTMLElement>) => {
- this.props.onFocus(this.props.option, event);
- };
-
- handleMouseMove = (event: React.MouseEvent<HTMLElement>) => {
- if (this.props.isFocused) {
- return;
- }
- this.props.onFocus(this.props.option, event);
- };
-
- render() {
- const { option } = this.props;
- return (
- <Tooltip overlay={option.label} placement="left">
- <div
- className={this.props.className}
- onMouseDown={this.handleMouseDown}
- onMouseEnter={this.handleMouseEnter}
- onMouseMove={this.handleMouseMove}
- role="listitem">
- <div>
- <BranchIcon className="little-spacer-right" />
- {option.label}
- </div>
- </div>
- </Tooltip>
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/apps/application-console/CreateBranchForm.tsx b/server/sonar-web/src/main/js/apps/application-console/CreateBranchForm.tsx
deleted file mode 100644
index 8b25d018c77..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/CreateBranchForm.tsx
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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 { some, without } from 'lodash';
-import * as React from 'react';
-import {
- addApplicationBranch,
- getApplicationDetails,
- updateApplicationBranch
-} from '../../api/application';
-import { ResetButtonLink, SubmitButton } from '../../components/controls/buttons';
-import SimpleModal from '../../components/controls/SimpleModal';
-import DeferredSpinner from '../../components/ui/DeferredSpinner';
-import MandatoryFieldMarker from '../../components/ui/MandatoryFieldMarker';
-import MandatoryFieldsExplanation from '../../components/ui/MandatoryFieldsExplanation';
-import { translate } from '../../helpers/l10n';
-import { Application, ApplicationProject } from '../../types/application';
-import ProjectBranchRow from './ProjectBranchRow';
-import { ApplicationBranch, SelectBranchOption } from './utils';
-
-interface Props {
- application: Application;
- branch?: ApplicationBranch;
- enabledProjectsKey: string[];
- onClose: () => void;
- onCreate?: (branch: ApplicationBranch) => void;
- onUpdate?: (name: string) => void;
-}
-
-interface BranchesList {
- [name: string]: SelectBranchOption | null;
-}
-
-interface State {
- loading: boolean;
- name: string;
- projects: ApplicationProject[];
- selected: string[];
- selectedBranches: BranchesList;
-}
-
-const MAX_PROJECTS_HEIGHT = 220;
-const PROJECT_HEIGHT = 22;
-export default class CreateBranchForm extends React.PureComponent<Props, State> {
- mounted = false;
- node?: HTMLElement | null = null;
- currentSelect?: HTMLElement | null = null;
-
- state: State = {
- loading: false,
- name: '',
- projects: [],
- selected: [],
- selectedBranches: {}
- };
-
- componentDidMount() {
- this.mounted = true;
- const { application } = this.props;
- const branch = this.props.branch ? this.props.branch.name : undefined;
- this.setState({ loading: true });
- getApplicationDetails(application.key, branch).then(
- ({ projects }) => {
- if (this.mounted) {
- const enabledProjects = projects.filter(p =>
- this.props.enabledProjectsKey.includes(p.key)
- );
- const selected = enabledProjects.filter(p => p.selected).map(p => p.key);
- const selectedBranches: BranchesList = {};
- enabledProjects.forEach(p => {
- if (!p.enabled) {
- selectedBranches[p.key] = null;
- } else {
- selectedBranches[p.key] = {
- value: p.branch || '',
- label: p.branch || '',
- isMain: p.isMain || false
- };
- }
- });
- this.setState({
- name: branch || '',
- selected,
- loading: false,
- projects: enabledProjects,
- selectedBranches
- });
- }
- },
- () => {
- this.props.onClose();
- }
- );
- }
-
- componentWillUnmount() {
- this.mounted = false;
- }
-
- stopLoading = () => {
- if (this.mounted) {
- this.setState({ loading: false });
- }
- };
-
- canSubmit = () => {
- const hasUnselectedBranches = some(this.state.selectedBranches, (branch, projectKey) => {
- return !branch && this.state.selected.includes(projectKey);
- });
- return (
- !this.state.loading &&
- this.state.name.length > 0 &&
- !hasUnselectedBranches &&
- this.state.selected.length > 0
- );
- };
-
- handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
- this.setState({ name: event.currentTarget.value });
- };
-
- handleFormSubmit = async () => {
- const projectKeys = this.state.selected;
-
- const projectBranches = projectKeys.map(p => {
- const branch = this.state.selectedBranches[p];
- return !branch || branch.isMain ? '' : branch.value;
- });
-
- if (this.props.branch) {
- await updateApplicationBranch({
- application: this.props.application.key,
- branch: this.props.branch.name,
- name: this.state.name,
- project: projectKeys,
- projectBranch: projectBranches
- });
- if (this.props.onUpdate) {
- this.props.onUpdate(this.state.name);
- }
- } else {
- await addApplicationBranch({
- application: this.props.application.key,
- branch: this.state.name,
- project: projectKeys,
- projectBranch: projectBranches
- });
- if (this.props.onCreate) {
- this.props.onCreate({ name: this.state.name, isMain: false });
- }
- }
- this.props.onClose();
- };
-
- handleProjectCheck = (checked: boolean, key: string) => {
- this.setState(state => ({
- selected: checked ? [...state.selected, key] : without(state.selected, key)
- }));
- };
-
- handleBranchChange = (projectKey: string, branch: SelectBranchOption) => {
- this.setState(state => ({
- selectedBranches: { ...state.selectedBranches, [projectKey]: branch }
- }));
- };
-
- handleSelectorClose = () => {
- if (this.node) {
- this.node.classList.add('selector-hidden');
- }
- };
-
- handleSelectorDirection = (selectNode: HTMLElement, elementCount: number) => {
- if (this.node) {
- const modalTop = this.node.getBoundingClientRect().top;
- const modalHeight = this.node.offsetHeight;
- const maxSelectHeight = Math.min(MAX_PROJECTS_HEIGHT, (elementCount + 1) * PROJECT_HEIGHT);
- const selectBottom = selectNode.getBoundingClientRect().top + maxSelectHeight;
- if (selectBottom > modalTop + modalHeight) {
- this.node.classList.add('inverted-direction');
- } else {
- this.node.classList.remove('inverted-direction');
- }
- this.node.classList.remove('selector-hidden');
- }
- };
-
- renderProjectsList = () => {
- return (
- <>
- <strong className="spacer-left spacer-top">
- {translate('application_console.branches.configuration')}
- </strong>
- <p className="spacer-top big-spacer-bottom spacer-left spacer-right">
- {translate('application_console.branches.create.help')}
- </p>
- <table className="data zebra">
- <thead>
- <tr>
- <th className="thin" />
- <th className="thin">{translate('project')}</th>
- <th>{translate('branch')}</th>
- </tr>
- </thead>
- <tbody>
- {this.state.projects.map(project => (
- <ProjectBranchRow
- checked={this.state.selected.includes(project.key)}
- key={project.key}
- onChange={this.handleBranchChange}
- onCheck={this.handleProjectCheck}
- onClose={this.handleSelectorClose}
- onOpen={this.handleSelectorDirection}
- project={project}
- />
- ))}
- </tbody>
- </table>
- </>
- );
- };
-
- render() {
- const isUpdating = this.props.branch !== undefined;
- const header = translate('application_console.branches', isUpdating ? 'update' : 'create');
- return (
- <SimpleModal
- header={header}
- onClose={this.props.onClose}
- onSubmit={this.handleFormSubmit}
- size="medium">
- {({ onCloseClick, onFormSubmit, submitting }) => (
- <form className="views-form" onSubmit={onFormSubmit}>
- <div className="modal-head">
- <h2>{header}</h2>
- </div>
-
- <div
- className="modal-body modal-container selector-hidden"
- ref={node => (this.node = node)}>
- {this.state.loading ? (
- <div className="text-center big-spacer-top big-spacer-bottom">
- <i className="spinner spacer-right" />
- </div>
- ) : (
- <>
- <MandatoryFieldsExplanation className="modal-field" />
- <div className="modal-field">
- <label htmlFor="view-edit-name">
- {translate('name')}
- <MandatoryFieldMarker />
- </label>
- <input
- autoFocus={true}
- className="input-super-large"
- maxLength={250}
- name="name"
- onChange={this.handleInputChange}
- size={50}
- type="text"
- value={this.state.name}
- />
- </div>
- {this.renderProjectsList()}
- </>
- )}
- </div>
-
- <div className="modal-foot">
- <DeferredSpinner className="spacer-right" loading={submitting} />
- <SubmitButton disabled={submitting || !this.canSubmit()}>
- {translate(
- 'application_console.branches',
- isUpdating ? 'update' : 'create',
- 'verb'
- )}
- </SubmitButton>
- <ResetButtonLink onClick={onCloseClick}>
- {translate('application_console.branches.cancel')}
- </ResetButtonLink>
- </div>
- </form>
- )}
- </SimpleModal>
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/apps/application-console/EditForm.tsx b/server/sonar-web/src/main/js/apps/application-console/EditForm.tsx
deleted file mode 100644
index 6e1cd3f2033..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/EditForm.tsx
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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 * as React from 'react';
-import { ResetButtonLink, SubmitButton } from '../../components/controls/buttons';
-import SimpleModal from '../../components/controls/SimpleModal';
-import DeferredSpinner from '../../components/ui/DeferredSpinner';
-import { translate } from '../../helpers/l10n';
-import { Application } from '../../types/application';
-
-interface Props {
- header: string;
- onClose: () => void;
- onEdit: (name: string, description: string) => Promise<void>;
- application: Application;
-}
-
-interface State {
- description: string;
- name: string;
-}
-
-export default class EditForm extends React.PureComponent<Props, State> {
- constructor(props: Props) {
- super(props);
- this.state = {
- description: props.application.description || '',
- name: props.application.name
- };
- }
-
- handleNameChange = (event: React.ChangeEvent<HTMLInputElement>) => {
- this.setState({ name: event.currentTarget.value });
- };
-
- handleDescriptionChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
- this.setState({ description: event.currentTarget.value });
- };
-
- handleFormSubmit = async () => {
- await this.props.onEdit(this.state.name, this.state.description);
- this.props.onClose();
- };
-
- render() {
- return (
- <SimpleModal
- header={this.props.header}
- onClose={this.props.onClose}
- onSubmit={this.handleFormSubmit}
- size="small">
- {({ onCloseClick, onFormSubmit, submitting }) => (
- <form onSubmit={onFormSubmit}>
- <div className="modal-head">
- <h2>{this.props.header}</h2>
- </div>
-
- <div className="modal-body">
- <div className="modal-field">
- <label htmlFor="view-edit-name">{translate('name')}</label>
- <input
- autoFocus={true}
- id="view-edit-name"
- maxLength={100}
- name="name"
- onChange={this.handleNameChange}
- size={50}
- type="text"
- value={this.state.name}
- />
- </div>
- <div className="modal-field">
- <label htmlFor="view-edit-description">{translate('description')}</label>
- <textarea
- id="view-edit-description"
- name="description"
- onChange={this.handleDescriptionChange}
- value={this.state.description}
- />
- </div>
- </div>
-
- <div className="modal-foot">
- <DeferredSpinner className="spacer-right" loading={submitting} />
- <SubmitButton disabled={submitting || !this.state.name.length}>
- {translate('save')}
- </SubmitButton>
- <ResetButtonLink onClick={onCloseClick}>{translate('cancel')}</ResetButtonLink>
- </div>
- </form>
- )}
- </SimpleModal>
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/apps/application-console/ProjectBranchRow.tsx b/server/sonar-web/src/main/js/apps/application-console/ProjectBranchRow.tsx
deleted file mode 100644
index 936859b7cad..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/ProjectBranchRow.tsx
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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 { orderBy } from 'lodash';
-import * as React from 'react';
-import { getBranches } from '../../api/branches';
-import Checkbox from '../../components/controls/Checkbox';
-import SelectLegacy from '../../components/controls/SelectLegacy';
-import Tooltip from '../../components/controls/Tooltip';
-import QualifierIcon from '../../components/icons/QualifierIcon';
-import DeferredSpinner from '../../components/ui/DeferredSpinner';
-import { ApplicationProject } from '../../types/application';
-import BranchSelectItem from './BranchSelectItem';
-import { ApplicationBranch, SelectBranchOption } from './utils';
-
-interface Props {
- checked: boolean;
- onChange: (projectKey: string, branch: SelectBranchOption) => void;
- onCheck: (checked: boolean, id?: string) => void;
- onClose: () => void;
- onOpen: (selectNode: HTMLElement, elementCount: number) => void;
- project: ApplicationProject;
-}
-
-interface State {
- branches?: SelectBranchOption[];
- loading: boolean;
- selectedBranch?: SelectBranchOption;
-}
-
-export default class ProjectBranchRow extends React.PureComponent<Props, State> {
- node?: HTMLElement | null = null;
- mounted = false;
- state: State = { loading: false };
-
- componentDidMount() {
- this.mounted = true;
- }
-
- componentWillUnmount() {
- this.mounted = false;
- }
-
- parseBranches = (branches: Array<ApplicationBranch>) => {
- return orderBy(branches, [b => b.isMain, b => b.name]).map(branch => {
- return { value: branch.name, label: branch.name, isMain: branch.isMain };
- });
- };
-
- setCurrentTarget = (event: React.FocusEvent<HTMLInputElement>) => {
- this.node = event.target;
- };
-
- handleChange = (value: SelectBranchOption) => {
- this.props.onChange(this.props.project.key, value);
- this.setState({ selectedBranch: value });
- };
-
- handleOpen = () => {
- if (this.state.branches && this.node) {
- this.props.onOpen(this.node, this.state.branches.length);
- return;
- }
-
- const { project } = this.props;
- this.setState({ loading: true });
- getBranches(project.key).then(
- branchesResult => {
- const branches = this.parseBranches(branchesResult);
- if (this.node) {
- this.props.onOpen(this.node, branches.length);
- }
- if (this.mounted) {
- this.setState({ branches, loading: false });
- }
- },
- () => {
- /* Fail silently*/
- }
- );
- };
-
- render() {
- const { checked, onCheck, onClose, project } = this.props;
- const options = this.state.branches || [
- { value: project.branch, label: project.branch, isMain: project.isMain }
- ];
- const value = project.enabled
- ? this.state.selectedBranch || project.branch
- : this.state.selectedBranch;
- return (
- <tr key={project.key}>
- <td className="text-center">
- <Checkbox checked={checked} id={project.key} onCheck={onCheck} />
- </td>
- <td className="nowrap hide-overflow branch-name-row">
- <Tooltip overlay={project.name}>
- <span>
- <QualifierIcon qualifier="TRK" /> {project.name}
- </span>
- </Tooltip>
- </td>
- <td>
- <SelectLegacy
- className="width100"
- clearable={false}
- disabled={!checked}
- onChange={this.handleChange}
- onClose={onClose}
- onFocus={this.setCurrentTarget}
- onOpen={this.handleOpen}
- optionComponent={BranchSelectItem}
- options={options}
- searchable={false}
- value={value}
- />
- <DeferredSpinner className="project-branch-row-spinner" loading={this.state.loading} />
- </td>
- </tr>
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/apps/application-console/__tests__/ApplicationBranches-test.tsx b/server/sonar-web/src/main/js/apps/application-console/__tests__/ApplicationBranches-test.tsx
deleted file mode 100644
index e332a2bb0f1..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/__tests__/ApplicationBranches-test.tsx
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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 { shallow } from 'enzyme';
-import * as React from 'react';
-import { mockApplication, mockApplicationProject } from '../../../helpers/mocks/application';
-import { mockBranch, mockMainBranch } from '../../../helpers/mocks/branch-like';
-import ApplicationBranches from '../ApplicationBranches';
-
-it('should render correctly', () => {
- expect(shallowRender()).toMatchSnapshot('default');
- expect(
- shallowRender({
- application: mockApplication({ projects: [mockApplicationProject({ enabled: true })] })
- })
- ).toMatchSnapshot('can create branches');
- expect(shallowRender({ canBrowseAllChildProjects: false })).toMatchSnapshot('readonly');
- const wrapper = shallowRender();
- wrapper.setState({ creating: true });
- expect(wrapper).toMatchSnapshot('creating branch');
-});
-
-it('correctly triggers the onUpdateBranches prop', () => {
- const onUpdateBranches = jest.fn();
- const branch = mockBranch();
- const branches = [mockMainBranch()];
- const wrapper = shallowRender({ application: mockApplication({ branches }), onUpdateBranches });
- const instance = wrapper.instance();
-
- instance.handleCreateClick();
- expect(wrapper.state().creating).toBe(true);
-
- instance.handleCreateFormClose();
- expect(wrapper.state().creating).toBe(false);
-
- instance.handleCreate(branch);
- expect(onUpdateBranches).toBeCalledWith([...branches, branch]);
-});
-
-function shallowRender(props: Partial<ApplicationBranches['props']> = {}) {
- return shallow<ApplicationBranches>(
- <ApplicationBranches
- application={mockApplication()}
- canBrowseAllChildProjects={true}
- onUpdateBranches={jest.fn()}
- {...props}
- />
- );
-}
diff --git a/server/sonar-web/src/main/js/apps/application-console/__tests__/ApplicationConsoleApp-test.tsx b/server/sonar-web/src/main/js/apps/application-console/__tests__/ApplicationConsoleApp-test.tsx
deleted file mode 100644
index f5957d8578d..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/__tests__/ApplicationConsoleApp-test.tsx
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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 { shallow } from 'enzyme';
-import * as React from 'react';
-import {
- editApplication,
- getApplicationDetails,
- refreshApplication
-} from '../../../api/application';
-import addGlobalSuccessMessage from '../../../app/utils/addGlobalSuccessMessage';
-import { mockApplication, mockApplicationProject } from '../../../helpers/mocks/application';
-import { mockLocation, mockRouter } from '../../../helpers/testMocks';
-import { waitAndUpdate } from '../../../helpers/testUtils';
-import { Application } from '../../../types/application';
-import ApplicationConsoleApp from '../ApplicationConsoleApp';
-
-jest.mock('../../../api/application', () => ({
- getApplicationDetails: jest.fn().mockResolvedValue({}),
- refreshApplication: jest.fn().mockResolvedValue({}),
- editApplication: jest.fn().mockResolvedValue({})
-}));
-
-jest.mock('../../../app/utils/addGlobalSuccessMessage', () => jest.fn());
-
-it('Should render correctly', async () => {
- expect(shallowRender()).toMatchSnapshot('Empty app');
- const app = mockApplication();
- (getApplicationDetails as jest.Mock<Promise<Application>>).mockResolvedValueOnce(app);
- const wrapper = shallowRender();
- await waitAndUpdate(wrapper);
- expect(wrapper).toMatchSnapshot('With app');
- wrapper.setProps({ component: { key: '1', canBrowseAllChildProjects: true } });
- expect(wrapper).toMatchSnapshot('can browse all child projects');
-});
-
-it('Should edit application correctly', async () => {
- const app = mockApplication();
-
- (getApplicationDetails as jest.Mock<Promise<Application>>).mockRejectedValueOnce(app);
- let wrapper = shallowRender({});
- wrapper.instance().handleEdit('NEW_NAME', 'NEW_DESC');
- expect(wrapper.state().application).toBeUndefined();
-
- (getApplicationDetails as jest.Mock<Promise<Application>>).mockResolvedValueOnce(app);
- wrapper = shallowRender({});
- await waitAndUpdate(wrapper);
- await wrapper.instance().handleEdit('NEW_NAME', 'NEW_DESC');
- expect(editApplication).toBeCalledWith(app.key, 'NEW_NAME', 'NEW_DESC');
- expect(wrapper.state().application?.name).toBe('NEW_NAME');
- expect(wrapper.state().application?.description).toBe('NEW_DESC');
-});
-
-it('Should add project to application', async () => {
- const app = mockApplication();
- const project = mockApplicationProject({ key: 'FOO' });
- (getApplicationDetails as jest.Mock<Promise<Application>>).mockRejectedValueOnce(app);
- let wrapper = shallowRender({});
- wrapper.instance().handleAddProject(project);
- expect(wrapper.state().application?.projects).toBeUndefined();
-
- (getApplicationDetails as jest.Mock<Promise<Application>>).mockResolvedValueOnce(app);
- wrapper = shallowRender({});
- await waitAndUpdate(wrapper);
- wrapper.instance().handleAddProject(project);
- expect(wrapper.state().application?.projects).toContain(project);
-});
-
-it('Should remove project from application', async () => {
- const project = mockApplicationProject({ key: 'FOO' });
- const app = mockApplication({ projects: [project] });
-
- (getApplicationDetails as jest.Mock<Promise<Application>>).mockRejectedValueOnce(app);
- let wrapper = shallowRender({});
- wrapper.instance().handleRemoveProject('FOO');
- expect(wrapper.state().application?.projects).toBeUndefined();
-
- (getApplicationDetails as jest.Mock<Promise<Application>>).mockResolvedValueOnce(app);
- wrapper = shallowRender({});
- await waitAndUpdate(wrapper);
- wrapper.instance().handleRemoveProject('FOO');
- expect(wrapper.state().application?.projects.length).toBe(0);
-});
-
-it('Should update branch correctly', async () => {
- const app = mockApplication();
-
- (getApplicationDetails as jest.Mock<Promise<Application>>).mockRejectedValueOnce(app);
- let wrapper = shallowRender({});
- wrapper.instance().handleUpdateBranches([]);
- expect(wrapper.state().application).toBeUndefined();
-
- (getApplicationDetails as jest.Mock<Promise<Application>>).mockResolvedValueOnce(app);
- wrapper = shallowRender({});
- await waitAndUpdate(wrapper);
- wrapper.instance().handleUpdateBranches([]);
- expect(wrapper.state().application?.branches.length).toBe(0);
-});
-
-it('should handle refreshing', async () => {
- const app = mockApplication();
- (getApplicationDetails as jest.Mock<Promise<Application>>).mockResolvedValueOnce(app);
- const wrapper = shallowRender();
- await waitAndUpdate(wrapper);
- wrapper.instance().handleRefreshClick();
- await waitAndUpdate(wrapper);
- expect(refreshApplication).toBeCalledWith('foo');
- expect(addGlobalSuccessMessage).toBeCalled();
-});
-
-function shallowRender(props: Partial<ApplicationConsoleApp['props']> = {}) {
- return shallow<ApplicationConsoleApp>(
- <ApplicationConsoleApp
- component={{ key: '1' }}
- location={mockLocation()}
- router={mockRouter()}
- {...props}
- />
- );
-}
diff --git a/server/sonar-web/src/main/js/apps/application-console/__tests__/ApplicationConsoleAppRenderer-test.tsx b/server/sonar-web/src/main/js/apps/application-console/__tests__/ApplicationConsoleAppRenderer-test.tsx
deleted file mode 100644
index 4ba7a59e833..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/__tests__/ApplicationConsoleAppRenderer-test.tsx
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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 { shallow } from 'enzyme';
-import * as React from 'react';
-import { mockApplication } from '../../../helpers/mocks/application';
-import { click } from '../../../helpers/testUtils';
-import ApplicationConsoleAppRenderer, {
- ApplicationConsoleAppRendererProps
-} from '../ApplicationConsoleAppRenderer';
-import EditForm from '../EditForm';
-
-jest.mock('../../../app/utils/addGlobalSuccessMessage', () => jest.fn());
-
-it('should render correctly', () => {
- expect(shallowRender()).toMatchSnapshot('default');
- expect(
- shallowRender({
- application: mockApplication({ description: 'Foo bar', key: 'foo' })
- })
- ).toMatchSnapshot('can recompute');
- expect(shallowRender({ loading: true })).toMatchSnapshot('is loading');
-});
-
-it('should handle editing', () => {
- const wrapper = shallowRender();
- click(wrapper.find('#view-details-edit'));
- expect(wrapper.find(EditForm)).toMatchSnapshot('edit form');
-});
-
-function shallowRender(props: Partial<ApplicationConsoleAppRendererProps> = {}) {
- return shallow(
- <ApplicationConsoleAppRenderer
- application={mockApplication({ key: 'foo' })}
- canBrowseAllChildProjects={true}
- loading={false}
- onAddProject={jest.fn()}
- onEdit={jest.fn()}
- onRefresh={jest.fn()}
- onRemoveProject={jest.fn()}
- onUpdateBranches={jest.fn()}
- {...props}
- />
- );
-}
diff --git a/server/sonar-web/src/main/js/apps/application-console/__tests__/ApplicationProjectBranch-test.tsx b/server/sonar-web/src/main/js/apps/application-console/__tests__/ApplicationProjectBranch-test.tsx
deleted file mode 100644
index c3fafcb7b39..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/__tests__/ApplicationProjectBranch-test.tsx
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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 { shallow } from 'enzyme';
-import * as React from 'react';
-import { mockApplication } from '../../../helpers/mocks/application';
-import { mockBranch, mockMainBranch } from '../../../helpers/mocks/branch-like';
-import ApplicationProjectBranch, {
- ApplicationProjectBranchProps
-} from '../ApplicationProjectBranch';
-
-it('should render correctly', () => {
- expect(shallowRender()).toMatchSnapshot('default');
- expect(shallowRender({ branch: mockMainBranch() })).toMatchSnapshot('main branch');
- expect(shallowRender({ readonly: true })).toMatchSnapshot('readonly');
-});
-
-function shallowRender(props: Partial<ApplicationProjectBranchProps> = {}) {
- return shallow<ApplicationProjectBranchProps>(
- <ApplicationProjectBranch
- application={mockApplication()}
- branch={mockBranch()}
- onUpdateBranches={jest.fn()}
- readonly={false}
- {...props}
- />
- );
-}
diff --git a/server/sonar-web/src/main/js/apps/application-console/__tests__/ApplicationProjects-test.tsx b/server/sonar-web/src/main/js/apps/application-console/__tests__/ApplicationProjects-test.tsx
deleted file mode 100644
index 3ea49a97ba9..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/__tests__/ApplicationProjects-test.tsx
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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 { shallow } from 'enzyme';
-import * as React from 'react';
-import {
- addProjectToApplication,
- getApplicationProjects,
- removeProjectFromApplication
-} from '../../../api/application';
-import SelectList, { SelectListFilter } from '../../../components/controls/SelectList';
-import { mockApplication } from '../../../helpers/mocks/application';
-import { waitAndUpdate } from '../../../helpers/testUtils';
-import ApplicationProjects from '../ApplicationProjects';
-
-jest.mock('../../../api/application', () => ({
- getApplicationProjects: jest.fn().mockResolvedValue({
- paging: { pageIndex: 1, pageSize: 3, total: 55 },
- projects: [
- { key: 'test1', name: 'test1', accessible: true, selected: false },
- {
- key: 'test2',
- name: 'test2',
- accessible: false,
- selected: false,
- disabled: true,
- includedIn: 'foo'
- },
- { key: 'test3', name: 'test3', accessible: true, selected: true }
- ]
- }),
- addProjectToApplication: jest.fn().mockResolvedValue({}),
- removeProjectFromApplication: jest.fn().mockResolvedValue({})
-}));
-
-beforeEach(jest.clearAllMocks);
-
-it('should render correctly in application mode', async () => {
- const wrapper = shallowRender();
- wrapper
- .find(SelectList)
- .props()
- .onSearch({ query: '', filter: SelectListFilter.Selected, page: 1, pageSize: 100 });
- await waitAndUpdate(wrapper);
-
- expect(wrapper).toMatchSnapshot();
- expect(wrapper.instance().renderElement('test1')).toMatchSnapshot('render project: basic');
- expect(wrapper.instance().renderElement('test2')).toMatchSnapshot('render project: inaccessible');
- expect(wrapper.instance().renderElement('cheeseburger')).toMatchInlineSnapshot(`""`);
-
- expect(getApplicationProjects).toHaveBeenCalledWith(
- expect.objectContaining({
- application: 'foo',
- p: 1,
- ps: 100,
- q: undefined,
- selected: SelectListFilter.Selected
- })
- );
-
- wrapper.instance().handleSelect('test1');
- await waitAndUpdate(wrapper);
- expect(addProjectToApplication).toHaveBeenCalledWith('foo', 'test1');
-
- wrapper.instance().fetchProjects({ query: 'bar', filter: SelectListFilter.Selected });
- await waitAndUpdate(wrapper);
- expect(getApplicationProjects).toHaveBeenCalledWith(
- expect.objectContaining({ application: 'foo', q: 'bar', selected: SelectListFilter.Selected })
- );
-
- wrapper.instance().handleUnselect('test1');
- await waitAndUpdate(wrapper);
- expect(removeProjectFromApplication).toHaveBeenCalledWith('foo', 'test1');
-});
-
-it('should refresh properly if props changes', () => {
- const wrapper = shallowRender();
- const spy = jest.spyOn(wrapper.instance(), 'fetchProjects');
-
- wrapper.setProps({ application: { key: 'bar' } as any });
- expect(wrapper.state().lastSearchParams.applicationKey).toBe('bar');
- expect(spy).toHaveBeenCalled();
-});
-
-function shallowRender(props: Partial<ApplicationProjects['props']> = {}) {
- return shallow<ApplicationProjects>(
- <ApplicationProjects application={mockApplication()} {...props} />
- );
-}
diff --git a/server/sonar-web/src/main/js/apps/application-console/__tests__/BranchRowActions-test.tsx b/server/sonar-web/src/main/js/apps/application-console/__tests__/BranchRowActions-test.tsx
deleted file mode 100644
index a6ce3013a19..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/__tests__/BranchRowActions-test.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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 { shallow } from 'enzyme';
-import * as React from 'react';
-import { mockApplication } from '../../../helpers/mocks/application';
-import { mockBranch } from '../../../helpers/mocks/branch-like';
-import BranchRowActions from '../BranchRowActions';
-
-it('Should render correctly', () => {
- expect(shallowRender()).toMatchSnapshot();
-});
-
-function shallowRender(props: Partial<BranchRowActions['props']> = {}) {
- return shallow<BranchRowActions>(
- <BranchRowActions
- application={mockApplication()}
- branch={mockBranch()}
- onUpdateBranches={jest.fn()}
- {...props}
- />
- );
-}
diff --git a/server/sonar-web/src/main/js/apps/application-console/__tests__/BranchSelectItem-test.tsx b/server/sonar-web/src/main/js/apps/application-console/__tests__/BranchSelectItem-test.tsx
deleted file mode 100644
index 7bfb96e3cae..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/__tests__/BranchSelectItem-test.tsx
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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 { shallow } from 'enzyme';
-import * as React from 'react';
-import BranchSelectItem from '../BranchSelectItem';
-
-it('Should render correctly', () => {
- expect(shallowRender()).toMatchSnapshot();
-});
-
-function shallowRender(props: Partial<BranchSelectItem['props']> = {}) {
- return shallow<BranchSelectItem>(
- <BranchSelectItem
- option={{ label: 'test', type: 'type', value: 'value' }}
- onFocus={jest.fn()}
- onSelect={jest.fn()}
- {...props}
- />
- );
-}
diff --git a/server/sonar-web/src/main/js/apps/application-console/__tests__/CreateBranchForm-test.tsx b/server/sonar-web/src/main/js/apps/application-console/__tests__/CreateBranchForm-test.tsx
deleted file mode 100644
index 91c441bb628..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/__tests__/CreateBranchForm-test.tsx
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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 { shallow } from 'enzyme';
-import * as React from 'react';
-import { getApplicationDetails } from '../../../api/application';
-import { mockApplication, mockApplicationProject } from '../../../helpers/mocks/application';
-import { waitAndUpdate } from '../../../helpers/testUtils';
-import { Application } from '../../../types/application';
-import CreateBranchForm from '../CreateBranchForm';
-
-jest.mock('../../../api/application', () => ({
- getApplicationDetails: jest.fn().mockResolvedValue({ projects: [] }),
- addApplicationBranch: jest.fn(),
- updateApplicationBranch: jest.fn()
-}));
-
-it('Should handle submit correctly', async () => {
- const app = mockApplication();
- (getApplicationDetails as jest.Mock<Promise<Application>>).mockResolvedValueOnce(app);
- const handleClose = jest.fn();
- const handleCeate = jest.fn();
- const handleUpdate = jest.fn();
- let wrapper = shallowRender({ application: app, onClose: handleClose, onCreate: handleCeate });
- wrapper.instance().handleFormSubmit();
- await waitAndUpdate(wrapper);
- expect(handleClose).toHaveBeenCalled();
- expect(handleCeate).toHaveBeenCalled();
-
- (getApplicationDetails as jest.Mock<Promise<Application>>).mockResolvedValueOnce(app);
- wrapper = shallowRender({
- application: app,
- branch: { isMain: false, name: 'foo' },
- onUpdate: handleUpdate
- });
- wrapper.instance().handleFormSubmit();
- await waitAndUpdate(wrapper);
- expect(handleUpdate).toHaveBeenCalled();
-});
-
-it('Should render correctly', async () => {
- const app = mockApplication({
- projects: [
- mockApplicationProject({ key: '1', enabled: true }),
- mockApplicationProject({ key: '2', enabled: true }),
- mockApplicationProject({ key: '3', enabled: false }),
- mockApplicationProject({ enabled: false })
- ]
- });
- (getApplicationDetails as jest.Mock<Promise<Application>>).mockResolvedValueOnce(app);
- const wrapper = shallowRender({ application: app, enabledProjectsKey: ['1', '3'] });
- await waitAndUpdate(wrapper);
- expect(wrapper).toMatchSnapshot();
-});
-
-it('Should close when no response', async () => {
- const app = mockApplication();
- (getApplicationDetails as jest.Mock<Promise<Application>>).mockRejectedValueOnce(app);
- const handleClose = jest.fn();
- const wrapper = shallowRender({ application: app, onClose: handleClose });
- await waitAndUpdate(wrapper);
- expect(handleClose).toHaveBeenCalled();
-});
-
-it('Should update loading flag', () => {
- const wrapper = shallowRender();
- wrapper.setState({ loading: true });
- wrapper.instance().stopLoading();
- expect(wrapper.state().loading).toBe(false);
-});
-
-it('Should update on input event', () => {
- const wrapper = shallowRender();
- wrapper.setState({ name: '' });
- wrapper
- .instance()
- .handleInputChange(({ currentTarget: { value: 'bar' } } as any) as React.ChangeEvent<
- HTMLInputElement
- >);
- expect(wrapper.state().name).toBe('bar');
-});
-
-it('Should tell if it can submit correctly', () => {
- const wrapper = shallowRender();
- wrapper.setState({ loading: true });
- expect(wrapper.instance().canSubmit()).toBe(false);
- wrapper.setState({ loading: false, name: '' });
- expect(wrapper.instance().canSubmit()).toBe(false);
- wrapper.setState({
- loading: false,
- name: 'ok',
- selectedBranches: { foo: null },
- selected: ['foo']
- });
- expect(wrapper.instance().canSubmit()).toBe(false);
- wrapper.setState({
- loading: false,
- name: 'ok',
- selectedBranches: { foo: { label: 'foo', isMain: true, value: 'foo' } },
- selected: ['foo']
- });
- expect(wrapper.instance().canSubmit()).toBe(true);
-});
-
-function shallowRender(props: Partial<CreateBranchForm['props']> = {}) {
- return shallow<CreateBranchForm>(
- <CreateBranchForm
- application={mockApplication()}
- enabledProjectsKey={[]}
- onClose={jest.fn()}
- onCreate={jest.fn()}
- onUpdate={jest.fn()}
- {...props}
- />
- );
-}
diff --git a/server/sonar-web/src/main/js/apps/application-console/__tests__/EditForm-test.tsx b/server/sonar-web/src/main/js/apps/application-console/__tests__/EditForm-test.tsx
deleted file mode 100644
index d2b66b36351..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/__tests__/EditForm-test.tsx
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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 { shallow } from 'enzyme';
-import * as React from 'react';
-import SimpleModal from '../../../components/controls/SimpleModal';
-import { mockApplication } from '../../../helpers/mocks/application';
-import { change, waitAndUpdate } from '../../../helpers/testUtils';
-import EditForm from '../EditForm';
-
-it('should render correctly', () => {
- expect(
- shallowRender()
- .find(SimpleModal)
- .dive()
- ).toMatchSnapshot();
-});
-
-it('should correctly submit the new info', async () => {
- const onClose = jest.fn();
- const onEdit = jest.fn();
- const wrapper = shallowRender({ onClose, onEdit });
- const modal = wrapper.find(SimpleModal).dive();
-
- change(modal.find('#view-edit-name'), 'New name');
- change(modal.find('#view-edit-description'), 'New description');
-
- wrapper.instance().handleFormSubmit();
- await waitAndUpdate(wrapper);
- expect(onEdit).toBeCalledWith('New name', 'New description');
- expect(onClose).toBeCalled();
-});
-
-function shallowRender(props: Partial<EditForm['props']> = {}) {
- return shallow<EditForm>(
- <EditForm
- header="Edit"
- onClose={jest.fn()}
- onEdit={jest.fn()}
- application={mockApplication()}
- {...props}
- />
- );
-}
diff --git a/server/sonar-web/src/main/js/apps/application-console/__tests__/ProjectBranchRow-test.tsx b/server/sonar-web/src/main/js/apps/application-console/__tests__/ProjectBranchRow-test.tsx
deleted file mode 100644
index b18f7674b59..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/__tests__/ProjectBranchRow-test.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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 { shallow } from 'enzyme';
-import * as React from 'react';
-import { mockApplicationProject } from '../../../helpers/mocks/application';
-import ProjectBranchRow from '../ProjectBranchRow';
-
-it('Should render correctly', () => {
- expect(shallowRender()).toMatchSnapshot();
-});
-
-function shallowRender(props: Partial<ProjectBranchRow['props']> = {}) {
- return shallow<ProjectBranchRow>(
- <ProjectBranchRow
- checked={true}
- onChange={jest.fn()}
- onCheck={jest.fn()}
- onOpen={jest.fn()}
- onClose={jest.fn()}
- project={mockApplicationProject()}
- {...props}
- />
- );
-}
diff --git a/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/ApplicationBranches-test.tsx.snap b/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/ApplicationBranches-test.tsx.snap
deleted file mode 100644
index 39ee8f1edcc..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/ApplicationBranches-test.tsx.snap
+++ /dev/null
@@ -1,217 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly: can create branches 1`] = `
-<div
- className="app-branches-console"
->
- <div
- className="boxed-group-actions"
- >
- <Button
- disabled={false}
- onClick={[Function]}
- >
- application_console.branches.create
- </Button>
- </div>
- <h2
- className="text-limited big-spacer-top"
- title="application_console.branches"
- >
- application_console.branches
- </h2>
- <p>
- application_console.branches.help
- </p>
- <div
- className="app-branches-list"
- >
- <table
- className="data zebra"
- >
- <tbody>
- <ApplicationProjectBranch
- application={
- Object {
- "branches": Array [
- Object {
- "analysisDate": "2018-01-01",
- "excludedFromPurge": true,
- "isMain": false,
- "name": "branch-6.7",
- },
- ],
- "key": "foo",
- "name": "Foo",
- "projects": Array [
- Object {
- "branch": "master",
- "enabled": true,
- "isMain": true,
- "key": "bar",
- "name": "Bar",
- },
- ],
- "visibility": "private",
- }
- }
- branch={
- Object {
- "analysisDate": "2018-01-01",
- "excludedFromPurge": true,
- "isMain": false,
- "name": "branch-6.7",
- }
- }
- key="branch-6.7"
- onUpdateBranches={[MockFunction]}
- readonly={false}
- />
- </tbody>
- </table>
- </div>
-</div>
-`;
-
-exports[`should render correctly: creating branch 1`] = `
-<div
- className="app-branches-console"
->
- <div
- className="boxed-group-actions"
- >
- <Button
- disabled={true}
- onClick={[Function]}
- >
- application_console.branches.create
- </Button>
- </div>
- <h2
- className="text-limited big-spacer-top"
- title="application_console.branches"
- >
- application_console.branches
- </h2>
- <p>
- application_console.branches.help
- </p>
- <div
- className="app-branches-list"
- >
- <p
- className="text-center big-spacer-top"
- >
- application_console.branches.no_branches
- </p>
- </div>
- <CreateBranchForm
- application={
- Object {
- "branches": Array [
- Object {
- "analysisDate": "2018-01-01",
- "excludedFromPurge": true,
- "isMain": false,
- "name": "branch-6.7",
- },
- ],
- "key": "foo",
- "name": "Foo",
- "projects": Array [
- Object {
- "branch": "master",
- "isMain": true,
- "key": "bar",
- "name": "Bar",
- },
- ],
- "visibility": "private",
- }
- }
- enabledProjectsKey={
- Array [
- "bar",
- ]
- }
- onClose={[Function]}
- onCreate={[Function]}
- />
-</div>
-`;
-
-exports[`should render correctly: default 1`] = `
-<div
- className="app-branches-console"
->
- <div
- className="boxed-group-actions"
- >
- <Button
- disabled={true}
- onClick={[Function]}
- >
- application_console.branches.create
- </Button>
- </div>
- <h2
- className="text-limited big-spacer-top"
- title="application_console.branches"
- >
- application_console.branches
- </h2>
- <p>
- application_console.branches.help
- </p>
- <div
- className="app-branches-list"
- >
- <p
- className="text-center big-spacer-top"
- >
- application_console.branches.no_branches
- </p>
- </div>
-</div>
-`;
-
-exports[`should render correctly: readonly 1`] = `
-<div
- className="app-branches-console"
->
- <Alert
- className="huge-spacer-top"
- variant="warning"
- >
- application_console.branches.cannot_access_all_child_projects
- </Alert>
- <div
- className="boxed-group-actions"
- >
- <Button
- disabled={true}
- onClick={[Function]}
- >
- application_console.branches.create
- </Button>
- </div>
- <h2
- className="text-limited big-spacer-top"
- title="application_console.branches"
- >
- application_console.branches
- </h2>
- <p>
- application_console.branches.help
- </p>
- <div
- className="app-branches-list"
- >
- <p
- className="text-center big-spacer-top"
- >
- application_console.branches.no_branches
- </p>
- </div>
-</div>
-`;
diff --git a/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/ApplicationConsoleApp-test.tsx.snap b/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/ApplicationConsoleApp-test.tsx.snap
deleted file mode 100644
index c92ad0958e4..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/ApplicationConsoleApp-test.tsx.snap
+++ /dev/null
@@ -1,73 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Should render correctly: Empty app 1`] = `""`;
-
-exports[`Should render correctly: With app 1`] = `
-<ApplicationConsoleAppRenderer
- application={
- Object {
- "branches": Array [
- Object {
- "analysisDate": "2018-01-01",
- "excludedFromPurge": true,
- "isMain": false,
- "name": "branch-6.7",
- },
- ],
- "key": "foo",
- "name": "Foo",
- "projects": Array [
- Object {
- "branch": "master",
- "isMain": true,
- "key": "bar",
- "name": "Bar",
- },
- ],
- "visibility": "private",
- }
- }
- canBrowseAllChildProjects={false}
- loading={false}
- onAddProject={[Function]}
- onEdit={[Function]}
- onRefresh={[Function]}
- onRemoveProject={[Function]}
- onUpdateBranches={[Function]}
-/>
-`;
-
-exports[`Should render correctly: can browse all child projects 1`] = `
-<ApplicationConsoleAppRenderer
- application={
- Object {
- "branches": Array [
- Object {
- "analysisDate": "2018-01-01",
- "excludedFromPurge": true,
- "isMain": false,
- "name": "branch-6.7",
- },
- ],
- "key": "foo",
- "name": "Foo",
- "projects": Array [
- Object {
- "branch": "master",
- "isMain": true,
- "key": "bar",
- "name": "Bar",
- },
- ],
- "visibility": "private",
- }
- }
- canBrowseAllChildProjects={true}
- loading={false}
- onAddProject={[Function]}
- onEdit={[Function]}
- onRefresh={[Function]}
- onRemoveProject={[Function]}
- onUpdateBranches={[Function]}
-/>
-`;
diff --git a/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/ApplicationConsoleAppRenderer-test.tsx.snap b/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/ApplicationConsoleAppRenderer-test.tsx.snap
deleted file mode 100644
index 7af0e3d73f4..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/ApplicationConsoleAppRenderer-test.tsx.snap
+++ /dev/null
@@ -1,265 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should handle editing: edit form 1`] = `
-<EditForm
- application={
- Object {
- "branches": Array [
- Object {
- "analysisDate": "2018-01-01",
- "excludedFromPurge": true,
- "isMain": false,
- "name": "branch-6.7",
- },
- ],
- "key": "foo",
- "name": "Foo",
- "projects": Array [
- Object {
- "branch": "master",
- "isMain": true,
- "key": "bar",
- "name": "Bar",
- },
- ],
- "visibility": "private",
- }
- }
- header="application_console.edit"
- onClose={[Function]}
- onEdit={[MockFunction]}
-/>
-`;
-
-exports[`should render correctly: can recompute 1`] = `
-<div
- className="page page-limited"
->
- <div
- className="boxed-group"
- id="view-details"
- >
- <div
- className="boxed-group-actions"
- >
- <Button
- className="little-spacer-right"
- id="view-details-edit"
- onClick={[Function]}
- >
- edit
- </Button>
- <Button
- className="little-spacer-right"
- onClick={[MockFunction]}
- >
- application_console.recompute
- </Button>
- </div>
- <header
- className="boxed-group-header"
- id="view-details-header"
- >
- <h2
- className="text-limited"
- title="Foo"
- >
- Foo
- </h2>
- </header>
- <div
- className="boxed-group-inner"
- id="view-details-content"
- >
- <div
- className="big-spacer-bottom"
- >
- <div
- className="little-spacer-bottom"
- >
- Foo bar
- </div>
- <div
- className="subtitle"
- >
- key
- :
- foo
- </div>
- </div>
- <ApplicationProjects
- application={
- Object {
- "branches": Array [
- Object {
- "analysisDate": "2018-01-01",
- "excludedFromPurge": true,
- "isMain": false,
- "name": "branch-6.7",
- },
- ],
- "description": "Foo bar",
- "key": "foo",
- "name": "Foo",
- "projects": Array [
- Object {
- "branch": "master",
- "isMain": true,
- "key": "bar",
- "name": "Bar",
- },
- ],
- "visibility": "private",
- }
- }
- onAddProject={[MockFunction]}
- onRemoveProject={[MockFunction]}
- />
- <ApplicationBranches
- application={
- Object {
- "branches": Array [
- Object {
- "analysisDate": "2018-01-01",
- "excludedFromPurge": true,
- "isMain": false,
- "name": "branch-6.7",
- },
- ],
- "description": "Foo bar",
- "key": "foo",
- "name": "Foo",
- "projects": Array [
- Object {
- "branch": "master",
- "isMain": true,
- "key": "bar",
- "name": "Bar",
- },
- ],
- "visibility": "private",
- }
- }
- canBrowseAllChildProjects={true}
- onUpdateBranches={[MockFunction]}
- />
- </div>
- </div>
-</div>
-`;
-
-exports[`should render correctly: default 1`] = `
-<div
- className="page page-limited"
->
- <div
- className="boxed-group"
- id="view-details"
- >
- <div
- className="boxed-group-actions"
- >
- <Button
- className="little-spacer-right"
- id="view-details-edit"
- onClick={[Function]}
- >
- edit
- </Button>
- <Button
- className="little-spacer-right"
- onClick={[MockFunction]}
- >
- application_console.recompute
- </Button>
- </div>
- <header
- className="boxed-group-header"
- id="view-details-header"
- >
- <h2
- className="text-limited"
- title="Foo"
- >
- Foo
- </h2>
- </header>
- <div
- className="boxed-group-inner"
- id="view-details-content"
- >
- <div
- className="big-spacer-bottom"
- >
- <div
- className="subtitle"
- >
- key
- :
- foo
- </div>
- </div>
- <ApplicationProjects
- application={
- Object {
- "branches": Array [
- Object {
- "analysisDate": "2018-01-01",
- "excludedFromPurge": true,
- "isMain": false,
- "name": "branch-6.7",
- },
- ],
- "key": "foo",
- "name": "Foo",
- "projects": Array [
- Object {
- "branch": "master",
- "isMain": true,
- "key": "bar",
- "name": "Bar",
- },
- ],
- "visibility": "private",
- }
- }
- onAddProject={[MockFunction]}
- onRemoveProject={[MockFunction]}
- />
- <ApplicationBranches
- application={
- Object {
- "branches": Array [
- Object {
- "analysisDate": "2018-01-01",
- "excludedFromPurge": true,
- "isMain": false,
- "name": "branch-6.7",
- },
- ],
- "key": "foo",
- "name": "Foo",
- "projects": Array [
- Object {
- "branch": "master",
- "isMain": true,
- "key": "bar",
- "name": "Bar",
- },
- ],
- "visibility": "private",
- }
- }
- canBrowseAllChildProjects={true}
- onUpdateBranches={[MockFunction]}
- />
- </div>
- </div>
-</div>
-`;
-
-exports[`should render correctly: is loading 1`] = `
-<i
- className="spinner spacer"
-/>
-`;
diff --git a/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/ApplicationProjectBranch-test.tsx.snap b/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/ApplicationProjectBranch-test.tsx.snap
deleted file mode 100644
index 4e1cbd90375..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/ApplicationProjectBranch-test.tsx.snap
+++ /dev/null
@@ -1,83 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly: default 1`] = `
-<tr>
- <td>
- <BranchIcon
- className="little-spacer-right"
- />
- branch-6.7
- </td>
- <td
- className="thin nowrap"
- >
- <BranchRowActions
- application={
- Object {
- "branches": Array [
- Object {
- "analysisDate": "2018-01-01",
- "excludedFromPurge": true,
- "isMain": false,
- "name": "branch-6.7",
- },
- ],
- "key": "foo",
- "name": "Foo",
- "projects": Array [
- Object {
- "branch": "master",
- "isMain": true,
- "key": "bar",
- "name": "Bar",
- },
- ],
- "visibility": "private",
- }
- }
- branch={
- Object {
- "analysisDate": "2018-01-01",
- "excludedFromPurge": true,
- "isMain": false,
- "name": "branch-6.7",
- }
- }
- onUpdateBranches={[MockFunction]}
- />
- </td>
-</tr>
-`;
-
-exports[`should render correctly: main branch 1`] = `
-<tr>
- <td>
- <BranchIcon
- className="little-spacer-right"
- />
- master
- <span
- className="badge spacer-left"
- >
- application_console.branches.main_branch
- </span>
- </td>
- <td
- className="thin nowrap"
- />
-</tr>
-`;
-
-exports[`should render correctly: readonly 1`] = `
-<tr>
- <td>
- <BranchIcon
- className="little-spacer-right"
- />
- branch-6.7
- </td>
- <td
- className="thin nowrap"
- />
-</tr>
-`;
diff --git a/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/ApplicationProjects-test.tsx.snap b/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/ApplicationProjects-test.tsx.snap
deleted file mode 100644
index cfd64c1000d..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/ApplicationProjects-test.tsx.snap
+++ /dev/null
@@ -1,75 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly in application mode 1`] = `
-<SelectList
- disabledElements={Array []}
- elements={
- Array [
- "test1",
- "test2",
- "test3",
- ]
- }
- elementsTotalCount={55}
- needToReload={false}
- onSearch={[Function]}
- onSelect={[Function]}
- onUnselect={[Function]}
- renderElement={[Function]}
- selectedElements={
- Array [
- "test3",
- ]
- }
- withPaging={true}
-/>
-`;
-
-exports[`should render correctly in application mode: render project: basic 1`] = `
-<div
- className="views-project-item display-flex-center little-padded"
->
- <QualifierIcon
- className="spacer-right"
- qualifier="TRK"
- />
- <div>
- <div
- title="test1"
- >
- test1
- </div>
- <div
- className="note"
- >
- test1
- </div>
- </div>
-</div>
-`;
-
-exports[`should render correctly in application mode: render project: inaccessible 1`] = `
-<div
- className="views-project-item display-flex-center little-padded bg-warning"
->
- <Tooltip
- overlay="application_console.project_inaccessible"
- >
- <WarningIcon
- className="spacer-right"
- />
- </Tooltip>
- <div>
- <div
- title="test2"
- >
- test2
- </div>
- <div
- className="note"
- >
- test2
- </div>
- </div>
-</div>
-`;
diff --git a/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/BranchRowActions-test.tsx.snap b/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/BranchRowActions-test.tsx.snap
deleted file mode 100644
index 7c1f10a8b4a..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/BranchRowActions-test.tsx.snap
+++ /dev/null
@@ -1,15 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Should render correctly 1`] = `
-<Fragment>
- <ConfirmButton
- confirmButtonText="delete"
- isDestructive={true}
- modalBody="application_console.branches.delete.warning_x.branch-6.7"
- modalHeader="application_console.branches.delete"
- onConfirm={[Function]}
- >
- <Component />
- </ConfirmButton>
-</Fragment>
-`;
diff --git a/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/BranchSelectItem-test.tsx.snap b/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/BranchSelectItem-test.tsx.snap
deleted file mode 100644
index a9878d576af..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/BranchSelectItem-test.tsx.snap
+++ /dev/null
@@ -1,22 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Should render correctly 1`] = `
-<Tooltip
- overlay="test"
- placement="left"
->
- <div
- onMouseDown={[Function]}
- onMouseEnter={[Function]}
- onMouseMove={[Function]}
- role="listitem"
- >
- <div>
- <BranchIcon
- className="little-spacer-right"
- />
- test
- </div>
- </div>
-</Tooltip>
-`;
diff --git a/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/CreateBranchForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/CreateBranchForm-test.tsx.snap
deleted file mode 100644
index 72322d18438..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/CreateBranchForm-test.tsx.snap
+++ /dev/null
@@ -1,12 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Should render correctly 1`] = `
-<SimpleModal
- header="application_console.branches.create"
- onClose={[MockFunction]}
- onSubmit={[Function]}
- size="medium"
->
- <Component />
-</SimpleModal>
-`;
diff --git a/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/EditForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/EditForm-test.tsx.snap
deleted file mode 100644
index 46f70be1267..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/EditForm-test.tsx.snap
+++ /dev/null
@@ -1,77 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<Modal
- contentLabel="Edit"
- onRequestClose={[MockFunction]}
- size="small"
->
- <form
- onSubmit={[Function]}
- >
- <div
- className="modal-head"
- >
- <h2>
- Edit
- </h2>
- </div>
- <div
- className="modal-body"
- >
- <div
- className="modal-field"
- >
- <label
- htmlFor="view-edit-name"
- >
- name
- </label>
- <input
- autoFocus={true}
- id="view-edit-name"
- maxLength={100}
- name="name"
- onChange={[Function]}
- size={50}
- type="text"
- value="Foo"
- />
- </div>
- <div
- className="modal-field"
- >
- <label
- htmlFor="view-edit-description"
- >
- description
- </label>
- <textarea
- id="view-edit-description"
- name="description"
- onChange={[Function]}
- value=""
- />
- </div>
- </div>
- <div
- className="modal-foot"
- >
- <DeferredSpinner
- className="spacer-right"
- loading={false}
- />
- <SubmitButton
- disabled={false}
- >
- save
- </SubmitButton>
- <ResetButtonLink
- onClick={[Function]}
- >
- cancel
- </ResetButtonLink>
- </div>
- </form>
-</Modal>
-`;
diff --git a/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/ProjectBranchRow-test.tsx.snap b/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/ProjectBranchRow-test.tsx.snap
deleted file mode 100644
index 26bfbcbc76c..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/ProjectBranchRow-test.tsx.snap
+++ /dev/null
@@ -1,59 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Should render correctly 1`] = `
-<tr
- key="bar"
->
- <td
- className="text-center"
- >
- <Checkbox
- checked={true}
- id="bar"
- onCheck={[MockFunction]}
- thirdState={false}
- />
- </td>
- <td
- className="nowrap hide-overflow branch-name-row"
- >
- <Tooltip
- overlay="Bar"
- >
- <span>
- <QualifierIcon
- qualifier="TRK"
- />
-
- Bar
- </span>
- </Tooltip>
- </td>
- <td>
- <SelectLegacy
- className="width100"
- clearable={false}
- disabled={false}
- onChange={[Function]}
- onClose={[MockFunction]}
- onFocus={[Function]}
- onOpen={[Function]}
- optionComponent={[Function]}
- options={
- Array [
- Object {
- "isMain": true,
- "label": "master",
- "value": "master",
- },
- ]
- }
- searchable={false}
- />
- <DeferredSpinner
- className="project-branch-row-spinner"
- loading={false}
- />
- </td>
-</tr>
-`;
diff --git a/server/sonar-web/src/main/js/apps/application-console/routes.ts b/server/sonar-web/src/main/js/apps/application-console/routes.ts
deleted file mode 100644
index 47601e1a1d3..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/routes.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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 { lazyLoadComponent } from '../../components/lazyLoadComponent';
-
-const routes = [
- {
- indexRoute: { component: lazyLoadComponent(() => import('./ApplicationConsoleApp')) }
- }
-];
-
-export default routes;
diff --git a/server/sonar-web/src/main/js/apps/application-console/utils.ts b/server/sonar-web/src/main/js/apps/application-console/utils.ts
deleted file mode 100644
index 50e5feb581a..00000000000
--- a/server/sonar-web/src/main/js/apps/application-console/utils.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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 { Branch } from '../../types/branch-like';
-
-export interface SelectBranchOption {
- value: string;
- label: string;
- isMain: boolean;
-}
-
-export type ApplicationBranch = Pick<Branch, 'isMain' | 'name'>;
diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/ApplicationCreation-test.tsx b/server/sonar-web/src/main/js/apps/projects/components/__tests__/ApplicationCreation-test.tsx
index 5e33911867b..300a07823de 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/ApplicationCreation-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/ApplicationCreation-test.tsx
@@ -50,7 +50,7 @@ it('should show form and callback when submitted - admin', async () => {
await openAndSubmitForm(wrapper);
expect(routerPush).toBeCalledWith({
- pathname: '/application/console',
+ pathname: '/project/admin/extension/developer-server/application-console',
query: {
id: 'new app'
}
diff --git a/server/sonar-web/src/main/js/helpers/mocks/application.ts b/server/sonar-web/src/main/js/helpers/mocks/application.ts
index 104df2d4406..eb7089194cf 100644
--- a/server/sonar-web/src/main/js/helpers/mocks/application.ts
+++ b/server/sonar-web/src/main/js/helpers/mocks/application.ts
@@ -17,20 +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 { Application, ApplicationPeriod, ApplicationProject } from '../../types/application';
-import { Visibility } from '../../types/component';
-import { mockBranch } from './branch-like';
-
-export function mockApplication(overrides: Partial<Application> = {}): Application {
- return {
- branches: [mockBranch()],
- key: 'foo',
- name: 'Foo',
- projects: [mockApplicationProject()],
- visibility: Visibility.Private,
- ...overrides
- };
-}
+import { ApplicationPeriod } from '../../types/application';
export function mockApplicationPeriod(
overrides: Partial<ApplicationPeriod> = {}
@@ -42,15 +29,3 @@ export function mockApplicationPeriod(
...overrides
};
}
-
-export function mockApplicationProject(
- overrides: Partial<ApplicationProject> = {}
-): ApplicationProject {
- return {
- branch: 'master',
- isMain: true,
- key: 'bar',
- name: 'Bar',
- ...overrides
- };
-}
diff --git a/server/sonar-web/src/main/js/helpers/urls.ts b/server/sonar-web/src/main/js/helpers/urls.ts
index 1d3b88659b1..ee616508baa 100644
--- a/server/sonar-web/src/main/js/helpers/urls.ts
+++ b/server/sonar-web/src/main/js/helpers/urls.ts
@@ -78,7 +78,10 @@ export function getPortfolioAdminUrl(key: string) {
}
export function getApplicationAdminUrl(key: string) {
- return { pathname: '/application/console', query: { id: key } };
+ return {
+ pathname: '/project/admin/extension/developer-server/application-console',
+ query: { id: key }
+ };
}
export function getComponentBackgroundTaskUrl(
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 8a5573e7201..71be2967cd2 100644
--- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties
+++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties
@@ -556,27 +556,6 @@ visibility.private.description.long=Only members of the organization will be abl
#
#------------------------------------------------------------------------------
-application_console.edit=Edit Application
-application_console.project_inaccessible=You do not have access to this project
-application_console.branches=Application Branches
-application_console.branches.cannot_access_all_child_projects=You must have access to all projects in this Application in order to administer branches.
-application_console.branches.cancel=Cancel
-application_console.branches.configuration=Branch configuration
-application_console.branches.create=Create branch
-application_console.branches.create.verb=Create
-application_console.branches.create.help=For each project of your Application, choose a project branch that will be displayed inside the Application’s branch.
-application_console.branches.delete=Delete branch
-application_console.branches.delete.warning_x=Are you sure you want to delete "{0}" ?
-application_console.branches.help=Track branches other than the main branch of this application's projects.
-application_console.branches.main_branch=Main Branch
-application_console.branches.update=Update branch
-application_console.branches.update.verb=Update
-application_console.branches.no_branches=No branches yet. You can create branches once projects are selected for this Application.
-application_console.page=Edit Definition
-application_console.delete_application=Delete Application
-application_console.recompute=Recompute
-application_console.refresh_started=Your application will be recomputed soon
-application_console.do_you_want_to_delete=Are you sure that you want to delete "{0}"?
application_settings.page=Application Settings
application_settings.report=Application Report Settings
application_settings.report.frequency=Application Reports Frequency