Skip to content
This repository has been archived by the owner on Mar 24, 2023. It is now read-only.

Commit

Permalink
Fix UI for workflows with multiple async lifecycle steps (#759)
Browse files Browse the repository at this point in the history
  • Loading branch information
Rob0h authored Dec 12, 2018
1 parent 19e9d15 commit 9bfedaf
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 56 deletions.
68 changes: 68 additions & 0 deletions fixtures/kubectl/ship.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
assets:
v1:
- inline:
dest: first/nginx.yaml
contents: |
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
- inline:
dest: second/redis.yaml
contents: |
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
labels:
app: redis
spec:
selector:
matchLabels:
app: redis
role: master
tier: backend
replicas: 1
template:
metadata:
labels:
app: redis
role: master
tier: backend
spec:
containers:
- name: master
image: redis
resources:
requests:
cpu: 100m
memory: 100Mi
ports:
- containerPort: 6379
lifecycle:
v1:
- message:
contents: "Hi - The following steps will create a nginx and redis deployment"
- render: {}
- kubectlApply:
path: first
- kubectlApply:
path: second
- message:
contents: "Bye"
62 changes: 30 additions & 32 deletions web/init/src/components/shared/DetermineComponentForRoute.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@ import React from "react";
import PropTypes from "prop-types";
import { withRouter } from "react-router-dom";
import find from "lodash/find";
import findIndex from "lodash/findIndex";
import indexOf from "lodash/indexOf";

import Loader from "./Loader";
import StepMessage from "./StepMessage";
import StepBuildingAssets from "./StepBuildingAssets";
import { RENDER_PHASE, StepBuildingAssets } from "./StepBuildingAssets";
import StepHelmIntro from "../../containers/HelmChartInfo";
import StepHelmValues from "../kustomize/HelmValuesEditor";
import StepTerraform from "./StepTerraform";
import StepKubectlApply from "./StepKubectlApply";
import { TERRAFORM_PHASE, StepTerraform } from "./StepTerraform";
import { KUBECTL_PHASE, StepKubectlApply } from "./StepKubectlApply";
import KustomizeEmpty from "../kustomize/kustomize_overlay/KustomizeEmpty";
import KustomizeOverlay from "../../containers/KustomizeOverlay";
import ConfigOnly from "../../containers/ConfigOnly";
Expand All @@ -31,8 +30,7 @@ export class DetermineComponentForRoute extends React.Component {
}

componentDidMount() {
const { getContentForStep, routeId } = this.props;
getContentForStep(routeId);
this.getContentForStep();
}

handleAction = async (action, gotoNext) => {
Expand All @@ -43,16 +41,17 @@ export class DetermineComponentForRoute extends React.Component {
}

getContentForStep = () => {
const { getContentForStep, routeId } = this.props;
const { getContentForStep, currentRoute } = this.props;
const { id: routeId } = currentRoute;
getContentForStep(routeId);
}

gotoRoute = async(route) => {
let nextRoute = route;
const { basePath, routes, routeId, history, onCompletion } = this.props;
const { basePath, routes, currentRoute, history, onCompletion } = this.props;

if (!nextRoute) {
const currRoute = find(routes, ["id", routeId]);
const currRoute = find(routes, ["id", currentRoute.id]);
const currIndex = indexOf(routes, currRoute);
nextRoute = routes[currIndex + 1];
}
Expand Down Expand Up @@ -119,27 +118,26 @@ export class DetermineComponentForRoute extends React.Component {
}
}

startPollingStep = (location, routeId) => {
const { initializeStep, basePath } = this.props;
if (location.pathname === `${basePath}/${routeId}`) {
initializeStep(routeId);
this.startPoll(routeId, () => {
// Timeout to wait a little bit before transitioning to the next step
setTimeout(this.gotoRoute, 500);
});
}
startPollingStep = (routeId) => {
const { initializeStep } = this.props;
initializeStep(routeId);
this.startPoll(routeId, () => {
// Timeout to wait a little bit before transitioning to the next step
setTimeout(this.gotoRoute, 500);
});
}

renderStep = (phase) => {
renderStep = () => {
const {
currentStep,
currentStep = {},
progress,
actions,
location,
initializeStep,
routes,
phase,
currentRoute,
} = this.props;
const { id: routeId } = find(routes, { phase }) || {};
const routeId = currentRoute.id;

if (!phase || !phase.length) return null;
switch (phase) {
Expand All @@ -165,7 +163,7 @@ export class DetermineComponentForRoute extends React.Component {
<ConfigOnly
actions={actions}
handleAction={this.handleAction}
routeId={this.props.routeId}
routeId={routeId}
/>
);
case "stream":
Expand All @@ -178,20 +176,20 @@ export class DetermineComponentForRoute extends React.Component {
isLoading={this.props.dataLoading.submitActionLoading || !currentStep.message.contents}
/>
);
case "render":
case RENDER_PHASE:
return (
<StepBuildingAssets
startPollingStep={this.startPollingStep}
routeId={routeId}
location={location}
status={progress || currentStep.status}
currentRoute={currentRoute}
/>
);
case "terraform":
case TERRAFORM_PHASE:
return (
<StepTerraform
startPollingStep={this.startPollingStep}
routeId={routeId}
currentRoute={currentRoute}
startPoll={this.startPoll}
location={location}
status={progress || currentStep.status}
Expand All @@ -200,11 +198,11 @@ export class DetermineComponentForRoute extends React.Component {
initializeStep={initializeStep}
/>
);
case "kubectl":
case KUBECTL_PHASE:
return (
<StepKubectlApply
startPollingStep={this.startPollingStep}
routeId={routeId}
currentRoute={currentRoute}
startPoll={this.startPoll}
location={location}
status={progress || currentStep.status}
Expand Down Expand Up @@ -233,7 +231,7 @@ export class DetermineComponentForRoute extends React.Component {
handleAction={this.handleAction}
isLoading={this.props.dataLoading.submitActionLoading}
/>
);
);
case "kustomize-intro":
return (
<KustomizeEmpty
Expand All @@ -248,7 +246,7 @@ export class DetermineComponentForRoute extends React.Component {
startPoll={this.startPoll}
getCurrentStep={this.getContentForStep}
pollCallback={this.gotoRoute}
routeId={this.props.routeId}
routeId={routeId}
actions={actions}
isNavcycle={true}
finalizeStep={this.props.finalizeStep}
Expand Down Expand Up @@ -283,7 +281,7 @@ export class DetermineComponentForRoute extends React.Component {
<p className="u-fontSize--large u-fontWeight--medium u-color--tundora">Oops, something isn't quite right. If you continue to experience this problem contact <a href="mailto:support@replicated.com">support@replicated.com</a></p>
</div>
:
this.renderStep(phase)
this.renderStep()
}
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion web/init/src/components/shared/RouteDecider.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const ShipRoutesWrapper = ({ routes, headerEnabled, basePath, onCompletion }) =>
onCompletion={onCompletion}
basePath={basePath}
routes={routes}
routeId={route.id}
currentRoute={route}
/>}
/>
))}
Expand Down
15 changes: 11 additions & 4 deletions web/init/src/components/shared/StepBuildingAssets.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@ import { Line } from "rc-progress";
import { Utilities } from "../../utilities/utilities";
import Loader from "./Loader";

export default class StepBuildingAssets extends React.Component {
export const RENDER_PHASE = "render";

export class StepBuildingAssets extends React.Component {
static propTypes = {
location: PropTypes.shape({
pathname: PropTypes.string,
}).isRequired,
routeId: PropTypes.string.isRequired,
currentRoute: PropTypes.shape({
id: PropTypes.string,
phase: PropTypes.string,
}).isRequired,
startPollingStep: PropTypes.func.isRequired,
status: PropTypes.shape({
type: PropTypes.string,
Expand All @@ -19,8 +24,10 @@ export default class StepBuildingAssets extends React.Component {
}

componentDidMount() {
const { startPollingStep, location, routeId } = this.props;
startPollingStep(location, routeId);
const { startPollingStep, currentRoute } = this.props;
if (currentRoute.phase === RENDER_PHASE) {
startPollingStep(currentRoute.id);
}
}

render() {
Expand Down
24 changes: 15 additions & 9 deletions web/init/src/components/shared/StepKubectlApply.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@ import { Utilities } from "../../utilities/utilities";
import Loader from "./Loader";
import StepMessage from "./StepMessage";

export default class StepKubectlApply extends React.Component {
export const KUBECTL_PHASE = "kubectl";

export class StepKubectlApply extends React.Component {
static propTypes = {
location: PropTypes.shape({
pathname: PropTypes.string,
}).isRequired,
routeId: PropTypes.string.isRequired,
currentRoute: PropTypes.shape({
id: PropTypes.string,
phase: PropTypes.string,
}).isRequired,
startPoll: PropTypes.func.isRequired,
gotoRoute: PropTypes.func.isRequired,
initializeStep: PropTypes.func.isRequired,
Expand All @@ -30,12 +35,13 @@ export default class StepKubectlApply extends React.Component {

componentDidMount() {
const {
routeId,
location,
currentRoute,
startPollingStep,
} = this.props;

startPollingStep(location, routeId);
if (currentRoute.phase === KUBECTL_PHASE) {
startPollingStep(currentRoute.id);
}
}

parseStatus = () => {
Expand Down Expand Up @@ -74,7 +80,7 @@ export default class StepKubectlApply extends React.Component {
const clampedPercent = clamp(percent, 0, 100);
return {
isJSON,
status: parsedDetailStatus,
status: "working",
percent: clampedPercent,
progressDetail,
message,
Expand All @@ -86,11 +92,11 @@ export default class StepKubectlApply extends React.Component {
const {
handleAction,
startPoll,
routeId,
currentRoute,
gotoRoute,
} = this.props;
handleAction(action, false);
startPoll(routeId, gotoRoute);
startPoll(currentRoute.id, gotoRoute);
}

render() {
Expand Down Expand Up @@ -122,7 +128,7 @@ export default class StepKubectlApply extends React.Component {
}
</div>
:
<p className="u-fontSizer--larger u-color--tundora u-fontWeight--bold u-marginTop--normal u-textAlign--center">{status}</p>
null
}
</div>: null
}
Expand Down
Loading

0 comments on commit 9bfedaf

Please sign in to comment.