aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/apps/projectsManagement
diff options
context:
space:
mode:
authorGuillaume Peoc'h <guillaume.peoch@sonarsource.com>2022-02-02 15:36:37 +0100
committersonartech <sonartech@sonarsource.com>2022-02-09 20:02:55 +0000
commit2b13f016dee62cc813d0374e9f835dee5f4cda28 (patch)
treea14a39e129bb993ab041c8b29af4f9963bdf0002 /server/sonar-web/src/main/js/apps/projectsManagement
parent2d48cb3c1eb4f6cd68bd091c4eb9d62fa71deff8 (diff)
downloadsonarqube-2b13f016dee62cc813d0374e9f835dee5f4cda28.tar.gz
sonarqube-2b13f016dee62cc813d0374e9f835dee5f4cda28.zip
SONAR-15909 Extract AppState Redux
Diffstat (limited to 'server/sonar-web/src/main/js/apps/projectsManagement')
-rw-r--r--server/sonar-web/src/main/js/apps/projectsManagement/App.tsx9
-rw-r--r--server/sonar-web/src/main/js/apps/projectsManagement/Search.tsx11
-rw-r--r--server/sonar-web/src/main/js/apps/projectsManagement/__tests__/App-test.tsx21
-rw-r--r--server/sonar-web/src/main/js/apps/projectsManagement/__tests__/Search-test.tsx14
4 files changed, 29 insertions, 26 deletions
diff --git a/server/sonar-web/src/main/js/apps/projectsManagement/App.tsx b/server/sonar-web/src/main/js/apps/projectsManagement/App.tsx
index 7b090bbc3ee..be9c7f03620 100644
--- a/server/sonar-web/src/main/js/apps/projectsManagement/App.tsx
+++ b/server/sonar-web/src/main/js/apps/projectsManagement/App.tsx
@@ -29,10 +29,10 @@ import ListFooter from '../../components/controls/ListFooter';
import { toShortNotSoISOString } from '../../helpers/dates';
import { translate } from '../../helpers/l10n';
import { hasGlobalPermission } from '../../helpers/users';
-import { getAppState, getCurrentUser, Store } from '../../store/rootReducer';
+import { getCurrentUser, Store } from '../../store/rootReducer';
import { Permissions } from '../../types/permissions';
import { SettingsKey } from '../../types/settings';
-import { AppState, LoggedInUser, Visibility } from '../../types/types';
+import { LoggedInUser, Visibility } from '../../types/types';
import CreateProjectForm from './CreateProjectForm';
import Header from './Header';
import Projects from './Projects';
@@ -40,7 +40,6 @@ import Search from './Search';
export interface Props {
currentUser: LoggedInUser;
- appState: Pick<AppState, 'qualifiers'>;
}
interface State {
@@ -198,7 +197,7 @@ export class App extends React.PureComponent<Props, State> {
};
render() {
- const { appState, currentUser } = this.props;
+ const { currentUser } = this.props;
const { defaultProjectVisibility } = this.state;
return (
<div className="page page-limited" id="projects-management-page">
@@ -228,7 +227,6 @@ export class App extends React.PureComponent<Props, State> {
query={this.state.query}
ready={this.state.ready}
selection={this.state.selection}
- topLevelQualifiers={appState.qualifiers}
total={this.state.total}
visibility={this.state.visibility}
/>
@@ -262,7 +260,6 @@ export class App extends React.PureComponent<Props, State> {
}
const mapStateToProps = (state: Store) => ({
- appState: getAppState(state),
currentUser: getCurrentUser(state) as LoggedInUser
});
diff --git a/server/sonar-web/src/main/js/apps/projectsManagement/Search.tsx b/server/sonar-web/src/main/js/apps/projectsManagement/Search.tsx
index 8f47af0fdf4..4d19a37e27a 100644
--- a/server/sonar-web/src/main/js/apps/projectsManagement/Search.tsx
+++ b/server/sonar-web/src/main/js/apps/projectsManagement/Search.tsx
@@ -20,6 +20,7 @@
import { sortBy } from 'lodash';
import * as React from 'react';
import { Project } from '../../api/components';
+import withAppStateContext from '../../app/components/app-state/withAppStateContext';
import { Button } from '../../components/controls/buttons';
import Checkbox from '../../components/controls/Checkbox';
import DateInput from '../../components/controls/DateInput';
@@ -28,7 +29,7 @@ import SearchBox from '../../components/controls/SearchBox';
import SelectLegacy from '../../components/controls/SelectLegacy';
import QualifierIcon from '../../components/icons/QualifierIcon';
import { translate } from '../../helpers/l10n';
-import { Visibility } from '../../types/types';
+import { AppState, Visibility } from '../../types/types';
import BulkApplyTemplateModal from './BulkApplyTemplateModal';
import DeleteModal from './DeleteModal';
@@ -48,7 +49,7 @@ export interface Props {
query: string;
ready: boolean;
selection: any[];
- topLevelQualifiers: string[];
+ appState: AppState;
total: number;
visibility?: Visibility;
}
@@ -60,12 +61,12 @@ interface State {
const QUALIFIERS_ORDER = ['TRK', 'VW', 'APP'];
-export default class Search extends React.PureComponent<Props, State> {
+export class Search extends React.PureComponent<Props, State> {
mounted = false;
state: State = { bulkApplyTemplateModal: false, deleteModal: false };
getQualifierOptions = () => {
- const options = this.props.topLevelQualifiers.map(q => ({
+ const options = this.props.appState.qualifiers.map(q => ({
label: translate('qualifiers', q),
value: q
}));
@@ -281,3 +282,5 @@ export default class Search extends React.PureComponent<Props, State> {
);
}
}
+
+export default withAppStateContext(Search);
diff --git a/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/App-test.tsx b/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/App-test.tsx
index cc02fe3436f..653e059a155 100644
--- a/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/App-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/App-test.tsx
@@ -22,10 +22,9 @@ import * as React from 'react';
import { getComponents } from '../../../api/components';
import { changeProjectDefaultVisibility } from '../../../api/permissions';
import { getValues } from '../../../api/settings';
-import { mockAppState, mockLoggedInUser } from '../../../helpers/testMocks';
+import { mockLoggedInUser } from '../../../helpers/testMocks';
import { waitAndUpdate } from '../../../helpers/testUtils';
import { App, Props } from '../App';
-import Search from '../Search';
jest.mock('lodash', () => {
const lodash = jest.requireActual('lodash');
@@ -65,7 +64,7 @@ it('fetches all projects on mount', async () => {
it('selects provisioned', () => {
const wrapper = shallowRender();
- wrapper.find('Search').prop<Function>('onProvisionedChanged')(true);
+ wrapper.find('withAppStateContext(Search)').prop<Function>('onProvisionedChanged')(true);
expect(getComponents).lastCalledWith({
...defaultSearchParameters,
onProvisionedOnly: true,
@@ -76,22 +75,21 @@ it('selects provisioned', () => {
it('changes qualifier and resets provisioned', () => {
const wrapper = shallowRender();
wrapper.setState({ provisioned: true });
- wrapper.find('Search').prop<Function>('onQualifierChanged')('VW');
+ wrapper.find('withAppStateContext(Search)').prop<Function>('onQualifierChanged')('VW');
expect(getComponents).lastCalledWith({ ...defaultSearchParameters, qualifiers: 'VW' });
});
it('searches', () => {
const wrapper = shallowRender();
- wrapper.find('Search').prop<Function>('onSearch')('foo');
+ wrapper.find('withAppStateContext(Search)').prop<Function>('onSearch')('foo');
expect(getComponents).lastCalledWith({ ...defaultSearchParameters, q: 'foo', qualifiers: 'TRK' });
});
it('should handle date filtering', () => {
const wrapper = shallowRender();
- wrapper
- .find(Search)
- .props()
- .onDateChanged(new Date('2019-11-14T06:55:02.663Z'));
+ wrapper.find('withAppStateContext(Search)').prop<Function>('onDateChanged')(
+ '2019-11-14T06:55:02.663Z'
+ );
expect(getComponents).toHaveBeenCalledWith({
...defaultSearchParameters,
qualifiers: 'TRK',
@@ -138,10 +136,10 @@ it('selects and deselects projects', async () => {
wrapper.find('Projects').prop<Function>('onProjectDeselected')('foo');
expect(wrapper.state('selection')).toEqual(['bar']);
- wrapper.find('Search').prop<Function>('onAllDeselected')();
+ wrapper.find('withAppStateContext(Search)').prop<Function>('onAllDeselected')();
expect(wrapper.state('selection')).toEqual([]);
- wrapper.find('Search').prop<Function>('onAllSelected')();
+ wrapper.find('withAppStateContext(Search)').prop<Function>('onAllSelected')();
expect(wrapper.state('selection')).toEqual(['foo', 'bar']);
});
@@ -165,7 +163,6 @@ it('creates project', () => {
function shallowRender(props?: { [P in keyof Props]?: Props[P] }) {
return shallow<App>(
<App
- appState={mockAppState({ qualifiers: ['TRK', 'VW', 'APP'] })}
currentUser={mockLoggedInUser({ login: 'foo', permissions: { global: ['provisioning'] } })}
{...props}
/>
diff --git a/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/Search-test.tsx b/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/Search-test.tsx
index 11dc6ea01f0..b4e3f13b637 100644
--- a/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/Search-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/Search-test.tsx
@@ -19,8 +19,9 @@
*/
import { shallow } from 'enzyme';
import * as React from 'react';
+import { mockAppState } from '../../../helpers/testMocks';
import { click } from '../../../helpers/testUtils';
-import Search, { Props } from '../Search';
+import { Props, Search } from '../Search';
it('renders', () => {
expect(shallowRender()).toMatchSnapshot();
@@ -37,12 +38,17 @@ it('disables the delete and bulk apply buttons unless a project is selected', ()
});
it('render qualifiers filter', () => {
- expect(shallowRender({ topLevelQualifiers: ['TRK', 'VW', 'APP'] })).toMatchSnapshot();
+ expect(
+ shallowRender({ appState: mockAppState({ qualifiers: ['TRK', 'VW', 'APP'] }) })
+ ).toMatchSnapshot();
});
it('updates qualifier', () => {
const onQualifierChanged = jest.fn();
- const wrapper = shallowRender({ onQualifierChanged, topLevelQualifiers: ['TRK', 'VW', 'APP'] });
+ const wrapper = shallowRender({
+ onQualifierChanged,
+ appState: mockAppState({ qualifiers: ['TRK', 'VW', 'APP'] })
+ });
wrapper.find('SelectLegacy[name="projects-qualifier"]').prop<Function>('onChange')({
value: 'VW'
});
@@ -129,7 +135,7 @@ function shallowRender(props?: { [P in keyof Props]?: Props[P] }) {
query=""
ready={true}
selection={[]}
- topLevelQualifiers={['TRK']}
+ appState={mockAppState({ qualifiers: ['TRK'] })}
total={17}
{...props}
/>