text: import React, { Component } from 'react';
  import * as PropTypes from 'prop-types';
  import graphql from 'babel-plugin-relay/macro';
  import { createFragmentContainer } from 'react-relay';
  import { Formik, Form, Field } from 'formik';
  import { withStyles } from '@material-ui/core/styles';
  import {
    assoc,
    compose,
    map,
    pathOr,
    pipe,
    pick,
    difference,
    head,
  } from 'ramda';
  import * as Yup from 'yup';
  import inject18n from '../../../../components/i18n';
  import TextField from '../../../../components/TextField';
  import { SubscriptionFocus } from '../../../../components/Subscription';
  import { commitMutation } from '../../../../relay/environment';
  import KillChainPhasesField from '../../common/form/KillChainPhasesField';
  import CreatedByField from '../../common/form/CreatedByField';
  import ObjectMarkingField from '../../common/form/ObjectMarkingField';
  import MarkDownField from '../../../../components/MarkDownField';
  
  const styles = (theme) => ({
    drawerPaper: {
      minHeight: '100vh',
      width: '50%',
      position: 'fixed',
      overflow: 'hidden',
      backgroundColor: theme.palette.navAlt.background,
      transition: theme.transitions.create('width', {
        easing: theme.transitions.easing.sharp,
        duration: theme.transitions.duration.enteringScreen,
      }),
      padding: '30px 30px 30px 30px',
    },
    createButton: {
      position: 'fixed',
      bottom: 30,
      right: 30,
    },
    importButton: {
      position: 'absolute',
      top: 30,
      right: 30,
    },
  });
  
  const toolMutationFieldPatch = graphql`
    mutation ToolEditionOverviewFieldPatchMutation(
      $id: ID!
      $input: [EditInput]!
    ) {
      toolEdit(id: $id) {
        fieldPatch(input: $input) {
          ...ToolEditionOverview_tool
          ...Tool_tool
        }
      }
    }
  `;
  
  export const toolEditionOverviewFocus = graphql`
    mutation ToolEditionOverviewFocusMutation($id: ID!, $input: EditContext!) {
      toolEdit(id: $id) {
        contextPatch(input: $input) {
          id
        }
      }
    }
  `;
  
  const toolMutationRelationAdd = graphql`
    mutation ToolEditionOverviewRelationAddMutation(
      $id: ID!
      $input: StixMetaRelationshipAddInput
    ) {
      toolEdit(id: $id) {
        relationAdd(input: $input) {
          from {
            ...ToolEditionOverview_tool
          }
        }
      }
    }
  `;
  
  const toolMutationRelationDelete = graphql`
    mutation ToolEditionOverviewRelationDeleteMutation(
      $id: ID!
      $toId: String!
      $relationship_type: String!
    ) {
      toolEdit(id: $id) {
        relationDelete(toId: $toId, relationship_type: $relationship_type) {
          ...ToolEditionOverview_tool
        }
      }
    }
  `;
  
  const toolValidation = (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')),
  });
  
  class ToolEditionOverviewComponent extends Component {
    handleChangeFocus(name) {
      commitMutation({
        mutation: toolEditionOverviewFocus,
        variables: {
          id: this.props.tool.id,
          input: {
            focusOn: name,
          },
        },
      });
    }
  
    handleSubmitField(name, value) {
      toolValidation(this.props.t)
        .validateAt(name, { [name]: value })
        .then(() => {
          commitMutation({
            mutation: toolMutationFieldPatch,
            variables: { id: this.props.tool.id, input: { key: name, value } },
          });
        })
        .catch(() => false);
    }
  
    handleChangeCreatedBy(name, value) {
      if (!this.props.enableReferences) {
        commitMutation({
          mutation: toolMutationFieldPatch,
          variables: {
            id: this.props.tool.id,
            input: { key: 'createdBy', value: value.value || '' },
          },
        });
      }
    }
  
    handleChangeKillChainPhases(name, values) {
      const { tool } = this.props;
      const currentKillChainPhases = pipe(
        pathOr([], ['killChainPhases', 'edges']),
        map((n) => ({
          label: `[${n.node.kill_chain_name}] ${n.node.phase_name}`,
          value: n.node.id,
        })),
      )(tool);
  
      const added = difference(values, currentKillChainPhases);
      const removed = difference(currentKillChainPhases, values);
  
      if (added.length > 0) {
        commitMutation({
          mutation: toolMutationRelationAdd,
          variables: {
            id: this.props.tool.id,
            input: {
              toId: head(added).value,
              relationship_type: 'kill-chain-phase',
            },
          },
        });
      }
  
      if (removed.length > 0) {
        commitMutation({
          mutation: toolMutationRelationDelete,
          variables: {
            id: this.props.tool.id,
            toId: head(removed).value,
            relationship_type: 'kill-chain-phase',
          },
        });
      }
    }
  
    handleChangeObjectMarking(name, values) {
      const { tool } = this.props;
      const currentMarkingDefinitions = pipe(
        pathOr([], ['objectMarking', 'edges']),
        map((n) => ({
          label: n.node.definition,
          value: n.node.id,
        })),
      )(tool);
  
      const added = difference(values, currentMarkingDefinitions);
      const removed = difference(currentMarkingDefinitions, values);
  
      if (added.length > 0) {
        commitMutation({
          mutation: toolMutationRelationAdd,
          variables: {
            id: this.props.tool.id,
            input: {
              toId: head(added).value,
              relationship_type: 'object-marking',
            },
          },
        });
      }
  
      if (removed.length > 0) {
        commitMutation({
          mutation: toolMutationRelationDelete,
          variables: {
            id: this.props.tool.id,
            toId: head(removed).value,
            relationship_type: 'object-marking',
          },
        });
      }
    }
  
    render() {
      const { t, tool, context } = this.props;
      const createdBy = pathOr(null, ['createdBy', 'name'], tool) === null
        ? ''
        : {
          label: pathOr(null, ['createdBy', 'name'], tool),
          value: pathOr(null, ['createdBy', 'id'], tool),
        };
      const killChainPhases = pipe(
        pathOr([], ['killChainPhases', 'edges']),
        map((n) => ({
          label: `[${n.node.kill_chain_name}] ${n.node.phase_name}`,
          value: n.node.id,
        })),
      )(tool);
      const objectMarking = pipe(
        pathOr([], ['objectMarking', 'edges']),
        map((n) => ({
          label: n.node.definition,
          value: n.node.id,
        })),
      )(tool);
      const initialValues = pipe(
        assoc('createdBy', createdBy),
        assoc('killChainPhases', killChainPhases),
        assoc('objectMarking', objectMarking),
        pick([
          'name',
          'description',
          'createdBy',
          'killChainPhases',
          'objectMarking',
        ]),
      )(tool);
      return (
        <Formik
          enableReinitialize={true}
          initialValues={initialValues}
          validationSchema={toolValidation(t)}
          onSubmit={() => true}
        >
          {({ setFieldValue }) => (
            <Form style={{ margin: '20px 0 20px 0' }}>
              <Field
                component={TextField}
                name="name"
                label={t('Name')}
                fullWidth={true}
                onFocus={this.handleChangeFocus.bind(this)}
                onSubmit={this.handleSubmitField.bind(this)}
                helperText={
                  <SubscriptionFocus context={context} fieldName="name" />
                }
              />
              <Field
                component={MarkDownField}
                name="description"
                label={t('Description')}
                fullWidth={true}
                multiline={true}
                rows="4"
                style={{ marginTop: 20 }}
                onFocus={this.handleChangeFocus.bind(this)}
                onSubmit={this.handleSubmitField.bind(this)}
                helperText={
                  <SubscriptionFocus context={context} fieldName="description" />
                }
              />
              <KillChainPhasesField
                name="killChainPhases"
                style={{ marginTop: 20, width: '100%' }}
                setFieldValue={setFieldValue}
                helpertext={
                  <SubscriptionFocus
                    context={context}
                    fieldName="killChainPhases"
                  />
                }
                onChange={this.handleChangeKillChainPhases.bind(this)}
              />
              <CreatedByField
                name="createdBy"
                style={{ marginTop: 20, width: '100%' }}
                setFieldValue={setFieldValue}
                helpertext={
                  <SubscriptionFocus context={context} fieldName="createdBy" />
                }
                onChange={this.handleChangeCreatedBy.bind(this)}
              />
              <ObjectMarkingField
                name="objectMarking"
                style={{ marginTop: 20, width: '100%' }}
                helpertext={
                  <SubscriptionFocus
                    context={context}
                    fieldname="objectMarking"
                  />
                }
                onChange={this.handleChangeObjectMarking.bind(this)}
              />
            </Form>
          )}
        </Formik>
      );
    }
  }
  
  ToolEditionOverviewComponent.propTypes = {
    t: PropTypes.func,
    tool: PropTypes.object,
    context: PropTypes.array,
  };
  
  const ToolEditionOverview = createFragmentContainer(
    ToolEditionOverviewComponent,
    {
      tool: graphql`
        fragment ToolEditionOverview_tool on Tool {
          id
          name
          description
          createdBy {
            ... on Identity {
              id
              name
              entity_type
            }
          }
          killChainPhases {
            edges {
              node {
                id
                kill_chain_name
                phase_name
                x_opencti_order
              }
            }
          }
          objectMarking {
            edges {
              node {
                id
                definition
                definition_type
              }
            }
          }
        }
      `,
    },
  );
  
  export default compose(
    inject18n,
    withStyles(styles, { withTheme: true }),
  )(ToolEditionOverview);
  