argo-cd

Форк
0
166 строк · 8.4 Кб
1
import {ErrorNotification, NotificationType} from 'argo-ui';
2
import * as classNames from 'classnames';
3
import * as React from 'react';
4
import {Form, FormApi} from 'react-form';
5
import {helpTip} from '../../../applications/components/utils';
6
import {Consumer} from '../../context';
7
import {Spinner} from '../spinner';
8

9
export interface EditablePanelItem {
10
    title: string;
11
    customTitle?: string | React.ReactNode;
12
    key?: string;
13
    before?: React.ReactNode;
14
    view: string | React.ReactNode;
15
    edit?: (formApi: FormApi) => React.ReactNode;
16
    titleEdit?: (formApi: FormApi) => React.ReactNode;
17
}
18

19
export interface EditablePanelProps<T> {
20
    title?: string | React.ReactNode;
21
    values: T;
22
    validate?: (values: T) => any;
23
    save?: (input: T, query: {validate?: boolean}) => Promise<any>;
24
    items: EditablePanelItem[];
25
    onModeSwitch?: () => any;
26
    noReadonlyMode?: boolean;
27
    view?: string | React.ReactNode;
28
    edit?: (formApi: FormApi) => React.ReactNode;
29
    hasMultipleSources?: boolean;
30
}
31

32
interface EditablePanelState {
33
    edit: boolean;
34
    saving: boolean;
35
}
36

37
require('./editable-panel.scss');
38

39
export class EditablePanel<T = {}> extends React.Component<EditablePanelProps<T>, EditablePanelState> {
40
    private formApi: FormApi;
41

42
    constructor(props: EditablePanelProps<T>) {
43
        super(props);
44
        this.state = {edit: !!props.noReadonlyMode, saving: false};
45
    }
46

47
    public UNSAFE_componentWillReceiveProps(nextProps: EditablePanelProps<T>) {
48
        if (this.formApi && JSON.stringify(this.props.values) !== JSON.stringify(nextProps.values)) {
49
            if (!!nextProps.noReadonlyMode) {
50
                this.formApi.setAllValues(nextProps.values);
51
            }
52
        }
53
    }
54

55
    public render() {
56
        return (
57
            <Consumer>
58
                {ctx => (
59
                    <div className={classNames('white-box editable-panel', {'editable-panel--disabled': this.state.saving})}>
60
                        <div className='white-box__details'>
61
                            {!this.props.noReadonlyMode && this.props.save && (
62
                                <div className='editable-panel__buttons'>
63
                                    {!this.state.edit && (
64
                                        <button
65
                                            onClick={() => {
66
                                                this.setState({edit: true});
67
                                                this.onModeSwitch();
68
                                            }}
69
                                            disabled={this.props.hasMultipleSources}
70
                                            className='argo-button argo-button--base'>
71
                                            {this.props.hasMultipleSources &&
72
                                                helpTip('Parameters are not editable for applications with multiple sources. You can edit them in the "Manifest" tab.')}{' '}
73
                                            Edit
74
                                        </button>
75
                                    )}
76
                                    {this.state.edit && (
77
                                        <React.Fragment>
78
                                            <button
79
                                                disabled={this.state.saving}
80
                                                onClick={() => !this.state.saving && this.formApi.submitForm(null)}
81
                                                className='argo-button argo-button--base'>
82
                                                <Spinner show={this.state.saving} style={{marginRight: '5px'}} />
83
                                                Save
84
                                            </button>{' '}
85
                                            <button
86
                                                onClick={() => {
87
                                                    this.setState({edit: false});
88
                                                    this.onModeSwitch();
89
                                                }}
90
                                                className='argo-button argo-button--base-o'>
91
                                                Cancel
92
                                            </button>
93
                                        </React.Fragment>
94
                                    )}
95
                                </div>
96
                            )}
97
                            {this.props.title && <p>{this.props.title}</p>}
98
                            {(!this.state.edit && (
99
                                <React.Fragment>
100
                                    {this.props.view}
101
                                    {this.props.items
102
                                        .filter(item => item.view)
103
                                        .map(item => (
104
                                            <React.Fragment key={item.key || item.title}>
105
                                                {item.before}
106
                                                <div className='row white-box__details-row'>
107
                                                    <div className='columns small-3'>{item.customTitle || item.title}</div>
108
                                                    <div className='columns small-9'>{item.view}</div>
109
                                                </div>
110
                                            </React.Fragment>
111
                                        ))}
112
                                </React.Fragment>
113
                            )) || (
114
                                <Form
115
                                    getApi={api => (this.formApi = api)}
116
                                    formDidUpdate={async form => {
117
                                        if (this.props.noReadonlyMode && this.props.save) {
118
                                            await this.props.save(form.values as any, {});
119
                                        }
120
                                    }}
121
                                    onSubmit={async input => {
122
                                        try {
123
                                            this.setState({saving: true});
124
                                            await this.props.save(input as any, {});
125
                                            this.setState({edit: false, saving: false});
126
                                            this.onModeSwitch();
127
                                        } catch (e) {
128
                                            ctx.notifications.show({
129
                                                content: <ErrorNotification title='Unable to save changes' e={e} />,
130
                                                type: NotificationType.Error
131
                                            });
132
                                        } finally {
133
                                            this.setState({saving: false});
134
                                        }
135
                                    }}
136
                                    defaultValues={this.props.values}
137
                                    validateError={this.props.validate}>
138
                                    {api => (
139
                                        <React.Fragment>
140
                                            {this.props.edit && this.props.edit(api)}
141
                                            {this.props.items.map(item => (
142
                                                <React.Fragment key={item.key || item.title}>
143
                                                    {item.before}
144
                                                    <div className='row white-box__details-row'>
145
                                                        <div className='columns small-3'>{(item.titleEdit && item.titleEdit(api)) || item.customTitle || item.title}</div>
146
                                                        <div className='columns small-9'>{(item.edit && item.edit(api)) || item.view}</div>
147
                                                    </div>
148
                                                </React.Fragment>
149
                                            ))}
150
                                        </React.Fragment>
151
                                    )}
152
                                </Form>
153
                            )}
154
                        </div>
155
                    </div>
156
                )}
157
            </Consumer>
158
        );
159
    }
160

161
    private onModeSwitch() {
162
        if (this.props.onModeSwitch) {
163
            this.props.onModeSwitch();
164
        }
165
    }
166
}
167

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

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

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

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