]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-20364 Migrate SelectList component to new UI
authorJeremy Davis <jeremy.davis@sonarsource.com>
Wed, 6 Sep 2023 15:56:30 +0000 (17:56 +0200)
committersonartech <sonartech@sonarsource.com>
Wed, 13 Sep 2023 20:02:55 +0000 (20:02 +0000)
22 files changed:
server/sonar-web/design-system/src/components/ToggleButton.tsx
server/sonar-web/src/main/js/apps/groups/__tests__/GroupsApp-it.tsx
server/sonar-web/src/main/js/apps/groups/components/ViewMembersModal.tsx
server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/QualityGate-it.tsx
server/sonar-web/src/main/js/apps/quality-profiles/__tests__/QualityProfileApp-it.tsx
server/sonar-web/src/main/js/apps/users/__tests__/UsersApp-it.tsx
server/sonar-web/src/main/js/components/common/SelectList.tsx [deleted file]
server/sonar-web/src/main/js/components/common/SelectListItem.tsx [deleted file]
server/sonar-web/src/main/js/components/common/__tests__/SelectList-test.tsx [deleted file]
server/sonar-web/src/main/js/components/common/__tests__/SelectListItem-test.tsx [deleted file]
server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/SelectList-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/SelectListItem-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/components/controls/SelectList.css [deleted file]
server/sonar-web/src/main/js/components/controls/SelectList.tsx
server/sonar-web/src/main/js/components/controls/SelectListListContainer.tsx
server/sonar-web/src/main/js/components/controls/SelectListListElement.tsx
server/sonar-web/src/main/js/components/controls/__tests__/SelectList-test.tsx
server/sonar-web/src/main/js/components/controls/__tests__/SelectListListContainer-test.tsx [deleted file]
server/sonar-web/src/main/js/components/controls/__tests__/SelectListListElement-test.tsx [deleted file]
server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/SelectList-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/SelectListListContainer-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/SelectListListElement-test.tsx.snap [deleted file]

index edd5c17b99b02b925d7b602d43749ccffaec39fd..beff4d826f12f4cec6dabcbbdb36b4aab86085c4 100644 (file)
@@ -51,6 +51,7 @@ export function ToggleButton<T extends ToggleButtonValueType>(props: ButtonToggl
     <Wrapper aria-label={label} role={role}>
       {options.map((option) => (
         <OptionButton
+          aria-checked={isRadioGroup ? option.value === value : undefined}
           aria-controls={isRadioGroup ? undefined : getTabPanelId(String(option.value))}
           aria-current={option.value === value}
           data-value={option.value}
index bbd668a96324da6f1a48001d6bb680bead7853b7..d6e591c004b27b202cb6447d63f739eb548a386e 100644 (file)
@@ -38,9 +38,10 @@ const ui = {
   createGroupButton: byRole('button', { name: 'groups.create_group' }),
   infoManageMode: byText(/groups\.page\.managed_description/),
   description: byText('user_groups.page.description'),
-  allFilter: byRole('button', { name: 'all' }),
-  selectedFilter: byRole('button', { name: 'selected' }),
-  unselectedFilter: byRole('button', { name: 'unselected' }),
+  allFilter: byRole('radio', { name: 'all' }),
+  selectedFilter: byRole('radio', { name: 'selected' }),
+  unselectedFilter: byRole('radio', { name: 'unselected' }),
+  localAndManagedFilter: byRole('button', { name: 'all' }),
   managedFilter: byRole('button', { name: 'managed' }),
   localFilter: byRole('button', { name: 'local' }),
   searchInput: byRole('searchbox', { name: 'search.search_by_name' }),
@@ -296,7 +297,7 @@ describe('in manage mode', () => {
   it('should render list of all groups', async () => {
     renderGroupsApp();
 
-    await act(async () => expect(await ui.allFilter.find()).toBeInTheDocument());
+    await act(async () => expect(await ui.localAndManagedFilter.find()).toBeInTheDocument());
 
     expect(ui.localGroupRowWithLocalBadge.get()).toBeInTheDocument();
     expect(ui.managedGroupRow.get()).toBeInTheDocument();
index 45d10388dc623806258a07b37dbfd759d41785c3..b5af92b945ca2de674dd851d057a94cd0ee1a75c 100644 (file)
@@ -84,7 +84,7 @@ export default function ViewMembersModal(props: Props) {
           placeholder={translate('search_verb')}
           value={query}
         />
-        <div className="select-list-list-container spacer-top">
+        <div className="select-list-list-container spacer-top sw-overflow-auto">
           <Spinner loading={loading}>
             <ul className="menu">
               {users.map((user) => (
index 1cb05d54ce46f6ca5e23c147cb9790dcbb015148..bf92f73326a7161f3132c163573c1ceaad5e69ed 100644 (file)
@@ -450,11 +450,11 @@ describe('The Project section', () => {
     expect(screen.getAllByRole('checkbox')).toHaveLength(2);
 
     // change tabs to show deselected projects
-    await user.click(screen.getByRole('button', { name: 'quality_gates.projects.without' }));
+    await user.click(screen.getByRole('radio', { name: 'quality_gates.projects.without' }));
     expect(screen.getAllByRole('checkbox')).toHaveLength(2);
 
     // change tabs to show all projects
-    await user.click(screen.getByRole('button', { name: 'quality_gates.projects.all' }));
+    await user.click(screen.getByRole('radio', { name: 'quality_gates.projects.all' }));
     expect(screen.getAllByRole('checkbox')).toHaveLength(4);
   });
 
@@ -479,7 +479,7 @@ describe('The Project section', () => {
     expect(screen.getAllByRole('checkbox')).toHaveLength(1);
 
     // change tabs to show deselected projects
-    await user.click(screen.getByRole('button', { name: 'quality_gates.projects.without' }));
+    await user.click(screen.getByRole('radio', { name: 'quality_gates.projects.without' }));
 
     const uncheckedProjects = screen.getAllByRole('checkbox')[0];
     expect(screen.getAllByRole('checkbox')).toHaveLength(3);
index 0eab39edea89023f8e78a8aa33afb4520da6e078..33b5c34404354c0a35d82107fa34638eefb5aebe 100644 (file)
@@ -53,7 +53,7 @@ const ui = {
   closeButton: byRole('button', { name: 'close' }),
   changeProjectsButton: byRole('button', { name: 'quality_profiles.change_projects' }),
   changeButton: byRole('button', { name: 'change_verb' }),
-  withoutFilterButton: byRole('button', { name: 'quality_gates.projects.without' }),
+  withoutFilterButton: byRole('radio', { name: 'quality_gates.projects.without' }),
   changeParentButton: byRole('button', { name: 'quality_profiles.change_parent' }),
   qualityProfileActions: byRole('button', {
     name: /quality_profiles.actions/,
index 6f2fbe3eade6056e8a15684f26b276e4a3c54bbe..19fc0093fb079a0b6f37ee978bc5237ccab65bd4 100644 (file)
@@ -45,9 +45,7 @@ const authenticationHandler = new AuthenticationServiceMock();
 
 const ui = {
   createUserButton: byRole('button', { name: 'users.create_user' }),
-  allFilter: byRole('button', { name: 'all' }),
-  selectedFilter: byRole('button', { name: 'selected' }),
-  unselectedFilter: byRole('button', { name: 'unselected' }),
+  localAndManagedFilter: byRole('button', { name: 'all' }),
   managedFilter: byRole('button', { name: 'managed' }),
   localFilter: byRole('button', { name: 'local' }),
   showMore: byRole('button', { name: 'show_more' }),
@@ -100,6 +98,10 @@ const ui = {
   jackRow: byRole('row', { name: /Jack/ }),
 
   dialogGroups: byRole('dialog', { name: 'users.update_groups' }),
+  allFilter: byRole('radio', { name: 'all' }),
+  selectedFilter: byRole('radio', { name: 'selected' }),
+  unselectedFilter: byRole('radio', { name: 'unselected' }),
+
   getGroups: () => within(ui.dialogGroups.get()).getAllByRole('checkbox'),
   dialogTokens: byRole('dialog', { name: 'users.tokens' }),
   dialogPasswords: byRole('dialog', { name: 'my_profile.password.title' }),
@@ -206,7 +208,7 @@ describe('different filters combinations', () => {
     const user = userEvent.setup();
     renderUsersApp();
 
-    await act(async () => user.click(await ui.allFilter.find()));
+    await user.click(await ui.localAndManagedFilter.find());
     await act(async () => {
       await selectEvent.select(ui.activityFilter.get(), 'users.activity_filter.inactive_users');
     });
@@ -483,7 +485,7 @@ describe('in manage mode', () => {
   it('should render list of all users', async () => {
     renderUsersApp();
 
-    await act(async () => expect(await ui.allFilter.find()).toBeInTheDocument());
+    await act(async () => expect(await ui.localAndManagedFilter.find()).toBeInTheDocument());
 
     expect(ui.aliceRowWithLocalBadge.get()).toBeInTheDocument();
     expect(ui.bobRow.get()).toBeInTheDocument();
diff --git a/server/sonar-web/src/main/js/components/common/SelectList.tsx b/server/sonar-web/src/main/js/components/common/SelectList.tsx
deleted file mode 100644 (file)
index aeb502f..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-import classNames from 'classnames';
-import * as React from 'react';
-import SelectListItem from './SelectListItem';
-
-interface Props {
-  className?: string;
-  items: string[];
-  currentItem: string;
-  onSelect: (item: string) => void;
-}
-
-interface State {
-  active: string;
-}
-
-export default class SelectList extends React.PureComponent<Props, State> {
-  constructor(props: Props) {
-    super(props);
-    this.state = {
-      active: props.currentItem,
-    };
-  }
-
-  componentDidUpdate(prevProps: Props) {
-    if (
-      prevProps.currentItem !== this.props.currentItem &&
-      !this.props.items.includes(this.state.active)
-    ) {
-      this.setState({ active: this.props.currentItem });
-    }
-  }
-
-  handleSelect = (item: string) => {
-    this.props.onSelect(item);
-  };
-
-  renderChild = (child: any) => {
-    if (child == null) {
-      return null;
-    }
-    // do not pass extra props to children like `<li className="divider" />`
-    if (child.type !== SelectListItem) {
-      return child;
-    }
-    return React.cloneElement(child, {
-      active: this.state.active,
-      onSelect: this.handleSelect,
-    });
-  };
-
-  render() {
-    const { children } = this.props;
-    const hasChildren = React.Children.count(children) > 0;
-    return (
-      <ul className={classNames('menu', this.props.className)}>
-        {hasChildren && React.Children.map(children, this.renderChild)}
-        {!hasChildren &&
-          this.props.items.map((item) => (
-            <SelectListItem
-              active={this.state.active}
-              item={item}
-              key={item}
-              onSelect={this.handleSelect}
-            />
-          ))}
-      </ul>
-    );
-  }
-}
diff --git a/server/sonar-web/src/main/js/components/common/SelectListItem.tsx b/server/sonar-web/src/main/js/components/common/SelectListItem.tsx
deleted file mode 100644 (file)
index 7dc5481..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-import classNames from 'classnames';
-import * as React from 'react';
-import Tooltip from '../../components/controls/Tooltip';
-import { ButtonPlain } from '../controls/buttons';
-
-interface Props {
-  active?: string;
-  className?: string;
-  item: string;
-  onSelect?: (item: string) => void;
-  title?: React.ReactNode;
-}
-
-interface State {
-  selected: boolean;
-}
-
-export default class SelectListItem extends React.PureComponent<Props, State> {
-  constructor(props: Props) {
-    super(props);
-    this.state = {
-      selected: false,
-    };
-  }
-
-  handleSelect = () => {
-    if (this.props.onSelect) {
-      this.props.onSelect(this.props.item);
-    }
-  };
-
-  handleHover = () => {
-    this.setState({ selected: true });
-  };
-
-  handleBlur = () => {
-    this.setState({ selected: false });
-  };
-
-  renderLink() {
-    const children = this.props.children || this.props.item;
-    const { selected } = this.state;
-    return (
-      <li>
-        <ButtonPlain
-          preventDefault
-          aria-selected={this.props.active === this.props.item}
-          className={classNames(
-            {
-              active: this.props.active === this.props.item,
-              hover: selected,
-            },
-            this.props.className,
-          )}
-          onClick={this.handleSelect}
-          onFocus={this.handleHover}
-          onBlur={this.handleBlur}
-          onMouseOver={this.handleHover}
-          onMouseLeave={this.handleBlur}
-        >
-          {children}
-        </ButtonPlain>
-      </li>
-    );
-  }
-
-  render() {
-    return (
-      <Tooltip overlay={this.props.title || undefined} placement="right">
-        {this.renderLink()}
-      </Tooltip>
-    );
-  }
-}
diff --git a/server/sonar-web/src/main/js/components/common/__tests__/SelectList-test.tsx b/server/sonar-web/src/main/js/components/common/__tests__/SelectList-test.tsx
deleted file mode 100644 (file)
index cebedab..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import SelectList from '../SelectList';
-import SelectListItem from '../SelectListItem';
-
-it('should render correctly without children', () => {
-  const wrapper = shallowRender();
-  expect(wrapper).toMatchSnapshot();
-});
-
-it('should render correctly with children', () => {
-  const items = ['item', 'seconditem', 'third'];
-  const children = items.map((item) => (
-    <SelectListItem item={item} key={item}>
-      <i className="myicon" />
-      item
-    </SelectListItem>
-  ));
-  const wrapper = shallowRender({ items }, children);
-  expect(wrapper).toMatchSnapshot();
-});
-
-function shallowRender(props: Partial<SelectList['props']> = {}, children?: React.ReactNode) {
-  return shallow<SelectList>(
-    <SelectList
-      currentItem="seconditem"
-      items={['item', 'seconditem', 'third']}
-      onSelect={jest.fn()}
-      {...props}
-    >
-      {children}
-    </SelectList>,
-  );
-}
diff --git a/server/sonar-web/src/main/js/components/common/__tests__/SelectListItem-test.tsx b/server/sonar-web/src/main/js/components/common/__tests__/SelectListItem-test.tsx
deleted file mode 100644 (file)
index a4f27de..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import SelectListItem from '../SelectListItem';
-
-it('should render correctly without children', () => {
-  expect(shallow(<SelectListItem item="myitem" />)).toMatchSnapshot();
-});
-
-it('should render correctly with children', () => {
-  expect(
-    shallow(
-      <SelectListItem active="myitem" item="seconditem">
-        <i className="custom-icon" />
-        <p>seconditem</p>
-      </SelectListItem>,
-    ),
-  ).toMatchSnapshot();
-});
-
-it('should render correctly with a tooltip', () => {
-  expect(shallow(<SelectListItem item="myitem" title="my custom tooltip" />)).toMatchSnapshot();
-});
-
-it('should render with the active class', () => {
-  expect(shallow(<SelectListItem active="myitem" item="myitem" />)).toMatchSnapshot();
-});
diff --git a/server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/SelectList-test.tsx.snap b/server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/SelectList-test.tsx.snap
deleted file mode 100644 (file)
index 7066fe0..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly with children 1`] = `
-<ul
-  className="menu"
->
-  <SelectListItem
-    active="seconditem"
-    item="item"
-    key=".$item"
-    onSelect={[Function]}
-  >
-    <i
-      className="myicon"
-    />
-    item
-  </SelectListItem>
-  <SelectListItem
-    active="seconditem"
-    item="seconditem"
-    key=".$seconditem"
-    onSelect={[Function]}
-  >
-    <i
-      className="myicon"
-    />
-    item
-  </SelectListItem>
-  <SelectListItem
-    active="seconditem"
-    item="third"
-    key=".$third"
-    onSelect={[Function]}
-  >
-    <i
-      className="myicon"
-    />
-    item
-  </SelectListItem>
-</ul>
-`;
-
-exports[`should render correctly without children 1`] = `
-<ul
-  className="menu"
->
-  <SelectListItem
-    active="seconditem"
-    item="item"
-    key="item"
-    onSelect={[Function]}
-  />
-  <SelectListItem
-    active="seconditem"
-    item="seconditem"
-    key="seconditem"
-    onSelect={[Function]}
-  />
-  <SelectListItem
-    active="seconditem"
-    item="third"
-    key="third"
-    onSelect={[Function]}
-  />
-</ul>
-`;
diff --git a/server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/SelectListItem-test.tsx.snap b/server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/SelectListItem-test.tsx.snap
deleted file mode 100644 (file)
index 7ffbbc1..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly with a tooltip 1`] = `
-<Tooltip
-  overlay="my custom tooltip"
-  placement="right"
->
-  <li>
-    <ButtonPlain
-      aria-selected={false}
-      onBlur={[Function]}
-      onClick={[Function]}
-      onFocus={[Function]}
-      onMouseLeave={[Function]}
-      onMouseOver={[Function]}
-      preventDefault={true}
-    >
-      myitem
-    </ButtonPlain>
-  </li>
-</Tooltip>
-`;
-
-exports[`should render correctly with children 1`] = `
-<Tooltip
-  placement="right"
->
-  <li>
-    <ButtonPlain
-      aria-selected={false}
-      onBlur={[Function]}
-      onClick={[Function]}
-      onFocus={[Function]}
-      onMouseLeave={[Function]}
-      onMouseOver={[Function]}
-      preventDefault={true}
-    >
-      <i
-        className="custom-icon"
-      />
-      <p>
-        seconditem
-      </p>
-    </ButtonPlain>
-  </li>
-</Tooltip>
-`;
-
-exports[`should render correctly without children 1`] = `
-<Tooltip
-  placement="right"
->
-  <li>
-    <ButtonPlain
-      aria-selected={false}
-      onBlur={[Function]}
-      onClick={[Function]}
-      onFocus={[Function]}
-      onMouseLeave={[Function]}
-      onMouseOver={[Function]}
-      preventDefault={true}
-    >
-      myitem
-    </ButtonPlain>
-  </li>
-</Tooltip>
-`;
-
-exports[`should render with the active class 1`] = `
-<Tooltip
-  placement="right"
->
-  <li>
-    <ButtonPlain
-      aria-selected={true}
-      className="active"
-      onBlur={[Function]}
-      onClick={[Function]}
-      onFocus={[Function]}
-      onMouseLeave={[Function]}
-      onMouseOver={[Function]}
-      preventDefault={true}
-    >
-      myitem
-    </ButtonPlain>
-  </li>
-</Tooltip>
-`;
diff --git a/server/sonar-web/src/main/js/components/controls/SelectList.css b/server/sonar-web/src/main/js/components/controls/SelectList.css
deleted file mode 100644 (file)
index a43b420..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-.select-list-container {
-  min-width: 500px;
-  box-sizing: border-box;
-}
-
-.select-list-control {
-  margin-bottom: 10px;
-  box-sizing: border-box;
-}
-
-.select-list-list-container {
-  border: 1px solid #bfbfbf;
-  box-sizing: border-box;
-  height: 400px;
-  overflow: auto;
-}
-
-.select-list-list-checkbox {
-  display: flex !important;
-  align-items: center;
-}
-
-.select-list-list-checkbox i {
-  display: inline-block;
-  vertical-align: middle;
-  margin-right: 10px;
-}
-
-.select-list-list-disabled {
-  cursor: not-allowed;
-}
-
-.select-list-list-disabled > a {
-  pointer-events: none;
-}
-
-.select-list-list-item {
-  display: inline-block;
-  vertical-align: middle;
-}
index 3fa5ac1133671eb7ea395f5b9df2e51c256f154d..c8371cc6af613f912720c7fbe940aabe1bbc2cf3 100644 (file)
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
+import { InputSearch, PageContentFontWrapper, ToggleButton } from 'design-system';
 import * as React from 'react';
 import { translate } from '../../helpers/l10n';
-import ButtonToggle from './ButtonToggle';
 import ListFooter from './ListFooter';
-import SearchBox from './SearchBox';
-import './SelectList.css';
 import SelectListListContainer from './SelectListListContainer';
 
 export enum SelectListFilter {
@@ -145,11 +143,11 @@ export default class SelectList extends React.PureComponent<Props, State> {
     const disabled = this.state.lastSearchParams.query !== '';
 
     return (
-      <div className="select-list">
-        <div className="display-flex-center">
-          <span className="select-list-filter spacer-right">
-            <ButtonToggle
-              onCheck={this.changeFilter}
+      <PageContentFontWrapper className="it__select-list">
+        <div className="sw-flex sw-items-center">
+          <span className="sw-mr-2">
+            <ToggleButton
+              onChange={this.changeFilter}
               disabled={disabled}
               options={[
                 { label: labelSelected, value: SelectListFilter.Selected },
@@ -159,7 +157,7 @@ export default class SelectList extends React.PureComponent<Props, State> {
               value={filter}
             />
           </span>
-          <SearchBox
+          <InputSearch
             autoFocus={autoFocusSearch}
             loading={this.state.loading}
             onChange={this.handleQueryChange}
@@ -185,9 +183,10 @@ export default class SelectList extends React.PureComponent<Props, State> {
             needReload={this.props.needToReload}
             reload={this.onReload}
             total={this.props.elementsTotalCount}
+            useMIUIButtons
           />
         )}
-      </div>
+      </PageContentFontWrapper>
     );
   }
 }
index 0cf5c2657f4213e54aada1f71bf927b98675f110..033a6aeed1c0f8c8f40e88fa2f42893dea0d2aa8 100644 (file)
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
-import classNames from 'classnames';
+import styled from '@emotion/styled';
+import { Checkbox, ListItem, UnorderedList, themeBorder } from 'design-system';
 import { uniqueId } from 'lodash';
 import * as React from 'react';
 import { translate } from '../../helpers/l10n';
-import Spinner from '../ui/Spinner';
-import Checkbox from './Checkbox';
 import { SelectListFilter } from './SelectList';
 import SelectListListElement from './SelectListListElement';
 
@@ -84,22 +83,17 @@ export default class SelectListListContainer extends React.PureComponent<Props,
   renderBulkSelector() {
     const { elements, readOnly, selectedElements } = this.props;
     return (
-      <>
-        <li>
-          <Checkbox
-            checked={selectedElements.length > 0}
-            disabled={this.state.loading || readOnly}
-            onCheck={this.handleBulkChange}
-            thirdState={selectedElements.length > 0 && elements.length !== selectedElements.length}
-          >
-            <span className="big-spacer-left">
-              {translate('bulk_change')}
-              <Spinner className="spacer-left" loading={this.state.loading} />
-            </span>
-          </Checkbox>
-        </li>
-        <li className="divider" />
-      </>
+      <BorderedListItem className="sw-pb-4">
+        <Checkbox
+          checked={selectedElements.length > 0}
+          disabled={this.state.loading || readOnly}
+          onCheck={this.handleBulkChange}
+          thirdState={selectedElements.length > 0 && elements.length !== selectedElements.length}
+          loading={this.state.loading}
+        >
+          <span className="sw-ml-4">{translate('bulk_change')}</span>
+        </Checkbox>
+      </BorderedListItem>
     );
   }
 
@@ -107,8 +101,8 @@ export default class SelectListListContainer extends React.PureComponent<Props,
     const { allowBulkSelection, elements, filter } = this.props;
 
     return (
-      <div className={classNames('select-list-list-container spacer-top')}>
-        <ul className="menu">
+      <ListContainer className="sw-mt-2 sw-p-3 sw-rounded-1 it__select-list-list-container">
+        <UnorderedList className="-sw-mt-3">
           {allowBulkSelection &&
             elements.length > 0 &&
             filter === SelectListFilter.All &&
@@ -124,8 +118,18 @@ export default class SelectListListContainer extends React.PureComponent<Props,
               selected={this.isSelected(element)}
             />
           ))}
-        </ul>
-      </div>
+        </UnorderedList>
+      </ListContainer>
     );
   }
 }
+
+const BorderedListItem = styled(ListItem)`
+  border-bottom: ${themeBorder('default', 'discreetBorder')};
+`;
+
+const ListContainer = styled.div`
+  overflow: auto;
+  height: 330px;
+  border: ${themeBorder('default')};
+`;
index c6caffb50008c11aa8befd769429d521e6f9b4a9..80397494bb70cf3ba998466416589ed780141563 100644 (file)
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
-import classNames from 'classnames';
+import { Checkbox, ListItem } from 'design-system';
 import * as React from 'react';
-import Checkbox from './Checkbox';
 
 interface Props {
-  active?: boolean;
   disabled?: boolean;
   element: string;
   onSelect: (element: string) => Promise<void>;
@@ -31,60 +29,34 @@ interface Props {
   selected: boolean;
 }
 
-interface State {
-  loading: boolean;
-}
-
-export default class SelectListListElement extends React.PureComponent<Props, State> {
-  mounted = false;
-  state: State = { loading: false };
-
-  componentDidMount() {
-    this.mounted = true;
-  }
-
-  componentWillUnmount() {
-    this.mounted = false;
-  }
-
-  stopLoading = () => {
-    if (this.mounted) {
-      this.setState({ loading: false });
-    }
-  };
-
-  handleCheck = (checked: boolean) => {
-    this.setState({ loading: true });
-    const request = checked ? this.props.onSelect : this.props.onUnselect;
-    request(this.props.element).then(this.stopLoading, this.stopLoading);
-  };
-
-  render() {
-    let item = this.props.renderElement(this.props.element);
-    let extra;
-    if (Array.isArray(item)) {
-      extra = item[1];
-      item = item[0];
-    }
-    return (
-      <li
-        className={classNames('display-flex-center', {
-          'select-list-list-disabled': this.props.disabled,
-        })}
-      >
-        <Checkbox
-          checked={this.props.selected}
-          className={classNames('select-list-list-checkbox flex-1', {
-            active: this.props.active,
-          })}
-          disabled={this.props.disabled}
-          loading={this.state.loading}
-          onCheck={this.handleCheck}
-        >
-          <span className="little-spacer-left">{item}</span>
-        </Checkbox>
-        {extra && <span className="select-list-list-extra">{extra}</span>}
-      </li>
-    );
+export default function SelectListListElement(props: Props) {
+  const { disabled, element, onSelect, onUnselect, renderElement, selected } = props;
+
+  const [loading, setLoading] = React.useState(false);
+
+  const handleCheck = React.useCallback(
+    (checked: boolean) => {
+      setLoading(true);
+      const request = checked ? onSelect : onUnselect;
+      request(element)
+        .then(() => setLoading(false))
+        .catch(() => setLoading(false));
+    },
+    [element, setLoading, onSelect, onUnselect],
+  );
+
+  let item = renderElement(element);
+  let extra;
+  if (Array.isArray(item)) {
+    extra = item[1];
+    item = item[0];
   }
+  return (
+    <ListItem className="sw-flex sw-justify-between">
+      <Checkbox checked={selected} disabled={disabled} loading={loading} onCheck={handleCheck}>
+        <span className="sw-ml-4">{item}</span>
+      </Checkbox>
+      {extra && <span>{extra}</span>}
+    </ListItem>
+  );
 }
index 3e65b6b427edb78c04825f65d45cf16052237607..8809f104b1d3562188ac405e86500daf9f86e813 100644 (file)
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
-import { shallow } from 'enzyme';
+import userEvent from '@testing-library/user-event';
 import * as React from 'react';
-import { waitAndUpdate } from '../../../helpers/testUtils';
+import { renderComponent } from '../../../helpers/testReactTestingUtils';
+import { byRole, byText } from '../../../helpers/testSelector';
 import SelectList, { SelectListFilter } from '../SelectList';
 
 const elements = ['foo', 'bar', 'baz'];
 const selectedElements = [elements[0]];
 const disabledElements = [elements[1]];
 
-it('should display properly with basics features', async () => {
-  const wrapper = shallowRender();
-  await waitAndUpdate(wrapper);
-  expect(wrapper.instance().mounted).toBe(true);
+it('should render with extra', () => {
+  renderSelectList({ renderElement: (element) => [element, 'with extra'] });
 
-  expect(wrapper).toMatchSnapshot();
-
-  wrapper.instance().componentWillUnmount();
-  expect(wrapper.instance().mounted).toBe(false);
-});
-
-it('should display properly with advanced features', async () => {
-  const wrapper = shallowRender({
-    allowBulkSelection: true,
-    elementsTotalCount: 125,
-    pageSize: 10,
-    readOnly: true,
-    withPaging: true,
-  });
-  await waitAndUpdate(wrapper);
-
-  expect(wrapper).toMatchSnapshot();
-});
-
-it('should display a loader when searching', async () => {
-  const wrapper = shallowRender();
-  await waitAndUpdate(wrapper);
-  expect(wrapper.state().loading).toBe(false);
-
-  wrapper.instance().search({});
-  expect(wrapper.state().loading).toBe(true);
-  expect(wrapper).toMatchSnapshot();
-
-  await waitAndUpdate(wrapper);
-  expect(wrapper.state().loading).toBe(false);
+  expect(byText('with extra').getAll()).toHaveLength(3);
 });
 
 it('should cancel filter selection when search is active', async () => {
+  const user = userEvent.setup();
+
   const spy = jest.fn().mockResolvedValue({});
-  const wrapper = shallowRender({ onSearch: spy });
-  wrapper.instance().changeFilter(SelectListFilter.Unselected);
-  await waitAndUpdate(wrapper);
+  renderSelectList({ onSearch: spy });
+
+  await user.click(ui.filterToggle(SelectListFilter.Unselected).get());
 
   expect(spy).toHaveBeenCalledWith({
     query: '',
@@ -75,10 +47,11 @@ it('should cancel filter selection when search is active', async () => {
     page: undefined,
     pageSize: undefined,
   });
-  expect(wrapper).toMatchSnapshot();
 
   const query = 'test';
-  wrapper.instance().handleQueryChange(query);
+
+  await user.type(ui.searchInput.get(), query);
+
   expect(spy).toHaveBeenCalledWith({
     query,
     filter: SelectListFilter.All,
@@ -86,25 +59,24 @@ it('should cancel filter selection when search is active', async () => {
     pageSize: undefined,
   });
 
-  await waitAndUpdate(wrapper);
-  expect(wrapper).toMatchSnapshot();
+  await user.clear(ui.searchInput.get());
 
-  wrapper.instance().handleQueryChange('');
   expect(spy).toHaveBeenCalledWith({
     query: '',
     filter: SelectListFilter.Unselected,
     page: undefined,
     pageSize: undefined,
   });
-
-  await waitAndUpdate(wrapper);
-  expect(wrapper).toMatchSnapshot();
 });
 
-it('should display pagination element properly and call search method with correct parameters', () => {
+it('should display pagination element properly and call search method with correct parameters', async () => {
+  const user = userEvent.setup();
   const spy = jest.fn().mockResolvedValue({});
-  const wrapper = shallowRender({ elementsTotalCount: 100, onSearch: spy, withPaging: true });
-  expect(wrapper).toMatchSnapshot();
+  renderSelectList({
+    elementsTotalCount: 100,
+    onSearch: spy,
+    withPaging: true,
+  });
   expect(spy).toHaveBeenCalledWith({
     query: '',
     filter: SelectListFilter.Selected,
@@ -112,28 +84,46 @@ it('should display pagination element properly and call search method with corre
     pageSize: 100,
   }); // Basic default call
 
-  wrapper.instance().onLoadMore();
+  await user.click(ui.footerLoadMore.get());
+
   expect(spy).toHaveBeenCalledWith({
     query: '',
     filter: SelectListFilter.Selected,
     page: 2,
     pageSize: 100,
   }); // Load more call
+});
+
+it('should allow to reload when needed', async () => {
+  const user = userEvent.setup();
+  const spy = jest.fn().mockResolvedValue({});
+
+  renderSelectList({
+    elementsTotalCount: 100,
+    onSearch: spy,
+    needToReload: true,
+    withPaging: true,
+  });
 
-  wrapper.instance().onReload();
   expect(spy).toHaveBeenCalledWith({
     query: '',
     filter: SelectListFilter.Selected,
     page: 1,
     pageSize: 100,
-  }); // Reload call
+  }); // Basic default call
+
+  await user.click(await ui.footerReload.find());
 
-  wrapper.setProps({ needToReload: true });
-  expect(wrapper).toMatchSnapshot();
+  expect(spy).toHaveBeenCalledWith({
+    query: '',
+    filter: SelectListFilter.Selected,
+    page: 1,
+    pageSize: 100,
+  }); // Reload call
 });
 
-function shallowRender(props: Partial<SelectList['props']> = {}) {
-  return shallow<SelectList>(
+function renderSelectList(props: Partial<SelectList['props']> = {}) {
+  return renderComponent(
     <SelectList
       disabledElements={disabledElements}
       elements={elements}
@@ -146,3 +136,13 @@ function shallowRender(props: Partial<SelectList['props']> = {}) {
     />,
   );
 }
+
+const ui = {
+  filterToggle: (filter: SelectListFilter) =>
+    byRole('radio', { name: filter === SelectListFilter.Unselected ? 'unselected' : filter }),
+
+  searchInput: byRole('searchbox', { name: 'search_verb' }),
+
+  footerLoadMore: byRole('button', { name: 'show_more' }),
+  footerReload: byRole('button', { name: 'reload' }),
+};
diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/SelectListListContainer-test.tsx b/server/sonar-web/src/main/js/components/controls/__tests__/SelectListListContainer-test.tsx
deleted file mode 100644 (file)
index b88467f..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import { SelectListFilter } from '../SelectList';
-import SelectListListContainer from '../SelectListListContainer';
-
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot();
-});
-
-function shallowRender(props: Partial<SelectListListContainer['props']> = {}) {
-  return shallow(
-    <SelectListListContainer
-      allowBulkSelection
-      disabledElements={[]}
-      elements={['foo', 'bar', 'baz']}
-      filter={SelectListFilter.All}
-      onSelect={jest.fn(() => Promise.resolve())}
-      onUnselect={jest.fn(() => Promise.resolve())}
-      readOnly={false}
-      renderElement={(foo: string) => foo}
-      selectedElements={['foo']}
-      {...props}
-    />,
-  );
-}
diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/SelectListListElement-test.tsx b/server/sonar-web/src/main/js/components/controls/__tests__/SelectListListElement-test.tsx
deleted file mode 100644 (file)
index d3dbbe7..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import { waitAndUpdate } from '../../../helpers/testUtils';
-import SelectListListElement from '../SelectListListElement';
-
-it('should display a loader when checking', async () => {
-  const wrapper = shallowRender();
-  expect(wrapper).toMatchSnapshot('default');
-  expect(wrapper.state().loading).toBe(false);
-
-  wrapper.instance().handleCheck(true);
-  expect(wrapper.state().loading).toBe(true);
-  expect(wrapper).toMatchSnapshot('loading');
-
-  await waitAndUpdate(wrapper);
-  expect(wrapper.state().loading).toBe(false);
-});
-
-it('should correctly handle a render callback that returns 2 elements', () => {
-  const wrapper = shallowRender({
-    renderElement: (foo: string) => [foo, 'extra info'],
-  });
-  expect(wrapper.find('.select-list-list-extra').exists()).toBe(true);
-});
-
-function shallowRender(props: Partial<SelectListListElement['props']> = {}) {
-  return shallow<SelectListListElement>(
-    <SelectListListElement
-      element="foo"
-      key="foo"
-      onSelect={jest.fn(() => Promise.resolve())}
-      onUnselect={jest.fn(() => Promise.resolve())}
-      renderElement={(foo: string) => foo}
-      selected={false}
-      {...props}
-    />,
-  );
-}
diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/SelectList-test.tsx.snap b/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/SelectList-test.tsx.snap
deleted file mode 100644 (file)
index 3aad3eb..0000000
+++ /dev/null
@@ -1,550 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should cancel filter selection when search is active 1`] = `
-<div
-  className="select-list"
->
-  <div
-    className="display-flex-center"
-  >
-    <span
-      className="select-list-filter spacer-right"
-    >
-      <ButtonToggle
-        disabled={false}
-        onCheck={[Function]}
-        options={
-          [
-            {
-              "label": "selected",
-              "value": "selected",
-            },
-            {
-              "label": "unselected",
-              "value": "deselected",
-            },
-            {
-              "label": "all",
-              "value": "all",
-            },
-          ]
-        }
-        value="deselected"
-      />
-    </span>
-    <SearchBox
-      autoFocus={true}
-      loading={false}
-      onChange={[Function]}
-      placeholder="search_verb"
-      value=""
-    />
-  </div>
-  <SelectListListContainer
-    disabledElements={
-      [
-        "bar",
-      ]
-    }
-    elements={
-      [
-        "foo",
-        "bar",
-        "baz",
-      ]
-    }
-    filter="deselected"
-    onSelect={[MockFunction]}
-    onUnselect={[MockFunction]}
-    renderElement={[Function]}
-    selectedElements={
-      [
-        "foo",
-      ]
-    }
-  />
-</div>
-`;
-
-exports[`should cancel filter selection when search is active 2`] = `
-<div
-  className="select-list"
->
-  <div
-    className="display-flex-center"
-  >
-    <span
-      className="select-list-filter spacer-right"
-    >
-      <ButtonToggle
-        disabled={true}
-        onCheck={[Function]}
-        options={
-          [
-            {
-              "label": "selected",
-              "value": "selected",
-            },
-            {
-              "label": "unselected",
-              "value": "deselected",
-            },
-            {
-              "label": "all",
-              "value": "all",
-            },
-          ]
-        }
-        value="deselected"
-      />
-    </span>
-    <SearchBox
-      autoFocus={true}
-      loading={false}
-      onChange={[Function]}
-      placeholder="search_verb"
-      value="test"
-    />
-  </div>
-  <SelectListListContainer
-    disabledElements={
-      [
-        "bar",
-      ]
-    }
-    elements={
-      [
-        "foo",
-        "bar",
-        "baz",
-      ]
-    }
-    filter="all"
-    onSelect={[MockFunction]}
-    onUnselect={[MockFunction]}
-    renderElement={[Function]}
-    selectedElements={
-      [
-        "foo",
-      ]
-    }
-  />
-</div>
-`;
-
-exports[`should cancel filter selection when search is active 3`] = `
-<div
-  className="select-list"
->
-  <div
-    className="display-flex-center"
-  >
-    <span
-      className="select-list-filter spacer-right"
-    >
-      <ButtonToggle
-        disabled={false}
-        onCheck={[Function]}
-        options={
-          [
-            {
-              "label": "selected",
-              "value": "selected",
-            },
-            {
-              "label": "unselected",
-              "value": "deselected",
-            },
-            {
-              "label": "all",
-              "value": "all",
-            },
-          ]
-        }
-        value="deselected"
-      />
-    </span>
-    <SearchBox
-      autoFocus={true}
-      loading={false}
-      onChange={[Function]}
-      placeholder="search_verb"
-      value=""
-    />
-  </div>
-  <SelectListListContainer
-    disabledElements={
-      [
-        "bar",
-      ]
-    }
-    elements={
-      [
-        "foo",
-        "bar",
-        "baz",
-      ]
-    }
-    filter="deselected"
-    onSelect={[MockFunction]}
-    onUnselect={[MockFunction]}
-    renderElement={[Function]}
-    selectedElements={
-      [
-        "foo",
-      ]
-    }
-  />
-</div>
-`;
-
-exports[`should display a loader when searching 1`] = `
-<div
-  className="select-list"
->
-  <div
-    className="display-flex-center"
-  >
-    <span
-      className="select-list-filter spacer-right"
-    >
-      <ButtonToggle
-        disabled={false}
-        onCheck={[Function]}
-        options={
-          [
-            {
-              "label": "selected",
-              "value": "selected",
-            },
-            {
-              "label": "unselected",
-              "value": "deselected",
-            },
-            {
-              "label": "all",
-              "value": "all",
-            },
-          ]
-        }
-        value="selected"
-      />
-    </span>
-    <SearchBox
-      autoFocus={true}
-      loading={true}
-      onChange={[Function]}
-      placeholder="search_verb"
-      value=""
-    />
-  </div>
-  <SelectListListContainer
-    disabledElements={
-      [
-        "bar",
-      ]
-    }
-    elements={
-      [
-        "foo",
-        "bar",
-        "baz",
-      ]
-    }
-    filter="selected"
-    onSelect={[MockFunction]}
-    onUnselect={[MockFunction]}
-    renderElement={[Function]}
-    selectedElements={
-      [
-        "foo",
-      ]
-    }
-  />
-</div>
-`;
-
-exports[`should display pagination element properly and call search method with correct parameters 1`] = `
-<div
-  className="select-list"
->
-  <div
-    className="display-flex-center"
-  >
-    <span
-      className="select-list-filter spacer-right"
-    >
-      <ButtonToggle
-        disabled={false}
-        onCheck={[Function]}
-        options={
-          [
-            {
-              "label": "selected",
-              "value": "selected",
-            },
-            {
-              "label": "unselected",
-              "value": "deselected",
-            },
-            {
-              "label": "all",
-              "value": "all",
-            },
-          ]
-        }
-        value="selected"
-      />
-    </span>
-    <SearchBox
-      autoFocus={true}
-      loading={true}
-      onChange={[Function]}
-      placeholder="search_verb"
-      value=""
-    />
-  </div>
-  <SelectListListContainer
-    disabledElements={
-      [
-        "bar",
-      ]
-    }
-    elements={
-      [
-        "foo",
-        "bar",
-        "baz",
-      ]
-    }
-    filter="selected"
-    onSelect={[MockFunction]}
-    onUnselect={[MockFunction]}
-    renderElement={[Function]}
-    selectedElements={
-      [
-        "foo",
-      ]
-    }
-  />
-  <ListFooter
-    count={3}
-    loadMore={[Function]}
-    reload={[Function]}
-    total={100}
-  />
-</div>
-`;
-
-exports[`should display pagination element properly and call search method with correct parameters 2`] = `
-<div
-  className="select-list"
->
-  <div
-    className="display-flex-center"
-  >
-    <span
-      className="select-list-filter spacer-right"
-    >
-      <ButtonToggle
-        disabled={false}
-        onCheck={[Function]}
-        options={
-          [
-            {
-              "label": "selected",
-              "value": "selected",
-            },
-            {
-              "label": "unselected",
-              "value": "deselected",
-            },
-            {
-              "label": "all",
-              "value": "all",
-            },
-          ]
-        }
-        value="selected"
-      />
-    </span>
-    <SearchBox
-      autoFocus={true}
-      loading={true}
-      onChange={[Function]}
-      placeholder="search_verb"
-      value=""
-    />
-  </div>
-  <SelectListListContainer
-    disabledElements={
-      [
-        "bar",
-      ]
-    }
-    elements={
-      [
-        "foo",
-        "bar",
-        "baz",
-      ]
-    }
-    filter="selected"
-    onSelect={[MockFunction]}
-    onUnselect={[MockFunction]}
-    renderElement={[Function]}
-    selectedElements={
-      [
-        "foo",
-      ]
-    }
-  />
-  <ListFooter
-    count={3}
-    loadMore={[Function]}
-    needReload={true}
-    reload={[Function]}
-    total={100}
-  />
-</div>
-`;
-
-exports[`should display properly with advanced features 1`] = `
-<div
-  className="select-list"
->
-  <div
-    className="display-flex-center"
-  >
-    <span
-      className="select-list-filter spacer-right"
-    >
-      <ButtonToggle
-        disabled={false}
-        onCheck={[Function]}
-        options={
-          [
-            {
-              "label": "selected",
-              "value": "selected",
-            },
-            {
-              "label": "unselected",
-              "value": "deselected",
-            },
-            {
-              "label": "all",
-              "value": "all",
-            },
-          ]
-        }
-        value="selected"
-      />
-    </span>
-    <SearchBox
-      autoFocus={true}
-      loading={false}
-      onChange={[Function]}
-      placeholder="search_verb"
-      value=""
-    />
-  </div>
-  <SelectListListContainer
-    allowBulkSelection={true}
-    disabledElements={
-      [
-        "bar",
-      ]
-    }
-    elements={
-      [
-        "foo",
-        "bar",
-        "baz",
-      ]
-    }
-    filter="selected"
-    onSelect={[MockFunction]}
-    onUnselect={[MockFunction]}
-    readOnly={true}
-    renderElement={[Function]}
-    selectedElements={
-      [
-        "foo",
-      ]
-    }
-  />
-  <ListFooter
-    count={3}
-    loadMore={[Function]}
-    reload={[Function]}
-    total={125}
-  />
-</div>
-`;
-
-exports[`should display properly with basics features 1`] = `
-<div
-  className="select-list"
->
-  <div
-    className="display-flex-center"
-  >
-    <span
-      className="select-list-filter spacer-right"
-    >
-      <ButtonToggle
-        disabled={false}
-        onCheck={[Function]}
-        options={
-          [
-            {
-              "label": "selected",
-              "value": "selected",
-            },
-            {
-              "label": "unselected",
-              "value": "deselected",
-            },
-            {
-              "label": "all",
-              "value": "all",
-            },
-          ]
-        }
-        value="selected"
-      />
-    </span>
-    <SearchBox
-      autoFocus={true}
-      loading={false}
-      onChange={[Function]}
-      placeholder="search_verb"
-      value=""
-    />
-  </div>
-  <SelectListListContainer
-    disabledElements={
-      [
-        "bar",
-      ]
-    }
-    elements={
-      [
-        "foo",
-        "bar",
-        "baz",
-      ]
-    }
-    filter="selected"
-    onSelect={[MockFunction]}
-    onUnselect={[MockFunction]}
-    renderElement={[Function]}
-    selectedElements={
-      [
-        "foo",
-      ]
-    }
-  />
-</div>
-`;
diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/SelectListListContainer-test.tsx.snap b/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/SelectListListContainer-test.tsx.snap
deleted file mode 100644 (file)
index ecbe4c9..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<div
-  className="select-list-list-container spacer-top"
->
-  <ul
-    className="menu"
-  >
-    <li>
-      <Checkbox
-        checked={true}
-        disabled={false}
-        onCheck={[Function]}
-        thirdState={true}
-      >
-        <span
-          className="big-spacer-left"
-        >
-          bulk_change
-          <Spinner
-            className="spacer-left"
-            loading={false}
-          />
-        </span>
-      </Checkbox>
-    </li>
-    <li
-      className="divider"
-    />
-    <SelectListListElement
-      disabled={false}
-      element="foo"
-      key="1"
-      onSelect={[MockFunction]}
-      onUnselect={[MockFunction]}
-      renderElement={[Function]}
-      selected={true}
-    />
-    <SelectListListElement
-      disabled={false}
-      element="bar"
-      key="2"
-      onSelect={[MockFunction]}
-      onUnselect={[MockFunction]}
-      renderElement={[Function]}
-      selected={false}
-    />
-    <SelectListListElement
-      disabled={false}
-      element="baz"
-      key="3"
-      onSelect={[MockFunction]}
-      onUnselect={[MockFunction]}
-      renderElement={[Function]}
-      selected={false}
-    />
-  </ul>
-</div>
-`;
diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/SelectListListElement-test.tsx.snap b/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/SelectListListElement-test.tsx.snap
deleted file mode 100644 (file)
index 9acb096..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should display a loader when checking: default 1`] = `
-<li
-  className="display-flex-center"
->
-  <Checkbox
-    checked={false}
-    className="select-list-list-checkbox flex-1"
-    loading={false}
-    onCheck={[Function]}
-    thirdState={false}
-  >
-    <span
-      className="little-spacer-left"
-    >
-      foo
-    </span>
-  </Checkbox>
-</li>
-`;
-
-exports[`should display a loader when checking: loading 1`] = `
-<li
-  className="display-flex-center"
->
-  <Checkbox
-    checked={false}
-    className="select-list-list-checkbox flex-1"
-    loading={true}
-    onCheck={[Function]}
-    thirdState={false}
-  >
-    <span
-      className="little-spacer-left"
-    >
-      foo
-    </span>
-  </Checkbox>
-</li>
-`;