mirror of
				https://github.com/NginxProxyManager/nginx-proxy-manager.git
				synced 2025-10-31 07:43:33 +00:00 
			
		
		
		
	i18n and improvements
This commit is contained in:
		| @@ -1,6 +1,6 @@ | ||||
| <div class="card"> | ||||
|     <div class="card-header"> | ||||
|         <h3 class="card-title">Audit Log</h3> | ||||
|         <h3 class="card-title"><%- i18n('audit-log', 'title') %></h3> | ||||
|     </div> | ||||
|     <div class="card-body no-padding min-100"> | ||||
|         <div class="dimmer active"> | ||||
|   | ||||
| @@ -1,9 +1,8 @@ | ||||
| 'use strict'; | ||||
|  | ||||
| const Mn            = require('backbone.marionette'); | ||||
| const App           = require('../main'); | ||||
| const AuditLogModel = require('../../models/audit-log'); | ||||
| const Api           = require('../api'); | ||||
| const Controller    = require('../controller'); | ||||
| const ListView      = require('./list/main'); | ||||
| const template      = require('./main.ejs'); | ||||
| const ErrorView     = require('../error/main'); | ||||
| @@ -25,7 +24,7 @@ module.exports = Mn.View.extend({ | ||||
|     onRender: function () { | ||||
|         let view = this; | ||||
|  | ||||
|         Api.AuditLog.getAll() | ||||
|         App.Api.AuditLog.getAll() | ||||
|             .then(response => { | ||||
|                 if (!view.isDestroyed() && response && response.length) { | ||||
|                     view.showChildView('list_region', new ListView({ | ||||
| @@ -33,8 +32,8 @@ module.exports = Mn.View.extend({ | ||||
|                     })); | ||||
|                 } else { | ||||
|                     view.showChildView('list_region', new EmptyView({ | ||||
|                         title:    'There are no logs.', | ||||
|                         subtitle: 'As soon as you or another user changes something, history of those events will show up here.' | ||||
|                         title:    App.i18n('audit-log', 'empty'), | ||||
|                         subtitle: App.i18n('audit-log', 'empty-subtitle') | ||||
|                     })); | ||||
|                 } | ||||
|             }) | ||||
| @@ -43,7 +42,7 @@ module.exports = Mn.View.extend({ | ||||
|                     code:    err.code, | ||||
|                     message: err.message, | ||||
|                     retry:   function () { | ||||
|                         Controller.showAuditLog(); | ||||
|                         App.Controller.showAuditLog(); | ||||
|                     } | ||||
|                 })); | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| <div class="page-header"> | ||||
|     <h1 class="page-title">Hi <%- getUserName() %></h1> | ||||
|     <h1 class="page-title"><%- i18n('dashboard', 'title', {name: getUserName()}) %></h1> | ||||
| </div> | ||||
|  | ||||
| <% if (columns) { %> | ||||
| @@ -12,7 +12,7 @@ | ||||
|                       <i class="fe fe-zap"></i> | ||||
|                     </span> | ||||
|                 <div> | ||||
|                     <h4 class="m-0"><a href="/nginx/proxy"><%- getHostStat('proxy') %> <small>Proxy Hosts</small></a></h4> | ||||
|                     <h4 class="m-0"><a href="/nginx/proxy"><%- getHostStat('proxy') %> <small><%- i18n('proxy-hosts', 'title') %></small></a></h4> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
| @@ -27,7 +27,7 @@ | ||||
|                       <i class="fe fe-shuffle"></i> | ||||
|                     </span> | ||||
|                 <div> | ||||
|                     <h4 class="m-0"><a href="/nginx/redirection"><%- getHostStat('redirection') %> <small>Redirection Hosts</small></a></h4> | ||||
|                     <h4 class="m-0"><a href="/nginx/redirection"><%- getHostStat('redirection') %> <small><%- i18n('redirection-hosts', 'title') %></small></a></h4> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
| @@ -42,7 +42,7 @@ | ||||
|                       <i class="fe fe-radio"></i> | ||||
|                     </span> | ||||
|                 <div> | ||||
|                     <h4 class="m-0"><a href="/nginx/stream"><%- getHostStat('stream') %> <small> Streams</small></a></h4> | ||||
|                     <h4 class="m-0"><a href="/nginx/stream"><%- getHostStat('stream') %> <small> <%- i18n('streams', 'title') %></small></a></h4> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
| @@ -57,7 +57,7 @@ | ||||
|                       <i class="fe fe-zap-off"></i> | ||||
|                     </span> | ||||
|                 <div> | ||||
|                     <h4 class="m-0"><a href="/nginx/404"><%- getHostStat('dead') %> <small>404 Hosts</small></a></h4> | ||||
|                     <h4 class="m-0"><a href="/nginx/404"><%- getHostStat('dead') %> <small><%- i18n('dead-hosts', 'title') %></small></a></h4> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
|   | ||||
| @@ -3,5 +3,5 @@ | ||||
| <%- message %> | ||||
|  | ||||
| <% if (retry) { %> | ||||
|     <br><br><a href="#" class="btn btn-sm btn-warning retry">Try again</a> | ||||
|     <br><br><a href="#" class="btn btn-sm btn-warning retry"><%- i18n('str', 'try-again') %></a> | ||||
| <% } %> | ||||
|   | ||||
| @@ -21,5 +21,5 @@ module.exports = function (namespace, key, data) { | ||||
|         return messages['en'][namespace][key](data); | ||||
|     } | ||||
|  | ||||
|     return 'INVALID I18N: ' + namespace + '/' + key; | ||||
|     return '(MISSING: ' + namespace + '/' + key + ')'; | ||||
| }; | ||||
|   | ||||
| @@ -16,6 +16,7 @@ const App = Mn.Application.extend({ | ||||
|     Cache:      Cache, | ||||
|     Api:        Api, | ||||
|     UI:         null, | ||||
|     i18n:       i18n, | ||||
|     Controller: Controller, | ||||
|  | ||||
|     region: { | ||||
|   | ||||
| @@ -1,13 +1,13 @@ | ||||
| <div class="modal-content"> | ||||
|     <div class="modal-header"> | ||||
|         <h5 class="modal-title"><% if (typeof id !== 'undefined') { %>Edit<% } else { %>New<% } %> Proxy Host</h5> | ||||
|         <h5 class="modal-title"><%- i18n('proxy-hosts', 'form-title', {id: id}) %></h5> | ||||
|         <button type="button" class="close cancel" aria-label="Close" data-dismiss="modal"> </button> | ||||
|     </div> | ||||
|     <div class="modal-body has-tabs"> | ||||
|         <form> | ||||
|             <ul class="nav nav-tabs" role="tablist"> | ||||
|                 <li role="presentation" class="nav-item"><a href="#details" aria-controls="tab1" role="tab" data-toggle="tab" class="nav-link active"><i class="fe fe-zap"></i> Details</a></li> | ||||
|                 <li role="presentation" class="nav-item"><a href="#ssl-options" aria-controls="tab2" role="tab" data-toggle="tab" class="nav-link"><i class="fe fe-shield"></i> SSL</a></li> | ||||
|                 <li role="presentation" class="nav-item"><a href="#details" aria-controls="tab1" role="tab" data-toggle="tab" class="nav-link active"><i class="fe fe-zap"></i> <%- i18n('all-hosts', 'details') %></a></li> | ||||
|                 <li role="presentation" class="nav-item"><a href="#ssl-options" aria-controls="tab2" role="tab" data-toggle="tab" class="nav-link"><i class="fe fe-shield"></i> <%- i18n('all-hosts', 'SSL') %></a></li> | ||||
|             </ul> | ||||
|             <div class="tab-content"> | ||||
|                 <!-- Details --> | ||||
| @@ -16,19 +16,19 @@ | ||||
|  | ||||
|                         <div class="col-sm-12 col-md-12"> | ||||
|                             <div class="form-group"> | ||||
|                                 <label class="form-label">Domain Names <span class="form-required">*</span></label> | ||||
|                                 <label class="form-label"><%- i18n('all-hosts', 'domain-names') %> <span class="form-required">*</span></label> | ||||
|                                 <input type="text" name="domain_names" class="form-control" id="input-domains" value="<%- domain_names.join(',') %>" required> | ||||
|                             </div> | ||||
|                         </div> | ||||
|                         <div class="col-sm-8 col-md-8"> | ||||
|                             <div class="form-group"> | ||||
|                                 <label class="form-label">Forward IP <span class="form-required">*</span></label> | ||||
|                                 <label class="form-label"><%- i18n('proxy-hosts', 'forward-ip') %><span class="form-required">*</span></label> | ||||
|                                 <input type="text" name="forward_ip" class="form-control text-monospace" placeholder="000.000.000.000" value="<%- forward_ip %>" autocomplete="off" maxlength="15" required> | ||||
|                             </div> | ||||
|                         </div> | ||||
|                         <div class="col-sm-4 col-md-4"> | ||||
|                             <div class="form-group"> | ||||
|                                 <label class="form-label">Forward Port <span class="form-required">*</span></label> | ||||
|                                 <label class="form-label"><%- i18n('proxy-hosts', 'forward-port') %> <span class="form-required">*</span></label> | ||||
|                                 <input name="forward_port" type="number" class="form-control text-monospace" placeholder="80" value="<%- forward_port %>" required> | ||||
|                             </div> | ||||
|                         </div> | ||||
| @@ -43,7 +43,7 @@ | ||||
|                                 <label class="custom-switch"> | ||||
|                                     <input type="checkbox" class="custom-switch-input" name="ssl_enabled" value="1"<%- ssl_enabled ? ' checked' : '' %>> | ||||
|                                     <span class="custom-switch-indicator"></span> | ||||
|                                     <span class="custom-switch-description">Enable SSL</span> | ||||
|                                     <span class="custom-switch-description"><%- i18n('all-hosts', 'enable-ssl') %></span> | ||||
|                                 </label> | ||||
|                             </div> | ||||
|                         </div> | ||||
| @@ -52,21 +52,21 @@ | ||||
|                                 <label class="custom-switch"> | ||||
|                                     <input type="checkbox" class="custom-switch-input" name="ssl_forced" value="1"<%- ssl_forced ? ' checked' : '' %><%- ssl_enabled ? '' : ' disabled' %>> | ||||
|                                     <span class="custom-switch-indicator"></span> | ||||
|                                     <span class="custom-switch-description">Force SSL</span> | ||||
|                                     <span class="custom-switch-description"><%- i18n('all-hosts', 'force-ssl') %></span> | ||||
|                                 </label> | ||||
|                             </div> | ||||
|                         </div> | ||||
|                         <div class="col-sm-12 col-md-12"> | ||||
|                             <div class="form-group"> | ||||
|                                 <label class="form-label">Certificate Provider</label> | ||||
|                                 <label class="form-label"><%- i18n('all-hosts', 'cert-provider') %></label> | ||||
|                                 <div class="selectgroup w-100"> | ||||
|                                     <label class="selectgroup-item"> | ||||
|                                         <input type="radio" name="ssl_provider" value="letsencrypt" class="selectgroup-input"<%- ssl_provider !== 'other' ? ' checked' : '' %>> | ||||
|                                         <span class="selectgroup-button">Let's Encrypt</span> | ||||
|                                         <span class="selectgroup-button"><%- i18n('all-hosts', 'letsencrypt') %></span> | ||||
|                                     </label> | ||||
|                                     <label class="selectgroup-item"> | ||||
|                                         <input type="radio" name="ssl_provider" value="other" class="selectgroup-input"<%- ssl_provider === 'other' ? ' checked' : '' %>> | ||||
|                                         <span class="selectgroup-button">Other</span> | ||||
|                                         <span class="selectgroup-button"><%- i18n('all-hosts', 'other-ssl') %></span> | ||||
|                                     </label> | ||||
|                                 </div> | ||||
|                             </div> | ||||
| @@ -75,7 +75,7 @@ | ||||
|                         <!-- Lets encrypt --> | ||||
|                         <div class="col-sm-12 col-md-12 letsencrypt-ssl"> | ||||
|                             <div class="form-group"> | ||||
|                                 <label class="form-label">Email Address for Let's Encrypt <span class="form-required">*</span></label> | ||||
|                                 <label class="form-label"><%- i18n('all-hosts', 'letsencrypt-email') %> <span class="form-required">*</span></label> | ||||
|                                 <input name="meta[letsencrypt_email]" type="email" class="form-control" placeholder="" value="<%- getLetsencryptEmail() %>" required> | ||||
|                             </div> | ||||
|                         </div> | ||||
| @@ -84,7 +84,7 @@ | ||||
|                                 <label class="custom-switch"> | ||||
|                                     <input type="checkbox" class="custom-switch-input" name="meta[letsencrypt_agree]" value="1" required<%- getLetsencryptAgree() ? ' checked' : '' %>> | ||||
|                                     <span class="custom-switch-indicator"></span> | ||||
|                                     <span class="custom-switch-description">I Agree to the <a href="https://letsencrypt.org/repository/" target="_blank">Let's Encrypt Terms of Service</a> <span class="form-required">*</span></span> | ||||
|                                     <span class="custom-switch-description"><%= i18n('all-hosts', 'letsencrypt-agree', {url: 'https://letsencrypt.org/repository/'}) %> <span class="form-required">*</span></span> | ||||
|                                 </label> | ||||
|                             </div> | ||||
|                         </div> | ||||
| @@ -92,19 +92,19 @@ | ||||
|                         <!-- Other --> | ||||
|                         <div class="col-sm-12 col-md-12 other-ssl"> | ||||
|                             <div class="form-group"> | ||||
|                                 <div class="form-label">Certificate</div> | ||||
|                                 <div class="form-label"><%- i18n('all-hosts', 'other-certificate') %></div> | ||||
|                                 <div class="custom-file"> | ||||
|                                     <input type="file" class="custom-file-input" name="meta[other_ssl_certificate]"> | ||||
|                                     <label class="custom-file-label">Choose file</label> | ||||
|                                     <label class="custom-file-label"><%- i18n('str', 'choose-file') %></label> | ||||
|                                 </div> | ||||
|                             </div> | ||||
|                         </div> | ||||
|                         <div class="col-sm-12 col-md-12 other-ssl"> | ||||
|                             <div class="form-group"> | ||||
|                                 <div class="form-label">Certificate Key</div> | ||||
|                                 <div class="form-label"><%- i18n('all-hosts', 'other-certificate-key') %></div> | ||||
|                                 <div class="custom-file"> | ||||
|                                     <input type="file" class="custom-file-input" name="meta[other_ssl_certificate_key]"> | ||||
|                                     <label class="custom-file-label">Choose file</label> | ||||
|                                     <label class="custom-file-label"><%- i18n('str', 'choose-file') %></label> | ||||
|                                 </div> | ||||
|                             </div> | ||||
|                         </div> | ||||
| @@ -116,7 +116,7 @@ | ||||
|         </form> | ||||
|     </div> | ||||
|     <div class="modal-footer"> | ||||
|         <button type="button" class="btn btn-secondary cancel" data-dismiss="modal">Cancel</button> | ||||
|         <button type="button" class="btn btn-teal save">Save</button> | ||||
|         <button type="button" class="btn btn-secondary cancel" data-dismiss="modal"><%- i18n('str', 'cancel') %></button> | ||||
|         <button type="button" class="btn btn-teal save"><%- i18n('str', 'save') %></button> | ||||
|     </div> | ||||
| </div> | ||||
|   | ||||
| @@ -2,12 +2,9 @@ | ||||
|  | ||||
| const _              = require('underscore'); | ||||
| const Mn             = require('backbone.marionette'); | ||||
| const template       = require('./form.ejs'); | ||||
| const Controller     = require('../../controller'); | ||||
| const Cache          = require('../../cache'); | ||||
| const Api            = require('../../api'); | ||||
| const App            = require('../../main'); | ||||
| const ProxyHostModel = require('../../../models/proxy-host'); | ||||
| const template       = require('./form.ejs'); | ||||
|  | ||||
| require('jquery-serializejson'); | ||||
| require('jquery-mask-plugin'); | ||||
| @@ -80,11 +77,11 @@ module.exports = Mn.View.extend({ | ||||
|  | ||||
|             // Process | ||||
|             this.ui.buttons.prop('disabled', true).addClass('btn-disabled'); | ||||
|             let method = Api.Nginx.ProxyHosts.create; | ||||
|             let method = App.Api.Nginx.ProxyHosts.create; | ||||
|  | ||||
|             if (this.model.get('id')) { | ||||
|                 // edit | ||||
|                 method  = Api.Nginx.ProxyHosts.update; | ||||
|                 method  = App.Api.Nginx.ProxyHosts.update; | ||||
|                 data.id = this.model.get('id'); | ||||
|             } | ||||
|  | ||||
| @@ -92,8 +89,8 @@ module.exports = Mn.View.extend({ | ||||
|                 .then(result => { | ||||
|                     view.model.set(result); | ||||
|                     App.UI.closeModal(function () { | ||||
|                         if (method === Api.Nginx.ProxyHosts.create) { | ||||
|                             Controller.showNginxProxy(); | ||||
|                         if (method === App.Api.Nginx.ProxyHosts.create) { | ||||
|                             App.Controller.showNginxProxy(); | ||||
|                         } | ||||
|                     }); | ||||
|                 }) | ||||
| @@ -106,7 +103,7 @@ module.exports = Mn.View.extend({ | ||||
|  | ||||
|     templateContext: { | ||||
|         getLetsencryptEmail: function () { | ||||
|             return typeof this.meta.letsencrypt_email !== 'undefined' ? this.meta.letsencrypt_email : Cache.User.get('email'); | ||||
|             return typeof this.meta.letsencrypt_email !== 'undefined' ? this.meta.letsencrypt_email : App.Cache.User.get('email'); | ||||
|         }, | ||||
|  | ||||
|         getLetsencryptAgree: function () { | ||||
|   | ||||
| @@ -1,10 +1,10 @@ | ||||
| <div class="card"> | ||||
|     <div class="card-status bg-success"></div> | ||||
|     <div class="card-header"> | ||||
|         <h3 class="card-title">Proxy Hosts</h3> | ||||
|         <h3 class="card-title"><%- i18n('proxy-hosts', 'title') %></h3> | ||||
|         <div class="card-options"> | ||||
|             <% if (showAddButton) { %> | ||||
|             <a href="#" class="btn btn-outline-success btn-sm ml-2 add-item">Add Proxy Host</a> | ||||
|             <a href="#" class="btn btn-outline-success btn-sm ml-2 add-item"><%- i18n('proxy-hosts', 'add') %></a> | ||||
|             <% } %> | ||||
|         </div> | ||||
|     </div> | ||||
|   | ||||
| @@ -1,14 +1,12 @@ | ||||
| 'use strict'; | ||||
|  | ||||
| const Mn             = require('backbone.marionette'); | ||||
| const App            = require('../../main'); | ||||
| const ProxyHostModel = require('../../../models/proxy-host'); | ||||
| 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-proxy', | ||||
| @@ -27,18 +25,18 @@ module.exports = Mn.View.extend({ | ||||
|     events: { | ||||
|         'click @ui.add': function (e) { | ||||
|             e.preventDefault(); | ||||
|             Controller.showNginxProxyForm(); | ||||
|             App.Controller.showNginxProxyForm(); | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     templateContext: { | ||||
|         showAddButton: Cache.User.canManage('proxy_hosts') | ||||
|         showAddButton: App.Cache.User.canManage('proxy_hosts') | ||||
|     }, | ||||
|  | ||||
|     onRender: function () { | ||||
|         let view = this; | ||||
|  | ||||
|         Api.Nginx.ProxyHosts.getAll(['owner', 'access_list']) | ||||
|         App.Api.Nginx.ProxyHosts.getAll(['owner', 'access_list']) | ||||
|             .then(response => { | ||||
|                 if (!view.isDestroyed()) { | ||||
|                     if (response && response.length) { | ||||
| @@ -46,16 +44,16 @@ module.exports = Mn.View.extend({ | ||||
|                             collection: new ProxyHostModel.Collection(response) | ||||
|                         })); | ||||
|                     } else { | ||||
|                         let manage = Cache.User.canManage('proxy_hosts'); | ||||
|                         let manage = App.Cache.User.canManage('proxy_hosts'); | ||||
|  | ||||
|                         view.showChildView('list_region', new EmptyView({ | ||||
|                             title:      'There are no Proxy Hosts', | ||||
|                             subtitle:   manage ? 'Why don\'t you create one?' : 'And you don\'t have permission to create one.', | ||||
|                             link:       manage ? 'Add Proxy Host' : null, | ||||
|                             title:      App.i18n('proxy-hosts', 'empty'), | ||||
|                             subtitle:   App.i18n('all-hosts', 'empty-subtitle', {manage: manage}), | ||||
|                             link:       manage ? App.i18n('proxy-hosts', 'add') : null, | ||||
|                             btn_color:  'success', | ||||
|                             permission: 'proxy_hosts', | ||||
|                             action:     function () { | ||||
|                                 Controller.showNginxProxyForm(); | ||||
|                                 App.Controller.showNginxProxyForm(); | ||||
|                             } | ||||
|                         })); | ||||
|                     } | ||||
| @@ -66,7 +64,7 @@ module.exports = Mn.View.extend({ | ||||
|                     code:    err.code, | ||||
|                     message: err.message, | ||||
|                     retry:   function () { | ||||
|                         Controller.showNginxProxy(); | ||||
|                         App.Controller.showNginxProxy(); | ||||
|                     } | ||||
|                 })); | ||||
|  | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
|         </div> | ||||
|     </div> | ||||
|     <div class="col-12 col-lg-auto mt-3 mt-lg-0 text-center"> | ||||
|         <%- i18n('footer', 'version', {version: getVersion()}) %> | ||||
|         <%- i18n('main', 'version', {version: getVersion()}) %> | ||||
|         <%= i18n('footer', 'copy', {url: 'https://jc21.com?utm_source=nginx-proxy-manager'}) %> | ||||
|         <%= i18n('footer', 'theme', {url: 'https://tabler.github.io/?utm_source=nginx-proxy-manager'}) %> | ||||
|     </div> | ||||
|   | ||||
| @@ -15,10 +15,10 @@ | ||||
|                 </a> | ||||
|                 <div class="dropdown-menu dropdown-menu-right dropdown-menu-arrow"> | ||||
|                     <a class="dropdown-item edit-details" href="#"> | ||||
|                         <i class="dropdown-icon fe fe-user"></i> <%- i18n('user', 'edit-details') %> | ||||
|                         <i class="dropdown-icon fe fe-user"></i> <%- i18n('users', 'edit-details') %> | ||||
|                     </a> | ||||
|                     <a class="dropdown-item change-password" href="#"> | ||||
|                         <i class="dropdown-icon fe fe-lock"></i> <%- i18n('user', 'change-password') %> | ||||
|                         <i class="dropdown-icon fe fe-lock"></i> <%- i18n('users', 'change-password') %> | ||||
|                     </a> | ||||
|                     <div class="dropdown-divider"></div> | ||||
|                     <a class="dropdown-item logout" href="/logout"> | ||||
|   | ||||
| @@ -59,7 +59,7 @@ module.exports = Mn.View.extend({ | ||||
|                 return i18n('main', 'sign-in-as', {name: Tokens.getNextTokenName()}); | ||||
|             } | ||||
|  | ||||
|             return i18n('main', 'sign-out'); | ||||
|             return i18n('str', 'sign-out'); | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|   | ||||
| @@ -3,39 +3,39 @@ | ||||
|         <div class="col-lg order-lg-first"> | ||||
|             <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> | ||||
|                     <a href="/" class="nav-link"><i class="fe fe-home"></i> <%- i18n('menu', 'dashboard') %></a> | ||||
|                 </li> | ||||
|                 <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> <%- i18n('menu', 'hosts') %></a> | ||||
|                     <div class="dropdown-menu dropdown-menu-arrow"> | ||||
|                         <% if (canShow('proxy_hosts')) { %> | ||||
|                         <a href="/nginx/proxy" class="dropdown-item ">Proxy Hosts</a> | ||||
|                         <a href="/nginx/proxy" class="dropdown-item "><%- i18n('proxy-hosts', 'title') %></a> | ||||
|                         <% } %> | ||||
|  | ||||
|                         <% if (canShow('redirection_hosts')) { %> | ||||
|                         <a href="/nginx/redirection" class="dropdown-item ">Redirections</a> | ||||
|                         <a href="/nginx/redirection" class="dropdown-item "><%- i18n('redirection-hosts', 'title') %></a> | ||||
|                         <% } %> | ||||
|  | ||||
|                         <% if (canShow('streams')) { %> | ||||
|                         <a href="/nginx/stream" class="dropdown-item ">Streams</a> | ||||
|                         <a href="/nginx/stream" class="dropdown-item "><%- i18n('streams', 'title') %></a> | ||||
|                         <% } %> | ||||
|  | ||||
|                         <% if (canShow('dead_hosts')) { %> | ||||
|                         <a href="/nginx/404" class="dropdown-item ">404 Hosts</a> | ||||
|                         <a href="/nginx/404" class="dropdown-item "><%- i18n('dead-hosts', 'title') %></a> | ||||
|                         <% } %> | ||||
|                     </div> | ||||
|                 </li> | ||||
|                 <% if (canShow('access_lists')) { %> | ||||
|                 <li class="nav-item"> | ||||
|                     <a href="/nginx/access" class="nav-link"><i class="fe fe-lock"></i> Access Lists</a> | ||||
|                     <a href="/nginx/access" class="nav-link"><i class="fe fe-lock"></i> <%- i18n('access-lists', 'title') %></a> | ||||
|                 </li> | ||||
|                 <% } %> | ||||
|                 <% if (isAdmin()) { %> | ||||
|                 <li class="nav-item"> | ||||
|                     <a href="/users" class="nav-link"><i class="fe fe-users"></i> Users</a> | ||||
|                     <a href="/users" class="nav-link"><i class="fe fe-users"></i> <%- i18n('users', 'title') %></a> | ||||
|                 </li> | ||||
|                 <li class="nav-item"> | ||||
|                     <a href="/audit-log" class="nav-link"><i class="fe fe-book-open"></i> Audit Log</a> | ||||
|                     <a href="/audit-log" class="nav-link"><i class="fe fe-book-open"></i> <%- i18n('audit-log', 'title') %></a> | ||||
|                 </li> | ||||
|                 <% } %> | ||||
|             </ul> | ||||
|   | ||||
| @@ -1,19 +1,19 @@ | ||||
| <div class="modal-content"> | ||||
|     <div class="modal-header"> | ||||
|         <h5 class="modal-title">Delete <%- name %></h5> | ||||
|         <h5 class="modal-title"><%- i18n('users', 'delete', {name: name}) %></h5> | ||||
|         <button type="button" class="close cancel" aria-label="Close" data-dismiss="modal"> </button> | ||||
|     </div> | ||||
|     <div class="modal-body"> | ||||
|         <form> | ||||
|             <div class="row"> | ||||
|                 <div class="col-sm-12 col-md-12"> | ||||
|                     Are you sure you want to delete <strong><%- name %></strong>? | ||||
|                     <%= i18n('users', 'delete-confirm', {name: name}) %> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </form> | ||||
|     </div> | ||||
|     <div class="modal-footer"> | ||||
|         <button type="button" class="btn btn-secondary cancel" data-dismiss="modal">Cancel</button> | ||||
|         <button type="button" class="btn btn-danger save">Yes I'm Sure</button> | ||||
|         <button type="button" class="btn btn-secondary cancel" data-dismiss="modal"><%- i18n('str', 'cancel') %></button> | ||||
|         <button type="button" class="btn btn-danger save"><%- i18n('str', 'sure') %></button> | ||||
|     </div> | ||||
| </div> | ||||
|   | ||||
| @@ -2,8 +2,6 @@ | ||||
|  | ||||
| const Mn       = require('backbone.marionette'); | ||||
| const template = require('./delete.ejs'); | ||||
| const Controller = require('../controller'); | ||||
| const Api        = require('../api'); | ||||
| const App      = require('../main'); | ||||
|  | ||||
| require('jquery-serializejson'); | ||||
| @@ -24,9 +22,9 @@ module.exports = Mn.View.extend({ | ||||
|         'click @ui.save': function (e) { | ||||
|             e.preventDefault(); | ||||
|  | ||||
|             Api.Users.delete(this.model.get('id')) | ||||
|             App.Api.Users.delete(this.model.get('id')) | ||||
|                 .then(() => { | ||||
|                     Controller.showUsers(); | ||||
|                     App.Controller.showUsers(); | ||||
|                     App.UI.closeModal(); | ||||
|                 }) | ||||
|                 .catch(err => { | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <div class="modal-content"> | ||||
|     <div class="modal-header"> | ||||
|         <h5 class="modal-title"><% if (typeof id !== 'undefined') { %>Edit<% } else { %>New<% } %> User</h5> | ||||
|         <h5 class="modal-title"><%- i18n('users', 'form-title', {id: id}) %></h5> | ||||
|         <button type="button" class="close cancel" aria-label="Close" data-dismiss="modal"> </button> | ||||
|     </div> | ||||
|     <div class="modal-body"> | ||||
| @@ -8,33 +8,33 @@ | ||||
|             <div class="row"> | ||||
|                 <div class="col-sm-6 col-md-6"> | ||||
|                     <div class="form-group"> | ||||
|                         <label class="form-label">Full Name <span class="form-required">*</span></label> | ||||
|                         <label class="form-label"><%- i18n('users', 'full-name') %> <span class="form-required">*</span></label> | ||||
|                         <input name="name" type="text" class="form-control" placeholder="Joe Citizen" value="<%- name %>" required> | ||||
|                     </div> | ||||
|                 </div> | ||||
|                 <div class="col-sm-6 col-md-6"> | ||||
|                     <div class="form-group"> | ||||
|                         <label class="form-label">Nickname</label> | ||||
|                         <label class="form-label"><%- i18n('users', 'nickname') %></label> | ||||
|                         <input name="nickname" type="text" class="form-control" placeholder="Joe" value="<%- nickname %>"> | ||||
|                     </div> | ||||
|                 </div> | ||||
|                 <div class="col-sm-12 col-md-12"> | ||||
|                     <div class="form-group"> | ||||
|                         <label class="form-label">Email <span class="form-required">*</span></label> | ||||
|                         <label class="form-label"><%- i18n('str', 'email') %> <span class="form-required">*</span></label> | ||||
|                         <input name="email" type="email" class="form-control" placeholder="joe@example.com" value="<%- email %>" required> | ||||
|                         <div class="invalid-feedback secret-error"></div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|                 <% if (isAdmin()) { %> | ||||
|                 <div class="col-sm-12 col-md-12"> | ||||
|                     <div class="form-label">Roles</div> | ||||
|                     <div class="form-label"><%- i18n('roles', 'title') %></div> | ||||
|                 </div> | ||||
|                 <div class="col-sm-6 col-md-6"> | ||||
|                     <div class="form-group"> | ||||
|                         <label class="custom-switch"> | ||||
|                             <input type="checkbox" class="custom-switch-input" name="is_admin" value="1"<%- isAdmin() ? ' checked' : '' %><%- isSelf() ? ' disabled' : '' %>> | ||||
|                             <span class="custom-switch-indicator"></span> | ||||
|                             <span class="custom-switch-description">Administrator</span> | ||||
|                             <span class="custom-switch-description"><%- i18n('roles', 'admin') %></span> | ||||
|                         </label> | ||||
|                     </div> | ||||
|                 </div> | ||||
| @@ -43,7 +43,7 @@ | ||||
|                         <label class="custom-switch"> | ||||
|                             <input type="checkbox" class="custom-switch-input" name="is_disabled" value="1"<%- is_disabled ? ' checked' : '' %><%- isSelf() ? ' disabled' : '' %>> | ||||
|                             <span class="custom-switch-indicator"></span> | ||||
|                             <span class="custom-switch-description">Disabled</span> | ||||
|                             <span class="custom-switch-description"><%- i18n('str', 'disabled') %></span> | ||||
|                         </label> | ||||
|                     </div> | ||||
|                 </div> | ||||
| @@ -52,7 +52,7 @@ | ||||
|         </form> | ||||
|     </div> | ||||
|     <div class="modal-footer"> | ||||
|         <button type="button" class="btn btn-secondary cancel" data-dismiss="modal">Cancel</button> | ||||
|         <button type="button" class="btn btn-teal save">Save</button> | ||||
|         <button type="button" class="btn btn-secondary cancel" data-dismiss="modal"><%- i18n('str', 'cancel') %></button> | ||||
|         <button type="button" class="btn btn-teal save"><%- i18n('str', 'save') %></button> | ||||
|     </div> | ||||
| </div> | ||||
|   | ||||
| @@ -1,12 +1,9 @@ | ||||
| 'use strict'; | ||||
|  | ||||
| const Mn        = require('backbone.marionette'); | ||||
| const template   = require('./form.ejs'); | ||||
| const Controller = require('../controller'); | ||||
| const Cache      = require('../cache'); | ||||
| const Api        = require('../api'); | ||||
| const App       = require('../main'); | ||||
| const UserModel = require('../../models/user'); | ||||
| const template  = require('./form.ejs'); | ||||
|  | ||||
| require('jquery-serializejson'); | ||||
|  | ||||
| @@ -34,45 +31,45 @@ module.exports = Mn.View.extend({ | ||||
|  | ||||
|             // admin@example.com is not allowed | ||||
|             if (data.email === 'admin@example.com') { | ||||
|                 this.ui.error.text('Default email address must be changed').show(); | ||||
|                 this.ui.error.text(App.i18n('users', 'default_error')).show(); | ||||
|                 this.ui.buttons.prop('disabled', false).removeClass('btn-disabled'); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             // Manipulate | ||||
|             data.roles = []; | ||||
|             if ((this.model.get('id') === Cache.User.get('id') && this.model.isAdmin()) || (typeof data.is_admin !== 'undefined' && data.is_admin)) { | ||||
|             if ((this.model.get('id') === App.Cache.User.get('id') && this.model.isAdmin()) || (typeof data.is_admin !== 'undefined' && data.is_admin)) { | ||||
|                 data.roles.push('admin'); | ||||
|                 delete data.is_admin; | ||||
|             } | ||||
|  | ||||
|             data.is_disabled = typeof data.is_disabled !== 'undefined' ? !!data.is_disabled : false; | ||||
|             this.ui.buttons.prop('disabled', true).addClass('btn-disabled'); | ||||
|             let method = Api.Users.create; | ||||
|             let method = App.Api.Users.create; | ||||
|  | ||||
|             if (this.model.get('id')) { | ||||
|                 // edit | ||||
|                 method  = Api.Users.update; | ||||
|                 method  = App.Api.Users.update; | ||||
|                 data.id = this.model.get('id'); | ||||
|             } | ||||
|  | ||||
|             method(data) | ||||
|                 .then(result => { | ||||
|                     if (result.id === Cache.User.get('id')) { | ||||
|                         Cache.User.set(result); | ||||
|                     if (result.id === App.Cache.User.get('id')) { | ||||
|                         App.Cache.User.set(result); | ||||
|                     } | ||||
|  | ||||
|                     if (view.model.get('id') !== Cache.User.get('id')) { | ||||
|                         Controller.showUsers(); | ||||
|                     if (view.model.get('id') !== App.Cache.User.get('id')) { | ||||
|                         App.Controller.showUsers(); | ||||
|                     } | ||||
|  | ||||
|                     view.model.set(result); | ||||
|                     App.UI.closeModal(function () { | ||||
|                         if (method === Api.Users.create) { | ||||
|                     App.App.UI.closeModal(function () { | ||||
|                         if (method === App.Api.Users.create) { | ||||
|                             // Show permissions dialog immediately | ||||
|                             Controller.showUserPermissions(view.model); | ||||
|                             App.Controller.showUserPermissions(view.model); | ||||
|                         } else if (show_password) { | ||||
|                             Controller.showUserPasswordForm(view.model); | ||||
|                             App.Controller.showUserPasswordForm(view.model); | ||||
|                         } | ||||
|                     }); | ||||
|                 }) | ||||
| @@ -88,7 +85,7 @@ module.exports = Mn.View.extend({ | ||||
|  | ||||
|         return { | ||||
|             isSelf: function () { | ||||
|                 return view.model.get('id') === Cache.User.get('id'); | ||||
|                 return view.model.get('id') === App.Cache.User.get('id'); | ||||
|             }, | ||||
|  | ||||
|             isAdmin: function () { | ||||
|   | ||||
| @@ -1,30 +1,30 @@ | ||||
| <div class="modal-content"> | ||||
|     <div class="modal-header"> | ||||
|         <h5 class="modal-title">Change Password <%- isSelf() ? '' : 'for' + name %></h5> | ||||
|         <h5 class="modal-title"><%- i18n('users', 'form-title', {self: isSelf(), name: name}) %></h5> | ||||
|         <button type="button" class="close cancel" aria-label="Close" data-dismiss="modal"> </button> | ||||
|     </div> | ||||
|     <div class="modal-body"> | ||||
|         <form> | ||||
|             <% if (isSelf()) { %> | ||||
|             <div class="form-group"> | ||||
|                 <label class="form-label">Current Password</label> | ||||
|                 <label class="form-label"><%- i18n('users', 'current-password') %></label> | ||||
|                 <input type="password" name="current_password" class="form-control" placeholder="" minlength="8" required> | ||||
|             </div> | ||||
|             <% } %> | ||||
|  | ||||
|             <div class="form-group"> | ||||
|                 <label class="form-label">New Password</label> | ||||
|                 <label class="form-label"><%- i18n('users', 'new-password') %></label> | ||||
|                 <input type="password" name="new_password1" class="form-control" placeholder="" minlength="8" required> | ||||
|                 <div class="invalid-feedback secret-error"></div> | ||||
|             </div> | ||||
|             <div class="form-group"> | ||||
|                 <label class="form-label">Confirm Password</label> | ||||
|                 <label class="form-label"><%- i18n('users', 'confirm-password') %></label> | ||||
|                 <input type="password" name="new_password2" class="form-control" placeholder="" minlength="8" required> | ||||
|             </div> | ||||
|         </form> | ||||
|     </div> | ||||
|     <div class="modal-footer"> | ||||
|         <button type="button" class="btn btn-secondary cancel" data-dismiss="modal">Cancel</button> | ||||
|         <button type="button" class="btn btn-teal save">Save</button> | ||||
|         <button type="button" class="btn btn-secondary cancel" data-dismiss="modal"><%- i18n('str', 'cancel') %></button> | ||||
|         <button type="button" class="btn btn-teal save"><%- i18n('str', 'save') %></button> | ||||
|     </div> | ||||
| </div> | ||||
|   | ||||
| @@ -1,11 +1,8 @@ | ||||
| 'use strict'; | ||||
|  | ||||
| const Mn       = require('backbone.marionette'); | ||||
| const template   = require('./password.ejs'); | ||||
| const Controller = require('../controller'); | ||||
| const Api        = require('../api'); | ||||
| const App      = require('../main'); | ||||
| const Cache      = require('../cache'); | ||||
| const template = require('./password.ejs'); | ||||
|  | ||||
| require('jquery-serializejson'); | ||||
|  | ||||
| @@ -39,10 +36,10 @@ module.exports = Mn.View.extend({ | ||||
|             }; | ||||
|  | ||||
|             this.ui.buttons.prop('disabled', true).addClass('btn-disabled'); | ||||
|             Api.Users.setPassword(this.model.get('id'), data) | ||||
|             App.Api.Users.setPassword(this.model.get('id'), data) | ||||
|                 .then(() => { | ||||
|                     App.UI.closeModal(); | ||||
|                     Controller.showUsers(); | ||||
|                     App.Controller.showUsers(); | ||||
|                 }) | ||||
|                 .catch(err => { | ||||
|                     this.ui.error.text(err.message).show(); | ||||
| @@ -52,7 +49,7 @@ module.exports = Mn.View.extend({ | ||||
|     }, | ||||
|  | ||||
|     isSelf: function () { | ||||
|         return Cache.User.get('id') === this.model.get('id'); | ||||
|         return App.Cache.User.get('id') === this.model.get('id'); | ||||
|     }, | ||||
|  | ||||
|     templateContext: function () { | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <div class="modal-content"> | ||||
|     <div class="modal-header"> | ||||
|         <h5 class="modal-title">Permissions for <%- name %></h5> | ||||
|         <h5 class="modal-title"><%- i18n('users', 'permissions-title', {name: name}) %></h5> | ||||
|         <button type="button" class="close cancel" aria-label="Close" data-dismiss="modal"> </button> | ||||
|     </div> | ||||
|     <div class="modal-body"> | ||||
| @@ -11,130 +11,58 @@ | ||||
|                     <% if (isAdmin()) { %> | ||||
|                     <div class="alert alert-icon alert-secondary" role="alert"> | ||||
|                         <i class="fe fe-alert-triangle mr-2" aria-hidden="true"></i> | ||||
|                         This user is an Administrator and some items cannot be altered | ||||
|                         <%- i18n('users', 'admin-perms') %> | ||||
|                     </div> | ||||
|                     <% } %> | ||||
|  | ||||
|                     <div class="form-group"> | ||||
|                         <label class="form-label">Item Visibility</label> | ||||
|                         <label class="form-label"><%- i18n('users', 'perms-visibility') %></label> | ||||
|                         <div class="selectgroup w-100"> | ||||
|                             <label class="selectgroup-item"> | ||||
|                                 <input type="radio" name="visibility" value="user" class="selectgroup-input"<%- getPerm('visibility') !== 'all' ? ' checked' : '' %>> | ||||
|                                 <span class="selectgroup-button">Created Items Only</span> | ||||
|                                 <span class="selectgroup-button"><%- i18n('users', 'perms-visibility-user') %></span> | ||||
|                             </label> | ||||
|                             <label class="selectgroup-item"> | ||||
|                                 <input type="radio" name="visibility" value="all" class="selectgroup-input"<%- getPerm('visibility') === 'all' ? ' checked' : '' %>> | ||||
|                                 <span class="selectgroup-button">All Items</span> | ||||
|                                 <span class="selectgroup-button"><%- i18n('users', 'perms-visibility-all') %></span> | ||||
|                             </label> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|  | ||||
|                 <% | ||||
|                 var list = ['proxy-hosts', 'redirection-hosts', 'dead-hosts', 'streams', 'access-lists']; | ||||
|                 list.map(function(item) { | ||||
|                     var perm = item.replace('-', '_'); | ||||
|                     %> | ||||
|                     <div class="col-sm-12 col-md-12"> | ||||
|                         <div class="form-group"> | ||||
|                         <label class="form-label">Proxy Hosts</label> | ||||
|                             <label class="form-label"><%- i18n(item, 'title') %></label> | ||||
|                             <div class="selectgroup w-100"> | ||||
|                                 <label class="selectgroup-item"> | ||||
|                                 <input type="radio" name="proxy_hosts" value="manage" class="selectgroup-input" <%- getPermProps('proxy_hosts', 'manage', true) %>> | ||||
|                                 <span class="selectgroup-button">Manage</span> | ||||
|                                     <input type="radio" name="<%- perm %>" value="manage" class="selectgroup-input" <%- getPermProps(perm, 'manage', true) %>> | ||||
|                                     <span class="selectgroup-button"><%- i18n('users', 'perm-manage') %></span> | ||||
|                                 </label> | ||||
|                                 <label class="selectgroup-item"> | ||||
|                                 <input type="radio" name="proxy_hosts" value="view" class="selectgroup-input" <%- getPermProps('proxy_hosts', 'view') %>> | ||||
|                                 <span class="selectgroup-button">View Only</span> | ||||
|                                     <input type="radio" name="<%- perm %>" value="view" class="selectgroup-input" <%- getPermProps(perm, 'view') %>> | ||||
|                                     <span class="selectgroup-button"><%- i18n('users', 'perm-view') %></span> | ||||
|                                 </label> | ||||
|                                 <label class="selectgroup-item"> | ||||
|                                 <input type="radio" name="proxy_hosts" value="hidden" class="selectgroup-input" <%- getPermProps('proxy_hosts', 'hidden') %>> | ||||
|                                 <span class="selectgroup-button">Hidden</span> | ||||
|                             </label> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|  | ||||
|                 <div class="col-sm-12 col-md-12"> | ||||
|                     <div class="form-group"> | ||||
|                         <label class="form-label">Redirection Hosts</label> | ||||
|                         <div class="selectgroup w-100"> | ||||
|                             <label class="selectgroup-item"> | ||||
|                                 <input type="radio" name="redirection_hosts" value="manage" class="selectgroup-input" <%- getPermProps('redirection_hosts', 'manage', true) %>> | ||||
|                                 <span class="selectgroup-button">Manage</span> | ||||
|                             </label> | ||||
|                             <label class="selectgroup-item"> | ||||
|                                 <input type="radio" name="redirection_hosts" value="view" class="selectgroup-input" <%- getPermProps('redirection_hosts', 'view') %>> | ||||
|                                 <span class="selectgroup-button">View Only</span> | ||||
|                             </label> | ||||
|                             <label class="selectgroup-item"> | ||||
|                                 <input type="radio" name="redirection_hosts" value="hidden" class="selectgroup-input" <%- getPermProps('redirection_hosts', 'hidden') %>> | ||||
|                                 <span class="selectgroup-button">Hidden</span> | ||||
|                             </label> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|  | ||||
|                 <div class="col-sm-12 col-md-12"> | ||||
|                     <div class="form-group"> | ||||
|                         <label class="form-label">404 Hosts</label> | ||||
|                         <div class="selectgroup w-100"> | ||||
|                             <label class="selectgroup-item"> | ||||
|                                 <input type="radio" name="dead_hosts" value="manage" class="selectgroup-input" <%- getPermProps('dead_hosts', 'manage', true) %>> | ||||
|                                 <span class="selectgroup-button">Manage</span> | ||||
|                             </label> | ||||
|                             <label class="selectgroup-item"> | ||||
|                                 <input type="radio" name="dead_hosts" value="view" class="selectgroup-input" <%- getPermProps('dead_hosts', 'view') %>> | ||||
|                                 <span class="selectgroup-button">View Only</span> | ||||
|                             </label> | ||||
|                             <label class="selectgroup-item"> | ||||
|                                 <input type="radio" name="dead_hosts" value="hidden" class="selectgroup-input" <%- getPermProps('dead_hosts', 'hidden') %>> | ||||
|                                 <span class="selectgroup-button">Hidden</span> | ||||
|                             </label> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|  | ||||
|                 <div class="col-sm-12 col-md-12"> | ||||
|                     <div class="form-group"> | ||||
|                         <label class="form-label">Streams</label> | ||||
|                         <div class="selectgroup w-100"> | ||||
|                             <label class="selectgroup-item"> | ||||
|                                 <input type="radio" name="streams" value="manage" class="selectgroup-input" <%- getPermProps('streams', 'manage', true) %>> | ||||
|                                 <span class="selectgroup-button">Manage</span> | ||||
|                             </label> | ||||
|                             <label class="selectgroup-item"> | ||||
|                                 <input type="radio" name="streams" value="view" class="selectgroup-input" <%- getPermProps('streams', 'view') %>> | ||||
|                                 <span class="selectgroup-button">View Only</span> | ||||
|                             </label> | ||||
|                             <label class="selectgroup-item"> | ||||
|                                 <input type="radio" name="streams" value="hidden" class="selectgroup-input" <%- getPermProps('streams', 'hidden') %>> | ||||
|                                 <span class="selectgroup-button">Hidden</span> | ||||
|                             </label> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|  | ||||
|                 <div class="col-sm-12 col-md-12"> | ||||
|                     <div class="form-group"> | ||||
|                         <label class="form-label">Access Lists</label> | ||||
|                         <div class="selectgroup w-100"> | ||||
|                             <label class="selectgroup-item"> | ||||
|                                 <input type="radio" name="access_lists" value="manage" class="selectgroup-input" <%- getPermProps('access_lists', 'manage', true) %>> | ||||
|                                 <span class="selectgroup-button">Manage</span> | ||||
|                             </label> | ||||
|                             <label class="selectgroup-item"> | ||||
|                                 <input type="radio" name="access_lists" value="view" class="selectgroup-input" <%- getPermProps('access_lists', 'view') %>> | ||||
|                                 <span class="selectgroup-button">View Only</span> | ||||
|                             </label> | ||||
|                             <label class="selectgroup-item"> | ||||
|                                 <input type="radio" name="access_lists" value="hidden" class="selectgroup-input" <%- getPermProps('access_lists', 'hidden') %>> | ||||
|                                 <span class="selectgroup-button">Hidden</span> | ||||
|                                     <input type="radio" name="<%- perm %>" value="hidden" class="selectgroup-input" <%- getPermProps(perm, 'hidden') %>> | ||||
|                                     <span class="selectgroup-button"><%- i18n('users', 'perm-hidden') %></span> | ||||
|                                 </label> | ||||
|                             </div> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                     <% | ||||
|                 }); | ||||
|                 %> | ||||
|  | ||||
|             </div> | ||||
|         </form> | ||||
|     </div> | ||||
|     <div class="modal-footer"> | ||||
|         <button type="button" class="btn btn-secondary cancel" data-dismiss="modal">Cancel</button> | ||||
|         <button type="button" class="btn btn-teal save">Save</button> | ||||
|         <button type="button" class="btn btn-secondary cancel" data-dismiss="modal"><%- i18n('str', 'cancel') %></button> | ||||
|         <button type="button" class="btn btn-teal save"><%- i18n('str', 'save') %></button> | ||||
|     </div> | ||||
| </div> | ||||
|   | ||||
| @@ -1,12 +1,9 @@ | ||||
| 'use strict'; | ||||
|  | ||||
| const Mn        = require('backbone.marionette'); | ||||
| const template   = require('./permissions.ejs'); | ||||
| const Controller = require('../controller'); | ||||
| const Cache      = require('../cache'); | ||||
| const Api        = require('../api'); | ||||
| const App       = require('../main'); | ||||
| const UserModel = require('../../models/user'); | ||||
| const template  = require('./permissions.ejs'); | ||||
|  | ||||
| require('jquery-serializejson'); | ||||
|  | ||||
| @@ -44,10 +41,10 @@ module.exports = Mn.View.extend({ | ||||
|  | ||||
|             this.ui.buttons.prop('disabled', true).addClass('btn-disabled'); | ||||
|  | ||||
|             Api.Users.setPermissions(view.model.get('id'), data) | ||||
|             App.Api.Users.setPermissions(view.model.get('id'), data) | ||||
|                 .then(() => { | ||||
|                     if (view.model.get('id') === Cache.User.get('id')) { | ||||
|                         Cache.User.set({permissions: data}); | ||||
|                     if (view.model.get('id') === App.Cache.User.get('id')) { | ||||
|                         App.Cache.User.set({permissions: data}); | ||||
|                     } | ||||
|  | ||||
|                     view.model.set({permissions: data}); | ||||
|   | ||||
| @@ -6,26 +6,36 @@ | ||||
| <td> | ||||
|     <div><%- name %></div> | ||||
|     <div class="small text-muted"> | ||||
|         Created: <%- formatDbDate(created_on, 'Do MMMM YYYY') %> | ||||
|         <%- i18n('str', 'created-on', {date: formatDbDate(created_on, 'Do MMMM YYYY')}) %> | ||||
|     </div> | ||||
| </td> | ||||
| <td> | ||||
|     <div><%- email %></div> | ||||
| </td> | ||||
| <td> | ||||
|     <div><%- roles.join(', ') %></div> | ||||
|     <div> | ||||
|         <% | ||||
|         var r = []; | ||||
|         roles.map(function(role) { | ||||
|             if (role) { | ||||
|                 r.push(i18n('roles', role)); | ||||
|             } | ||||
|         }); | ||||
|         %> | ||||
|         <%- r.join(', ') %> | ||||
|     </div> | ||||
| </td> | ||||
| <td class="text-center"> | ||||
|     <div class="item-action dropdown"> | ||||
|         <a href="#" data-toggle="dropdown" class="icon"><i class="fe fe-more-vertical"></i></a> | ||||
|         <div class="dropdown-menu dropdown-menu-right"> | ||||
|             <a href="#" class="edit-user dropdown-item"><i class="dropdown-icon fe fe-edit"></i> Edit Details</a> | ||||
|             <a href="#" class="edit-permissions dropdown-item"><i class="dropdown-icon fe fe-shield"></i> Edit Permissions</a> | ||||
|             <a href="#" class="set-password dropdown-item"><i class="dropdown-icon fe fe-lock"></i> Set Password</a> | ||||
|             <a href="#" class="edit-user dropdown-item"><i class="dropdown-icon fe fe-edit"></i> <%- i18n('users', 'edit-details') %></a> | ||||
|             <a href="#" class="edit-permissions dropdown-item"><i class="dropdown-icon fe fe-shield"></i> <%- i18n('users', 'edit-permissions') %></a> | ||||
|             <a href="#" class="set-password dropdown-item"><i class="dropdown-icon fe fe-lock"></i> <%- i18n('users', 'change-password') %></a> | ||||
|             <% if (!isSelf()) { %> | ||||
|             <a href="#" class="login dropdown-item"><i class="dropdown-icon fe fe-log-in"></i> Sign in as User</a> | ||||
|             <a href="#" class="login dropdown-item"><i class="dropdown-icon fe fe-log-in"></i> <%- i18n('users', 'sign-in-as') %></a> | ||||
|             <div class="dropdown-divider"></div> | ||||
|             <a href="#" class="delete-user dropdown-item"><i class="dropdown-icon fe fe-trash-2"></i> Delete User</a> | ||||
|             <a href="#" class="delete-user dropdown-item"><i class="dropdown-icon fe fe-trash-2"></i> <%- i18n('users', 'delete') %></a> | ||||
|             <% } %> | ||||
|         </div> | ||||
|     </div> | ||||
|   | ||||
| @@ -1,9 +1,7 @@ | ||||
| 'use strict'; | ||||
|  | ||||
| const Mn       = require('backbone.marionette'); | ||||
| const Controller = require('../../controller'); | ||||
| const Api        = require('../../api'); | ||||
| const Cache      = require('../../cache'); | ||||
| const App      = require('../../main'); | ||||
| const Tokens   = require('../../tokens'); | ||||
| const template = require('./item.ejs'); | ||||
|  | ||||
| @@ -22,31 +20,31 @@ module.exports = Mn.View.extend({ | ||||
|     events: { | ||||
|         'click @ui.edit': function (e) { | ||||
|             e.preventDefault(); | ||||
|             Controller.showUserForm(this.model); | ||||
|             App.Controller.showUserForm(this.model); | ||||
|         }, | ||||
|  | ||||
|         'click @ui.permissions': function (e) { | ||||
|             e.preventDefault(); | ||||
|             Controller.showUserPermissions(this.model); | ||||
|             App.Controller.showUserPermissions(this.model); | ||||
|         }, | ||||
|  | ||||
|         'click @ui.password': function (e) { | ||||
|             e.preventDefault(); | ||||
|             Controller.showUserPasswordForm(this.model); | ||||
|             App.Controller.showUserPasswordForm(this.model); | ||||
|         }, | ||||
|  | ||||
|         'click @ui.delete': function (e) { | ||||
|             e.preventDefault(); | ||||
|             Controller.showUserDeleteConfirm(this.model); | ||||
|             App.Controller.showUserDeleteConfirm(this.model); | ||||
|         }, | ||||
|  | ||||
|         'click @ui.login': function (e) { | ||||
|             e.preventDefault(); | ||||
|  | ||||
|             if (Cache.User.get('id') !== this.model.get('id')) { | ||||
|             if (App.Cache.User.get('id') !== this.model.get('id')) { | ||||
|                 this.ui.login.prop('disabled', true).addClass('btn-disabled'); | ||||
|  | ||||
|                 Api.Users.loginAs(this.model.get('id')) | ||||
|                 App.Api.Users.loginAs(this.model.get('id')) | ||||
|                     .then(res => { | ||||
|                         Tokens.addToken(res.token, res.user.nickname || res.user.name); | ||||
|                         window.location = '/'; | ||||
| @@ -62,7 +60,7 @@ module.exports = Mn.View.extend({ | ||||
|  | ||||
|     templateContext: { | ||||
|         isSelf: function () { | ||||
|             return Cache.User.get('id') === this.id; | ||||
|             return App.Cache.User.get('id') === this.id; | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| <thead> | ||||
|     <th width="30"> </th> | ||||
|     <th>Name</th> | ||||
|     <th>Email</th> | ||||
|     <th>Roles</th> | ||||
|     <th><%- i18n('str', 'name') %></th> | ||||
|     <th><%- i18n('str', 'email') %></th> | ||||
|     <th><%- i18n('str', 'roles') %></th> | ||||
|     <th> </th> | ||||
| </thead> | ||||
| <tbody> | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| <div class="card"> | ||||
|     <div class="card-header"> | ||||
|         <h3 class="card-title">Users</h3> | ||||
|         <h3 class="card-title"><%- i18n('users', 'title') %></h3> | ||||
|         <div class="card-options"> | ||||
|             <a href="#" class="btn btn-outline-teal btn-sm ml-2 add-user">Add User</a> | ||||
|             <a href="#" class="btn btn-outline-teal btn-sm ml-2 add-user"><%- i18n('users', 'add') %></a> | ||||
|         </div> | ||||
|     </div> | ||||
|     <div class="card-body no-padding min-100"> | ||||
|   | ||||
| @@ -1,12 +1,11 @@ | ||||
| 'use strict'; | ||||
|  | ||||
| const Mn        = require('backbone.marionette'); | ||||
| const App       = require('../main'); | ||||
| const UserModel = require('../../models/user'); | ||||
| const Api        = require('../api'); | ||||
| const Controller = require('../controller'); | ||||
| const ListView  = require('./list/main'); | ||||
| const template   = require('./main.ejs'); | ||||
| const ErrorView = require('../error/main'); | ||||
| const template  = require('./main.ejs'); | ||||
|  | ||||
| module.exports = Mn.View.extend({ | ||||
|     id:       'users', | ||||
| @@ -25,14 +24,14 @@ module.exports = Mn.View.extend({ | ||||
|     events: { | ||||
|         'click @ui.add': function (e) { | ||||
|             e.preventDefault(); | ||||
|             Controller.showUserForm(new UserModel.Model()); | ||||
|             App.Controller.showUserForm(new UserModel.Model()); | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     onRender: function () { | ||||
|         let view = this; | ||||
|  | ||||
|         Api.Users.getAll(['permissions']) | ||||
|         App.Api.Users.getAll(['permissions']) | ||||
|             .then(response => { | ||||
|                 if (!view.isDestroyed() && response && response.length) { | ||||
|                     view.showChildView('list_region', new ListView({ | ||||
| @@ -44,7 +43,9 @@ module.exports = Mn.View.extend({ | ||||
|                 view.showChildView('list_region', new ErrorView({ | ||||
|                     code:    err.code, | ||||
|                     message: err.message, | ||||
|                     retry:     function () { Controller.showUsers(); } | ||||
|                     retry:   function () { | ||||
|                         App.Controller.showUsers(); | ||||
|                     } | ||||
|                 })); | ||||
|  | ||||
|                 console.error(err); | ||||
|   | ||||
| @@ -1,27 +1,115 @@ | ||||
| { | ||||
|   "en": { | ||||
|     "str": { | ||||
|       "email-address": "Email address", | ||||
|       "password": "Password", | ||||
|       "sign-in": "Sign in", | ||||
|       "sign-out": "Sign out", | ||||
|       "try-again": "Try again", | ||||
|       "name": "Name", | ||||
|       "email": "Email", | ||||
|       "roles": "Roles", | ||||
|       "created-on": "Created: {date}", | ||||
|       "save": "Save", | ||||
|       "cancel": "Cancel", | ||||
|       "sure": "Yes I'm Sure", | ||||
|       "disabled": "Disabled", | ||||
|       "choose-file": "Choose file" | ||||
|     }, | ||||
|     "login": { | ||||
|       "title": "Login to your account" | ||||
|     }, | ||||
|     "main": { | ||||
|       "app": "Nginx Proxy Manager", | ||||
|       "version": "v{version}", | ||||
|       "welcome": "Welcome to Nginx Proxy Manager", | ||||
|       "logged-in": "You are logged in as {name}", | ||||
|       "unknown-error": "Error loading stuff. Please reload the app.", | ||||
|       "unknown-user": "Unknown User", | ||||
|       "sign-out": "Sign out", | ||||
|       "sign-in-as": "Sign back in as {name}" | ||||
|     }, | ||||
|     "user": { | ||||
|       "edit-details": "Edit Details", | ||||
|       "change-password": "Change Password" | ||||
|     }, | ||||
|     "roles": { | ||||
|       "title": "Roles", | ||||
|       "admin": "Administrator", | ||||
|       "user": "Apache Helicopter" | ||||
|     }, | ||||
|     "menu": { | ||||
|       "dashboard": "Dashboard", | ||||
|       "hosts": "Hosts" | ||||
|     }, | ||||
|     "footer": { | ||||
|       "fork-me": "Fork me on Github", | ||||
|       "copy": "© 2018 <a href=\"{url}\" target=\"_blank\">jc21.com</a>.", | ||||
|       "version": "v{version}", | ||||
|       "theme": "Theme by <a href=\"{url}\" target=\"_blank\">Tabler</a>" | ||||
|     }, | ||||
|     "dashboard": { | ||||
|       "title": "Hi {name}" | ||||
|     }, | ||||
|     "all-hosts": { | ||||
|       "empty-subtitle": "{manage, select, true{Why don't you create one?} other{And you don't have permission to create one.}}", | ||||
|       "details": "Details", | ||||
|       "ssl": "SSL", | ||||
|       "enable-ssl": "Enable SSL", | ||||
|       "force-ssl": "Force SSL", | ||||
|       "domain-names": "Domain Names", | ||||
|       "cert-provider": "Certificate Provider", | ||||
|       "other-ssl": "Other", | ||||
|       "letsencrypt": "Let's Encrypt", | ||||
|       "letsencrypt-email": "Email Address for Let's Encrypt", | ||||
|       "letsencrypt-agreee": "I Agree to the <a href=\"{url}\" target=\"_blank\">Let's Encrypt Terms of Service</a>", | ||||
|       "other-certificate": "Certificate", | ||||
|       "other-certificate-key": "Certificate Key" | ||||
|     }, | ||||
|     "proxy-hosts": { | ||||
|       "title": "Proxy Hosts", | ||||
|       "empty": "There are no Proxy Hosts", | ||||
|       "add": "Add Proxy Host", | ||||
|       "form-title": "{id, select, undefined{New} other{Edit}} Proxy Host", | ||||
|       "forward-ip": "Forward IP", | ||||
|       "forward-port": "Forward Port" | ||||
|     }, | ||||
|     "redirection-hosts": { | ||||
|       "title": "Redirection Hosts" | ||||
|     }, | ||||
|     "dead-hosts": { | ||||
|       "title": "404 Hosts" | ||||
|     }, | ||||
|     "streams": { | ||||
|       "title": "Streams" | ||||
|     }, | ||||
|     "access-lists": { | ||||
|       "title": "Access Lists" | ||||
|     }, | ||||
|     "users": { | ||||
|       "title": "Users", | ||||
|       "default_error": "Default email address must be changed", | ||||
|       "add": "Add User", | ||||
|       "nickname": "Nickname", | ||||
|       "full-name": "Full Name", | ||||
|       "edit-details": "Edit Details", | ||||
|       "change-password": "Change Password", | ||||
|       "edit-permissions": "Edit Permissions", | ||||
|       "sign-in-as": "Sign in as User", | ||||
|       "form-title": "{id, select, undefined{New} other{Edit}} User", | ||||
|       "delete": "Delete {name, select, undefined{User} other{{name}}}", | ||||
|       "delete-confirm": "Are you sure you want to delete <strong>{name}</strong>?", | ||||
|       "password-title": "Change Password{self, select, false{ for {name}} other{}}", | ||||
|       "current-password": "Current Password", | ||||
|       "new-password": "New Password", | ||||
|       "confirm-password": "Confirm Password", | ||||
|       "permissions-title": "Permissions for {name}", | ||||
|       "admin-perms": "This user is an Administrator and some items cannot be altered", | ||||
|       "perms-visibility": "Item Visibility", | ||||
|       "perms-visibility-user": "Created Items Only", | ||||
|       "perms-visibility-all": "All Items", | ||||
|       "perm-manage": "Manage", | ||||
|       "perm-view": "View Only", | ||||
|       "perm-hidden": "Hidden" | ||||
|     }, | ||||
|     "audit-log": { | ||||
|       "title": "Audit Log", | ||||
|       "empty": "There are no logs.", | ||||
|       "empty-subtitle": "As soon as you or another user changes something, history of those events will show up here." | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| 'use strict'; | ||||
|  | ||||
| const numeral = require('numeral'); | ||||
| const moment  = require('moment'); | ||||
|  | ||||
| module.exports = { | ||||
|  | ||||
| @@ -11,26 +10,5 @@ module.exports = { | ||||
|      */ | ||||
|     niceNumber: function (number) { | ||||
|         return numeral(number).format('0,0'); | ||||
|     }, | ||||
|  | ||||
|     /** | ||||
|      * @param   {String|Integer} date | ||||
|      * @returns {String} | ||||
|      */ | ||||
|     shortTime: function (date) { | ||||
|         let shorttime = ''; | ||||
|  | ||||
|         if (typeof date === 'number') { | ||||
|             shorttime = moment.unix(date).format('H:mm A'); | ||||
|         } else { | ||||
|             shorttime = moment(date).format('H:mm A'); | ||||
|     } | ||||
|  | ||||
|         return shorttime; | ||||
|     }, | ||||
|  | ||||
|     replaceSlackLinks: function (content) { | ||||
|         return content.replace(/<(http[^|>]+)\|([^>]+)>/gi, '<a href="$1" target="_blank">$2</a>'); | ||||
|     } | ||||
|  | ||||
| }; | ||||
|   | ||||
| @@ -3,7 +3,6 @@ | ||||
| const _      = require('underscore'); | ||||
| const Mn     = require('backbone.marionette'); | ||||
| const moment = require('moment'); | ||||
| const numeral = require('numeral'); | ||||
| const i18n   = require('../app/i18n'); | ||||
|  | ||||
| let render = Mn.Renderer.render; | ||||
| @@ -14,30 +13,6 @@ Mn.Renderer.render = function (template, data, view) { | ||||
|  | ||||
|     data.i18n = i18n; | ||||
|  | ||||
|     /** | ||||
|      * @param   {Integer} number | ||||
|      * @returns {String} | ||||
|      */ | ||||
|     data.niceNumber = function (number) { | ||||
|         return numeral(number).format('0,0'); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * @param   {Integer} seconds | ||||
|      * @returns {String} | ||||
|      */ | ||||
|     data.secondsToTime = function (seconds) { | ||||
|         let sec_num = parseInt(seconds, 10); | ||||
|         let minutes = Math.floor(sec_num / 60); | ||||
|         let sec     = sec_num - (minutes * 60); | ||||
|  | ||||
|         if (sec < 10) { | ||||
|             sec = '0' + sec; | ||||
|         } | ||||
|  | ||||
|         return minutes + ':' + sec; | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * @param   {String} date | ||||
|      * @returns {String} | ||||
| @@ -50,68 +25,6 @@ Mn.Renderer.render = function (template, data, view) { | ||||
|         return moment(date).format(format); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * @param   {String} date | ||||
|      * @returns {String} | ||||
|      */ | ||||
|     data.shortDate = function (date) { | ||||
|         let shortdate = data.formatDbDate(date, 'YYYY-MM-DD'); | ||||
|  | ||||
|         return moment().format('YYYY-MM-DD') === shortdate ? 'Today' : shortdate; | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * @param   {String} date | ||||
|      * @returns {String} | ||||
|      */ | ||||
|     data.shortTime = function (date) { | ||||
|         return data.formatDbDate(date, 'H:mm A'); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * @param   {String} string | ||||
|      * @returns {String} | ||||
|      */ | ||||
|     data.escape = function (string) { | ||||
|         let entityMap = { | ||||
|             '&':  '&', | ||||
|             '<':  '<', | ||||
|             '>':  '>', | ||||
|             '"':  '"', | ||||
|             '\'': ''', | ||||
|             '/':  '/' | ||||
|         }; | ||||
|  | ||||
|         return String(string).replace(/[&<>"'\/]/g, function (s) { | ||||
|             return entityMap[s]; | ||||
|         }); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * @param   {String} string | ||||
|      * @param   {Integer} length | ||||
|      * @returns {String} | ||||
|      */ | ||||
|     data.trim = function (string, length) { | ||||
|         if (string.length > length) { | ||||
|             let trimmedString = string.substr(0, length); | ||||
|             return trimmedString.substr(0, Math.min(trimmedString.length, trimmedString.lastIndexOf(' '))) + '...'; | ||||
|         } | ||||
|  | ||||
|         return string; | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * @param   {String} name | ||||
|      * @returns {String} | ||||
|      */ | ||||
|     data.niceVarName = function (name) { | ||||
|         return name.replace('_', ' ') | ||||
|             .replace(/^(.)|\s+(.)/g, function ($1) { | ||||
|                 return $1.toUpperCase(); | ||||
|             }); | ||||
|     }; | ||||
|  | ||||
|     return render.call(this, template, data, view); | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -3,23 +3,23 @@ | ||||
|         <div class="col col-login mx-auto"> | ||||
|             <form class="card" action="" method="post"> | ||||
|                 <div class="card-body p-6"> | ||||
|                     <div class="card-title">Login to your account</div> | ||||
|                     <div class="card-title"><%- i18n('login', 'title') %></div> | ||||
|                     <div class="form-group"> | ||||
|                         <label class="form-label">Email address</label> | ||||
|                         <input name="identity" type="email" class="form-control" placeholder="Enter email" required> | ||||
|                         <label class="form-label"><%- i18n('str', 'email-address') %></label> | ||||
|                         <input name="identity" type="email" class="form-control" placeholder="<%- i18n('str', 'email-address') %>" required> | ||||
|                     </div> | ||||
|                     <div class="form-group"> | ||||
|                         <label class="form-label">Password</label> | ||||
|                         <input name="secret" type="password" class="form-control" placeholder="Password" required> | ||||
|                         <label class="form-label"><%- i18n('str', 'password') %></label> | ||||
|                         <input name="secret" type="password" class="form-control" placeholder="<%- i18n('str', 'password') %>" required> | ||||
|                         <div class="invalid-feedback secret-error"></div> | ||||
|                     </div> | ||||
|                     <div class="form-footer"> | ||||
|                         <button type="submit" class="btn btn-teal btn-block">Sign in</button> | ||||
|                         <button type="submit" class="btn btn-teal btn-block"><%- i18n('str', 'sign-in') %></button> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </form> | ||||
|             <div class="text-center text-muted"> | ||||
|                 Nginx Proxy Manager v<%- getVersion() %> | ||||
|                 <%- i18n('main', 'app') %> <%- i18n('main', 'version', {version: getVersion()}) %> | ||||
|             </div> | ||||
|         </div> | ||||
|     </div> | ||||
|   | ||||
| @@ -4,6 +4,7 @@ const $        = require('jquery'); | ||||
| const Mn       = require('backbone.marionette'); | ||||
| const template = require('./login.ejs'); | ||||
| const Api      = require('../../app/api'); | ||||
| const i18n     = require('../../app/i18n'); | ||||
|  | ||||
| module.exports = Mn.View.extend({ | ||||
|     template:  template, | ||||
| @@ -35,6 +36,7 @@ module.exports = Mn.View.extend({ | ||||
|     }, | ||||
|  | ||||
|     templateContext: { | ||||
|         i18n:       i18n, | ||||
|         getVersion: function () { | ||||
|             return $('#login').data('version'); | ||||
|         } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user