Commit e19e9ffb authored by Maxime Chaillet's avatar Maxime Chaillet

merge TagListTableLine in TagListPanel. Reactivate current tests on...

merge TagListTableLine in TagListPanel. Reactivate current tests on tagListPanel. it fixes #176.
parent 5eb5805d
import React from 'react';
import PropTypes from 'prop-types';
import { Grid, Row, Col } from 'react-bootstrap';
import { TAG_MANAGER_CONTEXT, BASIC_EVENT_CONTEXT, EDIT_EVENT_CONTEXT, INFO_MESSAGE_TYPE } from '../../../constants/EventTypes';
import { Grid, Row, Col, Button, Label } from 'react-bootstrap';
import { INFO_MESSAGE_TYPE } from '../../../constants/EventTypes';
import _ from 'lodash';
import UserMessage from '../../UserMessage';
import './TagList.css';
import TagListTableLine from './TagListTableLine';
/**
* React component which displays a list of tags
* @param {*} props tag as provided by the server
* React component which renders a list of tags in a panel
*/
class TagListPanel extends React.Component {
constructor(props) {
super(props);
}
render() {
let { availableTags, context } = this.props;
let { availableTags, onEditButtonClicked } = this.props;
if (context === TAG_MANAGER_CONTEXT) {
// show tags for management
if (!availableTags || availableTags.length === 0) {
return (
if (!availableTags || availableTags.length === 0) {
return (
<Grid fluid={true} >
<h3> Tags currently available in this proposal</h3>
<Row style={{ marginLeft: '30px', marginRight: '30px', marginTop: '20px' }}>
<UserMessage
message='There is no tag in this proposal yet.'
isTextCentered={true}
type={INFO_MESSAGE_TYPE}
/>
</Row>
</Grid >
);
} else {
let detailedTags = [];
let sortedAvailableTags = _.sortBy(availableTags, ['name']);
detailedTags = sortedAvailableTags.map((tag, index) => { return (<TagListPanelLine key={index} tag={tag} onEditButtonClicked={onEditButtonClicked} />); });
return (
<div style={{ paddingBottom: '70px' }}>
<Grid fluid={true} >
<h3> Tags currently available in this proposal</h3>
<Row style={{ marginLeft: '30px', marginRight: '30px', marginTop: '20px' }}>
<UserMessage
message='There is no tag in this proposal yet.'
isTextCentered={true}
type={INFO_MESSAGE_TYPE}
/>
<Row style={{ marginTop: '20px' }}>
<Col xs={0} md={1}> </Col>
<Col xs={12} md={10}>
{detailedTags}
</Col>
<Col xs={0} md={1}> </Col>
</Row>
</Grid >
);
} else {
let detailedTags = [];
let sortedAvailableTags = _.sortBy(availableTags, ['name']);
detailedTags = sortedAvailableTags.map((tag, index) => { return (<TagListTableLine tag={tag} editTag={this.props.editTag} key={index} />); });
return (
<div style={{ paddingBottom: '70px' }}>
<Grid fluid={true} >
<h3> Tags currently available in this proposal</h3>
<Row style={{ marginTop: '20px' }}>
<Col xs={0} md={1}> </Col>
<Col xs={12} md={10}>
{detailedTags}
</Col>
<Col xs={0} md={1}> </Col>
</Row>
</Grid >
</div>);
};
// } else if (context === BASIC_EVENT_CONTEXT) {
// let selectedTags = this.props.selectedTags ?
// this.props.selectedTags.map((tag) => { return (<TagViewer key={tag._id} context={BASIC_EVENT_CONTEXT} tag={tag} removeTag={this.props.removeTagFromSelection} />); })
// : null;
// return (<div> {selectedTags} </div>);
}
return null;
</div>);
};
}
}
TagListPanel.propTypes = {
/* List of available tags (can be null when there is no available tags yet)*/
availableTags: PropTypes.array,
/* Context defining how tag list is rendered */
context: PropTypes.string.isRequired,
/* investigation identifier */
investigationId: PropTypes.string,
/* List of tags currently selected. Used only in the event context */
selectedTags: PropTypes.array,
/* Callback function trigered when the user selects a tag from the available tags. Used only in the EVENT context.*/
addTagToSelection: PropTypes.func,
/* Callback function used to create a new tag */
createNewTag: PropTypes.func,
/* Callback function trigered when the user click to edit the tag. Used only in the contexct of tag management */
editTag: PropTypes.func,
/* Callback function trigered when the user clicks the X on the tag label. Used only in Event context. */
removeTagFromSelection: PropTypes.func,
};
class TagListPanelLine extends React.Component {
render() {
let { tag, onEditButtonClicked } = this.props;
//set the tag scope
let tagScope = null;
if (tag.investigationId) {
tagScope = <span style={{ padding: '5px', backgroundColor: '#f2f2f2' }}> proposal </span>
} else if (tag.beamlineName) {
tagScope = <span style={{ padding: '5px', backgroundColor: '#f2f2f2' }}> beamline </span>
}
return (
<div>
<Row>
<div style={{ alignItems: 'center' }}>
<Col xs={12} sm={2} style={{ textAlign: 'center' }}>
<Label
style={{
backgroundColor: tag.color,
borderRadius: '10px',
display: 'inline-block',
paddingBottom: '5px',
fontSize: '14px'
}}>
{tag.name}
</Label>
</Col>
<Col xs={12} sm={6} style={{ alignItems: 'stretch', }}>
{tag.description ? <span> {tag.description} </span> : <span style={{ color: 'gray', fontStyle: 'italic' }}> No description yet</span>}
</Col>
<Col xs={12} sm={3}>
{tagScope}
</Col>
<Col xs={12} sm={1}>
<Button bsStyle="primary" bsSize="small" onClick={() => onEditButtonClicked(tag)}>Edit</Button>
</Col>
</div>
</Row>
<hr />
</div>
)
}
}
TagListPanelLine.proptype = {
/** tag object */
tag: PropTypes.object,
/** callback function when the user click the edit button */
onEditButtonClicked: PropTypes.func
}
export default TagListPanel;
import React from 'react';
import Proptypes from 'prop-types';
import { Row, Col, Button, Label } from "react-bootstrap"
/** React compoent which renders a line in the TagListTable */
class TagListTableLine extends React.Component {
render() {
let { tag, editTag } = this.props;
//set the tag scope
let tagScope = null;
if (tag.investigationId) {
tagScope = <span style={{ padding: '5px', backgroundColor: '#f2f2f2' }}> proposal </span>
} else if (tag.beamlineName) {
tagScope = <span style={{ padding: '5px', backgroundColor: '#f2f2f2' }}> beamline </span>
}
return (
<div>
<Row>
<div style={{ alignItems: 'center' }}>
<Col xs={12} sm={2} style={{ textAlign: 'center' }}>
<Label
style={{
backgroundColor: tag.color,
borderRadius: '10px',
display: 'inline-block',
paddingBottom: '5px',
fontSize: '14px'
}}>
{tag.name}
</Label>
</Col>
<Col xs={12} sm={6} style={{ alignItems: 'stretch', }}>
{tag.description ? <span> {tag.description} </span> : <span style={{ color: 'gray', fontStyle: 'italic' }}> No description yet</span>}
</Col>
<Col xs={12} sm={3}>
{tagScope}
</Col>
<Col xs={12} sm={1}>
<Button bsStyle="primary" bsSize="small" onClick={() => editTag(tag)}>Edit</Button>
</Col>
</div>
</Row>
<hr />
</div>
)
}
}
export default TagListTableLine;
TagListTableLine.proptype = {
/** tag object */
tag: Proptypes.object,
/** callback function when the user click the edit button */
editTag: Proptypes.func
}
\ No newline at end of file
......@@ -92,10 +92,7 @@ class TagContainer extends React.Component {
<TagListMenu onNewTagButtonClicked={this.onNewTagButtonClicked} />
<TagListPanel
availableTags={this.props.availableTags}
context={TAG_MANAGER_CONTEXT}
editTag={this.onEditTagButtonClicked}
investigationId={investigationId}
updateTags={this.updateTags}
onEditButtonClicked={this.onEditTagButtonClicked}
/>
</div>);
}
......
import React from 'react'
import Enzyme from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
import TagList from '../src/components/Event/Tag/TagList';
import { TAG_MANAGER_CONTEXT } from '../src/constants/EventTypes';
const resources = require('./resources/tagList.resource.js')
require('it-each')({ testPerIteration: true });
describe("TagList", () => {
beforeEach(() => {
Enzyme.configure({ adapter: new Adapter() });
})
describe("tagList used to manage tags", () => {
function getShallowedWrapper(tags) {
return Enzyme.shallow(<TagList
availableTags={tags}
context={TAG_MANAGER_CONTEXT}
investigationId="0123456789"
updateTags={() => null}
/>
)
}
// function getMountedWrapper(tags) {
// return Enzyme.mount(<TagManager
// investigationId="0123456789"
// tags={tags}
// updateTags={() => null}
// />
// )
// }
it.each(resources.asTagManager.itRenders, '[note: %s ]', ['aboutThisTest'],
function (element, next) {
let actualTags = element.tags;
expect(getShallowedWrapper(actualTags).find('TagViewer').length).toBe(2);
expect(getShallowedWrapper(actualTags).find('TagViewer').at(0).prop("tag")).toEqual(actualTags[0]);
expect(getShallowedWrapper(actualTags).find('TagViewer').at(1).prop("tag")).toEqual(actualTags[1]);
next();
})
it("informs that there is no tags when the investigation has no tags", () => {
let actualTags = null;
let expectedText = "There is no tag in this proposal yet."
expect(getShallowedWrapper(actualTags).find('TagViewer').length).toBe(0);
expect(getShallowedWrapper(actualTags).find('UserMessage').prop('message')).toEqual(expectedText);
})
// describe("actions", () => {
// it("closes the tab on clicking cancel button", () => {
// global.window = { close: function () { /* it closes the window */ return true } }
// let actualTags = null;
// let wrapper = getMountedWrapper(actualTags);
// global.window.close = jest.fn()
// wrapper.find("Button").at(1).simulate('click');
// expect(global.window.close).toHaveBeenCalled();
// })
// })
})
})
module.exports = {
asTagManager: {
itRenders: [
{
aboutThisTest: "renders 2 investigation tags",
tags: [
{
_id: 1,
color: "#000001",
description: "description1",
name: "tag1",
investigation: "0123456879",
},
{
_id: 2,
color: "#000002",
description: "description2",
name: "tag2",
investigation: "0123456879",
}
],
}
],
}
}
\ No newline at end of file
import React from 'react'
import Enzyme from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
import TagListPanel from '../../src/components/Logbook/Tag/TagListPanel';
const resources = require('./resources/TagListPanel.resource.js')
require('it-each')({ testPerIteration: true });
describe("TagListPanel unit tests", () => {
beforeEach(() => {
Enzyme.configure({ adapter: new Adapter() });
})
function getShallowedWrapper(tags, onEditButtonClicked) {
return Enzyme.shallow(<TagListPanel
availableTags={tags}
onEditButtonClicked={onEditButtonClicked} />);
}
function getMountedWrapper(tags, onEditButtonClicked) {
return Enzyme.mount(<TagListPanel
availableTags={tags}
onEditButtonClicked={onEditButtonClicked} />);
}
describe('rendering', () => {
it.each(resources.rendering, '[note: %s ]', ['aboutThisTest'],
function (element, next) {
expect(getShallowedWrapper(element.tags, () => null).find('TagListPanelLine').length).toBe(2);
expect(getShallowedWrapper(element.tags, () => null).find('TagListPanelLine').at(0).prop("tag")).toEqual(element.tags[0]);
expect(getShallowedWrapper(element.tags, () => null).find('TagListPanelLine').at(1).prop("tag")).toEqual(element.tags[1]);
next();
})
it("informs that there is no tags when the investigation has no tags", () => {
let expectedText = "There is no tag in this proposal yet."
expect(getShallowedWrapper([], () => null).find('TagListPanelLine').length).toBe(0);
expect(getShallowedWrapper([], () => null).find('UserMessage').prop('message')).toEqual(expectedText);
})
})
describe('callback', () => {
it('calls onEditButtonClicked when the user clicks the edit button', () => {
resources.callback
let mockedOnEditButtonClicked = jest.fn();
let wrapper = getMountedWrapper(resources.callback.tags, mockedOnEditButtonClicked);
expect(mockedOnEditButtonClicked).toHaveBeenCalledTimes(0);
wrapper.find('Button').simulate('click');
expect(mockedOnEditButtonClicked).toHaveBeenCalledTimes(1);
})
})
})
module.exports = {
rendering: [
{
aboutThisTest: "renders 2 investigation tags",
tags: [
{
_id: 1,
color: "#000001",
description: "description1",
name: "tag1",
investigation: "0123456879",
},
{
_id: 2,
color: "#000002",
description: "description2",
name: "tag2",
investigation: "0123456879",
}
],
}
],
callback: {
tags: [{
_id: 1,
color: "#000001",
description: "description1",
name: "tag1",
investigation: "0123456879"
}]
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment