UNPKG

synapse-react-client

Version:

[![Build Status](https://travis-ci.com/Sage-Bionetworks/Synapse-React-Client.svg?branch=main)](https://travis-ci.com/Sage-Bionetworks/Synapse-React-Client) [![npm version](https://badge.fury.io/js/synapse-react-client.svg)](https://badge.fury.io/js/synaps

207 lines 13.2 kB
"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