github.com/argoproj/argo-cd@v1.8.7/ui/src/app/shared/components/yaml-editor/yaml-editor.tsx (about)

     1  import {ErrorNotification, NotificationType} from 'argo-ui';
     2  import * as jsYaml from 'js-yaml';
     3  import * as monacoEditor from 'monaco-editor';
     4  import * as React from 'react';
     5  
     6  import {Consumer} from '../../context';
     7  import {MonacoEditor} from '../monaco-editor';
     8  
     9  const jsonMergePatch = require('json-merge-patch');
    10  require('./yaml-editor.scss');
    11  
    12  export class YamlEditor<T> extends React.Component<
    13      {
    14          input: T;
    15          hideModeButtons?: boolean;
    16          initialEditMode?: boolean;
    17          onSave?: (patch: string, patchType: string) => Promise<any>;
    18          onCancel?: () => any;
    19          minHeight?: number;
    20      },
    21      {
    22          editing: boolean;
    23      }
    24  > {
    25      private model: monacoEditor.editor.ITextModel;
    26  
    27      constructor(props: any) {
    28          super(props);
    29          this.state = {editing: props.initialEditMode};
    30      }
    31  
    32      public render() {
    33          const props = this.props;
    34          const yaml = props.input ? jsYaml.safeDump(props.input) : '';
    35  
    36          return (
    37              <div className='yaml-editor'>
    38                  {!props.hideModeButtons && (
    39                      <div className='yaml-editor__buttons'>
    40                          {(this.state.editing && (
    41                              <Consumer>
    42                                  {ctx => (
    43                                      <React.Fragment>
    44                                          <button
    45                                              onClick={async () => {
    46                                                  try {
    47                                                      const updated = jsYaml.load(this.model.getLinesContent().join('\n'));
    48                                                      const patch = jsonMergePatch.generate(props.input, updated);
    49                                                      const unmounted = await this.props.onSave(JSON.stringify(patch || {}), 'application/merge-patch+json');
    50                                                      if (unmounted !== true) {
    51                                                          this.setState({editing: false});
    52                                                      }
    53                                                  } catch (e) {
    54                                                      ctx.notifications.show({
    55                                                          content: <ErrorNotification title='Unable to save changes' e={e} />,
    56                                                          type: NotificationType.Error
    57                                                      });
    58                                                  }
    59                                              }}
    60                                              className='argo-button argo-button--base'>
    61                                              Save
    62                                          </button>{' '}
    63                                          <button
    64                                              onClick={() => {
    65                                                  this.model.setValue(jsYaml.safeDump(props.input));
    66                                                  this.setState({editing: !this.state.editing});
    67                                                  if (props.onCancel) {
    68                                                      props.onCancel();
    69                                                  }
    70                                              }}
    71                                              className='argo-button argo-button--base-o'>
    72                                              Cancel
    73                                          </button>
    74                                      </React.Fragment>
    75                                  )}
    76                              </Consumer>
    77                          )) || (
    78                              <button onClick={() => this.setState({editing: true})} className='argo-button argo-button--base'>
    79                                  Edit
    80                              </button>
    81                          )}
    82                      </div>
    83                  )}
    84                  <MonacoEditor
    85                      minHeight={props.minHeight}
    86                      editor={{
    87                          input: {text: yaml, language: 'yaml'},
    88                          options: {readOnly: !this.state.editing, minimap: {enabled: false}},
    89                          getApi: api => {
    90                              this.model = api.getModel() as monacoEditor.editor.ITextModel;
    91                          }
    92                      }}
    93                  />
    94              </div>
    95          );
    96      }
    97  }