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 }