text: import React, { Component } from 'react';
  import * as PropTypes from 'prop-types';
  import { Formik, Field, Form } from 'formik';
  import { withStyles } from '@material-ui/core/styles';
  import Drawer from '@material-ui/core/Drawer';
  import Typography from '@material-ui/core/Typography';
  import Button from '@material-ui/core/Button';
  import IconButton from '@material-ui/core/IconButton';
  import Fab from '@material-ui/core/Fab';
  import { Add, Close } from '@material-ui/icons';
  import {
    compose,
    pathOr,
    pipe,
    map,
    pluck,
    sortWith,
    path,
    ascend,
    union,
    assoc,
  } from 'ramda';
  import * as Yup from 'yup';
  import graphql from 'babel-plugin-relay/macro';
  import { ConnectionHandler } from 'relay-runtime';
  import inject18n from '../../../../components/i18n';
  import { commitMutation, fetchQuery } from '../../../../relay/environment';
  import Autocomplete from '../../../../components/Autocomplete';
  import AutocompleteCreate from '../../../../components/AutocompleteCreate';
  import TextField from '../../../../components/TextField';
  import { killChainPhasesSearchQuery } from '../../settings/KillChainPhases';
  import { markingDefinitionsLinesSearchQuery } from '../../settings/marking_definitions/MarkingDefinitionsLines';
  import IdentityCreation, {
    identityCreationIdentitiesSearchQuery,
  } from '../../common/identities/IdentityCreation';
  import TagAutocompleteField from '../../common/form/TagAutocompleteField';
  
  const styles = (theme) => ({
    drawerPaper: {
      minHeight: '100vh',
      width: '50%',
      position: 'fixed',
      backgroundColor: theme.palette.navAlt.background,
      transition: theme.transitions.create('width', {
        easing: theme.transitions.easing.sharp,
        duration: theme.transitions.duration.enteringScreen,
      }),
      padding: 0,
    },
    createButton: {
      position: 'fixed',
      bottom: 30,
      right: 30,
    },
    buttons: {
      marginTop: 20,
      textAlign: 'right',
    },
    button: {
      marginLeft: theme.spacing(2),
    },
    header: {
      backgroundColor: theme.palette.navAlt.backgroundHeader,
      padding: '20px 20px 20px 60px',
    },
    closeButton: {
      position: 'absolute',
      top: 12,
      left: 5,
    },
    importButton: {
      position: 'absolute',
      top: 15,
      right: 20,
    },
    container: {
      padding: '10px 20px 20px 20px',
    },
  });
  
  const malwareMutation = graphql`
    mutation MalwareCreationMutation($input: MalwareAddInput!) {
      malwareAdd(input: $input) {
        ...MalwareCard_node
      }
    }
  `;
  
  const malwareValidation = (t) => Yup.object().shape({
    name: Yup.string().required(t('This field is required')),
    description: Yup.string()
      .min(3, t('The value is too short'))
      .max(5000, t('The value is too long'))
      .required(t('This field is required')),
  });
  
  const sharedUpdater = (store, userId, paginationOptions, newEdge) => {
    const userProxy = store.get(userId);
    const conn = ConnectionHandler.getConnection(
      userProxy,
      'Pagination_malwares',
      paginationOptions,
    );
    ConnectionHandler.insertEdgeBefore(conn, newEdge);
  };
  
  class MalwareCreation extends Component {
    constructor(props) {
      super(props);
      this.state = {
        open: false,
        identities: [],
        identityCreation: false,
        identityInput: '',
        killChainPhases: [],
        markingDefinitions: [],
      };
    }
  
    handleOpen() {
      this.setState({ open: true });
    }
  
    handleClose() {
      this.setState({ open: false });
    }
  
    searchIdentities(event) {
      fetchQuery(identityCreationIdentitiesSearchQuery, {
        search: event.target.value,
        first: 10,
      }).then((data) => {
        const identities = pipe(
          pathOr([], ['identities', 'edges']),
          map((n) => ({ label: n.node.name, value: n.node.id })),
        )(data);
        this.setState({ identities: union(this.state.identities, identities) });
      });
    }
  
    handleOpenIdentityCreation(inputValue) {
      this.setState({ identityCreation: true, identityInput: inputValue });
    }
  
    handleCloseIdentityCreation() {
      this.setState({ identityCreation: false });
    }
  
    searchKillchainPhases(event) {
      fetchQuery(killChainPhasesSearchQuery, {
        search: event.target.value,
      }).then((data) => {
        const killChainPhases = pipe(
          pathOr([], ['killChainPhases', 'edges']),
          sortWith([ascend(path(['node', 'order']))]),
          map((n) => ({
            label: `[${n.node.kill_chain_name}] ${n.node.phase_name}`,
            value: n.node.id,
          })),
        )(data);
        this.setState({
          killChainPhases: union(this.state.killChainPhases, killChainPhases),
        });
      });
    }
  
    searchMarkingDefinitions(event) {
      fetchQuery(markingDefinitionsLinesSearchQuery, {
        search: event.target.value,
      }).then((data) => {
        const markingDefinitions = pipe(
          pathOr([], ['markingDefinitions', 'edges']),
          map((n) => ({ label: n.node.definition, value: n.node.id })),
        )(data);
        this.setState({
          markingDefinitions: union(
            this.state.markingDefinitions,
            markingDefinitions,
          ),
        });
      });
    }
  
    onSubmit(values, { setSubmitting, resetForm }) {
      const finalValues = pipe(
        assoc('createdByRef', values.createdByRef.value),
        assoc('killChainPhases', pluck('value', values.killChainPhases)),
        assoc('markingDefinitions', pluck('value', values.markingDefinitions)),
        assoc('tags', pluck('value', values.tags)),
      )(values);
      commitMutation({
        mutation: malwareMutation,
        variables: {
          input: finalValues,
        },
        updater: (store) => {
          const payload = store.getRootField('malwareAdd');
          const newEdge = payload.setLinkedRecord(payload, 'node'); // Creation of the pagination container.
          const container = store.getRoot();
          sharedUpdater(
            store,
            container.getDataID(),
            this.props.paginationOptions,
            newEdge,
          );
        },
        setSubmitting,
        onCompleted: () => {
          setSubmitting(false);
          resetForm();
          this.handleClose();
        },
      });
    }
  
    onReset() {
      this.handleClose();
    }
  
    render() {
      const { t, classes } = this.props;
      return (
        <div>
          <Fab
            onClick={this.handleOpen.bind(this)}
            color="secondary"
            aria-label="Add"
            className={classes.createButton}
          >
            <Add />
          </Fab>
          <Drawer
            open={this.state.open}
            anchor="right"
            classes={{ paper: classes.drawerPaper }}
            onClose={this.handleClose.bind(this)}
          >
            <div className={classes.header}>
              <IconButton
                aria-label="Close"
                className={classes.closeButton}
                onClick={this.handleClose.bind(this)}
              >
                <Close fontSize="small" />
              </IconButton>
              <Typography variant="h6">{t('Create a malware')}</Typography>
            </div>
            <div className={classes.container}>
              <Formik
                initialValues={{
                  name: '',
                  description: '',
                  createdByRef: '',
                  markingDefinitions: [],
                  killChainPhases: [],
                  tags: [],
                }}
                validationSchema={malwareValidation(t)}
                onSubmit={this.onSubmit.bind(this)}
                onReset={this.onReset.bind(this)}
                render={({
                  submitForm,
                  handleReset,
                  isSubmitting,
                  setFieldValue,
                }) => (
                  <div>
                    <Form style={{ margin: '20px 0 20px 0' }}>
                      <Field
                        name="name"
                        component={TextField}
                        label={t('Name')}
                        fullWidth={true}
                      />
                      <Field
                        name="description"
                        component={TextField}
                        label={t('Description')}
                        fullWidth={true}
                        multiline={true}
                        rows="4"
                        style={{ marginTop: 20 }}
                      />
                      <Field
                        name="createdByRef"
                        component={AutocompleteCreate}
                        multiple={false}
                        handleCreate={this.handleOpenIdentityCreation.bind(this)}
                        label={t('Author')}
                        options={this.state.identities}
                        onInputChange={this.searchIdentities.bind(this)}
                      />
                      <Field
                        name="killChainPhases"
                        component={Autocomplete}
                        multiple={true}
                        label={t('Kill chain phases')}
                        options={this.state.killChainPhases}
                        onInputChange={this.searchKillchainPhases.bind(this)}
                      />
                      <Field
                        name="markingDefinitions"
                        component={Autocomplete}
                        multiple={true}
                        label={t('Marking')}
                        options={this.state.markingDefinitions}
                        onInputChange={this.searchMarkingDefinitions.bind(this)}
                      />
                      <TagAutocompleteField />
                      <div className={classes.buttons}>
                        <Button
                          variant="contained"
                          onClick={handleReset}
                          disabled={isSubmitting}
                          classes={{ root: classes.button }}
                        >
                          {t('Cancel')}
                        </Button>
                        <Button
                          variant="contained"
                          color="primary"
                          onClick={submitForm}
                          disabled={isSubmitting}
                          classes={{ root: classes.button }}
                        >
                          {t('Create')}
                        </Button>
                      </div>
                    </Form>
                    <IdentityCreation
                      contextual={true}
                      inputValue={this.state.identityInput}
                      open={this.state.identityCreation}
                      handleClose={this.handleCloseIdentityCreation.bind(this)}
                      creationCallback={(data) => {
                        setFieldValue('createdByRef', {
                          label: data.identityAdd.name,
                          value: data.identityAdd.id,
                        });
                      }}
                    />
                  </div>
                )}
              />
            </div>
          </Drawer>
        </div>
      );
    }
  }
  
  MalwareCreation.propTypes = {
    paginationOptions: PropTypes.object,
    classes: PropTypes.object,
    theme: PropTypes.object,
    t: PropTypes.func,
  };
  
  export default compose(
    inject18n,
    withStyles(styles, { withTheme: true }),
  )(MalwareCreation);
  