argo-cd

Форк
0
332 строки · 11.6 Кб
1
import * as React from 'react';
2
import * as ReactForm from 'react-form';
3
import {FormValue} from 'react-form';
4

5
/*
6
    This provide a way to may a form field to an array of items. It allows you to
7

8
    * Add a new (maybe duplicate) item.
9
    * Replace an item.
10
    * Remove an item.
11

12
    E.g.
13
    env:
14
    - name: FOO
15
      value: bar
16
    - name: BAZ
17
      value: qux
18
    # You can have dup items
19
    - name: FOO
20
      value: bar
21

22
    It does not allow re-ordering of elements (maybe in a v2).
23
 */
24

25
export interface NameValue {
26
    name: string;
27
    value: string;
28
}
29

30
export const NameValueEditor = (item: NameValue, onChange?: (item: NameValue) => any) => {
31
    return (
32
        <React.Fragment>
33
            <input
34
                // disable chrome autocomplete
35
                autoComplete='fake'
36
                className='argo-field'
37
                style={{width: '40%', borderColor: !onChange ? '#eff3f5' : undefined}}
38
                placeholder='Name'
39
                value={item.name}
40
                onChange={e => onChange({...item, name: e.target.value})}
41
                // onBlur={e=>onChange({...item, name: e.target.value})}
42
                title='Name'
43
                readOnly={!onChange}
44
            />
45
            &nbsp; = &nbsp;
46
            <input
47
                // disable chrome autocomplete
48
                autoComplete='fake'
49
                className='argo-field'
50
                style={{width: '40%', borderColor: !onChange ? '#eff3f5' : undefined}}
51
                placeholder='Value'
52
                value={item.value || ''}
53
                onChange={e => onChange({...item, value: e.target.value})}
54
                title='Value'
55
                readOnly={!onChange}
56
            />
57
            &nbsp;
58
        </React.Fragment>
59
    );
60
};
61

62
export const ValueEditor = (item: string, onChange: (item: string) => any) => {
63
    return (
64
        <input
65
            // disable chrome autocomplete
66
            autoComplete='fake'
67
            className='argo-field'
68
            style={{width: '40%', borderColor: !onChange ? '#eff3f5' : undefined}}
69
            placeholder='Value'
70
            value={item || ''}
71
            onChange={e => onChange(e.target.value)}
72
            title='Value'
73
            readOnly={!onChange}
74
        />
75
    );
76
};
77

78
interface Props<T> {
79
    items: T[];
80
    onChange: (items: T[]) => void;
81
    editor: (item: T, onChange: (updated: T) => any) => React.ReactNode;
82
}
83

84
export function ArrayInput<T>(props: Props<T>) {
85
    const addItem = (item: T) => {
86
        props.onChange([...props.items, item]);
87
    };
88

89
    const replaceItem = (item: T, i: number) => {
90
        const items = props.items.slice();
91
        items[i] = item;
92
        props.onChange(items);
93
    };
94

95
    const removeItem = (i: number) => {
96
        const items = props.items.slice();
97
        items.splice(i, 1);
98
        props.onChange(items);
99
    };
100

101
    return (
102
        <div className='argo-field' style={{border: 0, marginTop: '15px', zIndex: 1}}>
103
            {props.items.map((item, i) => (
104
                <div key={`item-${i}`} style={{marginBottom: '5px'}}>
105
                    {props.editor(item, (updated: T) => replaceItem(updated, i))}
106
                    &nbsp;
107
                    <button>
108
                        <i className='fa fa-times' style={{cursor: 'pointer'}} onClick={() => removeItem(i)} />
109
                    </button>{' '}
110
                </div>
111
            ))}
112
            {props.items.length === 0 && <label>No items</label>}
113
            <div>
114
                <button className='argo-button argo-button--base argo-button--short' onClick={() => addItem({} as T)}>
115
                    <i style={{cursor: 'pointer'}} className='fa fa-plus' />
116
                </button>
117
            </div>
118
        </div>
119
    );
120
}
121

122
export const ResetOrDeleteButton = (props: {
123
    isPluginPar: boolean;
124
    getValue: () => FormValue;
125
    name: string;
126
    index: number;
127
    setValue: (value: FormValue) => void;
128
    setAppParamsDeletedState: any;
129
}) => {
130
    const handleDeleteChange = () => {
131
        if (props.index >= 0) {
132
            props.setAppParamsDeletedState((val: string[]) => val.concat(props.name));
133
        }
134
    };
135

136
    const handleResetChange = () => {
137
        if (props.index >= 0) {
138
            const items = [...props.getValue()];
139
            items.splice(props.index, 1);
140
            props.setValue(items);
141
        }
142
    };
143

144
    const disabled = props.index === -1;
145

146
    const content = props.isPluginPar ? 'Reset' : 'Delete';
147
    let tooltip = '';
148
    if (content === 'Reset' && !disabled) {
149
        tooltip = 'Resets the parameter to the value provided by the plugin. This removes the parameter override from the application manifest';
150
    } else if (content === 'Delete' && !disabled) {
151
        tooltip = 'Deletes this parameter values from the application manifest.';
152
    }
153

154
    return (
155
        <button
156
            className='argo-button argo-button--base'
157
            disabled={disabled}
158
            title={tooltip}
159
            style={{fontSize: '12px', display: 'flex', marginLeft: 'auto', marginTop: '8px'}}
160
            onClick={props.isPluginPar ? handleResetChange : handleDeleteChange}>
161
            {content}
162
        </button>
163
    );
164
};
165

166
export const ArrayInputField = ReactForm.FormField((props: {fieldApi: ReactForm.FieldApi}) => {
167
    const {
168
        fieldApi: {getValue, setValue}
169
    } = props;
170
    return <ArrayInput editor={NameValueEditor} items={getValue() || []} onChange={setValue} />;
171
});
172

173
export const ArrayValueField = ReactForm.FormField(
174
    (props: {fieldApi: ReactForm.FieldApi; name: string; defaultVal: string[]; isPluginPar: boolean; setAppParamsDeletedState: any}) => {
175
        const {
176
            fieldApi: {getValue, setValue}
177
        } = props;
178

179
        let liveParamArray;
180
        const liveParam = getValue()?.find((val: {name: string; array: object}) => val.name === props.name);
181
        if (liveParam) {
182
            liveParamArray = liveParam?.array ?? [];
183
        }
184
        const index = getValue()?.findIndex((val: {name: string; array: object}) => val.name === props.name) ?? -1;
185
        const values = liveParamArray ?? props.defaultVal ?? [];
186

187
        return (
188
            <React.Fragment>
189
                <ResetOrDeleteButton
190
                    isPluginPar={props.isPluginPar}
191
                    getValue={getValue}
192
                    name={props.name}
193
                    index={index}
194
                    setValue={setValue}
195
                    setAppParamsDeletedState={props.setAppParamsDeletedState}
196
                />
197
                <ArrayInput
198
                    editor={ValueEditor}
199
                    items={values || []}
200
                    onChange={change => {
201
                        const update = change.map((val: string | object) => (typeof val !== 'string' ? '' : val));
202
                        if (index >= 0) {
203
                            getValue()[index].array = update;
204
                            setValue([...getValue()]);
205
                        } else {
206
                            setValue([...(getValue() || []), {name: props.name, array: update}]);
207
                        }
208
                    }}
209
                />
210
            </React.Fragment>
211
        );
212
    }
213
);
214

215
export const StringValueField = ReactForm.FormField(
216
    (props: {fieldApi: ReactForm.FieldApi; name: string; defaultVal: string; isPluginPar: boolean; setAppParamsDeletedState: any}) => {
217
        const {
218
            fieldApi: {getValue, setValue}
219
        } = props;
220
        let liveParamString;
221
        const liveParam = getValue()?.find((val: {name: string; string: string}) => val.name === props.name);
222
        if (liveParam) {
223
            liveParamString = liveParam?.string ? liveParam?.string : '';
224
        }
225
        const values = liveParamString ?? props.defaultVal ?? '';
226
        const index = getValue()?.findIndex((val: {name: string; string: string}) => val.name === props.name) ?? -1;
227

228
        return (
229
            <React.Fragment>
230
                <ResetOrDeleteButton
231
                    isPluginPar={props.isPluginPar}
232
                    getValue={getValue}
233
                    name={props.name}
234
                    index={index}
235
                    setValue={setValue}
236
                    setAppParamsDeletedState={props.setAppParamsDeletedState}
237
                />
238
                <div>
239
                    <input
240
                        // disable chrome autocomplete
241
                        autoComplete='fake'
242
                        className='argo-field'
243
                        style={{width: '40%', display: 'inline-block', marginTop: 25}}
244
                        placeholder='Value'
245
                        value={values || ''}
246
                        onChange={e => {
247
                            if (index >= 0) {
248
                                getValue()[index].string = e.target.value;
249
                                setValue([...getValue()]);
250
                            } else {
251
                                setValue([...(getValue() || []), {name: props.name, string: e.target.value}]);
252
                            }
253
                        }}
254
                        title='Value'
255
                    />
256
                </div>
257
            </React.Fragment>
258
        );
259
    }
260
);
261

262
export const MapInputField = ReactForm.FormField((props: {fieldApi: ReactForm.FieldApi}) => {
263
    const {
264
        fieldApi: {getValue, setValue}
265
    } = props;
266
    const items = new Array<NameValue>();
267
    const map = getValue() || {};
268
    Object.keys(map).forEach(key => items.push({name: key, value: map[key]}));
269
    return (
270
        <ArrayInput
271
            editor={NameValueEditor}
272
            items={items}
273
            onChange={array => {
274
                const newMap = {} as any;
275
                array.forEach(item => (newMap[item.name || ''] = item.value || ''));
276
                setValue(newMap);
277
            }}
278
        />
279
    );
280
});
281

282
export const MapValueField = ReactForm.FormField(
283
    (props: {fieldApi: ReactForm.FieldApi; name: string; defaultVal: Map<string, string>; isPluginPar: boolean; setAppParamsDeletedState: any}) => {
284
        const {
285
            fieldApi: {getValue, setValue}
286
        } = props;
287
        const items = new Array<NameValue>();
288
        const liveParam = getValue()?.find((val: {name: string; map: object}) => val.name === props.name);
289
        const index = getValue()?.findIndex((val: {name: string; map: object}) => val.name === props.name) ?? -1;
290
        if (liveParam) {
291
            liveParam.map = liveParam.map ? liveParam.map : new Map<string, string>();
292
        }
293
        if (liveParam?.array) {
294
            items.push(...liveParam.array);
295
        } else {
296
            const map = liveParam?.map ?? props.defaultVal ?? new Map<string, string>();
297
            Object.keys(map).forEach(item => items.push({name: item || '', value: map[item] || ''}));
298
            if (liveParam?.map) {
299
                getValue()[index].array = items;
300
            }
301
        }
302

303
        return (
304
            <React.Fragment>
305
                <ResetOrDeleteButton
306
                    isPluginPar={props.isPluginPar}
307
                    getValue={getValue}
308
                    name={props.name}
309
                    index={index}
310
                    setValue={setValue}
311
                    setAppParamsDeletedState={props.setAppParamsDeletedState}
312
                />
313

314
                <ArrayInput
315
                    editor={NameValueEditor}
316
                    items={items || []}
317
                    onChange={change => {
318
                        if (index === -1) {
319
                            getValue().push({
320
                                name: props.name,
321
                                array: change
322
                            });
323
                        } else {
324
                            getValue()[index].array = change;
325
                        }
326
                        setValue([...getValue()]);
327
                    }}
328
                />
329
            </React.Fragment>
330
        );
331
    }
332
);
333

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.