Commit 2fe03d65 authored by Maxime Chaillet's avatar Maxime Chaillet

fix conflicts during merge with master. Update some tests. Pass QA. It fixes #126.

parents 89357d87 034c94a2
......@@ -126,7 +126,7 @@ class MyDataPage extends React.Component {
<LoginContainer />
<ExpirationLoginContainer></ExpirationLoginContainer>
<div style={{ marginTop: '30px', marginLeft: '30px', marginRight: '30px' }}>
<InvestigationsContainer linkProposal={true} openData={true} investigations={this.props.myInvestigations} />
<InvestigationsContainer showInvestigationStats={true} linkProposal={true} openData={true} investigations={this.props.myInvestigations} />
</div>
</div>
);
......@@ -153,7 +153,7 @@ class ClosedDataPage extends React.Component {
</Panel.Heading>
<Panel>
<Panel.Body>
<InvestigationsContainer linkProposal={false} investigations={this.props.investigations} openData={false} {...this.props} />
<InvestigationsContainer showInvestigationStats={this.props.user.isAdministrator} linkProposal={false} investigations={this.props.investigations} openData={false} {...this.props} />
</Panel.Body>
</Panel>
</Panel>
......
......@@ -3,8 +3,10 @@ import Moment from 'react-moment';
import { Grid, Row, Col, Image } from 'react-bootstrap';
import './DatasetSummary.css';
import EMDatasetSummary from './EMDatasetSummary';
import MXDatasetSummary from './MXDatasetSummary';
import GalleryDatasetThumbnail from '../GalleryDatasetThumbnail.js'
import { getDatasetParameterValueByName } from '../../../helpers/DatasetHelper.js';
import { getDatasetParameterValueByName, getDatasetParameterByPrefixName } from '../../../helpers/DatasetHelper.js';
import ParameterTableWidget from '../../Instrument/ParameterTableWidget.js';
class DatasetSummary extends React.Component {
......@@ -25,6 +27,13 @@ class DatasetSummary extends React.Component {
return <EMDatasetSummary dataset={this.props.dataset}></EMDatasetSummary>
}
}
else{
/** some MX datasets has no definition but we can figure out that it is MX because will have many MX_ parameters */
if (getDatasetParameterByPrefixName(this.props.dataset, "MX_").length > 1){
/** It is MX */
return <MXDatasetSummary dataset={this.props.dataset}></MXDatasetSummary>
}
}
return (
<Grid fluid style={{margin:'20px'}}>
......
......@@ -10,24 +10,41 @@ class EMDatasetSummary extends React.Component {
getParameters(){
return [
{name : 'Name', value : this.props.dataset.name},
{name : 'Dataset', value : this.props.dataset.name},
{name : 'Sample', value : this.props.dataset.sampleName},
{name : 'Protein', value : getDatasetParameterValueByName(this.props.dataset, "EM_protein_acronym")},
{name : 'Definition', value : getDatasetParameterValueByName(this.props.dataset, "definition")},
{name : 'Start', value : <Moment parse="YYYY-MM-DD HH:mm" format="LTS">{this.props.dataset.startDate}</Moment>},
{name : 'Sample', value : this.props.dataset.sampleName},
{name : 'Description', value : getDatasetParameterValueByName(this.props.dataset, "Sample_description")}
];
}
getTechniqueParameters(){
return [
{name : 'Amplitute', value : getDatasetParameterValueByName(this.props.dataset, "EM_amplitude_contrast") + " %" },
{name : 'Initial Dose', value : getDatasetParameterValueByName(this.props.dataset, "EM_dose_initial")},
{name : 'Dose/frame', value : getDatasetParameterValueByName(this.props.dataset, "EM_dose_per_frame")},
{name : 'Images', value : getDatasetParameterValueByName(this.props.dataset, "EM_images_count")},
{name : 'Magnification', value : getDatasetParameterValueByName(this.props.dataset, "EM_magnification")},
{name : 'Sampling Rate', value : getDatasetParameterValueByName(this.props.dataset, "EM_sampling_rate") + " Å/pixel"},
{name : 'Spherical Ab.', value : getDatasetParameterValueByName(this.props.dataset, "EM_spherical_aberration") + " mm"},
{name : 'Voltage', value : getDatasetParameterValueByName(this.props.dataset, "EM_voltage")}
];
}
render() {
return (
<Grid fluid style={{margin:'20px'}}>
<Row>
<Col xs={12} md={4}>
<ParameterTableWidget striped={true} parameters={this.getParameters()} ></ParameterTableWidget>
<Col xs={12} md={2}>
<ParameterTableWidget striped={false} parameters={this.getParameters()} ></ParameterTableWidget>
</Col>
<Col xs={12} sm={12} md={2}>
<ParameterTableWidget striped={false} parameters={this.getTechniqueParameters()} ></ParameterTableWidget>
</Col>
<Col xs={12} sm={12} md={2}>
......
import React from 'react';
import Moment from 'react-moment';
import { Grid, Row, Col, Image } from 'react-bootstrap';
import './DatasetSummary.css';
import GalleryDatasetThumbnail from '../GalleryDatasetThumbnail.js'
import { getDatasetParameterValueByName } from '../../../helpers/DatasetHelper.js';
import ParameterTableWidget from '../../Instrument/ParameterTableWidget.js';
class MXDatasetSummary extends React.Component {
getParameters(){
return [
{name : 'Name', value : this.props.dataset.name},
{name : 'Definition', value : getDatasetParameterValueByName(this.props.dataset, "definition")},
{name : 'Start', value : <Moment parse="YYYY-MM-DD HH:mm" format="LTS">{this.props.dataset.startDate}</Moment>},
{name : 'Sample', value : this.props.dataset.sampleName},
{name : 'Images', value : getDatasetParameterValueByName(this.props.dataset, "MX_numberOfImages")},
{name : 'Transmission', value : getDatasetParameterValueByName(this.props.dataset, "MX_transmission") + " %"},
{name : 'Prefix', value : getDatasetParameterValueByName(this.props.dataset, "MX_template")}
];
}
toExponential(value){
if (value){
try{
return parseFloat(value).toExponential();
}
catch(e){}
}
return "";
}
getTechniqueParameters(){
return [
{name : 'Resolution', value : getDatasetParameterValueByName(this.props.dataset, "MX_resolution") + " Å" },
{name : 'Wavelength', value : getDatasetParameterValueByName(this.props.dataset, "InstrumentMonochromator_wavelength") + " Å" },
{name : 'Exposure Time', value : getDatasetParameterValueByName(this.props.dataset, "MX_exposureTime") + " s"},
{name : 'Flux start', value : this.toExponential(getDatasetParameterValueByName(this.props.dataset, "MX_flux"))},
{name : 'Flux end', value : this.toExponential(getDatasetParameterValueByName(this.props.dataset, "MX_fluxEnd"))},
{name : 'X Beam', value : getDatasetParameterValueByName(this.props.dataset, "MX_xBeam") + " mm"},
{name : 'Y Beam', value : getDatasetParameterValueByName(this.props.dataset, "MX_yBeam") + " mm"}
];
}
render() {
return (
<Grid fluid style={{margin:'20px'}}>
<Row>
<Col xs={12} md={2}>
<ParameterTableWidget striped={false} parameters={this.getParameters()} ></ParameterTableWidget>
</Col>
<Col xs={12} sm={12} md={2}>
<ParameterTableWidget striped={false} parameters={this.getTechniqueParameters()} ></ParameterTableWidget>
</Col>
<Col xs={12} sm={12} md={2}>
<GalleryDatasetThumbnail dataset={this.props.dataset} sessionId={this.props.sessionId} index={0} ></GalleryDatasetThumbnail>
</Col>
<Col xs={12} sm={12} md={2}>
<GalleryDatasetThumbnail dataset={this.props.dataset} sessionId={this.props.sessionId} index={1} ></GalleryDatasetThumbnail>
</Col>
<Col xs={12} sm={12} md={2}>
<GalleryDatasetThumbnail dataset={this.props.dataset} sessionId={this.props.sessionId} index={2} ></GalleryDatasetThumbnail>
</Col>
</Row>
</Grid>
);
}
}
export default MXDatasetSummary;
\ No newline at end of file
......@@ -60,9 +60,13 @@ class DatasetWidget extends React.Component {
}
return null;
})}
<Tab eventKey={9} title="Instrument" disabled={ getDatasetParameterByPrefixName(this.props.dataset, "Instrument").length == 0}>
<InstrumentWidget dataset={dataset} ></InstrumentWidget>
</Tab>
{!getDatasetParameterByPrefixName(this.props.dataset, "Instrument").length == 0 &&
<Tab eventKey={9} title="Instrument" >
<InstrumentWidget dataset={dataset} ></InstrumentWidget>
</Tab>
}
<Tab eventKey={11} title={getFilesTabTitle(dataset)} mountOnEnter={true}>
<DatasetFileTree dataset={dataset} sessionId={this.props.sessionId}> ></DatasetFileTree>
</Tab>
......
......@@ -252,7 +252,7 @@ class InvestigationTable extends React.Component {
xs: { hidden : true },
sm: { hidden : true },
md: { hidden : true },
lg: { hidden : !this.props.openData && !this.props.user.isAdministrator, width: "150px" }
lg: { hidden : !this.props.showInvestigationStats, width: "150px" }
}
},
{
......
......@@ -12,6 +12,8 @@ class EventContentPanel extends React.Component {
constructor(props) {
super(props);
if (props.event) { this.eventId = props.event._id; }; //required for component will unmount in EDIT_EVENT_CONTEXT
this.storeToLocalStorage=this.storeToLocalStorage.bind(this);
}
render() {
let { event, context, investigationId, user, onEventModified } = this.props;
......
......@@ -17,7 +17,7 @@ class EventHistory extends React.Component {
<OverlayTrigger
trigger='click' placement='top' overlay={eventVersionsPopover(this.props.event)} rootClose={true} >
<div>
<LabeledElement data={null} type='text' labelText={<span> History <div className='arrow-down' /> </span>} />
<LabeledElement data={null} hasNoData={true} type='text' labelText={<span> History <div className='arrow-down' /> </span>} />
</div>
</OverlayTrigger>
</div>);
......
......@@ -14,7 +14,8 @@ class LabeledElement extends React.Component {
}
render() {
let { type, data, labelText, setTitleInput, tooltip } = this.props;
let { data, hasNoData, labelText, setTitleInput, tooltip, type } = this.props;
if (type === 'input') {
return (
<OverlayTrigger
......@@ -45,7 +46,11 @@ class LabeledElement extends React.Component {
return (<Overlay {...this.props}>
<div>
<Label> {labelText} </Label>
<div style={{ paddingTop: '5px', paddingLeft: '10px', color: '#666666', display: 'inline-block' }}> {data} </div>
{(hasNoData === true || (hasNoData === false && data)) ?
<div style={{ paddingTop: '5px', paddingLeft: '10px', color: '#666666', display: 'inline-block' }}> {data} </div>
:
<div style={{ paddingTop: '5px', paddingLeft: '10px', color: '#888888', display: 'inline-block', fontStyle: 'italic' }}> Not available </div>
}
</div>
</Overlay>);
}
......@@ -65,6 +70,8 @@ export default LabeledElement;
LabeledElement.proptypes = {
/** data to render */
data: Proptypes.string,
/** whehther data are provided or not */
hasNoData: Proptypes.bool.isRequired,
/** Text of the label */
labelText: Proptypes.string,
/** callback function triggered when user changed the data of the event */
......
......@@ -11,10 +11,9 @@ class NewlyAvailableEventsDialogue extends React.Component {
else {
let { eventCountSinceLastRefresh, onIconClicked, latestEvents } = this.props;
let newEventCountSinceLastRefresh = 0;
if (latestEvents && latestEvents.data && eventCountSinceLastRefresh) {
if (latestEvents && latestEvents.data && eventCountSinceLastRefresh != undefined) {
newEventCountSinceLastRefresh = (latestEvents.data.length < eventCountSinceLastRefresh) ? 0 : latestEvents.data.length - eventCountSinceLastRefresh
}
if (newEventCountSinceLastRefresh > 0) {
return (<div className='btn btn-sm' style={{ color: '#888888' }}> {newEventCountSinceLastRefresh
} new log(s) arrived. <Glyphicon onClick={onIconClicked} glyph='refresh' /> </div>)
......
......@@ -35,7 +35,7 @@ class NewOrEditEventPanel extends React.Component {
this.updateEvent = this.updateEvent.bind(this);
}
render() {
let { event, user, context, investigationId, setEditEventVisibility } = this.props;
let { event, user, context, investigationId } = this.props;
return (
<Panel bsStyle='primary' style={{ marginBottom: '0px', height: '100%', position: 'relative' }}>
<EventHeader context={context} />
......@@ -281,13 +281,13 @@ NewOrEditEventPanel.propTypes = {
/* User who is using this component */
user: PropTypes.object,
/* Callback used to request an event update on the server side */
updateEvent: PropTypes.object
updateEvent: PropTypes.func
}
/** React component which represents the creation date part. */
const CreationDate = (props) => {
if (props.event) {
return (<LabeledElement data={getEventCreationDate(getOriginalEvent(props.event))} type='text' labelText='Creation date' tooltip={<p> Event created on {getEventHistoryCreationDate(getOriginalEvent(props.event))} </p>} />);
return (<LabeledElement data={getEventCreationDate(getOriginalEvent(props.event))} hasNoData={false} type='text' labelText='Creation date' tooltip={<p> Event created on {getEventHistoryCreationDate(getOriginalEvent(props.event))} </p>} />);
}
return null;
}
......@@ -299,10 +299,10 @@ const CreationDate = (props) => {
const CommentBy = (props) => {
if (props.event) {
if (getPreviousVersionNumber(props.event) === 0) {
return (<LabeledElement data={props.event.username} type='text' labelText='Created by' tooltip='Author of the event' />);
return (<LabeledElement data={props.event.username} hasNoData={false} type='text' labelText='Created by' tooltip='Author of the event' />);
};
if (getPreviousVersionNumber(props.event) !== 0) {
return (<LabeledElement data={props.event.username} type='text' labelText='Commented by' tooltip='Author of the comment' />);
return (<LabeledElement data={props.event.username} hasNoData={false} type='text' labelText='Commented by' tooltip='Author of the comment' />);
};
}
return null;
......
......@@ -9,11 +9,11 @@ import _ from 'lodash';
/**
* React component used to edit or create a tag
*/
class TagEditor extends React.Component {
class NewOrEditTagPanel extends React.Component {
constructor(props) {
super(props);
this.state = {
tag: this.props.tag || { name: '', description: '', color: GUI_CONFIG().DEFAULT_TAG_COLOR, investigationId: this.props.investigationId },
tag: _.cloneDeep(this.props.tag) || { name: '', description: '', color: GUI_CONFIG().DEFAULT_TAG_COLOR, investigationId: this.props.investigationId },
};
this.onChangeComplete = this.onChangeComplete.bind(this);
......@@ -27,11 +27,8 @@ class TagEditor extends React.Component {
<Row className='show-grid'>
<Col xs={0} md={1}> </Col>
<Col xs={12} md={10}>
<h3> Editing Tag </h3>
<Panel bsStyle='primary'>
<Panel.Heading>
<strong>Please update tag details </strong>
</Panel.Heading>
<Panel.Heading> <strong> {this.props.panelHeaderText} </strong> </Panel.Heading>
<Panel.Body>
<FormGroup controlId='formControlTagLabel'>
<ControlLabel>Label <Mandatory></Mandatory></ControlLabel>
......@@ -139,7 +136,7 @@ class TagEditor extends React.Component {
class Mandatory extends React.Component {
render() {
return ( <span style={{ color: 'red' }}>*</span> );
return (<span style={{ color: 'red' }}>*</span>);
}
};
......@@ -150,11 +147,13 @@ const PopoverColorPickerBottom = (callback) => {
);
};
TagEditor.propTypes = {
NewOrEditTagPanel.propTypes = {
/** Text display in the panel header */
panelHeaderText: PropTypes.string,
/** callback function used to show the tag list */
showAvailableTags: PropTypes.func,
/* if present, it corresponds to the tag to edit. If absent, it indcates that a tag is being created*/
tag: PropTypes.object
};
export default TagEditor;
\ No newline at end of file
export default NewOrEditTagPanel;
\ No newline at end of file
......@@ -6,46 +6,31 @@ import EventListMenuButton from '../Menu/EventListMenuButton';
/**
* The menu displayed above the tag list
*/
class TagActionBar extends React.Component {
constructor(props) {
super(props);
this.showTagEditor = this.showTagEditor.bind(this);
}
class TagListMenu extends React.Component {
render() {
return (
<Grid fluid={true} style={{ marginTop: '10px' }}>
<Row>
<Col xs={2}>
<ButtonToolbar>
<EventListMenuButton
isNewComponentVisible={false}
onClick={this.showTagEditor}
/>
<div onClick={this.props.onNewTagButtonClicked}>
<EventListMenuButton
text='New'
tooltipText='Create a new tag'
glyph='plus'
isEnabled={true} />
</div>
</ButtonToolbar>
</Col>
</Row>
</Grid >
);
}
/** Callback triggered when the user click to create a new tag */
showTagEditor() {
this.props.showNewTag();
}
}
TagActionBar.propTypes = {
TagListMenu.propTypes = {
/** Callback function used to display new tag form */
showNewTag: PropTypes.func
onNewTagClicked: PropTypes.func
};
export default TagActionBar;
\ No newline at end of file
export default TagListMenu;
\ No newline at end of file
......@@ -40,6 +40,6 @@ export function GUI_CONFIG() {
/* Whether event list refreshed automatically or not by default. */
AUTOREFRESH_EVENTLIST: false,
/* the delay between 2 refreshments of event list. (in milliseconds)*/
AUTOREFRESH_DELAY: 3000,
AUTOREFRESH_DELAY: 30000,
}
}
\ No newline at end of file
......@@ -30,8 +30,8 @@ export const EVENT_HISTORY_ORIGINAL_VERSION_CONTEXT = 'eventHistoryOriginalVersi
export const EVENT_HISTORY_LATEST_VERSION_CONTEXT = 'eventHistoryLatestVersionContext';
export const EVENT_HISTORY_MIDDLE_VERSION_CONTEXT = 'eventHistoryNotOriginalAndNotLatestVersionContext';
export const TAG_MANAGER_CONTEXT = 'tagManagerContext';
export const TAG_EDITOR_CONTEXT = 'tagEditorContext';
export const TAG_CREATOR_CONTEXT = 'tagCreatorContext';
export const EDIT_TAG_CONTEXT = 'editTagContext';
export const NEW_TAG_CONTEXT = 'newTagContext';
export const INFO_MESSAGE_TYPE = 'info';
export const ERROR_MESSAGE_TYPE = 'error';
......
......@@ -16,8 +16,9 @@ class CameraContainer extends Component {
url: createEventFromBase64(this.props.user.sessionId, this.props.investigationId),
data: { base64: dataUri }
})
.then(function (value) {
.then(function (value) {
alert("Uploaded Successfully")
window.close();
}, function (error) {
alert(error);
});
......
......@@ -28,7 +28,8 @@ class InvestigationsContainer extends Component {
linkProposal={this.props.linkProposal}
closedData={this.props.closedData}
fetching={this.props.investigations.fetching}
investigations={this.props.investigations.data}>
investigations={this.props.investigations.data}
showInvestigationStats={this.props.showInvestigationStats}>
</InvestigationTable>
</Loader>
</div>);
......
......@@ -53,12 +53,14 @@ export class LogbookContainer extends React.Component {
this.isAppProperlyConfigured = this.isAppProperlyConfigured.bind(this);
this.onEventsReceptionFailure = this.onEventsReceptionFailure.bind(this);
this.onEventCountReceptionFailure = this.onEventCountReceptionFailure.bind(this);
this.onEventClicked = this.onEventClicked.bind(this);
this.onEventUpdated = this.onEventUpdated.bind(this);
this.onNewEventsReceived = this.onNewEventsReceived.bind(this);
this.onNewEventUploaded = this.onNewEventUploaded.bind(this);
this.onPageClicked = this.onPageClicked.bind(this);
this.reverseEventsSortingByCreationDate = this.reverseEventsSortingByCreationDate.bind(this);
this.searchEvents = this.searchEvents.bind(this);
this.setEditEventVisibility = this.setEditEventVisibility.bind(this);
this.setEventListAutorefresh = this.setEventListAutorefresh.bind(this);
this.setNewEventVisibility = this.setNewEventVisibility.bind(this);
this.setView = this.setView.bind(this);
......
......@@ -31,6 +31,10 @@ class PeriodicRefresher extends React.Component {
}
}
componentWillUnmount() {
clearInterval(this.intervalId);
}
onSuccess(data) {
this.setState({ data: data })
this.props.onCallbackSuccess()
......
This diff is collapsed.
......@@ -3,11 +3,11 @@ import PropTypes from 'prop-types';
import axios from 'axios';
import { connect } from 'react-redux';
import TagList from '../components/Logbook/Tag/TagList';
import TagEditor from '../components/Logbook/Tag/TagEditor';
import { getTagsByInvestigationId, createTagsByInvestigationId, updateTagsByInvestigationId } from '../api/icat/icatPlus';
import _ from 'lodash';
import { INFO_MESSAGE_TYPE, ERROR_MESSAGE_TYPE, TAG_MANAGER_CONTEXT, BASIC_EVENT_CONTEXT, TAG_EDITOR_CONTEXT, TAG_CREATOR_CONTEXT, NEW_EVENT_CONTEXT, EDIT_EVENT_CONTEXT, FETCHED_STATUS, FETCHING_STATUS } from '../constants/EventTypes';
import TagActionBar from '../components/Logbook/Tag/TagActionBar';
import { INFO_MESSAGE_TYPE, ERROR_MESSAGE_TYPE, TAG_MANAGER_CONTEXT, BASIC_EVENT_CONTEXT, NEW_EVENT_CONTEXT, EDIT_EVENT_CONTEXT, FETCHED_STATUS, FETCHING_STATUS, EDIT_TAG_CONTEXT, NEW_TAG_CONTEXT } from '../constants/EventTypes';
import NewOrEditTagPanel from '../components/Logbook/Tag/NewOrEditTagPanel';
import TagListMenu from '../components/Logbook/Tag/TagListMenu';
import UserMessage from '../components/UserMessage';
import { SUCCESS_MESSAGE_TYPE } from '../constants/UserMessages';
import { setAvailableTagAction } from '../actions/logbook';
......@@ -33,13 +33,13 @@ class TagContainer extends React.Component {
this.addTagToSelection = this.addTagToSelection.bind(this);
this.createNewTag = this.createNewTag.bind(this);
this.editTag = this.editTag.bind(this);
this.getTagsByInvestigationId = this.getTagsByInvestigationId.bind(this);
this.onEditTagButtonClicked = this.onEditTagButtonClicked.bind(this);
this.onNewTagButtonClicked = this.onNewTagButtonClicked.bind(this);
this.removeTagFromSelection = this.removeTagFromSelection.bind(this);
this.setMessage = this.setMessage.bind(this);
this.setSelectedTagsFromProps = this.setSelectedTagsFromProps.bind(this);
this.showAvailableTags = this.showAvailableTags.bind(this);
this.showNewTag = this.showNewTag.bind(this);
this.updateTags = this.updateTags.bind(this);
}
......@@ -80,25 +80,26 @@ class TagContainer extends React.Component {
if (this.state.context === TAG_MANAGER_CONTEXT) {
return (<div>
{userMessage}
<TagActionBar showNewTag={this.showNewTag} />
<TagListMenu onNewTagButtonClicked={this.onNewTagButtonClicked} />
<TagList
availableTags={this.props.availableTags}
context={TAG_MANAGER_CONTEXT}
editTag={this.editTag}
editTag={this.onEditTagButtonClicked}
investigationId={investigationId}
updateTags={this.updateTags}
/>
</div>);
}
if (this.state.context === TAG_EDITOR_CONTEXT || this.state.context === TAG_CREATOR_CONTEXT) {
if (this.state.context === EDIT_TAG_CONTEXT || this.state.context === NEW_TAG_CONTEXT) {
// if (this.state.selectedTags && this.state.selectedTags.length != 0) {
return (<div>
{userMessage}
<TagEditor
<NewOrEditTagPanel
createNewTag={this.createNewTag}
panelHeaderText={this.state.context === NEW_TAG_CONTEXT ? 'New tag' : 'Editing tag'}
showAvailableTags={this.showAvailableTags}
tag={this.state.selectedTags.length !== 0 ? this.state.selectedTags[0] : null}
createNewTag={this.createNewTag}
updateTags={this.updateTags}
/>
</div>);
......@@ -137,7 +138,7 @@ class TagContainer extends React.Component {
if (this.props.context === EDIT_EVENT_CONTEXT || this.props.context === NEW_EVENT_CONTEXT) {
this.isGettingSelectedTagsFromEventProp = false;
this.setSelectedTagsFromProps();
};
}
}
else {
this.getTagsByInvestigationId(onSuccess, onError); //fetch available tags.
......@@ -232,7 +233,7 @@ class TagContainer extends React.Component {
createNewTag(newTag) {
let _this = this;
let nextContext = (this.props.context === TAG_CREATOR_CONTEXT) ? TAG_MANAGER_CONTEXT : this.props.context;
let nextContext = (this.props.context === NEW_TAG_CONTEXT) ? TAG_MANAGER_CONTEXT : this.props.context;
// POST the new tag to the server
if (newTag) {
axios({
......@@ -298,12 +299,17 @@ class TagContainer extends React.Component {
Promise.all(promises)
.then((results) => {
let availableTags = _.cloneDeep(this.props.availableTags);
results.forEach((data) => {
console.log('The tag ' + data.name + ' was successfully updated on ICAT+ server.');
console.log('The tag ' + data.data.name + ' was successfully updated on ICAT+ server.');
let tagToBeUpdated = _.find(availableTags, (tag) => { return _.isEqual(tag._id, data.data._id) });
_.remove(availableTags, (tag) => { return _.isEqual(tag, tagToBeUpdated) });
availableTags.push(data.data);
});
this.props.setAvailableTags(availableTags);
this.setMessage(INFO_MESSAGE_TYPE, 'Tags was successfully updated');
this.setState({ context: TAG_MANAGER_CONTEXT });
})
.catch((error) => {
console.log('[ERROR] At least one tag could not be updated. The error is : ' + error);
......@@ -345,19 +351,19 @@ class TagContainer extends React.Component {
* Edit a given tag
* @param {*} tag the tag to be edited
*/
editTag(tag) {
onEditTagButtonClicked(tag) {
if (tag) {
this.setState({
context: TAG_EDITOR_CONTEXT,
context: EDIT_TAG_CONTEXT,
message: null,
selectedTags: [tag],
});
};
}
showNewTag() {
onNewTagButtonClicked() {
this.setState({
context: TAG_CREATOR_CONTEXT,
context: NEW_TAG_CONTEXT,
message: null,
});
}
......
......@@ -11,7 +11,7 @@ import promise from "redux-promise-middleware"
import { LOGGED_IN } from '../../src/constants/ActionTypes';
import { GUI_CONFIG } from '../../src/config/gui.config';
jest.mock("../../src/config/gui.config");
import LogbookContainer, {LogbookContainer as LogbookContainerNoConnect} from '../../src/containers/Logbook/LogbookContainer';
import LogbookContainer, { LogbookContainer as LogbookContainerNoConnect } from '../../src/containers/Logbook/LogbookContainer';
const IORequestModule = require('../../src/containers/Logbook/IORequests')
const resources = require('./resources/NewlyAvailableEventsDialogue.resource.js');
......@@ -28,7 +28,10 @@ describe("NewlyAvailableEventsDialogue integration tests", () => {
EVENTS_PER_PAGE: 2,
DEFAULT_SORTING_FILTER: {
createdAt: -1 // temporary workaround. createdAt must be replaced by creationDate
}
},
AUTOREFRESH_ENABLED: true,
AUTOREFRESH_DELAY: 100,
AUTOREFRESH_EVENTLIST: false
})
const middleware = [thunk];
......@@ -46,51 +49,66 @@ describe("NewlyAvailableEventsDialogue integration tests", () => {
/>)
};
it('calls getEvents when the user clicks the refresh icon on the NewlyAvailableEventsDialogue', () => {
it('calls getEvents when the user clicks the refresh icon on the NewlyAvailableEventsDialogue', (done) => {
IORequestModule.getEventsByInvestigationId = jest.fn((sessionId, investigationId, limit, offset, selectionFilter, sortingFilter, onSuccess, onError) => {
onSuccess(resources.refreshEventList.serverResponse1);
onSuccess(resources.refreshEventList.serverResponse_No_Event);
});
IORequestModule.getEventCountByInvestigationId = jest.fn((investigationId, sessionId, selectionFilter, onSuccess, onEventsReceptionFailure) => {
onSuccess(resources.refreshEventList.serverResponse2);
onSuccess(resources.refreshEventList.serverResponse_No_EventCount);
});
const mockedGetEvents = jest.spyOn(LogbookContainerNoConnect.prototype,'getEvents');
const mockedGetEvents = jest.spyOn(LogbookContainerNoConnect.prototype, 'getEvents');
const wrapper = getWrapper();
wrapper.update();
expect(mockedGetEvents).toHaveBeenCalledTimes(1); //called by component will mount
wrapper.find('EventListMenu').find('NewlyAvailableEventsDialogue').find('Glyphicon').simulate('click');
// change the mock functions to simulate that another event was created in the mean time. This is required so that the refresh glyphicon is rendered.
IORequestModule.getEventsByInvestigationId = jest.fn((sessionId, investigationId, limit, offset, selectionFilter, sortingFilter, onSuccess, onError) => {
onSuccess(resources.refreshEventList.serverResponse_One_Event);
});
IORequestModule.getEventCountByInvestigationId = jest.fn((investigationId, sessionId, selectionFilter, onSuccess, onEventsReceptionFailure) => {
onSuccess(resources.refreshEventList.serverResponse_One_EventCount);
});
// wait 500ms, it should be sufficient for the periodicRefresher to make the second call
setTimeout(() => {
wrapper.update()
wrapper.find('EventListMenu').find('NewlyAvailableEventsDialogue').find('Glyphicon').simulate('click');
expect(mockedGetEvents).toHaveBeenCalledTimes(2);
mockedGetEvents.mockRestore();
done()
}, 500);
wrapper.update()
expect(mockedGetEvents).toHaveBeenCalledTimes(2);
})
it('refreshes the event list when the user clicks the refresh icon on the NewlyAvailableEventsDialogue', () => {