Files
frontend-app-gradebook/src/data/selectors/index.js
Nathan Sprenkle 650e9321b1 Simplify Bulk Management Config (#200)
* refactor: simplify bulk management enabling

Formerly, a course had to have bulk management enabled and have a master's
track. This painted us into a corner where we had to create a
workaround for enabling bulk management on non-master's track courses.
Instead, this relies only on an enabled flag from edx-platform (based on
a course waffle flag) which simplifies the enabling code here.

* feat: remove unneeded bulk management allow-list
2021-08-04 11:04:55 -04:00

247 lines
7.8 KiB
JavaScript

import { StrictDict } from 'utils';
import lms from 'data/services/lms';
import * as filterConstants from 'data/constants/filters';
import * as module from '.';
import app from './app';
import assignmentTypes from './assignmentTypes';
import cohorts from './cohorts';
import filters from './filters';
import grades, { minGrade, maxGrade } from './grades';
import roles from './roles';
import tracks from './tracks';
const {
filterConfig,
filters: filterNames,
} = filterConstants;
/**
* editModalPossibleGrade(state)
* Returns the "possible" grade as shown in the edit modal.
* @param {object} state - redux state;
* @return {string} - possibleGrade to show on edit modal
*/
export const editModalPossibleGrade = (state) => (
app.modalState.adjustedGradePossible(state) || grades.gradeOriginalPossibleGraded(state)
);
/**
* filterBadgeConfig(state, name)
* Takes a filter name and returns the appropriate badge config, with value and isDefault.
* Determines if it should return a range or single-value config based on the presence of
* a filterOrder prop in the filter config associated with the passed name.
* @param {object} state - redux state
* @param {string} name - api filter name
*/
export const filterBadgeConfig = (state, name) => {
const filterValue = module.filterBadgeValues[name](state);
const { filterOrder, ...config } = filterConfig[name];
const isRange = !!filterOrder;
const value = isRange ? `${filterValue[0]} - ${filterValue[1]}` : filterValue;
const isDefault = (isRange
? (
filters.isDefault(filterOrder[0], filterValue[0])
&& filters.isDefault(filterOrder[1], filterValue[1])
)
: filters.isDefault(name, filterValue)
);
return { ...config, value, isDefault };
};
/**
* filterBadgeValues methods
* For each filter type with an associated badge, provides a selector that returns the
* content of that badge
*/
export const filterBadgeValues = StrictDict({
[filterNames.assignment]: (state) => (
filters.selectedAssignmentLabel(state) || ''
),
[filterNames.assignmentType]: filters.assignmentType,
[filterNames.includeCourseRoleMembers]: filters.includeCourseRoleMembers,
[filterNames.cohort]: (state) => {
const entry = module.selectedCohortEntry(state);
return entry ? entry.name : '';
},
[filterNames.track]: (state) => {
const entry = module.selectedTrackEntry(state);
return entry ? entry.name : '';
},
[filterNames.assignmentGrade]: (state) => ([
filters.assignmentGradeMin(state),
filters.assignmentGradeMax(state),
]),
[filterNames.courseGrade]: (state) => ([
filters.courseGradeMin(state),
filters.courseGradeMax(state),
]),
});
/**
* formattedGradeLimits(state)
* Returns an object of local grade limits, formatted for fetching.
* This means only setting any of them if the assignment is set, and only setting an
* individual min/max if they are not equal to the default min/max.
* @param {object} state - redux state
* @return {object} - { assignmentGradeMax, assignmentGradeMin, courseGradeMax, courseGradeMin }
*/
export const formattedGradeLimits = (state) => {
const { assignmentGradeMax, assignmentGradeMin } = app.assignmentGradeLimits(state);
const { courseGradeMax, courseGradeMin } = app.courseGradeLimits(state);
const hasAssignment = filters.selectedAssignmentId(state) !== undefined;
if (!hasAssignment) {
return {
assignmentGradeMax: null,
assignmentGradeMin: null,
courseGradeMax: null,
courseGradeMin: null,
};
}
return {
assignmentGradeMax: assignmentGradeMax === maxGrade ? null : assignmentGradeMax,
assignmentGradeMin: assignmentGradeMin === minGrade ? null : assignmentGradeMin,
courseGradeMax: courseGradeMax === maxGrade ? null : courseGradeMax,
courseGradeMin: courseGradeMin === minGrade ? null : courseGradeMin,
};
};
/**
* getHeadings(state)
* Returns the table headings given the current assignmentType and assignmentLabel filters.
* @param {object} state - redux state
* @return {string[]} - array of table headings
*/
export const getHeadings = (state) => grades.headingMapper(
filters.assignmentType(state) || 'All',
filters.selectedAssignmentLabel(state) || 'All',
)(grades.getExampleSectionBreakdown(state));
/**
* gradeExportUrl(state, options)
* Returns the output of getGradeCsvUrl, applying the current includeCourseRoleMembers
* filter.
* @param {object} state - redux state
* @return {string} - generated grade export url
*/
export const gradeExportUrl = (state) => (
lms.urls.gradeCsvUrl(module.lmsApiServiceArgs(state))
);
/**
* interventionExportUrl(state, options)
* Returns the output of getInterventionExportUrl.
* @param {object} state - redux state
* @return {string} - generated intervention export url
*/
export const interventionExportUrl = (state) => (
lms.urls.interventionExportCsvUrl(module.lmsApiServiceArgs(state))
);
/**
* lmsApiServiceArgs(state)
* Returns common lms api service request args.
* @param {object} state - redux state
* @return {object} lms api query params object
*/
export const lmsApiServiceArgs = (state) => ({
cohort: cohorts.getCohortNameById(state, filters.cohort(state)),
track: filters.track(state),
assignment: filters.selectedAssignmentId(state),
assignmentType: filters.assignmentType(state),
assignmentGradeMin: grades.formatMinAssignmentGrade(
filters.assignmentGradeMin(state),
{ assignmentId: filters.selectedAssignmentId(state) },
),
assignmentGradeMax: grades.formatMaxAssignmentGrade(
filters.assignmentGradeMax(state),
{ assignmentId: filters.selectedAssignmentId(state) },
),
courseGradeMin: grades.formatMinCourseGrade(filters.courseGradeMin(state)),
courseGradeMax: grades.formatMaxCourseGrade(filters.courseGradeMax(state)),
excludedCourseRoles: filters.excludedCourseRoles(state),
});
/**
* localFilters(state)
* returns local filter data for fetchGrades call
* @param {object} state - redux state
* @return {object} - fetch arguments signifying current local filter state
*/
export const localFilters = (state) => {
const id = filters.selectedAssignmentId(state);
const searchText = app.searchValue(state);
return {
assignment: id,
includeCourseRoleMembers: filters.includeCourseRoleMembers(state),
...module.formattedGradeLimits(state),
...(searchText !== '' && { searchText }),
};
};
/**
* selectedCohortEntry(state)
* Returns the full entry data for the selected cohort
* @param {object} state - redux state
* @return {object} - selected cohort entry object
*/
export const selectedCohortEntry = (state) => (
cohorts.allCohorts(state).find(
({ id }) => id === parseInt(filters.cohort(state), 10),
)
);
/**
* selectedTrackEntry(state)
* Returns the full entry data for the selected track
* @param {object} state - redux state
* @return {object} - selected track entry object
*/
export const selectedTrackEntry = (state) => (
tracks.allTracks(state).find(
({ slug }) => slug === filters.track(state),
)
);
/**
* shouldShowSpinner(state)
* Returns true iff the user can view the gradebook and grades.showSpinner is true.
* @param {object} state - redux state
* @return {bool} - should show spinner?
*/
export const shouldShowSpinner = (state) => (
roles.canUserViewGradebook(state)
&& grades.showSpinner(state)
);
/**
* showBulkManagement(state, options)
* Returns true iff the course has bulk management enabled
* @param {object} state - redux state
* @return {bool} - should show bulk management controls?
*/
export const showBulkManagement = (state) => (state.config.bulkManagementAvailable);
export default StrictDict({
root: StrictDict({
editModalPossibleGrade,
filterBadgeConfig,
getHeadings,
gradeExportUrl,
interventionExportUrl,
localFilters,
selectedCohortEntry,
selectedTrackEntry,
shouldShowSpinner,
showBulkManagement,
}),
app,
assignmentTypes,
cohorts,
filters,
grades,
roles,
tracks,
});