@ntlab/sipd-tu-bridge-ui 1.1.4 → 1.2.0

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/controller/ui.js CHANGED
@@ -125,10 +125,17 @@ class UiController extends Controller {
125
125
  }
126
126
  res.json(about);
127
127
  });
128
- this.addRoute('task', 'post', '/task/:op', (req, res, next) => {
128
+ this.addRoute('task', 'post', '/task/:op', async (req, res, next) => {
129
129
  const result = {
130
130
  success: false
131
131
  }
132
+ /** @type {import('..').SipdApi} */
133
+ const api = req.app.api;
134
+ switch (req.params.op) {
135
+ case 'restart':
136
+ Object.assign(result, await api.query({cmd: 'restart'}));
137
+ break;
138
+ }
132
139
  res.json(result);
133
140
  });
134
141
  }
package/index.js CHANGED
@@ -39,6 +39,7 @@
39
39
  * @property {StringPromiseFunction} getActivity Get activity logs
40
40
  * @property {ObjectPromiseFunction} getCount Get activity count
41
41
  * @property {PagedObjectsPromiseFunction} getErrors Get captured errors
42
+ * @property {QueryFunction} query Perform API query
42
43
  */
43
44
 
44
45
  /**
@@ -95,6 +96,14 @@
95
96
  * @returns {Promise<string>}
96
97
  */
97
98
 
99
+ /**
100
+ * A function which returns object Promise.
101
+ *
102
+ * @callback QueryFunction
103
+ * @param {object} data Query data
104
+ * @returns {Promise<object>}
105
+ */
106
+
98
107
  /* --- END API --- */
99
108
 
100
109
  const createError = require('http-errors');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ntlab/sipd-tu-bridge-ui",
3
- "version": "1.1.4",
3
+ "version": "1.2.0",
4
4
  "description": "SIPD Penatausahaan Bridge Web Interface",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -16,8 +16,11 @@ img.logo {
16
16
  }
17
17
 
18
18
  @media only screen and (min-width: 1200px) {
19
+ .ui.container.queue-name {
20
+ max-width: 20em;
21
+ }
19
22
  .ui.container.queue-result {
20
- max-width: 30em;
23
+ max-width: 22.5em;
21
24
  }
22
25
  .ui.container.err-data {
23
26
  max-width: 40em;
@@ -25,8 +28,11 @@ img.logo {
25
28
  }
26
29
 
27
30
  @media only screen and (min-width: 992px) and (max-width: 1199.98px) {
31
+ .ui.container.queue-name {
32
+ max-width: 15em;
33
+ }
28
34
  .ui.container.queue-result {
29
- max-width: 25em;
35
+ max-width: 17.5em;
30
36
  }
31
37
  .ui.container.err-data {
32
38
  max-width: 30em;
@@ -34,8 +40,11 @@ img.logo {
34
40
  }
35
41
 
36
42
  @media only screen and (min-width: 768px) and (max-width: 991.98px) {
43
+ .ui.container.queue-name {
44
+ max-width: 10em;
45
+ }
37
46
  .ui.container.queue-result {
38
- max-width: 20em;
47
+ max-width: 12.5em;
39
48
  }
40
49
  .ui.container.err-data {
41
50
  max-width: 20em;
@@ -43,11 +52,8 @@ img.logo {
43
52
  }
44
53
 
45
54
  @media only screen and (max-width: 767.98px) {
46
- .ui.container.queue-result {
47
- max-width: 75vw;
48
- margin-left: 0 !important;
49
- margin-right: 0 !important;
50
- }
55
+ .ui.container.queue-name,
56
+ .ui.container.queue-result,
51
57
  .ui.container.err-data {
52
58
  max-width: 75vw;
53
59
  margin-left: 0 !important;
@@ -20,6 +20,12 @@
20
20
  divider1: {
21
21
  type: 'divider'
22
22
  },
23
+ restart: {
24
+ title: _('Restart Server'),
25
+ },
26
+ divider2: {
27
+ type: 'divider'
28
+ },
23
29
  logout: {
24
30
  title: _('Logout'),
25
31
  url: route('Security', {name: 'logout'})
@@ -28,7 +34,7 @@
28
34
  } -%>
29
35
  <%- menu(menus, {mainmenu: true, indentation: 2}) %>
30
36
  <%_ script.create('JQuery')
31
- .useDependencies(['JQuery/Util', 'SemanticUI/Notification', 'SemanticUI/Dialog/Message'])
37
+ .useDependencies(['JQuery/Util', 'SemanticUI/Notification', 'SemanticUI/Dialog/Message', 'SemanticUI/Dialog/Confirm'])
32
38
  .add(`
33
39
  $.tasks = {
34
40
  about() {
@@ -57,11 +63,45 @@ $.tasks = {
57
63
  f();
58
64
  }
59
65
  },
66
+ restart() {
67
+ const self = this;
68
+ if (self._restart === undefined) {
69
+ self._restart = true;
70
+ $.ntdlg.confirm(
71
+ 'restart-confirm-dlg',
72
+ '${_('Confirm')}',
73
+ '${_('Are you sure want to restart the server?')}',
74
+ $.ntdlg.ICON_QUESTION,
75
+ function() {
76
+ $.post('${route('Ui', {name: 'task', op: 'restart'})}')
77
+ .done(function(json) {
78
+ self.notify(json);
79
+ })
80
+ .always(function() {
81
+ delete self._restart;
82
+ });
83
+ },
84
+ function() {
85
+ delete self._restart;
86
+ }
87
+ );
88
+ }
89
+ },
90
+ notify(result) {
91
+ if (result.success) {
92
+ $.notify('${_('Operation successfully submitted!')}', 'success');
93
+ } else {
94
+ $.notify('${_('Operation failed!')}', 'error');
95
+ }
96
+ },
60
97
  init() {
61
98
  const self = this;
62
- $('.menu-about').on('click', function(e) {
99
+ $('.menu div.item').on('click', function(e) {
63
100
  e.preventDefault();
64
- self.about();
101
+ const menu = $(this).attr('class').split(' ')[0].split('-')[1];
102
+ if (typeof self[menu] === 'function') {
103
+ self[menu]();
104
+ }
65
105
  });
66
106
  }
67
107
  }
@@ -25,6 +25,7 @@
25
25
  <div class="ui bottom attached tab segment" data-tab="error">
26
26
  <%- include('error') -%>
27
27
  </div>
28
+ <%- include('ticker') -%>
28
29
  <%- include('util') -%>
29
30
  <%_ script.create('JQuery')
30
31
  .useDependencies(['SocketIO'])
@@ -39,6 +40,9 @@ $.uiCon = {
39
40
  .on('connect', function() {
40
41
  self.connected = true;
41
42
  console.log('Socket connected');
43
+ if (self.restarted) {
44
+ window.location.reload();
45
+ }
42
46
  })
43
47
  .on('disconnect', function() {
44
48
  self.connected = false;
@@ -64,12 +68,17 @@ $.uiCon = {
64
68
  })
65
69
  .on('error', function() {
66
70
  $.error.reload();
71
+ })
72
+ .on('restart', function() {
73
+ console.log('Server restarted');
74
+ self.restarted = true;
75
+ $.ticker.start('${_('A server restart is undergo&hellip;')}');
67
76
  });
68
77
  }
69
78
  }
70
79
  `)
71
80
  .addInitializer(`
72
- $('.menu .item').tab({
81
+ $('.menu [data-tab]').tab({
73
82
  autoTabActivation: window.location.hash ? window.location.hash.substr(1) : true,
74
83
  onLoad(path, params, history) {
75
84
  window.location.hash = path;
@@ -40,7 +40,7 @@ $.queue.toRow = function(data) {
40
40
  \`<tr><td>\${data.nr}</td>
41
41
  <td>\${$.toStr(data.id)}</td>
42
42
  <td>\${$.toStr(data.type)}</td>
43
- <td>\${$.toStr(data.name)}</td>
43
+ <td><div class="ui scrolling container queue-name">\${$.hidePayload($.toStr(data.name))}</div></td>
44
44
  <td>\${this.toStatus(data.status)}</td>
45
45
  <td><div class="ui scrolling container queue-result">\${$.hidePayload($.toStr(data.result))}</div></td>
46
46
  <td>\${$.toStr(data.time)}</td>
@@ -0,0 +1,67 @@
1
+ <%_ script.create('JQuery')
2
+ .useDependencies(['SemanticUI/Dialog'])
3
+ .add(`
4
+ $.ticker = {
5
+ formatTick(value) {
6
+ return value.toString().padStart(2, '0');
7
+ },
8
+ formatTime(seconds) {
9
+ const self = this;
10
+ if (!self.seconds_in_hour) {
11
+ self.seconds_in_hour = 60 * 60;
12
+ }
13
+ if (!self.seconds_in_minute) {
14
+ self.seconds_in_minute = 60;
15
+ }
16
+ const hour = Math.floor(seconds / self.seconds_in_hour);
17
+ seconds -= hour * self.seconds_in_hour;
18
+ const minute = Math.floor(seconds / self.seconds_in_minute);
19
+ seconds -= minute * self.seconds_in_minute;
20
+ return \`\${self.formatTick(hour)}:\${self.formatTick(minute)}:\${self.formatTick(seconds)}\`;
21
+ },
22
+ build() {
23
+ const self = this;
24
+ self.start = new Date().getTime();
25
+ const f = function() {
26
+ const elapsed = Math.round((new Date().getTime() - self.start) / 1000);
27
+ $('.elapsed').text(self.formatTime(elapsed));
28
+ }
29
+ self.tick = setInterval(f, 1000);
30
+ f();
31
+ },
32
+ start(message) {
33
+ const self = this;
34
+ self.dlg = $.ntdlg.create(
35
+ 'restart-timer-dlg',
36
+ '${_('Please Wait')}',
37
+ \`<div class="ui grid container">
38
+ <div class="row">
39
+ <span class="ui large red text"><i class="clock outline icon"></i><span class="elapsed">00:00:00</span></span>
40
+ <span>&nbsp;&nbsp;&nbsp;</span>
41
+ <span class="ui large text">\${message}</span>
42
+ </div>
43
+ </div>\`,
44
+ {
45
+ size: 'small',
46
+ closable: false,
47
+ show() {
48
+ self.build();
49
+ },
50
+ hide() {
51
+ if (self.tick) {
52
+ clearInterval(self.tick);
53
+ delete self.tick;
54
+ }
55
+ }
56
+ }
57
+ );
58
+ $.ntdlg.show(self.dlg);
59
+ },
60
+ stop() {
61
+ const self = this;
62
+ if (self.dlg) {
63
+ $.ntdlg.close(self.dlg);
64
+ }
65
+ }
66
+ }
67
+ `) -%>
package/views/ui/util.ejs CHANGED
@@ -42,7 +42,7 @@ $.hidePayload = function(message) {
42
42
  if (message) {
43
43
  message = message.replace(
44
44
  /[A-Za-z0-9\\+\\/\\=\\@\\,]{40,}/g,
45
- s => \`<i class="comment dots outline icon" data-tooltip="\${s}" data-position="right center"></i>\`
45
+ s => \`<span data-tooltip="\${s}" data-position="right center"><i class="eye icon"></i></span>\`
46
46
  );
47
47
  }
48
48
  return message;