github.com/argoproj/argo-cd/v3@v3.2.1/ui/src/app/applications/components/application-parameters/application-parameters-source.tsx (about) 1 import * as classNames from 'classnames'; 2 import * as React from 'react'; 3 import {ReactNode, useContext, useState} from 'react'; 4 import {FormApi} from 'react-form'; 5 import {EditablePanelItem} from '../../../shared/components'; 6 import {EditableSection} from '../../../shared/components/editable-panel/editable-section'; 7 import {Context} from '../../../shared/context'; 8 import '../../../shared/components/editable-panel/editable-panel.scss'; 9 10 export interface ApplicationParametersPanelProps<T> { 11 floatingTitle?: string | ReactNode; 12 titleTop?: string | ReactNode; 13 titleBottom?: string | ReactNode; 14 index: number; 15 valuesTop?: T; 16 valuesBottom?: T; 17 validateTop?: (values: T) => any; 18 validateBottom?: (values: T) => any; 19 saveTop?: (input: T, query: {validate?: boolean}) => Promise<any>; 20 saveBottom?: (input: T, query: {validate?: boolean}) => Promise<any>; 21 itemsTop?: EditablePanelItem[]; 22 itemsBottom?: EditablePanelItem[]; 23 onModeSwitch?: () => any; 24 viewTop?: string | ReactNode; 25 viewBottom?: string | ReactNode; 26 editTop?: (formApi: FormApi) => ReactNode; 27 editBottom?: (formApi: FormApi) => ReactNode; 28 numberOfSources?: number; 29 noReadonlyMode?: boolean; 30 collapsible?: boolean; 31 deleteSource: () => void; 32 } 33 34 // Currently two editable sections, but can be modified to support N panels in general. This should be part of a white-box, editable-panel. 35 export function ApplicationParametersSource<T = {}>(props: ApplicationParametersPanelProps<T>) { 36 const [editTop, setEditTop] = useState(!!props.noReadonlyMode); 37 const [editBottom, setEditBottom] = useState(!!props.noReadonlyMode); 38 const [savingTop] = useState(false); 39 const ctx = useContext(Context); 40 41 const onModeSwitch = () => { 42 if (props.onModeSwitch) { 43 props.onModeSwitch(); 44 } 45 }; 46 47 return ( 48 <div className={classNames({'editable-panel--disabled': savingTop})}> 49 {props.floatingTitle && <div className='white-box--additional-top-space editable-panel__sticky-title'>{props.floatingTitle}</div>} 50 <EditableSection 51 uniqueId={'top_' + props.index} 52 title={props.titleTop} 53 view={props.viewTop} 54 values={props.valuesTop} 55 items={props.itemsTop} 56 validate={props.validateTop} 57 save={props.saveTop} 58 onModeSwitch={() => onModeSwitch()} 59 noReadonlyMode={props.noReadonlyMode} 60 edit={props.editTop} 61 collapsible={props.collapsible} 62 ctx={ctx} 63 isTopSection={true} 64 disabledState={editTop || editTop === null} 65 disabledDelete={props.numberOfSources <= 1} 66 updateButtons={editClicked => { 67 setEditBottom(editClicked); 68 }} 69 deleteSource={props.deleteSource} 70 /> 71 {props.itemsTop && ( 72 <> 73 <div className='row white-box__details-row'> 74 <p> </p> 75 </div> 76 <div className='white-box--no-padding editable-panel__divider' /> 77 </> 78 )} 79 <EditableSection 80 uniqueId={'bottom_' + props.index} 81 title={props.titleBottom} 82 view={props.viewBottom} 83 values={props.valuesBottom} 84 items={props.itemsBottom} 85 validate={props.validateBottom} 86 save={props.saveBottom} 87 onModeSwitch={() => onModeSwitch()} 88 noReadonlyMode={props.noReadonlyMode} 89 edit={props.editBottom} 90 collapsible={props.collapsible} 91 ctx={ctx} 92 isTopSection={false} 93 disabledState={editBottom || editBottom === null} 94 updateButtons={editClicked => { 95 setEditTop(editClicked); 96 }} 97 /> 98 </div> 99 ); 100 }