@electerm/electerm-react 1.39.5 → 1.39.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/client/common/constants.js +7 -3
  2. package/client/common/create-title.jsx +12 -2
  3. package/client/common/default-setting.js +5 -0
  4. package/client/common/init-setting-item.js +6 -0
  5. package/client/components/bookmark-form/form-ssh-common.jsx +1 -1
  6. package/client/components/bookmark-form/index.jsx +6 -2
  7. package/client/components/bookmark-form/rdp-form-ui.jsx +1 -1
  8. package/client/components/bookmark-form/rdp-form.jsx +1 -1
  9. package/client/components/bookmark-form/render-auth-ssh.jsx +27 -1
  10. package/client/components/bookmark-form/render-ssh-tunnel.jsx +60 -31
  11. package/client/components/bookmark-form/use-ui.jsx +12 -0
  12. package/client/components/bookmark-form/vnc-form-ui.jsx +179 -0
  13. package/client/components/bookmark-form/vnc-form.jsx +16 -0
  14. package/client/components/footer/footer-entry.jsx +13 -6
  15. package/client/components/main/term-fullscreen.styl +4 -1
  16. package/client/components/profile/profile-form-elem.jsx +87 -0
  17. package/client/components/profile/profile-form.jsx +33 -0
  18. package/client/components/profile/profile-list.jsx +79 -0
  19. package/client/components/profile/profile-transport-mod.jsx +5 -0
  20. package/client/components/profile/profile-transport.jsx +12 -0
  21. package/client/components/quick-commands/quick-command-transport-mod.jsx +13 -14
  22. package/client/components/quick-commands/quick-commands-list-form.jsx +54 -3
  23. package/client/components/rdp/rdp-session.jsx +53 -36
  24. package/client/components/session/session.jsx +14 -3
  25. package/client/components/session/session.styl +7 -2
  26. package/client/components/setting-panel/setting-modal.jsx +23 -6
  27. package/client/components/setting-panel/setting-terminal.jsx +1 -1
  28. package/client/components/setting-panel/setting-wrap.jsx +5 -1
  29. package/client/components/setting-panel/setting-wrap.styl +5 -3
  30. package/client/components/setting-panel/tab-profiles.jsx +38 -0
  31. package/client/components/sftp/list-table-ui.jsx +99 -46
  32. package/client/components/sftp/sftp-entry.jsx +1 -0
  33. package/client/components/sftp/sftp.styl +4 -1
  34. package/client/components/sftp/transfer-common.js +1 -1
  35. package/client/components/tabs/index.jsx +1 -1
  36. package/client/components/tabs/tab.jsx +9 -4
  37. package/client/components/terminal/index.jsx +5 -5
  38. package/client/components/vnc/vnc-form.jsx +66 -0
  39. package/client/components/vnc/vnc-session.jsx +297 -0
  40. package/client/store/common.js +21 -0
  41. package/client/store/index.js +1 -0
  42. package/client/store/init-state.js +4 -23
  43. package/client/store/load-data.js +9 -2
  44. package/client/store/sync.js +7 -3
  45. package/package.json +1 -1
@@ -0,0 +1,87 @@
1
+ import {
2
+ Form,
3
+ message,
4
+ Button
5
+ } from 'antd'
6
+ import generate from '../../common/uid'
7
+ import InputAutoFocus from '../common/input-auto-focus'
8
+ import renderAuth from '../bookmark-form/render-auth-ssh'
9
+ import { formItemLayout } from '../../common/form-layout'
10
+ import {
11
+ settingMap
12
+ } from '../../common/constants'
13
+ const FormItem = Form.Item
14
+ const { prefix } = window
15
+ const e = prefix('form')
16
+ const s = prefix('setting')
17
+ const ss = prefix('sftp')
18
+
19
+ export default function QuickCommandForm (props) {
20
+ const [form] = Form.useForm()
21
+ const { autofocustrigger } = props.store
22
+ async function handleSubmit (res) {
23
+ const { formData } = props
24
+ console.log(res)
25
+ const update1 = {
26
+ ...res,
27
+ id: generate()
28
+ }
29
+ if (formData.id) {
30
+ props.store.editItem(formData.id, res, settingMap.profiles)
31
+ } else {
32
+ props.store.addItem(update1, settingMap.profiles)
33
+ props.store.setSettingItem({
34
+ id: '',
35
+ name: e('profile')
36
+ })
37
+ }
38
+ message.success(s('saved'))
39
+ }
40
+ return (
41
+ <Form
42
+ form={form}
43
+ onFinish={handleSubmit}
44
+ className='form-wrap pd2l'
45
+ layout='vertical'
46
+ initialValues={props.formData}
47
+ >
48
+ <FormItem
49
+ label={e('profileName')}
50
+ {...formItemLayout}
51
+ rules={[{
52
+ max: 60, message: '60 chars max'
53
+ }, {
54
+ required: true, message: 'Name required'
55
+ }]}
56
+ hasFeedback
57
+ name='name'
58
+ >
59
+ <InputAutoFocus
60
+ selectall='yes'
61
+ autofocustrigger={autofocustrigger}
62
+ />
63
+ </FormItem>
64
+ {
65
+ renderAuth({
66
+ store: props.store,
67
+ form,
68
+ authType: 'password'
69
+ })
70
+ }
71
+ {
72
+ renderAuth({
73
+ store: props.store,
74
+ form
75
+ })
76
+ }
77
+ <FormItem>
78
+ <Button
79
+ type='primary'
80
+ htmlType='submit'
81
+ >
82
+ {ss('submit')}
83
+ </Button>
84
+ </FormItem>
85
+ </Form>
86
+ )
87
+ }
@@ -0,0 +1,33 @@
1
+ import { PureComponent } from 'react'
2
+ import ProfileCommandForm from './profile-form-elem'
3
+ import { LoadingOutlined } from '@ant-design/icons'
4
+
5
+ export default class ProfleFormIndex extends PureComponent {
6
+ state = {
7
+ ready: false
8
+ }
9
+
10
+ componentDidMount () {
11
+ this.timer = setTimeout(() => {
12
+ this.setState({
13
+ ready: true
14
+ })
15
+ }, 200)
16
+ }
17
+
18
+ componentWillUnmount () {
19
+ clearTimeout(this.timer)
20
+ }
21
+
22
+ render () {
23
+ const { ready } = this.state
24
+ if (!ready) {
25
+ return (
26
+ <div className='pd3 aligncenter'>
27
+ <LoadingOutlined />
28
+ </div>
29
+ )
30
+ }
31
+ return <ProfileCommandForm {...this.props} />
32
+ }
33
+ }
@@ -0,0 +1,79 @@
1
+ /**
2
+ * quick command list render
3
+ */
4
+
5
+ import List from '../setting-panel/list'
6
+ import { PlusOutlined } from '@ant-design/icons'
7
+ import classnames from 'classnames'
8
+ import highlight from '../common/highlight'
9
+ import ProfileTransport from './profile-transport'
10
+ import {
11
+ settingMap
12
+ } from '../../common/constants'
13
+
14
+ export default class ProfileList extends List {
15
+ del = (item, e) => {
16
+ e.stopPropagation()
17
+ this.props.store.delItem(item, settingMap.profiles)
18
+ }
19
+
20
+ onClickItem = (item) => {
21
+ this.props.onClickItem(item)
22
+ }
23
+
24
+ renderItem = (item, i) => {
25
+ if (!item) {
26
+ return null
27
+ }
28
+ const { activeItemId } = this.props
29
+ const { name, id } = item
30
+ const cls = classnames(
31
+ 'item-list-unit theme-item',
32
+ {
33
+ active: activeItemId === id
34
+ }
35
+ )
36
+ let title = name
37
+ title = highlight(
38
+ title,
39
+ this.state.keyword
40
+ )
41
+ return (
42
+ <div
43
+ key={i + id}
44
+ className={cls}
45
+ onClick={() => this.onClickItem(item)}
46
+ data-id={id}
47
+ >
48
+ <div className='elli pd1y pd2x' title={name}>
49
+ {
50
+ !id
51
+ ? <PlusOutlined className='mg1r' />
52
+ : null
53
+ }
54
+ {title}
55
+ </div>
56
+ {this.renderDelBtn(item)}
57
+ </div>
58
+ )
59
+ }
60
+
61
+ renderTransport = () => {
62
+ return (
63
+ <ProfileTransport
64
+ store={this.props.store}
65
+ />
66
+ )
67
+ }
68
+
69
+ filter = list => {
70
+ const { keyword } = this.state
71
+ return keyword
72
+ ? list.filter((item) => {
73
+ const n = (item.name || '').toLowerCase()
74
+ const k = keyword.toLowerCase()
75
+ return n.includes(k)
76
+ })
77
+ : list
78
+ }
79
+ }
@@ -0,0 +1,5 @@
1
+ import QmTransport from '../quick-commands/quick-command-transport'
2
+
3
+ export default class ProfileTransport extends QmTransport {
4
+ name = 'profiles'
5
+ }
@@ -0,0 +1,12 @@
1
+ import ProfileTransportMod from './profile-transport-mod'
2
+ import { Component } from '../common/react-subx'
3
+
4
+ export default class ProfileTransport extends Component {
5
+ render () {
6
+ return (
7
+ <div className='pd1b'>
8
+ <ProfileTransportMod store={this.props.store} />
9
+ </div>
10
+ )
11
+ }
12
+ }
@@ -4,13 +4,14 @@ import time from '../../common/time'
4
4
  import copy from 'json-deep-copy'
5
5
 
6
6
  export default class QmTransport extends BookmarkTransport {
7
+ name = 'quickCommands'
7
8
  beforeUpload = async (file) => {
8
9
  const { store } = this.props
9
10
  const txt = await window.fs.readFile(file.path)
10
11
  try {
11
- const quickCommands = JSON.parse(txt)
12
- const quickCommandsOld = copy(store.quickCommands)
13
- const bmTreeOld = quickCommandsOld.reduce((p, v) => {
12
+ const arr = JSON.parse(txt)
13
+ const arrOld = copy(store[this.name])
14
+ const bmTreeOld = arrOld.reduce((p, v) => {
14
15
  return {
15
16
  ...p,
16
17
  [v.id]: v
@@ -18,19 +19,19 @@ export default class QmTransport extends BookmarkTransport {
18
19
  }, {})
19
20
  const add = []
20
21
  const dbAdd = []
21
- quickCommands.forEach(bg => {
22
+ arr.forEach(bg => {
22
23
  if (!bmTreeOld[bg.id]) {
23
- quickCommandsOld.push(bg)
24
+ arrOld.push(bg)
24
25
  add.push(bg)
25
26
  dbAdd.push({
26
- db: 'quickCommands',
27
+ db: this.name,
27
28
  obj: bg
28
29
  })
29
30
  }
30
31
  })
31
- store.storeAssign({
32
- quickCommands: quickCommandsOld
33
- })
32
+ store.setState(
33
+ this.name, arrOld
34
+ )
34
35
  store.batchDbAdd(dbAdd)
35
36
  } catch (e) {
36
37
  store.onError(e)
@@ -44,11 +45,9 @@ export default class QmTransport extends BookmarkTransport {
44
45
 
45
46
  handleDownload = () => {
46
47
  const { store } = this.props
47
- const {
48
- quickCommands
49
- } = store
50
- const txt = JSON.stringify(quickCommands, null, 2)
48
+ const arr = store[this.name]
49
+ const txt = JSON.stringify(arr, null, 2)
51
50
  const stamp = time(undefined, 'YYYY-MM-DD-HH-mm-ss')
52
- download('quickCommands-' + stamp + '.json', txt)
51
+ download('electerm-' + this.name + '-' + stamp + '.json', txt)
53
52
  }
54
53
  }
@@ -3,10 +3,14 @@ import {
3
3
  InputNumber,
4
4
  Space,
5
5
  Button,
6
- Input
6
+ Input,
7
+ Tag
7
8
  } from 'antd'
8
9
  import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons'
9
10
  import { formItemLayout } from '../../common/form-layout'
11
+ import HelpIcon from '../common/help-icon'
12
+ import { copy } from '../../common/clipboard'
13
+ import { useRef } from 'react'
10
14
 
11
15
  const FormItem = Form.Item
12
16
  const FormList = Form.List
@@ -14,6 +18,7 @@ const { prefix } = window
14
18
  const t = prefix('quickCommands')
15
19
 
16
20
  export default function renderQm () {
21
+ const focused = useRef(0)
17
22
  function renderItem (field, i, add, remove) {
18
23
  return (
19
24
  <Space
@@ -43,7 +48,10 @@ export default function renderQm () {
43
48
  <Input.TextArea
44
49
  rows={1}
45
50
  placeholder={t('quickCommand')}
46
- className='compact-input'
51
+ className='compact-input qm-input'
52
+ onFocus={() => {
53
+ focused.current = i
54
+ }}
47
55
  />
48
56
  </FormItem>
49
57
  <Button
@@ -54,9 +62,52 @@ export default function renderQm () {
54
62
  </Space>
55
63
  )
56
64
  }
65
+ const commonCmds = [
66
+ { cmd: 'ls', desc: 'List directory contents' },
67
+ { cmd: 'cd', desc: 'Change the current directory' },
68
+ { cmd: 'pwd', desc: 'Print the current working directory' },
69
+ { cmd: 'cp', desc: 'Copy files and directories' },
70
+ { cmd: 'mv', desc: 'Move/rename files and directories' },
71
+ { cmd: 'rm', desc: 'Remove files or directories' },
72
+ { cmd: 'mkdir', desc: 'Create new directories' },
73
+ { cmd: 'rmdir', desc: 'Remove empty directories' },
74
+ { cmd: 'touch', desc: 'Create empty files or update file timestamps' },
75
+ { cmd: 'chmod', desc: 'Change file modes or Access Control Lists' },
76
+ { cmd: 'chown', desc: 'Change file owner and group' },
77
+ { cmd: 'cat', desc: 'Concatenate and display file content' },
78
+ { cmd: 'echo', desc: 'Display message or variable value' },
79
+ { cmd: 'grep', desc: 'Search text using patterns' },
80
+ { cmd: 'find', desc: 'Search for files in a directory hierarchy' },
81
+ { cmd: 'df', desc: 'Report file system disk space usage' },
82
+ { cmd: 'du', desc: 'Estimate file space usage' },
83
+ { cmd: 'top', desc: 'Display Linux tasks' },
84
+ { cmd: 'ps', desc: 'Report a snapshot of current processes' },
85
+ { cmd: 'kill', desc: 'Send a signal to a process' }
86
+ ]
57
87
 
88
+ const cmds = commonCmds.map(c => {
89
+ return (
90
+ <Tag
91
+ title={c.desc}
92
+ key={c.cmd}
93
+ onClick={() => {
94
+ copy(c.cmd)
95
+ }}
96
+ >
97
+ <b className='pointer'>{c.cmd}</b>
98
+ </Tag>
99
+ )
100
+ })
101
+ const label = (
102
+ <div>
103
+ {t('commonCommands')}
104
+ <HelpIcon
105
+ title={cmds}
106
+ />
107
+ </div>
108
+ )
58
109
  return (
59
- <FormItem {...formItemLayout} label={t('quickCommands')}>
110
+ <FormItem {...formItemLayout} label={label}>
60
111
  <FormList
61
112
  name='commands'
62
113
  >
@@ -70,7 +70,7 @@ export default class RdpSession extends Component {
70
70
  openedSideBar
71
71
  } = this.props
72
72
  return {
73
- width: width - (pinned && openedSideBar ? leftSidebarWidth : 0),
73
+ width: width - (pinned && openedSideBar ? leftSidebarWidth : 0) - 42,
74
74
  height: height - tabsHeight
75
75
  }
76
76
  }
@@ -235,7 +235,7 @@ export default class RdpSession extends Component {
235
235
  const isHorizontal = false
236
236
  const delta = isHorizontal ? e.deltaX : e.deltaY
237
237
  const step = Math.round(Math.abs(delta) * 15 / 8)
238
- console.log(x, y, step, delta, isHorizontal)
238
+ // console.log(x, y, step, delta, isHorizontal)
239
239
  params = [x, y, step, delta > 0, isHorizontal]
240
240
  } else if (type === 'keydown' || type === 'keyup') {
241
241
  params = [keyCode, pressed]
@@ -349,6 +349,14 @@ export default class RdpSession extends Component {
349
349
  this.setState(res, this.handleReInit)
350
350
  }
351
351
 
352
+ renderHelp = () => {
353
+ return (
354
+ <HelpIcon
355
+ link={rdpHelpLink}
356
+ />
357
+ )
358
+ }
359
+
352
360
  renderControl = () => {
353
361
  const {
354
362
  id
@@ -358,45 +366,54 @@ export default class RdpSession extends Component {
358
366
  onChange: this.handleResChange,
359
367
  popupMatchSelectWidth: false
360
368
  }
369
+ return (
370
+ <div className='pd1 fix session-v-info'>
371
+ <div className='fleft'>
372
+ <ReloadOutlined
373
+ onClick={this.handleReInit}
374
+ className='mg2r mg1l pointer'
375
+ />
376
+ <Select
377
+ {...sleProps}
378
+ >
379
+ {
380
+ this.getAllRes().map(d => {
381
+ const v = d.id
382
+ return (
383
+ <Option
384
+ key={v}
385
+ value={v}
386
+ >
387
+ {d.width}x{d.height}
388
+ </Option>
389
+ )
390
+ })
391
+ }
392
+ </Select>
393
+ <EditOutlined
394
+ onClick={this.handleEditResolutions}
395
+ className='mg2r mg1l pointer'
396
+ />
397
+ {this.renderInfo()}
398
+ {this.renderHelp()}
399
+ </div>
400
+ <div className='fright'>
401
+ {this.props.fullscreenIcon()}
402
+ </div>
403
+ </div>
404
+ )
405
+ }
406
+
407
+ renderInfo () {
361
408
  const {
362
409
  host,
363
410
  port,
364
411
  username
365
412
  } = this.props.tab
366
413
  return (
367
- <div className='pd1 fix'>
368
- <ReloadOutlined
369
- onClick={this.handleReInit}
370
- className='mg2r mg1l pointer'
371
- />
372
- <Select
373
- {...sleProps}
374
- >
375
- {
376
- this.getAllRes().map(d => {
377
- const v = d.id
378
- return (
379
- <Option
380
- key={v}
381
- value={v}
382
- >
383
- {d.width}x{d.height}
384
- </Option>
385
- )
386
- })
387
- }
388
- </Select>
389
- <EditOutlined
390
- onClick={this.handleEditResolutions}
391
- className='mg2r mg1l pointer'
392
- />
393
- <span className='mg2l mg2r'>
394
- {username}@{host}:{port}
395
- </span>
396
- <HelpIcon
397
- link={rdpHelpLink}
398
- />
399
- </div>
414
+ <span className='mg2l mg2r'>
415
+ {username}@{host}:{port}
416
+ </span>
400
417
  )
401
418
  }
402
419
 
@@ -425,7 +442,7 @@ export default class RdpSession extends Component {
425
442
  <Spin spinning={loading}>
426
443
  <div
427
444
  {...rdpProps}
428
- className='rdp-session-wrap pd1'
445
+ className='rdp-session-wrap session-v-wrap'
429
446
  >
430
447
  {this.renderControl()}
431
448
  <canvas
@@ -5,6 +5,7 @@ import { Component } from 'react'
5
5
  import Term from '../terminal'
6
6
  import Sftp from '../sftp/sftp-entry'
7
7
  import RdpSession from '../rdp/rdp-session'
8
+ import VncSession from '../vnc/vnc-session'
8
9
  import {
9
10
  BorderVerticleOutlined,
10
11
  BorderHorizontalOutlined,
@@ -29,7 +30,8 @@ import {
29
30
  footerHeight,
30
31
  terminalActions,
31
32
  connectionMap,
32
- terminalRdpType
33
+ terminalRdpType,
34
+ terminalVncType
33
35
  } from '../../common/constants'
34
36
  import ResizeWrap from '../common/resize-wrap'
35
37
  import safeName from '../../common/safe-name'
@@ -325,7 +327,7 @@ export default class SessionWrapper extends Component {
325
327
  const {
326
328
  pane, type
327
329
  } = this.props.tab
328
- if (type === terminalRdpType) {
330
+ if (type === terminalRdpType || type === terminalVncType) {
329
331
  const rdpProps = {
330
332
  tab: this.props.tab,
331
333
  sessionId,
@@ -339,14 +341,23 @@ export default class SessionWrapper extends Component {
339
341
  'openedSideBar',
340
342
  'delTab',
341
343
  'config',
344
+ 'reloadTab',
342
345
  'editTab'
343
346
  ]),
344
347
  ...pick(
345
348
  this,
346
349
  [
350
+ 'fullscreenIcon',
347
351
  'setSessionState'
348
352
  ])
349
353
  }
354
+ if (type === terminalVncType) {
355
+ return (
356
+ <VncSession
357
+ {...rdpProps}
358
+ />
359
+ )
360
+ }
350
361
  return (
351
362
  <RdpSession
352
363
  {...rdpProps}
@@ -506,7 +517,7 @@ export default class SessionWrapper extends Component {
506
517
  const { splitDirection, terminals, sftpPathFollowSsh } = this.state
507
518
  const { props } = this
508
519
  const { pane, enableSsh, type } = props.tab
509
- if (type === terminalRdpType) {
520
+ if (type === terminalRdpType || type === terminalVncType) {
510
521
  return null
511
522
  }
512
523
  const termType = props.tab?.type
@@ -59,6 +59,11 @@
59
59
  .web-session-wrap
60
60
  height 100vh
61
61
  background main
62
- .rdp-session-wrap
62
+ .session-v-wrap
63
63
  background main
64
- overflow scroll
64
+ overflow scroll
65
+ z-index 99
66
+ .vnc-session-wrap > div
67
+ display block !important
68
+ width auto !important
69
+ height auto !important
@@ -15,11 +15,13 @@ import TabHistory from './tab-history'
15
15
  import TabQuickCommands from './tab-quick-commands'
16
16
  import TabSettings from './tab-settings'
17
17
  import TabThemes from './tab-themes'
18
+ import TabProfiles from './tab-profiles'
18
19
 
19
20
  const { prefix } = window
20
21
  const m = prefix('common')
21
22
  const t = prefix('terminalThemes')
22
23
  const q = prefix('quickCommands')
24
+ const f = prefix('profiles')
23
25
 
24
26
  export default class SettingModalWrap extends Component {
25
27
  selectItem = (item) => {
@@ -92,17 +94,25 @@ export default class SettingModalWrap extends Component {
92
94
  key: settingMap.quickCommands,
93
95
  label: q(settingMap.quickCommands),
94
96
  children: null
97
+ },
98
+ {
99
+ key: settingMap.profiles,
100
+ label: f(settingMap.profiles),
101
+ children: null
95
102
  }
96
103
  ]
104
+ const tabsProps = {
105
+ activeKey: settingTab,
106
+ animated: false,
107
+ items,
108
+ onChange: store.handleChangeSettingTab,
109
+ destroyInactiveTabPane: true,
110
+ className: 'setting-tabs'
111
+ }
97
112
  return (
98
113
  <div>
99
114
  <Tabs
100
- activeKey={settingTab}
101
- animated={false}
102
- items={items}
103
- onChange={store.handleChangeSettingTab}
104
- destroyInactiveTabPane
105
- className='setting-tabs'
115
+ {...tabsProps}
106
116
  />
107
117
  <TabHistory
108
118
  listProps={props0}
@@ -136,6 +146,13 @@ export default class SettingModalWrap extends Component {
136
146
  store={store}
137
147
  settingTab={settingTab}
138
148
  />
149
+ <TabProfiles
150
+ listProps={props0}
151
+ settingItem={settingItem}
152
+ formProps={formProps}
153
+ store={store}
154
+ settingTab={settingTab}
155
+ />
139
156
  </div>
140
157
  )
141
158
  }
@@ -71,7 +71,7 @@ export default class SettingTerminal extends Component {
71
71
  }
72
72
 
73
73
  handleChangeDelMode = v => this.onChangeValue(v, 'backspaceMode')
74
- handleChangeRenderType = v => this.onChangeValue(v, 'renderType')
74
+ handleChangeRenderType = v => this.onChangeValue(v, 'rendererType')
75
75
 
76
76
  handleChangeFont = (values) => {
77
77
  this.onChangeValue(
@@ -36,7 +36,11 @@ export default class SettingWrap extends Component {
36
36
  {...pops}
37
37
  >
38
38
  <CloseCircleOutlined
39
- className='close-setting-wrap'
39
+ className='close-setting-wrap-icon close-setting-wrap'
40
+ onClick={this.props.onCancel}
41
+ />
42
+ <CloseCircleOutlined
43
+ className='close-setting-wrap-icon alt-close-setting-wrap'
40
44
  onClick={this.props.onCancel}
41
45
  />
42
46
  {
@@ -5,10 +5,8 @@
5
5
 
6
6
  body .ant-drawer .ant-drawer-content-wrapper
7
7
  left 43px
8
-
9
- .close-setting-wrap
8
+ .close-setting-wrap-icon
10
9
  position absolute
11
- left 20px
12
10
  top 70px
13
11
  font-size 16px
14
12
  color text
@@ -16,6 +14,10 @@ body .ant-drawer .ant-drawer-content-wrapper
16
14
  z-index 889
17
15
  &:hover
18
16
  color text
17
+ .alt-close-setting-wrap
18
+ right 20px
19
+ .close-setting-wrap
20
+ top 70px
19
21
  .setting-row
20
22
  position absolute
21
23
  top 127px