labo-components
Version:
274 lines (237 loc) • 9.51 kB
JSX
import IDUtil from '../../../../util/IDUtil';
import SessionStorageHandler from '../../../../util/SessionStorageHandler';
import ProjectViewWrapper from '../ProjectViewWrapper';
import PropTypes from 'prop-types';
import SortTable from '../../SortTable';
import { exportDataAsJSON } from '../../helpers/Export';
/**
* Tool sessions table for a given project, that handles the loading^ and filtering of
* the sessions list.
*
* ^ Todo: Project sessions are currently stored on the project object
* itself. Alternatively they could be stored in the annotation API
* @Jaap: Decide which approach fits best.
*/
class ProjectSessionView extends React.PureComponent {
constructor(props) {
super(props);
// // Add dummy data
// const exampleUrl = '/tool/exploratory-search?path=/browser/session%3Fid=an-1acf4520-f414-4198-a61f-a91a44fd7408';
// if (!props.project.sessions) {
// props.project.sessions = [{
// id: 'abcd12349',
// name: 'Session example: Wereldreis',
// tool: 'MS: DIVE+',
// data: { url: exampleUrl },
// created: '2017-12-08T18:31:47Z'
// }];
// }
this.defaultSort = {
field: 'name',
order: 'asc'
};
this.state = {
sessions: [],
filter: {
keywords: '',
currentUser: false
}
};
}
componentDidMount() {
this.loadData();
// store tab to sessionStorage
SessionStorageHandler.set("bg__project-tab", "sessions");
}
componentDidUpdate() {
if (this.lastFilter !== this.state.filter) {
this.lastFilter = this.state.filter;
this.loadData();
}
}
//whenever the keywords change
keywordsChange(e) {
this.setState({
filter: Object.assign({}, this.state.filter, {
keywords: e.target.value
})
});
}
//whenever the checkbox changes
currentUserChange(e) {
this.setState({
filter: Object.assign({}, this.state.filter, {
currentUser: e.target.checked
})
});
}
//load the session data and apply the current filter
loadData() {
let result = this.props.project.sessions ? this.props.project.sessions : [];
const filter = this.state.filter;
result = this.filterSessions(result, filter);
// update state
this.setState({
sessions: result
});
}
//Filter session list by given filter
filterSessions(sessions, filter) {
// filter on keywords in name or tool
if (filter.keywords) {
const keywords = filter.keywords.split(' ');
keywords.forEach(k => {
k = k.toLowerCase();
sessions = sessions.filter(
session =>
session.name.toLowerCase().includes(k) ||
session.tool.toLowerCase().includes(k)
);
});
}
return sessions;
}
deleteSession(session) {
if (window.confirm('Are you sure you want to delete session ' + session.name)) {
const project = this.props.project;
// delete sessions from project
project.sessions = project.sessions.filter(s => s !== session);
// store project
this.props.api.save(this.props.user.id, project, msg => {
if (msg && msg.success) {
// update data
this.loadData();
} else {
alert('An error occurred while saving this project');
}
});
}
}
//deletes multiple sessions
deleteSessions(sessions) {
if (window.confirm('Are you sure you want to delete ' + sessions.length + ' sessions?')) {
const project = this.props.project;
// delete sessions from project
project.sessions = project.sessions.filter(s => !sessions.includes(s));
// store project
this.props.api.save(this.props.user.id, project, msg => {
if (msg && msg.success) {
// update data
this.loadData();
} else {
alert('An error occured while saving this project');
}
});
}
}
sortSessions(sessions, sort) {
const sorted = sessions;
switch (sort.field) {
case 'name': sorted.sort((a, b) => a.name > b.name); break;
case 'tool': sorted.sort((a, b) => a.tool > b.tool); break;
case 'date': sorted.sort((a, b) => a.date > b.date); break;
default: return sorted;
}
return sort.order === 'desc' ? sorted.reverse() : sorted;
}
// based on the session, decide which url to generate
generateSessionUrl(session){
switch(session.tool){
// dive-vu via within media suite
case 'dive-vu':
//return "/tool/exploratory-search?path=/browser/session%3Fid="+encodeURIComponent(session.data.annotationId);
return "http://clariahvu.diveplus.frontwise.com/browser/session?id="+encodeURIComponent(session.data.annotationId);
break;
// dive frontwise open beelden
case 'dive-fw':
// When openbeelden is the Explore tool default
return "/tool/exploratory-search?path=/browser/session%3Fid="+encodeURIComponent(session.data.annotationId);
//return "http://openbeelden.diveplus.frontwise.com/browser/session?id="+encodeURIComponent(session.data.annotationId);
break;
default:
console.error("Could not generate a Url for ", session);
}
}
render() {
const sessions = this.state.sessions;
const currentUser = this.props.user;
return (
<div className={IDUtil.cssClassName('project-session-view')}>
<div className="tools">
<div className="left">
<h3>Filters</h3>
<div className="filter-container">
<input
className="search"
type="text"
placeholder="Search Tool sessions"
value={this.state.filter.keywords}
onChange={this.keywordsChange.bind(this)}/>
</div>
</div>
</div>
<SortTable
items={sessions}
head={[
{ field: 'name', content: 'Name', sortable: true },
{ field: 'tool', content: 'Tool', sortable: true },
{ field: 'date', content: 'Date', sortable: true },
{ field: '', content: '', sortable: false },
{ field: '', content: '', sortable: false },
{ field: '', content: '', sortable: false }
]}
row={session => [
{
props: { className: 'primary' },
content: <a href={this.generateSessionUrl(session)} target="_blank" rel="noopener noreferrer" >{session.name}</a>
},
{ content: session.tool },
{ content: session.created ? session.created.substring(0, 10) : '-'},
{
content: (
<a className="btn blank warning" onClick={this.deleteSession.bind(this, session)}>
Delete
</a>
)
},
{
content: (
<a className="btn blank" onClick={exportDataAsJSON.bind(this, session)}>
Export
</a>
)
},
{
content: (
<a href={this.generateSessionUrl(session)} className="btn" target="_blank" rel="noopener noreferrer">
Open
</a>
)
}
]}
onSort={this.sortSessions.bind(this)}
loading={this.state.loading}
bulkActions={[
{ title: 'Delete', onApply: this.deleteSessions.bind(this) },
{ title: 'Export', onApply: exportDataAsJSON.bind(this) }
]}
defaultSort={this.defaultSort}/>
</div>
)
}
}
ProjectSessionView.propTypes = {
// project api
api: PropTypes.func.isRequired,
// current user object used for defining access roles per project
user: PropTypes.shape({
id: PropTypes.string.isRequired
}).isRequired
};
class WrappedProjectSessionView extends React.PureComponent {
render() {
return <ProjectViewWrapper {...this.props} renderComponent={ProjectSessionView} />
}
}
WrappedProjectSessionView.propTypes = ProjectSessionView.propTypes;
export default WrappedProjectSessionView;