diff --git a/app-frontend/src/api/OneClickAppsApi.ts b/app-frontend/src/api/OneClickAppsApi.ts index 5d6838d..271bf41 100644 --- a/app-frontend/src/api/OneClickAppsApi.ts +++ b/app-frontend/src/api/OneClickAppsApi.ts @@ -1,5 +1,5 @@ import axios from "axios"; -import { IOneClickAppDef } from "../containers/apps/oneclick/OneClickAppSelector"; +import { IOneClickAppIdentifier } from "../containers/apps/oneclick/OneClickAppSelector"; const DOT_JSON = ".JSON"; @@ -31,7 +31,7 @@ export default class OneClickAppsApi { ) // .then(function(res) { // res contains data, headers, and etc... - return (res.data as IOneClickAppDef[]).map(element => { + return (res.data as IOneClickAppIdentifier[]).map(element => { return { name: element.name.substr(0, element.name.length - DOT_JSON.length), download_url: element.download_url diff --git a/app-frontend/src/containers/apps/oneclick/OneClickAppConfigPage.tsx b/app-frontend/src/containers/apps/oneclick/OneClickAppConfigPage.tsx index 0ff4846..899eaa2 100644 --- a/app-frontend/src/containers/apps/oneclick/OneClickAppConfigPage.tsx +++ b/app-frontend/src/containers/apps/oneclick/OneClickAppConfigPage.tsx @@ -5,11 +5,13 @@ import { IHashMapGeneric } from "../../../models/IHashMapGeneric"; import Toaster from "../../../utils/Toaster"; import { Row, Col, Card } from "antd"; import CenteredSpinner from "../../global/CenteredSpinner"; -import OneClickVariablesSection, { - IEnteredOneClickAppVariable -} from "./OneClickVariablesSection"; +import OneClickVariablesSection from "./OneClickVariablesSection"; +import OneClickAppDeployHelper, { + IDeploymentState +} from "./OneClickAppDeployHelper"; +import OneClickAppDeployProgress from "./OneClickAppDeployProgress"; -export interface IOneCLickVariable { +export interface IOneClickVariable { id: string; label: string; defaultValue?: string; @@ -25,7 +27,7 @@ export interface IDockerComposeService { depends_on?: string[]; } -export interface IOneClickConfig { +export interface IOneClickTemplate { dockerCompose: { version: string; services: IHashMapGeneric; @@ -34,28 +36,37 @@ export interface IOneClickConfig { start: string; end: string; }; - variables: IOneCLickVariable[]; + variables: IOneClickVariable[]; } export default class OneClickAppConfigPage extends Component< RouteComponentProps, { - apiData: IOneClickConfig | undefined; + apiData: IOneClickTemplate | undefined; + deploymentState: IDeploymentState | undefined; } > { + private oneClickAppDeployHelper: OneClickAppDeployHelper; + constructor(props: any) { super(props); + const self = this; this.state = { - apiData: undefined + apiData: undefined, + deploymentState: undefined }; + this.oneClickAppDeployHelper = new OneClickAppDeployHelper( + deploymentState => self.setState({ deploymentState }) + ); } componentDidMount() { const self = this; new OneClickAppsApi() .getOneClickAppByName(this.props.match.params.appName) - .then(function(data: IOneClickConfig) { + .then(function(data: IOneClickTemplate) { data.variables = data.variables || []; + // Adding app name to all one click apps data.variables.unshift({ id: "$$cap_appname", label: "App Name", @@ -68,12 +79,6 @@ export default class OneClickAppConfigPage extends Component< .catch(Toaster.createCatcher()); } - onNextClicked(values: IHashMapGeneric) { - // TODO - alert("Deploying"); - console.log(values); - } - render() { const self = this; @@ -81,6 +86,14 @@ export default class OneClickAppConfigPage extends Component< return ; } + if (!!this.state.deploymentState) { + return ( + + ); + } + const apiData = this.state.apiData!; return ( @@ -101,7 +114,12 @@ export default class OneClickAppConfigPage extends Component<
self.onNextClicked(values)} + onNextClicked={values => + self.oneClickAppDeployHelper.startDeployProcess( + self.state.apiData!, + values + ) + } />

diff --git a/app-frontend/src/containers/apps/oneclick/OneClickAppDeployHelper.ts b/app-frontend/src/containers/apps/oneclick/OneClickAppDeployHelper.ts new file mode 100644 index 0000000..fce9976 --- /dev/null +++ b/app-frontend/src/containers/apps/oneclick/OneClickAppDeployHelper.ts @@ -0,0 +1,39 @@ +import ApiManager from "../../../api/ApiManager"; +import { IHashMapGeneric } from "../../../models/IHashMapGeneric"; +import { IOneClickTemplate } from "./OneClickAppConfigPage"; + +export interface IDeploymentState { + steps: string[]; + error: string; + currentStep: number; +} + +export default class OneClickAppDeployHelper { + private apiManager: ApiManager; + constructor( + private onDeploymentStateChanged: ( + deploymentState: IDeploymentState + ) => void + ) { + this.apiManager = new ApiManager(); + } + + startDeployProcess( + template: IOneClickTemplate, + values: IHashMapGeneric + ) { + // JSON.stringfy + // Replace + // Re parse with error check + // Start deploy + // TODO + alert("Deploying"); + console.log(values); + + this.onDeploymentStateChanged({ + steps: [], + error: "", + currentStep: 0 + }); + } +} diff --git a/app-frontend/src/containers/apps/oneclick/OneClickAppDeployProgress.tsx b/app-frontend/src/containers/apps/oneclick/OneClickAppDeployProgress.tsx new file mode 100644 index 0000000..8b8ba38 --- /dev/null +++ b/app-frontend/src/containers/apps/oneclick/OneClickAppDeployProgress.tsx @@ -0,0 +1,15 @@ +import React, { Component } from "react"; +import { IDeploymentState } from "./OneClickAppDeployHelper"; + +export default class OneClickAppDeployProgress extends Component<{ + deploymentState: IDeploymentState; +}> { + render() { + return ( +
+

OneClickAppDeployProgress

+
{JSON.stringify(this.props.deploymentState, null, 2)}
+
+ ); + } +} diff --git a/app-frontend/src/containers/apps/oneclick/OneClickAppSelector.tsx b/app-frontend/src/containers/apps/oneclick/OneClickAppSelector.tsx index ed36293..44d7654 100644 --- a/app-frontend/src/containers/apps/oneclick/OneClickAppSelector.tsx +++ b/app-frontend/src/containers/apps/oneclick/OneClickAppSelector.tsx @@ -6,7 +6,7 @@ import { Row, Col, Card, Select, Button } from "antd"; import CenteredSpinner from "../../global/CenteredSpinner"; import { RouteComponentProps } from "react-router"; -export interface IOneClickAppDef { +export interface IOneClickAppIdentifier { name: string; download_url: string; } @@ -14,7 +14,7 @@ export interface IOneClickAppDef { export default class OneClickAppSelector extends Component< RouteComponentProps, { - oneClickAppList: IOneClickAppDef[] | undefined; + oneClickAppList: IOneClickAppIdentifier[] | undefined; selectedApp: string | undefined; } > { diff --git a/app-frontend/src/containers/apps/oneclick/OneClickVariablesSection.tsx b/app-frontend/src/containers/apps/oneclick/OneClickVariablesSection.tsx index 20a00c8..a729668 100644 --- a/app-frontend/src/containers/apps/oneclick/OneClickVariablesSection.tsx +++ b/app-frontend/src/containers/apps/oneclick/OneClickVariablesSection.tsx @@ -1,17 +1,12 @@ import React, { Component } from "react"; -import { IOneCLickVariable } from "./OneClickAppConfigPage"; +import { IOneClickVariable } from "./OneClickAppConfigPage"; import { Input, Row, Col, Alert, Button, message } from "antd"; import { IHashMapGeneric } from "../../../models/IHashMapGeneric"; import Utils from "../../../utils/Utils"; -export interface IEnteredOneClickAppVariable { - id: string; - value: string; -} - export default class OneClickVariablesSection extends Component< { - oneClickAppVariables: IOneCLickVariable[]; + oneClickAppVariables: IOneClickVariable[]; onNextClicked: (values: IHashMapGeneric) => void; }, { @@ -52,7 +47,7 @@ export default class OneClickVariablesSection extends Component< self.setState({ blurredFields }); } - isFieldValueValid(variable: IOneCLickVariable) { + isFieldValueValid(variable: IOneClickVariable) { const self = this; const currVal = self.state.variables[variable.id] || ""; let isEnteredValueValid = true;