Skip to content

Commit

Permalink
Merge pull request #992 from bitovi/search-criteria
Browse files Browse the repository at this point in the history
Search Criteria Support in the Web UI - Updated
  • Loading branch information
arm4b committed Oct 13, 2022
2 parents e172f1a + 038762c commit 0011c47
Show file tree
Hide file tree
Showing 6 changed files with 318 additions and 54 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ Added

Contributed by @Jappzy and @cded from @Bitovi

* Added the search rule criteria in the UI with the possibility of multiple patterns. #992, #964, #492

Contributed by @Jappzy and @cded from @Bitovi

Changed
~~~~~~~
* Updated nodejs from `14.16.1` to `14.20.1`, fixing the local build under ARM processor architecture. #880
Expand Down
6 changes: 4 additions & 2 deletions apps/st2-rules/rules-details.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,8 @@ export default class RulesDetails extends React.Component {
}

this.props.onComponentUpdate && this.props.onComponentUpdate();

this.setState({ editing: null });
}

handleSection(section) {
Expand Down Expand Up @@ -440,8 +442,8 @@ export default class RulesDetails extends React.Component {
? (
Object.keys(rule.criteria || {})
.map(name => {
const { type, pattern } = rule.criteria[name];
return <DetailsCriteriaLine key={`${name}//${type}//${pattern}`} name={name} type={type} pattern={pattern} />;
const { type, pattern, condition } = rule.criteria[name];
return <DetailsCriteriaLine key={`${name}//${type}//${pattern}`} name={name} type={type} pattern={pattern} condition={condition} />;
})
) : (
<DetailsLineNote>
Expand Down
262 changes: 233 additions & 29 deletions modules/st2-criteria/criteria.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ const types = {
'timediff_gt': 'Later Than',
'exists': 'Exists',
'nexists': 'Doesn\'t Exist',
'search': 'Search',
};

const searchConditions = {
'any': 'Any',
'all': 'All',
'any2any': 'Any2Any',
'all2any': 'All2Any',
};

export default class Criteria extends React.Component {
Expand All @@ -67,30 +75,163 @@ export default class Criteria extends React.Component {
disabled: false,
}

handleChangeKey(oldKey, key) {
handleChangeSearchCondition(key, condition) {
const { data, onChange } = this.props;

return onChange({
...data,
[key]: {
...data[key],
condition,
},
});
}


handleChangeSearchItemKey(key, oldItemKey, itemKey) {
const { onChange } = this.props;

const data = { ...this.props.data };
delete data[oldKey];
if(oldItemKey !== itemKey) {
const data = { ...this.props.data };
const dataItem = { ...data[key].pattern };
delete dataItem[oldItemKey];

return onChange({
...data,
[key]: {
...data[key],
pattern: {
...dataItem,
[itemKey]: {
...data[key].pattern[oldItemKey],
},
},
},
});
}
return onChange(this.props.data);

}

handleChangeSearchPattern(key, itemKey, pattern) {
const { data, onChange } = this.props;

return onChange({
...data,
[key]: this.props.data[oldKey],
[key]: {
...data[key],
pattern: {
...data[key].pattern,
[itemKey]: {
...data[key].pattern[itemKey],
pattern,
},
},
},
});
}

handleChangeType(key, type) {
handleChangeSearchType(key, itemKey, type) {
const { data, onChange } = this.props;

return onChange({
...data,
[key]: {
...data[key],
type,
pattern: {
...data[key].pattern,
[itemKey]: {
...data[key].pattern[itemKey],
type,
},
},
},
});
}

handleAddSearchPatternItem(key) {
const { data, onChange } = this.props;

return onChange({
...data,
[key]: {
...data[key],
pattern: {
...data[key].pattern,
['']: {
type: Object.keys(types)[0],
},
},
},
});
}

handleRemoveSearchPatternItem(key, itemKey) {
const { onChange } = this.props;

const data = { ...this.props.data };
const dataPattern = {...this.props.data[key].pattern};
delete dataPattern[itemKey];

return onChange({
...data,
[key]: {
...data[key],
pattern: {
...dataPattern,
},
},
});
}

handleChangeKey(oldKey, key) {
const { onChange } = this.props;

if(oldKey!== key) {
const data = { ...this.props.data };
delete data[oldKey];

return onChange({
...data,
[key]: this.props.data[oldKey],
});
}
return onChange(this.props.data);
}

handleChangeType(key, type) {
const { data, onChange } = this.props;

if (type === 'search') {
// save default values for search criteria
return onChange({
...data,
[key]: {
...data[key],
type,
condition: 'all',
pattern: {
['']: {
type: Object.keys(types)[0],
},
},
},
});
}
else {
// reset pattern from object to empty string if type != 'search'
this.handleChangePattern(key, '');
return onChange({
...data,
[key]: {
...data[key],
type,
pattern: '',
},
});
}
}

handleChangePattern(key, pattern) {
const { data, onChange } = this.props;

Expand Down Expand Up @@ -131,16 +272,23 @@ export default class Criteria extends React.Component {
return (
<div {...props} className={cx(style.component, flat && [ 'st2-auto-form--flat', style.flat ], className)}>
<div>
{ _.map(data, ({ type, pattern }, key) => (
{ _.map(data, ({ type, pattern, condition }, key) => (
<div className={style.line} key={key}>
<AutoFormCombobox
className={style.entity}
disabled={disabled}
data={key}
spec={spec}
onChange={(value) => this.handleChangeKey(key, value)}
/>
<div className={style.criteriaLabel}>
<AutoFormCombobox
name='Key'
className={style.entity}
disabled={disabled}
data={key}
spec={spec}
onChange={(value) => this.handleChangeKey(key, value)}
/>
{ disabled ? null :
<i className={cx('icon-cross', style.remove)} onClick={() => this.handleRemove(key)} />
}
</div>
<AutoFormSelect
name='Type'
className={style.entity}
disabled={disabled}
data={type}
Expand All @@ -150,28 +298,84 @@ export default class Criteria extends React.Component {
}}
onChange={(value) => this.handleChangeType(key, value)}
/>
<AutoFormInput
className={style.entity}
disabled={disabled}
data={pattern}
spec={{
required: true,
}}
onChange={(value) => this.handleChangePattern(key, value)}
/>
{ disabled ? null :
<i className={cx('icon-cross', style.remove)} onClick={() => this.handleRemove(key)} />
}
{ type === 'search' ? (
<>
<AutoFormSelect
name='Condition'
className={style.entity}
disabled={disabled}
data={condition}
spec={{
required: true,
enum: searchConditions,
}}
onChange={(value) => this.handleChangeSearchCondition(key, value)}
/>
<div className={style.break} />
<h5>Search Patterns <i className={cx('icon-plus', style.remove)} onClick={() => this.handleAddSearchPatternItem(key)} /></h5>
<div className={style.break} />
{ _.map(pattern, ({ type, pattern }, itemKey) => (
<div style={{display: 'flex'}} key={itemKey}>
<AutoFormCombobox
name={'Item name'}
className={style.entity}
disabled={disabled}
data={itemKey}
spec={{
required: true,
enum: [],
}}
onChange={(value) => this.handleChangeSearchItemKey(key, itemKey, value)}
/>
<AutoFormSelect
name={'Type'}
className={style.entity}
disabled={disabled}
data={type}
spec={{
required: true,
enum: types,
}}
onChange={(value) => this.handleChangeSearchType(key, itemKey, value)}
/>
<AutoFormInput
name={'Pattern'}
className={style.entity}
disabled={disabled}
data={pattern || ''}
spec={{
required: true,
}}
onChange={(value) => this.handleChangeSearchPattern(key, itemKey, value)}
/>
<i
className={cx('icon-cross', style.remove, style.subPatternRemove)} onClick={() => this.handleRemoveSearchPatternItem(key, itemKey)}
/>
</div>
))}
</>
) : (
<AutoFormInput
name={'Pattern'}
className={style.entity}
disabled={disabled}
data={pattern}
spec={{
required: true,
}}
onChange={(value) => this.handleChangePattern(key, value)}
/>
)}
</div>
)) }
</div>
{ disabled ? null : (
<div className={style.buttons}>
<input
type="button"
className="st2-forms__button st2-forms__button--small"
type='button'
className='st2-forms__button st2-forms__button--small'
onClick={() => this.handleAdd()}
value="Add criteria"
value='Add criteria'
/>
</div>
) }
Expand Down
20 changes: 20 additions & 0 deletions modules/st2-criteria/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,23 @@

flex: initial;
}

.break {
flex-basis: 100%;
height: 0;
}

.criteriaLabel {
position: relative;

i {
position: absolute;
top: 2px;
left: -25px;
}
}

.subPatternRemove {
margin-top: 20px;
margin-left: 5px;
}

0 comments on commit 0011c47

Please sign in to comment.