diff --git a/monkey/monkey_island/cc/ui/src/components/ui-components/AdvancedMultiSelect.js b/monkey/monkey_island/cc/ui/src/components/ui-components/AdvancedMultiSelect.js
index 7507f234f..db759b013 100644
--- a/monkey/monkey_island/cc/ui/src/components/ui-components/AdvancedMultiSelect.js
+++ b/monkey/monkey_island/cc/ui/src/components/ui-components/AdvancedMultiSelect.js
@@ -2,6 +2,7 @@ import React from "react";
import {Card, Button, Form} from 'react-bootstrap';
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
import {faCheckSquare} from '@fortawesome/free-solid-svg-icons';
+import {faMinusSquare} from '@fortawesome/free-solid-svg-icons';
import {faSquare} from '@fortawesome/free-regular-svg-icons';
import {cloneDeep} from 'lodash';
@@ -9,6 +10,12 @@ import {getComponentHeight} from './utils/HeightCalculator';
import {resolveObjectPath} from './utils/ObjectPathResolver';
import InfoPane from './InfoPane';
+const MasterCheckboxState = {
+ NONE: 0,
+ MIXED: 1,
+ ALL: 2
+}
+
// Definitions passed to components only contains value and label,
// custom fields like "info" or "links" must be pulled from registry object using this function
@@ -40,12 +47,19 @@ function MasterCheckbox(props) {
checkboxState
} = props;
+ var newCheckboxIcon = faCheckSquare;
+
+ if (checkboxState == MasterCheckboxState.NONE)
+ newCheckboxIcon = faSquare;
+ else if (checkboxState == MasterCheckboxState.MIXED)
+ newCheckboxIcon = faMinusSquare;
+
return (
{title}
@@ -77,42 +91,57 @@ function ChildCheckbox(props) {
class AdvancedMultiSelect extends React.Component {
constructor(props) {
super(props)
- this.state = {masterCheckbox: true, infoPaneParams: getDefaultPaneParams(props.schema.items.$ref, props.registry)};
+ this.state = {
+ masterCheckboxState: this.getMasterCheckboxState(props.value),
+ infoPaneParams: getDefaultPaneParams(props.schema.items.$ref, props.registry)
+ };
this.onMasterCheckboxClick = this.onMasterCheckboxClick.bind(this);
this.onChildCheckboxClick = this.onChildCheckboxClick.bind(this);
this.setPaneInfo = this.setPaneInfo.bind(this, props.schema.items.$ref, props.registry);
}
onMasterCheckboxClick() {
- if (this.state.masterCheckbox) {
- this.props.onChange([]);
- } else {
- this.props.onChange(this.props.schema.default);
+ var newValues = this.props.options.enumOptions.map(({value}) => value);
+
+ if (this.state.masterCheckboxState == MasterCheckboxState.ALL) {
+ newValues = [];
}
- this.toggleMasterCheckbox();
+ this.props.onChange(newValues);
+ this.setMasterCheckboxState(newValues);
}
onChildCheckboxClick(value) {
- this.props.onChange(this.getSelectValuesAfterClick(value));
+ var selectValues = this.getSelectValuesAfterClick(value)
+ this.props.onChange(selectValues);
+
+ this.setMasterCheckboxState(selectValues);
}
getSelectValuesAfterClick(clickedValue) {
const valueArray = cloneDeep(this.props.value);
if (valueArray.includes(clickedValue)) {
- return valueArray.filter((e) => {
- return e !== clickedValue;
- });
+ return valueArray.filter(e => e !== clickedValue);
} else {
valueArray.push(clickedValue);
return valueArray;
}
}
- toggleMasterCheckbox() {
- this.setState((state) => ({
- masterCheckbox: !state.masterCheckbox
+ getMasterCheckboxState(selectValues) {
+ if (selectValues.length == 0)
+ return MasterCheckboxState.NONE;
+
+ if (selectValues.length != this.props.options.enumOptions.length)
+ return MasterCheckboxState.MIXED;
+
+ return MasterCheckboxState.ALL;
+ }
+
+ setMasterCheckboxState(selectValues) {
+ this.setState(() => ({
+ masterCheckboxState: this.getMasterCheckboxState(selectValues)
}));
}
@@ -132,7 +161,6 @@ class AdvancedMultiSelect extends React.Component {
readonly,
multiple,
autofocus,
- onChange,
registry
} = this.props;
@@ -143,7 +171,7 @@ class AdvancedMultiSelect extends React.Component {
+ checkboxState={this.state.masterCheckboxState}/>