diff --git a/src/components/forms/EditEnvironmentSimpleForm/EditEnvironmentList.js b/src/components/forms/EditEnvironmentSimpleForm/EditEnvironmentList.js index 76a31bc17..95f0838ac 100644 --- a/src/components/forms/EditEnvironmentSimpleForm/EditEnvironmentList.js +++ b/src/components/forms/EditEnvironmentSimpleForm/EditEnvironmentList.js @@ -24,7 +24,7 @@ const EditEnvironmentList = ({ {runtimeEnvironments .sort((a, b) => a.longName.localeCompare(b.longName, locale)) .map(environment => ( - + - + - + - + } /> - + - + - + - + ; export const OutputIcon = props => ; export const PipelineIcon = props => ; +export const PipelineStructureIcon = props => ; export const PointsDecreasedIcon = props => ; export const PointsGraphIcon = props => ; export const PointsInterpolationIcon = props => ( diff --git a/src/components/layout/Navigation/PipelineNavigation.js b/src/components/layout/Navigation/PipelineNavigation.js index 275293778..4cf35b51a 100644 --- a/src/components/layout/Navigation/PipelineNavigation.js +++ b/src/components/layout/Navigation/PipelineNavigation.js @@ -4,13 +4,13 @@ import { FormattedMessage } from 'react-intl'; import Navigation from './Navigation'; import withLinks from '../../../helpers/withLinks'; -import { PipelineIcon, EditIcon } from '../../icons'; +import { PipelineIcon, PipelineStructureIcon, EditIcon } from '../../icons'; const PipelineNavigation = ({ pipelineId, canViewDetail = false, canEdit = false, - links: { PIPELINE_URI_FACTORY, PIPELINE_EDIT_URI_FACTORY }, + links: { PIPELINE_URI_FACTORY, PIPELINE_EDIT_URI_FACTORY, PIPELINE_EDIT_STRUCT_URI_FACTORY }, }) => ( , }, + canEdit && { + caption: , + link: PIPELINE_EDIT_STRUCT_URI_FACTORY(pipelineId), + icon: , + }, ]} /> ); diff --git a/src/locales/cs.json b/src/locales/cs.json index e645c895a..0012e836d 100644 --- a/src/locales/cs.json +++ b/src/locales/cs.json @@ -480,7 +480,7 @@ "app.editPipeline.deleteWarning": "Smazání pipeline rozbije všechny úlohy, které ji používají.", "app.editPipeline.disclaimer": "Upozornění", "app.editPipeline.disclaimerWarning": "Upravení pipeline může rozbít všechny úlohy, které pipeline používají!", - "app.editPipeline.title": "Změnit nastavení a obsah pipeline", + "app.editPipeline.title": "Změnit nastavení pipeline", "app.editPipelineEnvironmentsForm.title": "Běhová prostředí pipeline", "app.editPipelineForm.description": "Podrobnější popis (pro autory úloh):", "app.editPipelineForm.global": "Globalní pipeline spojená s konkrétními běhovými prostředími", @@ -495,6 +495,7 @@ "app.editPipelineForm.title": "Metadata pipeline", "app.editPipelineForm.validation.description": "Prosíme vyplňte popis této pipeline.", "app.editPipelineForm.validation.emptyName": "Prosíme vyplňte název této pipeline.", + "app.editPipelineStructure.title": "Upravit strukturu pipeline", "app.editShadowAssignment.deleteAssignment": "Smazat stínovou úlohu", "app.editShadowAssignment.deleteAssignmentWarning": "Smazání stínové úlohy rovněž odstraní body přidělené studentům.", "app.editShadowAssignment.title": "Změnit nastavení stínové úlohy", @@ -1074,6 +1075,7 @@ "app.navigation.groupAssignments": "Úlohy ve skupině", "app.navigation.groupInfo": "Info skupiny", "app.navigation.pipeline": "Pipeline", + "app.navigation.pipelineStructure": "Struktura", "app.navigation.referenceSolution": "Referenční řešení", "app.navigation.shadowAssignment": "Stínová úloha", "app.navigation.solution": "Řešení", diff --git a/src/locales/en.json b/src/locales/en.json index c70d8a85d..8f4612950 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -480,7 +480,7 @@ "app.editPipeline.deleteWarning": "Deleting an pipeline will break all exercises using the pipeline.", "app.editPipeline.disclaimer": "Disclaimer", "app.editPipeline.disclaimerWarning": "Modifying the pipeline might break all exercises using the pipeline!", - "app.editPipeline.title": "Change Pipeline Settings and Contents", + "app.editPipeline.title": "Update Pipeline Settings", "app.editPipelineEnvironmentsForm.title": "Pipeline Runtime Environments", "app.editPipelineForm.description": "Detailed description (for exercise authors):", "app.editPipelineForm.global": "Global pipeline associated with particular runtime environments", @@ -495,6 +495,7 @@ "app.editPipelineForm.title": "Pipeline Metadata", "app.editPipelineForm.validation.description": "Please fill the description of the pipeline.", "app.editPipelineForm.validation.emptyName": "Please fill the name of the pipeline.", + "app.editPipelineStructure.title": "Modify Pipeline Structure", "app.editShadowAssignment.deleteAssignment": "Delete the shadow assignment", "app.editShadowAssignment.deleteAssignmentWarning": "Deleting shadow assignment will remove all student points as well.", "app.editShadowAssignment.title": "Change Shadow Assignment Settings", @@ -1074,6 +1075,7 @@ "app.navigation.groupAssignments": "Group Assignments", "app.navigation.groupInfo": "Group Info", "app.navigation.pipeline": "Pipeline", + "app.navigation.pipelineStructure": "Structure", "app.navigation.referenceSolution": "Reference Solution", "app.navigation.shadowAssignment": "Shadow Assignment", "app.navigation.solution": "Solution", diff --git a/src/pages/EditPipeline/EditPipeline.js b/src/pages/EditPipeline/EditPipeline.js index 0e560794c..004256c8d 100644 --- a/src/pages/EditPipeline/EditPipeline.js +++ b/src/pages/EditPipeline/EditPipeline.js @@ -14,9 +14,7 @@ import Callout from '../../components/widgets/Callout'; import EditPipelineForm from '../../components/forms/EditPipelineForm'; import EditPipelineEnvironmentsForm from '../../components/forms/EditPipelineEnvironmentsForm'; import { EditIcon } from '../../components/icons'; -import PipelineFilesTableContainer from '../../containers/PipelineFilesTableContainer'; import DeletePipelineButtonContainer from '../../containers/DeletePipelineButtonContainer'; -import PipelineEditContainer from '../../containers/PipelineEditContainer'; import ResourceRenderer from '../../components/helpers/ResourceRenderer'; import { fetchPipelineIfNeeded, editPipeline, setPipelineRuntimeEnvironments } from '../../redux/modules/pipelines'; @@ -113,7 +111,7 @@ class EditPipeline extends Component { } - title={}> + title={}> {pipeline => ( <> - - - - - - - -
- - - - - - + {isSuperadmin && ( @@ -174,12 +159,6 @@ class EditPipeline extends Component { - - - - - - this.props.loadAsync(); + + componentDidUpdate(prevProps) { + if (this.props.match.params.pipelineId !== prevProps.match.params.pipelineId) { + this.props.loadAsync(); + } + } + + static loadAsync = ({ pipelineId }, dispatch) => + Promise.all([ + dispatch(fetchPipelineIfNeeded(pipelineId)), + dispatch(fetchRuntimeEnvironments()), + dispatch(fetchBoxTypes()), + ]); + + render() { + const { pipeline } = this.props; + + return ( + } + title={}> + {pipeline => ( + <> + + + + + +

+ +

+

+ +

+
+ +
+ + + + + + + + + + + + + + )} +
+ ); + } +} + +EditPipeline.propTypes = { + pipeline: ImmutablePropTypes.map, + loadAsync: PropTypes.func.isRequired, + match: PropTypes.shape({ + params: PropTypes.shape({ + pipelineId: PropTypes.string.isRequired, + }).isRequired, + }).isRequired, +}; + +export default connect( + ( + state, + { + match: { + params: { pipelineId }, + }, + } + ) => { + return { + pipeline: getPipeline(pipelineId)(state), + }; + }, + ( + dispatch, + { + match: { + params: { pipelineId }, + }, + } + ) => ({ + loadAsync: () => EditPipeline.loadAsync({ pipelineId }, dispatch), + }) +)(EditPipeline); diff --git a/src/pages/EditPipelineStructure/index.js b/src/pages/EditPipelineStructure/index.js new file mode 100644 index 000000000..0e7b45478 --- /dev/null +++ b/src/pages/EditPipelineStructure/index.js @@ -0,0 +1,2 @@ +import EditPipelineStructure from './EditPipelineStructure'; +export default EditPipelineStructure; diff --git a/src/pages/routes.js b/src/pages/routes.js index bd5cd6e93..0c87dc767 100644 --- a/src/pages/routes.js +++ b/src/pages/routes.js @@ -4,46 +4,47 @@ import { defaultMemoize } from 'reselect'; /* container components */ import App from '../containers/App'; +import Archive from './Archive'; +import Assignment from './Assignment'; +import AssignmentStats from './AssignmentStats'; +import ChangePassword from './ChangePassword'; import Dashboard from './Dashboard'; -import Home from './Home'; +import EditAssignment from './EditAssignment'; +import EditExercise from './EditExercise'; +import EditExerciseConfig from './EditExerciseConfig'; +import EditExerciseLimits from './EditExerciseLimits'; +import EditGroup from './EditGroup'; +import EditInstances from './EditInstance'; +import EditPipeline from './EditPipeline'; +import EditPipelineStructure from './EditPipelineStructure'; +import EditShadowAssignment from './EditShadowAssignment'; +import EditUser from './EditUser'; import EmailVerification from './EmailVerification'; import Exercise from './Exercise'; import ExerciseAssignments from './ExerciseAssignments'; import Exercises from './Exercises'; -import EditExercise from './EditExercise'; -import EditExerciseConfig from './EditExerciseConfig'; -import EditExerciseLimits from './EditExerciseLimits'; +import FAQ from './FAQ'; import GroupDetail from './GroupDetail'; import GroupInfo from './GroupInfo'; import GroupUserSolutions from './GroupUserSolutions'; -import EditGroup from './EditGroup'; +import Home from './Home'; import Instance from './Instance'; import Instances from './Instances'; -import EditInstances from './EditInstance'; import Login from './Login'; -import Assignment from './Assignment'; -import EditAssignment from './EditAssignment'; -import AssignmentStats from './AssignmentStats'; -import ShadowAssignment from './ShadowAssignment'; -import EditShadowAssignment from './EditShadowAssignment'; import NotFound from './NotFound'; -import Solution from './Solution'; -import Registration from './Registration'; -import Users from './Users'; -import User from './User'; -import EditUser from './EditUser'; -import ReferenceSolution from './ReferenceSolution'; -import Pipelines from './Pipelines'; -import EditPipeline from './EditPipeline'; import Pipeline from './Pipeline'; -import FAQ from './FAQ'; -import SubmissionFailures from './SubmissionFailures'; -import SisIntegration from './SisIntegration'; -import Archive from './Archive'; -import SystemMessages from './SystemMessages/SystemMessages'; -import ChangePassword from './ChangePassword'; +import Pipelines from './Pipelines'; +import ReferenceSolution from './ReferenceSolution'; +import Registration from './Registration'; import ResetPassword from './ResetPassword'; import ServerManagement from './ServerManagement'; +import ShadowAssignment from './ShadowAssignment'; +import SisIntegration from './SisIntegration'; +import Solution from './Solution'; +import SubmissionFailures from './SubmissionFailures'; +import SystemMessages from './SystemMessages/SystemMessages'; +import User from './User'; +import Users from './Users'; import { LOGIN_URI_PREFIX, createLoginLinkWithRedirect } from '../redux/helpers/api/tools'; import { API_BASE, URL_PATH_PREFIX } from '../helpers/config'; @@ -97,6 +98,7 @@ const routesDescriptors = [ r('app/pipelines', Pipelines, 'PIPELINES_URI', true), r('app/pipelines/:pipelineId', Pipeline, 'PIPELINE_URI_FACTORY', true), r('app/pipelines/:pipelineId/edit', EditPipeline, 'PIPELINE_EDIT_URI_FACTORY', true), + r('app/pipelines/:pipelineId/edit-struct', EditPipelineStructure, 'PIPELINE_EDIT_STRUCT_URI_FACTORY', true), r('app/group/:groupId/edit', EditGroup, 'GROUP_EDIT_URI_FACTORY', true), r('app/group/:groupId/info', GroupInfo, 'GROUP_INFO_URI_FACTORY', true), r('app/group/:groupId/detail', GroupDetail, 'GROUP_DETAIL_URI_FACTORY', true),