Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 13 additions & 8 deletions jsx/DataTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,21 +117,26 @@ class DataTable extends Component {
*/

downloadCSV(filteredRowIndexes) {
const fields = this.props.fields.map((field, index) => ({field, index}));
const visibleFields = fields.filter(({field}) => field.show !== false);
const headers = this.props.fields.map((field) => field.label);
let csvData = filteredRowIndexes.map((id) => this.props.data[id]);
// Map cell data to proper values if applicable.
if (this.props.getMappedCell) {
csvData = csvData
.map((row, i) => this.props.fields
.map((field, j) => this.props.getMappedCell(
.map((row) => visibleFields
.map(({field, index}) => this.props.getMappedCell(
field.label,
row[j],
row[index],
row,
this.props.fields.map(
(val) => val.label,
),
j
headers,
index
))
);
} else {
csvData = csvData.map(
(row) => visibleFields.map(({index}) => row[index])
);
}

let csvworker = new Worker(loris.BaseURL + '/js/workers/savecsv.js');
Expand All @@ -152,7 +157,7 @@ class DataTable extends Component {
document.body.removeChild(link);
}
});
const headerList = this.props.fields.map((field) => field.label);
const headerList = visibleFields.map(({field}) => field.label);
csvworker.postMessage({
cmd: 'SaveFile',
data: csvData,
Expand Down
85 changes: 76 additions & 9 deletions modules/examiner/jsx/examinerIndex.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ class ExaminerIndex extends Component {
this.fetchData = this.fetchData.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.setFormData = this.setFormData.bind(this);
this.filterVisibleRows = this.filterVisibleRows.bind(this);
this.formatColumn = this.formatColumn.bind(this);
this.mapCSVCell = this.mapCSVCell.bind(this);
this.renderAddExaminerForm = this.renderAddExaminerForm.bind(this);
this.openModal = this.openModal.bind(this);
this.closeModal = this.closeModal.bind(this);
Expand Down Expand Up @@ -104,6 +106,51 @@ class ExaminerIndex extends Component {
});
}

/**
* Get the subset of site IDs visible to the current user.
*
* @return {object}
*/
getVisibleSites() {
return this.state.data.fieldOptions?.sites || {};
}

/**
* Keep only site IDs visible to the current user.
*
* @param {string[]|number[]} siteIds - examiner site IDs
* @return {string[]|number[]}
*/
filterVisibleSiteIds(siteIds) {
const visibleSites = this.getVisibleSites();
if (!Array.isArray(siteIds)) {
return [];
}
return siteIds.filter((centerId) => visibleSites[centerId] != null);
}

/**
* Convert visible site IDs into site labels.
*
* @param {string[]|number[]} siteIds - examiner site IDs
* @return {string[]}
*/
mapVisibleSiteNames(siteIds) {
const visibleSites = this.getVisibleSites();
return this.filterVisibleSiteIds(siteIds)
.map((centerId) => visibleSites[centerId]);
}

/**
* Limit rows to examiners that share at least one visible site.
*
* @param {Array[]} rows - examiner data rows
* @return {Array[]}
*/
filterVisibleRows(rows) {
return rows.filter((row) => this.filterVisibleSiteIds(row[2]).length > 0);
}

/**
* Handles the submission of the Add Examiner form
*
Expand Down Expand Up @@ -184,16 +231,11 @@ class ExaminerIndex extends Component {
result = <td>{t('None', {ns: 'loris'})}</td>;
}
} else if (column === 'Site' || column === labelSite) {
// If user has multiple sites, join array of sites into string
const siteNames = this.mapVisibleSiteNames(cell);
result = (
<td>{cell
.filter((centerId) => this.state.data.fieldOptions.sites[centerId]
!= null)
.map((centerId) => this.state.data.fieldOptions.sites[centerId])
.join(', ')}
</td>
<td>{siteNames.join(', ')}</td>
);
if (cell.length === 0) {
if (siteNames.length === 0) {
result = (
<td>{t(
'This user has no site affiliations',
Expand All @@ -205,6 +247,29 @@ class ExaminerIndex extends Component {
return result;
}

/**
* Map raw row values to CSV-safe display values.
*
* @param {string} column - column label
* @param {*} cell - raw cell value
* @return {*} mapped cell value
*/
mapCSVCell(column, cell) {
const {t} = this.props;
const labelCertification = t('Certification', {ns: 'examiner'});
const labelSite = t('Site', {ns: 'loris', count: 1});

if (column === labelSite) {
return this.mapVisibleSiteNames(cell).join(', ');
}

if (column === labelCertification && cell === null) {
return t('None', {ns: 'loris'});
}

return cell;
}

/**
* Executed when modal is opened.
*/
Expand Down Expand Up @@ -308,6 +373,7 @@ class ExaminerIndex extends Component {
* queried columns in _setupVariables() in examiner.class.inc
*/
const options = this.state.data.fieldOptions;
const data = this.filterVisibleRows(this.state.data.Data);
const fields = [
{label: t('Examiner', {ns: 'examiner'}), show: true, filter: {
name: 'examiner',
Expand Down Expand Up @@ -345,9 +411,10 @@ class ExaminerIndex extends Component {
<FilterableDataTable
name='examiner'
title={t('Examiner', {ns: 'examiner'})}
data={this.state.data.Data}
data={data}
fields={fields}
getFormattedCell={this.formatColumn}
getMappedCell={this.mapCSVCell}
actions={actions}
/>
</div>
Expand Down
Loading