Commit d2931edc authored by Maxime Chaillet's avatar Maxime Chaillet

Merge branch 'issue102' into 'master'

Enable export event to pdf using existing filtres. writes test. It fixes #102.

Closes #102

See merge request !129
parents 9f41c0ed 3b82ef8a
Pipeline #10561 passed with stages
in 6 minutes and 27 seconds
......@@ -79,15 +79,15 @@ export function getFileByEventId(sessionId, investigationId, eventId) {
* @param {object} selectionFilter selection filter used to retrieve part of the logbook. This is URI encoded and passed as query string
*/
export function getPDF(sessionId, investigationId, selectionFilter) {
let url = ICATPLUS.server + "/logbook/sessionId/investigation/id/investigationId/event/pdf?find=&sort=&skip=&limit="
return ICATPLUS.server + "/logbook/sessionId/investigation/id/investigationId/event/pdf?find=&sort=&skip=&limit="
.replace("sessionId", sessionId)
.replace("investigationId", investigationId)
.replace("find=", 'find=' + JSON.stringify(selectionFilter.find))
.replace("&sort=", '&sort=' + JSON.stringify(selectionFilter.sort))
.replace("&skip=", '&skip=' + JSON.stringify(selectionFilter.skip))
.replace("&limit=", '&limit=' + JSON.stringify(selectionFilter.limit));
return url;
.replace("find=", () => { return 'find=' + ((selectionFilter && selectionFilter.find) ? JSON.stringify(selectionFilter.find) : '') })
.replace("&sort=", () => { return '&sort=' + ((selectionFilter && selectionFilter.sort) ? JSON.stringify(selectionFilter.sort) : '') })
.replace("&skip=", () => { return '&skip=' + ((selectionFilter && selectionFilter.skip !== undefined) ? JSON.stringify(selectionFilter.skip) : '') })
.replace("&limit=", () => { return '&limit=' + ((selectionFilter && selectionFilter.limit !== undefined) ? JSON.stringify(selectionFilter.limit) : '') });
}
/**
......
......@@ -35,6 +35,7 @@ class EventActionBar extends React.Component {
const { investigationId,
isNewEventVisible,
numberOfMatchingEventsFound,
selectionFilter,
sessionId,
setNewEventVisibility,
setView,
......@@ -74,13 +75,9 @@ class EventActionBar extends React.Component {
investigationId={investigationId}
isNewEventVisible={isNewEventVisible}
numberOfMatchingEventsFound={numberOfMatchingEventsFound}
selectionFilter={selectionFilter}
sessionId={sessionId}
/>
<MenuItem eventKey={3.1}>
</MenuItem>
<MenuItem eventKey={3.2}>
</MenuItem>
</NavDropdown>
<NavItem eventKey={4} href="#" className="logbookNavItem">
......@@ -201,7 +198,7 @@ class EventActionBar extends React.Component {
}
}
/* A React component which renders the 'PDF' button */
/* A React component which renders the 'Camera' button */
class CameraButton extends React.Component {
render() {
const tooltip = (text) => (
......@@ -231,44 +228,14 @@ class CameraButton extends React.Component {
/* A React component which renders the 'PDF' button */
class PDFButton extends React.Component {
render() {
let { isNewEventVisible, numberOfMatchingEventsFound, investigationId, sessionId } = this.props;
if (isNewEventVisible === undefined || isNewEventVisible === true || numberOfMatchingEventsFound === 0) {
return (<Button
bsSize='small'
bsStyle='primary'
disabled
style={{
marginTop: '5px',
marginBottom: '5px',
marginLeft: '10px',
}}
>
<Glyphicon glyph='download' style={{ marginRight: '3px' }} />
PDF
</Button>);
}
let { isNewEventVisible, numberOfMatchingEventsFound, investigationId, sessionId, selectionFilter } = this.props;
//default behavior
const tooltip = (text) => (
<Tooltip id='tooltip'>
{text}
</Tooltip>
);
// this selectionFilter is used to query all events from a given logbook. It is currently not flexible, to be changed.
let selectionFilter = {
find: {
$and: [{
$or: [
{ type: 'annotation' },
{ type: 'notification' }
]
}]
},
sort: { createdAt: -1 }
};
return (<OverlayTrigger placement='bottom' overlay={tooltip('Download the logbook as PDF')} >
<Button
bsSize='small'
......@@ -280,6 +247,7 @@ class PDFButton extends React.Component {
marginBottom: '5px',
marginLeft: '10px',
}}
disabled={(isNewEventVisible === undefined || isNewEventVisible === true || numberOfMatchingEventsFound === 0)}
>
<Glyphicon glyph='download' style={{ marginRight: '3px' }} /> PDF
</Button>
......@@ -298,6 +266,8 @@ EventActionBar.propTypes = {
reverseEventsSortingByCreationDate: PropTypes.func.isRequired,
/** Callback function which reloads the events based on search criteria*/
searchEvents: PropTypes.func,
/** selection filter for mongo request */
selectionFilter: PropTypes.object,
/* the sessionId*/
sessionId: PropTypes.string.isRequired,
/** Callback function triggered when the user clicks on the new event button */
......
......@@ -143,7 +143,7 @@ TagList.propTypes = {
/* Context defining how tag list is rendered */
context: PropTypes.string.isRequired,
/* investigation identifier */
investigatinoId: PropTypes.string,
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.*/
......
......@@ -13,7 +13,7 @@ import { convertPageToPageEventIndexes, isRangeAvailableOnTheClient } from '../.
import { GUI_CONFIG } from '../../config/gui.config.js';
import Loading from '../../components/Loading.js';
import UserMessage from '../../components/UserMessage.js';
import { getSelectionFiltersBySearchCriteria } from './SelectionFilterHelper.js';
import { getSelectionFiltersBySearchCriteria, getSelectionFiltersForMongoQuery } from './SelectionFilterHelper.js';
import { clearAvailableTagAction } from '../../actions/logbook.js';
/**
......@@ -34,7 +34,6 @@ class EventContainer extends React.Component {
isNewEventVisible: false,
pageEvents: [], // events currently displayed on the page
selectedEventId: 0,
selectionFilter: getSelectionFiltersBySearchCriteria([], LIST_VIEW),
sortingFilter: GUI_CONFIG().DEFAULT_SORTING_FILTER,
userSearchCriteria: [],
view: LIST_VIEW
......@@ -56,6 +55,7 @@ class EventContainer extends React.Component {
render() {
const { investigationId, user } = this.props;
const selectionFilter = getSelectionFiltersForMongoQuery(this.state.userSearchCriteria, this.state.sortingFilter, this.state.view);
function isDataFetched(parentThis) {
let _this = parentThis;
......@@ -67,13 +67,13 @@ class EventContainer extends React.Component {
return false;
}
if (this.isAppProperlyConfigured()) {
return (
<div style={{ marginBottom: '40px' }}>
<UserMessage type={ERROR_MESSAGE_TYPE} message={this.state.errorMessage} />
<EventActionBar
availableTags = {this.props.availableTags}
investigationId={investigationId}
isNewEventVisible={this.state.isNewEventVisible}
numberOfMatchingEventsFound={this.state.foundEventCount}
......@@ -83,8 +83,8 @@ class EventContainer extends React.Component {
setNewEventVisibility={this.setNewEventVisibility}
setView={this.setView}
sortingFilter={this.state.sortingFilter}
selectionFilter={selectionFilter}
view={this.state.view}
availableTags = {this.props.availableTags}
/>
<NewEvent
......@@ -163,7 +163,7 @@ class EventContainer extends React.Component {
sortingFilter = sortingFilter || GUI_CONFIG().DEFAULT_SORTING_FILTER;
if (!selectionFilter) {
// there is not selectionfilter as parameter when the user has clicked on a page
selectionFilter = this.state.selectionFilter;
selectionFilter = getSelectionFiltersBySearchCriteria(this.state.userSearchCriteria, this.state.view);
};
this.getEventsByInvestigationId(investigationId, user.sessionId, GUI_CONFIG().EVENTS_PER_DOWNLOAD, offset, selectionFilter, sortingFilter, this.onEventsReceptionFailure);
......@@ -332,6 +332,7 @@ class EventContainer extends React.Component {
*/
reverseEventsSortingByCreationDate(selectedEventId) {
let newSortingFilter = {};
let selectionFilter = getSelectionFiltersBySearchCriteria(this.state.userSearchCriteria, this.state.view);
/* temporary fix , in the future we will use creationDate instead of createdAt*/
newSortingFilter.createdAt = this.state.sortingFilter.createdAt * (-1);
......@@ -344,7 +345,7 @@ class EventContainer extends React.Component {
let rankInFutureList = this.state.foundEventCount - indexOfEventOnAllEventsFound;
let newPage = Math.ceil(rankInFutureList / GUI_CONFIG().EVENTS_PER_PAGE);
let offset = (newPage - 1) * GUI_CONFIG().EVENTS_PER_PAGE;
this.downloadEvents(offset, this.state.selectionFilter, false, newSortingFilter);
this.downloadEvents(offset, selectionFilter, false, newSortingFilter);
this.setState({
activePage: newPage,
selectedEventId: selectedEventId
......@@ -352,7 +353,7 @@ class EventContainer extends React.Component {
return;
}
}
this.downloadEvents(0, this.state.selectionFilter, false, newSortingFilter);
this.downloadEvents(0, selectionFilter, false, newSortingFilter);
this.setState({ activePage: 1, selectedEventId: 0 });
}
......
import { DOC_VIEW } from '../../constants/EventTypes.js';
import StringConverterForRegexp from 'escape-string-regexp';
import { GUI_CONFIG } from '../../config/gui.config.js';
const REGEXP_FILTER_TYPE = 'regexpFilterType';
const EQUALITY_FILTER_TYPE = 'equalityFilterType';
/**
* Get selecton filters combining find, sort selection filters for mongoDB query
* @param {*} findCriteria what will be the find parameter in mongo query
* @param {*} sortCriteria what will be the sort parameter in mongo query
* @param {*} view current logbook view
*/
export function getSelectionFiltersForMongoQuery(findCriteria, sortCriteria, view) {
if (!findCriteria) {
findCriteria =[];
}
if (!sortCriteria){
sortCriteria = GUI_CONFIG().DEFAULT_SORTING_FILTER;
}
return {
find: getSelectionFiltersBySearchCriteria(findCriteria, view),
sort: sortCriteria
}
}
/**
* Get selection filters to be used in mongoDB query
* @param {array} criteria user specified search criteria
......
import { getUserSpecificSelectionFilters, getSelectionFiltersBySearchCriteria } from '../src/containers/Event/SelectionFilterHelper';
import { getUserSpecificSelectionFilters, getSelectionFiltersForMongoQuery, getSelectionFiltersBySearchCriteria } from '../src/containers/Event/SelectionFilterHelper';
require('it-each')({ testPerIteration: true });
const resources = require('./resources/selectionFilterHelper.resource');
......@@ -23,4 +23,12 @@ describe("selectionFilterHelper", () => {
})
})
})
describe('getSelectionFiltersForMongoQuery', () => {
it.each(resources.getSelectionFiltersForMongoQuery, '[note: %s ]', ['aboutThisTest'],
function (element, next) {
expect(getSelectionFiltersForMongoQuery(element.findCriteria, element.sortCriteria, element.view)).toEqual(element.expected)
next();
})
})
})
\ No newline at end of file
......@@ -487,5 +487,15 @@ module.exports = {
}]
}
},
],
getSelectionFiltersForMongoQuery: [
{
aboutThisTest: 'returns mongo sleection filter using provided find and sort criteria',
findCriteria: { "$and": [{ "$or": [{ "type": "annotation" }, { "type": "notification" }] }] },
sortCriteria: { "createdAt": -1 },
expected: { "find": { "$and": [{ "$or": [{ "type": "annotation" }, { "type": "notification" }] }] } }
}
]
}
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