argo-cd

Форк
0
162 строки · 6.4 Кб
1
import {Checkbox, Select, Tooltip} from 'argo-ui';
2
import * as classNames from 'classnames';
3
import * as React from 'react';
4
import * as ReactForm from 'react-form';
5

6
import './application-sync-options.scss';
7

8
export const REPLACE_WARNING = `The resources will be synced using 'kubectl replace/create' command that is a potentially destructive action and might cause resources recreation.`;
9
export const FORCE_WARNING = `The resources will be synced using '--force' that is a potentially destructive action and will immediately remove resources from the API and bypasses graceful deletion. Immediate deletion of some resources may result in inconsistency or data loss.`;
10
export const PRUNE_ALL_WARNING = `The resources will be synced using '--prune', and all resources are marked to be pruned. Only continue if you want to delete all of the Application's resources.`;
11

12
export interface ApplicationSyncOptionProps {
13
    options: string[];
14
    onChanged: (updatedOptions: string[]) => any;
15
    id?: string;
16
}
17

18
function selectOption(name: string, label: string, defaultVal: string, values: string[], props: ApplicationSyncOptionProps) {
19
    const options = [...(props.options || [])];
20
    const prefix = `${name}=`;
21
    const index = options.findIndex(item => item.startsWith(prefix));
22
    const val = index < 0 ? defaultVal : options[index].substr(prefix.length);
23

24
    return (
25
        <div className='application-sync-options__select'>
26
            <label>{label}:</label>
27
            <Select
28
                value={val}
29
                options={values}
30
                onChange={opt => {
31
                    const newValue = `${name}=${opt.value}`;
32
                    if (index < 0) {
33
                        props.onChanged(options.concat(newValue));
34
                    } else {
35
                        options[index] = newValue;
36
                        props.onChanged(options);
37
                    }
38
                }}
39
            />
40
        </div>
41
    );
42
}
43

44
function booleanOption(name: string, label: string, defaultVal: boolean, props: ApplicationSyncOptionProps, invert: boolean, warning: string = null) {
45
    const options = [...(props.options || [])];
46
    const prefix = `${name}=`;
47
    const index = options.findIndex(item => item.startsWith(prefix));
48
    const checked = index < 0 ? defaultVal : options[index].substring(prefix.length) === (invert ? 'false' : 'true');
49
    return (
50
        <React.Fragment>
51
            <Checkbox
52
                id={`sync-option-${name}-${props.id}`}
53
                checked={checked}
54
                onChange={(val: boolean) => {
55
                    if (index < 0) {
56
                        props.onChanged(options.concat(`${name}=${invert ? !val : val}`));
57
                    } else {
58
                        options.splice(index, 1);
59
                        props.onChanged(options);
60
                    }
61
                }}
62
            />
63
            <label htmlFor={`sync-option-${name}-${props.id}`}>{label}</label>{' '}
64
            {warning && (
65
                <>
66
                    <Tooltip content={warning}>
67
                        <i className='fa fa-exclamation-triangle' />
68
                    </Tooltip>
69
                    {checked && <div className='application-sync-options__warning'>{warning}</div>}
70
                </>
71
            )}
72
        </React.Fragment>
73
    );
74
}
75

76
enum ManualSyncFlags {
77
    Prune = 'Prune',
78
    DryRun = 'Dry Run',
79
    ApplyOnly = 'Apply Only',
80
    Force = 'Force'
81
}
82

83
export interface SyncFlags {
84
    Prune: boolean;
85
    DryRun: boolean;
86
    ApplyOnly: boolean;
87
    Force: boolean;
88
}
89

90
const syncOptions: Array<(props: ApplicationSyncOptionProps) => React.ReactNode> = [
91
    props => booleanOption('Validate', 'Skip Schema Validation', false, props, true),
92
    props => booleanOption('CreateNamespace', 'Auto-Create Namespace', false, props, false),
93
    props => booleanOption('PruneLast', 'Prune Last', false, props, false),
94
    props => booleanOption('ApplyOutOfSyncOnly', 'Apply Out of Sync Only', false, props, false),
95
    props => booleanOption('RespectIgnoreDifferences', 'Respect Ignore Differences', false, props, false),
96
    props => booleanOption('ServerSideApply', 'Server-Side Apply', false, props, false),
97
    props => selectOption('PrunePropagationPolicy', 'Prune Propagation Policy', 'foreground', ['foreground', 'background', 'orphan'], props)
98
];
99

100
const optionStyle = {marginTop: '0.5em'};
101

102
export const ApplicationSyncOptions = (props: ApplicationSyncOptionProps) => (
103
    <div className='row application-sync-options'>
104
        {syncOptions.map((render, i) => (
105
            <div
106
                key={i}
107
                style={optionStyle}
108
                className={classNames('small-12', {
109
                    'large-6': i < syncOptions.length - 1
110
                })}>
111
                {render(props)}
112
            </div>
113
        ))}
114
        <div className='small-12' style={optionStyle}>
115
            {booleanOption('Replace', 'Replace', false, props, false, REPLACE_WARNING)}
116
        </div>
117
    </div>
118
);
119

120
export const ApplicationManualSyncFlags = ReactForm.FormField((props: {fieldApi: ReactForm.FieldApi; id?: string}) => {
121
    const {
122
        fieldApi: {getValue, setValue, setTouched}
123
    } = props;
124
    const val = getValue() || false;
125
    return (
126
        <div style={optionStyle}>
127
            {Object.keys(ManualSyncFlags).map(flag => (
128
                <React.Fragment key={flag}>
129
                    <Checkbox
130
                        id={`sync-option-${flag}-${props.id}`}
131
                        checked={val[flag]}
132
                        onChange={(newVal: boolean) => {
133
                            setTouched(true);
134
                            const update = {...val};
135
                            update[flag] = newVal;
136
                            setValue(update);
137
                        }}
138
                    />
139
                    <label htmlFor={`sync-option-${flag}-${props.id}`}>{ManualSyncFlags[flag as keyof typeof ManualSyncFlags]}</label>{' '}
140
                </React.Fragment>
141
            ))}
142
        </div>
143
    );
144
});
145

146
export const ApplicationSyncOptionsField = ReactForm.FormField((props: {fieldApi: ReactForm.FieldApi}) => {
147
    const {
148
        fieldApi: {getValue, setValue, setTouched}
149
    } = props;
150
    const val = getValue() || [];
151
    return (
152
        <div className='argo-field' style={{borderBottom: '0'}}>
153
            <ApplicationSyncOptions
154
                options={val}
155
                onChanged={opts => {
156
                    setTouched(true);
157
                    setValue(opts);
158
                }}
159
            />
160
        </div>
161
    );
162
});
163

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

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

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

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