Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature new query builder #22

Merged
merged 12 commits into from
Jul 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions js/components/ComponentFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ define(function (require) {
'SHARE': 'interface/share/Share',
'INFOMODAL': 'controls/modals/InfoModal',
'MDMODAL': 'controls/modals/MarkDownModal',
'QUERY': 'interface/query/query',
'QUERY': 'interface/query/queryBuilder',
'TUTORIAL': 'interface/tutorial/Tutorial',
'PYTHONCONSOLE': 'interface/pythonConsole/PythonConsole',
'DICOMVIEWER': 'interface/dicomViewer/DicomViewer',
Expand Down Expand Up @@ -200,7 +200,7 @@ define(function (require) {
case 'SHARE': require(['./interface/share/Share'],cb); break;
case 'INFOMODAL': require(['./controls/modals/InfoModal'],cb); break;
case 'MDMODAL': require(['./controls/modals/MarkDownModal'],cb); break;
case 'QUERY': require(['./interface/query/query'],cb); break;
case 'QUERY': require(['./interface/query/queryBuilder'],cb); break;
case 'TUTORIAL': require(['./interface/tutorial/Tutorial'],cb); break;
case 'PYTHONCONSOLE': require(['./interface/pythonConsole/PythonConsole'],cb); break;
case 'DICOMVIEWER': require(['./interface/dicomViewer/DicomViewer'],cb); break;
Expand Down
367 changes: 187 additions & 180 deletions js/components/interface/3dCanvas/ThreeDEngine.js

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
define(function (require) {

require("../query.less");
require("../react-simpletabs.less");

var React = require('react');
var GEPPETTO = require('geppetto');

class QueryLinkComponent extends React.Component {
constructor (props) {
super(props);
}

render () {

var displayText = this.props.data;
var path = this.props.rowData.id;
var that = this;

var action = function (e) {
e.preventDefault();
e.nativeEvent.stopImmediatePropagation();
var actionStr = that.props.metadata.actions;
actionStr = actionStr.replace(/\$entity\$/gi, path);
GEPPETTO.CommandController.execute(actionStr);
that.props.metadata.queryBuilder.close();
};

return (
<div>
<a href='#' onClick={action}>{displayText}</a>
</div>
)
}
}

return QueryLinkComponent;
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
define(function (require) {

require("../query.less");
require("../react-simpletabs.less");

var React = require('react');
var GEPPETTO = require('geppetto');

class QueryResultsControlsComponent extends React.Component {
constructor (props) {
super(props);

}

replaceTokensWithPath (inputStr, path) {
return inputStr.replace(/\$ID\$/gi, path);
}

getActionString (control, path) {
var actionStr = '';

if (control.actions.length > 0) {
for (var i = 0; i < control.actions.length; i++) {
actionStr += ((i != 0) ? ";" : "") + this.replaceTokensWithPath(control.actions[i], path);
}
}

return actionStr;
}

resolveCondition (control, path, negateCondition) {
if (negateCondition == undefined) {
negateCondition = false;
}

var resolvedConfig = control;

if (resolvedConfig.hasOwnProperty('condition')) {
// evaluate condition and reassign control depending on results
var conditionStr = this.replaceTokensWithPath(control.condition, path);
if (eval(conditionStr)) {
resolvedConfig = negateCondition ? resolvedConfig.false : resolvedConfig.true;
} else {
resolvedConfig = negateCondition ? resolvedConfig.true : resolvedConfig.false;
}
}

return resolvedConfig;
}

render () {
// TODO: would be nicer to pass controls and config straight from the parent component rather than assume
var config = this.props.metadata.queryBuilder.state.resultsControlsConfig;
var resultItemId = this.props.rowData.id;
var ctrlButtons = [];

// Add common control buttons to list
for (var control in config.Common) {
var add = true;

// check show condition
if (config.Common[control].showCondition != undefined) {
var condition = this.replaceTokensWithPath(config.Common[control].showCondition, resultItemId);
add = eval(condition);
}

if (add) {
ctrlButtons.push(config.Common[control]);
}
}

var that = this;

return (
<div>
{ctrlButtons.map(function (control, id) {
// grab attributes to init button attributes
var controlConfig = that.resolveCondition(control, resultItemId);
var idVal = resultItemId.replace(/\./g, '_').replace(/\[/g, '_').replace(/\]/g, '_') + "_" + controlConfig.id + "_queryResults_btn";
var tooltip = controlConfig.tooltip;
var classVal = "btn queryresults-button fa " + controlConfig.icon;
var styleVal = {};

// define action function
var actionFn = function (param) {
// NOTE: there is a closure on 'control' so it's always the right one
var controlConfig = that.resolveCondition(control, resultItemId);

// take out action string
var actionStr = that.getActionString(controlConfig, resultItemId);

if (param != undefined) {
actionStr = actionStr.replace(/\$param\$/gi, param);
}

// run action
if (actionStr != '' && actionStr != undefined) {
GEPPETTO.CommandController.execute(actionStr);
// check custom action to run after configured command
if (that.props.metadata.action != '' && that.props.metadata.action != undefined) {
// straight up eval as we don't want this to show on the geppetto console
eval(that.props.metadata.action.replace(/\$ID\$/gi, resultItemId));
}
}

// if conditional, swap icon with the other condition outcome
if (control.hasOwnProperty('condition')) {
var otherConfig = that.resolveCondition(control, path);
var element = $('#' + idVal);
element.removeClass();
element.addClass("btn queryresults-button fa " + otherConfig.icon);
}
};

return (
<span key={id}>
<button id={idVal}
className={classVal}
style={styleVal}
title={tooltip}
onClick={actionFn}>
</button>
</span>
)
})}
</div>
)
}
}

return QueryResultsControlsComponent;
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
define(function (require) {

require("../query.less");
require("../react-simpletabs.less");

var React = require('react');
var GEPPETTO = require('geppetto');
var slick = require('slick-carousel');

class SlideshowImageComponent extends React.Component {
constructor (props) {
super(props);

this.state = { carouselFullyLoaded: false };

this.isCarousel = false;
this.imageContainerId = '';
this.fullyLoaded = false;
}

getImageClickAction (path) {
var that = this;

var action = function (e) {
e.preventDefault();
e.nativeEvent.stopImmediatePropagation();
var actionStr = that.props.metadata.actions;
actionStr = actionStr.replace(/\$entity\$/gi, path);
GEPPETTO.CommandController.execute(actionStr);
that.props.metadata.queryBuilder.close();
};

return action;
}

componentDidMount () {
// apply carousel
if (this.isCarousel) {
var slickDivElement = $('#' + this.imageContainerId + '.slickdiv');
slickDivElement.slick();
var that = this;

// reload slick carousel if it's first time clicking on arrow in any direction
slickDivElement.find(".slick-arrow").on("click", function () {
if (!that.fullyLoaded) {
that.setState({ carouselFullyLoaded: true });
that.fullyLoaded = true;
}
}, { passive: true });
}
}

componentDidUpdate () {
// on component refresh, update slick carousel
$('#' + this.imageContainerId + '.slickdiv').slick('unslick').slick();
}

buildImage (thumbImage, imageContainerId) {
var action = this.getImageClickAction(thumbImage.reference);
const imgElement = <div id={imageContainerId} className="query-results-image collapse in">
<a href='' onClick={action}>
<img className="query-results-image invert" src={thumbImage.data} />
</a>
</div>
return imgElement;
}

buildCarousel () {
var jsonImageVariable = JSON.parse(this.props.data);
var imgElement = "";

if (jsonImageVariable.initialValues[0] != undefined) {
var imageContainerId = this.props.rowData.id + '-image-container';
this.imageContainerId = imageContainerId;

var value = jsonImageVariable.initialValues[0].value;
if (value.eClass == GEPPETTO.Resources.ARRAY_VALUE) {
if (value.elements.length > 1) {
this.isCarousel = true;
var imagesToLoad = 2;
if (this.state.carouselFullyLoaded) {
imagesToLoad = value.elements.length;
}

// set flag to fully loaded if total length of images to render is less or equal to 2
if (value.elements.length <= 2) {
this.fullyLoaded = true;
}

var that = this;
// if it's an array, create a carousel (relies on slick)
var elements = value.elements.map(function (item, key) {
if (key < imagesToLoad) {
var image = item.initialValue;
var action = that.getImageClickAction(image.reference);
return <div key={key} className="query-results-slick-image"> {image.name}
<a href='' onClick={action}>
<img className="popup-image invert" src={image.data} />
</a>
</div>
}
});

elements = elements.slice(0, imagesToLoad);

imgElement = <div id={imageContainerId} className="slickdiv query-results-slick collapse in"
data-slick={JSON.stringify({ fade: true, centerMode: true, slidesToShow: 1, slidesToScroll: 1 })}>
{elements}
</div>
} else {
imgElement = this.buildImage(value.elements[0].initialValue, imageContainerId);
}
} else if (value.eClass == GEPPETTO.Resources.IMAGE) {
// otherwise we just show an image
imgElement = this.buildImage(value, imageContainerId);
}
}

return imgElement;
}


render () {
var imgElement = "";
if (this.props.data != "" && this.props.data != undefined) {
imgElement = this.buildCarousel();
}

return (
<div>
{imgElement}
</div>
)
}
}

return SlideshowImageComponent;
});
Loading