diff --git a/client/components/Cohorts/DataTable.css b/client/components/Cohorts/DataTable.css
index 2b2e8147e..22ef62f90 100644
--- a/client/components/Cohorts/DataTable.css
+++ b/client/components/Cohorts/DataTable.css
@@ -34,6 +34,15 @@
);
}
+.dt__cell-truncated {
+ overflow: hidden !important;
+ white-space: nowrap !important;
+ text-overflow: ellipsis !important;
+ width: 250px;
+ max-width: 250px;
+ min-width: 250px;
+}
+
.gridcolumn__first-child--sticky {
min-width: 40% !important;
}
diff --git a/client/components/Researcher/index.jsx b/client/components/Researcher/index.jsx
index 20a1d67b6..31b230558 100644
--- a/client/components/Researcher/index.jsx
+++ b/client/components/Researcher/index.jsx
@@ -5,13 +5,14 @@ import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { Button, Icon, Pagination, Popup, Table } from '@components/UI';
import hash from 'object-hash';
-import { getCohorts } from '@actions/cohort';
+import { getAllCohorts, getCohorts } from '@actions/cohort';
import { getScenarios, getScenarioRunHistory } from '@actions/scenario';
import { getUser } from '@actions/user';
import Loading from '@components/Loading';
import CSV from '@utils/csv';
import { makeHeader } from '@utils/data-table';
import '../Cohorts/Cohort.css';
+import '../Cohorts/DataTable.css';
import './Researcher.css';
const ROWS_PER_PAGE = 10;
@@ -43,7 +44,13 @@ class Researcher extends Component {
this.props.history.push('/logout');
} else {
await this.props.getScenarios();
- await this.props.getCohorts();
+
+ if (this.props.user.is_super) {
+ await this.props.getAllCohorts();
+ } else {
+ await this.props.getCohorts();
+ }
+
this.setState({ isReady: true });
}
}
@@ -68,7 +75,10 @@ class Researcher extends Component {
const files = [];
for (let id of scenarioIds) {
- const { prompts, responses } = await getScenarioRunHistory(id, cohort.id);
+ const { prompts, responses } = await getScenarioRunHistory(
+ id,
+ cohort && cohort.id
+ );
const records = responses.flat();
@@ -84,7 +94,9 @@ class Researcher extends Component {
record.content += ` (${location.origin}/api/media/${value})`;
}
- record.cohort_id = cohort.id;
+ if (cohort) {
+ record.cohort_id = cohort.id;
+ }
});
const fields = [
@@ -96,14 +108,18 @@ class Researcher extends Component {
'created_at',
'ended_at',
'type',
- 'referrer_params',
- 'cohort_id'
+ 'referrer_params'
];
- const file = `${hash({ cohort, id })}.csv`;
+
+ if (cohort) {
+ fields.push('cohort_id');
+ }
+
+ const file = hash({ cohort, id });
const parser = new Parser({ fields });
const csv = parser.parse(records);
- files.push([file, csv]);
+ files.push([`${file}.csv`, csv]);
}
if (Object.entries(files).length === 1) {
@@ -117,26 +133,30 @@ class Researcher extends Component {
render() {
const { onPageChange, downloadData } = this;
const { activePage, isReady } = this.state;
- const { cohorts, scenariosById, user } = this.props;
+ const { cohorts, scenarios, scenariosById, user } = this.props;
if (!isReady) {
return ;
}
const hasAccessToCohort = cohort => {
+ if (user.is_super) {
+ return true;
+ }
+
return cohort.users.find(({ id, roles }) => {
return id === user.id && roles.includes('researcher');
});
};
- const downloadByCohortIcon = (
+ const downloadZipIcon = (
);
- const downloadByScenarioIcon = (
+ const downloadRunIcon = (
@@ -152,20 +172,21 @@ class Researcher extends Component {
accum.push(
...cohort.scenarios.map((id, index) => {
const scenario = scenariosById[id];
- const { title } = scenario;
-
- const onDownloadByScenarioClick = () => {
+ const onDownloadByScenarioRunClick = () => {
downloadData({ cohort, scenarioId: id });
};
return (
-
+
{index === 0 ? (
) : null}
@@ -173,11 +194,13 @@ class Researcher extends Component {
{cohort.name}
- {title}
+
+ {scenario.title}
+
);
})
@@ -186,6 +209,42 @@ class Researcher extends Component {
return accum;
}, []);
+ if (user.is_super) {
+ const scenarioRunDownloads = scenarios.reduce((accum, scenario) => {
+ const onDownloadByScenarioRunClick = () => {
+ downloadData({ scenarioId: scenario.id });
+ };
+ accum.push(
+
+
+
+
+
+ {scenario.title}
+
+
+ );
+ return accum;
+ }, []);
+
+ downloads.push(...scenarioRunDownloads);
+ }
+
+ downloads.sort((a, b) => {
+ return a.props.created_at > b.props.created_at;
+ });
+
const downloadsPages = Math.ceil(downloads.length / ROWS_PER_PAGE);
const downloadsIndex = (activePage - 1) * ROWS_PER_PAGE;
const downloadsSlice = downloads.slice(
@@ -278,6 +337,7 @@ Researcher.propTypes = {
runs: PropTypes.array,
scenarios: PropTypes.array,
scenariosById: PropTypes.object,
+ getAllCohorts: PropTypes.func,
getCohorts: PropTypes.func,
getScenarios: PropTypes.func,
getScenarioRunHistory: PropTypes.func,
@@ -292,6 +352,7 @@ const mapStateToProps = state => {
};
const mapDispatchToProps = dispatch => ({
+ getAllCohorts: () => dispatch(getAllCohorts()),
getCohorts: () => dispatch(getCohorts()),
getScenarios: () => dispatch(getScenarios()),
getScenarioRunHistory: (...params) =>