Various UX improvements

This commit is contained in:
mabashian 2019-09-09 12:53:53 -04:00
parent a3a5db1c44
commit 1f8f4e184b
18 changed files with 429 additions and 169 deletions

View File

@ -22,6 +22,7 @@ class AddResourceRole extends React.Component {
selectedResourceRows: [],
selectedRoleRows: [],
currentStepId: 1,
maxEnabledStep: 1,
};
this.handleResourceCheckboxClick = this.handleResourceCheckboxClick.bind(
@ -31,10 +32,11 @@ class AddResourceRole extends React.Component {
this.handleRoleCheckboxClick = this.handleRoleCheckboxClick.bind(this);
this.handleWizardNext = this.handleWizardNext.bind(this);
this.handleWizardSave = this.handleWizardSave.bind(this);
this.handleWizardGoToStep = this.handleWizardGoToStep.bind(this);
}
handleResourceCheckboxClick(user) {
const { selectedResourceRows } = this.state;
const { selectedResourceRows, currentStepId } = this.state;
const selectedIndex = selectedResourceRows.findIndex(
selectedRow => selectedRow.id === user.id
@ -42,7 +44,11 @@ class AddResourceRole extends React.Component {
if (selectedIndex > -1) {
selectedResourceRows.splice(selectedIndex, 1);
this.setState({ selectedResourceRows });
let stateToUpdate = { selectedResourceRows };
if (selectedResourceRows.length === 0) {
stateToUpdate.maxEnabledStep = currentStepId;
}
this.setState(stateToUpdate);
} else {
this.setState(prevState => ({
selectedResourceRows: [...prevState.selectedResourceRows, user],
@ -76,6 +82,13 @@ class AddResourceRole extends React.Component {
}
handleWizardNext(step) {
this.setState({
currentStepId: step.id,
maxEnabledStep: step.id,
});
}
handleWizardGoToStep(step) {
this.setState({
currentStepId: step.id,
});
@ -125,6 +138,7 @@ class AddResourceRole extends React.Component {
selectedResourceRows,
selectedRoleRows,
currentStepId,
maxEnabledStep,
} = this.state;
const { onClose, roles, i18n } = this.props;
@ -162,9 +176,14 @@ class AddResourceRole extends React.Component {
const steps = [
{
id: 1,
name: i18n._(t`Select Users Or Teams`),
name: i18n._(t`Select a Resource Type`),
component: (
<div style={{ display: 'flex' }}>
<div style={{ display: 'flex', flexWrap: 'wrap' }}>
<div style={{ width: '100%', marginBottom: '10px' }}>
{i18n._(
t`Choose the type of resource that will be receiving new roles. For example, if you'd like to add new roles to a set of users please choose Users and click Next. You'll be able to select the specific resources in the next step.`
)}
</div>
<SelectableCard
isSelected={selectedResource === 'users'}
label={i18n._(t`Users`)}
@ -181,7 +200,7 @@ class AddResourceRole extends React.Component {
},
{
id: 2,
name: i18n._(t`Select items from list`),
name: i18n._(t`Select Items from List`),
component: (
<Fragment>
{selectedResource === 'users' && (
@ -209,10 +228,11 @@ class AddResourceRole extends React.Component {
</Fragment>
),
enableNext: selectedResourceRows.length > 0,
canJumpTo: maxEnabledStep >= 2,
},
{
id: 3,
name: i18n._(t`Apply roles`),
name: i18n._(t`Select Roles to Apply`),
component: (
<SelectRoleStep
onRolesClick={this.handleRoleCheckboxClick}
@ -225,6 +245,7 @@ class AddResourceRole extends React.Component {
),
nextButtonText: i18n._(t`Save`),
enableNext: selectedRoleRows.length > 0,
canJumpTo: maxEnabledStep >= 3,
},
];
@ -238,6 +259,7 @@ class AddResourceRole extends React.Component {
onNext={this.handleWizardNext}
onClose={onClose}
onSave={this.handleWizardSave}
onGoToStep={this.handleWizardGoToStep}
steps={steps}
title={wizardTitle}
nextButtonText={currentStep.nextButtonText || undefined}

View File

@ -152,6 +152,7 @@ describe('<_AddResourceRole />', () => {
selectedResourceRows: [],
selectedRoleRows: [],
currentStepId: 1,
maxEnabledStep: 1,
});
wrapper.instance().handleResourceSelect('teams');
expect(wrapper.state()).toEqual({
@ -159,6 +160,7 @@ describe('<_AddResourceRole />', () => {
selectedResourceRows: [],
selectedRoleRows: [],
currentStepId: 1,
maxEnabledStep: 1,
});
});
test('handleWizardSave makes correct api calls, calls onSave when done', async () => {

View File

@ -83,6 +83,11 @@ class SelectResourceStep extends React.Component {
{isLoading && <div>{i18n._(t`Loading...`)}</div>}
{isInitialized && (
<Fragment>
<div>
{i18n._(
t`Choose the resources that will be receiving new roles. You'll be able to select the roles to apply in the next step. Note that the resources chosen here will receive all roles chosen in the next step.`
)}
</div>
{selectedResourceRows.length > 0 && (
<SelectedList
displayKey={displayKey}
@ -108,9 +113,7 @@ class SelectResourceStep extends React.Component {
onSelect={() => onRowClick(item)}
/>
)}
renderToolbar={props => (
<DataListToolbar {...props} alignToolbarLeft />
)}
renderToolbar={props => <DataListToolbar {...props} fillWidth />}
showPageSizeOptions={false}
/>
</Fragment>

View File

@ -21,6 +21,11 @@ class RolesStep extends React.Component {
return (
<Fragment>
<div>
{i18n._(
t`Choose roles to apply to the selected resources. Note that all selected roles will be applied to all selected resources.`
)}
</div>
<div>
{selectedResourceRows.length > 0 && (
<SelectedList

View File

@ -4,9 +4,9 @@ import {
DataListItem,
DataListItemRow,
DataListItemCells,
DataListCheck,
DataListCell,
} from '@patternfly/react-core';
import DataListCheck from '@components/DataListCheck';
import DataListRadio from '@components/DataListRadio';
import VerticalSeparator from '../VerticalSeparator';

View File

@ -0,0 +1,9 @@
import { DataListCheck as PFDataListCheck } from '@patternfly/react-core';
import styled from 'styled-components';
export default styled(PFDataListCheck)`
.pf-c-data-list__check {
display: flex;
align-items: center;
}
`;

View File

@ -0,0 +1,10 @@
import React from 'react';
import { mount } from 'enzyme';
import DataListCheck from './DataListCheck';
describe('DataListCheck', () => {
test('renders the expected content', () => {
const wrapper = mount(<DataListCheck checked aria-labelledby="Checkbox" />);
expect(wrapper).toHaveLength(1);
});
});

View File

@ -0,0 +1 @@
export { default } from './DataListCheck';

View File

@ -14,7 +14,7 @@ import {
Button,
ButtonVariant,
InputGroup as PFInputGroup,
Modal as PFModal,
Modal,
} from '@patternfly/react-core';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
@ -27,6 +27,13 @@ import SelectedList from '../SelectedList';
import { ChipGroup, Chip } from '../Chip';
import { getQSConfig, parseQueryString } from '../../util/qs';
const SearchButton = styled(Button)`
::after {
border: var(--pf-c-button--BorderWidth) solid
var(--pf-global--BorderColor--200);
}
`;
const InputGroup = styled(PFInputGroup)`
${props =>
props.multiple &&
@ -36,8 +43,9 @@ const InputGroup = styled(PFInputGroup)`
`}
`;
const Modal = styled(PFModal)`
--pf-c-modal-box--body--MinHeight: 460px;
const ChipHolder = styled.div`
--pf-c-form-control--BorderTopColor: var(--pf-global--BorderColor--200);
--pf-c-form-control--BorderRightColor: var(--pf-global--BorderColor--200);
`;
class Lookup extends React.Component {
@ -211,15 +219,15 @@ class Lookup extends React.Component {
return (
<Fragment>
<InputGroup onBlur={onBlur}>
<Button
<SearchButton
aria-label="Search"
id={id}
onClick={this.handleModalToggle}
variant={ButtonVariant.tertiary}
>
<SearchIcon />
</Button>
<div className="pf-c-form-control">{chips}</div>
</SearchButton>
<ChipHolder className="pf-c-form-control">{chips}</ChipHolder>
</InputGroup>
<Modal
className="awx-c-modal"

View File

@ -92,7 +92,7 @@ class PageHeaderToolbar extends Component {
/>
</ToolbarItem>
</Tooltip>
<Tooltip position="left" content={<div>User</div>}>
<Tooltip position="left" content={<div>{i18n._(t`User`)}</div>}>
<ToolbarItem>
<Dropdown
isPlain

View File

@ -19,6 +19,10 @@ const Tabs = styled(PFTabs)`
}
}
.pf-c-tabs__item.pf-m-current .pf-c-tabs__button {
font-weight: bold;
}
&:not(.pf-c-tabs__item)::before {
position: absolute;
top: 0;

View File

@ -19,11 +19,17 @@ import styled from 'styled-components';
const TextInput = styled(PFTextInput)`
min-height: 0px;
height: 30px;
--pf-c-form-control--BorderTopColor: var(--pf-global--BorderColor--200);
--pf-c-form-control--BorderLeftColor: var(--pf-global--BorderColor--200);
`;
const Button = styled(PFButton)`
width: 34px;
padding: 0px;
::after {
border: var(--pf-c-button--BorderWidth) solid
var(--pf-global--BorderColor--200);
}
`;
const Dropdown = styled(PFDropdown)`
@ -36,6 +42,10 @@ const Dropdown = styled(PFDropdown)`
padding: 0 10px;
margin: 0px;
::before {
border-color: var(--pf-global--BorderColor--200);
}
> span {
/* text element */
width: auto;
@ -53,7 +63,7 @@ const Dropdown = styled(PFDropdown)`
const NoOptionDropdown = styled.div`
align-self: stretch;
border: 1px solid grey;
border: 1px solid var(--pf-global--BorderColor--200);
padding: 3px 7px;
white-space: nowrap;
`;

View File

@ -8,6 +8,7 @@ import {
DropdownPosition,
DropdownToggle,
DropdownItem,
Tooltip,
} from '@patternfly/react-core';
import {
SortAlphaDownIcon,
@ -48,6 +49,21 @@ const IconWrapper = styled.span`
}
`;
const SortButton = styled(Button)`
padding: 5px 8px;
margin-top: 3px;
&:hover {
background-color: #0166cc;
color: white;
}
`;
const SortBy = styled.span`
margin-right: 15px;
font-size: var(--pf-global--FontSize--md);
`;
class Sort extends React.Component {
constructor(props) {
super(props);
@ -112,33 +128,40 @@ class Sort extends React.Component {
return (
<React.Fragment>
{sortDropdownItems.length > 1 && (
<Dropdown
style={{ marginRight: '20px' }}
onToggle={this.handleDropdownToggle}
onSelect={this.handleDropdownSelect}
direction={up}
isOpen={isSortDropdownOpen}
toggle={
<DropdownToggle
id="awx-sort"
onToggle={this.handleDropdownToggle}
>
{sortedColumnName}
</DropdownToggle>
}
dropdownItems={sortDropdownItems}
/>
<React.Fragment>
<SortBy>{i18n._(t`Sort By`)}</SortBy>
<Dropdown
style={{ marginRight: '10px' }}
onToggle={this.handleDropdownToggle}
onSelect={this.handleDropdownSelect}
direction={up}
isOpen={isSortDropdownOpen}
toggle={
<DropdownToggle
id="awx-sort"
onToggle={this.handleDropdownToggle}
>
{sortedColumnName}
</DropdownToggle>
}
dropdownItems={sortDropdownItems}
/>
</React.Fragment>
)}
<Button
onClick={this.handleSort}
variant="plain"
aria-label={i18n._(t`Sort`)}
css="padding: 0;"
<Tooltip
content={<div>{i18n._(t`Reverse Sort Order`)}</div>}
position="top"
>
<IconWrapper>
<SortIcon />
</IconWrapper>
</Button>
<SortButton
onClick={this.handleSort}
variant="plain"
aria-label={i18n._(t`Sort`)}
>
<IconWrapper>
<SortIcon style={{ verticalAlign: '-0.225em' }} />
</IconWrapper>
</SortButton>
</Tooltip>
</React.Fragment>
);
}

View File

@ -4,9 +4,9 @@ import {
DataListItem,
DataListItemRow,
DataListItemCells,
DataListCheck,
} from '@patternfly/react-core';
import DataListCell from '@components/DataListCell';
import DataListCheck from '@components/DataListCheck';
import VerticalSeparator from '@components/VerticalSeparator';
import { toTitleCase } from '@util/strings';
import { JOB_TYPE_URL_SEGMENTS } from '../../../constants';

View File

@ -7,12 +7,12 @@ import {
DataListItem,
DataListItemRow,
DataListItemCells,
DataListCheck,
} from '@patternfly/react-core';
import { Link } from 'react-router-dom';
import styled from 'styled-components';
import DataListCell from '@components/DataListCell';
import DataListCheck from '@components/DataListCheck';
import VerticalSeparator from '@components/VerticalSeparator';
import { Organization } from '@types';

View File

@ -466,9 +466,9 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
"$$typeof": Symbol(react.forward_ref),
"attrs": Array [],
"componentStyle": ComponentStyle {
"componentId": "sc-htpNat",
"componentId": "sc-bwzfXH",
"isStatic": false,
"lastClassName": "dnOsXG",
"lastClassName": "fPRqXT",
"rules": Array [
"flex-grow:1;margin-left:20px;margin-right:20px;",
[Function],
@ -479,7 +479,7 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
"DataListToolbar__Toolbar-ajzso8-1",
],
"render": [Function],
"styledComponentId": "sc-htpNat",
"styledComponentId": "sc-bwzfXH",
"target": [Function],
"toString": [Function],
"warnTooManyClasses": [Function],
@ -490,11 +490,11 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
>
<Toolbar
_css=""
className="DataListToolbar__Toolbar-ajzso8-1 sc-htpNat dnOsXG"
className="DataListToolbar__Toolbar-ajzso8-1 sc-bwzfXH fPRqXT"
>
<div
_css=""
className="pf-l-toolbar DataListToolbar__Toolbar-ajzso8-1 sc-htpNat dnOsXG"
className="pf-l-toolbar DataListToolbar__Toolbar-ajzso8-1 sc-bwzfXH fPRqXT"
>
<DataListToolbar__ColumnLeft
fillWidth={false}
@ -541,9 +541,9 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
"$$typeof": Symbol(react.forward_ref),
"attrs": Array [],
"componentStyle": ComponentStyle {
"componentId": "sc-bxivhb",
"componentId": "sc-htpNat",
"isStatic": true,
"lastClassName": "gYEJOJ",
"lastClassName": "dqEVhr",
"rules": Array [
"flex-grow: 1;",
],
@ -551,7 +551,7 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
"displayName": "Styled(ToolbarItem)",
"foldedComponentIds": Array [],
"render": [Function],
"styledComponentId": "sc-bxivhb",
"styledComponentId": "sc-htpNat",
"target": [Function],
"toString": [Function],
"warnTooManyClasses": [Function],
@ -561,10 +561,10 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
forwardedRef={null}
>
<ToolbarItem
className="sc-bxivhb gYEJOJ"
className="sc-htpNat dqEVhr"
>
<div
className="pf-l-toolbar__item sc-bxivhb gYEJOJ"
className="pf-l-toolbar__item sc-htpNat dqEVhr"
>
<WithI18n
columns={
@ -643,9 +643,9 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
"componentStyle": ComponentStyle {
"componentId": "Search__NoOptionDropdown-sc-1dwuww3-3",
"isStatic": true,
"lastClassName": "gMeiYd",
"lastClassName": "iMdtNX",
"rules": Array [
"align-self:stretch;border:1px solid grey;padding:3px 7px;white-space:nowrap;",
"align-self:stretch;border:1px solid var(--pf-global--BorderColor--200);padding:3px 7px;white-space:nowrap;",
],
},
"displayName": "Search__NoOptionDropdown",
@ -661,7 +661,7 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
forwardedRef={null}
>
<div
className="Search__NoOptionDropdown-sc-1dwuww3-3 gMeiYd"
className="Search__NoOptionDropdown-sc-1dwuww3-3 iMdtNX"
>
Name
</div>
@ -780,9 +780,9 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
"componentStyle": ComponentStyle {
"componentId": "Search__TextInput-sc-1dwuww3-0",
"isStatic": true,
"lastClassName": "EgkYH",
"lastClassName": "kyQbZs",
"rules": Array [
"min-height:0px;height:30px;",
"min-height:0px;height:30px;--pf-c-form-control--BorderTopColor:var(--pf-global--BorderColor--200);--pf-c-form-control--BorderLeftColor:var(--pf-global--BorderColor--200);",
],
},
"displayName": "Search__TextInput",
@ -807,7 +807,7 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
>
<TextInput
aria-label="Search text input"
className="Search__TextInput-sc-1dwuww3-0 EgkYH"
className="Search__TextInput-sc-1dwuww3-0 kyQbZs"
isDisabled={false}
isReadOnly={false}
isRequired={false}
@ -824,7 +824,7 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
<input
aria-invalid={false}
aria-label="Search text input"
className="pf-c-form-control Search__TextInput-sc-1dwuww3-0 EgkYH"
className="pf-c-form-control Search__TextInput-sc-1dwuww3-0 kyQbZs"
disabled={false}
onChange={[Function]}
readOnly={false}
@ -859,9 +859,9 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
"componentStyle": ComponentStyle {
"componentId": "Search__Button-sc-1dwuww3-1",
"isStatic": true,
"lastClassName": "jtZPEu",
"lastClassName": "bLlonv",
"rules": Array [
"width:34px;padding:0px;",
"width:34px;padding:0px;::after{border:var(--pf-c-button--BorderWidth) solid var(--pf-global--BorderColor--200);}",
],
},
"displayName": "Search__Button",
@ -881,7 +881,7 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
>
<Button
aria-label="Search submit button"
className="Search__Button-sc-1dwuww3-1 jtZPEu"
className="Search__Button-sc-1dwuww3-1 bLlonv"
onClick={[Function]}
type="submit"
variant="tertiary"
@ -889,7 +889,7 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
<button
aria-disabled={null}
aria-label="Search submit button"
className="pf-c-button pf-m-tertiary Search__Button-sc-1dwuww3-1 jtZPEu"
className="pf-c-button pf-m-tertiary Search__Button-sc-1dwuww3-1 bLlonv"
disabled={false}
onClick={[Function]}
tabIndex={null}
@ -1072,6 +1072,39 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
sortOrder="ascending"
sortedColumnKey="name"
>
<Sort__SortBy>
<StyledComponent
forwardedComponent={
Object {
"$$typeof": Symbol(react.forward_ref),
"attrs": Array [],
"componentStyle": ComponentStyle {
"componentId": "Sort__SortBy-sc-21g5aw-3",
"isStatic": true,
"lastClassName": "kxjfOq",
"rules": Array [
"margin-right:15px;font-size:var(--pf-global--FontSize--md);",
],
},
"displayName": "Sort__SortBy",
"foldedComponentIds": Array [],
"render": [Function],
"styledComponentId": "Sort__SortBy-sc-21g5aw-3",
"target": "span",
"toString": [Function],
"warnTooManyClasses": [Function],
"withComponent": [Function],
}
}
forwardedRef={null}
>
<span
className="Sort__SortBy-sc-21g5aw-3 kxjfOq"
>
Sort By
</span>
</StyledComponent>
</Sort__SortBy>
<Sort__Dropdown
dropdownItems={
Array [
@ -1092,7 +1125,7 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
onToggle={[Function]}
style={
Object {
"marginRight": "20px",
"marginRight": "10px",
}
}
toggle={
@ -1147,7 +1180,7 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
onToggle={[Function]}
style={
Object {
"marginRight": "20px",
"marginRight": "10px",
}
}
toggle={
@ -1180,7 +1213,7 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
onToggle={[Function]}
style={
Object {
"marginRight": "20px",
"marginRight": "10px",
}
}
toggle={
@ -1217,7 +1250,7 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
position="left"
style={
Object {
"marginRight": "20px",
"marginRight": "10px",
}
}
toggle={
@ -1234,7 +1267,7 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
onToggle={[Function]}
style={
Object {
"marginRight": "20px",
"marginRight": "10px",
}
}
>
@ -1250,7 +1283,7 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
Object {
"current": <div
class="pf-c-dropdown Sort__Dropdown-sc-21g5aw-0 kdSQuN"
style="margin-right: 20px;"
style="margin-right: 10px;"
>
<button
aria-expanded="false"
@ -1301,7 +1334,7 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
Object {
"current": <div
class="pf-c-dropdown Sort__Dropdown-sc-21g5aw-0 kdSQuN"
style="margin-right: 20px;"
style="margin-right: 10px;"
>
<button
aria-expanded="false"
@ -1386,116 +1419,245 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
</Dropdown>
</StyledComponent>
</Sort__Dropdown>
<Styled(Button)
aria-label="Sort"
onClick={[Function]}
variant="plain"
<Tooltip
appendTo={[Function]}
aria="describedby"
boundary="window"
className=""
content={
<div>
Reverse Sort Order
</div>
}
distance={15}
enableFlip={true}
entryDelay={500}
exitDelay={500}
flipBehavior={
Array [
"top",
"right",
"bottom",
"left",
"top",
"right",
"bottom",
]
}
isAppLauncher={false}
maxWidth="18.75rem"
position="top"
trigger="mouseenter focus"
zIndex={9999}
>
<StyledComponent
aria-label="Sort"
forwardedComponent={
<PopoverBase
animateFill={false}
appendTo={[Function]}
aria="describedby"
arrow={true}
boundary="window"
content={
<div
className=""
role="tooltip"
>
<TooltipContent>
<div>
Reverse Sort Order
</div>
</TooltipContent>
</div>
}
delay={
Array [
500,
500,
]
}
distance={15}
flip={true}
flipBehavior={
Array [
"top",
"right",
"bottom",
"left",
"top",
"right",
"bottom",
]
}
lazy={true}
maxWidth="18.75rem"
onCreate={[Function]}
performance={true}
placement="top"
popperOptions={
Object {
"$$typeof": Symbol(react.forward_ref),
"attrs": Array [],
"componentStyle": ComponentStyle {
"componentId": "sc-bwzfXH",
"isStatic": true,
"lastClassName": "iNPUwu",
"rules": Array [
"padding: 0;",
],
"modifiers": Object {
"hide": Object {
"enabled": true,
},
"preventOverflow": Object {
"enabled": true,
},
},
"displayName": "Styled(Button)",
"foldedComponentIds": Array [],
"render": [Function],
"styledComponentId": "sc-bwzfXH",
"target": [Function],
"toString": [Function],
"warnTooManyClasses": [Function],
"withComponent": [Function],
}
}
forwardedRef={null}
onClick={[Function]}
variant="plain"
theme="pf-tooltip"
trigger="mouseenter focus"
zIndex={9999}
>
<Button
<Sort__SortButton
aria-label="Sort"
className="sc-bwzfXH iNPUwu"
onClick={[Function]}
variant="plain"
>
<button
aria-disabled={null}
<StyledComponent
aria-label="Sort"
className="pf-c-button pf-m-plain sc-bwzfXH iNPUwu"
disabled={false}
forwardedComponent={
Object {
"$$typeof": Symbol(react.forward_ref),
"attrs": Array [],
"componentStyle": ComponentStyle {
"componentId": "Sort__SortButton-sc-21g5aw-2",
"isStatic": true,
"lastClassName": "FZjfT",
"rules": Array [
"padding:5px 8px;margin-top:3px;&:hover{background-color:#0166cc;color:white;}",
],
},
"displayName": "Sort__SortButton",
"foldedComponentIds": Array [],
"render": [Function],
"styledComponentId": "Sort__SortButton-sc-21g5aw-2",
"target": [Function],
"toString": [Function],
"warnTooManyClasses": [Function],
"withComponent": [Function],
}
}
forwardedRef={null}
onClick={[Function]}
tabIndex={null}
type="button"
variant="plain"
>
<Sort__IconWrapper>
<StyledComponent
forwardedComponent={
Object {
"$$typeof": Symbol(react.forward_ref),
"attrs": Array [],
"componentStyle": ComponentStyle {
"componentId": "Sort__IconWrapper-sc-21g5aw-1",
"isStatic": true,
"lastClassName": "fTwElO",
"rules": Array [
"> svg{font-size:18px;}",
],
},
"displayName": "Sort__IconWrapper",
"foldedComponentIds": Array [],
"render": [Function],
"styledComponentId": "Sort__IconWrapper-sc-21g5aw-1",
"target": "span",
"toString": [Function],
"warnTooManyClasses": [Function],
"withComponent": [Function],
}
}
forwardedRef={null}
<Button
aria-label="Sort"
className="Sort__SortButton-sc-21g5aw-2 FZjfT"
onClick={[Function]}
variant="plain"
>
<button
aria-disabled={null}
aria-label="Sort"
className="pf-c-button pf-m-plain Sort__SortButton-sc-21g5aw-2 FZjfT"
disabled={false}
onClick={[Function]}
tabIndex={null}
type="button"
>
<span
className="Sort__IconWrapper-sc-21g5aw-1 fTwElO"
>
<SortAlphaUpIcon
color="currentColor"
noVerticalAlign={false}
size="sm"
title={null}
>
<svg
aria-hidden={true}
aria-labelledby={null}
fill="currentColor"
height="1em"
role="img"
style={
Object {
"verticalAlign": "-0.125em",
}
<Sort__IconWrapper>
<StyledComponent
forwardedComponent={
Object {
"$$typeof": Symbol(react.forward_ref),
"attrs": Array [],
"componentStyle": ComponentStyle {
"componentId": "Sort__IconWrapper-sc-21g5aw-1",
"isStatic": true,
"lastClassName": "fTwElO",
"rules": Array [
"> svg{font-size:18px;}",
],
},
"displayName": "Sort__IconWrapper",
"foldedComponentIds": Array [],
"render": [Function],
"styledComponentId": "Sort__IconWrapper-sc-21g5aw-1",
"target": "span",
"toString": [Function],
"warnTooManyClasses": [Function],
"withComponent": [Function],
}
viewBox="0 0 448 512"
width="1em"
}
forwardedRef={null}
>
<span
className="Sort__IconWrapper-sc-21g5aw-1 fTwElO"
>
<path
d="M107.3 36.7c-6.2-6.2-16.4-6.2-22.6 0l-80 80c-10 10-2.9 27.3 11.3 27.3h48v320c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V144h48c14.2 0 21.4-17.2 11.3-27.3zm293.4 390.4h-61.1c.7-1 1.5-2 2.3-3.1l67.5-95.7c1.4-2 2.2-4.4 2.2-6.9V300c0-6.6-5.4-12-12-12H274.5c-6.6 0-12 5.4-12 12v28.9c0 6.6 5.4 12 12 12H331c-.7 1-1.5 2-2.3 3.1l-67.2 95.2c-1.4 2-2.2 4.4-2.2 6.9V468c0 6.6 5.4 12 12 12h129.4c6.6 0 12-5.4 12-12v-28.9c0-6.7-5.4-12-12-12zm23.5-219l-57.1-168c-1.7-4.9-6.2-8.1-11.4-8.1h-39.6c-5.1 0-9.7 3.3-11.4 8.1l-57.1 168c-2.6 7.8 3.1 15.9 11.4 15.9h35.7c5.4 0 10.1-3.5 11.5-8.7l8.1-28.2h42.9l8.3 28.3A12 12 0 0 0 377 224h35.7c8.4 0 14.2-8.1 11.5-15.9zm-95-71.5l6.8-22.9 6.6 22.9z"
transform=""
/>
</svg>
</SortAlphaUpIcon>
</span>
</StyledComponent>
</Sort__IconWrapper>
</button>
</Button>
</StyledComponent>
</Styled(Button)>
<SortAlphaUpIcon
color="currentColor"
noVerticalAlign={false}
size="sm"
style={
Object {
"verticalAlign": "-0.225em",
}
}
title={null}
>
<svg
aria-hidden={true}
aria-labelledby={null}
fill="currentColor"
height="1em"
role="img"
style={
Object {
"verticalAlign": "-0.225em",
}
}
viewBox="0 0 448 512"
width="1em"
>
<path
d="M107.3 36.7c-6.2-6.2-16.4-6.2-22.6 0l-80 80c-10 10-2.9 27.3 11.3 27.3h48v320c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V144h48c14.2 0 21.4-17.2 11.3-27.3zm293.4 390.4h-61.1c.7-1 1.5-2 2.3-3.1l67.5-95.7c1.4-2 2.2-4.4 2.2-6.9V300c0-6.6-5.4-12-12-12H274.5c-6.6 0-12 5.4-12 12v28.9c0 6.6 5.4 12 12 12H331c-.7 1-1.5 2-2.3 3.1l-67.2 95.2c-1.4 2-2.2 4.4-2.2 6.9V468c0 6.6 5.4 12 12 12h129.4c6.6 0 12-5.4 12-12v-28.9c0-6.7-5.4-12-12-12zm23.5-219l-57.1-168c-1.7-4.9-6.2-8.1-11.4-8.1h-39.6c-5.1 0-9.7 3.3-11.4 8.1l-57.1 168c-2.6 7.8 3.1 15.9 11.4 15.9h35.7c5.4 0 10.1-3.5 11.5-8.7l8.1-28.2h42.9l8.3 28.3A12 12 0 0 0 377 224h35.7c8.4 0 14.2-8.1 11.5-15.9zm-95-71.5l6.8-22.9 6.6 22.9z"
transform=""
/>
</svg>
</SortAlphaUpIcon>
</span>
</StyledComponent>
</Sort__IconWrapper>
</button>
</Button>
</StyledComponent>
</Sort__SortButton>
<Portal
containerInfo={
<div>
<div
class=""
role="tooltip"
>
<div
class="pf-c-tooltip__content"
>
<div>
Reverse Sort Order
</div>
</div>
</div>
</div>
}
>
<div
className=""
role="tooltip"
>
<TooltipContent>
<div
className="pf-c-tooltip__content"
>
<div>
Reverse Sort Order
</div>
</div>
</TooltipContent>
</div>
</Portal>
</PopoverBase>
</Tooltip>
</Sort>
</I18n>
</WithI18n>

View File

@ -4,7 +4,6 @@ import {
DataListItem,
DataListItemRow,
DataListItemCells,
DataListCheck,
Tooltip,
Button as PFButton,
} from '@patternfly/react-core';
@ -14,6 +13,7 @@ import { RocketIcon } from '@patternfly/react-icons';
import styled from 'styled-components';
import DataListCell from '@components/DataListCell';
import DataListCheck from '@components/DataListCheck';
import LaunchButton from '@components/LaunchButton';
import VerticalSeparator from '@components/VerticalSeparator';
import { Sparkline } from '@components/Sparkline';

View File

@ -123,7 +123,8 @@ describe('<TemplatesList />', () => {
el => el.state('hasContentLoading') === false
);
await wrapper
.find('DataListCheck#select-jobTemplate-1')
.find('input#select-jobTemplate-1')
.closest('DataListCheck')
.props()
.onChange();
expect(handleSelect).toBeCalled();