Implement basic lookup modal component.

This commit is contained in:
kialam
2019-01-07 10:09:35 -06:00
parent fefbb8fff8
commit c63896fbb6
5 changed files with 149 additions and 12 deletions

View File

@@ -119,7 +119,33 @@
--pf-c-about-modal-box--MaxWidth: 63rem; --pf-c-about-modal-box--MaxWidth: 63rem;
} }
.pf-c-list {
li {
list-style-type: none;
margin: 0;
padding: 0;
}
}
.pf-c-modal-box {
width: 70%;
}
.awx-lookup {
min-height: 36px;
}
.pf-c-input-group__text {
&:hover {
cursor: pointer;
}
}
.awx-pill {
color: white;
background-color: rgb(0, 123, 186);
border-radius: 3px;
margin: 1px 2px;
padding: 0 10px;
display: inline-block;
}
// //
// layout styles // layout styles
// //

View File

@@ -0,0 +1,89 @@
import React from 'react';
import { SearchIcon } from '@patternfly/react-icons';
import {
Modal,
List,
ListItem,
Checkbox,
Button,
ActionGroup,
Toolbar,
ToolbarGroup,
} from '@patternfly/react-core';
class Lookup extends React.Component {
constructor(props) {
super(props);
this.state = {
isModalOpen: false,
}
this.handleModalToggle = this.handleModalToggle.bind(this);
this.onLookup = this.onLookup.bind(this);
this.onChecked = this.onChecked.bind(this);
this.wrapTags = this.wrapTags.bind(this);
}
handleModalToggle() {
this.setState((prevState, _) => ({
isModalOpen: !prevState.isModalOpen,
}));
};
onLookup() {
this.handleModalToggle();
}
onChecked(_, evt) {
this.props.lookupChange(evt.target.id);
};
wrapTags(tags) {
return tags.filter(tag => tag.isChecked).map((tag, index) => {
return (
<span className="awx-pill" key={index}>{tag.name}</span>
)
})
}
render() {
const { isModalOpen } = this.state;
const { data } = this.props;
return (
<div className="pf-c-input-group awx-lookup">
<span className="pf-c-input-group__text" aria-label="search" id="search" onClick={this.onLookup}><SearchIcon /></span>
<div className="pf-c-form-control">{this.wrapTags(this.props.data)}</div>
<Modal
isLarge
title={`Select ${this.props.lookup_header}`}
isOpen={isModalOpen}
onClose={this.handleModalToggle}
>
<List>
{data.map(i =>
<ListItem key={i.id}>
<Checkbox
label={i.name}
isChecked={i.isChecked}
onChange={this.onChecked}
aria-label="result checkbox"
id={`${i.id}`}
/>
</ListItem>)}
</List>
<ActionGroup className="at-align-right">
<Toolbar>
<ToolbarGroup>
<Button className="at-C-SubmitButton" variant="primary" onClick={this.handleModalToggle} >Select</Button>
</ToolbarGroup>
<ToolbarGroup>
<Button className="at-C-CancelButton" variant="secondary" onClick={this.handleModalToggle}>Cancel</Button>
</ToolbarGroup>
</Toolbar>
</ActionGroup>
</Modal>
</div>
)
}
}
export default Lookup;

View File

@@ -0,0 +1,3 @@
import Lookup from './Lookup';
export default Lookup;

View File

@@ -4,4 +4,5 @@ export const API_LOGOUT = `${API_ROOT}logout/`;
export const API_V2 = `${API_ROOT}v2/`; export const API_V2 = `${API_ROOT}v2/`;
export const API_CONFIG = `${API_V2}config/`; export const API_CONFIG = `${API_V2}config/`;
export const API_PROJECTS = `${API_V2}projects/`; export const API_PROJECTS = `${API_V2}projects/`;
export const API_ORGANIZATIONS = `${API_V2}organizations/`; export const API_ORGANIZATIONS = `${API_V2}organizations/`;
export const API_INSTANCE_GROUPS = `${API_V2}instance_groups/`;

View File

@@ -20,8 +20,10 @@ import {
import { ConfigContext } from '../../../context'; import { ConfigContext } from '../../../context';
import { API_ORGANIZATIONS } from '../../../endpoints'; import { API_ORGANIZATIONS } from '../../../endpoints';
import { API_INSTANCE_GROUPS } from '../../../endpoints';
import api from '../../../api'; import api from '../../../api';
import AnsibleSelect from '../../../components/AnsibleSelect' import AnsibleSelect from '../../../components/AnsibleSelect';
import Lookup from '../../../components/Lookup';
const { light } = PageSectionVariants; const { light } = PageSectionVariants;
class OrganizationAdd extends React.Component { class OrganizationAdd extends React.Component {
@@ -30,6 +32,7 @@ class OrganizationAdd extends React.Component {
this.handleChange = this.handleChange.bind(this); this.handleChange = this.handleChange.bind(this);
this.onSelectChange = this.onSelectChange.bind(this); this.onSelectChange = this.onSelectChange.bind(this);
this.onLookupChange = this.onLookupChange.bind(this);
this.onSubmit = this.onSubmit.bind(this); this.onSubmit = this.onSubmit.bind(this);
this.resetForm = this.resetForm.bind(this); this.resetForm = this.resetForm.bind(this);
this.onCancel = this.onCancel.bind(this); this.onCancel = this.onCancel.bind(this);
@@ -38,15 +41,23 @@ class OrganizationAdd extends React.Component {
state = { state = {
name: '', name: '',
description: '', description: '',
instanceGroups: '', results: [],
instance_groups: [],
custom_virtualenv: '', custom_virtualenv: '',
error:'', error: '',
}; };
onSelectChange(value, _) { onSelectChange(value, _) {
this.setState({ custom_virtualenv: value }); this.setState({ custom_virtualenv: value });
}; };
onLookupChange(id, _) {
let selected = { ...this.state.results }
const index = id - 1;
selected[index].isChecked = !selected[index].isChecked;
this.setState({ selected })
}
resetForm() { resetForm() {
this.setState({ this.setState({
...this.state, ...this.state,
@@ -69,10 +80,18 @@ class OrganizationAdd extends React.Component {
this.props.history.push('/organizations'); this.props.history.push('/organizations');
} }
render() { async componentDidMount() {
const { name } = this.state; const { data } = await api.get(API_INSTANCE_GROUPS);
const enabled = name.length > 0; // TODO: add better form validation let results = [];
data.results.map((result) => {
results.push({ id: result.id, name: result.name, isChecked: false });
})
this.setState({ results });
}
render() {
const { name, results } = this.state;
const enabled = name.length > 0; // TODO: add better form validation
return ( return (
<Fragment> <Fragment>
<PageSection variant={light} className="pf-m-condensed"> <PageSection variant={light} className="pf-m-condensed">
@@ -109,11 +128,10 @@ class OrganizationAdd extends React.Component {
</FormGroup> </FormGroup>
{/* LOOKUP MODAL PLACEHOLDER */} {/* LOOKUP MODAL PLACEHOLDER */}
<FormGroup label="Instance Groups" fieldId="simple-form-instance-groups"> <FormGroup label="Instance Groups" fieldId="simple-form-instance-groups">
<TextInput <Lookup
id="add-org-form-instance-groups" lookup_header="Instance Groups"
name="instance-groups" lookupChange={this.onLookupChange}
value={this.state.instanceGroups} data={results}
onChange={this.handleChange}
/> />
</FormGroup> </FormGroup>
<ConfigContext.Consumer> <ConfigContext.Consumer>