Skip to content

Commit

Permalink
Add custom linkers for bool/string/cat
Browse files Browse the repository at this point in the history
  • Loading branch information
mboudet committed May 17, 2023
1 parent e0477e1 commit 763bcf2
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 13 deletions.
25 changes: 23 additions & 2 deletions askomics/libaskomics/SparqlQuery.py
Expand Up @@ -1311,7 +1311,11 @@ def build_query_from_json(self, preview=False, for_editor=False):
attributes[attribute["linkedWith"]]["entity_id"],
attributes[attribute["linkedWith"]]["label"]
))
var_to_replace.append((obj, var_2))
if not attribute.get('linkedNegative', False):
var_to_replace.append((obj, var_2))
else:
filter_string = "FILTER ( {} {} {} ) .".format(obj, "!=", var_2)
self.store_filter(filter_string, block_id, sblock_id, pblock_ids)

# Text
if attribute["type"] == "text":
Expand Down Expand Up @@ -1354,6 +1358,18 @@ def build_query_from_json(self, preview=False, for_editor=False):
))
var_to_replace.append((obj, var_2))

any([filter['filterSign'] == "=" and not filter['filterValue'] for filter in attribute.get('linkedFilters', [])])

if not (attribute.get('linkedNegative', False) or attribute.get('linkedFilterValue')):
var_to_replace.append((obj, var_2))
else:
filter = "!=" if attribute.get('linkedNegative', False) else "="
regex_clause = var_2
if attribute.get('linkedFilterValue'):
regex_clause = "REGEX(REPLACE('{}', '\\$1', {}, 'i'))".format(attribute.get('linkedFilterValue'), var_2)
filter_string = "FILTER ( {} {} {} ) .".format(obj, filter, regex_clause)
self.store_filter(filter_string, block_id, sblock_id, pblock_ids)

# Numeric
if attribute["type"] == "decimal":
if attribute["visible"] or Utils.check_key_in_list_of_dict(attribute["filters"], "filterValue") or attribute["id"] in start_end or attribute["id"] in linked_attributes:
Expand Down Expand Up @@ -1524,7 +1540,12 @@ def build_query_from_json(self, preview=False, for_editor=False):
attributes[attribute["linkedWith"]]["entity_id"],
attributes[attribute["linkedWith"]]["label"]
))
var_to_replace.append((category_value_uri, var_2))

if not attribute.get('linkedNegative', False):
var_to_replace.append((category_value_uri, var_2))
else:
filter_string = "FILTER ( {} {} {} ) .".format(category_value_uri, "!=", var_2)
self.store_filter(filter_string, block_id, sblock_id, pblock_ids)

from_string = "" if self.settings.getboolean("askomics", "single_tenant", fallback=False) else self.get_froms_from_graphs(self.graphs)
federated_from_string = self.get_federated_froms_from_graphs(self.graphs)
Expand Down
101 changes: 93 additions & 8 deletions askomics/react/src/routes/query/attribute.jsx
Expand Up @@ -39,6 +39,8 @@ export default class AttributeBox extends Component {
this.handleLinkedNumericValue = this.props.handleLinkedNumericValue.bind(this)
this.toggleAddNumLinkedFilter = this.props.toggleAddNumLinkedFilter.bind(this)
this.toggleRemoveNumLinkedFilter = this.props.toggleRemoveNumLinkedFilter.bind(this)
this.handleLinkedNegative = this.props.handleLinkedNegative.bind(this)
this.handleLinkedFilterValue = this.props.handleLinkedFilterValue.bind(this)
this.cancelRequest
}

Expand All @@ -60,7 +62,7 @@ export default class AttributeBox extends Component {
})
}

renderLinker (type="") {
renderLinker () {
let options = []
let optionDict = {}
let content
Expand All @@ -77,10 +79,19 @@ export default class AttributeBox extends Component {
}
})

if (type == "numeric"){
if (this.props.attribute.type == 'text') {
box = this.renderTextLinker(optionDict)
}
if (this.props.attribute.type == 'decimal') {
content = this.renderNumericLinker(optionDict)
}
if (type == "date"){
if (this.props.attribute.type == 'category') {
box = this.renderBooleanLinker(optionDict)
}
if (this.props.attribute.type == 'boolean') {
box = this.renderBooleanLinker(optionDict)
}
if (this.props.attribute.type == 'date') {
content = this.renderNumericLinker(optionDict, "date")
}

Expand Down Expand Up @@ -180,7 +191,7 @@ export default class AttributeBox extends Component {
}

if (this.props.attribute.linkedWith) {
form = this.renderLinker("text")
form = this.renderLinker()
} else {
form = (
<table style={{ width: '100%' }}>
Expand Down Expand Up @@ -251,7 +262,7 @@ export default class AttributeBox extends Component {
let numberOfFilters = this.props.attribute.filters.length - 1

if (this.props.attribute.linked) {
form = this.renderLinker("numeric")
form = this.renderLinker()
} else {
form = (
<table style={{ width: '100%' }}>
Expand Down Expand Up @@ -376,7 +387,7 @@ export default class AttributeBox extends Component {
let form

if (this.props.attribute.linked) {
form = this.renderLinker("boolean")
form = this.renderLinker()
} else {
form = (
<FormGroup>
Expand Down Expand Up @@ -436,7 +447,7 @@ export default class AttributeBox extends Component {
let numberOfFilters = this.props.attribute.filters.length - 1

if (this.props.attribute.linked) {
form = this.renderLinker("date")
form = this.renderLinker()
} else {
form = (
<table style={{ width: '100%' }}>
Expand Down Expand Up @@ -544,6 +555,78 @@ export default class AttributeBox extends Component {
return customParams
}

renderTextLinker (options){
let selected_sign = {
'=': !this.props.attribute.linkedNegative,
"≠": this.props.attribute.linkedNegative
}

let customParams
const placeholder = "$1"

if (typeof this.props.attribute.linkedWith !== "object") {
let selectedLabel = options[this.props.attribute.linkedWith.toString()] + " as $1"
customParams = (
<table style={{ width: '100%' }}>
<tr>
<td>
<CustomInput disabled={this.props.attribute.optional} type="select" id={this.props.attribute.id} onChange={this.handleLinkedNegative}>
{Object.keys(selected_sign).map(type => {
return <option key={type} selected={selected_sign[type]} value={type}>{type}</option>
})}
</CustomInput>
</td>
<td>
<Input disabled={true} type="text" value={selectedLabel} size={selectedLabel.length}/>
</td>
<td>
<Input
disabled={this.props.attribute.optional}
type="text"
id={this.props.attribute.id}
value={this.props.attribute.linkedFilterValue}
onChange={this.handleLinkedFilterValue}
placeholder={placeholder}
data-tip data-for={"linkedTooltip"}
/>
</td>
</tr>
</table>
)
}
return customParams
}

renderBooleanLinker (options, type="num"){
let selected_sign = {
'=': !this.props.attribute.linkedNegative,
"≠": this.props.attribute.linkedNegative
}

let customParams
const placeholder = "$1"

if (typeof this.props.attribute.linkedWith !== "object") {
let selectedLabel = options[this.props.attribute.linkedWith.toString()]
customParams = (
<table style={{ width: '100%' }}>
<tr>
<td>
<CustomInput disabled={this.props.attribute.optional} type="select" id={this.props.attribute.id} onChange={this.handleLinkedNegative}>
{Object.keys(selected_sign).map(type => {
return <option key={type} selected={selected_sign[type]} value={type}>{type}</option>
})}
</CustomInput>
</td>
<td>
<Input disabled={true} type="text" value={selectedLabel} size={selectedLabel.length}/>
</td>
</tr>
</table>
)
}
return customParams
}

render () {
let box = null
Expand Down Expand Up @@ -592,5 +675,7 @@ AttributeBox.propTypes = {
handleLinkedNumericSign: PropTypes.func,
handleLinkedNumericValue: PropTypes.func,
toggleAddNumLinkedFilter: PropTypes.func,
toggleRemoveNumLinkedFilter: PropTypes.func
toggleRemoveNumLinkedFilter: PropTypes.func,
handleLinkedNegative: PropTypes.func,
handleLinkedFilterValue: PropTypes.func
}
30 changes: 27 additions & 3 deletions askomics/react/src/routes/query/query.jsx
Expand Up @@ -389,19 +389,22 @@ export default class Query extends Component {
}

if (attributeType == 'text') {
nodeAttribute.filterType = nodeAttribute.linkedFilterType = 'exact'
nodeAttribute.filterType = 'exact'
nodeAttribute.linkedNegative = false
nodeAttribute.filterValue = nodeAttribute.linkedFilterValue = ''
}

if (attributeType == 'category') {
nodeAttribute.exclude = false
nodeAttribute.linkedNegative = false
nodeAttribute.filterValues = attr.categories
nodeAttribute.filterSelectedValues = []
}

if (attributeType == 'boolean') {
nodeAttribute.filterValues = nodeAttribute.linkedFilterValue = ["true", "false"]
nodeAttribute.filterSelectedValues = nodeAttribute.linkedFilterSelectedValues = []
nodeAttribute.filterValues = ["true", "false"]
nodeAttribute.linkedNegative = false
nodeAttribute.filterSelectedValues = []
}

if (attributeType == 'date') {
Expand Down Expand Up @@ -1133,6 +1136,15 @@ export default class Query extends Component {
this.updateGraphState()
}

handleLinkedNegative (event) {
this.graphState.attr.map(attr => {
if (attr.id == event.target.id) {
attr.linkedNegative = event.target.value == '=' ? false : true
}
})
this.updateGraphState()
}

handleFilterType (event) {
this.graphState.attr.map(attr => {
if (attr.id == event.target.id) {
Expand All @@ -1151,6 +1163,15 @@ export default class Query extends Component {
this.updateGraphState()
}

handleLinkedFilterValue (event) {
this.graphState.attr.map(attr => {
if (attr.id == event.target.id) {
attr.linkedFilterValue = event.target.value
}
})
this.updateGraphState()
}

handleFilterCategory (event) {
this.graphState.attr.map(attr => {
if (attr.id == event.target.id) {
Expand Down Expand Up @@ -1658,6 +1679,7 @@ export default class Query extends Component {
<ReactTooltip id="optionalTooltip">Show all values, including empty values.</ReactTooltip>
<ReactTooltip id="excludeTooltip">Exclude categories, instead of including</ReactTooltip>
<ReactTooltip id="visibleTooltip">Display attribute value in the results</ReactTooltip>
<ReactTooltip id="linkedTooltip">Regex value, with $1 as a placeholder for the linked value. Ex: $1-suffix</ReactTooltip>
</div>
)

Expand Down Expand Up @@ -1692,6 +1714,8 @@ export default class Query extends Component {
handleLinkedNumericValue={p => this.handleLinkedNumericValue(p)}
toggleAddNumLinkedFilter={p => this.toggleAddNumLinkedFilter(p)}
toggleRemoveNumLinkedFilter={p => this.toggleRemoveNumLinkedFilter(p)}
handleLinkedNegative={p => this.handleLinkedNegative(p)}
handleLinkedFilterValue={p => this.handleLinkedFilterValue(p)}
config={this.state.config}
isOnto={isOnto}
entityUri={this.currentSelected.uri}
Expand Down

0 comments on commit 763bcf2

Please sign in to comment.