diff --git a/src/frontend/js/app/controller.js b/src/frontend/js/app/controller.js index ab9d11d3..46ff67cc 100644 --- a/src/frontend/js/app/controller.js +++ b/src/frontend/js/app/controller.js @@ -214,6 +214,19 @@ module.exports = { } }, + /** + * Nginx Stream Form + * + * @param [model] + */ + showNginxStreamForm: function (model) { + if (Cache.User.isAdmin() || Cache.User.canManage('proxy_hosts')) { + require(['./main', './nginx/stream/form'], function (App, View) { + App.UI.showModalDialog(new View({model: model})); + }); + } + }, + /** * Nginx Dead Hosts */ diff --git a/src/frontend/js/app/nginx/stream/delete.ejs b/src/frontend/js/app/nginx/stream/delete.ejs new file mode 100644 index 00000000..d7ba3a21 --- /dev/null +++ b/src/frontend/js/app/nginx/stream/delete.ejs @@ -0,0 +1,19 @@ + diff --git a/src/frontend/js/app/nginx/stream/delete.js b/src/frontend/js/app/nginx/stream/delete.js new file mode 100644 index 00000000..94105e8d --- /dev/null +++ b/src/frontend/js/app/nginx/stream/delete.js @@ -0,0 +1,36 @@ +'use strict'; + +const Mn = require('backbone.marionette'); +const App = require('../../main'); +const template = require('./delete.ejs'); + +require('jquery-serializejson'); + +module.exports = Mn.View.extend({ + template: template, + className: 'modal-dialog', + + ui: { + form: 'form', + buttons: '.modal-footer button', + cancel: 'button.cancel', + save: 'button.save' + }, + + events: { + + 'click @ui.save': function (e) { + e.preventDefault(); + + App.Api.Nginx.Streams.delete(this.model.get('id')) + .then(() => { + App.Controller.showNginxStream(); + App.UI.closeModal(); + }) + .catch(err => { + alert(err.message); + this.ui.buttons.prop('disabled', false).removeClass('btn-disabled'); + }); + } + } +}); diff --git a/src/frontend/js/app/nginx/stream/form.ejs b/src/frontend/js/app/nginx/stream/form.ejs new file mode 100644 index 00000000..c1feee13 --- /dev/null +++ b/src/frontend/js/app/nginx/stream/form.ejs @@ -0,0 +1,52 @@ + diff --git a/src/frontend/js/app/nginx/stream/form.js b/src/frontend/js/app/nginx/stream/form.js new file mode 100644 index 00000000..143e54ed --- /dev/null +++ b/src/frontend/js/app/nginx/stream/form.js @@ -0,0 +1,93 @@ +'use strict'; + +const _ = require('underscore'); +const Mn = require('backbone.marionette'); +const App = require('../../main'); +const StreamModel = require('../../../models/stream'); +const template = require('./form.ejs'); + +require('jquery-serializejson'); +require('jquery-mask-plugin'); +require('selectize'); + +module.exports = Mn.View.extend({ + template: template, + className: 'modal-dialog', + max_file_size: 5120, + + ui: { + form: 'form', + forward_ip: 'input[name="forward_ip"]', + buttons: '.modal-footer button', + cancel: 'button.cancel', + save: 'button.save' + }, + + events: { + 'click @ui.save': function (e) { + e.preventDefault(); + + if (!this.ui.form[0].checkValidity()) { + $('').hide().appendTo(this.ui.form).click().remove(); + return; + } + + let view = this; + let data = this.ui.form.serializeJSON(); + + // Manipulate + data.forward_port = parseInt(data.forward_port, 10); + _.map(data, function (item, idx) { + if (typeof item === 'string' && item === '1') { + item = true; + } else if (typeof item === 'object' && item !== null) { + _.map(item, function (item2, idx2) { + if (typeof item2 === 'string' && item2 === '1') { + item[idx2] = true; + } + }); + } + data[idx] = item; + }); + + let method = App.Api.Nginx.Streams.create; + let is_new = true; + + if (this.model.get('id')) { + // edit + is_new = false; + method = App.Api.Nginx.Streams.update; + data.id = this.model.get('id'); + } + + this.ui.buttons.prop('disabled', true).addClass('btn-disabled'); + method(data) + .then(result => { + view.model.set(result); + + App.UI.closeModal(function () { + if (is_new) { + App.Controller.showNginxStream(); + } + }); + }) + .catch(err => { + alert(err.message); + this.ui.buttons.prop('disabled', false).removeClass('btn-disabled'); + }); + } + }, + + onRender: function () { + this.ui.forward_ip.mask('099.099.099.099', { + clearIfNotMatch: true, + placeholder: '000.000.000.000' + }); + }, + + initialize: function (options) { + if (typeof options.model === 'undefined' || !options.model) { + this.model = new StreamModel.Model(); + } + } +}); diff --git a/src/frontend/js/app/nginx/stream/list/item.ejs b/src/frontend/js/app/nginx/stream/list/item.ejs index bd4d19e0..b1aab6e4 100644 --- a/src/frontend/js/app/nginx/stream/list/item.ejs +++ b/src/frontend/js/app/nginx/stream/list/item.ejs @@ -1,32 +1,40 @@ -
- +
+
-
<%- name %>
+
+ <% domain_names.map(function(host) { + %> + <%- host %> + <% + }); + %> +
- Created: <%- formatDbDate(created_on, 'Do MMMM YYYY') %> + <%- i18n('str', 'created-on', {date: formatDbDate(created_on, 'Do MMMM YYYY')}) %>
-
<%- email %>
+
<%- forward_ip %>:<%- forward_port %>
-
<%- roles.join(', ') %>
+
<%- ssl_enabled && ssl_provider ? i18n('ssl', ssl_provider) : i18n('ssl', 'none') %>
+ +
<%- access_list_id ? access_list.name : i18n('str', 'public') %>
+ +<% if (canManage) { %> +<% } %> \ No newline at end of file diff --git a/src/frontend/js/app/nginx/stream/list/item.js b/src/frontend/js/app/nginx/stream/list/item.js index e2a68255..52a201e8 100644 --- a/src/frontend/js/app/nginx/stream/list/item.js +++ b/src/frontend/js/app/nginx/stream/list/item.js @@ -1,69 +1,32 @@ 'use strict'; -const Mn = require('backbone.marionette'); -const Controller = require('../../../controller'); -const Api = require('../../../api'); -const Cache = require('../../../cache'); -const Tokens = require('../../../tokens'); -const template = require('./item.ejs'); +const Mn = require('backbone.marionette'); +const App = require('../../../main'); +const template = require('./item.ejs'); module.exports = Mn.View.extend({ template: template, tagName: 'tr', ui: { - edit: 'a.edit-user', - permissions: 'a.edit-permissions', - password: 'a.set-password', - login: 'a.login', - delete: 'a.delete-user' + edit: 'a.edit', + delete: 'a.delete' }, events: { 'click @ui.edit': function (e) { e.preventDefault(); - Controller.showUserForm(this.model); - }, - - 'click @ui.permissions': function (e) { - e.preventDefault(); - Controller.showUserPermissions(this.model); - }, - - 'click @ui.password': function (e) { - e.preventDefault(); - Controller.showUserPasswordForm(this.model); + App.Controller.showNginxProxyForm(this.model); }, 'click @ui.delete': function (e) { e.preventDefault(); - Controller.showUserDeleteConfirm(this.model); - }, - - 'click @ui.login': function (e) { - e.preventDefault(); - - if (Cache.User.get('id') !== this.model.get('id')) { - this.ui.login.prop('disabled', true).addClass('btn-disabled'); - - Api.Users.loginAs(this.model.get('id')) - .then(res => { - Tokens.addToken(res.token, res.user.nickname || res.user.name); - window.location = '/'; - window.location.reload(); - }) - .catch(err => { - alert(err.message); - this.ui.login.prop('disabled', false).removeClass('btn-disabled'); - }); - } + App.Controller.showNginxProxyDeleteConfirm(this.model); } }, templateContext: { - isSelf: function () { - return Cache.User.get('id') === this.id; - } + canManage: App.Cache.User.canManage('proxy_hosts') }, initialize: function () { diff --git a/src/frontend/js/app/nginx/stream/list/main.ejs b/src/frontend/js/app/nginx/stream/list/main.ejs index ce893413..f2c64ea3 100644 --- a/src/frontend/js/app/nginx/stream/list/main.ejs +++ b/src/frontend/js/app/nginx/stream/list/main.ejs @@ -1,9 +1,12 @@   - Name - Email - Roles + <%- i18n('str', 'source') %> + <%- i18n('str', 'destination') %> + <%- i18n('str', 'ssl') %> + <%- i18n('str', 'access') %> + <% if (canManage) { %>   + <% } %> diff --git a/src/frontend/js/app/nginx/stream/list/main.js b/src/frontend/js/app/nginx/stream/list/main.js index 80b7bd54..64896c1f 100644 --- a/src/frontend/js/app/nginx/stream/list/main.js +++ b/src/frontend/js/app/nginx/stream/list/main.js @@ -1,8 +1,9 @@ 'use strict'; -const Mn = require('backbone.marionette'); -const ItemView = require('./item'); -const template = require('./main.ejs'); +const Mn = require('backbone.marionette'); +const App = require('../../../main'); +const ItemView = require('./item'); +const template = require('./main.ejs'); const TableBody = Mn.CollectionView.extend({ tagName: 'tbody', @@ -21,6 +22,10 @@ module.exports = Mn.View.extend({ } }, + templateContext: { + canManage: App.Cache.User.canManage('proxy_hosts') + }, + onRender: function () { this.showChildView('body', new TableBody({ collection: this.collection diff --git a/src/frontend/js/app/nginx/stream/main.ejs b/src/frontend/js/app/nginx/stream/main.ejs index dee68bf8..84e914be 100644 --- a/src/frontend/js/app/nginx/stream/main.ejs +++ b/src/frontend/js/app/nginx/stream/main.ejs @@ -1,10 +1,10 @@
-

Streams

+

<%- i18n('streams', 'title') %>

<% if (showAddButton) { %> - Add Stream + <%- i18n('streams', 'add') %> <% } %>
diff --git a/src/frontend/js/app/nginx/stream/main.js b/src/frontend/js/app/nginx/stream/main.js index d3607fe2..bdf1a441 100644 --- a/src/frontend/js/app/nginx/stream/main.js +++ b/src/frontend/js/app/nginx/stream/main.js @@ -1,17 +1,15 @@ 'use strict'; const Mn = require('backbone.marionette'); +const App = require('../../main'); const StreamModel = require('../../../models/stream'); -const Api = require('../../api'); -const Cache = require('../../cache'); -const Controller = require('../../controller'); const ListView = require('./list/main'); const ErrorView = require('../../error/main'); -const template = require('./main.ejs'); const EmptyView = require('../../empty/main'); +const template = require('./main.ejs'); module.exports = Mn.View.extend({ - id: 'nginx-streams', + id: 'nginx-stream', template: template, ui: { @@ -27,18 +25,18 @@ module.exports = Mn.View.extend({ events: { 'click @ui.add': function (e) { e.preventDefault(); - Controller.showNginxStreamForm(); + App.Controller.showNginxStreamForm(); } }, templateContext: { - showAddButton: Cache.User.canManage('streams') + showAddButton: App.Cache.User.canManage('streams') }, onRender: function () { let view = this; - Api.Nginx.RedirectionHosts.getAll() + App.Api.Nginx.Streams.getAll(['owner']) .then(response => { if (!view.isDestroyed()) { if (response && response.length) { @@ -46,15 +44,16 @@ module.exports = Mn.View.extend({ collection: new StreamModel.Collection(response) })); } else { - let manage = Cache.User.canManage('streams'); + let manage = App.Cache.User.canManage('streams'); view.showChildView('list_region', new EmptyView({ - title: 'There are no Streams', - subtitle: manage ? 'Why don\'t you create one?' : 'And you don\'t have permission to create one.', - link: manage ? 'Add Stream' : null, - btn_color: 'blue', - action: function () { - Controller.showNginxStreamForm(); + title: App.i18n('streams', 'empty'), + subtitle: App.i18n('all-hosts', 'empty-subtitle', {manage: manage}), + link: manage ? App.i18n('streams', 'add') : null, + btn_color: 'blue', + permission: 'streams', + action: function () { + App.Controller.showNginxStreamForm(); } })); } @@ -65,7 +64,7 @@ module.exports = Mn.View.extend({ code: err.code, message: err.message, retry: function () { - Controller.showNginxStream(); + App.Controller.showNginxStream(); } })); diff --git a/src/frontend/js/i18n/messages.json b/src/frontend/js/i18n/messages.json index b6f750a0..7856e4a4 100644 --- a/src/frontend/js/i18n/messages.json +++ b/src/frontend/js/i18n/messages.json @@ -97,7 +97,9 @@ "title": "404 Hosts" }, "streams": { - "title": "Streams" + "title": "Streams", + "empty": "There are no Streams", + "add": "Add Stream" }, "access-lists": { "title": "Access Lists", diff --git a/src/frontend/js/models/stream.js b/src/frontend/js/models/stream.js index 775c37de..e11ba3e6 100644 --- a/src/frontend/js/models/stream.js +++ b/src/frontend/js/models/stream.js @@ -11,12 +11,12 @@ const model = Backbone.Model.extend({ created_on: null, modified_on: null, owner: null, - incoming_port: 0, + incoming_port: 3000, forward_ip: '', - forwarding_port: 0, + forwarding_port: 3000, tcp_forwarding: true, udp_forwarding: false, - meta: [] + meta: {} }; } });