Commit ac83717f authored by Maxime Chaillet's avatar Maxime Chaillet

merge latest updates from master. It fixes #156.

parents 5b4ff558 f5a42e5b
......@@ -12,16 +12,17 @@ export class BreadCrumbs extends React.Component {
}
/** breadCrumbsSize is used to mark as active the latest item in the list */
var breadCrumbsSize = items.length;
return (<Breadcrumb style={{ backgroundColor: '#bfbfbf', marginTop: -20, borderBotton: '1px solid #f2f2f2', fontSize: '14px' }}>
return (<Breadcrumb style={{ backgroundColor: '#bfbfbf', marginTop: -20, borderBotton: '1px solid #f2f2f2', fontSize: '15px' }}>
{items.map(function (breadcrumb, i) {
if (i === 0) {
return <Breadcrumb.Item key={i} style={{ marginLeft: '40px' }} href={breadcrumb.link}> {breadcrumb.name} </Breadcrumb.Item>;
}
if (breadCrumbsSize === (i + 1)) {
return <Breadcrumb.Item key={i} active href={breadcrumb.link}>
<Label style={{ fontSize: '12px' }}>{breadcrumb.badge}</Label> {breadcrumb.name} </Breadcrumb.Item>;
<Label style={{ fontSize: '15px' }}>{breadcrumb.badge}</Label> <span style={{ color:'black'}}>{breadcrumb.name}</span> </Breadcrumb.Item>;
}
return <Breadcrumb.Item key={i} href={breadcrumb.link}> {breadcrumb.name} </Breadcrumb.Item>;
......
......@@ -2,17 +2,24 @@ import React, { Component } from 'react'
import { Image } from 'react-bootstrap';
import { getFileByEventId } from '../../api/icat/icatPlus.js';
import PropTypes from 'prop-types';
import ImageZoom from 'react-medium-image-zoom';
export default class GalleryDatasetThumbnail extends Component {
render() {
var gallery = this.props.dataset.parameters.filter(function (o) { return o.name === "ResourcesGallery" });
var name = this.props.dataset.parameters.filter(function (o) { return o.name === "name" });
if (gallery != null) {
if (gallery.length > 0) {
gallery = gallery[0].value.split(" ");
if (gallery.length > this.props.index) {
var url = getFileByEventId(this.props.sessionId, this.props.dataset.investigation.id, gallery[this.props.index] );
return <Image src={url} thumbnail />;
return <ImageZoom image={{
src: url,
//alt: "test",
className: 'thumbnail',
style: { width: '100%' }
}} />;
}
}
}
......
......@@ -2,19 +2,51 @@ import React from 'react';
import PropTypes from 'prop-types'
import _ from 'lodash'
import Moment from 'moment'
import { Table, OverlayTrigger, Tooltip, Glyphicon, Button } from 'react-bootstrap'
import { Table, OverlayTrigger, Tooltip, Glyphicon, Button, Label } from 'react-bootstrap'
import { getContent, convertImagesToThumbnails } from '../../../helpers/EventHelpers';
import { getOriginalEvent } from '../../../helpers/EventHelpers'
import EventIcon from './EventIcon.js';
import LazyLoad from 'react-lazyload';
import EventTimeLine from './EventTimeLine.js';
import { EVENT_CATEGORY_COMMANDLINE, NOTIFICATION } from '../../../constants/EventTypes.js';
require("./eventList.css");
const COLLAPSED_EVENT_TYPES = "EVENTS";
/**
* The list of the all events
*/
class EventList extends React.Component {
constructor(props) {
super(props)
this.state = {
items: this.getItems()
}
}
componentDidMount() {
this.setState({ items: this.getItems() })
}
collapse(items) {
var collapsed = [];
for (let i = 0; i < items.length; i++) {
const event = items[i];
if (event.category === EVENT_CATEGORY_COMMANDLINE && !event.previousVersionEvent) {
let lastEvent = collapsed[collapsed.length - 1];
if (lastEvent.category === EVENT_CATEGORY_COMMANDLINE) {
if (!lastEvent.events) {
lastEvent.events = [event];
}
lastEvent.type = COLLAPSED_EVENT_TYPES;
lastEvent.events.push(event);
continue;
}
}
collapsed.push(event);
}
return collapsed;
}
/** Returns the list of items to be displayed in the table: events + days */
getItems() {
var items = [];
......@@ -27,43 +59,24 @@ class EventList extends React.Component {
}
items.push(this.props.events[i]);
}
return items;
return this.collapse(items);
}
render() {
if (!this.props.events || this.props.events.length === 0) {
return null;
}
return (
<Table responsive style={{ fontSize: '12px' }} >
<tbody style={{ borderRight: '1px solid #F9F9F9' }}>
{this.getItems().map((event, index) => {
if (event.type === "date") {
return <tr key={index}><td style={{ borderTop: '1px solid #f2f2f2', textAlign: 'center', fontSize: '18px', fontWeight: 'bold' }} colSpan={3} ><a name={event.anchor}></a> {event.text}</td></tr>;
}
return (
<tr key={index} id='contentDocList'>
<td style={{ width: '16px', borderTop: '0' }}>
<EventIcon event={event} />
</td>
<td style={{ width: '16px', borderTop: '0', borderRight: '1px solid #f2f2f2' }}>
<OverlayTrigger placement="right" overlay={<Tooltip id="tooltip"> <p> Events created on {Moment(getOriginalEvent(event).creationDate).format("MMMM Do YYYY, h:mm:ss a")} </p> </Tooltip>}>
<span style={{ cursor: 'pointer', color: '#999999', margin: '0px' }}>{Moment(getOriginalEvent(event).creationDate).format("HH:mm:ss")} </span>
</OverlayTrigger>
</td>
<td style={{ border: 0 }}>
<LazyEvent event={event} />
</td>
<td style={{ border: 0 }}>
<Button bsStyle="link" bsSize="small" style={{ padding: '0px' }} onClick={() => this.props.onEventClicked(event)}>
<Glyphicon glyph='edit' style={{ width: '40px' }} />
</Button>
</td>
</tr>)
})}
</tbody>
</Table>
)
return <Table responsive style={{ fontSize: '12px' }} >
<tbody style={{ borderRight: '1px solid #F9F9F9' }}>
{this.state.items.map((event, index) => {
if (event.type === "date") {
return <tr><td style={{ borderTop: '1px solid #f2f2f2', textAlign: 'center', fontSize: '18px', fontWeight: 'bold' }} colSpan={3} ><a name={event.anchor}></a> {event.text}</td></tr>;
}
return <Event event={event} onEventClicked={this.props.onEventClicked} ></Event>
})}
</tbody>
</Table>
}
}
......@@ -74,15 +87,71 @@ EventList.propTypes = {
export default EventList;
class LazyEvent extends React.Component {
class Event extends React.Component {
constructor(props) {
super(props)
this.state = {
collapsed: true
}
this.handleClick = this.handleClick.bind(this);
}
handleClick(e) {
this.setState({ collapsed: !this.state.collapsed });
}
getUncollapsedEvents() {
return (<tbody> {this.props.event.events.map((event, index) => {
return this.getEventContentBody(event)
})}</tbody>);
}
render() {
let events = [this.props.event];
if (this.props.event.events && !this.state.collapsed) {
events = events.concat(this.props.event.events);
}
return events.map((event, index) => {
return <tr id='contentDocList'>
<td style={{ width: '16px', borderTop: '0' }}>
<EventIcon event={event} />
</td>
<td style={{ width: '16px', borderTop: '0', borderRight: '1px solid #f2f2f2' }}>
<OverlayTrigger placement="right" overlay={<Tooltip id="tooltip"> <p> Events created on {Moment(getOriginalEvent(event).creationDate).format("MMMM Do YYYY, h:mm:ss a")} </p> </Tooltip>}>
<span style={{ cursor: 'pointer', color: '#999999', margin: '0px' }}>{Moment(getOriginalEvent(event).creationDate).format("HH:mm:ss")} </span>
</OverlayTrigger>
</td>
<td style={{ border: 0 }}>
<LazyContentEvent event={event} />
{event.events && this.state.collapsed ? <Label style={{ color: "blue", backgroundColor: "white", cursor: "pointer" }} onClick={this.handleClick} >.... {event.events.length} command lines more</Label> : null}
</td>
<td style={{ border: 0 }}>
<Button bsStyle="link" bsSize="small" style={{ padding: '0px' }} onClick={() => this.props.onEventClicked(event)}>
<Glyphicon glyph='edit' style={{ width: '40px' }} />
</Button>
</td>
</tr>;
});
}
}
class LazyContentEvent extends React.Component {
getHTMLContent(event) {
return getContent(event.content, 'html') ? convertImagesToThumbnails(getContent(event.content, 'html')) : convertImagesToThumbnails(getContent(event.content, 'plainText'));
}
render() {
var content = this.getHTMLContent(this.props.event);
if (content) {
/** For performance only events with images are lazy loaded */
if ((this.props.event.type === NOTIFICATION || (this.props.event.type === COLLAPSED_EVENT_TYPES)) && this.props.event.previousVersionEvent) {
return <LazyLoad>
<div dangerouslySetInnerHTML={{ __html: this.getHTMLContent(getOriginalEvent(this.props.event)) }} />
<div dangerouslySetInnerHTML={{ __html: content }} />
</LazyLoad>;
}
/** For performance only events with images are lazy loaded */
if (content.indexOf("img") !== -1) {
/** For performance only events with images are lazy loaded */
return <LazyLoad once>
<div dangerouslySetInnerHTML={{ __html: content }} />
</LazyLoad>;
......@@ -92,6 +161,4 @@ class LazyEvent extends React.Component {
return <div style={{ fontStyle: 'italic', color: '#888888' }}> There is no content </div>
}
}
}
}
\ No newline at end of file
......@@ -3,6 +3,7 @@ export const ANNOTATION = 'annotation';
export const NOTIFICATION = 'notification';
export const EVENT_CATEGORY_COMMENT = 'comment';
export const EVENT_CATEGORY_COMMANDLINE = 'commandLine';
export const LIST_VIEW = 'list';
export const DOC_VIEW = 'doc';
......
......@@ -22,7 +22,7 @@ class DataCollectionsContainer extends Component {
</div>);
}
componentDidMount() {
componentDidMount() {
this.props.setBreadCrumbs([
{ name: 'Open Data', link: '/public' },
{ name: 'Investigations', link: '/public' },
......
......@@ -30,29 +30,30 @@ class InvestigationContainer extends Component {
loadDatasetsByInvestigationId() {
let { investigationId } = this.props;
if (investigationId) {
if (this.props.user.sessionId) {
this.props.fetchDatasetsByInvestigationId(this.props.user.sessionId, investigationId);
let investigation = _.find(this.props.myInvestigations, (investigation) => { return investigation.id === Number(investigationId) });
if (investigation) {
// investigation was found in my Data
this.props.setBreadCrumbs([
{ name: 'My Data', link: '/investigations' },
{ name: 'Investigations', link: '/investigations' },
{ name: 'My Data', link: '/investigations' },
{ name: investigation.visitId.toUpperCase(), link: '/investigations' },
{ badge: investigation.name, name: investigation.summary, link: '/investigation/' + investigation.id + '/datasets' }
]);
} else {
// investion not found in my data, it can be among closed data
investigation = _.find(this.props.investigations, (investigation) => { return investigation.id === Number(investigationId) });
if (investigation) {
// investigation was found in my Data
this.props.setBreadCrumbs([
{ name: 'Closed Data', link: '/closed' },
{ name: 'Investigations', link: '/closed' },
{ badge: investigation.name, name: investigation.summary, link: '/investigation/' + investigation.id + '/datasets' }
{ name: 'Closed Data', link: '/closed' },
{ name: investigation.visitId.toUpperCase(), link: '/investigations' },
{ name: investigation.name + ": " + investigation.summary, link: '/investigation/' + investigation.id + '/datasets' }
]);
}
......@@ -62,21 +63,29 @@ class InvestigationContainer extends Component {
}
}
setDOIBreadCrumbs(doi){
this.props.setBreadCrumbs([{ name: 'Open Data', link: '/public' }, { badge: doi, name: '', link: '/public/' + doi }]);
}
componentWillReceiveProps(nextProps) {
/** If component was mounted when sessionId was still not ready */
/** If component was mounted when sessionId was still not ready */
if (!this.props.user.sessionId) {
if (nextProps.user.sessionId) {
if (nextProps.user.sessionId !== this.props.user.sessionId) {
this.fetchData(nextProps.user.sessionId);
this.props.setBreadCrumbs([{ badge: this.props.doi, name: '', link: '/public/' + this.props.doi }]);
this.setDOIBreadCrumbs( this.props.doi);
}
}
}
if (this.props.doi){
this.setDOIBreadCrumbs( this.props.doi);
}
}
fetchData(sessionId) {
if (this.props.doi != null) {
if (sessionId) {
if (sessionId) {
this.props.fetchDatasetsByDOI(sessionId, this.props.doi);
}
}
......
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