mirror of
https://github.com/ansible/awx.git
synced 2026-02-17 11:10:03 -03:30
Adds edit buttons to Templates, Inventories, Organizations, and Projects list items when the user has edit capabilities.
This commit is contained in:
@@ -0,0 +1,8 @@
|
|||||||
|
import DataListCell from '@components/DataListCell';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
export default styled(DataListCell)`
|
||||||
|
& > :not(:first-child) {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { mount } from 'enzyme';
|
||||||
|
import ActionButtonCell from './ActionButtonCell';
|
||||||
|
|
||||||
|
describe('ActionButtonCell', () => {
|
||||||
|
test('renders the expected content', () => {
|
||||||
|
const wrapper = mount(<ActionButtonCell />);
|
||||||
|
expect(wrapper).toHaveLength(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
1
awx/ui_next/src/components/ActionButtonCell/index.js
Normal file
1
awx/ui_next/src/components/ActionButtonCell/index.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export { default } from './ActionButtonCell';
|
||||||
@@ -5,12 +5,16 @@ import {
|
|||||||
DataListItem,
|
DataListItem,
|
||||||
DataListItemRow,
|
DataListItemRow,
|
||||||
DataListItemCells,
|
DataListItemCells,
|
||||||
|
Tooltip,
|
||||||
} from '@patternfly/react-core';
|
} from '@patternfly/react-core';
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
import { PencilAltIcon } from '@patternfly/react-icons';
|
||||||
|
|
||||||
|
import ActionButtonCell from '@components/ActionButtonCell';
|
||||||
import DataListCell from '@components/DataListCell';
|
import DataListCell from '@components/DataListCell';
|
||||||
import DataListCheck from '@components/DataListCheck';
|
import DataListCheck from '@components/DataListCheck';
|
||||||
|
import ListActionButton from '@components/ListActionButton';
|
||||||
import VerticalSeparator from '@components/VerticalSeparator';
|
import VerticalSeparator from '@components/VerticalSeparator';
|
||||||
import { Inventory } from '@types';
|
import { Inventory } from '@types';
|
||||||
|
|
||||||
@@ -47,6 +51,23 @@ class InventoryListItem extends React.Component {
|
|||||||
? i18n._(t`Smart Inventory`)
|
? i18n._(t`Smart Inventory`)
|
||||||
: i18n._(t`Inventory`)}
|
: i18n._(t`Inventory`)}
|
||||||
</DataListCell>,
|
</DataListCell>,
|
||||||
|
<ActionButtonCell lastcolumn="true" key="action">
|
||||||
|
{inventory.summary_fields.user_capabilities.edit && (
|
||||||
|
<Tooltip content={i18n._(t`Edit Inventory`)} position="top">
|
||||||
|
<ListActionButton
|
||||||
|
variant="plain"
|
||||||
|
component={Link}
|
||||||
|
to={`/inventories/${
|
||||||
|
inventory.kind === 'smart'
|
||||||
|
? 'smart_inventory'
|
||||||
|
: 'inventory'
|
||||||
|
}/${inventory.id}/edit`}
|
||||||
|
>
|
||||||
|
<PencilAltIcon />
|
||||||
|
</ListActionButton>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
</ActionButtonCell>,
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
</DataListItemRow>
|
</DataListItemRow>
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ describe('<InventoryListItem />', () => {
|
|||||||
id: 1,
|
id: 1,
|
||||||
name: 'Default',
|
name: 'Default',
|
||||||
},
|
},
|
||||||
|
user_capabilities: {
|
||||||
|
edit: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
detailUrl="/inventories/inventory/1"
|
detailUrl="/inventories/inventory/1"
|
||||||
@@ -28,4 +31,58 @@ describe('<InventoryListItem />', () => {
|
|||||||
</I18nProvider>
|
</I18nProvider>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
test('edit button shown to users with edit capabilities', () => {
|
||||||
|
const wrapper = mountWithContexts(
|
||||||
|
<I18nProvider>
|
||||||
|
<MemoryRouter initialEntries={['/inventories']} initialIndex={0}>
|
||||||
|
<InventoryListItem
|
||||||
|
inventory={{
|
||||||
|
id: 1,
|
||||||
|
name: 'Inventory',
|
||||||
|
summary_fields: {
|
||||||
|
organization: {
|
||||||
|
id: 1,
|
||||||
|
name: 'Default',
|
||||||
|
},
|
||||||
|
user_capabilities: {
|
||||||
|
edit: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
detailUrl="/inventories/inventory/1"
|
||||||
|
isSelected
|
||||||
|
onSelect={() => {}}
|
||||||
|
/>
|
||||||
|
</MemoryRouter>
|
||||||
|
</I18nProvider>
|
||||||
|
);
|
||||||
|
expect(wrapper.find('PencilAltIcon').exists()).toBeTruthy();
|
||||||
|
});
|
||||||
|
test('edit button hidden from users without edit capabilities', () => {
|
||||||
|
const wrapper = mountWithContexts(
|
||||||
|
<I18nProvider>
|
||||||
|
<MemoryRouter initialEntries={['/inventories']} initialIndex={0}>
|
||||||
|
<InventoryListItem
|
||||||
|
inventory={{
|
||||||
|
id: 1,
|
||||||
|
name: 'Inventory',
|
||||||
|
summary_fields: {
|
||||||
|
organization: {
|
||||||
|
id: 1,
|
||||||
|
name: 'Default',
|
||||||
|
},
|
||||||
|
user_capabilities: {
|
||||||
|
edit: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
detailUrl="/inventories/inventory/1"
|
||||||
|
isSelected
|
||||||
|
onSelect={() => {}}
|
||||||
|
/>
|
||||||
|
</MemoryRouter>
|
||||||
|
</I18nProvider>
|
||||||
|
);
|
||||||
|
expect(wrapper.find('PencilAltIcon').exists()).toBeFalsy();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,12 +7,16 @@ import {
|
|||||||
DataListItem,
|
DataListItem,
|
||||||
DataListItemRow,
|
DataListItemRow,
|
||||||
DataListItemCells,
|
DataListItemCells,
|
||||||
|
Tooltip,
|
||||||
} from '@patternfly/react-core';
|
} from '@patternfly/react-core';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
import { PencilAltIcon } from '@patternfly/react-icons';
|
||||||
|
|
||||||
|
import ActionButtonCell from '@components/ActionButtonCell';
|
||||||
import DataListCell from '@components/DataListCell';
|
import DataListCell from '@components/DataListCell';
|
||||||
import DataListCheck from '@components/DataListCheck';
|
import DataListCheck from '@components/DataListCheck';
|
||||||
|
import ListActionButton from '@components/ListActionButton';
|
||||||
import VerticalSeparator from '@components/VerticalSeparator';
|
import VerticalSeparator from '@components/VerticalSeparator';
|
||||||
import { Organization } from '@types';
|
import { Organization } from '@types';
|
||||||
|
|
||||||
@@ -66,11 +70,7 @@ class OrganizationListItem extends React.Component {
|
|||||||
</Link>
|
</Link>
|
||||||
</span>
|
</span>
|
||||||
</DataListCell>,
|
</DataListCell>,
|
||||||
<DataListCell
|
<DataListCell key="related-field-counts">
|
||||||
key="related-field-counts"
|
|
||||||
righthalf="true"
|
|
||||||
width={2}
|
|
||||||
>
|
|
||||||
<ListGroup>
|
<ListGroup>
|
||||||
{i18n._(t`Members`)}
|
{i18n._(t`Members`)}
|
||||||
<Badge isRead>
|
<Badge isRead>
|
||||||
@@ -84,6 +84,22 @@ class OrganizationListItem extends React.Component {
|
|||||||
</Badge>
|
</Badge>
|
||||||
</ListGroup>
|
</ListGroup>
|
||||||
</DataListCell>,
|
</DataListCell>,
|
||||||
|
<ActionButtonCell lastcolumn="true" key="action">
|
||||||
|
{organization.summary_fields.user_capabilities.edit && (
|
||||||
|
<Tooltip
|
||||||
|
content={i18n._(t`Edit Organization`)}
|
||||||
|
position="top"
|
||||||
|
>
|
||||||
|
<ListActionButton
|
||||||
|
variant="plain"
|
||||||
|
component={Link}
|
||||||
|
to={`/organizations/${organization.id}/edit`}
|
||||||
|
>
|
||||||
|
<PencilAltIcon />
|
||||||
|
</ListActionButton>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
</ActionButtonCell>,
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
</DataListItemRow>
|
</DataListItemRow>
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ describe('<OrganizationListItem />', () => {
|
|||||||
users: 1,
|
users: 1,
|
||||||
teams: 1,
|
teams: 1,
|
||||||
},
|
},
|
||||||
|
user_capabilities: {
|
||||||
|
edit: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
detailUrl="/organization/1"
|
detailUrl="/organization/1"
|
||||||
@@ -30,4 +33,58 @@ describe('<OrganizationListItem />', () => {
|
|||||||
</I18nProvider>
|
</I18nProvider>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
test('edit button shown to users with edit capabilities', () => {
|
||||||
|
const wrapper = mountWithContexts(
|
||||||
|
<I18nProvider>
|
||||||
|
<MemoryRouter initialEntries={['/organizations']} initialIndex={0}>
|
||||||
|
<OrganizationListItem
|
||||||
|
organization={{
|
||||||
|
id: 1,
|
||||||
|
name: 'Org',
|
||||||
|
summary_fields: {
|
||||||
|
related_field_counts: {
|
||||||
|
users: 1,
|
||||||
|
teams: 1,
|
||||||
|
},
|
||||||
|
user_capabilities: {
|
||||||
|
edit: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
detailUrl="/organization/1"
|
||||||
|
isSelected
|
||||||
|
onSelect={() => {}}
|
||||||
|
/>
|
||||||
|
</MemoryRouter>
|
||||||
|
</I18nProvider>
|
||||||
|
);
|
||||||
|
expect(wrapper.find('PencilAltIcon').exists()).toBeTruthy();
|
||||||
|
});
|
||||||
|
test('edit button hidden from users without edit capabilities', () => {
|
||||||
|
const wrapper = mountWithContexts(
|
||||||
|
<I18nProvider>
|
||||||
|
<MemoryRouter initialEntries={['/organizations']} initialIndex={0}>
|
||||||
|
<OrganizationListItem
|
||||||
|
organization={{
|
||||||
|
id: 1,
|
||||||
|
name: 'Org',
|
||||||
|
summary_fields: {
|
||||||
|
related_field_counts: {
|
||||||
|
users: 1,
|
||||||
|
teams: 1,
|
||||||
|
},
|
||||||
|
user_capabilities: {
|
||||||
|
edit: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
detailUrl="/organization/1"
|
||||||
|
isSelected
|
||||||
|
onSelect={() => {}}
|
||||||
|
/>
|
||||||
|
</MemoryRouter>
|
||||||
|
</I18nProvider>
|
||||||
|
);
|
||||||
|
expect(wrapper.find('PencilAltIcon').exists()).toBeFalsy();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,10 +8,14 @@ import {
|
|||||||
Tooltip,
|
Tooltip,
|
||||||
} from '@patternfly/react-core';
|
} from '@patternfly/react-core';
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import { PencilAltIcon, SyncIcon } from '@patternfly/react-icons';
|
||||||
|
|
||||||
import { Link as _Link } from 'react-router-dom';
|
import { Link as _Link } from 'react-router-dom';
|
||||||
import { SyncIcon } from '@patternfly/react-icons';
|
import { SyncIcon } from '@patternfly/react-icons';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
import ActionButtonCell from '@components/ActionButtonCell';
|
||||||
import ClipboardCopyButton from '@components/ClipboardCopyButton';
|
import ClipboardCopyButton from '@components/ClipboardCopyButton';
|
||||||
import DataListCell from '@components/DataListCell';
|
import DataListCell from '@components/DataListCell';
|
||||||
import DataListCheck from '@components/DataListCheck';
|
import DataListCheck from '@components/DataListCheck';
|
||||||
@@ -21,12 +25,6 @@ import { StatusIcon } from '@components/Sparkline';
|
|||||||
import VerticalSeparator from '@components/VerticalSeparator';
|
import VerticalSeparator from '@components/VerticalSeparator';
|
||||||
import { Project } from '@types';
|
import { Project } from '@types';
|
||||||
|
|
||||||
/* eslint-disable react/jsx-pascal-case */
|
|
||||||
const Link = styled(props => <_Link {...props} />)`
|
|
||||||
margin-right: 10px;
|
|
||||||
`;
|
|
||||||
/* eslint-enable react/jsx-pascal-case */
|
|
||||||
|
|
||||||
class ProjectListItem extends React.Component {
|
class ProjectListItem extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
project: Project.isRequired,
|
project: Project.isRequired,
|
||||||
@@ -61,6 +59,11 @@ class ProjectListItem extends React.Component {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
handleEditClick = project => {
|
||||||
|
const { history } = this.props;
|
||||||
|
history.push(`/projects/${project.id}/edit`);
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { project, isSelected, onSelect, detailUrl, i18n } = this.props;
|
const { project, isSelected, onSelect, detailUrl, i18n } = this.props;
|
||||||
const labelId = `check-action-${project.id}`;
|
const labelId = `check-action-${project.id}`;
|
||||||
@@ -94,11 +97,13 @@ class ProjectListItem extends React.Component {
|
|||||||
</Link>
|
</Link>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
<span id={labelId}>
|
<Link
|
||||||
<Link to={`${detailUrl}`}>
|
id={labelId}
|
||||||
<b>{project.name}</b>
|
to={`${detailUrl}`}
|
||||||
</Link>
|
style={{ marginLeft: '10px' }}
|
||||||
</span>
|
>
|
||||||
|
<b>{project.name}</b>
|
||||||
|
</Link>
|
||||||
</DataListCell>,
|
</DataListCell>,
|
||||||
<DataListCell key="type">
|
<DataListCell key="type">
|
||||||
{project.scm_type.toUpperCase()}
|
{project.scm_type.toUpperCase()}
|
||||||
@@ -113,7 +118,7 @@ class ProjectListItem extends React.Component {
|
|||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
</DataListCell>,
|
</DataListCell>,
|
||||||
<DataListCell lastcolumn="true" key="action">
|
<ActionButtonCell lastcolumn="true" key="action">
|
||||||
{project.summary_fields.user_capabilities.start && (
|
{project.summary_fields.user_capabilities.start && (
|
||||||
<Tooltip content={i18n._(t`Sync Project`)} position="top">
|
<Tooltip content={i18n._(t`Sync Project`)} position="top">
|
||||||
<ProjectSyncButton projectId={project.id}>
|
<ProjectSyncButton projectId={project.id}>
|
||||||
@@ -125,7 +130,18 @@ class ProjectListItem extends React.Component {
|
|||||||
</ProjectSyncButton>
|
</ProjectSyncButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
</DataListCell>,
|
{project.summary_fields.user_capabilities.edit && (
|
||||||
|
<Tooltip content={i18n._(t`Edit Project`)} position="top">
|
||||||
|
<ListActionButton
|
||||||
|
variant="plain"
|
||||||
|
component={Link}
|
||||||
|
to={`/projects/${project.id}/edit`}
|
||||||
|
>
|
||||||
|
<PencilAltIcon />
|
||||||
|
</ListActionButton>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
</ActionButtonCell>,
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
</DataListItemRow>
|
</DataListItemRow>
|
||||||
|
|||||||
@@ -59,4 +59,56 @@ describe('<ProjectsListItem />', () => {
|
|||||||
);
|
);
|
||||||
expect(wrapper.find('ProjectSyncButton').exists()).toBeFalsy();
|
expect(wrapper.find('ProjectSyncButton').exists()).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
test('edit button shown to users with edit capabilities', () => {
|
||||||
|
const wrapper = mountWithContexts(
|
||||||
|
<ProjectsListItem
|
||||||
|
isSelected={false}
|
||||||
|
detailUrl="/project/1"
|
||||||
|
onSelect={() => {}}
|
||||||
|
project={{
|
||||||
|
id: 1,
|
||||||
|
name: 'Project 1',
|
||||||
|
url: '/api/v2/projects/1',
|
||||||
|
type: 'project',
|
||||||
|
scm_type: 'git',
|
||||||
|
summary_fields: {
|
||||||
|
last_job: {
|
||||||
|
id: 9000,
|
||||||
|
status: 'successful',
|
||||||
|
},
|
||||||
|
user_capabilities: {
|
||||||
|
edit: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
expect(wrapper.find('PencilAltIcon').exists()).toBeTruthy();
|
||||||
|
});
|
||||||
|
test('edit button hidden from users without edit capabilities', () => {
|
||||||
|
const wrapper = mountWithContexts(
|
||||||
|
<ProjectsListItem
|
||||||
|
isSelected={false}
|
||||||
|
detailUrl="/project/1"
|
||||||
|
onSelect={() => {}}
|
||||||
|
project={{
|
||||||
|
id: 1,
|
||||||
|
name: 'Project 1',
|
||||||
|
url: '/api/v2/projects/1',
|
||||||
|
type: 'project',
|
||||||
|
scm_type: 'git',
|
||||||
|
summary_fields: {
|
||||||
|
last_job: {
|
||||||
|
id: 9000,
|
||||||
|
status: 'successful',
|
||||||
|
},
|
||||||
|
user_capabilities: {
|
||||||
|
edit: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
expect(wrapper.find('PencilAltIcon').exists()).toBeFalsy();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,8 +8,9 @@ import {
|
|||||||
} from '@patternfly/react-core';
|
} from '@patternfly/react-core';
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import { withI18n } from '@lingui/react';
|
import { withI18n } from '@lingui/react';
|
||||||
import { RocketIcon } from '@patternfly/react-icons';
|
import { PencilAltIcon, RocketIcon } from '@patternfly/react-icons';
|
||||||
|
|
||||||
|
import ActionButtonCell from '@components/ActionButtonCell';
|
||||||
import DataListCell from '@components/DataListCell';
|
import DataListCell from '@components/DataListCell';
|
||||||
import DataListCheck from '@components/DataListCheck';
|
import DataListCheck from '@components/DataListCheck';
|
||||||
import LaunchButton from '@components/LaunchButton';
|
import LaunchButton from '@components/LaunchButton';
|
||||||
@@ -20,6 +21,16 @@ import { toTitleCase } from '@util/strings';
|
|||||||
|
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const rightStyle = `
|
||||||
|
@media screen and (max-width: 768px) {
|
||||||
|
&& {
|
||||||
|
padding-top: 0px;
|
||||||
|
flex: 0 0 33%;
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
const DataListItemCells = styled(PFDataListItemCells)`
|
const DataListItemCells = styled(PFDataListItemCells)`
|
||||||
display: flex;
|
display: flex;
|
||||||
@media screen and (max-width: 768px) {
|
@media screen and (max-width: 768px) {
|
||||||
@@ -37,13 +48,10 @@ const LeftDataListCell = styled(DataListCell)`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
const RightDataListCell = styled(DataListCell)`
|
const RightDataListCell = styled(DataListCell)`
|
||||||
@media screen and (max-width: 768px) {
|
${rightStyle}
|
||||||
&& {
|
`;
|
||||||
padding-top: 0px;
|
const RightActionButtonCell = styled(ActionButtonCell)`
|
||||||
flex: 0 0 33%;
|
${rightStyle}
|
||||||
padding-right: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
class TemplateListItem extends Component {
|
class TemplateListItem extends Component {
|
||||||
@@ -87,8 +95,8 @@ class TemplateListItem extends Component {
|
|||||||
>
|
>
|
||||||
<Sparkline jobs={template.summary_fields.recent_jobs} />
|
<Sparkline jobs={template.summary_fields.recent_jobs} />
|
||||||
</RightDataListCell>,
|
</RightDataListCell>,
|
||||||
<RightDataListCell
|
<RightActionButtonCell
|
||||||
css="max-width: 40px;"
|
css="max-width: 80px;"
|
||||||
righthalf="true"
|
righthalf="true"
|
||||||
lastcolumn="true"
|
lastcolumn="true"
|
||||||
key="launch"
|
key="launch"
|
||||||
@@ -107,7 +115,18 @@ class TemplateListItem extends Component {
|
|||||||
</LaunchButton>
|
</LaunchButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
</RightDataListCell>,
|
{template.summary_fields.user_capabilities.edit && (
|
||||||
|
<Tooltip content={i18n._(t`Edit Template`)} position="top">
|
||||||
|
<ListActionButton
|
||||||
|
variant="plain"
|
||||||
|
component={Link}
|
||||||
|
to={`/templates/${template.type}/${template.id}/edit`}
|
||||||
|
>
|
||||||
|
<PencilAltIcon />
|
||||||
|
</ListActionButton>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
</RightActionButtonCell>,
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
</DataListItemRow>
|
</DataListItemRow>
|
||||||
|
|||||||
@@ -43,4 +43,42 @@ describe('<TemplatesListItem />', () => {
|
|||||||
);
|
);
|
||||||
expect(wrapper.find('LaunchButton').exists()).toBeFalsy();
|
expect(wrapper.find('LaunchButton').exists()).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
test('edit button shown to users with edit capabilities', () => {
|
||||||
|
const wrapper = mountWithContexts(
|
||||||
|
<TemplatesListItem
|
||||||
|
isSelected={false}
|
||||||
|
template={{
|
||||||
|
id: 1,
|
||||||
|
name: 'Template 1',
|
||||||
|
url: '/templates/job_template/1',
|
||||||
|
type: 'job_template',
|
||||||
|
summary_fields: {
|
||||||
|
user_capabilities: {
|
||||||
|
edit: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
expect(wrapper.find('PencilAltIcon').exists()).toBeTruthy();
|
||||||
|
});
|
||||||
|
test('edit button hidden from users without edit capabilities', () => {
|
||||||
|
const wrapper = mountWithContexts(
|
||||||
|
<TemplatesListItem
|
||||||
|
isSelected={false}
|
||||||
|
template={{
|
||||||
|
id: 1,
|
||||||
|
name: 'Template 1',
|
||||||
|
url: '/templates/job_template/1',
|
||||||
|
type: 'job_template',
|
||||||
|
summary_fields: {
|
||||||
|
user_capabilities: {
|
||||||
|
edit: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
expect(wrapper.find('PencilAltIcon').exists()).toBeFalsy();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user