Refactors Lookup

This commit is contained in:
Alex Corey
2019-11-06 12:03:13 -05:00
committed by Keith Grant
parent efbd2177a5
commit 2a722ba8d0
8 changed files with 143 additions and 111 deletions

View File

@@ -36,7 +36,7 @@ function CredentialLookup({
name="credential" name="credential"
value={value} value={value}
onBlur={onBlur} onBlur={onBlur}
onLookupSave={onChange} onChange={onChange}
getItems={getCredentials} getItems={getCredentials}
required={required} required={required}
sortedColumnKey="name" sortedColumnKey="name"

View File

@@ -39,7 +39,7 @@ class InstanceGroupsLookup extends React.Component {
lookupHeader={i18n._(t`Instance Groups`)} lookupHeader={i18n._(t`Instance Groups`)}
name="instanceGroups" name="instanceGroups"
value={value} value={value}
onLookupSave={onChange} onChange={onChange}
getItems={getInstanceGroups} getItems={getInstanceGroups}
qsNamespace="instance-group" qsNamespace="instance-group"
multiple multiple

View File

@@ -37,7 +37,7 @@ class InventoryLookup extends React.Component {
lookupHeader={i18n._(t`Inventory`)} lookupHeader={i18n._(t`Inventory`)}
name="inventory" name="inventory"
value={value} value={value}
onLookupSave={onChange} onChange={onChange}
onBlur={onBlur} onBlur={onBlur}
getItems={getInventories} getItems={getInventories}
required={required} required={required}

View File

@@ -59,13 +59,13 @@ class Lookup extends React.Component {
super(props); super(props);
this.assertCorrectValueType(); this.assertCorrectValueType();
let lookupSelectedItems = []; let selectedItems = [];
if (props.value) { if (props.value) {
lookupSelectedItems = props.multiple ? [...props.value] : [props.value]; selectedItems = props.multiple ? [...props.value] : [props.value];
} }
this.state = { this.state = {
isModalOpen: false, isModalOpen: false,
lookupSelectedItems, selectedItems,
results: [], results: [],
count: 0, count: 0,
error: null, error: null,
@@ -76,7 +76,8 @@ class Lookup extends React.Component {
order_by: props.sortedColumnKey, order_by: props.sortedColumnKey,
}); });
this.handleModalToggle = this.handleModalToggle.bind(this); this.handleModalToggle = this.handleModalToggle.bind(this);
this.toggleSelected = this.toggleSelected.bind(this); this.addItem = this.addItem.bind(this);
this.removeItem = this.removeItem.bind(this);
this.saveModal = this.saveModal.bind(this); this.saveModal = this.saveModal.bind(this);
this.getData = this.getData.bind(this); this.getData = this.getData.bind(this);
this.clearQSParams = this.clearQSParams.bind(this); this.clearQSParams = this.clearQSParams.bind(this);
@@ -132,46 +133,82 @@ class Lookup extends React.Component {
} }
} }
toggleSelected(row) { removeItem(row) {
const { const { selectedItems } = this.state;
name, const { onToggleItem } = this.props;
onLookupSave, if (onToggleItem) {
multiple, this.setState({ selectedItems: onToggleItem(selectedItems, row) });
onToggleItem, return;
selectCategoryOptions,
} = this.props;
const {
lookupSelectedItems: updatedSelectedItems,
isModalOpen,
} = this.state;
const selectedIndex = updatedSelectedItems.findIndex(
selectedRow => selectedRow.id === row.id
);
if (multiple) {
if (selectCategoryOptions) {
onToggleItem(row, isModalOpen);
}
if (selectedIndex > -1) {
updatedSelectedItems.splice(selectedIndex, 1);
this.setState({ lookupSelectedItems: updatedSelectedItems });
} else {
this.setState(prevState => ({
lookupSelectedItems: [...prevState.lookupSelectedItems, row],
}));
}
} else {
this.setState({ lookupSelectedItems: [row] });
}
// Updates the selected items from parent state
// This handles the case where the user removes chips from the lookup input
// while the modal is closed
if (!isModalOpen) {
onLookupSave(updatedSelectedItems, name);
} }
this.setState({
selectedItems: selectedItems.filter(item => item.id !== row.id),
});
} }
addItem(row) {
const { selectedItems } = this.state;
const { multiple, onToggleItem } = this.props;
if (onToggleItem) {
this.setState({ selectedItems: onToggleItem(selectedItems, row) });
return;
}
const index = selectedItems.findIndex(item => item.id === row.id);
if (!multiple) {
this.setState({ selectedItems: [row] });
return;
}
if (index > -1) {
return;
}
this.setState({ selectedItems: [...selectedItems, row] });
}
// toggleSelected(row) {
// const {
// name,
// onChange,
// multiple,
// onToggleItem,
// selectCategoryOptions,
// onChange,
// value
// } = this.props;
// const {
// selectedItems: updatedSelectedItems,
// isModalOpen,
// } = this.state;
// const selectedIndex = updatedSelectedItems.findIndex(
// selectedRow => selectedRow.id === row.id
// );
//
// if (multiple) {
//
// if (selectCategoryOptions) {
//
// onToggleItem(row, isModalOpen);
// }
// if (selectedIndex > -1) {
//
// const valueToUpdate = value.filter(itemValue => itemValue.id !==row.id );
// onChange(valueToUpdate)
// } else {
//
// onChange([...value, row])
// }
// } else {
//
// onChange(row)
// }
// Updates the selected items from parent state
// This handles the case where the user removes chips from the lookup input
// while the modal is closed
// if (!isModalOpen) {
// onChange(updatedSelectedItems, name);
// }
// }
handleModalToggle() { handleModalToggle() {
const { isModalOpen } = this.state; const { isModalOpen } = this.state;
const { value, multiple, selectCategory } = this.props; const { value, multiple, selectCategory } = this.props;
@@ -179,11 +216,11 @@ class Lookup extends React.Component {
// This handles the case where the user closes/cancels the modal and // This handles the case where the user closes/cancels the modal and
// opens it again // opens it again
if (!isModalOpen) { if (!isModalOpen) {
let lookupSelectedItems = []; let selectedItems = [];
if (value) { if (value) {
lookupSelectedItems = multiple ? [...value] : [value]; selectedItems = multiple ? [...value] : [value];
} }
this.setState({ lookupSelectedItems }); this.setState({ selectedItems });
} else { } else {
this.clearQSParams(); this.clearQSParams();
if (selectCategory) { if (selectCategory) {
@@ -195,15 +232,22 @@ class Lookup extends React.Component {
})); }));
} }
removeItemAndSave(row) {
const { value, onChange, multiple } = this.props;
if (multiple) {
onChange(value.filter(item => item.id !== row.id));
} else if (value.id === row.id) {
onChange(null);
}
}
saveModal() { saveModal() {
const { onLookupSave, name, multiple } = this.props; const { onChange, multiple } = this.props;
const { lookupSelectedItems } = this.state; const { selectedItems } = this.state;
const value = multiple const value = multiple ? selectedItems : selectedItems[0] || null;
? lookupSelectedItems
: lookupSelectedItems[0] || null;
this.handleModalToggle(); this.handleModalToggle();
onLookupSave(value, name); onChange(value);
} }
clearQSParams() { clearQSParams() {
@@ -215,13 +259,7 @@ class Lookup extends React.Component {
} }
render() { render() {
const { const { isModalOpen, selectedItems, error, results, count } = this.state;
isModalOpen,
lookupSelectedItems,
error,
results,
count,
} = this.state;
const { const {
form, form,
id, id,
@@ -245,7 +283,7 @@ class Lookup extends React.Component {
{(multiple ? value : [value]).map(chip => ( {(multiple ? value : [value]).map(chip => (
<CredentialChip <CredentialChip
key={chip.id} key={chip.id}
onClick={() => this.toggleSelected(chip)} onClick={() => this.removeItemAndSave(chip)}
isReadOnly={!canDelete} isReadOnly={!canDelete}
credential={chip} credential={chip}
/> />
@@ -256,7 +294,7 @@ class Lookup extends React.Component {
{(multiple ? value : [value]).map(chip => ( {(multiple ? value : [value]).map(chip => (
<Chip <Chip
key={chip.id} key={chip.id}
onClick={() => this.toggleSelected(chip)} onClick={() => this.removeItemAndSave(chip)}
isReadOnly={!canDelete} isReadOnly={!canDelete}
> >
{chip.name} {chip.name}
@@ -287,19 +325,19 @@ class Lookup extends React.Component {
onClose={this.handleModalToggle} onClose={this.handleModalToggle}
actions={[ actions={[
<Button <Button
key="save" key="select"
variant="primary" variant="primary"
onClick={this.saveModal} onClick={this.saveModal}
style={results.length === 0 ? { display: 'none' } : {}} style={selectedItems.length === 0 ? { display: 'none' } : {}}
> >
{i18n._(t`Save`)} {i18n._(t`Select`)}
</Button>, </Button>,
<Button <Button
key="cancel" key="cancel"
variant="secondary" variant="secondary"
onClick={this.handleModalToggle} onClick={this.handleModalToggle}
> >
{results.length === 0 ? i18n._(t`Close`) : i18n._(t`Cancel`)} {i18n._(t`Cancel`)}
</Button>, </Button>,
]} ]}
> >
@@ -318,6 +356,18 @@ class Lookup extends React.Component {
/> />
</ToolbarItem> </ToolbarItem>
)} )}
{selectedItems.length > 0 && (
<SelectedList
label={i18n._(t`Selected`)}
selected={selectedItems}
showOverflowAfter={5}
onRemove={this.removeItem}
isReadOnly={!canDelete}
isCredentialList={
selectCategoryOptions && selectCategoryOptions.length > 0
}
/>
)}
<PaginatedDataList <PaginatedDataList
items={results} items={results}
itemCount={count} itemCount={count}
@@ -330,12 +380,8 @@ class Lookup extends React.Component {
itemId={item.id} itemId={item.id}
name={multiple ? item.name : name} name={multiple ? item.name : name}
label={item.name} label={item.name}
isSelected={ isSelected={selectedItems.some(i => i.id === item.id)}
selectCategoryOptions onSelect={() => this.addItem(item)}
? value.some(i => i.id === item.id)
: lookupSelectedItems.some(i => i.id === item.id)
}
onSelect={() => this.toggleSelected(item)}
isRadio={ isRadio={
!multiple || !multiple ||
(selectCategoryOptions && (selectCategoryOptions &&
@@ -347,17 +393,6 @@ class Lookup extends React.Component {
renderToolbar={props => <DataListToolbar {...props} fillWidth />} renderToolbar={props => <DataListToolbar {...props} fillWidth />}
showPageSizeOptions={false} showPageSizeOptions={false}
/> />
{lookupSelectedItems.length > 0 && (
<SelectedList
label={i18n._(t`Selected`)}
selected={selectCategoryOptions ? value : lookupSelectedItems}
onRemove={this.toggleSelected}
isReadOnly={!canDelete}
isCredentialList={
selectCategoryOptions && selectCategoryOptions.length > 0
}
/>
)}
{error ? <div>error</div> : ''} {error ? <div>error</div> : ''}
</Modal> </Modal>
</Fragment> </Fragment>
@@ -374,7 +409,7 @@ Lookup.propTypes = {
getItems: func.isRequired, getItems: func.isRequired,
lookupHeader: string, lookupHeader: string,
name: string, name: string,
onLookupSave: func.isRequired, onChange: func.isRequired,
value: oneOfType([Item, arrayOf(Item)]), value: oneOfType([Item, arrayOf(Item)]),
sortedColumnKey: string.isRequired, sortedColumnKey: string.isRequired,
multiple: bool, multiple: bool,

View File

@@ -12,7 +12,25 @@ import Lookup from '@components/Lookup';
const QuestionCircleIcon = styled(PFQuestionCircleIcon)` const QuestionCircleIcon = styled(PFQuestionCircleIcon)`
margin-left: 10px; margin-left: 10px;
`; `;
function toggleCredentialSelection(credentialsToUpdate, newCredential) {
let newCredentialsList;
const isSelectedCredentialInState =
credentialsToUpdate.filter(cred => cred.id === newCredential.id).length >
0;
if (isSelectedCredentialInState) {
newCredentialsList = credentialsToUpdate.filter(
cred => cred.id !== newCredential.id
);
} else {
newCredentialsList = credentialsToUpdate.filter(
credential =>
credential.kind === 'vault' || credential.kind !== newCredential.kind
);
newCredentialsList = [...newCredentialsList, newCredential];
}
return newCredentialsList;
}
class MultiCredentialsLookup extends React.Component { class MultiCredentialsLookup extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
@@ -26,7 +44,6 @@ class MultiCredentialsLookup extends React.Component {
this this
); );
this.loadCredentials = this.loadCredentials.bind(this); this.loadCredentials = this.loadCredentials.bind(this);
this.toggleCredentialSelection = this.toggleCredentialSelection.bind(this);
} }
componentDidMount() { componentDidMount() {
@@ -69,27 +86,7 @@ class MultiCredentialsLookup extends React.Component {
return CredentialsAPI.read(params); return CredentialsAPI.read(params);
} }
toggleCredentialSelection(newCredential) {
const { onChange, credentials: credentialsToUpdate } = this.props;
let newCredentialsList;
const isSelectedCredentialInState =
credentialsToUpdate.filter(cred => cred.id === newCredential.id).length >
0;
if (isSelectedCredentialInState) {
newCredentialsList = credentialsToUpdate.filter(
cred => cred.id !== newCredential.id
);
} else {
newCredentialsList = credentialsToUpdate.filter(
credential =>
credential.kind === 'vault' || credential.kind !== newCredential.kind
);
newCredentialsList = [...newCredentialsList, newCredential];
}
onChange(newCredentialsList);
}
handleCredentialTypeSelect(value, type) { handleCredentialTypeSelect(value, type) {
const { credentialTypes } = this.state; const { credentialTypes } = this.state;
@@ -99,7 +96,7 @@ class MultiCredentialsLookup extends React.Component {
render() { render() {
const { selectedCredentialType, credentialTypes } = this.state; const { selectedCredentialType, credentialTypes } = this.state;
const { tooltip, i18n, credentials } = this.props; const { tooltip, i18n, credentials, onChange } = this.props;
return ( return (
<FormGroup label={i18n._(t`Credentials`)} fieldId="multiCredential"> <FormGroup label={i18n._(t`Credentials`)} fieldId="multiCredential">
{tooltip && ( {tooltip && (
@@ -112,14 +109,14 @@ class MultiCredentialsLookup extends React.Component {
selectCategoryOptions={credentialTypes} selectCategoryOptions={credentialTypes}
selectCategory={this.handleCredentialTypeSelect} selectCategory={this.handleCredentialTypeSelect}
selectedCategory={selectedCredentialType} selectedCategory={selectedCredentialType}
onToggleItem={this.toggleCredentialSelection} onToggleItem={toggleCredentialSelection}
onloadCategories={this.loadCredentialTypes} onloadCategories={this.loadCredentialTypes}
id="multiCredential" id="multiCredential"
lookupHeader={i18n._(t`Credentials`)} lookupHeader={i18n._(t`Credentials`)}
name="credentials" name="credentials"
value={credentials} value={credentials}
multiple multiple
onLookupSave={() => {}} onChange={onChange}
getItems={this.loadCredentials} getItems={this.loadCredentials}
qsNamespace="credentials" qsNamespace="credentials"
columns={[ columns={[

View File

@@ -32,7 +32,7 @@ function OrganizationLookup({
name="organization" name="organization"
value={value} value={value}
onBlur={onBlur} onBlur={onBlur}
onLookupSave={onChange} onChange={onChange}
getItems={getOrganizations} getItems={getOrganizations}
required={required} required={required}
sortedColumnKey="name" sortedColumnKey="name"

View File

@@ -45,7 +45,7 @@ class ProjectLookup extends React.Component {
name="project" name="project"
value={value} value={value}
onBlur={onBlur} onBlur={onBlur}
onLookupSave={onChange} onChange={onChange}
getItems={loadProjects} getItems={loadProjects}
required={required} required={required}
sortedColumnKey="name" sortedColumnKey="name"

View File

@@ -51,7 +51,7 @@ export const ScmCredentialFormField = withI18n()(
value={credential.value} value={credential.value}
onChange={value => { onChange={value => {
onCredentialSelection('scm', value); onCredentialSelection('scm', value);
form.setFieldValue('credential', value.id); form.setFieldValue('credential', value ? value.id : '');
}} }}
/> />
)} )}