Skip to content

Commit 27d4f1d

Browse files
committed
The pipeline edit page was cleft in twain (metadata and structure).
1 parent ce36e76 commit 27d4f1d

File tree

10 files changed

+178
-64
lines changed

10 files changed

+178
-64
lines changed

src/components/forms/EditEnvironmentSimpleForm/EditEnvironmentList.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const EditEnvironmentList = ({
2424
{runtimeEnvironments
2525
.sort((a, b) => a.longName.localeCompare(b.longName, locale))
2626
.map(environment => (
27-
<Col key={environment.id} xs={12} sm={6} md={fullWidth ? 4 : 6} lg={fullWidth ? 3 : 6}>
27+
<Col key={environment.id} sm={12} md={fullWidth ? 6 : 12} lg={fullWidth ? 4 : 12} xl={fullWidth ? 3 : 6}>
2828
<Field
2929
name={`${namePrefix}${environment.id}`}
3030
component={CheckboxField}

src/components/forms/EditPipelineForm/EditPipelineForm.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ class EditPipelineForm extends Component {
9090
<hr className="mt-0" />
9191

9292
<Row>
93-
<Col xl={4} lg={6} md={12}>
93+
<Col xl={6} lg={12}>
9494
<Field
9595
name="parameters.isCompilationPipeline"
9696
component={CheckboxField}
@@ -100,7 +100,7 @@ class EditPipelineForm extends Component {
100100
}
101101
/>
102102
</Col>
103-
<Col xl={4} lg={6} md={12}>
103+
<Col xl={6} lg={12}>
104104
<Field
105105
name="parameters.isExecutionPipeline"
106106
component={CheckboxField}
@@ -110,15 +110,15 @@ class EditPipelineForm extends Component {
110110
}
111111
/>
112112
</Col>
113-
<Col xl={4} lg={6} md={12}>
113+
<Col xl={6} lg={12}>
114114
<Field
115115
name="parameters.judgeOnlyPipeline"
116116
component={CheckboxField}
117117
onOff
118118
label={<FormattedMessage id="app.editPipelineForm.judgeOnlyPipeline" defaultMessage="Judge-Only" />}
119119
/>
120120
</Col>
121-
<Col xl={4} lg={6} md={12}>
121+
<Col xl={6} lg={12}>
122122
<Field
123123
name="parameters.producesStdout"
124124
component={CheckboxField}
@@ -128,7 +128,7 @@ class EditPipelineForm extends Component {
128128
}
129129
/>
130130
</Col>
131-
<Col xl={4} lg={6} md={12}>
131+
<Col xl={6} lg={12}>
132132
<Field
133133
name="parameters.producesFiles"
134134
component={CheckboxField}
@@ -141,7 +141,7 @@ class EditPipelineForm extends Component {
141141
}
142142
/>
143143
</Col>
144-
<Col xl={4} lg={6} md={12}>
144+
<Col xl={6} lg={12}>
145145
<Field
146146
name="parameters.hasEntryPoint"
147147
component={CheckboxField}
@@ -151,7 +151,7 @@ class EditPipelineForm extends Component {
151151
}
152152
/>
153153
</Col>
154-
<Col xl={4} lg={6} md={12}>
154+
<Col xl={6} lg={12}>
155155
<Field
156156
name="parameters.hasExtraFiles"
157157
component={CheckboxField}

src/components/icons/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ export const NoteIcon = props => <Icon {...props} icon={['far', 'sticky-note']}
7070
export const ObserverIcon = props => <Icon {...props} icon="binoculars" />;
7171
export const OutputIcon = props => <Icon {...props} icon="sign-out-alt" />;
7272
export const PipelineIcon = props => <Icon {...props} icon="random" />;
73+
export const PipelineStructureIcon = props => <Icon {...props} icon="sitemap" />;
7374
export const PointsDecreasedIcon = props => <Icon icon="level-down-alt" className="text-muted" {...props} />;
7475
export const PointsGraphIcon = props => <Icon icon={['far', 'chart-bar']} {...props} />;
7576
export const PointsInterpolationIcon = props => (

src/components/layout/Navigation/PipelineNavigation.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ import { FormattedMessage } from 'react-intl';
44

55
import Navigation from './Navigation';
66
import withLinks from '../../../helpers/withLinks';
7-
import { PipelineIcon, EditIcon } from '../../icons';
7+
import { PipelineIcon, PipelineStructureIcon, EditIcon } from '../../icons';
88

99
const PipelineNavigation = ({
1010
pipelineId,
1111
canViewDetail = false,
1212
canEdit = false,
13-
links: { PIPELINE_URI_FACTORY, PIPELINE_EDIT_URI_FACTORY },
13+
links: { PIPELINE_URI_FACTORY, PIPELINE_EDIT_URI_FACTORY, PIPELINE_EDIT_STRUCT_URI_FACTORY },
1414
}) => (
1515
<Navigation
1616
pipelineId={pipelineId}
@@ -25,6 +25,11 @@ const PipelineNavigation = ({
2525
link: PIPELINE_EDIT_URI_FACTORY(pipelineId),
2626
icon: <EditIcon gapRight />,
2727
},
28+
canEdit && {
29+
caption: <FormattedMessage id="app.navigation.pipelineStructure" defaultMessage="Structure" />,
30+
link: PIPELINE_EDIT_STRUCT_URI_FACTORY(pipelineId),
31+
icon: <PipelineStructureIcon gapRight />,
32+
},
2833
]}
2934
/>
3035
);

src/locales/cs.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@
480480
"app.editPipeline.deleteWarning": "Smazání pipeline rozbije všechny úlohy, které ji používají.",
481481
"app.editPipeline.disclaimer": "Upozornění",
482482
"app.editPipeline.disclaimerWarning": "Upravení pipeline může rozbít všechny úlohy, které pipeline používají!",
483-
"app.editPipeline.title": "Změnit nastavení a obsah pipeline",
483+
"app.editPipeline.title": "Změnit nastavení pipeline",
484484
"app.editPipelineEnvironmentsForm.title": "Běhová prostředí pipeline",
485485
"app.editPipelineForm.description": "Podrobnější popis (pro autory úloh):",
486486
"app.editPipelineForm.global": "Globalní pipeline spojená s konkrétními běhovými prostředími",
@@ -495,6 +495,7 @@
495495
"app.editPipelineForm.title": "Metadata pipeline",
496496
"app.editPipelineForm.validation.description": "Prosíme vyplňte popis této pipeline.",
497497
"app.editPipelineForm.validation.emptyName": "Prosíme vyplňte název této pipeline.",
498+
"app.editPipelineStructure.title": "Upravit strukturu pipeline",
498499
"app.editShadowAssignment.deleteAssignment": "Smazat stínovou úlohu",
499500
"app.editShadowAssignment.deleteAssignmentWarning": "Smazání stínové úlohy rovněž odstraní body přidělené studentům.",
500501
"app.editShadowAssignment.title": "Změnit nastavení stínové úlohy",
@@ -1074,6 +1075,7 @@
10741075
"app.navigation.groupAssignments": "Úlohy ve skupině",
10751076
"app.navigation.groupInfo": "Info skupiny",
10761077
"app.navigation.pipeline": "Pipeline",
1078+
"app.navigation.pipelineStructure": "Struktura",
10771079
"app.navigation.referenceSolution": "Referenční řešení",
10781080
"app.navigation.shadowAssignment": "Stínová úloha",
10791081
"app.navigation.solution": "Řešení",

src/locales/en.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@
480480
"app.editPipeline.deleteWarning": "Deleting an pipeline will break all exercises using the pipeline.",
481481
"app.editPipeline.disclaimer": "Disclaimer",
482482
"app.editPipeline.disclaimerWarning": "Modifying the pipeline might break all exercises using the pipeline!",
483-
"app.editPipeline.title": "Change Pipeline Settings and Contents",
483+
"app.editPipeline.title": "Update Pipeline Settings",
484484
"app.editPipelineEnvironmentsForm.title": "Pipeline Runtime Environments",
485485
"app.editPipelineForm.description": "Detailed description (for exercise authors):",
486486
"app.editPipelineForm.global": "Global pipeline associated with particular runtime environments",
@@ -495,6 +495,7 @@
495495
"app.editPipelineForm.title": "Pipeline Metadata",
496496
"app.editPipelineForm.validation.description": "Please fill the description of the pipeline.",
497497
"app.editPipelineForm.validation.emptyName": "Please fill the name of the pipeline.",
498+
"app.editPipelineStructure.title": "Modify Pipeline Structure",
498499
"app.editShadowAssignment.deleteAssignment": "Delete the shadow assignment",
499500
"app.editShadowAssignment.deleteAssignmentWarning": "Deleting shadow assignment will remove all student points as well.",
500501
"app.editShadowAssignment.title": "Change Shadow Assignment Settings",
@@ -1074,6 +1075,7 @@
10741075
"app.navigation.groupAssignments": "Group Assignments",
10751076
"app.navigation.groupInfo": "Group Info",
10761077
"app.navigation.pipeline": "Pipeline",
1078+
"app.navigation.pipelineStructure": "Structure",
10771079
"app.navigation.referenceSolution": "Reference Solution",
10781080
"app.navigation.shadowAssignment": "Shadow Assignment",
10791081
"app.navigation.solution": "Solution",

src/pages/EditPipeline/EditPipeline.js

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@ import Callout from '../../components/widgets/Callout';
1414
import EditPipelineForm from '../../components/forms/EditPipelineForm';
1515
import EditPipelineEnvironmentsForm from '../../components/forms/EditPipelineEnvironmentsForm';
1616
import { EditIcon } from '../../components/icons';
17-
import PipelineFilesTableContainer from '../../containers/PipelineFilesTableContainer';
1817
import DeletePipelineButtonContainer from '../../containers/DeletePipelineButtonContainer';
19-
import PipelineEditContainer from '../../containers/PipelineEditContainer';
2018
import ResourceRenderer from '../../components/helpers/ResourceRenderer';
2119

2220
import { fetchPipelineIfNeeded, editPipeline, setPipelineRuntimeEnvironments } from '../../redux/modules/pipelines';
@@ -113,7 +111,7 @@ class EditPipeline extends Component {
113111
<Page
114112
resource={pipeline}
115113
icon={<EditIcon />}
116-
title={<FormattedMessage id="app.editPipeline.title" defaultMessage="Change Pipeline Settings and Contents" />}>
114+
title={<FormattedMessage id="app.editPipeline.title" defaultMessage="Update Pipeline Settings" />}>
117115
{pipeline => (
118116
<>
119117
<PipelineNavigation
@@ -139,25 +137,12 @@ class EditPipeline extends Component {
139137
</Row>
140138

141139
<Row>
142-
<Col lg={12}>
143-
<Row>
144-
<Col lg={12}>
145-
<EditPipelineForm
146-
initialValues={perpareInitialPipelineData(pipeline)}
147-
onSubmit={this.savePipeline}
148-
isSuperadmin={isSuperadmin}
149-
/>
150-
</Col>
151-
</Row>
152-
</Col>
153140
<Col lg={6}>
154-
<div />
155-
</Col>
156-
</Row>
157-
158-
<Row>
159-
<Col lg={6}>
160-
<PipelineFilesTableContainer pipeline={pipeline} />
141+
<EditPipelineForm
142+
initialValues={perpareInitialPipelineData(pipeline)}
143+
onSubmit={this.savePipeline}
144+
isSuperadmin={isSuperadmin}
145+
/>
161146
</Col>
162147
<Col lg={6}>
163148
{isSuperadmin && (
@@ -174,12 +159,6 @@ class EditPipeline extends Component {
174159
</Col>
175160
</Row>
176161

177-
<Row>
178-
<Col lg={12}>
179-
<PipelineEditContainer pipeline={pipeline} />
180-
</Col>
181-
</Row>
182-
183162
<Row>
184163
<Col lg={12}>
185164
<Box
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import React, { Component } from 'react';
2+
import PropTypes from 'prop-types';
3+
import ImmutablePropTypes from 'react-immutable-proptypes';
4+
import { FormattedMessage } from 'react-intl';
5+
import { Row, Col } from 'react-bootstrap';
6+
import { connect } from 'react-redux';
7+
8+
import Page from '../../components/layout/Page';
9+
import { PipelineNavigation } from '../../components/layout/Navigation';
10+
import Callout from '../../components/widgets/Callout';
11+
import { PipelineStructureIcon } from '../../components/icons';
12+
import PipelineFilesTableContainer from '../../containers/PipelineFilesTableContainer';
13+
import PipelineEditContainer from '../../containers/PipelineEditContainer';
14+
15+
import { fetchPipelineIfNeeded } from '../../redux/modules/pipelines';
16+
import { fetchBoxTypes } from '../../redux/modules/boxes';
17+
import { fetchRuntimeEnvironments } from '../../redux/modules/runtimeEnvironments';
18+
import { getPipeline } from '../../redux/selectors/pipelines';
19+
20+
import { hasPermissions } from '../../helpers/common';
21+
22+
class EditPipeline extends Component {
23+
componentDidMount = () => this.props.loadAsync();
24+
25+
componentDidUpdate(prevProps) {
26+
if (this.props.match.params.pipelineId !== prevProps.match.params.pipelineId) {
27+
this.props.loadAsync();
28+
}
29+
}
30+
31+
static loadAsync = ({ pipelineId }, dispatch) =>
32+
Promise.all([
33+
dispatch(fetchPipelineIfNeeded(pipelineId)),
34+
dispatch(fetchRuntimeEnvironments()),
35+
dispatch(fetchBoxTypes()),
36+
]);
37+
38+
render() {
39+
const { pipeline } = this.props;
40+
41+
return (
42+
<Page
43+
resource={pipeline}
44+
icon={<PipelineStructureIcon />}
45+
title={<FormattedMessage id="app.editPipelineStructure.title" defaultMessage="Modify Pipeline Structure" />}>
46+
{pipeline => (
47+
<>
48+
<PipelineNavigation
49+
pipelineId={pipeline.id}
50+
canViewDetail={hasPermissions(pipeline, 'viewDetail')}
51+
canEdit={hasPermissions(pipeline, 'update')}
52+
/>
53+
54+
<Row>
55+
<Col lg={12}>
56+
<Callout variant="warning">
57+
<h4>
58+
<FormattedMessage id="app.editPipeline.disclaimer" defaultMessage="Disclaimer" />
59+
</h4>
60+
<p>
61+
<FormattedMessage
62+
id="app.editPipeline.disclaimerWarning"
63+
defaultMessage="Modifying the pipeline might break all exercises using the pipeline!"
64+
/>
65+
</p>
66+
</Callout>
67+
</Col>
68+
</Row>
69+
70+
<Row>
71+
<Col lg={12}>
72+
<PipelineEditContainer pipeline={pipeline} />
73+
</Col>
74+
</Row>
75+
76+
<Row>
77+
<Col xl={6}>
78+
<PipelineFilesTableContainer pipeline={pipeline} />
79+
</Col>
80+
</Row>
81+
</>
82+
)}
83+
</Page>
84+
);
85+
}
86+
}
87+
88+
EditPipeline.propTypes = {
89+
pipeline: ImmutablePropTypes.map,
90+
loadAsync: PropTypes.func.isRequired,
91+
match: PropTypes.shape({
92+
params: PropTypes.shape({
93+
pipelineId: PropTypes.string.isRequired,
94+
}).isRequired,
95+
}).isRequired,
96+
};
97+
98+
export default connect(
99+
(
100+
state,
101+
{
102+
match: {
103+
params: { pipelineId },
104+
},
105+
}
106+
) => {
107+
return {
108+
pipeline: getPipeline(pipelineId)(state),
109+
};
110+
},
111+
(
112+
dispatch,
113+
{
114+
match: {
115+
params: { pipelineId },
116+
},
117+
}
118+
) => ({
119+
loadAsync: () => EditPipeline.loadAsync({ pipelineId }, dispatch),
120+
})
121+
)(EditPipeline);
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import EditPipelineStructure from './EditPipelineStructure';
2+
export default EditPipelineStructure;

0 commit comments

Comments
 (0)