synapse-react-client
Version:
[](https://travis-ci.com/Sage-Bionetworks/Synapse-React-Client) [](https://badge.fury.io/js/synaps
207 lines • 13.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.HelpersToTest = exports.EvaluationRoundEditor = void 0;
var tslib_1 = require("tslib");
var react_1 = (0, tslib_1.__importStar)(require("react"));
var react_bootstrap_1 = require("react-bootstrap");
var moment_1 = (0, tslib_1.__importDefault)(require("moment"));
var CalendarWithIconFormGroup_1 = require("./CalendarWithIconFormGroup");
var EvaluationRoundLimitOptionsList_1 = require("./round_limits/EvaluationRoundLimitOptionsList");
var free_solid_svg_icons_1 = require("@fortawesome/free-solid-svg-icons");
var react_fontawesome_1 = require("@fortawesome/react-fontawesome");
var useListState_1 = require("../../utils/hooks/useListState");
var models_1 = require("./input_models/models");
var SynapseClient_1 = require("../../utils/SynapseClient");
var EvaluationRoundEditorDropdown_1 = require("./EvaluationRoundEditorDropdown");
var ErrorBanner_1 = require("../ErrorBanner");
var SynapseContext_1 = require("../../utils/SynapseContext");
var disallowCalendarDateBefore = function (date) {
var startOfDay = date.startOf('day');
return function (currentDate) { return currentDate.isSameOrAfter(startOfDay); };
};
var determineRoundStatus = function (roundStart, roundEnd) {
var className;
var icon;
var status;
var now = (0, moment_1.default)();
// based off of start/end datetime from props so that users making
// unsaved changes to the start/end dates do not change the status
if (now.isSameOrAfter(roundStart)) {
if (now.isBefore(roundEnd)) {
className = 'status-in-progress';
icon = free_solid_svg_icons_1.faSyncAlt;
status = 'IN PROGRESS';
}
else {
className = 'status-completed';
icon = free_solid_svg_icons_1.faClipboardCheck;
status = 'COMPLETED';
}
}
else {
className = 'status-not-yet-started';
icon = undefined;
status = 'NOT YET STARTED';
}
return (react_1.default.createElement("div", { className: className },
react_1.default.createElement("div", { className: "status" },
icon && react_1.default.createElement(react_fontawesome_1.FontAwesomeIcon, { icon: icon }),
react_1.default.createElement("span", null, status))));
};
var convertInputsToEvaluationRound = function (evaluationRoundInputProp, startDate, endDate, totalSubmissionLimit, advancedLimits) {
var limits = [];
if (totalSubmissionLimit) {
var totalSubmissionLimitInt = Number(totalSubmissionLimit);
if (Number.isNaN(totalSubmissionLimitInt)) {
throw TypeError('Total Submission is not an integer');
}
limits.push({
limitType: 'TOTAL',
maximumSubmissions: totalSubmissionLimitInt,
});
}
advancedLimits.forEach(function (limitInput) {
if (limitInput.maxSubmissionString) {
var maxSubmissionInt = Number(limitInput.maxSubmissionString);
if (Number.isNaN(maxSubmissionInt)) {
throw TypeError(limitInput.type + ' Limit is not an integer');
}
limits.push({
limitType: limitInput.type,
maximumSubmissions: maxSubmissionInt,
});
}
});
return {
id: evaluationRoundInputProp.id,
etag: evaluationRoundInputProp.etag,
evaluationId: evaluationRoundInputProp.evaluationId,
roundStart: moment_1.default.utc(startDate).toJSON(),
roundEnd: moment_1.default.utc(endDate).toJSON(),
limits: limits,
};
};
var EvaluationRoundEditor = function (_a) {
var evaluationRoundInput = _a.evaluationRoundInput, onSave = _a.onSave, onDelete = _a.onDelete;
var accessToken = (0, SynapseContext_1.useSynapseContext)().accessToken;
var _b = (0, react_1.useState)(), error = _b[0], setError = _b[1];
var _c = (0, react_1.useState)(false), showSaveSuccess = _c[0], setShowSaveSuccess = _c[1];
(0, react_1.useEffect)(function () {
if (error) {
setShowSaveSuccess(false);
}
}, [error]);
var _d = (0, react_1.useState)((0, moment_1.default)(evaluationRoundInput.roundStart)), startDate = _d[0], setStartDate = _d[1];
var _e = (0, react_1.useState)((0, moment_1.default)(evaluationRoundInput.roundEnd)), endDate = _e[0], setEndDate = _e[1];
var _f = (0, react_1.useState)(evaluationRoundInput.totalSubmissionLimit), totalSubmissionLimit = _f[0], setTotalSubmissionLimit = _f[1];
var _g = (0, react_1.useState)(false), advancedMode = _g[0], setAdvancedMode = _g[1];
var _h = (0, useListState_1.useListState)(evaluationRoundInput.otherLimits), advancedLimits = _h.list, handleListRemove = _h.handleListRemove, handleAdvancedLimitsChange = _h.handleListChange, addAdvancedLimit = _h.appendToList;
// if we remove the last advanced limit, hide the advanced limits
var handleAdvancedLimitsRemove = function (index) {
var generatedRemoveFunc = handleListRemove(index);
return function () {
//we are deleting the last advanced limit
generatedRemoveFunc();
if (advancedLimits.length === 1) {
// NOTE: we dont check for length == 0 because we don't modify the original list,
// instead the generated function will setState() with a NEW empty list
// so the original list we reference still has 1 element
setAdvancedMode(false);
}
};
};
var onSaveButtonClick = function () {
setShowSaveSuccess(false);
var evaluationRound;
try {
evaluationRound = convertInputsToEvaluationRound(evaluationRoundInput, startDate, endDate, totalSubmissionLimit, advancedLimits);
}
catch (err) {
// error thrown if number
setError(err);
}
if (evaluationRound) {
var promise = evaluationRound.id
? (0, SynapseClient_1.updateEvaluationRound)(evaluationRound, accessToken)
: (0, SynapseClient_1.createEvaluationRound)(evaluationRound, accessToken);
promise
.then(function (createdOrUpdatedRound) {
var newInput = (0, models_1.convertEvaluationRoundToInput)(createdOrUpdatedRound, evaluationRoundInput.reactListKey);
//clear out previous error if any
setError(undefined);
setShowSaveSuccess(true);
onSave(newInput);
})
.catch(function (error) { return setError(error); });
}
};
var onDeleteButtonClick = function () {
if (evaluationRoundInput.id) {
(0, SynapseClient_1.deleteEvaluationRound)(evaluationRoundInput.evaluationId, evaluationRoundInput.id, accessToken)
.then(function () { return onDelete(); })
.catch(function (error) { return setError(error); });
}
else {
onDelete();
}
};
var disallowDatesBeforeNow = disallowCalendarDateBefore((0, moment_1.default)());
// https://react-bootstrap.github.io/components/forms/#forms-validation-native
return (react_1.default.createElement("div", { className: "evaluation-round-editor" },
react_1.default.createElement(react_bootstrap_1.Card, null,
react_1.default.createElement(react_bootstrap_1.Card.Body, null,
react_1.default.createElement(react_bootstrap_1.Form, null,
react_1.default.createElement(react_bootstrap_1.Row, null,
react_1.default.createElement(react_bootstrap_1.Col, null,
react_1.default.createElement("h5", null,
"ROUND STATUS",
evaluationRoundInput.id &&
' (' + evaluationRoundInput.id + ')')),
react_1.default.createElement(react_bootstrap_1.Col, null,
react_1.default.createElement(EvaluationRoundEditorDropdown_1.EvaluationRoundEditorDropdown, { onDelete: onDeleteButtonClick, onSave: onSaveButtonClick }))),
react_1.default.createElement(react_bootstrap_1.Row, { className: "mb-3" },
react_1.default.createElement(react_bootstrap_1.Col, null,
react_1.default.createElement("div", { className: "round-status" }, determineRoundStatus(evaluationRoundInput.roundStart, evaluationRoundInput.roundEnd)))),
react_1.default.createElement(react_bootstrap_1.Row, null,
react_1.default.createElement(react_bootstrap_1.Col, null,
react_1.default.createElement("h5", null, "DURATION"))),
react_1.default.createElement(react_bootstrap_1.Row, null,
react_1.default.createElement(react_bootstrap_1.Col, null,
react_1.default.createElement(CalendarWithIconFormGroup_1.CalendarWithIconFormGroup, { value: startDate, setterCallback: setStartDate, label: "Round Start", isValidDate: disallowDatesBeforeNow, disabled: (0, moment_1.default)().isSameOrAfter(evaluationRoundInput.roundStart) })),
react_1.default.createElement(react_bootstrap_1.Col, null,
react_1.default.createElement(CalendarWithIconFormGroup_1.CalendarWithIconFormGroup, { value: endDate, label: "Round End", setterCallback: setEndDate, isValidDate: disallowDatesBeforeNow }))),
react_1.default.createElement(react_bootstrap_1.Row, null,
react_1.default.createElement(react_bootstrap_1.Col, null,
react_1.default.createElement("h5", null, "SUBMISSION LIMITS"))),
react_1.default.createElement(react_bootstrap_1.Row, null,
react_1.default.createElement(react_bootstrap_1.Col, null,
react_1.default.createElement(react_bootstrap_1.FormGroup, null,
react_1.default.createElement("label", null, "Total Submissions / Round"),
react_1.default.createElement(react_bootstrap_1.FormControl, { value: totalSubmissionLimit, type: "text", pattern: "[0-9]*", onChange: function (event) {
return setTotalSubmissionLimit(event.target.value);
},
// Chrome for some reason decides to autofill this input box with email address, so we must disable autofill
// this is a hacky, but consistent way to disable autofill because Chrome does not respect the spec :(
// https://bugs.chromium.org/p/chromium/issues/detail?id=914451
autoComplete: "new-password" })))),
react_1.default.createElement(react_bootstrap_1.Row, { className: "mb-3" },
react_1.default.createElement(react_bootstrap_1.Col, null,
react_1.default.createElement(react_bootstrap_1.Button, { variant: "link", className: "advanced-limits-link font-weight-bold", onClick: function () { return setAdvancedMode(!advancedMode); } }, "Advanced Limits"))),
advancedMode && (react_1.default.createElement(EvaluationRoundLimitOptionsList_1.EvaluationRoundLimitOptionsList, { limitInputs: advancedLimits, handleChange: handleAdvancedLimitsChange, handleDeleteLimit: handleAdvancedLimitsRemove, onAddNewLimit: addAdvancedLimit })),
error && (react_1.default.createElement(react_bootstrap_1.Row, { className: "my-3" },
react_1.default.createElement(react_bootstrap_1.Col, null,
react_1.default.createElement(ErrorBanner_1.ErrorBanner, { error: error })))),
showSaveSuccess && (react_1.default.createElement(react_bootstrap_1.Row, { className: "my-3" },
react_1.default.createElement(react_bootstrap_1.Col, null,
react_1.default.createElement(react_bootstrap_1.Alert, { className: "save-success-alert", dismissible: true, variant: "success", transition: false, onClose: function () { return setShowSaveSuccess(false); } }, "Successfully saved.")))),
react_1.default.createElement(react_bootstrap_1.Row, { className: "mt-3" },
react_1.default.createElement(react_bootstrap_1.Col, null,
react_1.default.createElement(react_bootstrap_1.Button, { className: "save-button float-right border-0", onClick: onSaveButtonClick }, "Save"))))))));
};
exports.EvaluationRoundEditor = EvaluationRoundEditor;
exports.HelpersToTest = {
disallowCalendarDateBefore: disallowCalendarDateBefore,
determineRoundStatus: determineRoundStatus,
convertInputsToEvaluationRound: convertInputsToEvaluationRound,
};
//# sourceMappingURL=EvaluationRoundEditor.js.map