Skip to content

Commit

Permalink
Implement type question answer
Browse files Browse the repository at this point in the history
  • Loading branch information
holubv committed May 2, 2021
1 parent 7eb8685 commit 572e927
Show file tree
Hide file tree
Showing 6 changed files with 262 additions and 18 deletions.
3 changes: 3 additions & 0 deletions src/Constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@ export default class Constants {
static HAS_UNIT_OF_MEASURE = 'http://onto.fel.cvut.cz/ontologies/form/has-unit-of-measure-question';

static LAYOUT_TYPE_QUESTION = 'type-question';

static BROADER = 'http://www.w3.org/2004/02/skos/core#broader';
static DISJOINT_WITH = 'http://www.w3.org/2002/07/owl#disjointWith';
}
33 changes: 33 additions & 0 deletions src/Utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,39 @@ export default class Utils {
return false;
}

/**
* @param {string[]} arr1
* @param {string[]} arr2
*/
static hasArraySameValues(arr1, arr2) {

if (!arr1 || !arr2) {
return false;
}

if (arr1.length === undefined) {
return false;
}

if (arr1.length !== arr2.length) {
return false;
}

const set = {};
for (let el of arr1) {
set[el] = 1;
}

for (let el of arr2) {
if (!set[el]) {
return false;
}
set[el] = 2;
}

return Object.values(set).every(el => el === 2);
}

// static _findQuestion(question, id) {
//
// if (question['@id'] === id) {
Expand Down
10 changes: 10 additions & 0 deletions src/components/AnswerableSectionComposite.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ export default class AnswerableSectionComposite extends Question {
});
}

_getAnswerWidthStyle() {
if (TypeQuestionAnswer.mappingRule(this.props.question)) {
return {
maxWidth: 'none'
}
}

return super._getAnswerWidthStyle();
}

renderAnswers() {
const question = this.props.question,
children = [],
Expand Down
161 changes: 151 additions & 10 deletions src/components/TypeQuestionAnswer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import Constants from "../Constants";
import SmartComponents from "../SmartComponents";
import PropTypes from "prop-types";
import {VirtualizedTreeSelect} from "intelligent-tree-select";
import Utils from "../Utils";

export default class TypeQuestionAnswer extends React.Component {

Expand All @@ -23,40 +24,167 @@ export default class TypeQuestionAnswer extends React.Component {
super(props);

this.state = {
tree: [
{id: '1', value: '1', label: 'One', children: ['1-1', '1-2']},
{id: '1-1', value: '1-1', label: 'One One', children: []},
{id: '1-2', value: '1-2', label: 'One Two', children: []},
{id: '2', value: '2', label: 'Two', children: []},
],
selected: null
// tree: [
// {id: '1', value: '1', label: 'One', children: ['1-1', '1-2']},
// {id: '1-1', value: '1-1', label: 'One One', children: []},
// {id: '1-2', value: '1-2', label: 'One Two', children: []},
// {id: '2', value: '2', label: 'Two', children: []},
// ],
tree: {},
selected: [],
update: 0
}
}

_onChange = value => {
console.log(value);

//console.log(JsonLdObjectMap.objectMap);
//console.log(JsonLdObjectMap.getObject('x:zvire'));

const change = { ...this.props.answer };
const change = {...this.props.answer};

change[SConstants.HAS_DATA_VALUE] = {
'@value': !!(value && value.length)
};

this.setState({selected: value});
this.setState({
selected: value,
tree: this._checkDisjointOptions(this.state.tree, value),
update: this.state.update + 1
});

// const tree = this.state.tree;
// tree[1].checked = false;
// tree[1].disabled = true;
// this.setState({tree: tree});

this.props.onChange(this.props.index, change);
}

_checkDisjointOptions(tree, selected) {

for (let o of Object.values(tree)) {
o.disabled = false;
}

if (selected === undefined) {
selected = this.state.selected;
}

if (selected) {
for (let selectedOption of selected) {
for (let d of selectedOption.disjoint) {
tree[d].disabled = true;
}
}
}

return tree;
}

_isRegenerationNeeded(previousQuestion) {
if (!Object.values(this.state.tree).length) {
return true;
}
const question = this.props.question;
return !Utils.hasArraySameValues(previousQuestion[SConstants.HAS_OPTION], question[SConstants.HAS_OPTION]);
}

_generateOptions() {
console.log('generating tree...');
const question = this.props.question;
const possibleValues = question[SConstants.HAS_OPTION];
if (!possibleValues || !possibleValues.length) {
return [];
}

const objects = possibleValues
.map(id => {
let def = JsonLdObjectMap.getObject(id);
if (!def) {
console.warn('cannot find object ' + id);
return null;
}
return def;
})
.filter(o => o !== null);

const options = {};
const relations = [];

for (let def of objects) {

let label = JsonLdUtils.getLocalized(def[SConstants.RDFS_LABEL], this.context.options.intl);

options[def['@id']] = {
value: def['@id'],
label: label,
children: [],
disjoint: []
};

if (def[Constants.DISJOINT_WITH]) {
let disjoints = def[Constants.DISJOINT_WITH];

if (disjoints.length === undefined) {
// only single disjoint without array
disjoints = [disjoints];
}

for (let disjoint of disjoints) {
relations.push({
type: 'disjoint',
a: disjoint['@id'],
b: def['@id']
});
}
}

if (def[Constants.BROADER]) {
relations.push({
type: 'parent-child',
parent: def[Constants.BROADER]['@id'],
child: def['@id']
});
}
}

for (let relation of relations) {

if (relation.type === 'parent-child') {
options[relation.parent].children.push(relation.child);
}

if (relation.type === 'disjoint') {
options[relation.a].disjoint.push(relation.b);
options[relation.b].disjoint.push(relation.a);
}
}

this._checkDisjointOptions(options);

console.log(options);

this.setState({
tree: options,
update: this.state.update + 1
});
}

_renderSelect() {

if (!Object.values(this.state.tree).length) {
return null;
}

return (
<VirtualizedTreeSelect
value={this.state.selected}
valueKey="value"
labelKey="label"
childrenKey="children"
options={this.state.tree}
options={Object.values(this.state.tree)}
expanded={true}
closeOnSelect={false}
onChange={this._onChange}
Expand All @@ -80,7 +208,20 @@ export default class TypeQuestionAnswer extends React.Component {
return <Form.Label>{label}</Form.Label>;
}

componentDidMount() {
this._generateOptions();
}

componentDidUpdate(prevProps) {
if (this._isRegenerationNeeded(prevProps.question)) {
console.log('regeneration needed');
this._generateOptions();
}

}

render() {

return (
<div className="type-answer-group">
{this._renderLabel()}
Expand Down
10 changes: 9 additions & 1 deletion src/styles/components.css
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@
margin-left: 20px;
}

.answerable-section > .card > .card-header .answer {
justify-content: space-between;
}

.answerable-section > .card > .card-header .answer .show-advanced-switch {
flex-grow: 0;
}

.answerable-section > .card > .card-header .answer > .answer-content {
position: relative;
min-height: 24px;
Expand All @@ -55,7 +63,7 @@
.type-answer-group {
display: flex;
position: absolute;
width: 100%;
min-width: 370px;
}

.type-answer-group .Select {
Expand Down
63 changes: 56 additions & 7 deletions test/form2.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
"xml": "http://www.w3.org/XML/1998/namespace",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"skos": "http://www.w3.org/2004/02/skos/core#",
"label": {
"@id": "http://www.w3.org/2000/01/rdf-schema#label"
},
Expand Down Expand Up @@ -119,15 +120,56 @@
},
"@graph": [
{
"@id": "x:zvire",
"label": "Zvíře"
"@id": "pravnicka-osoba",
"label": "Právnická osoba"
},
{
"@id": "x:pes",
"label": "Pes",
"broader": {
"@id": "x:zvire"
}
"@id": "fyzicka-osoba",
"label": "Fyzická osoba",
"owl:disjointWith": [
{
"@id": "pravnicka-osoba"
}
]
},
{
"@id": "fyzicka-osoba--nezletila",
"label": "Fyzická osoba nezletilá",
"skos:broader": {
"@id": "fyzicka-osoba"
},
"owl:disjointWith": [
{
"@id": "pravnicka-osoba"
}
]
},
{
"@id": "fyzicka-osoba--chytra",
"label": "Fyzická osoba chytrá",
"skos:broader": {
"@id": "fyzicka-osoba"
},
"owl:disjointWith": [
{
"@id": "pravnicka-osoba"
}
]
},
{
"@id": "fyzicka-osoba--hloupa",
"label": "Fyzická osoba hloupá",
"skos:broader": {
"@id": "fyzicka-osoba"
},
"owl:disjointWith": [
{
"@id": "pravnicka-osoba"
},
{
"@id": "fyzicka-osoba--chytra"
}
]
},
{
"@id": "_:b0",
Expand Down Expand Up @@ -214,6 +256,13 @@
"section",
"type-question"
],
"has-possible-value": [
"fyzicka-osoba",
"pravnicka-osoba",
"fyzicka-osoba--nezletila",
"fyzicka-osoba--chytra",
"fyzicka-osoba--hloupa"
],
"label": "Provozovatel"
},
{
Expand Down

0 comments on commit 572e927

Please sign in to comment.