|
|
|
@ -24,8 +24,6 @@ import { format } from 'date-fns'; |
|
|
|
|
|
|
|
|
|
import { makeStyles } from '@material-ui/core/styles'; |
|
|
|
|
|
|
|
|
|
import { polygonStore } from './polygons.js'; |
|
|
|
|
|
|
|
|
|
import { |
|
|
|
|
filter_is_const_false, ConstFilter, LogicalOperatorFilter, MatchingFilter, |
|
|
|
|
ResultTypeEnum, LogicalOperatorEnum, MatchTypeEnum, NegationFilter, TimeFilterTypeEnum, |
|
|
|
@ -239,8 +237,6 @@ export function EditFilterExpressionDialog(props) { |
|
|
|
|
const { onClose, startingFilter, open } = props; |
|
|
|
|
const [filter, setFilter] = React.useState(startingFilter); |
|
|
|
|
|
|
|
|
|
const polygons_dispatch = useContext(polygonStore).dispatch; |
|
|
|
|
|
|
|
|
|
const FilterTypeEnum = { |
|
|
|
|
CONST: 0, |
|
|
|
|
NEGATION: 1, |
|
|
|
@ -270,7 +266,7 @@ export function EditFilterExpressionDialog(props) { |
|
|
|
|
} else if (val == FilterTypeEnum.IMAGETYPE) { |
|
|
|
|
setFilter(new ImageTypeFilter(filter.result_type, ImageTypeEnum.PHOTO)); |
|
|
|
|
} else if (val == FilterTypeEnum.LOCATION) { |
|
|
|
|
setFilter(new LocationFilter(filter.result_type, [[0.0, 0.0]], polygons_dispatch)); |
|
|
|
|
setFilter(new LocationFilter(filter.result_type, [[0.0, 0.0]])); |
|
|
|
|
} else { |
|
|
|
|
throw new Error('Unsupported filter type: ' + val); |
|
|
|
|
} |
|
|
|
@ -483,12 +479,12 @@ export function LogicalOperatorFilterExpressionControl(props) { |
|
|
|
|
<Box className={classes.logic_op_sbs}> |
|
|
|
|
<Box> |
|
|
|
|
<Box className={classes.logic_op_subexpr}> |
|
|
|
|
<FilterExpressionControl expr={expr.sub_filter_a} onChange={handleAChanged} isRoot={false} /> |
|
|
|
|
<FilterExpressionControl expr={expr.sub_filter_a} onChange={handleAChanged} mayBeRemoved={true} /> |
|
|
|
|
</Box> |
|
|
|
|
</Box> |
|
|
|
|
<Box> |
|
|
|
|
<Box className={classes.logic_op_subexpr}> |
|
|
|
|
<FilterExpressionControl expr={expr.sub_filter_b} onChange={handleBChanged} isRoot={false} /> |
|
|
|
|
<FilterExpressionControl expr={expr.sub_filter_b} onChange={handleBChanged} mayBeRemoved={true} /> |
|
|
|
|
</Box> |
|
|
|
|
</Box> |
|
|
|
|
</Box> |
|
|
|
@ -532,13 +528,16 @@ export function NegationExpressionControl(props) { |
|
|
|
|
onChange(new_filter); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Only nodes which are transformation nodes may normally be removed.
|
|
|
|
|
const may_be_removed = expr instanceof NegationFilter; |
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
<> |
|
|
|
|
<Box className={classes.logic_op_outer}> |
|
|
|
|
<Box className={classes.logic_op_sbs}> |
|
|
|
|
<Box> |
|
|
|
|
<Box className={classes.logic_op_subexpr}> |
|
|
|
|
<FilterExpressionControl expr={expr.body} onChange={handleBodyChanged} isRoot={false} /> |
|
|
|
|
<FilterExpressionControl expr={expr.body} onChange={handleBodyChanged} mayBeRemoved={may_be_removed} /> |
|
|
|
|
</Box> |
|
|
|
|
</Box> |
|
|
|
|
</Box> |
|
|
|
@ -624,7 +623,7 @@ export function LocationFilterExpressionControl(props) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
export function FilterExpressionControl(props) { |
|
|
|
|
const { expr, onChange, isRoot } = props; |
|
|
|
|
const { expr, onChange, mayBeRemoved } = props; |
|
|
|
|
const [anchorEl, setAnchorEl] = React.useState(null); |
|
|
|
|
const [editDialogOpen, setEditDialogOpen] = React.useState(false); |
|
|
|
|
const [combineDialogOpen, setCombineDialogOpen] = React.useState(false); |
|
|
|
@ -718,11 +717,6 @@ export function FilterExpressionControl(props) { |
|
|
|
|
throw new Error('Unsupported filter expression'); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// If this is the root node, removing it is not allowed.
|
|
|
|
|
// Other nodes may be removed.
|
|
|
|
|
// The only exception is a negation node: removing that will replace it by its child.
|
|
|
|
|
var allowRemove = !isRoot || (expr instanceof NegationFilter); |
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
<> |
|
|
|
|
{filter_elem} |
|
|
|
@ -737,7 +731,7 @@ export function FilterExpressionControl(props) { |
|
|
|
|
<MenuItem onClick={handleAnd}>And...</MenuItem> |
|
|
|
|
<MenuItem onClick={handleOr}>Or...</MenuItem> |
|
|
|
|
<MenuItem onClick={handleNegation}>Negate</MenuItem> |
|
|
|
|
{allowRemove && <MenuItem onClick={handleRemove}>Remove</MenuItem>} |
|
|
|
|
{mayBeRemoved && <MenuItem onClick={handleRemove}>Remove</MenuItem>} |
|
|
|
|
</Menu> |
|
|
|
|
<EditFilterExpressionDialog |
|
|
|
|
onClose={handleCloseEditFilterDialog} |
|
|
|
@ -768,6 +762,10 @@ export function FilterControl(props) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// The root node may in principle never be removed,
|
|
|
|
|
// except if it is a transformation node (then the body becomes the new root).
|
|
|
|
|
const may_be_removed = filter instanceof NegationFilter; |
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
<> |
|
|
|
|
<Box className={classes.filtercontrol}> |
|
|
|
@ -781,7 +779,7 @@ export function FilterControl(props) { |
|
|
|
|
} |
|
|
|
|
label={resultTypeString + ':'} |
|
|
|
|
/> |
|
|
|
|
<FilterExpressionControl expr={filter} onChange={onChange} isRoot={true} /> |
|
|
|
|
<FilterExpressionControl expr={filter} onChange={onChange} mayBeRemoved={may_be_removed} /> |
|
|
|
|
</Box> |
|
|
|
|
</> |
|
|
|
|
); |
|
|
|
|