Skip to content

Commit 298b0f8

Browse files
refactor(Tablet): separate TabletControls
1 parent 78838eb commit 298b0f8

File tree

3 files changed

+162
-143
lines changed

3 files changed

+162
-143
lines changed

src/containers/Tablet/Tablet.js

Lines changed: 3 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,10 @@ import {Icon} from '../../components/Icon';
1313
import {EmptyState} from '../../components/EmptyState';
1414
import {Link as ExternalLink, Button, Loader} from '@gravity-ui/uikit';
1515
import {CriticalActionDialog} from '../../components/CriticalActionDialog';
16-
import routes, {createHref} from '../../routes';
17-
import {getDefaultNodePath} from '../Node/NodePages';
1816

1917
import {TabletTable} from './TabletTable';
2018
import {TabletInfo} from './TabletInfo';
19+
import {TabletControls} from './TabletControls';
2120

2221
import './Tablet.scss';
2322

@@ -53,19 +52,10 @@ class Tablet extends React.Component {
5352
}
5453

5554
state = {
56-
typeVisibleDialog: null,
57-
dialogVisible: false,
5855
isFirstFetchData: true,
5956
tenantPath: '-',
60-
disableTabletActions: false,
6157
};
6258

63-
makeShowDialog = (type) => () => this.setState({dialogVisible: true, typeVisibleDialog: type});
64-
showKillDialog = this.makeShowDialog('kill');
65-
showStopDialog = this.makeShowDialog('stop');
66-
showResumeDialog = this.makeShowDialog('resume');
67-
hideDialog = () => this.setState({dialogVisible: false, typeVisibleDialog: null});
68-
6959
fetchTabletInfo = () => {
7060
const {version, id} = this.props;
7161
const {isFirstFetchData} = this.state;
@@ -85,9 +75,7 @@ class Tablet extends React.Component {
8575
}
8676

8777
this.fetcher = setInterval(() => {
88-
this.props.getTablet(id).then(() => {
89-
this.setState({disableTabletActions: false});
90-
});
78+
this.props.getTablet(id);
9179
}, 10000);
9280
}
9381
};
@@ -126,104 +114,6 @@ class Tablet extends React.Component {
126114
</li>
127115
);
128116
};
129-
_onKillClick = () => {
130-
const {TabletId: id} = this.props.tablet;
131-
132-
this.setState({disableTabletActions: true});
133-
134-
return window.api.killTablet(id);
135-
};
136-
_onStopClick = () => {
137-
const {TabletId: id, HiveId: hiveId} = this.props.tablet;
138-
139-
this.setState({disableTabletActions: true});
140-
141-
return window.api.stopTablet(id, hiveId);
142-
};
143-
_onResumeClick = () => {
144-
const {TabletId: id, HiveId: hiveId} = this.props.tablet;
145-
146-
this.setState({disableTabletActions: true});
147-
148-
return window.api.resumeTablet(id, hiveId);
149-
};
150-
renderDialog = () => {
151-
const {dialogVisible, typeVisibleDialog} = this.state;
152-
153-
if (!dialogVisible) {
154-
return null;
155-
}
156-
157-
switch (typeVisibleDialog) {
158-
case 'kill': {
159-
return (
160-
<CriticalActionDialog
161-
visible={dialogVisible}
162-
text="The tablet will be restarted. Do you want to proceed?"
163-
onClose={this.hideDialog}
164-
onConfirm={this._onKillClick}
165-
/>
166-
);
167-
}
168-
case 'stop': {
169-
return (
170-
<CriticalActionDialog
171-
visible={dialogVisible}
172-
text="The tablet will be stopped. Do you want to proceed?"
173-
onClose={this.hideDialog}
174-
onConfirm={this._onStopClick}
175-
/>
176-
);
177-
}
178-
case 'resume': {
179-
return (
180-
<CriticalActionDialog
181-
visible={dialogVisible}
182-
text="The tablet will be resumed. Do you want to proceed?"
183-
onClose={this.hideDialog}
184-
onConfirm={this._onResumeClick}
185-
/>
186-
);
187-
}
188-
default:
189-
return null;
190-
}
191-
};
192-
193-
hasHiveId = () => {
194-
const {tablet} = this.props;
195-
const {HiveId} = tablet;
196-
197-
return HiveId && HiveId !== '0';
198-
};
199-
200-
isDisabledResume = () => {
201-
const {tablet} = this.props;
202-
const {disableTabletActions} = this.state;
203-
204-
if (disableTabletActions) {
205-
return true;
206-
}
207-
208-
return tablet.State !== 'Stopped' && tablet.State !== 'Dead';
209-
};
210-
211-
isDisabledKill = () => {
212-
const {disableTabletActions} = this.state;
213-
214-
return disableTabletActions;
215-
};
216-
217-
isDisabledStop = () => {
218-
const {tablet} = this.props;
219-
const {disableTabletActions} = this.state;
220-
221-
if (disableTabletActions) {
222-
return true;
223-
}
224-
225-
return tablet.State === 'Stopped' || tablet.State === 'Deleted';
226-
};
227117

228118
renderTablet = () => {
229119
const {tablet, tenantPath} = this.props;
@@ -257,42 +147,12 @@ class Tablet extends React.Component {
257147
{(tablet.Master || tablet.Leader) && <Tag text="Leader" type="blue" />}
258148
</div>
259149
<TabletInfo tablet={tablet} tenantPath={tenantPath} />
260-
<div className={b('controls')}>
261-
<Button
262-
onClick={this.showKillDialog}
263-
view="action"
264-
disabled={this.isDisabledKill()}
265-
className={b('control')}
266-
>
267-
Restart
268-
</Button>
269-
{this.hasHiveId() ? (
270-
<React.Fragment>
271-
<Button
272-
onClick={this.showStopDialog}
273-
view="action"
274-
disabled={this.isDisabledStop()}
275-
className={b('control')}
276-
>
277-
Stop
278-
</Button>
279-
<Button
280-
onClick={this.showResumeDialog}
281-
view="action"
282-
disabled={this.isDisabledResume()}
283-
className={b('control')}
284-
>
285-
Resume
286-
</Button>
287-
</React.Fragment>
288-
) : null}
289-
</div>
150+
<TabletControls tablet={tablet} />
290151
</div>
291152
<div className={b('rigth-pane')}>
292153
<TabletTable history={this.props.history} />
293154
</div>
294155
</div>
295-
{this.renderDialog()}
296156
</div>
297157
);
298158
};
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
import {useEffect, useState} from 'react';
2+
import {Button} from '@gravity-ui/uikit';
3+
4+
import {ETabletState, TTabletStateInfo} from '../../../types/api/tablet';
5+
import {CriticalActionDialog} from '../../../components/CriticalActionDialog';
6+
7+
import {b} from '../Tablet';
8+
9+
enum EVisibleDialogType {
10+
'kill' = 'kill',
11+
'stop' = 'kill',
12+
'resume' = 'kill',
13+
}
14+
15+
type VisibleDialogType = EVisibleDialogType | null;
16+
17+
interface TabletControlsProps {
18+
tablet: TTabletStateInfo;
19+
}
20+
21+
export const TabletControls = ({tablet}: TabletControlsProps) => {
22+
const {TabletId, HiveId} = tablet;
23+
24+
const [isDialogVisible, setIsDialogVisible] = useState(false);
25+
const [visibleDialogType, setVisibleDialogType] = useState<VisibleDialogType>(null);
26+
const [isTabletActionsDisabled, setIsTabletActionsDisabled] = useState(false);
27+
28+
// Enable controls after data update
29+
useEffect(() => {
30+
setIsTabletActionsDisabled(false);
31+
}, [tablet]);
32+
33+
const makeShowDialog = (type: VisibleDialogType) => () => {
34+
setIsDialogVisible(true);
35+
setVisibleDialogType(type);
36+
};
37+
38+
const showKillDialog = makeShowDialog(EVisibleDialogType.kill);
39+
const showStopDialog = makeShowDialog(EVisibleDialogType.stop);
40+
const showResumeDialog = makeShowDialog(EVisibleDialogType.resume);
41+
42+
const hideDialog = () => {
43+
setIsDialogVisible(false);
44+
setVisibleDialogType(null);
45+
};
46+
47+
const _onKillClick = () => {
48+
setIsTabletActionsDisabled(true);
49+
return window.api.killTablet(TabletId);
50+
};
51+
const _onStopClick = () => {
52+
setIsTabletActionsDisabled(true);
53+
return window.api.stopTablet(TabletId, HiveId);
54+
};
55+
const _onResumeClick = () => {
56+
setIsTabletActionsDisabled(true);
57+
return window.api.resumeTablet(TabletId, HiveId);
58+
};
59+
60+
const hasHiveId = () => {
61+
return HiveId && HiveId !== '0';
62+
};
63+
64+
const isDisabledResume = () => {
65+
if (isTabletActionsDisabled) {
66+
return true;
67+
}
68+
69+
return tablet.State !== ETabletState.Stopped && tablet.State !== ETabletState.Dead;
70+
};
71+
72+
const isDisabledKill = () => {
73+
return isTabletActionsDisabled;
74+
};
75+
76+
const isDisabledStop = () => {
77+
if (isTabletActionsDisabled) {
78+
return true;
79+
}
80+
81+
return tablet.State === ETabletState.Stopped || tablet.State === ETabletState.Deleted;
82+
};
83+
84+
const renderDialog = () => {
85+
if (!isDialogVisible) {
86+
return null;
87+
}
88+
89+
switch (visibleDialogType) {
90+
case EVisibleDialogType.kill: {
91+
return (
92+
<CriticalActionDialog
93+
visible={isDialogVisible}
94+
text="The tablet will be restarted. Do you want to proceed?"
95+
onClose={hideDialog}
96+
onConfirm={_onKillClick}
97+
/>
98+
);
99+
}
100+
case EVisibleDialogType.stop: {
101+
return (
102+
<CriticalActionDialog
103+
visible={isDialogVisible}
104+
text="The tablet will be stopped. Do you want to proceed?"
105+
onClose={hideDialog}
106+
onConfirm={_onStopClick}
107+
/>
108+
);
109+
}
110+
case EVisibleDialogType.resume: {
111+
return (
112+
<CriticalActionDialog
113+
visible={isDialogVisible}
114+
text="The tablet will be resumed. Do you want to proceed?"
115+
onClose={hideDialog}
116+
onConfirm={_onResumeClick}
117+
/>
118+
);
119+
}
120+
default:
121+
return null;
122+
}
123+
};
124+
125+
return (
126+
<div className={b('controls')}>
127+
<Button
128+
onClick={showKillDialog}
129+
view="action"
130+
disabled={isDisabledKill()}
131+
className={b('control')}
132+
>
133+
Restart
134+
</Button>
135+
{hasHiveId() ? (
136+
<>
137+
<Button
138+
onClick={showStopDialog}
139+
view="action"
140+
disabled={isDisabledStop()}
141+
className={b('control')}
142+
>
143+
Stop
144+
</Button>
145+
<Button
146+
onClick={showResumeDialog}
147+
view="action"
148+
disabled={isDisabledResume()}
149+
className={b('control')}
150+
>
151+
Resume
152+
</Button>
153+
</>
154+
) : null}
155+
{renderDialog()}
156+
</div>
157+
);
158+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './TabletControls';

0 commit comments

Comments
 (0)