Skip to content

Commit

Permalink
Fix geosolutions-it#3608 add TOC tooltip custmoization
Browse files Browse the repository at this point in the history
  • Loading branch information
MV88 committed Mar 11, 2019
1 parent 891f3db commit 8b299c7
Show file tree
Hide file tree
Showing 9 changed files with 168 additions and 27 deletions.
5 changes: 3 additions & 2 deletions web/client/components/TOC/DefaultGroup.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ class DefaultGroup extends React.Component {
currentLocale: PropTypes.string,
selectedNodes: PropTypes.array,
onSelect: PropTypes.func,
titleTooltip: PropTypes.bool
titleTooltip: PropTypes.bool,
tooltipOptions: PropTypes.object
};

static defaultProps = {
Expand Down Expand Up @@ -74,7 +75,7 @@ class DefaultGroup extends React.Component {
<div className="toc-default-group-head">
{grab}
{this.renderVisibility(error)}
<GroupTitle tooltip={this.props.titleTooltip} node={this.props.node} currentLocale={this.props.currentLocale} onClick={this.props.onToggle} onSelect={this.props.onSelect}/>
<GroupTitle tooltipOptions={this.props.tooltipOptions} tooltip={this.props.titleTooltip} node={this.props.node} currentLocale={this.props.currentLocale} onClick={this.props.onToggle} onSelect={this.props.onSelect}/>
</div>
<GroupChildren level={this.props.level + 1} onSort={this.props.onSort} position="collapsible">
{this.props.children}
Expand Down
8 changes: 6 additions & 2 deletions web/client/components/TOC/DefaultLayer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ const localizedProps = require('../misc/enhancers/localizedProps');

const GlyphIndicator = localizedProps('tooltip')(withTooltip(Glyphicon));

/**
* Default layer node for TOC
*/
class DefaultLayer extends React.Component {
static propTypes = {
node: PropTypes.object,
Expand All @@ -46,7 +49,8 @@ class DefaultLayer extends React.Component {
titleTooltip: PropTypes.bool,
filter: PropTypes.func,
showFullTitleOnExpand: PropTypes.bool,
hideOpacityTooltip: PropTypes.bool
hideOpacityTooltip: PropTypes.bool,
tooltipOptions: PropTypes.object
};

static defaultProps = {
Expand Down Expand Up @@ -144,7 +148,7 @@ class DefaultLayer extends React.Component {
<div className="toc-default-layer-head">
{grab}
{this.renderVisibility()}
<Title tooltip={this.props.titleTooltip} filterText={this.props.filterText} node={this.props.node} currentLocale={this.props.currentLocale} onClick={this.props.onSelect} onContextMenu={this.props.onContextMenu} />
<Title tooltipOptions={this.props.tooltipOptions} tooltip={this.props.titleTooltip} filterText={this.props.filterText} node={this.props.node} currentLocale={this.props.currentLocale} onClick={this.props.onSelect} onContextMenu={this.props.onContextMenu} />
{this.props.node.loading ? <div className="toc-inline-loader"></div> : this.renderToolsLegend(isEmpty)}
{this.props.indicators ? this.renderIndicators() : null}
</div>
Expand Down
10 changes: 6 additions & 4 deletions web/client/components/TOC/fragments/GroupTitle.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
const React = require('react');
const PropTypes = require('prop-types');
const StatusIcon = require('./StatusIcon');
const {isObject} = require('lodash');
const {Tooltip} = require('react-bootstrap');
const OverlayTrigger = require('../../misc/OverlayTrigger');
const {getTooltipText, getTooltip} = require('../../../utils/TOCUtils');

class GroupTitle extends React.Component {
static propTypes = {
Expand All @@ -20,7 +20,8 @@ class GroupTitle extends React.Component {
onSelect: PropTypes.func,
style: PropTypes.object,
currentLocale: PropTypes.string,
tooltip: PropTypes.bool
tooltip: PropTypes.bool,
tooltipOptions: PropTypes.object
};

static inheritedPropTypes = ['node'];
Expand All @@ -37,9 +38,10 @@ class GroupTitle extends React.Component {

render() {
let expanded = this.props.node.expanded !== undefined ? this.props.node.expanded : true;
const groupTitle = isObject(this.props.node.title) ? this.props.node.title[this.props.currentLocale] || this.props.node.title.default || this.props.node.name : this.props.node.title || this.props.node.name;
const groupTitle = getTooltipText("title", this.props.node, this.props.currentLocale);
const tooltipText = getTooltip(this.props.tooltipOptions, this.props.node, this.props.currentLocale);
return this.props.tooltip ? (
<OverlayTrigger placement="top" overlay={(<Tooltip id={"tooltip-layer-group"}>{groupTitle}</Tooltip>)}>
<OverlayTrigger placement="top" overlay={(<Tooltip id={"tooltip-layer-group"}>{tooltipText}</Tooltip>)}>
<div style={this.props.style}>
<span className="toc-group-title" onClick={ this.props.onSelect ? (e) => this.props.onSelect(this.props.node.id, 'group', e.ctrlKey) : () => {}}>{groupTitle}</span><StatusIcon onClick={() => this.props.onClick(this.props.node.id, expanded)} expanded={expanded} node={this.props.node}/>
</div>
Expand Down
15 changes: 9 additions & 6 deletions web/client/components/TOC/fragments/Title.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@

const PropTypes = require('prop-types');
const React = require('react');
const {isObject} = require('lodash');
const {Tooltip} = require('react-bootstrap');
const OverlayTrigger = require('../../misc/OverlayTrigger');
const {getTooltipText, getTooltip} = require('../../../utils/TOCUtils');
require("./css/toctitle.css");

class Title extends React.Component {
Expand All @@ -20,15 +20,17 @@ class Title extends React.Component {
onContextMenu: PropTypes.func,
currentLocale: PropTypes.string,
filterText: PropTypes.string,
tooltip: PropTypes.bool
tooltip: PropTypes.bool,
tooltipOptions: PropTypes.object
};

static defaultProps = {
onClick: () => {},
onContextMenu: () => {},
currentLocale: 'en-US',
filterText: '',
tooltip: false
tooltip: false,
tooltipOptions: null
};

getFilteredTitle = (title) => {
Expand All @@ -43,10 +45,10 @@ class Title extends React.Component {
}

render() {
const translation = isObject(this.props.node.title) ? this.props.node.title[this.props.currentLocale] || this.props.node.title.default : this.props.node.title;
const title = translation || this.props.node.name;
const title = getTooltipText("title", this.props.node, this.props.currentLocale);
const tooltipText = getTooltip(this.props.tooltipOptions, this.props.node, this.props.currentLocale);
return this.props.tooltip ? (
<OverlayTrigger placement="top" overlay={(<Tooltip id={"tooltip-layer-title"}>{title}</Tooltip>)}>
<OverlayTrigger placement="top" overlay={(<Tooltip id={"tooltip-layer-title"}>{tooltipText}</Tooltip>)}>
<div className="toc-title" onClick={this.props.onClick ? (e) => this.props.onClick(this.props.node.id, 'layer', e.ctrlKey) : () => {}} onContextMenu={(e) => {e.preventDefault(); this.props.onContextMenu(this.props.node); }}>
{this.getFilteredTitle(title)}
</div>
Expand All @@ -61,4 +63,5 @@ class Title extends React.Component {
}
}


module.exports = Title;
21 changes: 21 additions & 0 deletions web/client/components/TOC/fragments/__tests__/GroupTitle-test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const GroupTitle = require('../GroupTitle');

const expect = require('expect');
const ReactTestUtils = require('react-dom/test-utils');
const {getTooltip} = require('../../../../utils/TOCUtils');

describe('test GroupTitle module component', () => {
beforeEach((done) => {
Expand Down Expand Up @@ -91,4 +92,24 @@ describe('test GroupTitle module component', () => {
ReactTestUtils.Simulate.mouseOver(domNode);
expect(ReactDOM.findDOMNode(comp).getAttribute('aria-describedby')).toBe(null);
});

it('tests GroupTitle with customtooltip fragments', () => {
const node = {
name: 'group1',
title: {
'default': 'Group',
'it-IT': 'Gruppo'
},
id: "group1",
description: "desc"
};
const tooltipOptions = {"group1": ["title", "description"]};
const currentLocale = "it-IT";
const comp = ReactDOM.render(<GroupTitle node={node} tooltip tooltipOptions={tooltipOptions} currentLocale={currentLocale}/>, document.getElementById("container"));
const domNode = ReactDOM.findDOMNode(comp);
expect(domNode).toExist();
ReactTestUtils.Simulate.mouseOver(domNode);
expect(ReactDOM.findDOMNode(comp).getAttribute('aria-describedby')).toBe('tooltip-layer-group');
expect(getTooltip(tooltipOptions, node, currentLocale)).toBe("Gruppo - desc");
});
});
36 changes: 31 additions & 5 deletions web/client/components/TOC/fragments/__tests__/Title-test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
* LICENSE file in the root directory of this source tree.
*/

var React = require('react');
var ReactDOM = require('react-dom');
var Title = require('../Title');
const React = require('react');
const ReactDOM = require('react-dom');
const Title = require('../Title');
const {getTooltip} = require('../../../../utils/TOCUtils');

var expect = require('expect');
const expect = require('expect');

var ReactTestUtils = require('react-dom/test-utils');
const ReactTestUtils = require('react-dom/test-utils');

describe('test Title module component', () => {
beforeEach((done) => {
Expand Down Expand Up @@ -152,4 +153,29 @@ describe('test Title module component', () => {
ReactTestUtils.Simulate.mouseOver(domNode);
expect(ReactDOM.findDOMNode(comp).getAttribute('aria-describedby')).toBe(null);
});

it('tests Title with customtooltip fragments', () => {
const node = {
name: 'layer00',
title: {
'default': 'Layer',
'it-IT': 'Livello'
},
id: "layer00",
description: "desc",
visibility: true,
storeIndex: 9,
type: 'wms',
url: 'fakeurl'
};
const tooltipOptions = {"layer00": ["title", "description"]};
const currentLocale = "it-IT";
const comp = ReactDOM.render(<Title node={node} tooltip tooltipOptions={tooltipOptions} currentLocale={currentLocale}/>, document.getElementById("container"));
const domNode = ReactDOM.findDOMNode(comp);
expect(domNode).toExist();
ReactTestUtils.Simulate.mouseOver(domNode);
expect(ReactDOM.findDOMNode(comp).getAttribute('aria-describedby')).toBe('tooltip-layer-title');
expect(getTooltip(tooltipOptions, node, currentLocale)).toBe("Livello - desc");
});

});
13 changes: 12 additions & 1 deletion web/client/plugins/TOC.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,7 @@ class LayerTree extends React.Component {
* @prop {object} cfg.layerOptions: options to pass to the layer.
* @prop {boolean} cfg.showFullTitleOnExpand shows full length title in the legend. default `false`.
* @prop {boolean} cfg.hideOpacityTooltip hide toolip on opacity sliders
*
* Some of the layerOptions are: `legendContainerStyle`, `legendStyle`. These 2 allow to customize the legend:
* For instance you can pass some styling props to the legend.
* this example is to make the legend scrollable horizontally
Expand All @@ -472,7 +473,7 @@ class LayerTree extends React.Component {
* }
* }
* ```
* Another layerOptionS entry can be `indicators`. `indicators` is an array of icons to add to the TOC. They must satisfy a condition to be shown in the TOC.
* Another layerOptions entry can be `indicators`. `indicators` is an array of icons to add to the TOC. They must satisfy a condition to be shown in the TOC.
* For the moment only indicators of type `dimension` are supported.
* example :
* ```
Expand All @@ -493,6 +494,16 @@ class LayerTree extends React.Component {
* }
* }]
* ```
*
* Another layerOptions is `tooltipOptions` which contains the custom tooltips fragment for nodes in the TOC
* structure is {"nodeID": ["prop1", "prop2"], "joinsStr": " - "}, it will display the fragment in the order are written
* for example
* ```
* "tooltipOptions": {
* "id_of_the_layer": ["title", "description"]
* }
* ```
* it can contain also the "joinStr" property to be used for joining tooltips fragments, default is " - "
*/
const TOCPlugin = connect(tocSelector, {
groupPropertiesChangeHandler: changeGroupProperties,
Expand Down
38 changes: 38 additions & 0 deletions web/client/utils/TOCUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* LICENSE file in the root directory of this source tree.
*/

const {isObject, find, isNil} = require('lodash');

const TOCUtils = {
createFromSearch: function(options, search) {
Expand All @@ -22,6 +23,43 @@ const TOCUtils = {

const val = search.replace(/\./g, '${dot}').replace(/\//g, '.');
return {label: search, value: val};
},
/**
* it fetches and joins the fragments for tooltips for node component in the TOC
* @param {object} tooltipOptions
* @param {object} node layer or group
* @param {string} currentLocale
* @return {string} tooltip text
*/
getTooltip: (tooltipOptions, node, currentLocale) => {
// if this node is present in the tooltipOptions then use those keys to create the text for the tooltip
let tooltips = tooltipOptions && find(Object.keys(tooltipOptions), id => id === node.id);
if (tooltips) {
// if you specify a joinsStr it uses it for concatenating the various fields
return tooltipOptions[tooltips]
.map(t => TOCUtils.getTooltipText(t, node, currentLocale))
.filter(t => !isNil(t))
.join(tooltipOptions.joinStr || " - ");
}
return TOCUtils.getTooltipText("title", node, currentLocale);
},
/**
* it fetch the fragment to compose the tooltip
* @param {object} fragment in the node
* @param {object} node layer or group
* @param {string} currentLocale
* @return {string} tooltip fragment
*/
getTooltipText: (fragment, node, currentLocale) => {
switch (fragment) {
case "title": {
const translation = isObject(node.title) ? node.title[currentLocale] || node.title.default : node.title;
const title = translation || node.name;
return title;
}
// default is the name of the property passed
default: return node[fragment];
}
}
};

Expand Down
49 changes: 42 additions & 7 deletions web/client/utils/__tests__/TOCUtils-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* LICENSE file in the root directory of this source tree.
*/
const expect = require('expect');
const {createFromSearch} = require('../TOCUtils');
const {createFromSearch, getTooltip, getTooltipText} = require('../TOCUtils');
let options = [{label: "lab1", value: "val1"}];

describe('TOCUtils', () => {
Expand All @@ -20,11 +20,46 @@ describe('TOCUtils', () => {
});

it('test createFromSearch for General Fragment with new valid value', () => {
let val = createFromSearch(options, "lab2");
expect(val.label).toBe("lab2");
expect(val.value).toBe("lab2");
val = createFromSearch(options, "lab2/lab5");
expect(val.label).toBe("lab2/lab5");
expect(val.value).toBe("lab2.lab5");
const node = {
name: 'layer00',
title: {
'default': 'Layer',
'it-IT': 'Livello'
},
id: "layer00",
description: "desc",
visibility: true,
storeIndex: 9,
type: 'wms',
url: 'fakeurl'
};
const tooltipOptions = {"layer00": ["title", "description", "fakeFragment"]};
const currentLocale = "it-IT";
const tooltip = getTooltip(tooltipOptions, node, currentLocale);
expect(tooltip).toBe("Livello - desc");
});
it('test getTooltipText', () => {
const node = {
name: 'layer00',
title: {
'default': 'Layer',
'it-IT': 'Livello'
},
id: "layer00",
description: "desc",
visibility: true,
storeIndex: 9,
type: 'wms',
url: 'fakeurl'
};
const currentLocale = "it-IT";
let tooltip = getTooltipText("title", node, currentLocale);
expect(tooltip).toBe("Livello");
tooltip = getTooltipText("description", node, currentLocale);
expect(tooltip).toBe("desc");

tooltip = getTooltipText("fakeFragment", node, currentLocale);
expect(tooltip).toBe(undefined);

});
});

0 comments on commit 8b299c7

Please sign in to comment.