aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/components/controls
diff options
context:
space:
mode:
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>2019-07-16 13:12:16 +0200
committerSonarTech <sonartech@sonarsource.com>2019-07-16 20:21:10 +0200
commit03bb045cca26245804592602c7ff0c6e477f3b8d (patch)
tree0d2e536a64eb136b5eafb77955794e0244e5169a /server/sonar-web/src/main/js/components/controls
parent5ed20116d427b617b04e93bb4f2937ad6692803a (diff)
downloadsonarqube-03bb045cca26245804592602c7ff0c6e477f3b8d.tar.gz
sonarqube-03bb045cca26245804592602c7ff0c6e477f3b8d.zip
SC-704 Extract more components (#1921)
* Extract BoxedGroupAccordion * Extract Select and SearchSelect * Extract Validation controls * Update sonar-ui-common
Diffstat (limited to 'server/sonar-web/src/main/js/components/controls')
-rw-r--r--server/sonar-web/src/main/js/components/controls/BoxedGroupAccordion.tsx78
-rw-r--r--server/sonar-web/src/main/js/components/controls/DateInput.tsx2
-rw-r--r--server/sonar-web/src/main/js/components/controls/SearchSelect.tsx154
-rw-r--r--server/sonar-web/src/main/js/components/controls/Select.tsx59
-rw-r--r--server/sonar-web/src/main/js/components/controls/ValidationForm.tsx72
-rw-r--r--server/sonar-web/src/main/js/components/controls/ValidationInput.tsx60
-rw-r--r--server/sonar-web/src/main/js/components/controls/ValidationModal.tsx83
-rw-r--r--server/sonar-web/src/main/js/components/controls/__tests__/BoxedGroupAccordion-test.tsx52
-rw-r--r--server/sonar-web/src/main/js/components/controls/__tests__/SearchSelect-test.tsx50
-rw-r--r--server/sonar-web/src/main/js/components/controls/__tests__/ValidationForm-test.tsx47
-rw-r--r--server/sonar-web/src/main/js/components/controls/__tests__/ValidationInput-test.tsx73
-rw-r--r--server/sonar-web/src/main/js/components/controls/__tests__/ValidationModal-test.tsx47
-rw-r--r--server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/BoxedGroupAccordion-test.tsx.snap26
-rw-r--r--server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/SearchSelect-test.tsx.snap17
-rw-r--r--server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/ValidationForm-test.tsx.snap19
-rw-r--r--server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/ValidationInput-test.tsx.snap104
-rw-r--r--server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/ValidationModal-test.tsx.snap21
-rw-r--r--server/sonar-web/src/main/js/components/controls/react-select.css483
18 files changed, 1 insertions, 1446 deletions
diff --git a/server/sonar-web/src/main/js/components/controls/BoxedGroupAccordion.tsx b/server/sonar-web/src/main/js/components/controls/BoxedGroupAccordion.tsx
deleted file mode 100644
index 8e1a4cd99ad..00000000000
--- a/server/sonar-web/src/main/js/components/controls/BoxedGroupAccordion.tsx
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 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 * as classNames from 'classnames';
-import OpenCloseIcon from 'sonar-ui-common/components/icons/OpenCloseIcon';
-
-interface Props {
- children: React.ReactNode;
- className?: string;
- data?: string;
- onClick: (data?: string) => void;
- open: boolean;
- renderHeader?: () => React.ReactNode;
- title: React.ReactNode;
-}
-
-interface State {
- hoveringInner: boolean;
-}
-
-export default class BoxedGroupAccordion extends React.PureComponent<Props, State> {
- state: State = { hoveringInner: false };
-
- handleClick = () => {
- this.props.onClick(this.props.data);
- };
-
- onDetailEnter = () => {
- this.setState({ hoveringInner: true });
- };
-
- onDetailLeave = () => {
- this.setState({ hoveringInner: false });
- };
-
- render() {
- const { className, open, renderHeader, title } = this.props;
- return (
- <div
- className={classNames('boxed-group boxed-group-accordion', className, {
- 'no-hover': this.state.hoveringInner
- })}>
- <div className="boxed-group-header" onClick={this.handleClick} role="listitem">
- <span className="boxed-group-accordion-title">
- <OpenCloseIcon className="little-spacer-right" open={open} />
- {title}
- </span>
- {renderHeader && renderHeader()}
- </div>
- {open && (
- <div
- className="boxed-group-inner"
- onMouseEnter={this.onDetailEnter}
- onMouseLeave={this.onDetailLeave}>
- {this.props.children}
- </div>
- )}
- </div>
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/components/controls/DateInput.tsx b/server/sonar-web/src/main/js/components/controls/DateInput.tsx
index dcb777c8573..da7918c9be3 100644
--- a/server/sonar-web/src/main/js/components/controls/DateInput.tsx
+++ b/server/sonar-web/src/main/js/components/controls/DateInput.tsx
@@ -37,7 +37,7 @@ import {
import { ButtonIcon, ClearButton } from 'sonar-ui-common/components/controls/buttons';
import OutsideClickHandler from 'sonar-ui-common/components/controls/OutsideClickHandler';
import { lazyLoad } from 'sonar-ui-common/components/lazyLoad';
-import Select from './Select';
+import Select from 'sonar-ui-common/components/controls/Select';
import './DayPicker.css';
import './styles.css';
diff --git a/server/sonar-web/src/main/js/components/controls/SearchSelect.tsx b/server/sonar-web/src/main/js/components/controls/SearchSelect.tsx
deleted file mode 100644
index c4b681624e6..00000000000
--- a/server/sonar-web/src/main/js/components/controls/SearchSelect.tsx
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 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 { debounce } from 'lodash';
-import { translate, translateWithParameters } from 'sonar-ui-common/helpers/l10n';
-import Select, { Creatable } from './Select';
-
-interface Props<T> {
- autofocus?: boolean;
- canCreate?: boolean;
- className?: string;
- clearable?: boolean;
- defaultOptions?: T[];
- minimumQueryLength?: number;
- multi?: boolean;
- onSearch: (query: string) => Promise<T[]>;
- onSelect?: (option: T) => void;
- onMultiSelect?: (options: T[]) => void;
- promptTextCreator?: (label: string) => string;
- renderOption?: (option: T) => JSX.Element;
- resetOnBlur?: boolean;
- value?: T | T[];
-}
-
-interface State<T> {
- loading: boolean;
- options: T[];
- query: string;
-}
-
-export default class SearchSelect<T extends { value: string }> extends React.PureComponent<
- Props<T>,
- State<T>
-> {
- mounted = false;
-
- constructor(props: Props<T>) {
- super(props);
- this.state = { loading: false, options: props.defaultOptions || [], query: '' };
- this.handleSearch = debounce(this.handleSearch, 250);
- }
-
- componentDidMount() {
- this.mounted = true;
- }
-
- componentWillUnmount() {
- this.mounted = false;
- }
-
- get autofocus() {
- return this.props.autofocus !== undefined ? this.props.autofocus : true;
- }
-
- get minimumQueryLength() {
- return this.props.minimumQueryLength !== undefined ? this.props.minimumQueryLength : 2;
- }
-
- get resetOnBlur() {
- return this.props.resetOnBlur !== undefined ? this.props.resetOnBlur : true;
- }
-
- handleSearch = (query: string) => {
- // Ignore the result if the query changed
- const currentQuery = query;
- this.props.onSearch(currentQuery).then(
- options => {
- if (this.mounted) {
- this.setState(state => ({
- loading: false,
- options: state.query === currentQuery ? options : state.options
- }));
- }
- },
- () => {
- if (this.mounted) {
- this.setState({ loading: false });
- }
- }
- );
- };
-
- handleChange = (option: T | T[]) => {
- if (Array.isArray(option)) {
- if (this.props.onMultiSelect) {
- this.props.onMultiSelect(option);
- }
- } else if (this.props.onSelect) {
- this.props.onSelect(option);
- }
- };
-
- handleInputChange = (query: string) => {
- if (query.length >= this.minimumQueryLength) {
- this.setState({ loading: true, query });
- this.handleSearch(query);
- } else {
- // `onInputChange` is called with an empty string after a user selects a value
- // in this case we shouldn't reset `options`, because it also resets select value :(
- const options = (query.length === 0 && this.props.defaultOptions) || [];
- this.setState({ options, query });
- }
- };
-
- // disable internal filtering
- handleFilterOption = () => true;
-
- render() {
- const Component = this.props.canCreate ? Creatable : Select;
- return (
- <Component
- autoFocus={this.autofocus}
- className={this.props.className}
- clearable={this.props.clearable}
- escapeClearsValue={false}
- filterOption={this.handleFilterOption}
- isLoading={this.state.loading}
- multi={this.props.multi}
- noResultsText={
- this.state.query.length < this.minimumQueryLength
- ? translateWithParameters('select2.tooShort', this.minimumQueryLength)
- : translate('select2.noMatches')
- }
- onBlurResetsInput={this.resetOnBlur}
- onChange={this.handleChange}
- onInputChange={this.handleInputChange}
- optionRenderer={this.props.renderOption}
- options={this.state.options}
- placeholder={translate('search_verb')}
- promptTextCreator={this.props.promptTextCreator}
- searchable={true}
- value={this.props.value}
- valueRenderer={this.props.renderOption}
- />
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/components/controls/Select.tsx b/server/sonar-web/src/main/js/components/controls/Select.tsx
deleted file mode 100644
index 2086716ac0f..00000000000
--- a/server/sonar-web/src/main/js/components/controls/Select.tsx
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 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 { ReactSelectProps, ReactCreatableSelectProps, ReactAsyncSelectProps } from 'react-select';
-import { ClearButton } from 'sonar-ui-common/components/controls/buttons';
-import { lazyLoad } from 'sonar-ui-common/components/lazyLoad';
-import './react-select.css';
-
-const ReactSelectLib = import('react-select');
-const ReactSelect = lazyLoad(() => ReactSelectLib);
-const ReactCreatable = lazyLoad(() => ReactSelectLib.then(lib => ({ default: lib.Creatable })));
-const ReactAsync = lazyLoad(() => ReactSelectLib.then(lib => ({ default: lib.Async })));
-
-function renderInput() {
- return <ClearButton className="button-tiny spacer-left text-middle" iconProps={{ size: 12 }} />;
-}
-
-interface WithInnerRef {
- innerRef?: (element: React.Component) => void;
-}
-
-export default function Select({ innerRef, ...props }: WithInnerRef & ReactSelectProps) {
- // TODO try to define good defaults, if any
- // ReactSelect doesn't declare `clearRenderer` prop
- const ReactSelectAny = ReactSelect as any;
- // hide the "x" icon when select is empty
- const clearable = props.clearable ? Boolean(props.value) : false;
- return (
- <ReactSelectAny {...props} clearRenderer={renderInput} clearable={clearable} ref={innerRef} />
- );
-}
-
-export function Creatable(props: ReactCreatableSelectProps) {
- // ReactSelect doesn't declare `clearRenderer` prop
- const ReactCreatableAny = ReactCreatable as any;
- return <ReactCreatableAny {...props} clearRenderer={renderInput} />;
-}
-
-// TODO figure out why `ref` prop is incompatible
-export function AsyncSelect(props: ReactAsyncSelectProps & { ref?: any }) {
- return <ReactAsync {...props} />;
-}
diff --git a/server/sonar-web/src/main/js/components/controls/ValidationForm.tsx b/server/sonar-web/src/main/js/components/controls/ValidationForm.tsx
deleted file mode 100644
index 9f2ca8217ee..00000000000
--- a/server/sonar-web/src/main/js/components/controls/ValidationForm.tsx
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 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 { FormikActions, FormikProps, Formik } from 'formik';
-
-export type ChildrenProps<V> = T.Omit<FormikProps<V>, 'handleSubmit'>;
-
-interface Props<V> {
- children: (props: ChildrenProps<V>) => React.ReactNode;
- initialValues: V;
- isInitialValid?: boolean;
- onSubmit: (data: V) => Promise<void>;
- validate: (data: V) => { [P in keyof V]?: string } | Promise<{ [P in keyof V]?: string }>;
-}
-
-export default class ValidationForm<V> extends React.Component<Props<V>> {
- mounted = false;
-
- componentDidMount() {
- this.mounted = true;
- }
-
- componentWillUnmount() {
- this.mounted = false;
- }
-
- handleSubmit = (data: V, { setSubmitting }: FormikActions<V>) => {
- const result = this.props.onSubmit(data);
- const stopSubmitting = () => {
- if (this.mounted) {
- setSubmitting(false);
- }
- };
-
- if (result) {
- result.then(stopSubmitting, stopSubmitting);
- } else {
- stopSubmitting();
- }
- };
-
- render() {
- return (
- <Formik<V>
- initialValues={this.props.initialValues}
- isInitialValid={this.props.isInitialValid}
- onSubmit={this.handleSubmit}
- validate={this.props.validate}>
- {({ handleSubmit, ...props }) => (
- <form onSubmit={handleSubmit}>{this.props.children(props)}</form>
- )}
- </Formik>
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/components/controls/ValidationInput.tsx b/server/sonar-web/src/main/js/components/controls/ValidationInput.tsx
deleted file mode 100644
index 3d7a78104a1..00000000000
--- a/server/sonar-web/src/main/js/components/controls/ValidationInput.tsx
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 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 AlertErrorIcon from 'sonar-ui-common/components/icons/AlertErrorIcon';
-import AlertSuccessIcon from 'sonar-ui-common/components/icons/AlertSuccessIcon';
-import HelpTooltip from 'sonar-ui-common/components/controls/HelpTooltip';
-
-interface Props {
- description?: string;
- children: React.ReactNode;
- className?: string;
- error: string | undefined;
- help?: string;
- id: string;
- isInvalid: boolean;
- isValid: boolean;
- label: React.ReactNode;
- required?: boolean;
-}
-
-export default function ValidationInput(props: Props) {
- const hasError = props.isInvalid && props.error !== undefined;
- return (
- <div className={props.className}>
- <label htmlFor={props.id}>
- <span className="text-middle">
- <strong>{props.label}</strong>
- {props.required && <em className="mandatory">*</em>}
- </span>
- {props.help && <HelpTooltip className="spacer-left" overlay={props.help} />}
- </label>
- <div className="little-spacer-top spacer-bottom">
- {props.children}
- {props.isInvalid && <AlertErrorIcon className="spacer-left text-middle" />}
- {hasError && (
- <span className="little-spacer-left text-danger text-middle">{props.error}</span>
- )}
- {props.isValid && <AlertSuccessIcon className="spacer-left text-middle" />}
- </div>
- {props.description && <div className="note abs-width-400">{props.description}</div>}
- </div>
- );
-}
diff --git a/server/sonar-web/src/main/js/components/controls/ValidationModal.tsx b/server/sonar-web/src/main/js/components/controls/ValidationModal.tsx
deleted file mode 100644
index 841b3592be1..00000000000
--- a/server/sonar-web/src/main/js/components/controls/ValidationModal.tsx
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 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 { translate } from 'sonar-ui-common/helpers/l10n';
-import { SubmitButton, ResetButtonLink } from 'sonar-ui-common/components/controls/buttons';
-import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner';
-import Modal, { ModalProps } from 'sonar-ui-common/components/controls/Modal';
-import ValidationForm, { ChildrenProps } from './ValidationForm';
-
-interface Props<V> extends ModalProps {
- children: (props: ChildrenProps<V>) => React.ReactNode;
- confirmButtonText: string;
- header: string;
- initialValues: V;
- isDestructive?: boolean;
- isInitialValid?: boolean;
- onClose: () => void;
- onSubmit: (data: V) => Promise<void>;
- validate: (data: V) => { [P in keyof V]?: string };
-}
-
-export default class ValidationModal<V> extends React.PureComponent<Props<V>> {
- handleSubmit = (data: V) => {
- return this.props.onSubmit(data).then(() => {
- this.props.onClose();
- });
- };
-
- render() {
- return (
- <Modal
- contentLabel={this.props.header}
- noBackdrop={this.props.noBackdrop}
- onRequestClose={this.props.onClose}
- size={this.props.size}>
- <ValidationForm
- initialValues={this.props.initialValues}
- isInitialValid={this.props.isInitialValid}
- onSubmit={this.handleSubmit}
- validate={this.props.validate}>
- {props => (
- <>
- <header className="modal-head">
- <h2>{this.props.header}</h2>
- </header>
-
- <div className="modal-body">{this.props.children(props)}</div>
-
- <footer className="modal-foot">
- <DeferredSpinner className="spacer-right" loading={props.isSubmitting} />
- <SubmitButton
- className={this.props.isDestructive ? 'button-red' : undefined}
- disabled={props.isSubmitting || !props.isValid || !props.dirty}>
- {this.props.confirmButtonText}
- </SubmitButton>
- <ResetButtonLink disabled={props.isSubmitting} onClick={this.props.onClose}>
- {translate('cancel')}
- </ResetButtonLink>
- </footer>
- </>
- )}
- </ValidationForm>
- </Modal>
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/BoxedGroupAccordion-test.tsx b/server/sonar-web/src/main/js/components/controls/__tests__/BoxedGroupAccordion-test.tsx
deleted file mode 100644
index b77c4c5bbcd..00000000000
--- a/server/sonar-web/src/main/js/components/controls/__tests__/BoxedGroupAccordion-test.tsx
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 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 { shallow } from 'enzyme';
-import { click } from 'sonar-ui-common/helpers/testUtils';
-import BoxedGroupAccordion from '../BoxedGroupAccordion';
-
-it('should render correctly', () => {
- expect(getWrapper()).toMatchSnapshot();
-});
-
-it('should show the inner content after a click', () => {
- const onClick = jest.fn();
- const wrapper = getWrapper({ onClick });
- click(wrapper.find('.boxed-group-header'));
-
- expect(onClick).lastCalledWith('foo');
- wrapper.setProps({ open: true });
-
- expect(wrapper.find('.boxed-group-inner').exists()).toBeTruthy();
-});
-
-function getWrapper(props = {}) {
- return shallow(
- <BoxedGroupAccordion
- data="foo"
- onClick={() => {}}
- open={false}
- renderHeader={() => <div>header content</div>}
- title="Foo"
- {...props}>
- <div>inner content</div>
- </BoxedGroupAccordion>
- );
-}
diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/SearchSelect-test.tsx b/server/sonar-web/src/main/js/components/controls/__tests__/SearchSelect-test.tsx
deleted file mode 100644
index 340e30c16f2..00000000000
--- a/server/sonar-web/src/main/js/components/controls/__tests__/SearchSelect-test.tsx
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 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 { shallow } from 'enzyme';
-import SearchSelect from '../SearchSelect';
-
-jest.mock('lodash', () => {
- const lodash = require.requireActual('lodash');
- lodash.debounce = jest.fn(fn => fn);
- return lodash;
-});
-
-it('should render Select', () => {
- expect(shallow(<SearchSelect onSearch={jest.fn()} onSelect={jest.fn()} />)).toMatchSnapshot();
-});
-
-it('should call onSelect', () => {
- const onSelect = jest.fn();
- const wrapper = shallow(<SearchSelect onSearch={jest.fn()} onSelect={onSelect} />);
- wrapper.prop('onChange')({ value: 'foo' });
- expect(onSelect).lastCalledWith({ value: 'foo' });
-});
-
-it('should call onSearch', () => {
- const onSearch = jest.fn().mockReturnValue(Promise.resolve([]));
- const wrapper = shallow(
- <SearchSelect minimumQueryLength={2} onSearch={onSearch} onSelect={jest.fn()} />
- );
- wrapper.prop('onInputChange')('f');
- expect(onSearch).not.toHaveBeenCalled();
- wrapper.prop('onInputChange')('foo');
- expect(onSearch).lastCalledWith('foo');
-});
diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/ValidationForm-test.tsx b/server/sonar-web/src/main/js/components/controls/__tests__/ValidationForm-test.tsx
deleted file mode 100644
index 3760b02ca81..00000000000
--- a/server/sonar-web/src/main/js/components/controls/__tests__/ValidationForm-test.tsx
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 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 { shallow } from 'enzyme';
-import ValidationForm from '../ValidationForm';
-
-it('should render and submit', async () => {
- const render = jest.fn();
- const onSubmit = jest.fn();
- const setSubmitting = jest.fn();
- const wrapper = shallow(
- <ValidationForm initialValues={{ foo: 'bar' }} onSubmit={onSubmit} validate={jest.fn()}>
- {render}
- </ValidationForm>
- );
- expect(wrapper).toMatchSnapshot();
- wrapper.dive();
- expect(render).toBeCalledWith(
- expect.objectContaining({ dirty: false, errors: {}, values: { foo: 'bar' } })
- );
-
- wrapper.prop<Function>('onSubmit')({ foo: 'bar' }, { setSubmitting });
- expect(setSubmitting).toBeCalledWith(false);
-
- onSubmit.mockResolvedValue(undefined).mockClear();
- setSubmitting.mockClear();
- wrapper.prop<Function>('onSubmit')({ foo: 'bar' }, { setSubmitting });
- await new Promise(setImmediate);
- expect(setSubmitting).toBeCalledWith(false);
-});
diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/ValidationInput-test.tsx b/server/sonar-web/src/main/js/components/controls/__tests__/ValidationInput-test.tsx
deleted file mode 100644
index 280d52bec6c..00000000000
--- a/server/sonar-web/src/main/js/components/controls/__tests__/ValidationInput-test.tsx
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 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 { shallow } from 'enzyme';
-import ValidationInput from '../ValidationInput';
-
-it('should render', () => {
- expect(
- shallow(
- <ValidationInput
- description="My description"
- error={undefined}
- help="Help message"
- id="field-id"
- isInvalid={false}
- isValid={false}
- label="Field label"
- required={true}>
- <div />
- </ValidationInput>
- )
- ).toMatchSnapshot();
-});
-
-it('should render with error', () => {
- expect(
- shallow(
- <ValidationInput
- description="My description"
- error="Field error message"
- id="field-id"
- isInvalid={true}
- isValid={false}
- label="Field label">
- <div />
- </ValidationInput>
- )
- ).toMatchSnapshot();
-});
-
-it('should render when valid', () => {
- expect(
- shallow(
- <ValidationInput
- description="My description"
- error={undefined}
- id="field-id"
- isInvalid={false}
- isValid={true}
- label="Field label"
- required={true}>
- <div />
- </ValidationInput>
- )
- ).toMatchSnapshot();
-});
diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/ValidationModal-test.tsx b/server/sonar-web/src/main/js/components/controls/__tests__/ValidationModal-test.tsx
deleted file mode 100644
index f4af7f14294..00000000000
--- a/server/sonar-web/src/main/js/components/controls/__tests__/ValidationModal-test.tsx
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 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 { shallow } from 'enzyme';
-import ValidationModal from '../ValidationModal';
-
-it('should render correctly', () => {
- const wrapper = shallow(
- <ValidationModal<{ field: string }>
- confirmButtonText="confirm"
- header="title"
- initialValues={{ field: 'foo' }}
- isDestructive={true}
- isInitialValid={true}
- onClose={jest.fn()}
- onSubmit={jest.fn()}
- validate={jest.fn()}>
- {props => (
- <input
- name="field"
- onBlur={props.handleBlur}
- onChange={props.handleChange}
- type="text"
- value={props.values.field}
- />
- )}
- </ValidationModal>
- );
- expect(wrapper).toMatchSnapshot();
-});
diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/BoxedGroupAccordion-test.tsx.snap b/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/BoxedGroupAccordion-test.tsx.snap
deleted file mode 100644
index 0c7b74b79d9..00000000000
--- a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/BoxedGroupAccordion-test.tsx.snap
+++ /dev/null
@@ -1,26 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<div
- className="boxed-group boxed-group-accordion"
->
- <div
- className="boxed-group-header"
- onClick={[Function]}
- role="listitem"
- >
- <span
- className="boxed-group-accordion-title"
- >
- <OpenCloseIcon
- className="little-spacer-right"
- open={false}
- />
- Foo
- </span>
- <div>
- header content
- </div>
- </div>
-</div>
-`;
diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/SearchSelect-test.tsx.snap b/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/SearchSelect-test.tsx.snap
deleted file mode 100644
index 792343f1a73..00000000000
--- a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/SearchSelect-test.tsx.snap
+++ /dev/null
@@ -1,17 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render Select 1`] = `
-<Select
- autoFocus={true}
- escapeClearsValue={false}
- filterOption={[Function]}
- isLoading={false}
- noResultsText="select2.tooShort.2"
- onBlurResetsInput={true}
- onChange={[Function]}
- onInputChange={[Function]}
- options={Array []}
- placeholder="search_verb"
- searchable={true}
-/>
-`;
diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/ValidationForm-test.tsx.snap b/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/ValidationForm-test.tsx.snap
deleted file mode 100644
index e00f009ef2f..00000000000
--- a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/ValidationForm-test.tsx.snap
+++ /dev/null
@@ -1,19 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render and submit 1`] = `
-<Formik
- enableReinitialize={false}
- initialValues={
- Object {
- "foo": "bar",
- }
- }
- isInitialValid={false}
- onSubmit={[Function]}
- validate={[MockFunction]}
- validateOnBlur={true}
- validateOnChange={true}
->
- <Component />
-</Formik>
-`;
diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/ValidationInput-test.tsx.snap b/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/ValidationInput-test.tsx.snap
deleted file mode 100644
index e417b038bc6..00000000000
--- a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/ValidationInput-test.tsx.snap
+++ /dev/null
@@ -1,104 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render 1`] = `
-<div>
- <label
- htmlFor="field-id"
- >
- <span
- className="text-middle"
- >
- <strong>
- Field label
- </strong>
- <em
- className="mandatory"
- >
- *
- </em>
- </span>
- <HelpTooltip
- className="spacer-left"
- overlay="Help message"
- />
- </label>
- <div
- className="little-spacer-top spacer-bottom"
- >
- <div />
- </div>
- <div
- className="note abs-width-400"
- >
- My description
- </div>
-</div>
-`;
-
-exports[`should render when valid 1`] = `
-<div>
- <label
- htmlFor="field-id"
- >
- <span
- className="text-middle"
- >
- <strong>
- Field label
- </strong>
- <em
- className="mandatory"
- >
- *
- </em>
- </span>
- </label>
- <div
- className="little-spacer-top spacer-bottom"
- >
- <div />
- <AlertSuccessIcon
- className="spacer-left text-middle"
- />
- </div>
- <div
- className="note abs-width-400"
- >
- My description
- </div>
-</div>
-`;
-
-exports[`should render with error 1`] = `
-<div>
- <label
- htmlFor="field-id"
- >
- <span
- className="text-middle"
- >
- <strong>
- Field label
- </strong>
- </span>
- </label>
- <div
- className="little-spacer-top spacer-bottom"
- >
- <div />
- <AlertErrorIcon
- className="spacer-left text-middle"
- />
- <span
- className="little-spacer-left text-danger text-middle"
- >
- Field error message
- </span>
- </div>
- <div
- className="note abs-width-400"
- >
- My description
- </div>
-</div>
-`;
diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/ValidationModal-test.tsx.snap b/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/ValidationModal-test.tsx.snap
deleted file mode 100644
index ecf12ce47b4..00000000000
--- a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/ValidationModal-test.tsx.snap
+++ /dev/null
@@ -1,21 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<Modal
- contentLabel="title"
- onRequestClose={[MockFunction]}
->
- <ValidationForm
- initialValues={
- Object {
- "field": "foo",
- }
- }
- isInitialValid={true}
- onSubmit={[Function]}
- validate={[MockFunction]}
- >
- <Component />
- </ValidationForm>
-</Modal>
-`;
diff --git a/server/sonar-web/src/main/js/components/controls/react-select.css b/server/sonar-web/src/main/js/components/controls/react-select.css
deleted file mode 100644
index 463c0044f47..00000000000
--- a/server/sonar-web/src/main/js/components/controls/react-select.css
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 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.
- */
-.Select {
- position: relative;
- display: inline-block;
- vertical-align: middle;
- font-size: var(--smallFontSize);
- text-align: left;
-}
-
-.Select,
-.Select div,
-.Select input,
-.Select span {
- box-sizing: border-box;
-}
-
-.Select.is-disabled > .Select-control {
- background-color: var(--disableGrayBg) !important;
- border-color: var(--disableGrayBorder) !important;
-}
-
-.Select.is-disabled > .Select-control:hover {
- box-shadow: none !important;
-}
-
-.Select.is-disabled .Select-arrow-zone {
- cursor: not-allowed !important;
- pointer-events: none !important;
-}
-
-.Select.is-disabled .Select-placeholder,
-.Select.is-disabled .Select-value {
- color: var(--disableGrayText) !important;
-}
-
-.Select-control {
- position: relative;
- display: table;
- width: 100%;
- height: var(--controlHeight);
- line-height: calc(var(--controlHeight) - 2px);
- border: 1px solid var(--gray80);
- border-collapse: separate;
- border-radius: 2px;
- background-color: #fff;
- color: var(--baseFontColor);
- cursor: default;
- outline: none;
- overflow: hidden;
-}
-
-.is-searchable.is-open > .Select-control {
- cursor: text;
-}
-
-.is-open > .Select-control {
- border-bottom-right-radius: 0;
- border-bottom-left-radius: 0;
- background: #fff;
-}
-
-.is-open > .Select-control > .Select-arrow {
- border-color: transparent transparent #999;
- border-width: 0 5px 5px;
-}
-
-.is-searchable.is-focused:not(.is-open) > .Select-control {
- cursor: text;
-}
-
-.is-focused:not(.is-open) > .Select-control {
- border-color: var(--blue);
-}
-
-.Select-placeholder {
- color: var(--secondFontColor);
-}
-
-.Select-placeholder,
-:not(.Select--multi) > .Select-control .Select-value {
- bottom: 0;
- left: 0;
- line-height: 23px;
- padding-left: 8px;
- padding-right: 24px;
- position: absolute;
- right: 0;
- top: 0;
- max-width: 100%;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.Select-value [class^='icon-'] {
- padding-top: 5px;
-}
-
-.Select-value svg,
-.Select-value img {
- padding-top: 4px;
-}
-
-.Select-value .outline-badge,
-.Select-option .outline-badge {
- height: 20px;
- line-height: 19px;
- margin-top: 1px;
-}
-
-.Select-option svg,
-.Select-option img,
-.Select-option [class^='icon-'] {
- padding-top: 2px;
-}
-
-.has-value:not(.Select--multi) > .Select-control > .Select-value .Select-value-label,
-.has-value.is-pseudo-focused:not(.Select--multi)
- > .Select-control
- > .Select-value
- .Select-value-label {
- color: var(--baseFontColor);
-}
-
-.has-value:not(.Select--multi) > .Select-control > .Select-value a.Select-value-label,
-.has-value.is-pseudo-focused:not(.Select--multi)
- > .Select-control
- > .Select-value
- a.Select-value-label {
- cursor: pointer;
- text-decoration: none;
-}
-
-.has-value:not(.Select--multi) > .Select-control > .Select-value a.Select-value-label:hover,
-.has-value.is-pseudo-focused:not(.Select--multi)
- > .Select-control
- > .Select-value
- a.Select-value-label:hover,
-.has-value:not(.Select--multi) > .Select-control > .Select-value a.Select-value-label:focus,
-.has-value.is-pseudo-focused:not(.Select--multi)
- > .Select-control
- > .Select-value
- a.Select-value-label:focus {
- color: #007eff;
- outline: none;
- text-decoration: underline;
-}
-
-.Select-input {
- vertical-align: top;
- height: 22px;
- padding-left: 8px;
- padding-right: 8px;
- outline: none;
-}
-
-.Select-input > input {
- background: none transparent;
- border: 0 none;
- cursor: default;
- display: inline-block;
- font-family: inherit;
- font-size: var(--smallFontSize);
- height: 22px;
- margin: 0;
- outline: none;
- padding: 0;
- box-shadow: none;
- -webkit-appearance: none;
-}
-
-.is-focused .Select-input > input {
- cursor: text;
-}
-
-.has-value.is-pseudo-focused .Select-input {
- opacity: 0;
-}
-
-.Select-control:not(.is-searchable) > .Select-input {
- outline: none;
-}
-
-.Select-loading-zone {
- cursor: pointer;
- display: table-cell;
- position: relative;
- text-align: center;
- vertical-align: middle;
- width: 16px;
-}
-
-.Select-loading {
- -webkit-animation: Select-animation-spin 400ms infinite linear;
- -o-animation: Select-animation-spin 400ms infinite linear;
- animation: Select-animation-spin 400ms infinite linear;
- width: 16px;
- height: 16px;
- box-sizing: border-box;
- border-radius: 50%;
- border: 2px solid #ccc;
- border-right-color: var(--baseFontColor);
- display: inline-block;
- position: relative;
- vertical-align: middle;
-}
-
-.Select-clear-zone {
- -webkit-animation: Select-animation-fadeIn 200ms;
- -o-animation: Select-animation-fadeIn 200ms;
- animation: Select-animation-fadeIn 200ms;
- color: #999;
- cursor: pointer;
- display: table-cell;
- position: relative;
- text-align: center;
- vertical-align: middle;
- width: 16px;
- height: 16px;
- padding-right: 4px;
-}
-
-.Select-clear-zone:hover .Select-clear {
- background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj48c3ZnIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxNCAxNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3BhY2U9InByZXNlcnZlIiBzdHlsZT0iZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjEuNDE0MjE7Ij4gICAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoMC4wMjM0Mzc1LDAsMCwwLjAyMzQzNzUsLTUuMDE1NjIsLTUuMDE1NjIpIj4gICAgICAgIDxwYXRoIGQ9Ik04MTAsMjc0TDU3Miw1MTJMODEwLDc1MEw3NTAsODEwTDUxMiw1NzJMMjc0LDgxMEwyMTQsNzUwTDQ1Miw1MTJMMjE0LDI3NEwyNzQsMjE0TDUxMiw0NTJMNzUwLDIxNEw4MTAsMjc0WiIgc3R5bGU9ImZpbGw6cmdiKDIzMSwyMCw1Nik7ZmlsbC1ydWxlOm5vbnplcm87Ii8+ICAgIDwvZz48L3N2Zz4=);
-}
-
-.Select-clear {
- display: block;
- width: 9px;
- height: 9px;
- background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj48c3ZnIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxNCAxNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3BhY2U9InByZXNlcnZlIiBzdHlsZT0iZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjEuNDE0MjE7Ij4gICAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoMC4wMjM0Mzc1LDAsMCwwLjAyMzQzNzUsLTUuMDE1NjIsLTUuMDE1NjIpIj4gICAgICAgIDxwYXRoIGQ9Ik04MTAsMjc0TDU3Miw1MTJMODEwLDc1MEw3NTAsODEwTDUxMiw1NzJMMjc0LDgxMEwyMTQsNzUwTDQ1Miw1MTJMMjE0LDI3NEwyNzQsMjE0TDUxMiw0NTJMNzUwLDIxNEw4MTAsMjc0WiIgc3R5bGU9ImZpbGw6cmdiKDE1MywxNTMsMTUzKTtmaWxsLXJ1bGU6bm9uemVybzsiLz4gICAgPC9nPjwvc3ZnPg==);
- background-size: 9px 9px;
- text-indent: -9999px;
-}
-
-.Select--multi .Select-clear-zone {
- width: 17px;
-}
-
-.Select-arrow-zone {
- cursor: pointer;
- display: table-cell;
- position: relative;
- text-align: center;
- vertical-align: middle;
- width: 20px;
- padding-right: 5px;
-}
-
-.Select-arrow {
- border-color: #999 transparent transparent;
- border-style: solid;
- border-width: 4px 4px 2px;
- display: inline-block;
- height: 0;
- width: 0;
-}
-
-.is-open .Select-arrow,
-.Select-arrow-zone:hover > .Select-arrow {
- border-top-color: #666;
-}
-
-@-webkit-keyframes Select-animation-fadeIn {
- from {
- opacity: 0;
- }
-
- to {
- opacity: 1;
- }
-}
-
-@keyframes Select-animation-fadeIn {
- from {
- opacity: 0;
- }
-
- to {
- opacity: 1;
- }
-}
-
-.Select-menu-outer {
- border-bottom-right-radius: 4px;
- border-bottom-left-radius: 4px;
- background-color: #fff;
- border: 1px solid #ccc;
- border-top-color: var(--barBorderColor);
- box-sizing: border-box;
- margin-top: -1px;
- max-height: 200px;
- position: absolute;
- top: 100%;
- width: 100%;
- z-index: var(--dropdownMenuZIndex);
- -webkit-overflow-scrolling: touch;
- box-shadow: var(--defaultShadow);
-}
-
-.Select-menu {
- max-height: 198px;
- padding: 5px 0;
- overflow-y: auto;
-}
-
-.Select-option {
- display: block;
- line-height: 20px;
- padding: 0 8px;
- box-sizing: border-box;
- color: var(--baseFontColor);
- font-size: var(--smallFontSize);
- cursor: pointer;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.Select-option:last-child {
- border-bottom-right-radius: 2px;
- border-bottom-left-radius: 2px;
-}
-
-.Select-option.is-focused {
- background-color: var(--barBackgroundColor);
-}
-
-.Select-option.is-disabled {
- font-weight: 600;
- cursor: default;
-}
-
-.Select-noresults {
- box-sizing: border-box;
- color: #999;
- cursor: default;
- display: block;
- padding: 8px 10px;
-}
-
-.Select--multi .Select-value {
- background-color: rgba(0, 126, 255, 0.08);
- border-radius: 2px;
- border: 1px solid rgba(0, 126, 255, 0.24);
- color: var(--baseFontColor);
- display: inline-block;
- font-size: var(--smallFontSize);
- line-height: 14px;
- margin: 1px 4px 1px 1px;
- vertical-align: top;
-}
-
-.Select-value-label {
- font-size: var(--smallFontSize);
-}
-
-.is-searchable.is-open .Select-value-label {
- opacity: 0.5;
-}
-
-.Select-big .Select-control {
- padding-top: 4px;
- padding-bottom: 4px;
-}
-
-.Select-big .Select-placeholder {
- margin-top: 4px;
- margin-bottom: 4px;
-}
-
-.Select-big .Select-value-label {
- display: inline-block;
- margin-top: 7px;
- line-height: 16px;
-}
-
-.Select-big .Select-option {
- padding: 7px 8px;
- line-height: 16px;
-}
-
-.Select-big img,
-.Select-big svg {
- padding-top: 0;
-}
-
-.Select--multi .Select-value-icon,
-.Select--multi .Select-value-label {
- display: inline-block;
- vertical-align: middle;
-}
-
-.Select--multi .Select-value-label {
- display: inline-block;
- max-width: 200px;
- border-bottom-right-radius: 2px;
- border-top-right-radius: 2px;
- cursor: default;
- padding: 2px 5px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.Select--multi a.Select-value-label {
- color: #007eff;
- cursor: pointer;
- text-decoration: none;
-}
-
-.Select--multi a.Select-value-label:hover {
- text-decoration: underline;
-}
-
-.Select--multi .Select-value-icon {
- cursor: pointer;
- border-bottom-left-radius: 2px;
- border-top-left-radius: 2px;
- border-right: 1px solid rgba(0, 126, 255, 0.24);
- padding: 1px 5px;
-}
-
-.Select--multi .Select-value-icon:hover,
-.Select--multi .Select-value-icon:focus {
- background-color: rgba(0, 113, 230, 0.08);
- color: #0071e6;
-}
-
-.Select--multi .Select-value-icon:active {
- background-color: rgba(0, 126, 255, 0.24);
-}
-
-.Select--multi.is-disabled .Select-value {
- background-color: #fcfcfc;
- border: 1px solid #e3e3e3;
- color: var(--baseFontColor);
-}
-
-.Select--multi.is-disabled .Select-value-icon {
- cursor: not-allowed;
- border-right: 1px solid #e3e3e3;
-}
-
-.Select--multi.is-disabled .Select-value-icon:hover,
-.Select--multi.is-disabled .Select-value-icon:focus,
-.Select--multi.is-disabled .Select-value-icon:active {
- background-color: #fcfcfc;
-}
-
-.Select-aria-only {
- display: none;
-}
-
-@keyframes Select-animation-spin {
- to {
- transform: rotate(1turn);
- }
-}
-
-@-webkit-keyframes Select-animation-spin {
- to {
- -webkit-transform: rotate(1turn);
- }
-}