mirror of
https://github.com/ansible/awx.git
synced 2026-01-21 06:28:01 -03:30
unwind error handling use auth cookie as source of truth, fetch config only when authenticated
248 lines
6.8 KiB
JavaScript
248 lines
6.8 KiB
JavaScript
import React, { Fragment } from 'react';
|
|
import PropTypes from 'prop-types';
|
|
import { withI18n } from '@lingui/react';
|
|
import { t } from '@lingui/macro';
|
|
import { Wizard } from '@patternfly/react-core';
|
|
import SelectResourceStep from './SelectResourceStep';
|
|
import SelectRoleStep from './SelectRoleStep';
|
|
import SelectableCard from './SelectableCard';
|
|
import { TeamsAPI, UsersAPI } from '../../api';
|
|
|
|
const readUsers = async (queryParams) => UsersAPI.read(
|
|
Object.assign(queryParams, { is_superuser: false })
|
|
);
|
|
|
|
const readTeams = async (queryParams) => TeamsAPI.read(queryParams);
|
|
|
|
class AddResourceRole extends React.Component {
|
|
constructor (props) {
|
|
super(props);
|
|
|
|
this.state = {
|
|
selectedResource: null,
|
|
selectedResourceRows: [],
|
|
selectedRoleRows: [],
|
|
currentStepId: 1,
|
|
};
|
|
|
|
this.handleResourceCheckboxClick = this.handleResourceCheckboxClick.bind(this);
|
|
this.handleResourceSelect = this.handleResourceSelect.bind(this);
|
|
this.handleRoleCheckboxClick = this.handleRoleCheckboxClick.bind(this);
|
|
this.handleWizardNext = this.handleWizardNext.bind(this);
|
|
this.handleWizardSave = this.handleWizardSave.bind(this);
|
|
}
|
|
|
|
handleResourceCheckboxClick (user) {
|
|
const { selectedResourceRows } = this.state;
|
|
|
|
const selectedIndex = selectedResourceRows
|
|
.findIndex(selectedRow => selectedRow.id === user.id);
|
|
|
|
if (selectedIndex > -1) {
|
|
selectedResourceRows.splice(selectedIndex, 1);
|
|
this.setState({ selectedResourceRows });
|
|
} else {
|
|
this.setState(prevState => ({
|
|
selectedResourceRows: [...prevState.selectedResourceRows, user]
|
|
}));
|
|
}
|
|
}
|
|
|
|
handleRoleCheckboxClick (role) {
|
|
const { selectedRoleRows } = this.state;
|
|
|
|
const selectedIndex = selectedRoleRows
|
|
.findIndex(selectedRow => selectedRow.id === role.id);
|
|
|
|
if (selectedIndex > -1) {
|
|
selectedRoleRows.splice(selectedIndex, 1);
|
|
this.setState({ selectedRoleRows });
|
|
} else {
|
|
this.setState(prevState => ({
|
|
selectedRoleRows: [...prevState.selectedRoleRows, role]
|
|
}));
|
|
}
|
|
}
|
|
|
|
handleResourceSelect (resourceType) {
|
|
this.setState({
|
|
selectedResource: resourceType,
|
|
selectedResourceRows: [],
|
|
selectedRoleRows: []
|
|
});
|
|
}
|
|
|
|
handleWizardNext (step) {
|
|
this.setState({
|
|
currentStepId: step.id,
|
|
});
|
|
}
|
|
|
|
async handleWizardSave () {
|
|
const {
|
|
onSave
|
|
} = this.props;
|
|
const {
|
|
selectedResourceRows,
|
|
selectedRoleRows,
|
|
selectedResource
|
|
} = this.state;
|
|
|
|
try {
|
|
const roleRequests = [];
|
|
|
|
for (let i = 0; i < selectedResourceRows.length; i++) {
|
|
for (let j = 0; j < selectedRoleRows.length; j++) {
|
|
if (selectedResource === 'users') {
|
|
roleRequests.push(
|
|
UsersAPI.associateRole(selectedResourceRows[i].id, selectedRoleRows[j].id)
|
|
);
|
|
} else if (selectedResource === 'teams') {
|
|
roleRequests.push(
|
|
TeamsAPI.associateRole(selectedResourceRows[i].id, selectedRoleRows[j].id)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
await Promise.all(roleRequests);
|
|
onSave();
|
|
} catch (err) {
|
|
// TODO: handle this error
|
|
}
|
|
}
|
|
|
|
render () {
|
|
const {
|
|
selectedResource,
|
|
selectedResourceRows,
|
|
selectedRoleRows,
|
|
currentStepId,
|
|
} = this.state;
|
|
const {
|
|
onClose,
|
|
roles,
|
|
i18n
|
|
} = this.props;
|
|
|
|
const userColumns = [
|
|
{ name: i18n._(t`Username`), key: 'username', isSortable: true }
|
|
];
|
|
|
|
const teamColumns = [
|
|
{ name: i18n._(t`Name`), key: 'name', isSortable: true }
|
|
];
|
|
|
|
let wizardTitle = '';
|
|
|
|
switch (selectedResource) {
|
|
case 'users':
|
|
wizardTitle = i18n._(t`Add User Roles`);
|
|
break;
|
|
case 'teams':
|
|
wizardTitle = i18n._(t`Add Team Roles`);
|
|
break;
|
|
default:
|
|
wizardTitle = i18n._(t`Add Roles`);
|
|
}
|
|
|
|
const steps = [
|
|
{
|
|
id: 1,
|
|
name: i18n._(t`Select Users Or Teams`),
|
|
component: (
|
|
<div style={{ display: 'flex' }}>
|
|
<SelectableCard
|
|
isSelected={selectedResource === 'users'}
|
|
label={i18n._(t`Users`)}
|
|
onClick={() => this.handleResourceSelect('users')}
|
|
/>
|
|
<SelectableCard
|
|
isSelected={selectedResource === 'teams'}
|
|
label={i18n._(t`Teams`)}
|
|
onClick={() => this.handleResourceSelect('teams')}
|
|
/>
|
|
</div>
|
|
),
|
|
enableNext: selectedResource !== null
|
|
},
|
|
{
|
|
id: 2,
|
|
name: i18n._(t`Select items from list`),
|
|
component: (
|
|
<Fragment>
|
|
{selectedResource === 'users' && (
|
|
<SelectResourceStep
|
|
columns={userColumns}
|
|
displayKey="username"
|
|
onRowClick={this.handleResourceCheckboxClick}
|
|
onSearch={readUsers}
|
|
selectedLabel={i18n._(t`Selected`)}
|
|
selectedResourceRows={selectedResourceRows}
|
|
sortedColumnKey="username"
|
|
itemName="user"
|
|
/>
|
|
)}
|
|
{selectedResource === 'teams' && (
|
|
<SelectResourceStep
|
|
columns={teamColumns}
|
|
onRowClick={this.handleResourceCheckboxClick}
|
|
onSearch={readTeams}
|
|
selectedLabel={i18n._(t`Selected`)}
|
|
selectedResourceRows={selectedResourceRows}
|
|
itemName="team"
|
|
/>
|
|
)}
|
|
</Fragment>
|
|
),
|
|
enableNext: selectedResourceRows.length > 0
|
|
},
|
|
{
|
|
id: 3,
|
|
name: i18n._(t`Apply roles`),
|
|
component: (
|
|
<SelectRoleStep
|
|
onRolesClick={this.handleRoleCheckboxClick}
|
|
roles={roles}
|
|
selectedListKey={selectedResource === 'users' ? 'username' : 'name'}
|
|
selectedListLabel={i18n._(t`Selected`)}
|
|
selectedResourceRows={selectedResourceRows}
|
|
selectedRoleRows={selectedRoleRows}
|
|
/>
|
|
),
|
|
nextButtonText: i18n._(t`Save`),
|
|
enableNext: selectedRoleRows.length > 0
|
|
}
|
|
];
|
|
|
|
const currentStep = steps.find(step => step.id === currentStepId);
|
|
|
|
// TODO: somehow internationalize steps and currentStep.nextButtonText
|
|
return (
|
|
<Wizard
|
|
style={{ overflow: 'scroll' }}
|
|
isOpen
|
|
onNext={this.handleWizardNext}
|
|
onClose={onClose}
|
|
onSave={this.handleWizardSave}
|
|
steps={steps}
|
|
title={wizardTitle}
|
|
nextButtonText={currentStep.nextButtonText || undefined}
|
|
/>
|
|
);
|
|
}
|
|
}
|
|
|
|
AddResourceRole.propTypes = {
|
|
onClose: PropTypes.func.isRequired,
|
|
onSave: PropTypes.func.isRequired,
|
|
roles: PropTypes.shape()
|
|
};
|
|
|
|
AddResourceRole.defaultProps = {
|
|
roles: {}
|
|
};
|
|
|
|
export { AddResourceRole as _AddResourceRole };
|
|
export default withI18n()(AddResourceRole);
|