mirror of
https://github.com/jc21/nginx-proxy-manager.git
synced 2024-08-30 18:22:48 +00:00
Shell for UI pages, some placeholder dashboard stats
This commit is contained in:
parent
493bb77169
commit
c69b174771
25
src/backend/internal/report.js
Normal file
25
src/backend/internal/report.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const _ = require('lodash');
|
||||||
|
const error = require('../lib/error');
|
||||||
|
|
||||||
|
const internalReport = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Access} access
|
||||||
|
* @return {Promise}
|
||||||
|
*/
|
||||||
|
getHostsReport: access => {
|
||||||
|
return access.can('reports:hosts', 1)
|
||||||
|
.then(() => {
|
||||||
|
return {
|
||||||
|
proxy: 12,
|
||||||
|
redirection: 2,
|
||||||
|
stream: 1,
|
||||||
|
'404': 0
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = internalReport;
|
7
src/backend/lib/access/reports-hosts.json
Normal file
7
src/backend/lib/access/reports-hosts.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "roles#/definitions/user"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const pjson = require('../../../../package.json');
|
const pjson = require('../../../../package.json');
|
||||||
|
const error = require('../../lib/error');
|
||||||
|
|
||||||
let router = express.Router({
|
let router = express.Router({
|
||||||
caseSensitive: true,
|
caseSensitive: true,
|
||||||
@ -28,5 +29,16 @@ router.get('/', (req, res/*, next*/) => {
|
|||||||
|
|
||||||
router.use('/tokens', require('./tokens'));
|
router.use('/tokens', require('./tokens'));
|
||||||
router.use('/users', require('./users'));
|
router.use('/users', require('./users'));
|
||||||
|
router.use('/reports', require('./reports'));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API 404 for all other routes
|
||||||
|
*
|
||||||
|
* ALL /api/*
|
||||||
|
*/
|
||||||
|
router.all(/(.+)/, function (req, res, next) {
|
||||||
|
req.params.page = req.params['0'];
|
||||||
|
next(new error.ItemNotFoundError(req.params.page));
|
||||||
|
});
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
31
src/backend/routes/api/reports.js
Normal file
31
src/backend/routes/api/reports.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const express = require('express');
|
||||||
|
const jwtdecode = require('../../lib/express/jwt-decode');
|
||||||
|
const internalReport = require('../../internal/report');
|
||||||
|
|
||||||
|
let router = express.Router({
|
||||||
|
caseSensitive: true,
|
||||||
|
strict: true,
|
||||||
|
mergeParams: true
|
||||||
|
});
|
||||||
|
|
||||||
|
router
|
||||||
|
.route('/hosts')
|
||||||
|
.options((req, res) => {
|
||||||
|
res.sendStatus(204);
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET /reports/hosts
|
||||||
|
*/
|
||||||
|
.get(jwtdecode(), (req, res, next) => {
|
||||||
|
internalReport.getHostsReport(res.locals.access)
|
||||||
|
.then(data => {
|
||||||
|
res.status(200)
|
||||||
|
.send(data);
|
||||||
|
})
|
||||||
|
.catch(next);
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = router;
|
@ -225,5 +225,15 @@ module.exports = {
|
|||||||
loginAs: function (id) {
|
loginAs: function (id) {
|
||||||
return fetch('post', 'users/' + id + '/login');
|
return fetch('post', 'users/' + id + '/login');
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
Reports: {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
getHostStats: function () {
|
||||||
|
return fetch('get', 'reports/hosts');
|
||||||
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -94,6 +94,66 @@ module.exports = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nginx Proxy Hosts
|
||||||
|
*/
|
||||||
|
showNginxProxy: function () {
|
||||||
|
let controller = this;
|
||||||
|
|
||||||
|
require(['./main', './nginx/proxy/main'], (App, View) => {
|
||||||
|
controller.navigate('/nginx/proxy');
|
||||||
|
App.UI.showAppContent(new View());
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nginx Redirection Hosts
|
||||||
|
*/
|
||||||
|
showNginxRedirection: function () {
|
||||||
|
let controller = this;
|
||||||
|
|
||||||
|
require(['./main', './nginx/redirection/main'], (App, View) => {
|
||||||
|
controller.navigate('/nginx/redirection');
|
||||||
|
App.UI.showAppContent(new View());
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nginx Stream Hosts
|
||||||
|
*/
|
||||||
|
showNginxStream: function () {
|
||||||
|
let controller = this;
|
||||||
|
|
||||||
|
require(['./main', './nginx/stream/main'], (App, View) => {
|
||||||
|
controller.navigate('/nginx/stream');
|
||||||
|
App.UI.showAppContent(new View());
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nginx 404 Hosts
|
||||||
|
*/
|
||||||
|
showNginx404: function () {
|
||||||
|
let controller = this;
|
||||||
|
|
||||||
|
require(['./main', './nginx/404/main'], (App, View) => {
|
||||||
|
controller.navigate('/nginx/404');
|
||||||
|
App.UI.showAppContent(new View());
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nginx Access
|
||||||
|
*/
|
||||||
|
showNginxAccess: function () {
|
||||||
|
let controller = this;
|
||||||
|
|
||||||
|
require(['./main', './nginx/access/main'], (App, View) => {
|
||||||
|
controller.navigate('/nginx/access');
|
||||||
|
App.UI.showAppContent(new View());
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dashboard
|
* Dashboard
|
||||||
*/
|
*/
|
||||||
|
@ -1 +1,57 @@
|
|||||||
Hi
|
<div class="page-header">
|
||||||
|
<h1 class="page-title">Hi <%- getUserName() %></h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-6 col-lg-3">
|
||||||
|
<div class="card p-3">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<span class="stamp stamp-md bg-green mr-3">
|
||||||
|
<i class="fe fe-zap"></i>
|
||||||
|
</span>
|
||||||
|
<div>
|
||||||
|
<h4 class="m-0"><a href="/nginx/proxy"><%- getHostStat('proxy') %> <small>Proxy Hosts</small></a></h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-6 col-lg-3">
|
||||||
|
<div class="card p-3">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<span class="stamp stamp-md bg-yellow mr-3">
|
||||||
|
<i class="fe fe-shuffle"></i>
|
||||||
|
</span>
|
||||||
|
<div>
|
||||||
|
<h4 class="m-0"><a href="/nginx/redirection"><%- getHostStat('redirection') %> <small>Redirection Hosts</small></a></h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-6 col-lg-3">
|
||||||
|
<div class="card p-3">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<span class="stamp stamp-md bg-blue mr-3">
|
||||||
|
<i class="fe fe-radio"></i>
|
||||||
|
</span>
|
||||||
|
<div>
|
||||||
|
<h4 class="m-0"><a href="/nginx/stream"><%- getHostStat('stream') %> <small> Streams</small></a></h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-6 col-lg-3">
|
||||||
|
<div class="card p-3">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<span class="stamp stamp-md bg-red mr-3">
|
||||||
|
<i class="fe fe-zap-off"></i>
|
||||||
|
</span>
|
||||||
|
<div>
|
||||||
|
<h4 class="m-0"><a href="/nginx/404"><%- getHostStat('404') %> <small>404 Hosts</small></a></h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -1,10 +1,61 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const Mn = require('backbone.marionette');
|
const Mn = require('backbone.marionette');
|
||||||
|
const Cache = require('../cache');
|
||||||
|
const Controller = require('../controller');
|
||||||
|
const Api = require('../api');
|
||||||
|
const Helpers = require('../../lib/helpers');
|
||||||
const template = require('./main.ejs');
|
const template = require('./main.ejs');
|
||||||
|
|
||||||
module.exports = Mn.View.extend({
|
module.exports = Mn.View.extend({
|
||||||
template: template,
|
template: template,
|
||||||
id: 'dashboard'
|
id: 'dashboard',
|
||||||
});
|
|
||||||
|
|
||||||
|
stats: {},
|
||||||
|
|
||||||
|
ui: {
|
||||||
|
links: 'a'
|
||||||
|
},
|
||||||
|
|
||||||
|
events: {
|
||||||
|
'click @ui.links': function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
Controller.navigate($(e.currentTarget).attr('href'), true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
templateContext: function () {
|
||||||
|
let view = this;
|
||||||
|
|
||||||
|
return {
|
||||||
|
getUserName: function () {
|
||||||
|
return Cache.User.get('nickname') || Cache.User.get('name');
|
||||||
|
},
|
||||||
|
|
||||||
|
getHostStat: function (type) {
|
||||||
|
if (view.stats && typeof view.stats.hosts !== 'undefined' && typeof view.stats.hosts[type] !== 'undefined') {
|
||||||
|
return Helpers.niceNumber(view.stats.hosts[type]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return '-';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onRender: function () {
|
||||||
|
let view = this;
|
||||||
|
|
||||||
|
if (typeof view.stats.hosts === 'undefined') {
|
||||||
|
Api.Reports.getHostStats()
|
||||||
|
.then(response => {
|
||||||
|
if (!view.isDestroyed()) {
|
||||||
|
view.stats.hosts = response;
|
||||||
|
view.render();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
1
src/frontend/js/app/nginx/404/main.ejs
Normal file
1
src/frontend/js/app/nginx/404/main.ejs
Normal file
@ -0,0 +1 @@
|
|||||||
|
404
|
9
src/frontend/js/app/nginx/404/main.js
Normal file
9
src/frontend/js/app/nginx/404/main.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const Mn = require('backbone.marionette');
|
||||||
|
const template = require('./main.ejs');
|
||||||
|
|
||||||
|
module.exports = Mn.View.extend({
|
||||||
|
template: template,
|
||||||
|
id: 'nginx-404'
|
||||||
|
});
|
1
src/frontend/js/app/nginx/access/main.ejs
Normal file
1
src/frontend/js/app/nginx/access/main.ejs
Normal file
@ -0,0 +1 @@
|
|||||||
|
access
|
9
src/frontend/js/app/nginx/access/main.js
Normal file
9
src/frontend/js/app/nginx/access/main.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const Mn = require('backbone.marionette');
|
||||||
|
const template = require('./main.ejs');
|
||||||
|
|
||||||
|
module.exports = Mn.View.extend({
|
||||||
|
template: template,
|
||||||
|
id: 'nginx-access'
|
||||||
|
});
|
1
src/frontend/js/app/nginx/proxy/main.ejs
Normal file
1
src/frontend/js/app/nginx/proxy/main.ejs
Normal file
@ -0,0 +1 @@
|
|||||||
|
proxy
|
9
src/frontend/js/app/nginx/proxy/main.js
Normal file
9
src/frontend/js/app/nginx/proxy/main.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const Mn = require('backbone.marionette');
|
||||||
|
const template = require('./main.ejs');
|
||||||
|
|
||||||
|
module.exports = Mn.View.extend({
|
||||||
|
template: template,
|
||||||
|
id: 'nginx-proxy'
|
||||||
|
});
|
1
src/frontend/js/app/nginx/redirection/main.ejs
Normal file
1
src/frontend/js/app/nginx/redirection/main.ejs
Normal file
@ -0,0 +1 @@
|
|||||||
|
redirection
|
9
src/frontend/js/app/nginx/redirection/main.js
Normal file
9
src/frontend/js/app/nginx/redirection/main.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const Mn = require('backbone.marionette');
|
||||||
|
const template = require('./main.ejs');
|
||||||
|
|
||||||
|
module.exports = Mn.View.extend({
|
||||||
|
template: template,
|
||||||
|
id: 'nginx-redirection'
|
||||||
|
});
|
1
src/frontend/js/app/nginx/stream/main.ejs
Normal file
1
src/frontend/js/app/nginx/stream/main.ejs
Normal file
@ -0,0 +1 @@
|
|||||||
|
stream
|
9
src/frontend/js/app/nginx/stream/main.js
Normal file
9
src/frontend/js/app/nginx/stream/main.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const Mn = require('backbone.marionette');
|
||||||
|
const template = require('./main.ejs');
|
||||||
|
|
||||||
|
module.exports = Mn.View.extend({
|
||||||
|
template: template,
|
||||||
|
id: 'nginx-stream'
|
||||||
|
});
|
@ -8,6 +8,11 @@ module.exports = Mn.AppRouter.extend({
|
|||||||
users: 'showUsers',
|
users: 'showUsers',
|
||||||
profile: 'showProfile',
|
profile: 'showProfile',
|
||||||
logout: 'logout',
|
logout: 'logout',
|
||||||
|
'nginx/proxy': 'showNginxProxy',
|
||||||
|
'nginx/redirection': 'showNginxRedirection',
|
||||||
|
'nginx/404': 'showNginx404',
|
||||||
|
'nginx/stream': 'showNginxStream',
|
||||||
|
'nginx/access': 'showNginxAccess',
|
||||||
'*default': 'showDashboard'
|
'*default': 'showDashboard'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
<div class="row align-items-center">
|
<div class="row align-items-center">
|
||||||
<div class="col-lg order-lg-first">
|
<div class="col-lg order-lg-first">
|
||||||
<ul class="nav nav-tabs border-0 flex-column flex-lg-row">
|
<ul class="nav nav-tabs border-0 flex-column flex-lg-row">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="/" class="nav-link"><i class="fe fe-home"></i> Dashboard</a>
|
||||||
|
</li>
|
||||||
<li class="nav-item dropdown">
|
<li class="nav-item dropdown">
|
||||||
<a href="#" class="nav-link" data-toggle="dropdown"><i class="fe fe-monitor"></i> Hosts</a>
|
<a href="#" class="nav-link" data-toggle="dropdown"><i class="fe fe-monitor"></i> Hosts</a>
|
||||||
<div class="dropdown-menu dropdown-menu-arrow">
|
<div class="dropdown-menu dropdown-menu-arrow">
|
||||||
|
@ -12,22 +12,13 @@ module.exports = Mn.View.extend({
|
|||||||
template: template,
|
template: template,
|
||||||
|
|
||||||
ui: {
|
ui: {
|
||||||
link: 'a'
|
links: 'a'
|
||||||
},
|
},
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
'click @ui.link': function (e) {
|
'click @ui.links': function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
let href = $(e.currentTarget).attr('href');
|
Controller.navigate($(e.currentTarget).attr('href'), true);
|
||||||
|
|
||||||
switch (href) {
|
|
||||||
case '/':
|
|
||||||
Controller.showDashboard();
|
|
||||||
break;
|
|
||||||
case '/users':
|
|
||||||
Controller.showUsers();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">Email <span class="form-required">*</span></label>
|
<label class="form-label">Email <span class="form-required">*</span></label>
|
||||||
<input name="email" type="email" class="form-control" placeholder="joe@example.com" value="<%- email %>" required>
|
<input name="email" type="email" class="form-control" placeholder="joe@example.com" value="<%- email %>" required>
|
||||||
|
<div class="invalid-feedback secret-error"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<% if (!isSelf()) { %>
|
<% if (!isSelf()) { %>
|
||||||
|
@ -18,13 +18,15 @@ module.exports = Mn.View.extend({
|
|||||||
form: 'form',
|
form: 'form',
|
||||||
buttons: '.modal-footer button',
|
buttons: '.modal-footer button',
|
||||||
cancel: 'button.cancel',
|
cancel: 'button.cancel',
|
||||||
save: 'button.save'
|
save: 'button.save',
|
||||||
|
error: '.secret-error'
|
||||||
},
|
},
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
|
|
||||||
'click @ui.save': function (e) {
|
'click @ui.save': function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
this.ui.error.hide();
|
||||||
let view = this;
|
let view = this;
|
||||||
let data = this.ui.form.serializeJSON();
|
let data = this.ui.form.serializeJSON();
|
||||||
|
|
||||||
@ -59,7 +61,7 @@ module.exports = Mn.View.extend({
|
|||||||
App.UI.closeModal();
|
App.UI.closeModal();
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
alert(err.message);
|
this.ui.error.text(err.message).show();
|
||||||
this.ui.buttons.prop('disabled', false).removeClass('btn-disabled');
|
this.ui.buttons.prop('disabled', false).removeClass('btn-disabled');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user