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),