dockly 3.23.0 → 3.23.2

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dockly",
3
- "version": "3.23.0",
3
+ "version": "3.23.2",
4
4
  "description": "Immersive terminal interface for managing docker containers and services",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/src/enum.js ADDED
@@ -0,0 +1,11 @@
1
+ module.exports = {
2
+ ContainerState: {
3
+ created: 'created',
4
+ restarting: 'restarting',
5
+ running: 'running',
6
+ removing: 'removing',
7
+ paused: 'paused',
8
+ exited: 'exited',
9
+ dead: 'dead'
10
+ }
11
+ }
package/src/screen.js CHANGED
@@ -11,16 +11,17 @@ const MODES = require('../lib/modes')
11
11
  // from the user (index.js)
12
12
  const CONTAINERS_GRID_LAYOUT = {
13
13
  'actionsMenu': [4, 4, 4, 4],
14
- 'searchInput': [11, 0, 1, 12],
15
- 'actionStatus': [6, 0, 1, 10],
14
+ 'help': [4, 4, 4, 4],
16
15
  'containerInfo': [2, 2, 8, 8],
16
+ 'containerSortList': [4, 5, 3, 2],
17
17
  'containerList': [0, 0, 6, 10],
18
- 'containerLogs': [7, 0, 4, 12],
18
+ 'actionStatus': [6, 0, 1, 10],
19
19
  'containerStatus': [0, 10, 2, 2],
20
20
  'containerUtilization': [2, 10, 3, 2],
21
21
  'containerVsImages': [5, 10, 2, 2],
22
- 'help': [4, 4, 4, 4],
23
- 'toolbar': [11, 0, 1, 12]
22
+ 'containerLogs': [7, 0, 4, 12],
23
+ 'toolbar': [11, 0, 1, 12],
24
+ 'searchInput': [11, 0, 1, 12]
24
25
  }
25
26
 
26
27
  const SERVICES_GRID_LAYOUT = {
@@ -208,6 +209,7 @@ class screen {
208
209
  this.clearWidgets()
209
210
  this.toggleMode()
210
211
  this.screen.destroy()
212
+ // TODO refactor this so that all of the assets aren't reloaded on screen switch
211
213
  this.init()
212
214
  })
213
215
  }
@@ -45,9 +45,9 @@ class myWidget extends baseWidget(EventEmitter) {
45
45
  this.toggleWidgetListColor = !this.toggleWidgetListColor
46
46
 
47
47
  if (this.toggleWidgetListColor) {
48
- str = chalk.cyan(chunk.toString('utf-8').trim())
48
+ str = chalk.cyan(chunk.toString('utf8').trim())
49
49
  } else {
50
- str = chalk.green(chunk.toString('utf-8').trim())
50
+ str = chalk.green(chunk.toString('utf8').trim())
51
51
  }
52
52
 
53
53
  this.updateItemLogs(str)
@@ -119,7 +119,7 @@ class myWidget extends baseWidget() {
119
119
  }
120
120
 
121
121
  getWidget () {
122
- return this.grid.gridObj.set(...this.grid.gridLayout, this.blessed.list, {
122
+ return this.blessed.list({
123
123
  label: this.label,
124
124
  scrollable: true,
125
125
  alwaysScroll: true,
@@ -137,7 +137,11 @@ class myWidget extends baseWidget() {
137
137
  ch: '|'
138
138
  },
139
139
  vi: true,
140
- align: 'center'
140
+ align: 'center',
141
+ left: 'center',
142
+ top: 'center',
143
+ width: '33%',
144
+ height: '33%'
141
145
  })
142
146
  }
143
147
 
@@ -5,11 +5,14 @@ const figures = require('figures')
5
5
 
6
6
  const ListWidget = require('../../src/widgetsTemplates/list.widget.template')
7
7
 
8
+ const ContainerState = require('../../src/enum.js').ContainerState
9
+
8
10
  class myWidget extends ListWidget {
9
11
  constructor ({ blessed = {}, contrib = {}, screen = {}, grid = {} }) {
10
12
  super({ blessed, contrib, screen, grid })
11
13
  this.containersList = {}
12
14
  this.containersListData = []
15
+ this.sortBy = ContainerState.running
13
16
  }
14
17
 
15
18
  getLabel () {
@@ -17,15 +20,21 @@ class myWidget extends ListWidget {
17
20
  }
18
21
 
19
22
  getItemLogs (containerId, cb) {
20
- return this.utilsRepo.get('docker').getContainerLogs(containerId, cb)
23
+ if (this.widgetsRepo.has('containerLogs')) {
24
+ return this.utilsRepo.get('docker').getContainerLogs(containerId, cb)
25
+ }
21
26
  }
22
27
 
23
28
  updateItemLogs (str) {
24
- return this.widgetsRepo.get('containerLogs').update(str)
29
+ if (this.widgetsRepo.has('containerLogs')) {
30
+ return this.widgetsRepo.get('containerLogs').update(str)
31
+ }
25
32
  }
26
33
 
27
34
  clearItemLogs () {
28
- return this.widgetsRepo.get('containerLogs').clear()
35
+ if (this.widgetsRepo.has('containerLogs')) {
36
+ return this.widgetsRepo.get('containerLogs').clear()
37
+ }
29
38
  }
30
39
 
31
40
  getListItems (cb) {
@@ -56,6 +65,12 @@ class myWidget extends ListWidget {
56
65
  }
57
66
  }
58
67
 
68
+ sortContainersByState (state) {
69
+ this.sortBy = state
70
+ this.refreshList()
71
+ }
72
+
73
+ // TODO refactor this
59
74
  formatList (containers) {
60
75
  const containerList = {}
61
76
  if (containers) {
@@ -82,12 +97,19 @@ class myWidget extends ListWidget {
82
97
  let container = []
83
98
 
84
99
  container = containerList[key]
100
+ const status = container[4]
85
101
  container[4] = this.formatContainerState(container[4])
86
102
  container[5] = this.formatContainerStatus(container[5])
103
+ container[7] = status
87
104
 
88
105
  return container
89
106
  })
90
107
 
108
+ list.sort(this.sortContainers(this.sortBy))
109
+ list = list.map(a => {
110
+ a.pop()
111
+ return a
112
+ })
91
113
  list.unshift(['Id', 'Name', 'Image', 'Command', 'State', 'Status', 'Ports'])
92
114
  this.containersListData = list
93
115
  this.containersList = containerList
@@ -141,27 +163,17 @@ class myWidget extends ListWidget {
141
163
  return this.widget.getItem(this.widget.selected).getContent().toString().trim().split(' ').shift()
142
164
  }
143
165
 
144
- /**
145
- * Sort containers by their state: running, created, then exited.
146
- *
147
- * @param item left
148
- * @param item right
149
- * @returns {number} for position
150
- */
151
- sortContainers (a, b) {
152
- if (a[4] === 'running' && b[4] !== 'running') {
153
- return -1
154
- }
166
+ sortContainers (state) {
167
+ return (a, b) => {
168
+ if (a[7] === state && b[7] !== state) {
169
+ return -1
170
+ }
155
171
 
156
- if (a[4] === 'paused' && b[4] !== 'paused') {
157
- return -1
172
+ if (b[7] === state && a[7] !== state) {
173
+ return 1
174
+ }
175
+ return 0
158
176
  }
159
-
160
- if (a[4] === 'exited' && b[4] !== 'exited') {
161
- return 1
162
- }
163
-
164
- return 0
165
177
  }
166
178
  }
167
179
 
@@ -0,0 +1,103 @@
1
+ const baseWidget = require('../../src/baseWidget')
2
+ const { ContainerState } = require('../../src/enum')
3
+
4
+ class ContainerSortListWidget extends baseWidget() {
5
+ constructor ({ blessed = {}, contrib = {}, screen = {}, grid = {} }) {
6
+ super()
7
+ this.blessed = blessed
8
+ this.contrib = contrib
9
+ this.screen = screen
10
+ this.grid = grid
11
+ this.label = 'Sort By:'
12
+ this.isVisible = false
13
+ const sortedStates = Object.keys(ContainerState)
14
+ sortedStates.sort((a, b) => a.length - b.length)
15
+ this.items = sortedStates
16
+ .map(state =>
17
+ ({
18
+ [`By ${state.charAt(0).toUpperCase()}${state.slice(1)}`]:
19
+ {
20
+ handler: () => this.sortContainerList(state)
21
+ }
22
+ })
23
+ ).reduce((accum, obj) => ({ ...accum, ...obj }), {})
24
+
25
+ this.widget = this.getWidget()
26
+ }
27
+
28
+ init () {
29
+ if (!this.widgetsRepo.has('toolbar')) {
30
+ return null
31
+ }
32
+
33
+ this.registerEscapeKey()
34
+ this.registerSortHandler()
35
+ this.registerToolbarKey()
36
+ }
37
+
38
+ sortContainerList (state) {
39
+ const containerList = this.widgetsRepo.get('containerList')
40
+ if (!containerList) {
41
+ // TODO throw error!
42
+ return
43
+ }
44
+ containerList.sortContainersByState(state)
45
+ }
46
+
47
+ registerSortHandler () {
48
+ this.widget.on('select', (el) => {
49
+ this.items[el.getText()].handler()
50
+ this.toggleVisibility()
51
+ })
52
+ }
53
+
54
+ registerToolbarKey () {
55
+ const toolbar = this.widgetsRepo.get('toolbar')
56
+ toolbar.on('key', (keyString) => {
57
+ if (keyString === 'o') {
58
+ this.toggleVisibility()
59
+ }
60
+ })
61
+ }
62
+
63
+ registerEscapeKey () {
64
+ this.widget.on('keypress', (ch, key) => {
65
+ if (key.name === 'escape' || key.name === 'return') {
66
+ this.toggleVisibility()
67
+ }
68
+ })
69
+ }
70
+
71
+ toggleVisibility () {
72
+ if (this.isVisible) {
73
+ this.screen.remove(this.widget)
74
+ } else {
75
+ this.screen.append(this.widget)
76
+ this.screen.render()
77
+ this.widget.focus()
78
+ }
79
+ this.isVisible = !this.isVisible
80
+ }
81
+
82
+ getWidget () {
83
+ return this.blessed.list({
84
+ label: this.label,
85
+ keys: true,
86
+ align: 'center',
87
+ border: {
88
+ type: 'line'
89
+ },
90
+ left: 'center',
91
+ top: 'center',
92
+ width: '16%',
93
+ height: '25%',
94
+ style: this.getWidgetStyle(),
95
+ items: Object.keys(this.items)
96
+ })
97
+ }
98
+
99
+ renderWidget () {
100
+ }
101
+ }
102
+
103
+ module.exports = ContainerSortListWidget
@@ -45,11 +45,11 @@ class myWidget extends ListWidget {
45
45
 
46
46
  if (images) {
47
47
  images.forEach((image) => {
48
- const getTag = (tag, part) => tag ? tag[0].split(':')[part] : 'none'
48
+ const getTag = (tag, part) => (tag && tag.length) ? tag[0].split(':')[part] : 'none'
49
49
 
50
50
  imageList.push([
51
51
  image.Id.substring(7, 12),
52
- image.RepoDigests ? image.RepoDigests[0].split('@')[0] : getTag(image[2], 0),
52
+ (image.RepoDigests && image.RepoDigests.length) ? image.RepoDigests[0].split('@')[0] : getTag(image[2], 0),
53
53
  getTag(image.RepoTags, 1),
54
54
  this.timeDifference(image.Created),
55
55
  this.formatBytes(image.Size)
@@ -74,6 +74,10 @@ class myWidget extends baseWidget(EventEmitter) {
74
74
  'menu': {
75
75
  keys: ['m'],
76
76
  callback: () => { this.emit('key', 'm') }
77
+ },
78
+ 'sort': {
79
+ keys: ['o'],
80
+ callback: () => { this.emit('key', 'o') }
77
81
  }
78
82
  }
79
83