From 18647902042e3cbb31c01a4f847c9f66a6f277ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kruli=C5=A1?= Date: Tue, 19 Dec 2017 09:43:29 +0100 Subject: [PATCH] Ux improvements (#152) * Minor modification of submission table. * Improving evaluation results table and byte pretty print function. * Fixing bugs in EditGroup form. * Fixing and improving assignment-exercise sync dialog. --- .../AssignmentSync/AssignmentSync.js | 199 +++++++++++------- .../TestResultsTable/TestResultsTable.js | 41 ++-- .../forms/EditGroupForm/EditGroupForm.js | 3 + src/components/helpers/stringFormatters.js | 4 +- src/locales/cs.json | 12 +- src/locales/en.json | 12 +- src/pages/EditGroup/EditGroup.js | 2 +- 7 files changed, 167 insertions(+), 106 deletions(-) diff --git a/src/components/Assignments/Assignment/AssignmentSync/AssignmentSync.js b/src/components/Assignments/Assignment/AssignmentSync/AssignmentSync.js index 2304db7fe..4e6678118 100644 --- a/src/components/Assignments/Assignment/AssignmentSync/AssignmentSync.js +++ b/src/components/Assignments/Assignment/AssignmentSync/AssignmentSync.js @@ -1,27 +1,137 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { FormattedMessage } from 'react-intl'; +import { FormattedMessage, FormattedDate, FormattedTime } from 'react-intl'; import { Row, Col, Alert } from 'react-bootstrap'; import Button from '../../../widgets/FlatButton'; -const AssignmentSync = ({ syncInfo, exerciseSync }) => - !syncInfo.exerciseConfig.upToDate || - !syncInfo.configurationType.upToDate || - !syncInfo.exerciseEnvironmentConfigs.upToDate || - !syncInfo.hardwareGroups.upToDate || - !syncInfo.localizedTexts.upToDate || - !syncInfo.limits.upToDate || - !syncInfo.scoreConfig.upToDate || - !syncInfo.scoreCalculator.upToDate || - !syncInfo.exerciseTests.upToDate +const syncMessages = { + supplementaryFiles: ( + + ), + attachmentFiles: ( + + ), + exerciseTests: ( + + ), + localizedTexts: ( + + ), + configurationType: ( + + ), + scoreConfig: ( + + ), + scoreCalculator: ( + + ), + exerciseConfig: ( + + ), + runtimeEnvironments: ( + + ), + exerciseEnvironmentConfigs: ( + + ), + hardwareGroups: ( + + ), + limits: ( + + ) +}; + +const getSyncMessages = syncInfo => { + const res = []; + for (const field in syncMessages) { + if (!syncInfo[field]) { + console.log('Field ' + field + ' not present.'); + continue; + } + + if (!syncInfo[field].upToDate) { + res.push( +
  • + {syncMessages[field]} +
  • + ); + } + } + return res; +}; + +const AssignmentSync = ({ syncInfo, exerciseSync }) => { + const messages = getSyncMessages(syncInfo); + return messages.length > 0 ?

    + + {' ('} + + {')'} + + : '??', + assignmentUpdated: syncInfo.updatedAt.assignment + ? + + {' ('} + + {')'} + + : '??' + }} />

    @@ -30,69 +140,7 @@ const AssignmentSync = ({ syncInfo, exerciseSync }) => defaultMessage="The exercise for this assignment was updated in following categories:" />
      - {!syncInfo.exerciseConfig.upToDate && -
    • - -
    • } - {!syncInfo.configurationType.upToDate && -
    • - -
    • } - {!syncInfo.exerciseEnvironmentConfigs.upToDate && -
    • - -
    • } - {!syncInfo.hardwareGroups.upToDate && -
    • - -
    • } - {!syncInfo.localizedTexts.upToDate && -
    • - -
    • } - {!syncInfo.limits.upToDate && -
    • - -
    • } - {!syncInfo.scoreConfig.upToDate && -
    • - -
    • } - {!syncInfo.scoreCalculator.upToDate && -
    • - -
    • } - {!syncInfo.exerciseTests.upToDate && -
    • - -
    • } + {messages}

    @@ -107,6 +155,7 @@ const AssignmentSync = ({ syncInfo, exerciseSync }) => :

    ; +}; AssignmentSync.propTypes = { syncInfo: PropTypes.object.isRequired, diff --git a/src/components/Submissions/TestResultsTable/TestResultsTable.js b/src/components/Submissions/TestResultsTable/TestResultsTable.js index baafe8e8d..5a67f989e 100644 --- a/src/components/Submissions/TestResultsTable/TestResultsTable.js +++ b/src/components/Submissions/TestResultsTable/TestResultsTable.js @@ -11,7 +11,7 @@ import exitCodeMapping from '../../helpers/exitCodeMapping'; const hasValue = value => value !== null; -const tickOrCrossAndRatioOrValue = (isOK, ratio, value, pretty) => +const tickOrCrossAndRatioOrValue = (isOK, ratio, value, pretty, multiplier) => maximumFactionDigits={3} />} {hasValue(value) && ') '} - {hasValue(value) && pretty(value * 1000)} + {hasValue(value) && pretty(value * multiplier)} ; @@ -38,6 +38,7 @@ const TestResultsTable = ({ results, runtimeEnvironmentId }) => + - @@ -140,6 +141,9 @@ const TestResultsTable = ({ results, runtimeEnvironmentId }) => exitCode }) => + -
    - - } > - + @@ -83,12 +78,15 @@ const TestResultsTable = ({ results, runtimeEnvironmentId }) => } > - + +    + + @@ -98,12 +96,15 @@ const TestResultsTable = ({ results, runtimeEnvironmentId }) => } > - + +    + + @@ -118,7 +119,7 @@ const TestResultsTable = ({ results, runtimeEnvironmentId }) => } > - +
    + {testName} + - {testName} - {status === 'OK' && @@ -184,13 +185,15 @@ const TestResultsTable = ({ results, runtimeEnvironmentId }) => memoryExceeded === false, memoryRatio, memory, - prettyPrintBytes + prettyPrintBytes, + 1024 )} {tickOrCrossAndRatioOrValue( timeExceeded === false, timeRatio, time, - prettyMs + prettyMs, + 1000 )} diff --git a/src/components/forms/EditGroupForm/EditGroupForm.js b/src/components/forms/EditGroupForm/EditGroupForm.js index 938287880..c1d942202 100644 --- a/src/components/forms/EditGroupForm/EditGroupForm.js +++ b/src/components/forms/EditGroupForm/EditGroupForm.js @@ -163,6 +163,7 @@ const validate = ({ localizedTexts = [], threshold }) => { const errors = {}; if (threshold) { + threshold = String(threshold); const numericThreshold = Number(threshold); if (threshold !== Math.round(numericThreshold).toString()) { errors['threshold'] = ( @@ -254,5 +255,7 @@ const validate = ({ localizedTexts = [], threshold }) => { export default reduxForm({ form: 'editGroup', + enableReinitialize: true, + keepDirtyOnReinitialize: false, validate })(EditGroupForm); diff --git a/src/components/helpers/stringFormatters.js b/src/components/helpers/stringFormatters.js index 50623dd19..14b00805e 100644 --- a/src/components/helpers/stringFormatters.js +++ b/src/components/helpers/stringFormatters.js @@ -11,7 +11,9 @@ export function parseBytes(value) { absValue /= base; ++unit; } - const rounded = Math.round(absValue * 1000) / 1000; + const intDigits = Math.round(absValue).toString().length; + const fractionBase = intDigits > 3 ? 1 : Math.pow(10, 4 - intDigits); + const rounded = Math.round(absValue * fractionBase) / fractionBase; return { value: rounded.toString(), unit: units[unit] }; } diff --git a/src/locales/cs.json b/src/locales/cs.json index dd9956100..7bd6391a9 100644 --- a/src/locales/cs.json +++ b/src/locales/cs.json @@ -52,8 +52,9 @@ "app.assignment.runtimeEnvironmentsIds": "Povolené jazyky/frameworky/technologie:", "app.assignment.secondDeadline": "Druhý termín odevzdání:", "app.assignment.submissionsCountLimit": "Limit počtu odevzdaných řešení:", + "app.assignment.syncAttachmentFiles": "Text attachment files", "app.assignment.syncButton": "Update this assignment", - "app.assignment.syncConfigType": "Type of exercise configuration", + "app.assignment.syncConfigurationType": "Configuration was switched to advanced mode", "app.assignment.syncDescription": "The exercise for this assignment was updated in following categories:", "app.assignment.syncExerciseConfig": "Exercise configuration", "app.assignment.syncExerciseEnvironmentConfigs": "Environment configuration", @@ -61,9 +62,11 @@ "app.assignment.syncHardwareGroups": "Hardware groups", "app.assignment.syncLimits": "Limits", "app.assignment.syncLocalizedTexts": "Localized texts", - "app.assignment.syncRequired": "The exercise was updated!", + "app.assignment.syncRequired": "The exercise data are newer than assignment data. Exercise was updated {exerciseUpdated}, but the assignment was last updated {assignmentUpdated}!", + "app.assignment.syncRuntimeEnvironments": "Selection of runtime environments", "app.assignment.syncScoreCalculator": "Score calculator", "app.assignment.syncScoreConfig": "Score configuration", + "app.assignment.syncSupplementaryFiles": "Supplementary files", "app.assignment.title": "Zadání úlohy", "app.assignment.viewResults": "Zobrazit výsledky studenta", "app.assignmentStats.title": "Statistiky zadané úlohy", @@ -924,14 +927,13 @@ "app.submissionEvaluation.title": "Other submissions of this solution", "app.submissionStatus.accepted": "Toto řešení bylo připnuto cvičícím.", "app.submissions.testResultsTable.exitCode": "Exit code", - "app.submissions.testResultsTable.memoryExceeded": "Paměťový limit", + "app.submissions.testResultsTable.memoryExceeded": "Naměřená spotřeba paměti", "app.submissions.testResultsTable.overallTestResult": "Celkové výsledky testu", "app.submissions.testResultsTable.status": "Stav vyhodnocení", "app.submissions.testResultsTable.statusFailed": "Chyba", "app.submissions.testResultsTable.statusOK": "OK", "app.submissions.testResultsTable.statusSkipped": "Přeskočeno", - "app.submissions.testResultsTable.testName": "Název testu", - "app.submissions.testResultsTable.timeExceeded": "Časový limit", + "app.submissions.testResultsTable.timeExceeded": "Naměřený čas spuštění", "app.submissionsTable.failedLoading": "Nebylo možné načíst odevzdaná řešení.", "app.submissionsTable.loading": "Načítají se odezvdaná řešení ...", "app.submissionsTable.noSolutionsFound": "Zatím nebyla odevzdána žádná řešení.", diff --git a/src/locales/en.json b/src/locales/en.json index b05d29a5c..460f837f5 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -52,8 +52,9 @@ "app.assignment.runtimeEnvironmentsIds": "Allowed languages/frameworks/technologies:", "app.assignment.secondDeadline": "Second deadline:", "app.assignment.submissionsCountLimit": "Submission count limit:", + "app.assignment.syncAttachmentFiles": "Text attachment files", "app.assignment.syncButton": "Update this assignment", - "app.assignment.syncConfigType": "Type of exercise configuration", + "app.assignment.syncConfigurationType": "Configuration was switched to advanced mode", "app.assignment.syncDescription": "The exercise for this assignment was updated in following categories:", "app.assignment.syncExerciseConfig": "Exercise configuration", "app.assignment.syncExerciseEnvironmentConfigs": "Environment configuration", @@ -61,9 +62,11 @@ "app.assignment.syncHardwareGroups": "Hardware groups", "app.assignment.syncLimits": "Limits", "app.assignment.syncLocalizedTexts": "Localized texts", - "app.assignment.syncRequired": "The exercise was updated!", + "app.assignment.syncRequired": "The exercise data are newer than assignment data. Exercise was updated {exerciseUpdated}, but the assignment was last updated {assignmentUpdated}!", + "app.assignment.syncRuntimeEnvironments": "Selection of runtime environments", "app.assignment.syncScoreCalculator": "Score calculator", "app.assignment.syncScoreConfig": "Score configuration", + "app.assignment.syncSupplementaryFiles": "Supplementary files", "app.assignment.title": "Exercise assignment", "app.assignment.viewResults": "View student results", "app.assignmentStats.title": "Assignment statistics", @@ -924,14 +927,13 @@ "app.submissionEvaluation.title": "Other submissions of this solution", "app.submissionStatus.accepted": "This solution was marked by one of the supervisors as accepted.", "app.submissions.testResultsTable.exitCode": "Exit code", - "app.submissions.testResultsTable.memoryExceeded": "Memory limit", + "app.submissions.testResultsTable.memoryExceeded": "Measured memory utilization", "app.submissions.testResultsTable.overallTestResult": "Overall test result", "app.submissions.testResultsTable.status": "Evaluation status", "app.submissions.testResultsTable.statusFailed": "FAILED", "app.submissions.testResultsTable.statusOK": "OK", "app.submissions.testResultsTable.statusSkipped": "SKIPPED", - "app.submissions.testResultsTable.testName": "Test name", - "app.submissions.testResultsTable.timeExceeded": "Time limit", + "app.submissions.testResultsTable.timeExceeded": "Measured execution time", "app.submissionsTable.failedLoading": "Could not load this submission.", "app.submissionsTable.loading": "Loading submitted solutions ...", "app.submissionsTable.noSolutionsFound": "No solutions were submitted yet.", diff --git a/src/pages/EditGroup/EditGroup.js b/src/pages/EditGroup/EditGroup.js index d8e71c7a8..5e786398e 100644 --- a/src/pages/EditGroup/EditGroup.js +++ b/src/pages/EditGroup/EditGroup.js @@ -31,7 +31,7 @@ class EditGroup extends Component { getInitialValues = ({ threshold, ...group }) => ({ ...group, - threshold: threshold * 100 + threshold: String(threshold * 100) }); render() {