dockly 3.24.4 → 3.24.6

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/README.md CHANGED
@@ -12,7 +12,6 @@
12
12
  [![npm module downloads](http://img.shields.io/npm/dt/dockly.svg)](https://www.npmjs.org/package/dockly)
13
13
  [![Security Responsible Disclosure](https://img.shields.io/badge/Security-Responsible%20Disclosure-yellow.svg)](./SECURITY.md
14
14
  )
15
- [![dockly](https://snyk.io/advisor/npm-package/dockly/badge.svg)](https://snyk.io/advisor/npm-package/dockly)
16
15
 
17
16
  Dockly has been highlighted, featured and chosen as favorite docker container management tool on:
18
17
 
@@ -21,9 +20,7 @@ Dockly has been highlighted, featured and chosen as favorite docker container ma
21
20
  [![terminals are sexy](https://img.shields.io/badge/TerminalsAreSexy-%F0%9F%92%BB-green.svg
22
21
  )](https://github.com/k4m4/terminals-are-sexy) [![Programmer's Weekly](https://img.shields.io/badge/ProgrammersWeekly-%F0%9F%95%B6-purple.svg
23
22
  )](https://mailchi.mp/programmerweekly/programmer-weekly-issue-94?e=e8c11d0390) [![Console.dev](https://img.shields.io/badge/ConsoleDotDev-%F0%9F%95%B6-blue.svg
24
- )](https://console.dev/tools/)
25
-
26
- <a href="https://console.dev" title="Visit Console - the best tools for developers"><img src="https://console.dev/img/badges/1.0/png/console-badge-pick-green1-dark.png" alt="Console - Developer Tool of the Week" /></a>
23
+ )](https://console.dev/)
27
24
 
28
25
  ![dockly-demo-2](https://cloud.githubusercontent.com/assets/316371/25682867/c5212216-3027-11e7-8f36-72d38516d2af.gif)
29
26
 
@@ -137,6 +134,10 @@ See [Awesome Docker list](https://github.com/veggiemonk/awesome-docker/blob/mast
137
134
  - [Dockly – Manage Docker Containers From Terminal](https://ostechnix.com/dockly-manage-docker-containers-from-terminal/)
138
135
  - [Clever cloud CEO, Quentin Adam, tweeting about dockly](https://twitter.com/waxzce/status/1123886351924043777)
139
136
 
137
+ ## Contributing
138
+
139
+ Please consult [CONTRIBUTING](./CONTRIBUTING.md) for guidelines on contributing to this project.
140
+
140
141
  # Author
141
142
  Liran Tal <liran.tal@gmail.com>
142
143
 
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "dockly",
3
- "version": "3.24.4",
3
+ "version": "3.24.6",
4
4
  "description": "Immersive terminal interface for managing docker containers and services",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
- "test": "yarn run lint",
8
- "lint": "standard && yarn run lint:lockfile",
7
+ "test": "npm run lint",
8
+ "lint": "standard && npm run lint:lockfile",
9
9
  "lint:fix": "standard --fix",
10
- "lint:lockfile": "lockfile-lint --path yarn.lock --type yarn --validate-https --allowed-hosts npm yarn",
10
+ "lint:lockfile": "lockfile-lint --path package-lock.json --type npm --validate-https --allowed-hosts npm",
11
11
  "debug": "node --inspect=0.0.0.0:9222 ./index.js "
12
12
  },
13
13
  "files": [
@@ -19,7 +19,8 @@
19
19
  "dockerRunScript.sh"
20
20
  ],
21
21
  "engines": {
22
- "node": ">=7.6.0"
22
+ "npm": ">=11.10.0",
23
+ "node": ">=24.0.0"
23
24
  },
24
25
  "bin": {
25
26
  "dockly": "./index.js"
@@ -75,18 +76,20 @@
75
76
  "dockerode": "3.3.5",
76
77
  "figures": "^2.0.0",
77
78
  "glob": "^7.2.3",
78
- "lockfile-lint": "^3.0.9",
79
+ "lockfile-lint": "^4.12.0",
79
80
  "semver": "7.6.3"
80
81
  },
81
82
  "devDependencies": {
83
+ "semantic-release": "25.0.3",
82
84
  "standard": "^12.0.1"
83
85
  },
84
- "release": {
85
- "branches": "main"
86
- },
87
86
  "standard": {
88
87
  "ignore": [
89
88
  "docs/**"
90
89
  ]
90
+ },
91
+ "publishConfig": {
92
+ "provenance": true,
93
+ "access": "public"
91
94
  }
92
95
  }
@@ -0,0 +1,43 @@
1
+ const CONTAINERS_GRID_LAYOUT = {
2
+ 'actionsMenu': [4, 4, 4, 4],
3
+ 'help': [4, 4, 4, 4],
4
+ 'containerInfo': [2, 2, 8, 8],
5
+ 'containerSortList': [4, 5, 3, 2],
6
+ 'containerList': [0, 0, 6, 10],
7
+ 'actionStatus': [6, 0, 1.5, 10],
8
+ 'containerStatus': [0, 10, 2, 2],
9
+ 'containerUtilization': [2, 10, 3, 2],
10
+ 'containerVsImages': [5, 10, 2, 2],
11
+ 'containerLogs': [7.5, 0, 4, 12],
12
+ 'toolbar': [11.5, 0, 1, 12],
13
+ 'searchInput': [11, 0, 1, 12]
14
+ }
15
+
16
+ const SERVICES_GRID_LAYOUT = {
17
+ 'actionsMenu': [4, 4, 4, 4],
18
+ 'actionStatus': [6, 0, 1.5, 10],
19
+ 'searchInput': [11, 0, 1, 12],
20
+ 'help': [4, 4, 4, 4],
21
+ 'servicesInfo': [2, 2, 8, 8],
22
+ 'servicesList': [0, 0, 6, 10],
23
+ 'servicesLogs': [7.5, 0, 4, 12],
24
+ 'servicesStatus': [0, 10, 2, 2],
25
+ 'servicesVsImages': [2, 10, 2, 2],
26
+ 'toolbar': [11, 0, 1, 12]
27
+ }
28
+
29
+ const IMAGES_GRID_LAYOUT = {
30
+ 'imageInfo': [2, 2, 8, 8],
31
+ 'imageList': [0, 0, 6, 10],
32
+ 'searchInput': [11, 0, 1, 12],
33
+ 'actionStatus': [6, 0, 1.5, 10],
34
+ 'help': [4, 4, 4, 4],
35
+ 'toolbar': [11, 0, 1, 12],
36
+ 'imageUtilization': [0, 10, 2, 2]
37
+ }
38
+
39
+ module.exports = {
40
+ CONTAINERS_GRID_LAYOUT,
41
+ SERVICES_GRID_LAYOUT,
42
+ IMAGES_GRID_LAYOUT
43
+ }
package/src/screen.js CHANGED
@@ -4,48 +4,11 @@ const path = require('path')
4
4
  const blessed = require('blessed')
5
5
  const contrib = require('blessed-contrib')
6
6
  const assetsLoader = require(path.join(__dirname, '/assetsLoader'))
7
-
7
+ const { CONTAINERS_GRID_LAYOUT, SERVICES_GRID_LAYOUT, IMAGES_GRID_LAYOUT } = require('./grid.config')
8
8
  const MODES = require('../lib/modes')
9
9
 
10
10
  // @TODO should be moved outside and used as a config
11
11
  // from the user (index.js)
12
- const CONTAINERS_GRID_LAYOUT = {
13
- 'actionsMenu': [4, 4, 4, 4],
14
- 'help': [4, 4, 4, 4],
15
- 'containerInfo': [2, 2, 8, 8],
16
- 'containerSortList': [4, 5, 3, 2],
17
- 'containerList': [0, 0, 6, 10],
18
- 'actionStatus': [6, 0, 1, 10],
19
- 'containerStatus': [0, 10, 2, 2],
20
- 'containerUtilization': [2, 10, 3, 2],
21
- 'containerVsImages': [5, 10, 2, 2],
22
- 'containerLogs': [7, 0, 4, 12],
23
- 'toolbar': [11, 0, 1, 12],
24
- 'searchInput': [11, 0, 1, 12]
25
- }
26
-
27
- const SERVICES_GRID_LAYOUT = {
28
- 'actionsMenu': [4, 4, 4, 4],
29
- 'actionStatus': [6, 0, 1, 10],
30
- 'searchInput': [11, 0, 1, 12],
31
- 'help': [4, 4, 4, 4],
32
- 'servicesInfo': [2, 2, 8, 8],
33
- 'servicesList': [0, 0, 6, 10],
34
- 'servicesLogs': [7, 0, 4, 12],
35
- 'servicesStatus': [0, 10, 2, 2],
36
- 'servicesVsImages': [2, 10, 2, 2],
37
- 'toolbar': [11, 0, 1, 12]
38
- }
39
-
40
- const IMAGES_GRID_LAYOUT = {
41
- 'imageInfo': [2, 2, 8, 8],
42
- 'imageList': [0, 0, 6, 10],
43
- 'searchInput': [11, 0, 1, 12],
44
- 'actionStatus': [6, 0, 1, 10],
45
- 'help': [4, 4, 4, 4],
46
- 'toolbar': [11, 0, 1, 12],
47
- 'imageUtilization': [0, 10, 2, 2]
48
- }
49
12
 
50
13
  const GRID_LAYOUT = {}
51
14
  GRID_LAYOUT[MODES.container] = CONTAINERS_GRID_LAYOUT
@@ -34,7 +34,6 @@ class myWidget extends baseWidget(EventEmitter) {
34
34
  if (err) {
35
35
  return null
36
36
  }
37
-
38
37
  // clear log box of previous logs
39
38
  this.clearItemLogs()
40
39
 
@@ -75,6 +74,12 @@ class myWidget extends baseWidget(EventEmitter) {
75
74
  })
76
75
 
77
76
  searchInput.on('exitSearch', () => {
77
+ this.update(
78
+ this.containersListData ||
79
+ this.imagesListData ||
80
+ this.servicesListData ||
81
+ [])
82
+ this.screen.render()
78
83
  this.focus()
79
84
  })
80
85
  }
@@ -45,7 +45,7 @@ class myWidget extends ListWidget {
45
45
  let filteredContainersList = this.containersListData[0]
46
46
  let containersList = this.containersListData.slice(1)
47
47
  let filteredContainers = []
48
-
48
+ const headerRow = this.containersListData[0]
49
49
  if (data) {
50
50
  filteredContainers = containersList.filter((container, index, containerItems) => {
51
51
  const containerName = container[1]
@@ -56,12 +56,19 @@ class myWidget extends ListWidget {
56
56
  }
57
57
  })
58
58
  }
59
-
59
+ // Render filtered services if available; otherwise, it means either the user hasn't provided input or no matches were found.
60
60
  if (filteredContainers.length > 0) {
61
61
  filteredContainers.unshift(filteredContainersList)
62
62
  this.update(filteredContainers)
63
63
  } else {
64
- this.update(this.containersListData)
64
+ if (data.length > 0) {
65
+ this.update([
66
+ headerRow,
67
+ ['', 'No containers found matching: ' + data, '', '', '', '', '']
68
+ ])
69
+ } else {
70
+ this.update(this.containersListData)
71
+ }
65
72
  }
66
73
  }
67
74
 
@@ -75,8 +82,8 @@ class myWidget extends ListWidget {
75
82
  const containerList = {}
76
83
  if (containers) {
77
84
  containers.forEach((container) => {
78
- let containerPortPublic = (container.Ports[0] && container.Ports[0].PublicPort) ? String(container.Ports[0].PublicPort) : ''
79
- let containerPortPrivate = (container.Ports[0] && container.Ports[0].PrivatePort) ? String(container.Ports[0].PrivatePort) : ''
85
+ let containerPortPublic = (container.Ports && container.Ports[0] && container.Ports[0].PublicPort) ? String(container.Ports[0].PublicPort) : ''
86
+ let containerPortPrivate = (container.Ports && container.Ports[0] && container.Ports[0].PrivatePort) ? String(container.Ports[0].PrivatePort) : ''
80
87
  let containerPort = containerPortPrivate + ':' + containerPortPublic
81
88
 
82
89
  containerList[container.Id] = [
@@ -20,6 +20,7 @@ class myWidget extends ListWidget {
20
20
  let imageTitleList = this.imagesListData[0]
21
21
  let imageList = this.imagesListData.slice(1)
22
22
  let filteredimages = []
23
+ const headerRow = this.imagesListData[0]
23
24
 
24
25
  if (data) {
25
26
  filteredimages = imageList.filter((container, index, containerItems) => {
@@ -31,12 +32,19 @@ class myWidget extends ListWidget {
31
32
  }
32
33
  })
33
34
  }
34
-
35
+ // Render filtered services if available; otherwise, it means either the user hasn't provided input or no matches were found.
35
36
  if (filteredimages.length > 0) {
36
37
  filteredimages.unshift(imageTitleList)
37
38
  this.update(filteredimages)
38
39
  } else {
39
- this.update(this.imagesListData)
40
+ if (data.length > 0) {
41
+ this.update([
42
+ headerRow,
43
+ ['', 'No Images found matching: ' + data, '', '', '', '', '']
44
+ ])
45
+ } else {
46
+ this.update(this.imagesListData)
47
+ }
40
48
  }
41
49
  }
42
50
 
@@ -64,8 +64,13 @@ class myWidget extends baseWidget(EventEmitter) {
64
64
  this.inputValue = []
65
65
  this.widget.destroy()
66
66
  this.emit('exitSearch')
67
+ this.screen.remove(this.widget)
68
+ this.screen.render()
67
69
  } else {
68
- this.emit('keypress', this.captureText(key))
70
+ const searchText = this.captureText(key)
71
+ this.widget.setValue(searchText)
72
+ this.emit('keypress', searchText)
73
+ this.screen.render()
69
74
  }
70
75
  })
71
76
 
@@ -86,12 +91,11 @@ class myWidget extends baseWidget(EventEmitter) {
86
91
  // by default, remove this widget from the screen
87
92
  this.screen.remove(this.widget)
88
93
  }
89
-
90
94
  getWidget () {
91
95
  return this.grid.gridObj.set(...this.grid.gridLayout, this.blessed.textbox, {
92
- focused: false,
96
+ focused: true,
93
97
  border: 'line',
94
- style: this.getWidgetStyle({ bg: 'yellow', fg: 'black' }),
98
+ style: this.getWidgetStyle(),
95
99
  align: 'left',
96
100
  inputOnFocus: true,
97
101
  vi: true,
@@ -32,23 +32,30 @@ class myWidget extends ListWidget {
32
32
  let filteredContainersList = this.servicesListData[0]
33
33
  let serviceList = this.servicesListData.slice(1)
34
34
  let filteredServices = []
35
+ const headerRow = this.servicesListData[0]
35
36
 
36
37
  if (data) {
37
38
  filteredServices = serviceList.filter((service) => {
38
39
  const serviceName = service[1]
39
40
  const serviceImageName = service[2]
40
-
41
41
  if ((serviceName.indexOf(data) !== -1) || (serviceImageName.indexOf(data) !== -1)) {
42
42
  return true
43
43
  }
44
44
  })
45
45
  }
46
-
46
+ // Render filtered services if available; otherwise, it means either the user hasn't provided input or no matches were found.
47
47
  if (filteredServices.length > 0) {
48
48
  filteredServices.unshift(filteredContainersList)
49
49
  this.update(filteredServices)
50
50
  } else {
51
- this.update(this.servicesListData)
51
+ if (data.length > 0) {
52
+ this.update([
53
+ headerRow,
54
+ ['', 'No Services found matching: ' + data, '', '', '', '', '']
55
+ ])
56
+ } else {
57
+ this.update(this.servicesListData)
58
+ }
52
59
  }
53
60
  }
54
61