New: Ability to edit restriction terms in Release Profiles

This commit is contained in:
Mark McDowall 2020-10-12 15:30:32 -07:00
parent d47ad37791
commit dab6242ff2
5 changed files with 91 additions and 13 deletions

View File

@ -75,6 +75,12 @@ class TagInput extends Component {
// //
// Listeners // Listeners
onTagEdit = ({ value, ...otherProps }) => {
this.setState({ value });
this.props.onTagDelete(otherProps);
}
onInputContainerPress = () => { onInputContainerPress = () => {
this._autosuggestRef.input.focus(); this._autosuggestRef.input.focus();
} }
@ -188,6 +194,7 @@ class TagInput extends Component {
const { const {
tags, tags,
kind, kind,
canEdit,
tagComponent, tagComponent,
onTagDelete onTagDelete
} = this.props; } = this.props;
@ -199,8 +206,10 @@ class TagInput extends Component {
kind={kind} kind={kind}
inputProps={inputProps} inputProps={inputProps}
isFocused={this.state.isFocused} isFocused={this.state.isFocused}
canEdit={canEdit}
tagComponent={tagComponent} tagComponent={tagComponent}
onTagDelete={onTagDelete} onTagDelete={onTagDelete}
onTagEdit={this.onTagEdit}
onInputContainerPress={this.onInputContainerPress} onInputContainerPress={this.onInputContainerPress}
/> />
); );
@ -262,6 +271,7 @@ TagInput.propTypes = {
placeholder: PropTypes.string.isRequired, placeholder: PropTypes.string.isRequired,
delimiters: PropTypes.arrayOf(PropTypes.string).isRequired, delimiters: PropTypes.arrayOf(PropTypes.string).isRequired,
minQueryLength: PropTypes.number.isRequired, minQueryLength: PropTypes.number.isRequired,
canEdit: PropTypes.bool,
hasError: PropTypes.bool, hasError: PropTypes.bool,
hasWarning: PropTypes.bool, hasWarning: PropTypes.bool,
tagComponent: PropTypes.elementType.isRequired, tagComponent: PropTypes.elementType.isRequired,
@ -277,6 +287,7 @@ TagInput.defaultProps = {
placeholder: '', placeholder: '',
delimiters: ['Tab', 'Enter', ' ', ','], delimiters: ['Tab', 'Enter', ' ', ','],
minQueryLength: 1, minQueryLength: 1,
canEdit: false,
tagComponent: TagInputTag tagComponent: TagInputTag
}; };

View File

@ -28,8 +28,10 @@ class TagInputInput extends Component {
tags, tags,
inputProps, inputProps,
kind, kind,
canEdit,
tagComponent: TagComponent, tagComponent: TagComponent,
onTagDelete onTagDelete,
onTagEdit
} = this.props; } = this.props;
return ( return (
@ -47,8 +49,10 @@ class TagInputInput extends Component {
index={index} index={index}
tag={tag} tag={tag}
kind={kind} kind={kind}
canEdit={canEdit}
isLastTag={index === tags.length - 1} isLastTag={index === tags.length - 1}
onDelete={onTagDelete} onDelete={onTagDelete}
onEdit={onTagEdit}
/> />
); );
}) })
@ -67,8 +71,10 @@ TagInputInput.propTypes = {
inputProps: PropTypes.object.isRequired, inputProps: PropTypes.object.isRequired,
kind: PropTypes.oneOf(kinds.all).isRequired, kind: PropTypes.oneOf(kinds.all).isRequired,
isFocused: PropTypes.bool.isRequired, isFocused: PropTypes.bool.isRequired,
canEdit: PropTypes.bool.isRequired,
tagComponent: PropTypes.elementType.isRequired, tagComponent: PropTypes.elementType.isRequired,
onTagDelete: PropTypes.func.isRequired, onTagDelete: PropTypes.func.isRequired,
onTagEdit: PropTypes.func.isRequired,
onInputContainerPress: PropTypes.func.isRequired onInputContainerPress: PropTypes.func.isRequired
}; };

View File

@ -1,5 +1,25 @@
.tag { .tag {
composes: link from '~Components/Link/Link.css'; display: flex;
justify-content: center;
flex-direction: column;
height: 31px; height: 31px;
} }
.link {
composes: link from '~Components/Link/Link.css';
line-height: 1px;
}
.editContainer {
display: inline-block;
margin-left: 4px;
padding-left: 2px;
border-left: 1px solid #eee;
}
.editButton {
composes: button from '~Components/Link/IconButton.css';
width: auto;
}

View File

@ -1,8 +1,9 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React, { Component } from 'react'; import React, { Component } from 'react';
import { kinds } from 'Helpers/Props'; import { icons, kinds } from 'Helpers/Props';
import tagShape from 'Helpers/Props/Shapes/tagShape'; import tagShape from 'Helpers/Props/Shapes/tagShape';
import Label from 'Components/Label'; import Label from 'Components/Label';
import IconButton from 'Components/Link/IconButton';
import Link from 'Components/Link/Link'; import Link from 'Components/Link/Link';
import styles from './TagInputTag.css'; import styles from './TagInputTag.css';
@ -24,24 +25,60 @@ class TagInputTag extends Component {
}); });
} }
onEdit = () => {
const {
index,
tag,
onEdit
} = this.props;
onEdit({
index,
id: tag.id,
value: tag.name
});
}
// //
// Render // Render
render() { render() {
const { const {
tag, tag,
kind kind,
canEdit
} = this.props; } = this.props;
return ( return (
<Link <div
className={styles.tag} className={styles.tag}
tabIndex={-1} tabIndex={-1}
onPress={this.onDelete}
> >
<Label kind={kind}> <Label
{tag.name} kind={kind}
>
<Link
className={styles.link}
tabIndex={-1}
onPress={this.onDelete}
>
{tag.name}
</Link>
{
canEdit ?
<div className={styles.editContainer}>
<IconButton
className={styles.editButton}
name={icons.EDIT}
size={9}
onPress={this.onEdit}
/>
</div> :
null
}
</Label> </Label>
</Link> </div>
); );
} }
} }
@ -50,7 +87,9 @@ TagInputTag.propTypes = {
index: PropTypes.number.isRequired, index: PropTypes.number.isRequired,
tag: PropTypes.shape(tagShape), tag: PropTypes.shape(tagShape),
kind: PropTypes.oneOf(kinds.all).isRequired, kind: PropTypes.oneOf(kinds.all).isRequired,
onDelete: PropTypes.func.isRequired canEdit: PropTypes.bool.isRequired,
onDelete: PropTypes.func.isRequired,
onEdit: PropTypes.func.isRequired
}; };
export default TagInputTag; export default TagInputTag;

View File

@ -62,13 +62,14 @@ function EditReleaseProfileModalContent(props) {
<FormLabel>Must Contain</FormLabel> <FormLabel>Must Contain</FormLabel>
<FormInputGroup <FormInputGroup
{...required}
type={inputTypes.TEXT_TAG} type={inputTypes.TEXT_TAG}
name="required" name="required"
helpText="The release must contain at least one of these terms (case insensitive)" helpText="The release must contain at least one of these terms (case insensitive)"
kind={kinds.SUCCESS} kind={kinds.SUCCESS}
placeholder="Add new restriction" placeholder="Add new restriction"
delimiters={tagInputDelimiters} delimiters={tagInputDelimiters}
{...required} canEdit={true}
onChange={onInputChange} onChange={onInputChange}
/> />
</FormGroup> </FormGroup>
@ -77,13 +78,14 @@ function EditReleaseProfileModalContent(props) {
<FormLabel>Must Not Contain</FormLabel> <FormLabel>Must Not Contain</FormLabel>
<FormInputGroup <FormInputGroup
{...ignored}
type={inputTypes.TEXT_TAG} type={inputTypes.TEXT_TAG}
name="ignored" name="ignored"
helpText="The release will be rejected if it contains one or more of terms (case insensitive)" helpText="The release will be rejected if it contains one or more of terms (case insensitive)"
kind={kinds.DANGER} kind={kinds.DANGER}
placeholder="Add new restriction" placeholder="Add new restriction"
delimiters={tagInputDelimiters} delimiters={tagInputDelimiters}
{...ignored} canEdit={true}
onChange={onInputChange} onChange={onInputChange}
/> />
</FormGroup> </FormGroup>