Skip to content

Commit

Permalink
Creating a separate page with all source code files of a solution dis…
Browse files Browse the repository at this point in the history
…played at once.
  • Loading branch information
krulis-martin committed Sep 12, 2022
1 parent add9c9a commit 7613028
Show file tree
Hide file tree
Showing 10 changed files with 321 additions and 14 deletions.
4 changes: 3 additions & 1 deletion src/components/helpers/syntaxHighlighting.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,14 @@ const prismMapping = {
h: 'cpp',
hpp: 'cpp',
hs: 'haskell',
html: 'cshtml',
html: 'markup',
ino: 'arduino',
pl: 'prolog',
sh: 'bash',
sql: 'sql',
svg: 'markup',
y: 'bison',
xml: 'markup',
};

export const getAceModeFromExtension = createExtensionTranslator(aceMapping);
Expand Down
18 changes: 17 additions & 1 deletion src/components/layout/Navigation/AssignmentSolutionNavigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@ import { FormattedMessage } from 'react-intl';

import Navigation from './Navigation';
import withLinks from '../../../helpers/withLinks';
import { AssignmentIcon, ExerciseIcon, ResultsIcon, SolutionResultsIcon, UserIcon, UserProfileIcon } from '../../icons';
import {
AssignmentIcon,
CodeFileIcon,
ExerciseIcon,
ResultsIcon,
SolutionResultsIcon,
UserIcon,
UserProfileIcon,
} from '../../icons';
import { createGroupLinks } from './linkCreators';

const AssignmentSolutionNavigation = ({
Expand All @@ -13,6 +21,7 @@ const AssignmentSolutionNavigation = ({
exerciseId = null,
userId,
groupId,
attemptIndex = null,
canViewSolutions = false,
canViewExercise = false,
canViewUserProfile = false,
Expand All @@ -21,12 +30,18 @@ const AssignmentSolutionNavigation = ({
<Navigation
assignmentId={assignmentId}
userId={userId}
titlePrefix={attemptIndex ? `#${attemptIndex}` : null}
links={[
{
caption: <FormattedMessage id="app.navigation.solution" defaultMessage="Solution" />,
link: links.SOLUTION_DETAIL_URI_FACTORY(assignmentId, solutionId),
icon: <SolutionResultsIcon gapRight />,
},
{
caption: <FormattedMessage id="app.navigation.solutionFiles" defaultMessage="Submitted Files" />,
link: links.SOLUTION_SOURCE_CODES_URI_FACTORY(assignmentId, solutionId),
icon: <CodeFileIcon gapRight />,
},
{
caption: <FormattedMessage id="app.navigation.userSolution" defaultMessage="User Solutions" />,
link: links.GROUP_USER_SOLUTIONS_URI_FACTORY(groupId, userId),
Expand Down Expand Up @@ -66,6 +81,7 @@ AssignmentSolutionNavigation.propTypes = {
exerciseId: PropTypes.string,
userId: PropTypes.string.isRequired,
groupId: PropTypes.string.isRequired,
attemptIndex: PropTypes.number,
canViewSolutions: PropTypes.bool,
canViewExercise: PropTypes.bool,
canViewUserProfile: PropTypes.bool,
Expand Down
8 changes: 8 additions & 0 deletions src/components/layout/Navigation/Navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ const Navigation = ({
links,
secondaryLinks,
location,
titlePrefix = null,
titleSuffix = null,
}) => {
links = Array.isArray(links) ? links.filter(link => link) : [];
secondaryLinks = Array.isArray(secondaryLinks) ? secondaryLinks.filter(link => link) : [];
Expand All @@ -77,6 +79,8 @@ const Navigation = ({
</div>
)}

{titlePrefix && <span>{titlePrefix}</span>}

{groupId && (
<span>
<OverlayTrigger
Expand Down Expand Up @@ -161,6 +165,8 @@ const Navigation = ({
showRoleIcon={onlyUser}
/>
)}

{titleSuffix && <span>{titleSuffix}</span>}
</Card.Title>
</Card.Header>

Expand Down Expand Up @@ -193,6 +199,8 @@ Navigation.propTypes = {
pathname: PropTypes.string.isRequired,
search: PropTypes.string.isRequired,
}).isRequired,
titlePrefix: PropTypes.oneOfType([PropTypes.element, PropTypes.string]),
titleSuffix: PropTypes.oneOfType([PropTypes.element, PropTypes.string]),
};

export default withRouter(Navigation);
4 changes: 4 additions & 0 deletions src/locales/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -1094,6 +1094,7 @@
"app.navigation.referenceSolution": "Referenční řešení",
"app.navigation.shadowAssignment": "Stínová úloha",
"app.navigation.solution": "Řešení",
"app.navigation.solutionFiles": "Odevzdané soubory",
"app.navigation.user": "Uživatel",
"app.navigation.userProfile": "Uživatelský profil",
"app.navigation.userSolution": "Všechna řešení uživatele",
Expand Down Expand Up @@ -1596,6 +1597,9 @@
"app.solutionFiles.sizeLimitExceeded": "Celková velikost všech odevzdaných souborů překročila výchozí limit ({limit} KiB).",
"app.solutionFiles.title": "Odevzdané soubory",
"app.solutionFiles.total": "Celkem:",
"app.solutionSourceCodes.malformedTooltip": "Tento soubor neobsahuje běžný text v kódování UTF-8, takže není možne jej zobrazit jako zdrojový kód.",
"app.solutionSourceCodes.title": "Přehled odevzdaných zdrojových souborů řešení",
"app.solutionSourceCodes.tooLargeTooltip": "Soubor je příliš velký pro zobrazení náhledu, a proto byl oříznut.",
"app.solutionsTable.assignment": "Úloha",
"app.solutionsTable.attemptsCount": "Odevzdaných řešení: {count}",
"app.solutionsTable.attemptsDeleted": "{deleted} {deleted, plural, =2 {smazána} =3 {smazána} =4 {smazána} other {smazáno}}",
Expand Down
4 changes: 4 additions & 0 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1094,6 +1094,7 @@
"app.navigation.referenceSolution": "Reference Solution",
"app.navigation.shadowAssignment": "Shadow Assignment",
"app.navigation.solution": "Solution",
"app.navigation.solutionFiles": "Submitted Files",
"app.navigation.user": "User",
"app.navigation.userProfile": "User's Profile",
"app.navigation.userSolution": "User Solutions",
Expand Down Expand Up @@ -1596,6 +1597,9 @@
"app.solutionFiles.sizeLimitExceeded": "The total size of all submitted files exceeds the default solution size limit ({limit} KiB).",
"app.solutionFiles.title": "Submitted Files",
"app.solutionFiles.total": "Total:",
"app.solutionSourceCodes.malformedTooltip": "The file is not a valid UTF-8 text file so it cannot be properly displayed as a source code.",
"app.solutionSourceCodes.title": "Solution Source Code Files Overview",
"app.solutionSourceCodes.tooLargeTooltip": "The file is too large for code preview and it was cropped.",
"app.solutionsTable.assignment": "Assignment",
"app.solutionsTable.attemptsCount": "Solutions submitted: {count}",
"app.solutionsTable.attemptsDeleted": "{deleted} deleted",
Expand Down
23 changes: 11 additions & 12 deletions src/pages/Solution/Solution.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ class Solution extends Component {
exerciseId={assignment.exerciseId}
userId={solution.authorId}
groupId={assignment.groupId}
attemptIndex={solution.attemptIndex}
canViewSolutions={hasPermissions(assignment, 'viewAssignmentSolutions')}
canViewExercise={
hasPermissions(
Expand Down Expand Up @@ -153,18 +154,16 @@ class Solution extends Component {
)}
</TheButtonGroup>

{!(
hasPermissions(assignment, 'resubmitSubmissions') &&
assignmentHasRuntime(assignment, solution.runtimeEnvironmentId)
) && (
<span>
<WarningIcon largeGapLeft gapRight className="text-warning" />
<FormattedMessage
id="app.solution.environmentNotAllowedCannotResubmit"
defaultMessage="The assignment no longer supports the environment for which this solution was evaluated. Resubmission is not possible."
/>
</span>
)}
{hasPermissions(assignment, 'resubmitSubmissions') &&
!assignmentHasRuntime(assignment, solution.runtimeEnvironmentId) && (
<span>
<WarningIcon largeGapLeft gapRight className="text-warning" />
<FormattedMessage
id="app.solution.environmentNotAllowedCannotResubmit"
defaultMessage="The assignment no longer supports the environment for which this solution was evaluated. Resubmission is not possible."
/>
</span>
)}
</div>
)}
<ResourceRenderer resource={runtimeEnvironments} returnAsArray>
Expand Down
Loading

0 comments on commit 7613028

Please sign in to comment.