aboutsummaryrefslogtreecommitdiffstats
path: root/src/tools/emcoui/src/compositeApps/dialogs/CompositeAppForm.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/emcoui/src/compositeApps/dialogs/CompositeAppForm.jsx')
-rw-r--r--src/tools/emcoui/src/compositeApps/dialogs/CompositeAppForm.jsx441
1 files changed, 277 insertions, 164 deletions
diff --git a/src/tools/emcoui/src/compositeApps/dialogs/CompositeAppForm.jsx b/src/tools/emcoui/src/compositeApps/dialogs/CompositeAppForm.jsx
index 29e17cd7..751ea8eb 100644
--- a/src/tools/emcoui/src/compositeApps/dialogs/CompositeAppForm.jsx
+++ b/src/tools/emcoui/src/compositeApps/dialogs/CompositeAppForm.jsx
@@ -11,185 +11,298 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
-// ========================================================================
-import React from "react";
-import { withStyles } from "@material-ui/core/styles";
+// ========================================================================
+import React, { useState } from "react";
import Button from "@material-ui/core/Button";
import Dialog from "@material-ui/core/Dialog";
-import MuiDialogTitle from "@material-ui/core/DialogTitle";
-import MuiDialogContent from "@material-ui/core/DialogContent";
-import MuiDialogActions from "@material-ui/core/DialogActions";
+import AppBar from "@material-ui/core/AppBar";
+import Toolbar from "@material-ui/core/Toolbar";
+import IconButton from "@material-ui/core/IconButton";
import Typography from "@material-ui/core/Typography";
-import { TextField } from '@material-ui/core';
-const styles = (theme) => ({
- root: {
- margin: 0,
- padding: theme.spacing(2),
+import CloseIcon from "@material-ui/icons/Close";
+import Slide from "@material-ui/core/Slide";
+import { Grid } from "@material-ui/core";
+import { TextField } from "@material-ui/core";
+import { makeStyles } from "@material-ui/core/styles";
+import AddIcon from "@material-ui/icons/Add";
+import NewAppForm from "../../common/Form";
+import AppForm from "./AppForm";
+import { Formik, FieldArray } from "formik";
+import * as Yup from "yup";
+
+const Transition = React.forwardRef(function Transition(props, ref) {
+ return <Slide direction="up" ref={ref} {...props} />;
+});
+
+const useStyles = makeStyles((theme) => ({
+ tableRoot: {
+ width: "100%",
},
- closeButton: {
+ paper: {
+ width: "100%",
+ marginBottom: theme.spacing(2),
+ },
+ table: {
+ minWidth: 550,
+ },
+ visuallyHidden: {
+ border: 0,
+ clip: "rect(0 0 0 0)",
+ height: 1,
+ margin: -1,
+ overflow: "hidden",
+ padding: 0,
position: "absolute",
- right: theme.spacing(1),
- top: theme.spacing(1),
- color: theme.palette.grey[500],
+ top: 20,
+ width: 1,
},
-});
-
-
-const DialogContent = withStyles((theme) => ({
- root: {
- padding: theme.spacing(2),
+ appBar: {
+ position: "relative",
+ },
+ title: {
+ marginLeft: theme.spacing(2),
+ flex: 1,
+ },
+ demo: {
+ backgroundColor: theme.palette.background.paper,
},
-}))(MuiDialogContent);
-
-const DialogActions = withStyles((theme) => ({
root: {
- margin: 0,
- padding: theme.spacing(1),
+ flexGrow: 1,
+ backgroundColor: theme.palette.background.paper,
+ display: "flex",
+ height: 424,
},
-}))(MuiDialogActions);
-
+ tabs: {
+ borderRight: `1px solid ${theme.palette.divider}`,
+ },
+}));
-class CreateCompositeAppForm extends React.Component {
- constructor(props) {
- super(props)
- this.state = {
- fields: { name: "", version: "", description: "" },
- errors: {}
- }
- this.handleChange = this.handleChange.bind(this);
- this.submituserRegistrationForm = this.submituserRegistrationForm.bind(this);
- }
+const PROFILE_SUPPORTED_FORMATS = [
+ ".tgz",
+ ".tar.gz",
+ ".tar",
+ "application/x-tar",
+ "application/x-tgz",
+ "application/x-compressed",
+ "application/x-gzip",
+ "application/x-compressed-tar",
+ "application/gzip",
+];
+const APP_PACKAGE_SUPPORTED_FORMATS = [
+ ".tgz",
+ ".tar.gz",
+ ".tar",
+ "application/x-tar",
+ "application/x-tgz",
+ "application/x-compressed",
+ "application/x-gzip",
+ "application/x-compressed-tar",
+];
+const serviceBasicValidationSchema = Yup.object({
+ name: Yup.string().required(),
+ description: Yup.string(),
+ apps: Yup.array()
+ .of(
+ Yup.object({
+ appName: Yup.string().required("App name is required"),
+ file: Yup.mixed()
+ .required("An app package file is required")
+ .test(
+ "fileFormat",
+ "Unsupported file format",
+ (value) =>
+ value && APP_PACKAGE_SUPPORTED_FORMATS.includes(value.type)
+ ),
+ profilePackageFile: Yup.mixed()
+ .required("A profile package file is required")
+ .test(
+ "fileFormat",
+ "Unsupported file format",
+ (value) => value && PROFILE_SUPPORTED_FORMATS.includes(value.type)
+ ),
+ })
+ )
+ .required("At least one app is required"),
+});
- componentDidMount = () => {
- if (this.props.item) {
- this.title = "Edit Composite App";
- this.buttonLabel = "Update";
- this.isEdit = true;
- }
- else {
- this.title = "New Composite App";
- this.buttonLabel = "Create";
- this.isEdit = false;
- }
+const CreateCompositeAppForm = ({ open, handleClose }) => {
+ const classes = useStyles();
+ const [openForm, setOpenForm] = useState(false);
+ const handleCloseForm = () => {
+ setOpenForm(false);
};
-
- componentDidUpdate = (prevProps, prevState) => {
- if (this.props.item && ((prevProps.item !== this.props.item))) {
- this.setState({ fields: { ...this.props.item.metadata, version: this.props.item.spec.version } });
- }
- }
-
- resetFields = () => {
- if (!this.isEdit) {
- this.setState({
- fields: { name: "", version: "", description: "" },
- errors: {}
- });
- }
- else {
- this.setState({ fields: { ...this.props.item.metadata, version: this.props.item.spec.version } });
- }
- }
-
- handleClose = () => {
- this.resetFields();
- this.props.handleClose();
+ const handleAddApp = () => {
+ setOpenForm(true);
};
-
- submituserRegistrationForm(e) {
- e.preventDefault();
- if (this.validateForm()) {
- this.resetFields();
- this.props.handleClose(this.state.fields);
- }
- }
-
- validateForm() {
- let fields = this.state.fields;
- let errors = {};
- let formIsValid = true;
-
- if (!fields["name"]) {
- formIsValid = false;
- errors["name"] = "*Please enter your username.";
- }
-
- if (typeof fields["name"] !== "string") {
- if (!fields["name"].match(/^[a-zA-Z ]*$/)) {
- formIsValid = false;
- errors["name"] = "*Please enter alphabet characters only.";
- }
- }
- this.setState({
- errors: errors
- });
- return formIsValid;
- }
-
- handleChange = (e) => {
- this.setState({ fields: { ...this.state.fields, [e.target.name]: e.target.value } });
- }
-
- render = () => {
- const { classes } = this.props;
- return (
- <>
+ let initialValues = { name: "", description: "", apps: [] };
+ return (
+ <>
+ {open && (
<Dialog
- maxWidth={"xs"}
- onClose={this.handleClose}
- aria-labelledby="customized-dialog-title"
- open={this.props.open}
- disableBackdropClick
+ open={open}
+ onClose={() => {
+ handleClose();
+ }}
+ fullScreen
+ TransitionComponent={Transition}
>
- <MuiDialogTitle disableTypography className={classes.root} >
- <Typography variant="h6">{this.title}</Typography>
- </MuiDialogTitle>
+ <Formik
+ initialValues={initialValues}
+ onSubmit={(values, { setSubmitting }) => {
+ setSubmitting(false);
+ handleClose(values);
+ }}
+ validationSchema={serviceBasicValidationSchema}
+ >
+ {(props) => {
+ const {
+ values,
+ touched,
+ errors,
+ isSubmitting,
+ handleChange,
+ handleBlur,
+ handleSubmit,
+ } = props;
+ return (
+ <>
+ <form noValidate onSubmit={handleSubmit}>
+ <AppBar className={classes.appBar}>
+ <Toolbar>
+ <IconButton
+ edge="start"
+ color="inherit"
+ onClick={() => {
+ handleClose();
+ }}
+ aria-label="close"
+ >
+ <CloseIcon />
+ </IconButton>
+ <Typography variant="h6" className={classes.title}>
+ Add Service
+ </Typography>
+ <Button
+ type="submit"
+ autoFocus
+ variant="contained"
+ disabled={isSubmitting}
+ >
+ SUBMIT
+ </Button>
+ </Toolbar>
+ </AppBar>
+ <div style={{ padding: "12px" }}>
+ <Grid
+ container
+ direction="row"
+ justify="center"
+ alignItems="center"
+ style={{ marginTop: "40px" }}
+ spacing={3}
+ >
+ <Grid item xs={6}>
+ <Grid container spacing={3}>
+ {errors.apps &&
+ touched.apps &&
+ typeof errors.apps !== "object" && (
+ <Grid item xs={12} sm={12}>
+ <Typography>{errors.apps}</Typography>
+ </Grid>
+ )}
+
+ <Grid item xs={12} sm={6}>
+ <TextField
+ fullWidth
+ name="name"
+ id="input-name"
+ label="Name"
+ variant="outlined"
+ size="small"
+ value={values.name}
+ onChange={handleChange}
+ onBlur={handleBlur}
+ required
+ helperText={
+ errors.name &&
+ touched.name &&
+ "Name is required"
+ }
+ error={errors.name && touched.name}
+ />
+ </Grid>
+ <Grid item xs={12} sm={6}>
+ <TextField
+ fullWidth
+ name="description"
+ id="input-description"
+ label="Description"
+ variant="outlined"
+ size="small"
+ value={values.description}
+ onChange={handleChange}
+ onBlur={handleBlur}
+ />
+ </Grid>
- <form onSubmit={this.submituserRegistrationForm}>
- <DialogContent dividers>
- <TextField
- style={{ width: "40%", marginBottom: "10px" }}
- name="name"
- value={this.state.fields.name}
- id="input-name"
- label="Name"
- helperText="Name should be unique"
- onChange={this.handleChange}
- required
- />
- <TextField
- style={{ width: "40%", marginBottom: "20px", float: "right" }}
- name="version"
- value={this.state.fields.version}
- onChange={this.handleChange}
- id="input-version"
- label="Version"
- required
- />
- <TextField
- style={{ width: "100%", marginBottom: "25px" }}
- name="description"
- value={this.state.fields.description}
- onChange={this.handleChange}
- id="input-description"
- label="Description"
- multiline
- rowsMax={4}
- />
- </DialogContent>
- <DialogActions>
- <Button autoFocus onClick={this.handleClose} color="secondary">
- Cancel
- </Button>
- <Button autoFocus type="submit" color="primary">
- {this.buttonLabel}
- </Button>
- </DialogActions>
- </form>
+ <FieldArray
+ name="apps"
+ render={(arrayHelpers) => (
+ <>
+ <NewAppForm
+ open={openForm}
+ onClose={handleCloseForm}
+ onSubmit={(values) => {
+ arrayHelpers.push({
+ appName: values.name,
+ description: values.description,
+ });
+ setOpenForm(false);
+ }}
+ />
+ {values.apps &&
+ values.apps.length > 0 &&
+ values.apps.map((app, index) => (
+ <Grid key={index} item sm={12} xs={12}>
+ <AppForm
+ formikProps={props}
+ name={app.appName}
+ description={app.description}
+ index={index}
+ initialValues={values}
+ />
+ </Grid>
+ ))}
+ </>
+ )}
+ />
+ <Grid item xs={12}>
+ <Button
+ variant="outlined"
+ size="small"
+ fullWidth
+ color="primary"
+ onClick={() => {
+ handleAddApp();
+ }}
+ startIcon={<AddIcon />}
+ >
+ Add App
+ </Button>
+ </Grid>
+ </Grid>
+ </Grid>
+ </Grid>
+ </div>
+ </form>
+ </>
+ );
+ }}
+ </Formik>
</Dialog>
- </>
- );
- }
-}
-export default withStyles(styles)(CreateCompositeAppForm)
+ )}
+ </>
+ );
+};
+export default CreateCompositeAppForm;