EditExperimentParam.tsx 9.06 KB
Newer Older
1
2
import React, { useState, useCallback, useContext } from 'react';
import axios from 'axios';
3
import { Dropdown } from '@fluentui/react';
4
import { EXPERIMENT } from '../../../static/datamodel';
5
import { AppContext } from '../../../App';
6
import { EditExpeParamContext } from './context';
7
8
import { durationUnit } from '../overviewConst';
import { MANAGER_IP, MAX_TRIAL_NUMBERS } from '../../../static/const';
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import { Edit, CheckMark, Cancel } from '../../buttons/Icon';
import MessageInfo from '../../modals/MessageInfo';
import '../../../static/style/overview/count.scss';

const DurationInputRef = React.createRef<HTMLInputElement>();

export const EditExperimentParam = (): any => {
    const [isShowPencil, setShowPencil] = useState(true);
    const [isShowSucceedInfo, setShowSucceedInfo] = useState(false);
    const [typeInfo, setTypeInfo] = useState('');
    const [info, setInfo] = useState('');
    const showPencil = useCallback(() => {
        setShowPencil(true);
    }, []);
    const hidePencil = useCallback(() => {
        setShowPencil(false);
    }, []);
    const showSucceedInfo = useCallback(() => setShowSucceedInfo(true), []);
    const hideSucceedInfo = useCallback(() => {
        setShowSucceedInfo(false);
    }, []);
    const { title, field, editType, maxExecDuration, maxTrialNum, trialConcurrency, updateOverviewPage } = useContext(
        EditExpeParamContext
    );
33
34
    const { maxDurationUnit, changeMaxDurationUnit } = useContext(AppContext);
    const [unit, setUnit] = useState(maxDurationUnit);
35
36
37
38
39
    let defaultVal = '';
    let editVal = '';
    if (title === 'Max duration') {
        defaultVal = maxExecDuration;
        editVal = maxExecDuration;
40
    } else if (title === MAX_TRIAL_NUMBERS) {
41
42
43
44
45
46
47
48
49
50
51
52
        defaultVal = maxTrialNum.toString();
        editVal = maxTrialNum.toString();
    } else {
        defaultVal = trialConcurrency.toString();
        editVal = trialConcurrency.toString();
    }
    const [editInputVal, setEditValInput] = useState(editVal);

    function setInputVal(event: any): void {
        setEditValInput(event.target.value);
    }

53
54
55
56
57
58
59
60
61
62
63
    function showMessageInfo(info: string, typeInfo: string): any {
        setInfo(info);
        setTypeInfo(typeInfo);
        showSucceedInfo();
        setTimeout(hideSucceedInfo, 2000);
    }

    function updateUnit(event: React.FormEvent<HTMLDivElement>, item: any): void {
        if (item !== undefined) {
            setUnit(item.key);
        }
64
65
66
67
68
69
    }

    async function confirmEdit(): Promise<void> {
        const isMaxDuration = title === 'Max duration';
        const newProfile = Object.assign({}, EXPERIMENT.profile);
        let beforeParam = '';
70
71
72
73
74
75
76
77
78
79
80
81
        if (isMaxDuration) {
            if (!editInputVal.match(/^\d+(?=\.{0,1}\d+$|$)/)) {
                showMessageInfo('Please enter a number!', 'error');
                setEditValInput(defaultVal);
                return;
            }
        } else {
            if (!editInputVal.match(/^[1-9]\d*$/)) {
                showMessageInfo('Please enter a positive integer!', 'error');
                setEditValInput(defaultVal);
                return;
            }
82
83
84
        }
        if (isMaxDuration) {
            beforeParam = maxExecDuration;
85
        } else if (title === MAX_TRIAL_NUMBERS) {
86
87
88
89
            beforeParam = maxTrialNum.toString();
        } else {
            beforeParam = trialConcurrency.toString();
        }
90

91
        if (editInputVal === beforeParam) {
92
93
94
95
96
97
98
99
100
            if (isMaxDuration) {
                if (maxDurationUnit === unit) {
                    showMessageInfo(`Trial ${field} has not changed`, 'error');
                    return;
                }
            } else {
                showMessageInfo(`Trial ${field} has not changed`, 'error');
                return;
            }
101
102
        }
        if (isMaxDuration) {
103
104
105
106
107
108
109
110
            const maxDura = JSON.parse(editInputVal);
            if (unit === 'm') {
                newProfile.params[field] = maxDura * 60;
            } else if (unit === 'h') {
                newProfile.params[field] = maxDura * 3600;
            } else {
                newProfile.params[field] = maxDura * 24 * 60 * 60;
            }
111
112
113
114
115
116
117
118
119
120
        } else {
            newProfile.params[field] = parseInt(editInputVal, 10);
        }
        // rest api, modify trial concurrency value
        try {
            const res = await axios.put(`${MANAGER_IP}/experiment`, newProfile, {
                // eslint-disable-next-line @typescript-eslint/camelcase
                params: { update_type: editType }
            });
            if (res.status === 200) {
121
122
                showMessageInfo(`Successfully updated experiment's ${field}`, 'success');
                changeMaxDurationUnit(unit);
123
124
125
126
127
128
129
130
131
132
133
            }
        } catch (error) {
            if (error.response && error.response.data.error) {
                showMessageInfo(`Failed to update trial ${field}\n${error.response.data.error}`, 'error');
            } else if (error.response) {
                showMessageInfo(`Failed to update trial ${field}\nServer responsed ${error.response.status}`, 'error');
            } else if (error.message) {
                showMessageInfo(`Failed to update trial ${field}\n${error.message}`, 'error');
            } else {
                showMessageInfo(`Failed to update trial ${field}\nUnknown error`, 'error');
            }
134
            setEditValInput(defaultVal);
135
136
137
138
139
        }
        showPencil();
        updateOverviewPage();
    }

140
141
142
143
    function cancelEdit(): void {
        setEditValInput(defaultVal);
        showPencil();
        setUnit(maxDurationUnit);
144
145
    }

146
147
148
149
150
151
152
153
154
155
156
    function convertUnit(val: string): string {
        if (val === 'd') {
            return 'day';
        } else if (val === 'h') {
            return 'hour';
        } else if (val === 'm') {
            return 'min';
        } else {
            return val;
        }
    }
Lijiaoa's avatar
Lijiaoa committed
157

158
    return (
159
160
        <AppContext.Consumer>
            {(values): React.ReactNode => {
161
                return (
162
163
164
165
166
167
168
169
170
                    <EditExpeParamContext.Consumer>
                        {(value): React.ReactNode => {
                            let editClassName = '';
                            if (value.field === 'maxExecDuration') {
                                editClassName = isShowPencil ? 'noEditDuration' : 'editDuration';
                            }
                            return (
                                <React.Fragment>
                                    <div className={`${editClassName} editparam`}>
171
                                        <div className='title'>{value.title}</div>
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
                                        <input
                                            className={`${value.field} editparam-Input`}
                                            ref={DurationInputRef}
                                            disabled={isShowPencil ? true : false}
                                            value={editInputVal}
                                            onChange={setInputVal}
                                        />
                                        {isShowPencil && title === 'Max duration' && (
                                            <span>{convertUnit(values.maxDurationUnit)}</span>
                                        )}
                                        {!isShowPencil && title === 'Max duration' && (
                                            <Dropdown
                                                selectedKey={unit}
                                                options={durationUnit}
                                                className='editparam-dropdown'
                                                onChange={updateUnit}
                                            />
                                        )}
                                        {isShowPencil && (
191
                                            <span className='edit cursor' onClick={hidePencil}>
192
193
194
195
196
                                                {Edit}
                                            </span>
                                        )}
                                        {!isShowPencil && (
                                            <span className='series'>
197
                                                <span className='confirm cursor' onClick={confirmEdit}>
198
199
                                                    {CheckMark}
                                                </span>
200
                                                <span className='cancel cursor' onClick={cancelEdit}>
201
202
203
204
                                                    {Cancel}
                                                </span>
                                            </span>
                                        )}
205

206
207
208
209
210
211
212
213
                                        {isShowSucceedInfo && (
                                            <MessageInfo className='info' typeInfo={typeInfo} info={info} />
                                        )}
                                    </div>
                                </React.Fragment>
                            );
                        }}
                    </EditExpeParamContext.Consumer>
214
215
                );
            }}
216
        </AppContext.Consumer>
217
218
    );
};