mirror of
https://github.com/YunoHost/yunohost-admin.git
synced 2024-09-03 20:06:15 +02:00
Merge branch 'stretch-unstable' into new-diagnosis-interface
This commit is contained in:
commit
35ba9efce1
44 changed files with 1193 additions and 1778 deletions
|
@ -706,14 +706,17 @@ input[type='radio'].nice-radio {
|
||||||
#view-groups {
|
#view-groups {
|
||||||
.panel-heading a {
|
.panel-heading a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
&.group-delete {
|
}
|
||||||
|
.group-delete {
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 24px;
|
||||||
|
padding: 0;
|
||||||
float:right;
|
float:right;
|
||||||
color:lighten(@label-danger-bg, 20%);
|
color:lighten(@label-danger-bg, 20%);
|
||||||
:hover {
|
:hover {
|
||||||
color:@label-danger-bg;
|
color:@label-danger-bg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
.panel-body {
|
.panel-body {
|
||||||
h3 {
|
h3 {
|
||||||
margin-top:0;
|
margin-top:0;
|
||||||
|
@ -725,6 +728,10 @@ input[type='radio'].nice-radio {
|
||||||
.dropdown-menu {
|
.dropdown-menu {
|
||||||
max-height: 200px;
|
max-height: 200px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
|
button {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.label-removable {
|
.label-removable {
|
||||||
// The following match properties from regular btn's
|
// The following match properties from regular btn's
|
||||||
|
@ -743,15 +750,17 @@ input[type='radio'].nice-radio {
|
||||||
|
|
||||||
margin-right:7px; // Spacing between labels
|
margin-right:7px; // Spacing between labels
|
||||||
|
|
||||||
> a {
|
> button {
|
||||||
|
line-height: 12px;
|
||||||
margin-left:6px;
|
margin-left:6px;
|
||||||
|
padding: 0;
|
||||||
padding-left:6px;
|
padding-left:6px;
|
||||||
border-left: #ccc 1px solid;
|
border-left: #ccc 1px solid;
|
||||||
color:lighten(@label-info-bg,20);
|
color:lighten(@label-info-bg,20);
|
||||||
|
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
> a:hover {
|
> button:hover {
|
||||||
color:@label-info-bg;
|
color:@label-info-bg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -926,6 +935,12 @@ input[type='radio'].nice-radio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.notransition {
|
||||||
|
-webkit-transition: none !important;
|
||||||
|
-moz-transition: none !important;
|
||||||
|
-o-transition: none !important;
|
||||||
|
transition: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
/* Just to be able to override list-group-item with alert-success's background and border colors */
|
/* Just to be able to override list-group-item with alert-success's background and border colors */
|
||||||
.alert-success-yo {
|
.alert-success-yo {
|
||||||
|
|
|
@ -81,8 +81,8 @@
|
||||||
</header>
|
</header>
|
||||||
<div class="content"></div>
|
<div class="content"></div>
|
||||||
<footer>
|
<footer>
|
||||||
<button type="button" id="modal-cancel" data-action="cancel" data-y18n="cancel">Cancel</button>
|
<button type="button" id="modal-cancel" data-modal-action="cancel" data-y18n="cancel">Cancel</button>
|
||||||
<button type="button" id="modal-confirm" data-action="confirm" data-y18n="ok">OK</button>
|
<button type="button" id="modal-confirm" data-modal-action="confirm" data-y18n="ok">OK</button>
|
||||||
</footer>
|
</footer>
|
||||||
</div></div>
|
</div></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
// List installed apps
|
// List installed apps
|
||||||
app.get('#/apps', function (c) {
|
app.get('#/apps', function (c) {
|
||||||
c.api('/apps?installed', function(data) { // http://api.yunohost.org/#!/app/app_list_get_8
|
c.api('GET', '/apps?installed', {}, function(data) {
|
||||||
var apps = data['apps'];
|
var apps = data['apps'];
|
||||||
c.arraySortById(apps);
|
c.arraySortById(apps);
|
||||||
c.view('app/app_list', {apps: apps});
|
c.view('app/app_list', {apps: apps});
|
||||||
|
@ -109,8 +109,8 @@
|
||||||
|
|
||||||
// List available apps
|
// List available apps
|
||||||
app.get('#/apps/install', function (c) {
|
app.get('#/apps/install', function (c) {
|
||||||
c.api('/apps', function (data) { // http://api.yunohost.org/#!/app/app_list_get_8
|
c.api('GET', '/apps', {}, function (data) {
|
||||||
c.api('/apps?raw', function (dataraw) { // http://api.yunohost.org/#!/app/app_list_get_8
|
c.api('GET', '/apps?raw', {}, function (dataraw) {
|
||||||
var apps = []
|
var apps = []
|
||||||
$.each(data['apps'], function(k, v) {
|
$.each(data['apps'], function(k, v) {
|
||||||
app = dataraw[v['id']];
|
app = dataraw[v['id']];
|
||||||
|
@ -201,8 +201,8 @@
|
||||||
|
|
||||||
// Get app information
|
// Get app information
|
||||||
app.get('#/apps/:app', function (c) {
|
app.get('#/apps/:app', function (c) {
|
||||||
c.api('/apps/'+c.params['app']+'?raw', function(data) { // http://api.yunohost.org/#!/app/app_info_get_9
|
c.api('GET', '/apps/'+c.params['app']+'?raw', {}, function(data) {
|
||||||
c.api('/users/permissions', function(data_permissions) {
|
c.api('GET', '/users/permissions', {}, function(data_permissions) {
|
||||||
|
|
||||||
// Permissions
|
// Permissions
|
||||||
data.permissions = data_permissions.permissions[c.params['app']+".main"]["allowed"];
|
data.permissions = data_permissions.permissions[c.params['app']+".main"]["allowed"];
|
||||||
|
@ -217,21 +217,43 @@
|
||||||
data.manifest.multi_instance = data.manifest.multi_instance ? y18n.t('yes') : y18n.t('no');
|
data.manifest.multi_instance = data.manifest.multi_instance ? y18n.t('yes') : y18n.t('no');
|
||||||
data.install_time = new Date(data.settings.install_time * 1000);
|
data.install_time = new Date(data.settings.install_time * 1000);
|
||||||
|
|
||||||
c.view('app/app_info', data);
|
c.view('app/app_info', data, function() {
|
||||||
|
|
||||||
|
// Button to set the app as default
|
||||||
|
$('button[data-action="set-as-default"]').on("click", function() {
|
||||||
|
var app = $(this).data("app");
|
||||||
|
c.confirm(
|
||||||
|
y18n.t('applications'),
|
||||||
|
y18n.t('confirm_app_default'),
|
||||||
|
function() { c.api('PUT', '/apps/'+app+'/default', {}, function() { c.refresh() }); }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Button to uninstall the app
|
||||||
|
$('button[data-action="uninstall"]').on("click", function() {
|
||||||
|
var app = $(this).data("app");
|
||||||
|
c.confirm(
|
||||||
|
y18n.t('applications'),
|
||||||
|
y18n.t('confirm_uninstall', [app]),
|
||||||
|
function() {
|
||||||
|
c.api('DELETE', '/apps/'+ app, {}, function() {
|
||||||
|
c.redirect_to('#/apps');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get app debug page
|
//
|
||||||
app.get('#/apps/:app/debug', function (c) {
|
// App actions
|
||||||
c.api('/apps/'+c.params['app']+'/debug', function(data) {
|
//
|
||||||
c.view('app/app_debug', data);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Get app actions list
|
// Get app actions list
|
||||||
app.get('#/apps/:app/actions', function (c) {
|
app.get('#/apps/:app/actions', function (c) {
|
||||||
c.api('/apps/'+c.params['app']+'/actions', function(data) {
|
c.api('GET', '/apps/'+c.params['app']+'/actions', {}, function(data) {
|
||||||
$.each(data.actions, function(_, action) {
|
$.each(data.actions, function(_, action) {
|
||||||
formatYunoHostStyleArguments(action.arguments, c.params);
|
formatYunoHostStyleArguments(action.arguments, c.params);
|
||||||
|
|
||||||
|
@ -248,7 +270,7 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Perform application
|
// Perform app action
|
||||||
app.put('#/apps/:app/actions/:action', function(c) {
|
app.put('#/apps/:app/actions/:action', function(c) {
|
||||||
// taken from app install
|
// taken from app install
|
||||||
$.each(c.params, function(k, v) {
|
$.each(c.params, function(k, v) {
|
||||||
|
@ -267,14 +289,18 @@
|
||||||
'args': c.serialize(c.params.toHash())
|
'args': c.serialize(c.params.toHash())
|
||||||
}
|
}
|
||||||
|
|
||||||
c.api('/apps/'+app_id+'/actions/'+action_id, function() { // http://api.yunohost.org/#!/app/app_install_post_2
|
c.api('PUT', '/apps/'+app_id+'/actions/'+action_id, params, function() {
|
||||||
c.redirect('#/apps/'+app_id+'/actions');
|
c.redirect_to('#/apps/'+app_id+'/actions', {slide:false});
|
||||||
}, 'PUT', params);
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
// App config panel
|
||||||
|
//
|
||||||
|
|
||||||
// Get app config panel
|
// Get app config panel
|
||||||
app.get('#/apps/:app/config-panel', function (c) {
|
app.get('#/apps/:app/config-panel', function (c) {
|
||||||
c.api('/apps/'+c.params['app']+'/config-panel', function(data) {
|
c.api('GET', '/apps/'+c.params['app']+'/config-panel', {}, function(data) {
|
||||||
$.each(data.config_panel.panel, function(_, panel) {
|
$.each(data.config_panel.panel, function(_, panel) {
|
||||||
$.each(panel.sections, function(_, section) {
|
$.each(panel.sections, function(_, section) {
|
||||||
formatYunoHostStyleArguments(section.options, c.params);
|
formatYunoHostStyleArguments(section.options, c.params);
|
||||||
|
@ -300,16 +326,16 @@
|
||||||
'args': c.serialize(c.params.toHash())
|
'args': c.serialize(c.params.toHash())
|
||||||
}
|
}
|
||||||
|
|
||||||
c.api('/apps/'+app_id+'/config', function() { // http://api.yunohost.org/#!/app/app_install_post_2
|
c.api('POST', '/apps/'+app_id+'/config', params, function() {
|
||||||
c.redirect('#/apps/'+app_id+'/config-panel');
|
c.redirect_to('#/apps/'+app_id+'/config-panel', {slide:false});
|
||||||
}, 'POST', params);
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
// Special case for custom app installation.
|
// Special case for custom app installation.
|
||||||
app.get('#/apps/install/custom', function (c) {
|
app.get('#/apps/install/custom', function (c) {
|
||||||
// If we try to GET /apps/install/custom, it means that installation fail.
|
// If we try to GET /apps/install/custom, it means that installation fail.
|
||||||
// Need to redirect to apps/install to get rid of pacamn and see the log.
|
// Need to redirect to apps/install to get rid of pacamn and see the log.
|
||||||
c.redirect('#/apps/install');
|
c.redirect_to('#/apps/install');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Helper function that formats YunoHost style arguments for generating a form
|
// Helper function that formats YunoHost style arguments for generating a form
|
||||||
|
@ -480,7 +506,7 @@
|
||||||
|
|
||||||
// App installation form
|
// App installation form
|
||||||
app.get('#/apps/install/:app', function (c) {
|
app.get('#/apps/install/:app', function (c) {
|
||||||
c.api('/apps?raw', function(data) { // http://api.yunohost.org/#!/app/app_list_get_8
|
c.api('GET', '/apps?raw', {}, function(data) {
|
||||||
var app_name = c.params["app"];
|
var app_name = c.params["app"];
|
||||||
var app_infos = data[app_name];
|
var app_infos = data[app_name];
|
||||||
if (app_infos['state'] === "validated")
|
if (app_infos['state'] === "validated")
|
||||||
|
@ -502,10 +528,6 @@
|
||||||
app_infos.manifest,
|
app_infos.manifest,
|
||||||
c.params
|
c.params
|
||||||
);
|
);
|
||||||
},
|
|
||||||
function(){
|
|
||||||
$('div.loader').remove();
|
|
||||||
c.redirect('#/apps/install');
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -546,14 +568,13 @@
|
||||||
delete params['args'];
|
delete params['args'];
|
||||||
}
|
}
|
||||||
|
|
||||||
c.api('/apps', function() { // http://api.yunohost.org/#!/app/app_install_post_2
|
c.api('POST', '/apps', params, function() {
|
||||||
c.redirect('#/apps');
|
c.redirect_to('#/apps');
|
||||||
}, 'POST', params);
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
c.flash('warning', y18n.t('app_install_cancel'));
|
c.flash('warning', y18n.t('app_install_cancel'));
|
||||||
store.clear('slide');
|
c.refresh();
|
||||||
c.redirect('#/apps/install');
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -593,56 +614,15 @@
|
||||||
})
|
})
|
||||||
.fail(function(xhr) {
|
.fail(function(xhr) {
|
||||||
c.flash('fail', y18n.t('app_install_custom_no_manifest'));
|
c.flash('fail', y18n.t('app_install_custom_no_manifest'));
|
||||||
store.clear('slide');
|
c.refresh();
|
||||||
c.redirect('#/apps/install');
|
|
||||||
});
|
});
|
||||||
},
|
|
||||||
function(){
|
|
||||||
c.flash('warning', y18n.t('app_install_cancel'));
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/apps/install');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Remove installed app
|
|
||||||
app.get('#/apps/:app/uninstall', function (c) {
|
|
||||||
c.confirm(
|
|
||||||
y18n.t('applications'),
|
|
||||||
y18n.t('confirm_uninstall', [c.params['app']]),
|
|
||||||
function() {
|
|
||||||
c.api('/apps/'+ c.params['app'], function() { // http://api.yunohost.org/#!/app/app_remove_delete_4
|
|
||||||
c.redirect('#/apps');
|
|
||||||
}, 'DELETE');
|
|
||||||
},
|
|
||||||
function() {
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/apps/'+ c.params['app']);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Make app default
|
|
||||||
app.get('#/apps/:app/default', function (c) {
|
|
||||||
c.confirm(
|
|
||||||
y18n.t('applications'),
|
|
||||||
y18n.t('confirm_app_default'),
|
|
||||||
function() {
|
|
||||||
c.api('/apps/'+ c.params['app'] +'/default', function() { //
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/apps/'+ c.params['app']);
|
|
||||||
}, 'PUT');
|
|
||||||
},
|
|
||||||
function() {
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/apps/'+ c.params['app']);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get app change label page
|
// Get app change label page
|
||||||
app.get('#/apps/:app/changelabel', function (c) {
|
app.get('#/apps/:app/changelabel', function (c) {
|
||||||
c.api('/apps/'+c.params['app']+'?raw', function(app_data) {
|
c.api('GET', '/apps/'+c.params['app']+'?raw', {}, function(app_data) {
|
||||||
data = {
|
data = {
|
||||||
id: c.params['app'],
|
id: c.params['app'],
|
||||||
label: app_data.settings.label,
|
label: app_data.settings.label,
|
||||||
|
@ -654,16 +634,15 @@
|
||||||
// Change app label
|
// Change app label
|
||||||
app.post('#/apps/:app/changelabel', function (c) {
|
app.post('#/apps/:app/changelabel', function (c) {
|
||||||
params = {'new_label': c.params['label']};
|
params = {'new_label': c.params['label']};
|
||||||
c.api('/apps/' + c.params['app'] + '/label', function(data) { // Call changelabel API
|
c.api('PUT', '/apps/' + c.params['app'] + '/label', params, function(data) {
|
||||||
store.clear('slide');
|
c.redirect_to('#/apps/'+ c.params['app']);
|
||||||
c.redirect('#/apps/'+ c.params['app']);
|
});
|
||||||
}, 'PUT', params);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get app change URL page
|
// Get app change URL page
|
||||||
app.get('#/apps/:app/changeurl', function (c) {
|
app.get('#/apps/:app/changeurl', function (c) {
|
||||||
c.api('/apps/'+c.params['app']+'?raw', function(app_data) {
|
c.api('GET', '/apps/'+c.params['app']+'?raw', {}, function(app_data) {
|
||||||
c.api('/domains', function(domain_data) { // http://api.yunohost.org/#!/domain/domain_list_get_2
|
c.api('GET', '/domains', {}, function(domain_data) {
|
||||||
|
|
||||||
// Display a list of available domains
|
// Display a list of available domains
|
||||||
var domains = [];
|
var domains = [];
|
||||||
|
@ -695,14 +674,9 @@
|
||||||
y18n.t('confirm_app_change_url', [c.params['app']]),
|
y18n.t('confirm_app_change_url', [c.params['app']]),
|
||||||
function() {
|
function() {
|
||||||
params = {'domain': c.params['domain'], 'path': c.params['path']};
|
params = {'domain': c.params['domain'], 'path': c.params['path']};
|
||||||
c.api('/apps/' + c.params['app'] + '/changeurl', function(data) { // Call changeurl API
|
c.api('PUT', '/apps/' + c.params['app'] + '/changeurl', params, function(data) {
|
||||||
store.clear('slide');
|
c.redirect_to('#/apps/'+ c.params['app']);
|
||||||
c.redirect('#/apps/'+ c.params['app']);
|
});
|
||||||
}, 'PUT', params);
|
|
||||||
},
|
|
||||||
function() {
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/apps/'+ c.params['app'] + '/changeurl');
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
@ -32,118 +32,9 @@
|
||||||
c.view('backup/backup', {'storages':storages});
|
c.view('backup/backup', {'storages':storages});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Storage list
|
|
||||||
app.get('#/storages/create', function (c) {
|
|
||||||
c.view('backup/storage_create', {});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Create a storage
|
|
||||||
app.post('#/storages', function (c) {
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/storages');
|
|
||||||
});
|
|
||||||
|
|
||||||
// Create a backup
|
|
||||||
app.get('#/backup/:storage/create', function (c) {
|
|
||||||
var data = [];
|
|
||||||
data['storage'] = {
|
|
||||||
id:c.params['storage'],
|
|
||||||
name:y18n.t('local_archives')
|
|
||||||
};
|
|
||||||
c.api('/hooks/backup', function(hooks) {
|
|
||||||
data['hooks'] = c.groupHooks(hooks['hooks']);
|
|
||||||
data['apps'] = {};
|
|
||||||
c.api('/apps?with_backup', function(apps_list) {
|
|
||||||
data['apps'] = apps_list.apps;
|
|
||||||
c.view('backup/backup_create', data, c.selectAllOrNone);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
app.post('#/backup/:storage', function (c) {
|
|
||||||
var params = c.ungroupHooks(c.params['system_parts'],c.params['apps']);
|
|
||||||
c.api('/backup', function() {
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/backup/'+ c.params['storage']);
|
|
||||||
}, 'POST', params);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Restore a backup
|
|
||||||
app.post('#/backup/:storage/:archive/restore', function (c) {
|
|
||||||
c.confirm(
|
|
||||||
y18n.t('backup'),
|
|
||||||
y18n.t('confirm_restore', [c.params['archive']]),
|
|
||||||
$.proxy(function(c){
|
|
||||||
var params = c.ungroupHooks(c.params['system_parts'],c.params['apps']);
|
|
||||||
params['force'] = '';
|
|
||||||
c.api('/backup/restore/'+c.params['archive'], function(data) {
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/backup/'+ c.params['storage']+'/'+c.params['archive']);
|
|
||||||
}, 'POST', params);
|
|
||||||
}, this, c),
|
|
||||||
function(){
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/backup/'+ c.params['storage']+'/'+c.params['archive']);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Delete a backup
|
|
||||||
app.get('#/backup/:storage/:archive/delete', function (c) {
|
|
||||||
c.confirm(
|
|
||||||
y18n.t('backup'),
|
|
||||||
y18n.t('confirm_delete', [c.params['archive']]),
|
|
||||||
function(){
|
|
||||||
c.api('/backup/archives/'+c.params['archive'], function(data) {
|
|
||||||
c.redirect('#/backup/'+ c.params['storage']);
|
|
||||||
}, 'DELETE');
|
|
||||||
},
|
|
||||||
function(){
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/backup/'+ c.params['storage']+'/'+c.params['archive']);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Download a backup
|
|
||||||
app.get('#/backup/:storage/:archive/download', function (c) {
|
|
||||||
c.api('/backup/'+c.params['archive']+'/download', function(data) {
|
|
||||||
c.redirect('#/backup/'+ c.params['storage']+'/'+c.params['archive']);
|
|
||||||
}, 'GET');
|
|
||||||
});
|
|
||||||
|
|
||||||
// Copy a backup
|
|
||||||
app.get('#/backup/:storage/:archive/copy', function (c) {
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/backup/'+ c.params['storage']+'/'+c.params['archive']);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Upload a backup
|
|
||||||
app.get('#/backup/:storage/:archive/upload', function (c) {
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/backup/'+ c.params['storage']+'/'+c.params['archive']);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Get archive info
|
|
||||||
app.get('#/backup/:storage/:archive', function (c) {
|
|
||||||
c.api('/backup/archives/'+c.params['archive']+'?with_details', function(data) {
|
|
||||||
data.storage = {
|
|
||||||
id: c.params['storage'],
|
|
||||||
name: y18n.t('local_archives')
|
|
||||||
};
|
|
||||||
data.other_storages = [];
|
|
||||||
data.name = c.params['archive'];
|
|
||||||
data.system_parts = c.groupHooks(Object.keys(data['system']),data['system']);
|
|
||||||
data.items = (data['system']!={} || data['apps']!=[]);
|
|
||||||
data.locale = y18n.locale
|
|
||||||
c.view('backup/backup_info', data, c.selectAllOrNone);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Archive list
|
// Archive list
|
||||||
app.get('#/backup/:storage', function (c) {
|
app.get('#/backup/:storage', function (c) {
|
||||||
c.api('/backup/archives?with_info', function(data) {
|
c.api('GET', '/backup/archives?with_info', {}, function(data) {
|
||||||
data.storage = {
|
data.storage = {
|
||||||
id: 'local',
|
id: 'local',
|
||||||
name: y18n.t('local_archives')
|
name: y18n.t('local_archives')
|
||||||
|
@ -159,4 +50,173 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// View to create a backup
|
||||||
|
app.get('#/backup/:storage/create', function (c) {
|
||||||
|
var data = [];
|
||||||
|
data['storage'] = {
|
||||||
|
id:c.params['storage'],
|
||||||
|
name:y18n.t('local_archives')
|
||||||
|
};
|
||||||
|
c.api('GET', '/hooks/backup', {}, function(hooks) {
|
||||||
|
data['hooks'] = groupHooks(hooks['hooks']);
|
||||||
|
data['apps'] = {};
|
||||||
|
c.api('GET', '/apps?with_backup', {}, function(apps_list) {
|
||||||
|
data['apps'] = apps_list.apps;
|
||||||
|
c.view('backup/backup_create', data, function() {
|
||||||
|
|
||||||
|
// Configure buttons "select all" and "select none"
|
||||||
|
|
||||||
|
// Remove active style from buttons
|
||||||
|
$(".select_all-none input").click(function(){ $(this).toggleClass("active"); });
|
||||||
|
// Select all checkbox in this panel
|
||||||
|
$(".select_all").click(function(){
|
||||||
|
$(this).parents(".panel").children(".list-group").find("input").prop("checked", true);
|
||||||
|
});
|
||||||
|
// Deselect all checkbox in this panel
|
||||||
|
$(".select_none").click(function(){
|
||||||
|
$(this).parents(".panel").children(".list-group").find("input").prop("checked", false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Actually creating the backup
|
||||||
|
app.post('#/backup/:storage', function (c) {
|
||||||
|
var params = ungroupHooks(c.params['system_parts'],c.params['apps']);
|
||||||
|
c.api('POST', '/backup', params, function() {
|
||||||
|
c.redirect_to('#/backup/'+ c.params['storage']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get archive info
|
||||||
|
app.get('#/backup/:storage/:archive', function (c) {
|
||||||
|
c.api('GET', '/backup/archives/'+c.params['archive']+'?with_details', {}, function(data) {
|
||||||
|
data.storage = {
|
||||||
|
id: c.params['storage'],
|
||||||
|
name: y18n.t('local_archives')
|
||||||
|
};
|
||||||
|
data.name = c.params['archive'];
|
||||||
|
data.system_parts = groupHooks(Object.keys(data['system']),data['system']);
|
||||||
|
data.items = (data['system']!={} || data['apps']!=[]);
|
||||||
|
data.locale = y18n.locale;
|
||||||
|
c.view('backup/backup_info', data, function() {
|
||||||
|
|
||||||
|
// Configure buttons "select all" and "select none"
|
||||||
|
|
||||||
|
// Remove active style from buttons
|
||||||
|
$(".select_all-none input").click(function(){ $(this).toggleClass("active"); });
|
||||||
|
// Select all checkbox in this panel
|
||||||
|
$(".select_all").click(function(){
|
||||||
|
$(this).parents(".panel").children(".list-group").find("input").prop("checked", true);
|
||||||
|
});
|
||||||
|
// Deselect all checkbox in this panel
|
||||||
|
$(".select_none").click(function(){
|
||||||
|
$(this).parents(".panel").children(".list-group").find("input").prop("checked", false);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Delete button
|
||||||
|
$('button[data-action="delete"]').on('click', function() {
|
||||||
|
var storage = $(this).data('storage');
|
||||||
|
var archive = $(this).data('archive');
|
||||||
|
c.confirm(
|
||||||
|
y18n.t('backup'),
|
||||||
|
y18n.t('confirm_delete', [archive]),
|
||||||
|
function(){
|
||||||
|
c.api('DELETE', '/backup/archives/'+archive, {}, function(data) {
|
||||||
|
c.redirect_to('#/backup/'+ storage);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Restore a backup
|
||||||
|
app.post('#/backup/:storage/:archive/restore', function (c) {
|
||||||
|
c.confirm(
|
||||||
|
y18n.t('backup'),
|
||||||
|
y18n.t('confirm_restore', [c.params['archive']]),
|
||||||
|
$.proxy(function(c){
|
||||||
|
var params = ungroupHooks(c.params['system_parts'],c.params['apps']);
|
||||||
|
params['force'] = '';
|
||||||
|
c.api('POST', '/backup/restore/'+c.params['archive'], params, function(data) {
|
||||||
|
c.redirect_to('#/backup/'+ c.params['storage']+'/'+c.params['archive']);
|
||||||
|
});
|
||||||
|
}, this, c)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
function groupHooks(hooks, raw_infos) {
|
||||||
|
var data = {};
|
||||||
|
var rules = [
|
||||||
|
{
|
||||||
|
id:'configuration',
|
||||||
|
isIn:function (hook) {
|
||||||
|
return hook.indexOf('conf_')==0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
$.each(hooks, function(i, hook) {
|
||||||
|
var group_id=hook;
|
||||||
|
var hook_size=(raw_infos && raw_infos[hook] && raw_infos[hook].size)?raw_infos[hook].size:0;
|
||||||
|
$.each(rules, function(i, rule) {
|
||||||
|
if (rule.isIn(hook)) {
|
||||||
|
group_id = 'adminjs_group_'+rule.id;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(group_id in data) {
|
||||||
|
data[group_id] = {
|
||||||
|
name:y18n.t('hook_'+group_id),
|
||||||
|
value:data[group_id].value+','+hook,
|
||||||
|
description:data[group_id].description+', '+y18n.t('hook_'+hook),
|
||||||
|
size:data[group_id].size + hook_size
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
data[group_id] = {
|
||||||
|
name:y18n.t('hook_'+group_id),
|
||||||
|
value:hook,
|
||||||
|
description:(group_id==hook)?y18n.t('hook_'+hook+'_desc'):y18n.t('hook_'+hook),
|
||||||
|
size:hook_size
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
function ungroupHooks(system_parts, apps) {
|
||||||
|
|
||||||
|
var data = {};
|
||||||
|
data['apps'] = apps || [];
|
||||||
|
data['system'] = system_parts || [];
|
||||||
|
|
||||||
|
if (data['system'].constructor !== Array) {
|
||||||
|
data['system'] = [data['system']];
|
||||||
|
}
|
||||||
|
if (data['apps'].constructor !== Array) {
|
||||||
|
data['apps'] = [data['apps']];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some hook value contains multiple hooks separated by commas
|
||||||
|
var split_hooks = [];
|
||||||
|
$.each(data['system'], function(i, hook) {
|
||||||
|
split_hooks = split_hooks.concat(hook.split(','));
|
||||||
|
});
|
||||||
|
data['system'] = split_hooks;
|
||||||
|
|
||||||
|
if (data['system'].length == 0) {
|
||||||
|
delete data['system'];
|
||||||
|
}
|
||||||
|
if (data['apps'].length == 0) {
|
||||||
|
delete data['apps'];
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -10,8 +10,8 @@
|
||||||
|
|
||||||
// List existing domains
|
// List existing domains
|
||||||
app.get('#/domains', function (c) {
|
app.get('#/domains', function (c) {
|
||||||
c.api('/domains', function(data) { // http://api.yunohost.org/#!/domain/domain_list_get_2
|
c.api('GET', '/domains', {}, function(data) {
|
||||||
c.api('/domains/main', function(data2) {
|
c.api('PUT', '/domains/main', {}, function(data2) {
|
||||||
var domains = [];
|
var domains = [];
|
||||||
$.each(data.domains, function(k, domain) {
|
$.each(data.domains, function(k, domain) {
|
||||||
domains.push({
|
domains.push({
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
domains: domains,
|
domains: domains,
|
||||||
main_domain_form: main_domain_form
|
main_domain_form: main_domain_form
|
||||||
});
|
});
|
||||||
}, 'PUT');
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -68,8 +68,7 @@
|
||||||
if (c.params['domain'] === '') {
|
if (c.params['domain'] === '') {
|
||||||
if (c.params['ddomain'] === '') {
|
if (c.params['ddomain'] === '') {
|
||||||
c.flash('fail', y18n.t('error_select_domain'));
|
c.flash('fail', y18n.t('error_select_domain'));
|
||||||
store.clear('slide');
|
c.redirect_to('#/domains/add');
|
||||||
c.redirect('#/domains/add');
|
|
||||||
}
|
}
|
||||||
params.domain = c.params['ddomain'] + c.params['ddomain-ext'];
|
params.domain = c.params['ddomain'] + c.params['ddomain-ext'];
|
||||||
endurl = 'dyndns';
|
endurl = 'dyndns';
|
||||||
|
@ -77,42 +76,56 @@
|
||||||
params.domain = c.params['domain'];
|
params.domain = c.params['domain'];
|
||||||
}
|
}
|
||||||
|
|
||||||
c.api('/domains?'+endurl, function(data) { // http://api.yunohost.org/#!/domain/domain_add_post_1
|
c.api('POST', '/domains?'+endurl, params, function(data) {
|
||||||
c.redirect('#/domains');
|
c.redirect_to('#/domains');
|
||||||
}, 'POST', params);
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get existing domain info
|
// Get existing domain info
|
||||||
app.get('#/domains/:domain', function (c) {
|
app.get('#/domains/:domain', function (c) {
|
||||||
c.api('/domains/main', function(dataMain) {
|
c.api('PUT', '/domains/main', {}, function(dataMain) {
|
||||||
c.api('/apps?installed', function(data) { // http://api.yunohost.org/#!/app/app_list_get_8
|
c.api('GET', '/apps?installed', {}, function(data) {
|
||||||
|
|
||||||
// FIXME - This dirty trick (along with the previous API call
|
|
||||||
// for apps installed) should be removed once letsencrypt_ynh
|
|
||||||
// is not used by many people anymore. Probably around 07/2017
|
|
||||||
// or end of 2017...
|
|
||||||
var enable_cert_management_ = true;
|
|
||||||
$.each(data['apps'], function(k, v) {
|
|
||||||
if (v.id == "letsencrypt") {
|
|
||||||
enable_cert_management_ = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
var domain = {
|
var domain = {
|
||||||
name: c.params['domain'],
|
name: c.params['domain'],
|
||||||
main: (c.params['domain'] == dataMain.current_main_domain) ? true : false,
|
main: (c.params['domain'] == dataMain.current_main_domain) ? true : false,
|
||||||
url: "https://"+c.params['domain'],
|
url: "https://"+c.params['domain']
|
||||||
enable_cert_management: enable_cert_management_
|
|
||||||
};
|
};
|
||||||
c.view('domain/domain_info', domain);
|
c.view('domain/domain_info', domain, function() {
|
||||||
|
|
||||||
|
// Configure "set default" button
|
||||||
|
$('button[data-action="set_default"]').on("click", function() {
|
||||||
|
var domain = $(this).data("domain");
|
||||||
|
c.confirm(
|
||||||
|
y18n.t('domains'),
|
||||||
|
y18n.t('confirm_change_maindomain'),
|
||||||
|
function() {
|
||||||
|
c.api('PUT', '/domains/main', {new_main_domain: domain}, function() { c.refresh() });
|
||||||
|
}
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
// Configure delete button
|
||||||
|
$('button[data-action="delete"]').on("click", function() {
|
||||||
|
var domain = $(this).data("domain");
|
||||||
|
c.confirm(
|
||||||
|
y18n.t('domains'),
|
||||||
|
y18n.t('confirm_delete', [domain]),
|
||||||
|
function(){
|
||||||
|
c.api('DELETE', '/domains/'+ domain, {}, function(data) {
|
||||||
|
c.redirect_to('#/domains');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}, 'PUT');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Domain DNS
|
// Domain DNS
|
||||||
app.get('#/domains/:domain/dns', function (c) {
|
app.get('#/domains/:domain/dns', function (c) {
|
||||||
c.api('/domains/' + c.params['domain'] + '/dns', function(data) {
|
c.api('GET', '/domains/' + c.params['domain'] + '/dns', {}, function(data) {
|
||||||
var domain = {
|
var domain = {
|
||||||
name: c.params['domain'],
|
name: c.params['domain'],
|
||||||
dns: data
|
dns: data
|
||||||
|
@ -123,7 +136,7 @@
|
||||||
|
|
||||||
// Domain certificate
|
// Domain certificate
|
||||||
app.get('#/domains/:domain/cert-management', function (c) {
|
app.get('#/domains/:domain/cert-management', function (c) {
|
||||||
c.api('/domains/cert-status/' + c.params['domain'] + '?full', function(data) {
|
c.api('GET', '/domains/cert-status/' + c.params['domain'] + '?full', {}, function(data) {
|
||||||
|
|
||||||
var s = data["certificates"][c.params['domain']];
|
var s = data["certificates"][c.params['domain']];
|
||||||
var status_ = {
|
var status_ = {
|
||||||
|
@ -199,132 +212,45 @@
|
||||||
status: status_,
|
status: status_,
|
||||||
actions_enabled : actions_enabled
|
actions_enabled : actions_enabled
|
||||||
};
|
};
|
||||||
c.view('domain/domain_cert', data_);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Install let's encrypt certificate on domain
|
c.view('domain/domain_cert', data_, function() {
|
||||||
app.get('#/domains/:domain/cert-install-LE', function (c) {
|
// Configure install / renew buttons behavior
|
||||||
|
$("button[data-action]").on("click", function () {
|
||||||
|
var action = $(this).data("action"),
|
||||||
|
domain = $(this).data("domain"),
|
||||||
|
confirm_key = "",
|
||||||
|
api_url = "";
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case 'install-LE':
|
||||||
|
confirm_key = 'confirm_cert_install_LE';
|
||||||
|
api_url = '/domains/cert-install/' + domain;
|
||||||
|
break;
|
||||||
|
case 'regen-selfsigned':
|
||||||
|
confirm_key = 'confirm_cert_regen_selfsigned';
|
||||||
|
api_url = '/domains/cert-install/' + domain + "?self_signed";
|
||||||
|
break;
|
||||||
|
case 'renew-letsencrypt':
|
||||||
|
confirm_key = 'confirm_cert_manual_renew_LE';
|
||||||
|
api_url = '/domains/cert-renew/' + domain + "?force";
|
||||||
|
break;
|
||||||
|
case 'replace-with-selfsigned':
|
||||||
|
confirm_key = 'confirm_cert_revert_to_selfsigned';
|
||||||
|
api_url = '/domains/cert-install/' + domain + "?self_signed&force";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
c.flash('fail', y18n.t('unknown_action', [action]));
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
c.confirm(
|
c.confirm(
|
||||||
y18n.t('certificate'),
|
y18n.t('certificate'),
|
||||||
y18n.t('confirm_cert_install_LE', [c.params['domain']]),
|
y18n.t(confirm_key, [domain]),
|
||||||
function(){
|
function(){ c.api('POST', api_url, {}, function() { c.refresh() }); }
|
||||||
c.api('/domains/cert-install/' + c.params['domain'], function(data) {
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/domains/'+c.params['domain']+'/cert-management');
|
|
||||||
}, 'POST');
|
|
||||||
},
|
|
||||||
function(){
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/domains/'+c.params['domain']+'/cert-management');
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Regenerate a self-signed certificate
|
|
||||||
app.get('#/domains/:domain/cert-regen-selfsigned', function (c) {
|
|
||||||
c.confirm(
|
|
||||||
y18n.t('certificate'),
|
|
||||||
y18n.t('confirm_cert_regen_selfsigned', [c.params['domain']]),
|
|
||||||
function(){
|
|
||||||
c.api('/domains/cert-install/' + c.params['domain'] + "?self_signed", function(data) {
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/domains/'+c.params['domain']+'/cert-management');
|
|
||||||
}, 'POST');
|
|
||||||
},
|
|
||||||
function(){
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/domains/'+c.params['domain']+'/cert-management');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Manually renew a Let's Encrypt certificate
|
|
||||||
app.get('#/domains/:domain/cert-renew-letsencrypt', function (c) {
|
|
||||||
c.confirm(
|
|
||||||
y18n.t('certificate'),
|
|
||||||
y18n.t('confirm_cert_manual_renew_LE', [c.params['domain']]),
|
|
||||||
function(){
|
|
||||||
c.api('/domains/cert-renew/' + c.params['domain'] + "?force", function(data) {
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/domains/'+c.params['domain']+'/cert-management');
|
|
||||||
}, 'POST');
|
|
||||||
},
|
|
||||||
function(){
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/domains/'+c.params['domain']+'/cert-management');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Replace valid cert with self-signed
|
|
||||||
app.get('#/domains/:domain/cert-replace-with-selfsigned', function (c) {
|
|
||||||
c.confirm(
|
|
||||||
y18n.t('certificate'),
|
|
||||||
y18n.t('confirm_cert_revert_to_selfsigned', [c.params['domain']]),
|
|
||||||
function(){
|
|
||||||
c.api('/domains/cert-install/' + c.params['domain'] + "?self_signed&force", function(data) {
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/domains/'+c.params['domain']+'/cert-management');
|
|
||||||
}, 'POST');
|
|
||||||
},
|
|
||||||
function(){
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/domains/'+c.params['domain']+'/cert-management');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// Remove existing domain
|
|
||||||
app.get('#/domains/:domain/delete', function (c) {
|
|
||||||
c.confirm(
|
|
||||||
y18n.t('domains'),
|
|
||||||
y18n.t('confirm_delete', [c.params['domain']]),
|
|
||||||
function(){
|
|
||||||
c.api('/domains/'+ c.params['domain'], function(data) { // http://api.yunohost.org/#!/domain/domain_remove_delete_3
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/domains');
|
|
||||||
}, 'DELETE');
|
|
||||||
},
|
|
||||||
function(){
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/domains');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Set default domain
|
|
||||||
app.post('#/domains', function (c) {
|
|
||||||
if (c.params['domain'] === '') {
|
|
||||||
c.flash('fail', y18n.t('error_select_domain'));
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/domains');
|
|
||||||
} else {
|
|
||||||
c.confirm(
|
|
||||||
y18n.t('domains'),
|
|
||||||
y18n.t('confirm_change_maindomain'),
|
|
||||||
function(){
|
|
||||||
var params = {
|
|
||||||
new_domain: c.params['domain']
|
|
||||||
};
|
|
||||||
c.api('/domains/main', function(data) { // http://api.yunohost.org/#!/tools/tools_maindomain_put_1
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/domains');
|
|
||||||
}, 'PUT', params);
|
|
||||||
|
|
||||||
// Wait 15s and refresh the page
|
|
||||||
var refreshDomain = window.setTimeout(function(){
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/domains');
|
|
||||||
}, 15000);
|
|
||||||
},
|
|
||||||
function(){
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/domains');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
// Firewall status
|
// Firewall status
|
||||||
app.get('#/tools/firewall', function (c) {
|
app.get('#/tools/firewall', function (c) {
|
||||||
c.api('/firewall?raw', function(data) {
|
c.api('GET', '/firewall?raw', {}, function(data) {
|
||||||
var firewall = {
|
var firewall = {
|
||||||
ports: {},
|
ports: {},
|
||||||
upnp: false
|
upnp: false
|
||||||
|
@ -30,28 +30,49 @@
|
||||||
// Get UPnP status
|
// Get UPnP status
|
||||||
firewall.upnp = data.uPnP.enabled;
|
firewall.upnp = data.uPnP.enabled;
|
||||||
|
|
||||||
c.view('tools/tools_firewall', firewall);
|
c.view('tools/tools_firewall', firewall, function() {
|
||||||
});
|
|
||||||
|
// Buttons in the 'ports' panel to open/close specific ports
|
||||||
|
$("button[data-port]").on("click", function() {
|
||||||
|
|
||||||
|
var port = $(this).data("port");
|
||||||
|
var action = $(this).data("action");
|
||||||
|
var protocol = $(this).data("protocol");
|
||||||
|
var connection = $(this).data("connection");
|
||||||
|
c.confirm(
|
||||||
|
y18n.t('firewall'),
|
||||||
|
// confirm_firewall_open and confirm_firewall_close
|
||||||
|
y18n.t('confirm_firewall_' + action, [ port, y18n.t(protocol), y18n.t(connection)]),
|
||||||
|
function(){ c.togglePort(port, protocol, connection, action); }
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Enable/Disable UPnP
|
// Buttons to enable / disable UPnP
|
||||||
app.get('#/tools/firewall/upnp/:action', function (c) {
|
$("button[data-upnp]").on("click", function() {
|
||||||
|
var action = $(this).data("upnp");
|
||||||
c.confirm(
|
c.confirm(
|
||||||
y18n.t('firewall'),
|
y18n.t('firewall'),
|
||||||
// confirm_upnp_enable and confirm_upnp_disable
|
// confirm_upnp_enable and confirm_upnp_disable
|
||||||
y18n.t('confirm_upnp_' + c.params['action'].toLowerCase()),
|
y18n.t('confirm_upnp_' + action),
|
||||||
|
function(){ c.api('GET', '/firewall/upnp', {action: action}, function() { c.refresh() }); }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update port status from form
|
||||||
|
app.post('#/tools/firewall/port', function (c) {
|
||||||
|
c.confirm(
|
||||||
|
y18n.t('firewall'),
|
||||||
|
y18n.t('confirm_firewall_' + c.params['action'].toLowerCase(), [ c.params['port'], y18n.t(c.params['protocol']), y18n.t(c.params['connection']) ]),
|
||||||
function(){
|
function(){
|
||||||
var params = {
|
c.togglePort(
|
||||||
action : c.params['action']
|
c.params['port'],
|
||||||
};
|
c.params['protocol'],
|
||||||
c.api('/firewall/upnp', function(data) {
|
c.params['connection'],
|
||||||
store.clear('slide');
|
c.params['action']
|
||||||
c.redirect('#/tools/firewall');
|
);
|
||||||
}, 'GET', params);
|
|
||||||
},
|
|
||||||
function(){
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/tools/firewall');
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -65,8 +86,7 @@
|
||||||
|
|
||||||
if (port != parseInt(port) || port < 0 || port > 65535) {
|
if (port != parseInt(port) || port < 0 || port > 65535) {
|
||||||
c.flash('fail', y18n.t('unknown_argument', [port]));
|
c.flash('fail', y18n.t('unknown_argument', [port]));
|
||||||
store.clear('slide');
|
c.refresh();
|
||||||
c.redirect('#/tools/firewall');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (connection) {
|
switch (connection) {
|
||||||
|
@ -98,11 +118,9 @@
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
c.flash('fail', y18n.t('unknown_action', [action]));
|
c.flash('fail', y18n.t('unknown_action', [action]));
|
||||||
store.clear('slide');
|
c.refresh();
|
||||||
c.redirect('#/tools/firewall');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (method !== null && protocol !== null && port !== null) {
|
|
||||||
// port:
|
// port:
|
||||||
// protocol:
|
// protocol:
|
||||||
// - UDP
|
// - UDP
|
||||||
|
@ -115,58 +133,12 @@
|
||||||
port : port,
|
port : port,
|
||||||
protocol : protocol
|
protocol : protocol
|
||||||
};
|
};
|
||||||
c.api('/firewall/port?'+endurl, function(data) {
|
|
||||||
store.clear('slide');
|
c.api(method, '/firewall/port?'+endurl, params, function() { c.refresh() });
|
||||||
c.redirect('#/tools/firewall');
|
|
||||||
}, method, params);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/tools/firewall');
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update port status from direct link
|
|
||||||
// #/firewall/port/{{@key}}/tcp/ipv4/close
|
|
||||||
app.get('#/tools/firewall/port/:port/:protocol/:connection/:action', function (c) {
|
|
||||||
c.confirm(
|
|
||||||
y18n.t('firewall'),
|
|
||||||
// confirm_firewall_open and confirm_firewall_close
|
|
||||||
y18n.t( 'confirm_firewall_' + c.params['action'].toLowerCase(), [ c.params['port'], y18n.t(c.params['protocol']), y18n.t(c.params['connection'])]),
|
|
||||||
function(){
|
|
||||||
c.togglePort(
|
|
||||||
c.params['port'],
|
|
||||||
c.params['protocol'],
|
|
||||||
c.params['connection'],
|
|
||||||
c.params['action']
|
|
||||||
);
|
|
||||||
},
|
|
||||||
function(){
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/tools/firewall');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update port status from form
|
|
||||||
app.post('#/tools/firewall/port', function (c) {
|
|
||||||
c.confirm(
|
|
||||||
y18n.t('firewall'),
|
|
||||||
y18n.t('confirm_firewall_' + c.params['action'].toLowerCase(), [ c.params['port'], y18n.t(c.params['protocol']), y18n.t(c.params['connection']) ]),
|
|
||||||
function(){
|
|
||||||
c.togglePort(
|
|
||||||
c.params['port'],
|
|
||||||
c.params['protocol'],
|
|
||||||
c.params['connection'],
|
|
||||||
c.params['action']
|
|
||||||
);
|
|
||||||
},
|
|
||||||
function(){
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/tools/firewall');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
})();
|
})();
|
|
@ -24,45 +24,36 @@
|
||||||
$('#masthead').show()
|
$('#masthead').show()
|
||||||
.find('.logout-btn').hide();
|
.find('.logout-btn').hide();
|
||||||
store.set('path-1', '#/login');
|
store.set('path-1', '#/login');
|
||||||
if ($('div.loader').length === 0) {
|
|
||||||
$('#main').append('<div class="loader loader-content"></div>');
|
c.showLoader();
|
||||||
|
|
||||||
|
// We gonna retry 3 times to check if yunohost is installed
|
||||||
|
if (app.isInstalledTry === undefined) {
|
||||||
|
app.isInstalledTry = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
c.checkInstall(function(isInstalled) {
|
c.checkInstall(function(isInstalled) {
|
||||||
|
|
||||||
if (isInstalled) {
|
if (isInstalled) {
|
||||||
// Remove loader
|
|
||||||
$('div.loader').remove();
|
|
||||||
// Pass domain to hide form field
|
|
||||||
c.view('login', { 'domain': window.location.hostname });
|
c.view('login', { 'domain': window.location.hostname });
|
||||||
} else if (typeof isInstalled === 'undefined') {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof isInstalled !== 'undefined') {
|
||||||
|
c.redirect('#/postinstall');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the retry counter is still up, retry this function 5 sec
|
||||||
|
// later
|
||||||
if (app.isInstalledTry > 0) {
|
if (app.isInstalledTry > 0) {
|
||||||
app.isInstalledTry--;
|
app.isInstalledTry--;
|
||||||
app.loaded = false; // Show pacman
|
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
c.redirect('#/');
|
c.redirect('#/');
|
||||||
}, 5000);
|
}, 5000);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Reset count
|
c.flash('fail', y18n.t('api_not_responding'));
|
||||||
app.isInstalledTry = 3;
|
|
||||||
|
|
||||||
// API is not responding after 3 try
|
|
||||||
$( document ).ajaxError(function( event, request, settings ) {
|
|
||||||
// Display error if status != 200.
|
|
||||||
// .ajaxError fire even with status code 200 because json is sometimes not valid.
|
|
||||||
if (request.status !== 200) c.flash('fail', y18n.t('api_not_responding', [request.status+' '+request.statusText] ));
|
|
||||||
|
|
||||||
// Unbind directly
|
|
||||||
$(document).off('ajaxError');
|
|
||||||
});
|
|
||||||
|
|
||||||
// Remove pacman
|
|
||||||
app.loaded = true;
|
|
||||||
$('div.loader').remove();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$('div.loader').remove();
|
|
||||||
c.redirect('#/postinstall');
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -80,7 +71,7 @@
|
||||||
var params = {
|
var params = {
|
||||||
password: c.params['password']
|
password: c.params['password']
|
||||||
};
|
};
|
||||||
c.api('/login', function(data) {
|
c.api('POST', '/login', params, function(data) {
|
||||||
store.set('connected', true);
|
store.set('connected', true);
|
||||||
c.trigger('login');
|
c.trigger('login');
|
||||||
$('#masthead .logout-btn').fadeIn();
|
$('#masthead .logout-btn').fadeIn();
|
||||||
|
@ -90,19 +81,19 @@
|
||||||
} else {
|
} else {
|
||||||
c.redirect('#/');
|
c.redirect('#/');
|
||||||
}
|
}
|
||||||
}, 'POST', params, false);
|
}, undefined, false);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('#/logout', function (c) {
|
app.get('#/logout', function (c) {
|
||||||
c.api('/logout', function (data) {
|
c.api('GET', '/logout', {}, function (data) {
|
||||||
store.clear('url');
|
store.clear('url');
|
||||||
store.clear('connected');
|
store.clear('connected');
|
||||||
store.set('path', '#/');
|
store.set('path', '#/');
|
||||||
c.trigger('logout');
|
c.trigger('logout');
|
||||||
c.flash('success', y18n.t('logged_out'));
|
c.flash('success', y18n.t('logged_out'));
|
||||||
c.redirect('#/login');
|
c.redirect('#/login');
|
||||||
}, 'GET', {}, false);
|
}, undefined, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
(function() {
|
|
||||||
// Get application context
|
|
||||||
var app = Sammy.apps['#main'];
|
|
||||||
var store = app.store;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Monitor
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Server monitoring
|
|
||||||
app.get('#/tools/monitor', function (c) {
|
|
||||||
var monitorData = {};
|
|
||||||
|
|
||||||
// Why this method ?
|
|
||||||
c.api('/services/glances', function(data) { // ?
|
|
||||||
monitorData.status = true;
|
|
||||||
|
|
||||||
if (data.status == 'running') {
|
|
||||||
c.api('/monitor/system', function(data) {
|
|
||||||
monitorData.system = data;
|
|
||||||
|
|
||||||
c.api('/monitor/disk', function(data) {
|
|
||||||
monitorData.disk = data;
|
|
||||||
|
|
||||||
c.api('/monitor/network', function(data) {
|
|
||||||
monitorData.network = data;
|
|
||||||
|
|
||||||
// Remove useless interface
|
|
||||||
delete monitorData.network.usage.lo;
|
|
||||||
|
|
||||||
// Get YunoHost versions too
|
|
||||||
c.api('/diagnosis', function(diagnosis) {
|
|
||||||
monitorData.versions = diagnosis.packages;
|
|
||||||
c.view('tools/tools_monitoring', monitorData);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
monitorData.status = false;
|
|
||||||
c.view('tools/tools_monitoring', monitorData);
|
|
||||||
}
|
|
||||||
|
|
||||||
}, 'GET');
|
|
||||||
});
|
|
||||||
|
|
||||||
})();
|
|
|
@ -13,7 +13,7 @@
|
||||||
$('#masthead').hide();
|
$('#masthead').hide();
|
||||||
c.checkInstall(function(isInstalled) {
|
c.checkInstall(function(isInstalled) {
|
||||||
if (isInstalled || typeof isInstalled === 'undefined') {
|
if (isInstalled || typeof isInstalled === 'undefined') {
|
||||||
c.redirect('#/login');
|
c.redirect_to('#/login');
|
||||||
} else {
|
} else {
|
||||||
c.view('postinstall/postinstall_1');
|
c.view('postinstall/postinstall_1');
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,6 @@
|
||||||
if ($('#domain').val() === '') {
|
if ($('#domain').val() === '') {
|
||||||
if ($('#ddomain').val() === '') {
|
if ($('#ddomain').val() === '') {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
store.clear('slide');
|
|
||||||
c.flash('fail', y18n.t('error_select_domain'));
|
c.flash('fail', y18n.t('error_select_domain'));
|
||||||
} else {
|
} else {
|
||||||
domain = $('#ddomain').val() + $('select[name="ddomain-ext"]').val();
|
domain = $('#ddomain').val() + $('select[name="ddomain-ext"]').val();
|
||||||
|
@ -51,7 +50,7 @@
|
||||||
}
|
}
|
||||||
store.set('maindomain', domain);
|
store.set('maindomain', domain);
|
||||||
});
|
});
|
||||||
}, false); // We disable enableSlide because that causes some issues with accordion when using the 'previous' button
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -59,49 +58,52 @@
|
||||||
app.get('#/postinstall/password', function(c) {
|
app.get('#/postinstall/password', function(c) {
|
||||||
$('#masthead').hide();
|
$('#masthead').hide();
|
||||||
if (!store.get('maindomain')) {
|
if (!store.get('maindomain')) {
|
||||||
store.clear('slide');
|
c.redirect_to('#/postinstall/domain');
|
||||||
c.redirect('#/postinstall/domain');
|
|
||||||
} else {
|
} else {
|
||||||
c.view('postinstall/postinstall_3', { 'domain': store.get('maindomain').toLowerCase() },
|
c.view('postinstall/postinstall_3', { 'domain': store.get('maindomain').toLowerCase() });
|
||||||
function() { },
|
|
||||||
false); // We disable enableSlide because that causes some issues with accordion when using the 'previous' button
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Execute post-installation
|
// Execute post-installation
|
||||||
app.post('#/postinstall', function (c) {
|
app.post('#/postinstall', function (c) {
|
||||||
if (c.params['password'] === '' || c.params['confirmation'] === '') {
|
|
||||||
|
var password = c.params['password'];
|
||||||
|
var confirmation = c.params['confirmation'];
|
||||||
|
var domain = c.params['domain'].toLowerCase();
|
||||||
|
|
||||||
|
// Check password ain't empty
|
||||||
|
if (password === '' || confirmation === '') {
|
||||||
c.flash('fail', y18n.t('password_empty'));
|
c.flash('fail', y18n.t('password_empty'));
|
||||||
}
|
return;
|
||||||
else if (c.params['password'] == c.params['confirmation']) {
|
|
||||||
if (c.params['domain'] === '') {
|
|
||||||
c.flash('fail', y18n.t('error_select_domain'));
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/postinstall/domain');
|
|
||||||
} else {
|
|
||||||
var params = {
|
|
||||||
domain: c.params['domain'].toLowerCase()
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check password matches confirmation
|
||||||
|
if (password !== confirmation) {
|
||||||
|
c.flash('fail', y18n.t('passwords_dont_match'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check domain ain't empty...
|
||||||
|
if (domain === '') {
|
||||||
|
c.flash('fail', y18n.t('error_select_domain'));
|
||||||
|
c.redirect_to('#/postinstall/domain', {slide: false});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ask confirmation to the user
|
||||||
c.confirm(
|
c.confirm(
|
||||||
y18n.t('postinstall'),
|
y18n.t('postinstall'),
|
||||||
y18n.t('confirm_postinstall', [c.params['domain']]),
|
y18n.t('confirm_postinstall', [c.params['domain']]),
|
||||||
|
// Start the actual postinstall process
|
||||||
function(){
|
function(){
|
||||||
params.password = c.params['password'];
|
|
||||||
|
|
||||||
store.set('url', window.location.hostname +'/yunohost/api');
|
store.set('url', window.location.hostname +'/yunohost/api');
|
||||||
store.set('user', 'admin');
|
store.set('user', 'admin');
|
||||||
c.api('/postinstall', function(data) { // http://api.yunohost.org/#!/tools/tools_postinstall_post_0
|
c.api('POST', '/postinstall', {domain: domain, password: password}, function() {
|
||||||
c.redirect('#/login');
|
c.flash('success', y18n.t('installation_complete'));
|
||||||
}, 'POST', params);
|
c.redirect_to('#/login');
|
||||||
},
|
});
|
||||||
function(){
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else {
|
|
||||||
c.flash('fail', y18n.t('passwords_dont_match'));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
// All services status
|
// All services status
|
||||||
app.get('#/services', function (c) {
|
app.get('#/services', function (c) {
|
||||||
c.api('/services', function(data) { // ?
|
c.api('GET', '/services', {}, function(data) {
|
||||||
var data2 = {
|
var data2 = {
|
||||||
services: []
|
services: []
|
||||||
};
|
};
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
|
|
||||||
// Status & actions for a service
|
// Status & actions for a service
|
||||||
app.get('#/services/:service', function (c) {
|
app.get('#/services/:service', function (c) {
|
||||||
c.api('/services/'+ c.params['service'], function(data) { // ?
|
c.api('GET', '/services/'+ c.params['service'], {}, function(data) {
|
||||||
var data2 = {
|
var data2 = {
|
||||||
service: data
|
service: data
|
||||||
};
|
};
|
||||||
|
@ -64,37 +64,20 @@
|
||||||
{
|
{
|
||||||
data2.service.active_at = 0;
|
data2.service.active_at = 0;
|
||||||
}
|
}
|
||||||
store.clear('slide');
|
c.view('service/service_info', data2, function() {
|
||||||
c.view('service/service_info', data2);
|
|
||||||
}, 'GET');
|
|
||||||
});
|
|
||||||
|
|
||||||
// Service log
|
// Configure behavior for enable/disable and start/stop buttons
|
||||||
app.get('#/services/:service/log', function (c) {
|
$('button[data-action]').on('click', function() {
|
||||||
var params = {
|
|
||||||
number: 50
|
|
||||||
};
|
|
||||||
c.api('/services/'+ c.params['service'] +'/log', function(data) { // ?
|
|
||||||
data2 = { 'logs': [], 'name': c.params['service'] };
|
|
||||||
$.each(data, function(k, v) {
|
|
||||||
data2.logs.push({filename: k, filecontent: v.join('\n')});
|
|
||||||
});
|
|
||||||
|
|
||||||
c.view('service/service_log', data2);
|
var service = $(this).data('service');
|
||||||
}, 'GET', params);
|
var action = $(this).data('action');
|
||||||
});
|
|
||||||
|
c.confirm("Service", y18n.t('confirm_service_' + action, [service]), function(){
|
||||||
|
|
||||||
// Enable/Disable & Start/Stop service
|
|
||||||
app.get('#/services/:service/:action', function (c) {
|
|
||||||
c.confirm(
|
|
||||||
"Service",
|
|
||||||
// confirm_service_start, confirm_service_stop, confirm_service_enable and confirm_service_disable
|
|
||||||
y18n.t('confirm_service_' + c.params['action'].toLowerCase(), [c.params['service']]),
|
|
||||||
function(){
|
|
||||||
var method = null,
|
var method = null,
|
||||||
endurl = c.params['service'];
|
endurl = service;
|
||||||
|
|
||||||
switch (c.params['action']) {
|
switch (action) {
|
||||||
case 'start':
|
case 'start':
|
||||||
method = 'PUT';
|
method = 'PUT';
|
||||||
break;
|
break;
|
||||||
|
@ -110,27 +93,31 @@
|
||||||
endurl += '/enable';
|
endurl += '/enable';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
c.flash('fail', y18n.t('unknown_action', [c.params['action']]));
|
c.flash('fail', y18n.t('unknown_action', [action]));
|
||||||
store.clear('slide');
|
c.refresh();
|
||||||
c.redirect('#/services/'+ c.params['service']);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (method && endurl) {
|
c.api(method, '/services/'+ endurl, {}, function() { c.refresh(); });
|
||||||
c.api('/services/'+ endurl, function(data) {
|
});
|
||||||
store.clear('slide');
|
});
|
||||||
c.redirect('#/services/'+ c.params['service']);
|
});
|
||||||
}, method);
|
});
|
||||||
}
|
});
|
||||||
else {
|
|
||||||
store.clear('slide');
|
// Service log
|
||||||
c.redirect('#/services/'+ c.params['service']);
|
app.get('#/services/:service/log', function (c) {
|
||||||
}
|
var params = {
|
||||||
},
|
number: 50
|
||||||
function(){
|
};
|
||||||
store.clear('slide');
|
c.api('GET', '/services/'+ c.params['service'] +'/log', params, function(data) { // ?
|
||||||
c.redirect('#/services/'+ c.params['service']);
|
data2 = { 'logs': [], 'name': c.params['service'] };
|
||||||
}
|
$.each(data, function(k, v) {
|
||||||
);
|
data2.logs.push({filename: k, filecontent: v.join('\n')});
|
||||||
|
});
|
||||||
|
|
||||||
|
c.view('service/service_log', data2);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -26,77 +26,69 @@
|
||||||
});
|
});
|
||||||
if ($.isEmptyObject(params)) {
|
if ($.isEmptyObject(params)) {
|
||||||
c.flash('fail', y18n.t('error_modify_something'));
|
c.flash('fail', y18n.t('error_modify_something'));
|
||||||
store.clear('slide');
|
c.refresh();
|
||||||
c.redirect('#/tools/adminpw');
|
return;
|
||||||
} else if (params['new_password'] !== params['confirm_new_password']) {
|
}
|
||||||
|
if (params['new_password'] !== params['confirm_new_password']) {
|
||||||
c.flash('fail', y18n.t('passwords_dont_match'));
|
c.flash('fail', y18n.t('passwords_dont_match'));
|
||||||
store.clear('slide');
|
c.refresh();
|
||||||
c.redirect('#/tools/adminpw');
|
return;
|
||||||
} else {
|
}
|
||||||
c.api('/login', function(data) {
|
|
||||||
|
c.api('POST', '/login', { 'password': params['old_password'] }, function(data) {
|
||||||
// Remove useless variable
|
// Remove useless variable
|
||||||
delete params['old_password'];
|
delete params['old_password'];
|
||||||
delete params['confirm_new_password'];
|
delete params['confirm_new_password'];
|
||||||
|
|
||||||
// Update password and redirect to the home
|
// Update password and redirect to the home
|
||||||
c.api('/adminpw', function(data) { // http://api.yunohost.org/#!/tools/tools_adminpw_put_3
|
c.api('PUT', '/adminpw', params, function(data) {
|
||||||
c.redirect('#/logout');
|
c.redirect_to('#/logout');
|
||||||
}, 'PUT', params);
|
});
|
||||||
}, 'POST', { 'password': params['old_password'] }, false);
|
}, undefined, false);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// System update & upgrade
|
// System update & upgrade
|
||||||
app.get('#/update', function (c) {
|
app.get('#/update', function (c) {
|
||||||
c.api('/update', function(data) {
|
c.api('PUT', '/update', {}, function(data) {
|
||||||
c.view('update/update', data);
|
c.view('tools/tools_update', data, function() {
|
||||||
}, 'PUT');
|
// Configure buttons behaviors
|
||||||
});
|
$("button[data-upgrade]").on("click", function() {
|
||||||
|
|
||||||
// Upgrade apps or packages
|
var what = $(this).data("upgrade").toLowerCase();
|
||||||
app.get('#/upgrade/:type', function (c) {
|
|
||||||
c.confirm(
|
// Upgrade all apps or the system
|
||||||
y18n.t('tools'),
|
|
||||||
// confirm_update_apps and confirm_update_packages
|
if ((what == "system") || (what == "system"))
|
||||||
y18n.t('confirm_update_' + c.params['type'].toLowerCase()),
|
{
|
||||||
function(){
|
var confirm_message = y18n.t('confirm_update_' + what);
|
||||||
c.api('/upgrade?'+c.params["type"],
|
var api_url = '/upgrade?'+what;
|
||||||
function(data) {
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/tools/logs');
|
|
||||||
},
|
|
||||||
'PUT');
|
|
||||||
},
|
|
||||||
function(){
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/update');
|
|
||||||
}
|
}
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Upgrade a specific apps
|
// Upgrade a specific apps
|
||||||
app.get('#/upgrade/apps/:app', function (c) {
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var confirm_message = y18n.t('confirm_update_specific_app', [what]);
|
||||||
|
var api_url = '/upgrade/apps?app='+what;
|
||||||
|
}
|
||||||
|
|
||||||
c.confirm(
|
c.confirm(
|
||||||
y18n.t('tools'),
|
y18n.t('tools'),
|
||||||
y18n.t('confirm_update_specific_app', [c.params['app']]),
|
confirm_message,
|
||||||
function(){
|
function(){
|
||||||
c.api('/upgrade/apps?app='+c.params['app'].toLowerCase(),
|
c.api('PUT', api_url, {}, function(data) {
|
||||||
function(data) {
|
c.redirect_to('#/tools/logs');
|
||||||
store.clear('slide');
|
});
|
||||||
c.redirect('#/tools/logs');
|
|
||||||
},
|
|
||||||
'PUT');
|
|
||||||
},
|
|
||||||
function(){
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/update');
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// Display journals list
|
// Display journals list
|
||||||
app.get('#/tools/logs', function (c) {
|
app.get('#/tools/logs', function (c) {
|
||||||
c.api("/logs?limit=25&with_details", function(categories) {
|
c.api('GET', "/logs?limit=25&with_details", {}, function(categories) {
|
||||||
data = [];
|
data = [];
|
||||||
category_icons = {
|
category_icons = {
|
||||||
'operation': 'wrench',
|
'operation': 'wrench',
|
||||||
|
@ -139,7 +131,7 @@
|
||||||
var number = (c.params["number"])?c.params["number"]:50;
|
var number = (c.params["number"])?c.params["number"]:50;
|
||||||
params += "&number=" + number;
|
params += "&number=" + number;
|
||||||
|
|
||||||
c.api("/logs/display" + params, function(log) {
|
c.api('GET', "/logs/display" + params, {}, function(log) {
|
||||||
if ('metadata' in log) {
|
if ('metadata' in log) {
|
||||||
if (!'env' in log.metadata && 'args' in log.metadata) {
|
if (!'env' in log.metadata && 'args' in log.metadata) {
|
||||||
log.metadata.env = log.metadata.args
|
log.metadata.env = log.metadata.args
|
||||||
|
@ -149,6 +141,15 @@
|
||||||
"log": log,
|
"log": log,
|
||||||
"next_number": log.logs.length == number ? number * 10:false,
|
"next_number": log.logs.length == number ? number * 10:false,
|
||||||
"locale": y18n.locale
|
"locale": y18n.locale
|
||||||
|
}, function() {
|
||||||
|
// Configure behavior for the button to share log on Yunohost (it calls display --share)
|
||||||
|
$('button[data-action="share"]').on("click", function() {
|
||||||
|
c.api('GET', '/logs/display?path='+$(this).data('log-id')+'&share', {},
|
||||||
|
function(data) {
|
||||||
|
c.hideLoader();
|
||||||
|
window.open(data.url, '_blank');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -210,22 +211,19 @@
|
||||||
|
|
||||||
// Reboot or shutdown button
|
// Reboot or shutdown button
|
||||||
app.get('#/tools/reboot', function (c) {
|
app.get('#/tools/reboot', function (c) {
|
||||||
c.view('tools/tools_reboot');
|
c.view('tools/tools_reboot', {}, function() {
|
||||||
});
|
// Configure reboot/shutdown buttons behavior
|
||||||
|
$("button[data-action]").on("click", function() {
|
||||||
|
var action = $(this).data("action");
|
||||||
|
|
||||||
// Reboot or shutdown actions
|
|
||||||
app.get('#/tools/reboot/:action', function (c) {
|
|
||||||
var action = c.params['action'].toLowerCase();
|
|
||||||
if (action == 'reboot' || action == 'shutdown') {
|
|
||||||
c.confirm(
|
c.confirm(
|
||||||
y18n.t('tools_' + action),
|
y18n.t('tools_' + action),
|
||||||
// confirm_reboot_action_reboot or confirm_reboot_action_shutdown
|
|
||||||
y18n.t('confirm_reboot_action_' + action),
|
y18n.t('confirm_reboot_action_' + action),
|
||||||
function(){
|
function(){
|
||||||
c.api('/'+action+'?force', function(data) {
|
c.api('PUT', '/'+action+'?force', {}, function(data) {
|
||||||
// This code is not executed due to 502 response (reboot or shutdown)
|
// This code is not executed due to 502 response (reboot or shutdown)
|
||||||
c.redirect('#/logout');
|
c.redirect_to('#/logout');
|
||||||
}, 'PUT', {}, false, function (xhr) {
|
}, function (xhr) {
|
||||||
c.flash('success', y18n.t('tools_' + action + '_done'))
|
c.flash('success', y18n.t('tools_' + action + '_done'))
|
||||||
// Disconnect from the webadmin
|
// Disconnect from the webadmin
|
||||||
store.clear('url');
|
store.clear('url');
|
||||||
|
@ -243,26 +241,14 @@
|
||||||
$('#main').replaceWith('<div id="main"><div class="alert alert-warning"><i class="fa-power-off"></i> ' + y18n.t('tools_shuttingdown') + '</div></div>');
|
$('#main').replaceWith('<div id="main"><div class="alert alert-warning"><i class="fa-power-off"></i> ' + y18n.t('tools_shuttingdown') + '</div></div>');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove loader if any
|
c.hideLoader();
|
||||||
$('div.loader').remove();
|
|
||||||
|
|
||||||
// Force scrollTop on page load
|
// Force scrollTop on page load
|
||||||
$('html, body').scrollTop(0);
|
$('html, body').scrollTop(0);
|
||||||
store.clear('slide');
|
}, false);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
},
|
|
||||||
function(){
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/tools/reboot');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
c.flash('fail', y18n.t('unknown_action', [action]));
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/tools/reboot');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Diagnosis
|
// Diagnosis
|
||||||
|
@ -271,7 +257,7 @@
|
||||||
var private = (c.params.splat[0] == 'private');
|
var private = (c.params.splat[0] == 'private');
|
||||||
|
|
||||||
var endurl = (private) ? '?private' : '';
|
var endurl = (private) ? '?private' : '';
|
||||||
c.api('/diagnosis'+endurl, function(diagnosis) {
|
c.api('GET', '/diagnosis'+endurl, {}, function(diagnosis) {
|
||||||
c.view('tools/tools_diagnosis', {
|
c.view('tools/tools_diagnosis', {
|
||||||
'diagnosis' : JSON.stringify(diagnosis, undefined, 4),
|
'diagnosis' : JSON.stringify(diagnosis, undefined, 4),
|
||||||
'raw' : diagnosis,
|
'raw' : diagnosis,
|
||||||
|
@ -280,10 +266,10 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Reboot or shutdown button
|
// Migrations
|
||||||
app.get('#/tools/migrations', function (c) {
|
app.get('#/tools/migrations', function (c) {
|
||||||
c.api('/migrations?pending', function(pending_migrations) {
|
c.api('GET', '/migrations?pending', {}, function(pending_migrations) {
|
||||||
c.api('/migrations?done', function(done_migrations) {
|
c.api('GET', '/migrations?done', {}, function(done_migrations) {
|
||||||
pending_migrations = pending_migrations.migrations;
|
pending_migrations = pending_migrations.migrations;
|
||||||
done_migrations = done_migrations.migrations;
|
done_migrations = done_migrations.migrations;
|
||||||
|
|
||||||
|
@ -302,71 +288,45 @@
|
||||||
c.view('tools/tools_migrations', {
|
c.view('tools/tools_migrations', {
|
||||||
'pending_migrations' : pending_migrations.reverse(),
|
'pending_migrations' : pending_migrations.reverse(),
|
||||||
'done_migrations' : done_migrations.reverse()
|
'done_migrations' : done_migrations.reverse()
|
||||||
});
|
}, function() {
|
||||||
});
|
|
||||||
});
|
// Configure button 'Run'
|
||||||
});
|
$('button[data-action="run"]').on("click", function() {
|
||||||
|
|
||||||
app.get('#/tools/migrations/run', function (c) {
|
|
||||||
var disclaimerAcks = $(".disclaimer-ack");
|
var disclaimerAcks = $(".disclaimer-ack");
|
||||||
var withAcceptDisclaimerFlag = false;
|
|
||||||
for (var i = 0 ; i < disclaimerAcks.length ; i++)
|
for (var i = 0 ; i < disclaimerAcks.length ; i++)
|
||||||
{
|
{
|
||||||
console.log($(disclaimerAcks[i]).find("input:checked").val());
|
|
||||||
if (! $(disclaimerAcks[i]).find("input:checked").val())
|
if (! $(disclaimerAcks[i]).find("input:checked").val())
|
||||||
{
|
{
|
||||||
// FIXME / TODO i18n
|
// FIXME / TODO i18n
|
||||||
c.flash('fail', "Some of these migrations require you to acknowledge a disclaimer before running them.");
|
c.flash('fail', "Some of these migrations require you to acknowledge a disclaimer before running them.");
|
||||||
c.redirect('#/tools/migrations');
|
c.refresh();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
withAcceptDisclaimerFlag = true;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Not sure if necessary, but this distinction is to avoid accidentally
|
c.api('POST', '/migrations/migrate?accept_disclaimer', {}, function() { c.refresh(); });
|
||||||
// triggering a migration with a disclaimer if one goes to the
|
|
||||||
// /tools/migrations/run page "directly" somehow ...
|
|
||||||
if (withAcceptDisclaimerFlag)
|
|
||||||
{
|
|
||||||
c.api('/migrations/migrate?accept_disclaimer',
|
|
||||||
function (data) {
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/tools/migrations');
|
|
||||||
}, 'POST')
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
c.api('/migrations/migrate',
|
|
||||||
function (data) {
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/tools/migrations');
|
|
||||||
}, 'POST')
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('#/tools/migrations/skip/:migration_id', function (c) {
|
// Configure buttons 'Skip'
|
||||||
|
$('button[data-action="skip"]').on("click", function() {
|
||||||
|
var migration_id = $(this).data("migration");
|
||||||
c.confirm(
|
c.confirm(
|
||||||
y18n.t('migrations'),
|
y18n.t('migrations'),
|
||||||
y18n.t('confirm_migrations_skip'),
|
y18n.t('confirm_migrations_skip'),
|
||||||
function(){
|
function(){
|
||||||
c.api('/migrations/migrate?skip&targets=' + c.params['migration_id'], function(data) {
|
c.api('POST', '/migrations/migrate?skip&targets=' + migration_id, {}, function() { c.refresh() });
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/tools/migrations');
|
|
||||||
}, 'POST');
|
|
||||||
},
|
|
||||||
function(){
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/tools/migrations');
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// List available apps lists
|
// List available apps lists
|
||||||
app.get('#/tools/appslists', function (c) {
|
app.get('#/tools/appslists', function (c) {
|
||||||
c.api('/appslists', function(data) {
|
c.api('GET', '/appslists', {}, function(data) {
|
||||||
list = [];
|
list = [];
|
||||||
$.each(data, function(listname, listinfo) {
|
$.each(data, function(listname, listinfo) {
|
||||||
list.push({
|
list.push({
|
||||||
|
@ -379,7 +339,7 @@
|
||||||
c.view('tools/tools_appslists_list', {
|
c.view('tools/tools_appslists_list', {
|
||||||
appslists: list
|
appslists: list
|
||||||
});
|
});
|
||||||
}, 'GET');
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add a new apps list
|
// Add a new apps list
|
||||||
|
@ -389,15 +349,14 @@
|
||||||
'url' : c.params['appslist_url']
|
'url' : c.params['appslist_url']
|
||||||
}
|
}
|
||||||
|
|
||||||
c.api('/appslists', function(data) {
|
c.api('PUT', '/appslists', list, function(data) {
|
||||||
store.clear('slide');
|
c.redirect_to('#/tools/appslists/' + list.name);
|
||||||
c.redirect('#/tools/appslists/' + list.name);
|
});
|
||||||
}, 'PUT', list);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Show appslist info and operations
|
// Show appslist info and operations
|
||||||
app.get('#/tools/appslists/:appslist', function (c) {
|
app.get('#/tools/appslists/:appslist', function (c) {
|
||||||
c.api('/appslists', function(data) {
|
c.api('GET', '/appslists', {}, function(data) {
|
||||||
if (typeof data[c.params['appslist']] !== 'undefined') {
|
if (typeof data[c.params['appslist']] !== 'undefined') {
|
||||||
list = {
|
list = {
|
||||||
'name' : c.params['appslist'],
|
'name' : c.params['appslist'],
|
||||||
|
@ -409,25 +368,23 @@
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
c.flash('warning', y18n.t('appslists_unknown_list', [c.params['appslist']]));
|
c.flash('warning', y18n.t('appslists_unknown_list', [c.params['appslist']]));
|
||||||
store.clear('slide');
|
c.redirect_to('#/tools/appslists', {slide: false});
|
||||||
c.redirect('#/tools/appslists');
|
|
||||||
}
|
}
|
||||||
}, 'GET');
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Refresh available apps list
|
// Refresh available apps list
|
||||||
app.get('#/tools/appslists/refresh', function (c) {
|
app.get('#/tools/appslists/refresh', function (c) {
|
||||||
c.api('/appslists', function(data) {
|
c.api('PUT', '/appslists', {}, function(data) {
|
||||||
// c.redirect(store.get('path'));
|
c.redirect_to('#/apps/install', {slide: false});
|
||||||
c.redirect('#/apps/install');
|
});
|
||||||
}, 'PUT');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Refresh specific apps list
|
// Refresh specific apps list
|
||||||
app.get('#/tools/appslists/:appslist/refresh', function (c) {
|
app.get('#/tools/appslists/:appslist/refresh', function (c) {
|
||||||
c.api('/appslists', function(data) {
|
c.api('PUT', '/appslists', {'name' : c.params['appslist']}, function(data) {
|
||||||
c.redirect('#/tools/appslists');
|
c.redirect_to('#/tools/appslists', {slide: false});
|
||||||
}, 'PUT', {'name' : c.params['appslist']});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Remove apps list
|
// Remove apps list
|
||||||
|
@ -436,13 +393,9 @@
|
||||||
y18n.t('appslist'),
|
y18n.t('appslist'),
|
||||||
y18n.t('appslists_confirm_remove', [c.params['app']]),
|
y18n.t('appslists_confirm_remove', [c.params['app']]),
|
||||||
function() {
|
function() {
|
||||||
c.api('/appslists', function() {
|
c.api('DELETE', '/appslists', {'name' : c.params['appslist']}, function() {
|
||||||
c.redirect('#/tools/appslists');
|
c.redirect_to('#/tools/appslists');
|
||||||
}, 'DELETE', {'name' : c.params['appslist']});
|
});
|
||||||
},
|
|
||||||
function() {
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/tools/appslists/'+ c.params['appslist']);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
@ -38,12 +38,12 @@
|
||||||
**/
|
**/
|
||||||
function updateGroup(model, params) {
|
function updateGroup(model, params) {
|
||||||
var type = params.type;
|
var type = params.type;
|
||||||
var operation = params.operation;
|
var action = params.action;
|
||||||
var item = params.item;
|
var item = params.item;
|
||||||
var groupname = params.group;
|
var groupname = params.group;
|
||||||
var group = data.groups[groupname];
|
var group = data.groups[groupname];
|
||||||
var to = (operation == 'add')?group[type]:group[type + 'Inv'];
|
var to = (action == 'add')?group[type]:group[type + 'Inv'];
|
||||||
var from = (operation == 'add')?group[type+'Inv']:group[type];
|
var from = (action == 'add')?group[type+'Inv']:group[type];
|
||||||
// Do nothing, if array of destination already contains the item
|
// Do nothing, if array of destination already contains the item
|
||||||
if (from.indexOf(item) === -1) return;
|
if (from.indexOf(item) === -1) return;
|
||||||
|
|
||||||
|
@ -57,17 +57,17 @@
|
||||||
var params = {}; var url;
|
var params = {}; var url;
|
||||||
if (type == 'members') {
|
if (type == 'members') {
|
||||||
url = '/users/groups/' + groupname;
|
url = '/users/groups/' + groupname;
|
||||||
params[operation] = [item];
|
params[action] = [item];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
url = '/users/permissions/' + item;
|
url = '/users/permissions/' + item;
|
||||||
params[operation] = [groupname];
|
params[action] = [groupname];
|
||||||
}
|
}
|
||||||
c.api(url, function(data_update) {
|
c.api('PUT', url, params, function(data_update) {
|
||||||
to.push(item);
|
to.push(item);
|
||||||
from.splice(from.indexOf(item), 1);
|
from.splice(from.indexOf(item), 1);
|
||||||
updateView(data);
|
updateView(data);
|
||||||
}, 'PUT', params);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -91,23 +91,35 @@
|
||||||
var rendered = c.render('views/user/group_list.ms', model);
|
var rendered = c.render('views/user/group_list.ms', model);
|
||||||
rendered.swap(function () {
|
rendered.swap(function () {
|
||||||
// Add click event to get a nice "reactive" interface
|
// Add click event to get a nice "reactive" interface
|
||||||
jQuery(".group-update").on('click', function (e) {
|
$("button[data-action='add'], button[data-action='remove']").on('click', function (e) {
|
||||||
updateGroup(model, jQuery(this)[0].dataset);
|
updateGroup(model, $(this)[0].dataset);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
jQuery(".group-add-user").on('click', function (e) {
|
$('button[data-action="add-user-specific-permission"]').on('click', function (e) {
|
||||||
data.groups[$(this)[0].dataset.user].display = true;
|
data.groups[$(this).data("user")].display = true;
|
||||||
updateView(data);
|
updateView(data);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
$('button[data-action="delete-group"]').on('click', function (e) {
|
||||||
|
|
||||||
|
var group = $(this).data("group");
|
||||||
|
|
||||||
|
c.confirm(
|
||||||
|
y18n.t('groups'),
|
||||||
|
$('<div>'+ y18n.t('confirm_delete', [group]) +'</div>'),
|
||||||
|
function() {
|
||||||
|
c.api('DELETE', '/users/groups/'+ group, {}, function(data) { c.refresh(); });
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
app.get('#/groups', function (c) {
|
app.get('#/groups', function (c) {
|
||||||
c.api('/users/groups?full&include_primary_groups', function(data_groups) {
|
c.api('GET', '/users/groups?full&include_primary_groups', {}, function(data_groups) {
|
||||||
c.api('/users', function(data_users) {
|
c.api('GET', '/users', {}, function(data_users) {
|
||||||
c.api('/users/permissions?short', function(data_permissions) {
|
c.api('GET', '/users/permissions?short', {}, function(data_permissions) {
|
||||||
//var perms = data_permissions.permissions;
|
//var perms = data_permissions.permissions;
|
||||||
var specific_perms = {};
|
var specific_perms = {};
|
||||||
var all_perms = data_permissions.permissions;
|
var all_perms = data_permissions.permissions;
|
||||||
|
@ -166,33 +178,9 @@
|
||||||
|
|
||||||
app.post('#/groups/create', function (c) {
|
app.post('#/groups/create', function (c) {
|
||||||
c.params['groupname'] = c.params['groupname'].replace(' ', '_').toLowerCase();
|
c.params['groupname'] = c.params['groupname'].replace(' ', '_').toLowerCase();
|
||||||
c.api('/users/groups', function(data) {
|
c.api('POST', '/users/groups', c.params.toHash(), function(data) {
|
||||||
c.redirect('#/groups');
|
c.redirect_to('#/groups');
|
||||||
}, 'POST', c.params.toHash());
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('#/groups/:group/delete', function (c) {
|
|
||||||
|
|
||||||
var params = {};
|
|
||||||
|
|
||||||
// make confirm content
|
|
||||||
var confirmModalContent = $('<div>'+ y18n.t('confirm_delete', [c.params['group']]) +'</div>');
|
|
||||||
|
|
||||||
// display confirm modal
|
|
||||||
c.confirm(
|
|
||||||
y18n.t('groups'),
|
|
||||||
confirmModalContent,
|
|
||||||
function(){
|
|
||||||
c.api('/users/groups/'+ c.params['group'], function(data) {
|
|
||||||
c.redirect('#/groups');
|
|
||||||
}, 'DELETE', params);
|
|
||||||
},
|
|
||||||
function(){
|
|
||||||
//store.clear('slide');
|
|
||||||
c.redirect('#/groups');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -202,14 +190,14 @@
|
||||||
|
|
||||||
// List existing users
|
// List existing users
|
||||||
app.get('#/users', function (c) {
|
app.get('#/users', function (c) {
|
||||||
c.api('/users', function(data) { // http://api.yunohost.org/#!/user/user_list_get_3
|
c.api('GET', '/users', {}, function(data) {
|
||||||
c.view('user/user_list', data);
|
c.view('user/user_list', data);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create user form
|
// Create user form
|
||||||
app.get('#/users/create', function (c) {
|
app.get('#/users/create', function (c) {
|
||||||
c.api('/domains', function(data) { // http://api.yunohost.org/#!/domain/domain_list_get_2
|
c.api('GET', '/domains', {}, function(data) {
|
||||||
|
|
||||||
// Password min length
|
// Password min length
|
||||||
data.password_min_length = PASSWORD_MIN_LENGTH;
|
data.password_min_length = PASSWORD_MIN_LENGTH;
|
||||||
|
@ -230,7 +218,6 @@
|
||||||
if (c.params['password'] == c.params['confirmation']) {
|
if (c.params['password'] == c.params['confirmation']) {
|
||||||
if (c.params['password'].length < PASSWORD_MIN_LENGTH) {
|
if (c.params['password'].length < PASSWORD_MIN_LENGTH) {
|
||||||
c.flash('fail', y18n.t('password_too_short'));
|
c.flash('fail', y18n.t('password_too_short'));
|
||||||
store.clear('slide');
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Force unit or disable quota
|
// Force unit or disable quota
|
||||||
|
@ -242,28 +229,63 @@
|
||||||
// Compute email field
|
// Compute email field
|
||||||
c.params['mail'] = c.params['email'] + c.params['domain'];
|
c.params['mail'] = c.params['email'] + c.params['domain'];
|
||||||
|
|
||||||
c.api('/users', function(data) { // http://api.yunohost.org/#!/user/user_create_post_2
|
c.api('POST', '/users', c.params.toHash(), function(data) {
|
||||||
c.redirect('#/users');
|
c.redirect_to('#/users');
|
||||||
}, 'POST', c.params.toHash());
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
c.flash('fail', y18n.t('passwords_dont_match'));
|
c.flash('fail', y18n.t('passwords_dont_match'));
|
||||||
store.clear('slide');
|
|
||||||
//c.redirect('#/users/create');
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Show user information
|
// Show user information
|
||||||
app.get('#/users/:user', function (c) {
|
app.get('#/users/:user', function (c) {
|
||||||
c.api('/users/'+ c.params['user'], function(data) { // http://api.yunohost.org/#!/user/user_info_get_0
|
c.api('GET', '/users/'+ c.params['user'], {}, function(data) {
|
||||||
c.view('user/user_info', data);
|
c.view('user/user_info', data, function() {
|
||||||
|
|
||||||
|
// Configure delete button behavior
|
||||||
|
$('button[data-action="delete"]').on("click", function() {
|
||||||
|
var user = $(this).data("user");
|
||||||
|
|
||||||
|
var params = {};
|
||||||
|
|
||||||
|
// make confirm content
|
||||||
|
var purgeCheckbox = '<div><input type="checkbox" id="purge-user-data" name="purge-user-data"> <label for="purge-user-data">'+ y18n.t('purge_user_data_checkbox', [user]) +'</label></div>';
|
||||||
|
var purgeAlertMessage = '<div class="danger" style="display: none">⚠ '+ y18n.t('purge_user_data_warning') +'</div>';
|
||||||
|
var confirmModalContent = $('<div>'+ y18n.t('confirm_delete', [user]) +'<br><br>'+ purgeCheckbox +'<br>'+ purgeAlertMessage +'</div>');
|
||||||
|
|
||||||
|
// display confirm modal
|
||||||
|
c.confirm(
|
||||||
|
y18n.t('users'),
|
||||||
|
confirmModalContent,
|
||||||
|
function(){
|
||||||
|
c.api('DELETE', '/users/'+ user, params, function(data) {
|
||||||
|
c.redirect_to('#/users');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// toggle purge warning and parameter
|
||||||
|
confirmModalContent.find("input").click(function(){
|
||||||
|
|
||||||
|
if (confirmModalContent.find("input").is(':checked')) {
|
||||||
|
params.purge = "";
|
||||||
|
confirmModalContent.find(".danger").show();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
delete params.purge;
|
||||||
|
confirmModalContent.find(".danger").hide();
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Edit user form
|
// Edit user form
|
||||||
app.get('#/users/:user/edit', function (c) {
|
app.get('#/users/:user/edit', function (c) {
|
||||||
c.api('/users/'+ c.params['user'], function(data) { // http://api.yunohost.org/#!/user/user_info_get_0
|
c.api('GET', '/users/'+ c.params['user'], {}, function(data) {
|
||||||
c.api('/domains', function(dataDomains) { // http://api.yunohost.org/#!/domain/domain_list_get_2
|
c.api('GET', '/domains', {}, function(dataDomains) {
|
||||||
|
|
||||||
// Password min length
|
// Password min length
|
||||||
data.password_min_length = PASSWORD_MIN_LENGTH;
|
data.password_min_length = PASSWORD_MIN_LENGTH;
|
||||||
|
@ -314,7 +336,7 @@
|
||||||
// Update user information
|
// Update user information
|
||||||
app.put('#/users/:user', function (c) {
|
app.put('#/users/:user', function (c) {
|
||||||
// Get full user object
|
// Get full user object
|
||||||
c.api('/users/'+ c.params['user'], function(user) {
|
c.api('GET', '/users/'+ c.params['user'], {}, function(user) {
|
||||||
// Force unit or disable quota
|
// Force unit or disable quota
|
||||||
if (c.params['mailbox_quota']) {
|
if (c.params['mailbox_quota']) {
|
||||||
c.params['mailbox_quota'] += "M";
|
c.params['mailbox_quota'] += "M";
|
||||||
|
@ -353,79 +375,32 @@
|
||||||
|
|
||||||
if ($.isEmptyObject(params)) {
|
if ($.isEmptyObject(params)) {
|
||||||
c.flash('fail', y18n.t('error_modify_something'));
|
c.flash('fail', y18n.t('error_modify_something'));
|
||||||
store.clear('slide');
|
c.redirect_to('#/users/'+ c.params['user'] + '/edit', {slide: false});
|
||||||
c.redirect('#/users/'+ c.params['user'] + '/edit');
|
|
||||||
} else {
|
} else {
|
||||||
if (params['password']) {
|
if (params['password']) {
|
||||||
if (params['password'] == params['confirmation']) {
|
if (params['password'] == params['confirmation']) {
|
||||||
if (params['password'].length < PASSWORD_MIN_LENGTH) {
|
if (params['password'].length < PASSWORD_MIN_LENGTH) {
|
||||||
c.flash('fail', y18n.t('password_too_short'));
|
c.flash('fail', y18n.t('password_too_short'));
|
||||||
store.clear('slide');
|
c.redirect_to('#/users/'+ c.params['user'] + '/edit', {slide: false});
|
||||||
c.redirect('#/users/'+ c.params['user'] + '/edit');
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
params['change_password'] = params['password'];
|
params['change_password'] = params['password'];
|
||||||
c.api('/users/'+ c.params['user'], function(data) { // http://api.yunohost.org/#!/user/user_update_put_1
|
c.api('PUT', '/users/'+ c.params['user'], params, function(data) {
|
||||||
c.redirect('#/users/'+ c.params['user']);
|
c.redirect_to('#/users/'+ c.params['user']);
|
||||||
}, 'PUT', params);
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
c.flash('fail', y18n.t('passwords_dont_match'));
|
c.flash('fail', y18n.t('passwords_dont_match'));
|
||||||
store.clear('slide');
|
c.redirect_to('#/users/'+ c.params['user'] + '/edit', {slide: false});
|
||||||
c.redirect('#/users/'+ c.params['user'] + '/edit');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
c.api('/users/'+ c.params['user'], function(data) { // http://api.yunohost.org/#!/user/user_update_put_1
|
c.api('PUT', '/users/'+ c.params['user'], params, function(data) {
|
||||||
c.redirect('#/users/'+ c.params['user']);
|
c.redirect_to('#/users/'+ c.params['user']);
|
||||||
}, 'PUT', params);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 'GET');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Remove existing user
|
|
||||||
app.get('#/users/:user/delete', function (c) {
|
|
||||||
|
|
||||||
var params = {};
|
|
||||||
|
|
||||||
// make confirm content
|
|
||||||
var purgeCheckbox = '<div><input type="checkbox" id="purge-user-data" name="purge-user-data"> <label for="purge-user-data">'+ y18n.t('purge_user_data_checkbox', [c.params['user']]) +'</label></div>';
|
|
||||||
var purgeAlertMessage = '<div class="danger" style="display: none">⚠ '+ y18n.t('purge_user_data_warning') +'</div>';
|
|
||||||
var confirmModalContent = $('<div>'+ y18n.t('confirm_delete', [c.params['user']]) +'<br><br>'+ purgeCheckbox +'<br>'+ purgeAlertMessage +'</div>');
|
|
||||||
|
|
||||||
// display confirm modal
|
|
||||||
c.confirm(
|
|
||||||
y18n.t('users'),
|
|
||||||
confirmModalContent,
|
|
||||||
function(){
|
|
||||||
c.api('/users/'+ c.params['user'], function(data) { // http://api.yunohost.org/#!/user/user_delete_delete_4
|
|
||||||
c.redirect('#/users');
|
|
||||||
}, 'DELETE', params);
|
|
||||||
},
|
|
||||||
function(){
|
|
||||||
store.clear('slide');
|
|
||||||
c.redirect('#/users/'+ c.params['user']);
|
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
|
||||||
// toggle purge warning and parameter
|
|
||||||
confirmModalContent.find("input").click(function(){
|
|
||||||
|
|
||||||
if (confirmModalContent.find("input").is(':checked')) {
|
|
||||||
params.purge = "";
|
|
||||||
confirmModalContent.find(".warning").show();
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
delete params.purge;
|
|
||||||
confirmModalContent.find(".warning").hide();
|
|
||||||
};
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
app.bind('login', function(e, data) {
|
app.bind('login', function(e, data) {
|
||||||
c.api('/users', function(data) {
|
c.api('GET', '/users', {}, function(data) {
|
||||||
// Warn admin if no users are created.
|
// Warn admin if no users are created.
|
||||||
if (typeof data.users !== 'undefined' && data.users.length === 0) {
|
if (typeof data.users !== 'undefined' && data.users.length === 0) {
|
||||||
c.flash('warning', y18n.t('warning_first_user'));
|
c.flash('warning', y18n.t('warning_first_user'));
|
||||||
|
@ -69,13 +69,13 @@
|
||||||
c.flash('fail', y18n.t('error_retrieve_feed', [securityFeed]));
|
c.flash('fail', y18n.t('error_retrieve_feed', [securityFeed]));
|
||||||
});
|
});
|
||||||
|
|
||||||
c.api("/diagnosis", function(data) {
|
c.api("GET", "/diagnosis", {}, function(data) {
|
||||||
versions = data.packages;
|
versions = data.packages;
|
||||||
$('#yunohost-version').html(y18n.t('footer_version', [versions.yunohost.version, versions.yunohost.repo]));
|
$('#yunohost-version').html(y18n.t('footer_version', [versions.yunohost.version, versions.yunohost.repo]));
|
||||||
if (data.security["CVE-2017-5754"].vulnerable) {
|
if (data.security["CVE-2017-5754"].vulnerable) {
|
||||||
c.flash('danger', y18n.t('meltdown'));
|
c.flash('danger', y18n.t('meltdown'));
|
||||||
}
|
}
|
||||||
$('div.loader').remove();
|
c.hideLoader();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
function prefetchDomains(req) {
|
function prefetchDomains(req) {
|
||||||
// Preload domains list.
|
// Preload domains list.
|
||||||
req.params.domains = [];
|
req.params.domains = [];
|
||||||
req.api('/domains', function(data) {
|
req.api('GET', '/domains', {}, function(data) {
|
||||||
req.params.domains = data.domains;
|
req.params.domains = data.domains;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
function prefetchUsers(req){
|
function prefetchUsers(req){
|
||||||
// Preload users lists.
|
// Preload users lists.
|
||||||
req.params.users = [];
|
req.params.users = [];
|
||||||
req.api('/users', function(data) {
|
req.api('GET', '/users', {}, function(data) {
|
||||||
req.params.users = data.users;
|
req.params.users = data.users;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,20 +3,64 @@
|
||||||
var app = Sammy.apps['#main'];
|
var app = Sammy.apps['#main'];
|
||||||
var store = app.store;
|
var store = app.store;
|
||||||
|
|
||||||
|
// The logic used to temporily disable transition is from
|
||||||
|
// https://stackoverflow.com/a/16575811
|
||||||
|
function whichTransitionEvent(){
|
||||||
|
var t;
|
||||||
|
var el = document.createElement('fakeelement');
|
||||||
|
var transitions = {
|
||||||
|
'transition':'transitionend',
|
||||||
|
'OTransition':'oTransitionEnd',
|
||||||
|
'MozTransition':'transitionend',
|
||||||
|
'WebkitTransition':'webkitTransitionEnd'
|
||||||
|
}
|
||||||
|
|
||||||
|
for(t in transitions){
|
||||||
|
if( el.style[t] !== undefined ){
|
||||||
|
return transitions[t];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var transitionEvent = whichTransitionEvent();
|
||||||
|
|
||||||
|
function resetSliders()
|
||||||
|
{
|
||||||
|
// Disable transition effects
|
||||||
|
$('#slider-container').addClass('notransition');
|
||||||
|
// Delete the left/right temporary stuff only used during animation
|
||||||
|
$('#slideTo').css('display', 'none');
|
||||||
|
$('#slideTo').html("");
|
||||||
|
$('#slideBack').css('display', 'none');
|
||||||
|
$('#slideBack').html("");
|
||||||
|
// Set the margin-left back to 0
|
||||||
|
$('#slider-container').css('margin-left', '0');
|
||||||
|
// c.f. the stackoverflow thread
|
||||||
|
$('#slider-container')[0].offsetHeight;
|
||||||
|
// Remove the binding to this event handler for next times
|
||||||
|
// Re-enable transition effects
|
||||||
|
$('#slider-container').removeClass('notransition');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helpers
|
* Helpers
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
app.helpers({
|
app.helpers({
|
||||||
|
|
||||||
// Serialize an object
|
//
|
||||||
serialize : function(obj) {
|
// Pacman loader management
|
||||||
var str = [];
|
//
|
||||||
for(var p in obj)
|
|
||||||
if (obj.hasOwnProperty(p)) {
|
showLoader: function() {
|
||||||
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
|
app.loaded = false; // Not sure if that's really useful ... this is from old code with no explanation what it really does ...
|
||||||
|
if ($('div.loader').length === 0) {
|
||||||
|
$('#main').append('<div class="loader loader-content"></div>');
|
||||||
}
|
}
|
||||||
return str.join("&");
|
},
|
||||||
|
|
||||||
|
hideLoader: function() {
|
||||||
|
app.loaded = true; // Not sure if that's really useful ... this is from old code with no explanation what it really does ...
|
||||||
|
$('div.loader').remove();
|
||||||
},
|
},
|
||||||
|
|
||||||
// Flash helper to diplay instant notifications
|
// Flash helper to diplay instant notifications
|
||||||
|
@ -85,7 +129,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
// API call
|
// API call
|
||||||
api: function(uri, callback, method, data, websocket, callbackOnFailure) {
|
api: function(method, uri, data, callback, callbackOnFailure, websocket) {
|
||||||
c = this;
|
c = this;
|
||||||
|
|
||||||
method = typeof method !== 'undefined' ? method : 'GET';
|
method = typeof method !== 'undefined' ? method : 'GET';
|
||||||
|
@ -93,39 +137,14 @@
|
||||||
if (window.navigator && window.navigator.language && (typeof data.locale === 'undefined')) {
|
if (window.navigator && window.navigator.language && (typeof data.locale === 'undefined')) {
|
||||||
data.locale = y18n.locale || window.navigator.language.substr(0, 2);
|
data.locale = y18n.locale || window.navigator.language.substr(0, 2);
|
||||||
}
|
}
|
||||||
app.loaded = false;
|
|
||||||
if ($('div.loader').length === 0) {
|
c.showLoader();
|
||||||
$('#main').append('<div class="loader loader-content"></div>');
|
|
||||||
}
|
|
||||||
call = function(uri, callback, method, data, callbackOnFailure) {
|
call = function(uri, callback, method, data, callbackOnFailure) {
|
||||||
|
|
||||||
var args = data;
|
// Define default callback for failures
|
||||||
// TODO: change this code
|
|
||||||
if (uri === '/postinstall') {
|
|
||||||
var post_installing = false;
|
|
||||||
setInterval(function () {
|
|
||||||
post_installing = true;
|
|
||||||
}, 1500);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof callbackOnFailure !== 'function') {
|
if (typeof callbackOnFailure !== 'function') {
|
||||||
callbackOnFailure = function(xhr) {
|
callbackOnFailure = function(xhr) {
|
||||||
// Postinstall is a custom case, we have to wait that
|
|
||||||
// operation is done before doing anything
|
|
||||||
if ((uri === '/postinstall') && (post_installing)) {
|
|
||||||
interval = window.location.hostname === args.domain ? 20000 : 5000;
|
|
||||||
checkInstall = setInterval(function () {
|
|
||||||
c.checkInstall(function(isInstalled) {
|
|
||||||
if (isInstalled || typeof isInstalled === 'undefined') {
|
|
||||||
c.flash('success', y18n.t('installation_complete'));
|
|
||||||
clearInterval(checkInstall);
|
|
||||||
window.location.href = 'https://'+ window.location.hostname +'/yunohost/admin/';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, interval);
|
|
||||||
}
|
|
||||||
// Regular errors
|
|
||||||
else {
|
|
||||||
if (xhr.status == 200) {
|
if (xhr.status == 200) {
|
||||||
// Fail with 200, WTF
|
// Fail with 200, WTF
|
||||||
callback({});
|
callback({});
|
||||||
|
@ -176,13 +195,11 @@
|
||||||
console.log(xhr);
|
console.log(xhr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove loader if any
|
c.hideLoader();
|
||||||
$('div.loader').remove();
|
|
||||||
|
|
||||||
// Force scrollTop on page load
|
// Force scrollTop on page load
|
||||||
$('html, body').scrollTop(0);
|
$('html, body').scrollTop(0);
|
||||||
store.clear('slide');
|
store.clear('slide');
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,78 +254,17 @@
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Render view (cross-browser)
|
|
||||||
view: function (view, data, callback, enableSlide) {
|
// Ask confirmation to the user through the modal window
|
||||||
|
confirm: function(title, content, confirmCallback, cancelCallback) {
|
||||||
c = this;
|
c = this;
|
||||||
|
|
||||||
// Default
|
|
||||||
callback = typeof callback !== 'undefined' ? callback : function() {};
|
|
||||||
enableSlide = (typeof enableSlide !== 'undefined') ? enableSlide : true; // Change to false to disable animation
|
|
||||||
|
|
||||||
app.loaded = true;
|
|
||||||
|
|
||||||
// Hide loader and modal
|
|
||||||
$('div.loader').remove();
|
|
||||||
$('#modal').modal('hide');
|
|
||||||
|
|
||||||
// Render content
|
|
||||||
var rendered = this.render('views/'+ view +'.ms', data);
|
|
||||||
|
|
||||||
// Update content helper
|
|
||||||
var leSwap = function() {
|
|
||||||
rendered.swap(function() {
|
|
||||||
// Slide direction
|
|
||||||
if (enableSlide) {
|
|
||||||
$('.slide, .btn-breadcrumb a:not(:last-child)').on('click', function() {
|
|
||||||
$(this).addClass('active');
|
|
||||||
if ($(this).hasClass('back') || $(this).parent('.btn-breadcrumb').length) {
|
|
||||||
store.set('slide', 'back');
|
|
||||||
} else {
|
|
||||||
store.set('slide', 'to');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Paste <pre> helper
|
|
||||||
c.prePaste();
|
|
||||||
|
|
||||||
// Run callback
|
|
||||||
callback();
|
|
||||||
|
|
||||||
// Force scrollTop on page load
|
|
||||||
$('html, body').scrollTop(0);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// Slide back effect
|
|
||||||
if (enableSlide && store.get('slide') == 'back') {
|
|
||||||
store.clear('slide');
|
|
||||||
$('#slideBack').css('display', 'none');
|
|
||||||
$('#slider-container').css('margin-left', '-100%');
|
|
||||||
$('#slideTo').show().html($('#main').html());
|
|
||||||
leSwap();
|
|
||||||
$('#slider-container').css('margin-left', '0px');
|
|
||||||
}
|
|
||||||
// Slide to effect
|
|
||||||
else if (enableSlide && store.get('slide') == 'to') {
|
|
||||||
store.clear('slide');
|
|
||||||
$('#slideTo').css('display', 'none');
|
|
||||||
$('#slider-container').css('margin-left', '0px');
|
|
||||||
$('#slideBack').show().html($('#main').html());
|
|
||||||
leSwap();
|
|
||||||
$('#slider-container').css('margin-left', '-100%');
|
|
||||||
}
|
|
||||||
// No slideing effect
|
|
||||||
else {
|
|
||||||
leSwap();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
confirm: function(title, content, confirmCallback, cancelCallback) {
|
|
||||||
// Default callbacks
|
// Default callbacks
|
||||||
confirmCallback = typeof confirmCallback !== 'undefined' ? confirmCallback : function() {};
|
confirmCallback = typeof confirmCallback !== 'undefined' ? confirmCallback : function() {};
|
||||||
cancelCallback = typeof cancelCallback !== 'undefined' ? cancelCallback : function() {};
|
cancelCallback = typeof cancelCallback !== 'undefined' ? cancelCallback : function() {};
|
||||||
|
|
||||||
|
c.hideLoader();
|
||||||
|
|
||||||
// Get modal element
|
// Get modal element
|
||||||
var box = $('#modal');
|
var box = $('#modal');
|
||||||
|
|
||||||
|
@ -335,12 +291,10 @@
|
||||||
|
|
||||||
$('#modal footer button').unbind( "click" );
|
$('#modal footer button').unbind( "click" );
|
||||||
// Reset & Hide modal
|
// Reset & Hide modal
|
||||||
box
|
box.removeClass('no-title').modal('hide');
|
||||||
.removeClass('no-title')
|
|
||||||
.modal('hide');
|
|
||||||
|
|
||||||
// Do corresponding callback
|
// Do corresponding callback
|
||||||
if ($(this).data('action') == 'confirm') {
|
if ($(this).data('modal-action') == 'confirm') {
|
||||||
confirmCallback();
|
confirmCallback();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -352,19 +306,165 @@
|
||||||
return box.modal('show');
|
return box.modal('show');
|
||||||
},
|
},
|
||||||
|
|
||||||
selectAllOrNone: function () {
|
|
||||||
// Remove active style from buttons
|
// Render view (cross-browser)
|
||||||
$(".select_all-none input").click(function(){ $(this).toggleClass("active"); });
|
view: function (view, data, callback) {
|
||||||
// Select all checkbox in this panel
|
c = this;
|
||||||
$(".select_all").click(function(){
|
|
||||||
$(this).parents(".panel").children(".list-group").find("input").prop("checked", true);
|
// Default
|
||||||
|
callback = typeof callback !== 'undefined' ? callback : function() {};
|
||||||
|
|
||||||
|
// Hide loader and modal
|
||||||
|
c.hideLoader();
|
||||||
|
$('#modal').modal('hide');
|
||||||
|
|
||||||
|
// Render content
|
||||||
|
var rendered = this.render('views/'+ view +'.ms', data);
|
||||||
|
|
||||||
|
// Update content helper
|
||||||
|
var leSwap = function() {
|
||||||
|
rendered.swap(function() {
|
||||||
|
// Clicking on those kind of CSS elements will trigger a
|
||||||
|
// slide effect i.e. the next view rendering will have
|
||||||
|
// store.get('slide') set to 'back' or 'to'
|
||||||
|
$('.slide, .btn-breadcrumb a:not(:last-child)').on('click', function() {
|
||||||
|
$(this).addClass('active');
|
||||||
|
if ($(this).hasClass('back') || $(this).parent('.btn-breadcrumb').length) {
|
||||||
|
store.set('slide', 'back');
|
||||||
|
} else {
|
||||||
|
store.set('slide', 'to');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
// Deselect all checkbox in this panel
|
|
||||||
$(".select_none").click(function(){
|
// Paste <pre> helper
|
||||||
$(this).parents(".panel").children(".list-group").find("input").prop("checked", false);
|
c.prePaste();
|
||||||
|
|
||||||
|
// Run callback
|
||||||
|
callback();
|
||||||
|
|
||||||
|
// Force scrollTop on page load
|
||||||
|
$('html, body').scrollTop(0);
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Slide back effect
|
||||||
|
if (store.get('slide') == 'back') {
|
||||||
|
|
||||||
|
store.clear('slide');
|
||||||
|
// Disable transition while we tweak CSS
|
||||||
|
$('#slider-container').addClass('notransition');
|
||||||
|
// "Delete" the left part of the slider
|
||||||
|
$('#slideBack').css('display', 'none');
|
||||||
|
|
||||||
|
// Push the slider to the left
|
||||||
|
$('#slider-container').css('margin-left', '-100%');
|
||||||
|
// slideTo is the right part, and should contain the old view,
|
||||||
|
// so we copypasta what's in the "center" slider (#main)
|
||||||
|
$('#slideTo').show().html($('#main').html());
|
||||||
|
// leSwap will put the new view in the "center" slider (#main)
|
||||||
|
leSwap();
|
||||||
|
|
||||||
|
// So now things look like:
|
||||||
|
// | |
|
||||||
|
// | the screen |
|
||||||
|
// | |
|
||||||
|
//
|
||||||
|
// . #main . #slideTo .
|
||||||
|
// . the new view . the old view .
|
||||||
|
// ^ ^
|
||||||
|
// margin-left: -100% currently shown
|
||||||
|
//
|
||||||
|
// =====>>> sliiiiide =====>>>
|
||||||
|
|
||||||
|
// Re-add transition effect
|
||||||
|
$('#slider-container').removeClass('notransition');
|
||||||
|
|
||||||
|
// add the transition event to detect the end of the transition effect
|
||||||
|
transitionEvent
|
||||||
|
&& $("#slider-container").off(transitionEvent)
|
||||||
|
&& $("#slider-container").on(transitionEvent, resetSliders);
|
||||||
|
|
||||||
|
// And actually play the transition effect that will move the container from left to right
|
||||||
|
$('#slider-container').css('margin-left', '0px');
|
||||||
|
}
|
||||||
|
// Slide to effect
|
||||||
|
else if (store.get('slide') == 'to') {
|
||||||
|
|
||||||
|
// Disable transition while we tweak CSS
|
||||||
|
$('#slider-container').addClass('notransition');
|
||||||
|
// "Delete" the right part of the slider
|
||||||
|
$('#slideTo').css('display', 'none');
|
||||||
|
// Push the slider to the right
|
||||||
|
$('#slider-container').css('margin-left', '0px');
|
||||||
|
// slideBack should contain the old view,
|
||||||
|
// so we copypasta what's in the "center" slider (#main)
|
||||||
|
$('#slideBack').show().html($('#main').html());
|
||||||
|
leSwap();
|
||||||
|
|
||||||
|
// So now things look like:
|
||||||
|
//
|
||||||
|
// | |
|
||||||
|
// | the screen |
|
||||||
|
// | |
|
||||||
|
//
|
||||||
|
// . . #slideBack . #main .
|
||||||
|
// . . the old view . the new view .
|
||||||
|
// ^ ^ ^
|
||||||
|
// margin-left: -100% currently shown
|
||||||
|
//
|
||||||
|
// <<<===== sliiiiide <<<=======
|
||||||
|
|
||||||
|
|
||||||
|
// Re-add transition effect
|
||||||
|
$('#slider-container').removeClass('notransition');
|
||||||
|
|
||||||
|
// add the transition event to detect the end of the transition effect
|
||||||
|
var transitionEvent = whichTransitionEvent();
|
||||||
|
transitionEvent
|
||||||
|
&& $("#slider-container").off(transitionEvent)
|
||||||
|
&& $("#slider-container").on(transitionEvent, resetSliders);
|
||||||
|
|
||||||
|
// And actually play the transition effect that will move the container from right to left
|
||||||
|
$('#slider-container').css('margin-left', '-100%');
|
||||||
|
}
|
||||||
|
// No slideing effect
|
||||||
|
else {
|
||||||
|
leSwap();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
redirect_to: function(destination, options) {
|
||||||
|
c = this;
|
||||||
|
|
||||||
|
options = options !== undefined ? options : {};
|
||||||
|
|
||||||
|
// If destination if the same as current url,
|
||||||
|
// we don't want to display the slide animation
|
||||||
|
// (or if the code explicitly state to disable slide animation)
|
||||||
|
if ((c.path.split("#")[1] == destination.split("#")[1]) || (options.slide == false))
|
||||||
|
{
|
||||||
|
store.clear('slide');
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a copy-pasta of some of the redirect/refresh code of
|
||||||
|
// sammy.js because for some reason calling the original
|
||||||
|
// redirect/refresh function in some context does not work >.>
|
||||||
|
// (e.g. if you're already on the page)
|
||||||
|
c.trigger('redirect', {to: destination});
|
||||||
|
c.app.last_location = c.path;
|
||||||
|
c.app.setLocation(destination);
|
||||||
|
c.app.trigger('location-changed');
|
||||||
|
},
|
||||||
|
|
||||||
|
refresh: function() {
|
||||||
|
c = this;
|
||||||
|
c.redirect_to(c.path, {slide: false});
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Array / object helpers
|
||||||
|
//
|
||||||
|
|
||||||
arraySortById: function(arr) {
|
arraySortById: function(arr) {
|
||||||
arr.sort(function(a, b){
|
arr.sort(function(a, b){
|
||||||
if (a.id > b.id) {
|
if (a.id > b.id) {
|
||||||
|
@ -385,74 +485,20 @@
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
groupHooks: function(hooks, raw_infos){
|
// Serialize an object
|
||||||
var data = {};
|
serialize : function(obj) {
|
||||||
var rules = [
|
var str = [];
|
||||||
{
|
for(var p in obj)
|
||||||
id:'configuration',
|
if (obj.hasOwnProperty(p)) {
|
||||||
isIn:function (hook) {
|
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
|
||||||
return hook.indexOf('conf_')==0
|
|
||||||
}
|
}
|
||||||
}
|
return str.join("&");
|
||||||
];
|
|
||||||
|
|
||||||
$.each(hooks, function(i, hook) {
|
|
||||||
var group_id=hook;
|
|
||||||
var hook_size=(raw_infos && raw_infos[hook] && raw_infos[hook].size)?raw_infos[hook].size:0;
|
|
||||||
$.each(rules, function(i, rule) {
|
|
||||||
if (rule.isIn(hook)) {
|
|
||||||
group_id = 'adminjs_group_'+rule.id;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if(group_id in data) {
|
|
||||||
data[group_id] = {
|
|
||||||
name:y18n.t('hook_'+group_id),
|
|
||||||
value:data[group_id].value+','+hook,
|
|
||||||
description:data[group_id].description+', '+y18n.t('hook_'+hook),
|
|
||||||
size:data[group_id].size + hook_size
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
data[group_id] = {
|
|
||||||
name:y18n.t('hook_'+group_id),
|
|
||||||
value:hook,
|
|
||||||
description:(group_id==hook)?y18n.t('hook_'+hook+'_desc'):y18n.t('hook_'+hook),
|
|
||||||
size:hook_size
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return data;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
ungroupHooks: function(system_parts,apps) {
|
|
||||||
var data = {};
|
|
||||||
data['apps'] = apps || [];
|
|
||||||
data['system'] = system_parts || [];
|
|
||||||
|
|
||||||
if (data['system'].constructor !== Array) {
|
//
|
||||||
data['system'] = [data['system']];
|
// Misc helpers used in views etc..
|
||||||
}
|
//
|
||||||
if (data['apps'].constructor !== Array) {
|
|
||||||
data['apps'] = [data['apps']];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Some hook value contains multiple hooks separated by commas
|
|
||||||
var split_hooks = [];
|
|
||||||
$.each(data['system'], function(i, hook) {
|
|
||||||
split_hooks = split_hooks.concat(hook.split(','));
|
|
||||||
});
|
|
||||||
data['system'] = split_hooks;
|
|
||||||
|
|
||||||
if (data['system'].length == 0) {
|
|
||||||
delete data['system'];
|
|
||||||
}
|
|
||||||
if (data['apps'].length == 0) {
|
|
||||||
delete data['apps'];
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
},
|
|
||||||
|
|
||||||
// Paste <pre>
|
// Paste <pre>
|
||||||
prePaste: function() {
|
prePaste: function() {
|
||||||
|
@ -461,8 +507,7 @@
|
||||||
// Get paste content element
|
// Get paste content element
|
||||||
var preElement = $($(this).data('paste-content'));
|
var preElement = $($(this).data('paste-content'));
|
||||||
|
|
||||||
// Add pacman loader
|
c.showLoader();
|
||||||
$('#main').append('<div class="loader loader-content"></div>');
|
|
||||||
|
|
||||||
// Send to paste.yunohost.org
|
// Send to paste.yunohost.org
|
||||||
$.ajax({
|
$.ajax({
|
||||||
|
@ -477,8 +522,7 @@
|
||||||
c.flash('fail', y18n.t('paste_error'));
|
c.flash('fail', y18n.t('paste_error'));
|
||||||
})
|
})
|
||||||
.always(function(){
|
.always(function(){
|
||||||
// Remove pacman
|
c.hideLoader();
|
||||||
$('div.loader').remove();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -494,6 +538,7 @@
|
||||||
c.app.setLocation(to);
|
c.app.setLocation(to);
|
||||||
c.app.trigger('location-changed');
|
c.app.trigger('location-changed');
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -181,7 +181,7 @@
|
||||||
sam.store.set('url', window.location.hostname + '/yunohost/api');
|
sam.store.set('url', window.location.hostname + '/yunohost/api');
|
||||||
|
|
||||||
if (sam.store.get('connected')) {
|
if (sam.store.get('connected')) {
|
||||||
this.api('/diagnosis', function(diagnosis) {
|
this.api('GET', '/diagnosis', {}, function(diagnosis) {
|
||||||
versions = diagnosis.packages;
|
versions = diagnosis.packages;
|
||||||
$('#yunohost-version').html(y18n.t('footer_version', [versions.yunohost.version, versions.yunohost.repo]));
|
$('#yunohost-version').html(y18n.t('footer_version', [versions.yunohost.version, versions.yunohost.repo]));
|
||||||
});
|
});
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
"app_change_url": "Canvia l'URL",
|
"app_change_url": "Canvia l'URL",
|
||||||
"app_debug_no_logs": "Els registres de l'aplicació no estan disponibles",
|
"app_debug_no_logs": "Els registres de l'aplicació no estan disponibles",
|
||||||
"app_debug_tab": "Mostra la informació de depuració",
|
"app_debug_tab": "Mostra la informació de depuració",
|
||||||
"app_info_access_desc": "Administrar l'accés d'usuaris. Usuaris permesos: %s",
|
"app_info_access_desc": "Grups / usuaris autoritzats actualment a accedir a aquesta aplicació:",
|
||||||
"app_info_changelabel_desc": "Canvia l'etiqueta de l'aplicació al portal.",
|
"app_info_changelabel_desc": "Canvia l'etiqueta de l'aplicació al portal.",
|
||||||
"app_info_debug_desc": "Mostrar la informació de depuració per aquesta aplicació.",
|
"app_info_debug_desc": "Mostrar la informació de depuració per aquesta aplicació.",
|
||||||
"app_info_default_desc": "Redirigeix l'arrel del domini a aquesta aplicació (%s).",
|
"app_info_default_desc": "Redirigeix l'arrel del domini a aquesta aplicació (%s).",
|
||||||
|
@ -437,5 +437,20 @@
|
||||||
"request_help": "ajuda necessària",
|
"request_help": "ajuda necessària",
|
||||||
"request_help_details": "El desenvolupador actual necessita ajuda per mantenir aquesta aplicació. Podeu contribuir-hi!",
|
"request_help_details": "El desenvolupador actual necessita ajuda per mantenir aquesta aplicació. Podeu contribuir-hi!",
|
||||||
"advanced": "Avançat",
|
"advanced": "Avançat",
|
||||||
"from_to": "de %s fins a %s"
|
"from_to": "de %s fins a %s",
|
||||||
|
"group": "Grup",
|
||||||
|
"group_name": "Nom del grup",
|
||||||
|
"group_all_users": "Tots els usuaris",
|
||||||
|
"group_visitors": "Visitants",
|
||||||
|
"group_format_name_help": "Podeu utilitzar caràcters alfanumèrics i l'espai",
|
||||||
|
"group_add_member": "Afegir usuari",
|
||||||
|
"group_explain_all_users": "Aquest és un grup especial que conté tots els comptes d'usuari del servidor",
|
||||||
|
"group_add_permission": "Afegir permís",
|
||||||
|
"group_new": "Nou grup",
|
||||||
|
"group_explain_visitors": "Aquest és un grup especial que representa els visitants anònims",
|
||||||
|
"group_specific_permissions": "Permisos específics de l'usuari",
|
||||||
|
"groups_and_permissions": "Grups i permisos",
|
||||||
|
"groups_and_permissions_manage": "Gestionar grups i usuaris",
|
||||||
|
"permissions": "Permisos",
|
||||||
|
"nobody": "Ningú"
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
"api_not_responding": "The YunoHost API is not responding. Maybe 'yunohost-api' is down or got restarted?",
|
"api_not_responding": "The YunoHost API is not responding. Maybe 'yunohost-api' is down or got restarted?",
|
||||||
"app_change_label": "Change Label",
|
"app_change_label": "Change Label",
|
||||||
"app_change_url": "Change URL",
|
"app_change_url": "Change URL",
|
||||||
"app_debug_no_logs": "Application's logs are not available",
|
|
||||||
"app_debug_tab": "Display debug information",
|
|
||||||
"app_info_access_desc": "Groups / users currently allowed to access this app:",
|
"app_info_access_desc": "Groups / users currently allowed to access this app:",
|
||||||
"app_info_changelabel_desc": "Change app label in the portal.",
|
"app_info_changelabel_desc": "Change app label in the portal.",
|
||||||
"app_info_debug_desc": "Display debugging information for this application.",
|
"app_info_debug_desc": "Display debugging information for this application.",
|
||||||
|
@ -37,7 +35,6 @@
|
||||||
"application": "Application",
|
"application": "Application",
|
||||||
"applications": "Applications",
|
"applications": "Applications",
|
||||||
"archive_empty": "Empty archive",
|
"archive_empty": "Empty archive",
|
||||||
"available": "Available",
|
|
||||||
"available_apps": "Available apps",
|
"available_apps": "Available apps",
|
||||||
"backup": "Backup",
|
"backup": "Backup",
|
||||||
"backup_action": "Backup",
|
"backup_action": "Backup",
|
||||||
|
@ -53,12 +50,9 @@
|
||||||
"backup_type": "Type",
|
"backup_type": "Type",
|
||||||
"backups_no": "No backup",
|
"backups_no": "No backup",
|
||||||
"begin": "Begin",
|
"begin": "Begin",
|
||||||
"bit_rate": "Bit rate",
|
|
||||||
"both": "Both",
|
"both": "Both",
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
"check": "Check",
|
"check": "Check",
|
||||||
"check_mx": "MX record",
|
|
||||||
"check_stmp": "port 25 access",
|
|
||||||
"close": "Close",
|
"close": "Close",
|
||||||
"confirm_app_change_url": "Are you sure you want to change the app access URL?",
|
"confirm_app_change_url": "Are you sure you want to change the app access URL?",
|
||||||
"confirm_app_default": "Are you sure you want to make this app default?",
|
"confirm_app_default": "Are you sure you want to make this app default?",
|
||||||
|
@ -87,10 +81,7 @@
|
||||||
"confirm_reboot_action_shutdown": "Are you sure you want to shutdown your server?",
|
"confirm_reboot_action_shutdown": "Are you sure you want to shutdown your server?",
|
||||||
"connection": "Connection",
|
"connection": "Connection",
|
||||||
"copy": "Copy",
|
"copy": "Copy",
|
||||||
"count_min": "%s min",
|
|
||||||
"cpu_load": "CPU Load",
|
|
||||||
"created_at": "Created at",
|
"created_at": "Created at",
|
||||||
"cumulative_usage": "Cumulative usage",
|
|
||||||
"current_maintainer_title": "Current maintainer of this package",
|
"current_maintainer_title": "Current maintainer of this package",
|
||||||
"custom_app_install": "Install custom app",
|
"custom_app_install": "Install custom app",
|
||||||
"custom_app_url_only_github": "Currently only from GitHub",
|
"custom_app_url_only_github": "Currently only from GitHub",
|
||||||
|
@ -105,7 +96,6 @@
|
||||||
"diagnosis_with_private": "Diagnosis with private data",
|
"diagnosis_with_private": "Diagnosis with private data",
|
||||||
"disable": "Disable",
|
"disable": "Disable",
|
||||||
"disabled": "Disabled",
|
"disabled": "Disabled",
|
||||||
"disk": "Disk",
|
|
||||||
"dns": "DNS",
|
"dns": "DNS",
|
||||||
"domain": "Domain",
|
"domain": "Domain",
|
||||||
"domain_add": "Add domain",
|
"domain_add": "Add domain",
|
||||||
|
@ -137,14 +127,11 @@
|
||||||
"error_connection_interrupted": "The server closed the connection instead of answering it. Has nginx or the yunohost-api been restarted or stoppted for some reason? (Error code/message: %s)",
|
"error_connection_interrupted": "The server closed the connection instead of answering it. Has nginx or the yunohost-api been restarted or stoppted for some reason? (Error code/message: %s)",
|
||||||
"everything_good": "Everything good!",
|
"everything_good": "Everything good!",
|
||||||
"experimental_warning": "Warning: this feature is experimental and not consider stable, you shouldn't be using it except if you know what you are doing.",
|
"experimental_warning": "Warning: this feature is experimental and not consider stable, you shouldn't be using it except if you know what you are doing.",
|
||||||
"filesystem": "Filesystem",
|
|
||||||
"firewall": "Firewall",
|
"firewall": "Firewall",
|
||||||
"footer_version": "Powered by <a href='https://yunohost.org'>YunoHost</a> %s (%s).",
|
"footer_version": "Powered by <a href='https://yunohost.org'>YunoHost</a> %s (%s).",
|
||||||
"form_input_example": "Example: %s",
|
"form_input_example": "Example: %s",
|
||||||
"free": "Free",
|
"free": "Free",
|
||||||
"from_to": "from %s to %s",
|
"from_to": "from %s to %s",
|
||||||
"fs_type": "FS Type",
|
|
||||||
"gateway": "Gateway: ",
|
|
||||||
"good_practices_about_admin_password": "You are now about to define a new admin password. The password should be at least 8 characters - though it is good practice to use longer password (i.e. a passphrase) and/or to use various kind of characters (uppercase, lowercase, digits and special characters).",
|
"good_practices_about_admin_password": "You are now about to define a new admin password. The password should be at least 8 characters - though it is good practice to use longer password (i.e. a passphrase) and/or to use various kind of characters (uppercase, lowercase, digits and special characters).",
|
||||||
"good_practices_about_user_password": "You are now about to define a new user password. The password should be at least 8 characters - though it is good practice to use longer password (i.e. a passphrase) and/or to use various kind of characters (uppercase, lowercase, digits and special characters).",
|
"good_practices_about_user_password": "You are now about to define a new user password. The password should be at least 8 characters - though it is good practice to use longer password (i.e. a passphrase) and/or to use various kind of characters (uppercase, lowercase, digits and special characters).",
|
||||||
"group": "Group",
|
"group": "Group",
|
||||||
|
@ -177,7 +164,6 @@
|
||||||
"hook_data_home_desc": "User data located in /home/USER",
|
"hook_data_home_desc": "User data located in /home/USER",
|
||||||
"hook_data_mail": "Mail",
|
"hook_data_mail": "Mail",
|
||||||
"hook_data_mail_desc": "Raw emails stored on the server",
|
"hook_data_mail_desc": "Raw emails stored on the server",
|
||||||
"hostname": "Hostname",
|
|
||||||
"id": "ID",
|
"id": "ID",
|
||||||
"ignore": "Ignore",
|
"ignore": "Ignore",
|
||||||
"ignored": "%s ignored",
|
"ignored": "%s ignored",
|
||||||
|
@ -190,9 +176,7 @@
|
||||||
"installed": "Installed",
|
"installed": "Installed",
|
||||||
"installed_apps": "Installed apps",
|
"installed_apps": "Installed apps",
|
||||||
"installing": "Installing",
|
"installing": "Installing",
|
||||||
"interface": "Interface",
|
|
||||||
"internal_exception": "<strong>Yunohost encountered an internal error:/</strong><br><em>Really sorry about that.<br>You should look for help on <a href=\"https://forum.yunohost.org/\">the forum</a> or <a href=\"https://chat.yunohost.org/\">the chat</a> to fix the situation, or report the bug on <a href=\"https://github.com/YunoHost/issues\">the bugtracker</a>.</em><br>The following information might be useful for the person helping you:<h3>Action</h3><pre>%s%s</pre><h3>Traceback</h3><pre>%s</pre>",
|
"internal_exception": "<strong>Yunohost encountered an internal error:/</strong><br><em>Really sorry about that.<br>You should look for help on <a href=\"https://forum.yunohost.org/\">the forum</a> or <a href=\"https://chat.yunohost.org/\">the chat</a> to fix the situation, or report the bug on <a href=\"https://github.com/YunoHost/issues\">the bugtracker</a>.</em><br>The following information might be useful for the person helping you:<h3>Action</h3><pre>%s%s</pre><h3>Traceback</h3><pre>%s</pre>",
|
||||||
"io": "I/O",
|
|
||||||
"ipv4": "IPv4",
|
"ipv4": "IPv4",
|
||||||
"ipv6": "IPv6",
|
"ipv6": "IPv6",
|
||||||
"label": "Label",
|
"label": "Label",
|
||||||
|
@ -202,7 +186,6 @@
|
||||||
"license": "License",
|
"license": "License",
|
||||||
"loading": "Loading …",
|
"loading": "Loading …",
|
||||||
"local_archives": "Local archives",
|
"local_archives": "Local archives",
|
||||||
"local_ip": "Local IP",
|
|
||||||
"log": "Log",
|
"log": "Log",
|
||||||
"logged_in": "Logged in",
|
"logged_in": "Logged in",
|
||||||
"logged_out": "Logged out",
|
"logged_out": "Logged out",
|
||||||
|
@ -215,7 +198,6 @@
|
||||||
"manage_apps": "Manage apps",
|
"manage_apps": "Manage apps",
|
||||||
"manage_domains": "Manage domains",
|
"manage_domains": "Manage domains",
|
||||||
"manage_users": "Manage users",
|
"manage_users": "Manage users",
|
||||||
"memory": "Memory",
|
|
||||||
"menu": "Menu",
|
"menu": "Menu",
|
||||||
"migrations": "Migrations",
|
"migrations": "Migrations",
|
||||||
"migrations_pending": "Pending migrations",
|
"migrations_pending": "Pending migrations",
|
||||||
|
@ -223,14 +205,9 @@
|
||||||
"migrations_no_pending": "No pending migrations",
|
"migrations_no_pending": "No pending migrations",
|
||||||
"migrations_no_done": "No previous migrations",
|
"migrations_no_done": "No previous migrations",
|
||||||
"mode": "Mode",
|
"mode": "Mode",
|
||||||
"monitoring": "Monitoring",
|
|
||||||
"monitoring_check_glances": "Check <a href='#/services/glances'>glances</a> service status.",
|
|
||||||
"monitoring_disabled": "Monitoring is not enabled.",
|
|
||||||
"mount_point": "Mount point",
|
|
||||||
"multi_instance": "Multi instance",
|
"multi_instance": "Multi instance",
|
||||||
"myserver": "myserver",
|
"myserver": "myserver",
|
||||||
"myserver_org": "myserver.org",
|
"myserver_org": "myserver.org",
|
||||||
"network": "Network",
|
|
||||||
"next": "Next",
|
"next": "Next",
|
||||||
"no": "No",
|
"no": "No",
|
||||||
"no_installed_apps": "No installed apps.",
|
"no_installed_apps": "No installed apps.",
|
||||||
|
@ -245,7 +222,6 @@
|
||||||
"operations": "Operations",
|
"operations": "Operations",
|
||||||
"orphaned": "not maintained",
|
"orphaned": "not maintained",
|
||||||
"orphaned_details": "This app is not maintained anymore. It may still be working but won't receive any upgrade. Feel free to come and revive it!",
|
"orphaned_details": "This app is not maintained anymore. It may still be working but won't receive any upgrade. Feel free to come and revive it!",
|
||||||
"os": "OS",
|
|
||||||
"password": "Password",
|
"password": "Password",
|
||||||
"password_confirmation": "Password confirmation",
|
"password_confirmation": "Password confirmation",
|
||||||
"password_description": "Password must be at least %s characters long.",
|
"password_description": "Password must be at least %s characters long.",
|
||||||
|
@ -285,13 +261,8 @@
|
||||||
"postinstall_intro_3": "You can obtain more information by visiting the <a href='//yunohost.org/postinstall' target='_blank'>appropriate documentation page</a>",
|
"postinstall_intro_3": "You can obtain more information by visiting the <a href='//yunohost.org/postinstall' target='_blank'>appropriate documentation page</a>",
|
||||||
"postinstall_password": "This password will be used to manage everything on your server. Take the time to choose it wisely.",
|
"postinstall_password": "This password will be used to manage everything on your server. Take the time to choose it wisely.",
|
||||||
"previous": "Previous",
|
"previous": "Previous",
|
||||||
"process": "Process",
|
|
||||||
"protocol": "Protocol",
|
"protocol": "Protocol",
|
||||||
"public_ip": "Public IP: ",
|
|
||||||
"ram": "RAM",
|
|
||||||
"read": "Read",
|
|
||||||
"read_more": "Read more",
|
"read_more": "Read more",
|
||||||
"reception": "Reception",
|
|
||||||
"rerun_diagnosis": "Rerun diagnosis",
|
"rerun_diagnosis": "Rerun diagnosis",
|
||||||
"refresh_app_list": "Refresh list",
|
"refresh_app_list": "Refresh list",
|
||||||
"request_adoption": "waiting adoption",
|
"request_adoption": "waiting adoption",
|
||||||
|
@ -300,7 +271,6 @@
|
||||||
"request_help_details": "The current maintainer would like some help with the maintainance of this app. Feel free to come contribute on it!",
|
"request_help_details": "The current maintainer would like some help with the maintainance of this app. Feel free to come contribute on it!",
|
||||||
"restore": "Restore",
|
"restore": "Restore",
|
||||||
"run": "Run",
|
"run": "Run",
|
||||||
"running": "Running",
|
|
||||||
"save": "Save",
|
"save": "Save",
|
||||||
"search_for_apps": "Search for apps...",
|
"search_for_apps": "Search for apps...",
|
||||||
"select_all": "Select all",
|
"select_all": "Select all",
|
||||||
|
@ -321,7 +291,6 @@
|
||||||
"storage_create": "Add remote storage",
|
"storage_create": "Add remote storage",
|
||||||
"storages_new": "New remote storage",
|
"storages_new": "New remote storage",
|
||||||
"storages_no": "No storages.",
|
"storages_no": "No storages.",
|
||||||
"swap": "Swap",
|
|
||||||
"system": "System",
|
"system": "System",
|
||||||
"system_apps": "Apps",
|
"system_apps": "Apps",
|
||||||
"system_apps_nothing": "There are no apps to upgrade.",
|
"system_apps_nothing": "There are no apps to upgrade.",
|
||||||
|
@ -333,7 +302,6 @@
|
||||||
"system_upgrade_all_applications_btn": "Upgrade all applications",
|
"system_upgrade_all_applications_btn": "Upgrade all applications",
|
||||||
"system_upgrade_all_packages_btn": "Upgrade all packages",
|
"system_upgrade_all_packages_btn": "Upgrade all packages",
|
||||||
"tcp": "TCP",
|
"tcp": "TCP",
|
||||||
"time_since_update": "Time since update: ",
|
|
||||||
"tools": "Tools",
|
"tools": "Tools",
|
||||||
"tools_adminpw": "Change administration password",
|
"tools_adminpw": "Change administration password",
|
||||||
"tools_adminpw_confirm_placeholder": "Confirm the new password",
|
"tools_adminpw_confirm_placeholder": "Confirm the new password",
|
||||||
|
@ -355,8 +323,6 @@
|
||||||
"tools_shutdown_done": "Shutting down...",
|
"tools_shutdown_done": "Shutting down...",
|
||||||
"tools_shuttingdown": "Your server is powering off. As long as your server is off, you won't be able to use the web administration.",
|
"tools_shuttingdown": "Your server is powering off. As long as your server is off, you won't be able to use the web administration.",
|
||||||
"tools_shutdown_reboot": "Shutdown/Reboot",
|
"tools_shutdown_reboot": "Shutdown/Reboot",
|
||||||
"total": "Total",
|
|
||||||
"transmission": "Transmission",
|
|
||||||
"udp": "UDP",
|
"udp": "UDP",
|
||||||
"unauthorized": "Unauthorized",
|
"unauthorized": "Unauthorized",
|
||||||
"unignore": "Unignore",
|
"unignore": "Unignore",
|
||||||
|
@ -369,10 +335,7 @@
|
||||||
"upnp": "UPnP",
|
"upnp": "UPnP",
|
||||||
"upnp_disabled": "UPnP is disabled.",
|
"upnp_disabled": "UPnP is disabled.",
|
||||||
"upnp_enabled": "UPnP is enabled.",
|
"upnp_enabled": "UPnP is enabled.",
|
||||||
"uptime": "Uptime",
|
|
||||||
"url": "URL",
|
"url": "URL",
|
||||||
"usage": "Usage",
|
|
||||||
"used": "Used",
|
|
||||||
"user_email": "Email",
|
"user_email": "Email",
|
||||||
"user_emailaliases": "Mail aliases",
|
"user_emailaliases": "Mail aliases",
|
||||||
"user_emailforward": "Mail forward",
|
"user_emailforward": "Mail forward",
|
||||||
|
@ -388,11 +351,9 @@
|
||||||
"users_list": "User list",
|
"users_list": "User list",
|
||||||
"users_new": "New user",
|
"users_new": "New user",
|
||||||
"users_no": "No users.",
|
"users_no": "No users.",
|
||||||
"versions": "Versions",
|
|
||||||
"version": "Version",
|
"version": "Version",
|
||||||
"warnings": "%s warnings",
|
"warnings": "%s warnings",
|
||||||
"warning_first_user": "You probably need to <a href='#/users/create' class='alert-link'>create a user</a> first.",
|
"warning_first_user": "You probably need to <a href='#/users/create' class='alert-link'>create a user</a> first.",
|
||||||
"write": "Write",
|
|
||||||
"wrong_password": "Wrong password",
|
"wrong_password": "Wrong password",
|
||||||
"yes": "Yes",
|
"yes": "Yes",
|
||||||
"certificate_alert_not_valid": "CRITICAL: Current certificate is not valid! HTTPS won't work at all!",
|
"certificate_alert_not_valid": "CRITICAL: Current certificate is not valid! HTTPS won't work at all!",
|
||||||
|
@ -433,6 +394,6 @@
|
||||||
"appslists_last_update": "Last update",
|
"appslists_last_update": "Last update",
|
||||||
"appslists_unknown_list": "Unknown apps list: %s",
|
"appslists_unknown_list": "Unknown apps list: %s",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"purge_user_data_checkbox": "Purge %s's data? (This will remove the content of it's home and mail directories.)",
|
"purge_user_data_checkbox": "Purge %s's data? (This will remove the content of its home and mail directories.)",
|
||||||
"purge_user_data_warning": "Purging user's data is not reversible. Be sure you know what you're doing!"
|
"purge_user_data_warning": "Purging user's data is not reversible. Be sure you know what you're doing!"
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,7 +124,7 @@
|
||||||
"domain_dns_config": "Agordo DNS",
|
"domain_dns_config": "Agordo DNS",
|
||||||
"cpu_load": "CPU Ŝarĝo",
|
"cpu_load": "CPU Ŝarĝo",
|
||||||
"form_input_example": "Ekzemplo: %s",
|
"form_input_example": "Ekzemplo: %s",
|
||||||
"app_info_access_desc": "Administri la aliron de uzanto. Permesitaj uzantoj : %s",
|
"app_info_access_desc": "Grupoj/uzantoj nuntempe rajtas aliri ĉi tiun programon:",
|
||||||
"diagnosis_with_private": "Diagnozo kun privataj datumoj",
|
"diagnosis_with_private": "Diagnozo kun privataj datumoj",
|
||||||
"install_name": "Instalu %s",
|
"install_name": "Instalu %s",
|
||||||
"domain_default": "Defaŭlta domajno",
|
"domain_default": "Defaŭlta domajno",
|
||||||
|
@ -425,5 +425,20 @@
|
||||||
"name": "Nomo",
|
"name": "Nomo",
|
||||||
"udp": "UDP",
|
"udp": "UDP",
|
||||||
"swap": "Interŝanĝu",
|
"swap": "Interŝanĝu",
|
||||||
"user_interface_link": "Uzantinterfaco"
|
"user_interface_link": "Uzantinterfaco",
|
||||||
|
"group_format_name_help": "Vi povas uzi alfa-numerikajn signojn kaj spacon",
|
||||||
|
"group_add_member": "Aldonu uzanton",
|
||||||
|
"group": "Grupo",
|
||||||
|
"group_name": "Grupo nomo",
|
||||||
|
"group_all_users": "Ĉiuj uzantoj",
|
||||||
|
"groups_and_permissions": "Grupoj kaj permesoj",
|
||||||
|
"groups_and_permissions_manage": "Administri grupojn kaj permesojn",
|
||||||
|
"group_visitors": "Vizitantoj",
|
||||||
|
"group_explain_all_users": "Jen speciala grupo enhavanta ĉiujn uzantajn kontojn en la servilo",
|
||||||
|
"group_add_permission": "Aldonu permeson",
|
||||||
|
"group_new": "Nova grupo",
|
||||||
|
"group_explain_visitors": "Ĉi tio estas speciala grupo reprezentanta anonimajn vizitantojn",
|
||||||
|
"group_specific_permissions": "Uzaj specifaj permesoj",
|
||||||
|
"permissions": "Permesoj",
|
||||||
|
"nobody": "Neniu"
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
"app_access_title": "Acceso %s 4",
|
"app_access_title": "Acceso %s 4",
|
||||||
"app_debug_no_logs": "Los registros de la aplicación no están disponibles",
|
"app_debug_no_logs": "Los registros de la aplicación no están disponibles",
|
||||||
"app_debug_tab": "Mostrar información de depuración",
|
"app_debug_tab": "Mostrar información de depuración",
|
||||||
"app_info_access_desc": "Administrar el acceso de usuarios. Usuarios permitidos: %s 5",
|
"app_info_access_desc": "Grupos / usuarios actualmente autorizados a acceder a esta aplicación:",
|
||||||
"app_info_debug_desc": "Mostrar información de depuración para esta aplicación.",
|
"app_info_debug_desc": "Mostrar información de depuración para esta aplicación.",
|
||||||
"app_info_default_desc": "Redirigir la raíz del dominio para esta aplicación (%s 6).",
|
"app_info_default_desc": "Redirigir la raíz del dominio para esta aplicación (%s 6).",
|
||||||
"app_info_uninstall_desc": "Eliminar a esta aplicación.",
|
"app_info_uninstall_desc": "Eliminar a esta aplicación.",
|
||||||
|
@ -440,5 +440,20 @@
|
||||||
"appslists_confirm_remove": "¿Seguro que quiere eliminar esta lista de aplicaciones?",
|
"appslists_confirm_remove": "¿Seguro que quiere eliminar esta lista de aplicaciones?",
|
||||||
"level": "nivel",
|
"level": "nivel",
|
||||||
"system_upgrade_all_applications_btn": "Actualizar todas las aplicaciones",
|
"system_upgrade_all_applications_btn": "Actualizar todas las aplicaciones",
|
||||||
"select_all": "Seleccionar todo"
|
"select_all": "Seleccionar todo",
|
||||||
|
"group_explain_all_users": "Este es un grupo especial que contiene todas las cuentas de usuarios en el servidor",
|
||||||
|
"group": "Grupo",
|
||||||
|
"group_name": "Nombre del grupo",
|
||||||
|
"group_all_users": "Todos los usuarios",
|
||||||
|
"group_visitors": "Visitantes",
|
||||||
|
"group_format_name_help": "Puede usar caracteres alfanuméricos y espacio",
|
||||||
|
"group_add_member": "Añadir un usuario",
|
||||||
|
"group_add_permission": "Añadir permiso",
|
||||||
|
"group_new": "Nuevo grupo",
|
||||||
|
"group_explain_visitors": "Este es un grupo especial que representa a los visitantes anónimos",
|
||||||
|
"group_specific_permissions": "Permisos específicos de usuario",
|
||||||
|
"groups_and_permissions": "Grupos y permisos",
|
||||||
|
"groups_and_permissions_manage": "Gestionar grupos y permisos",
|
||||||
|
"permissions": "Permisos",
|
||||||
|
"nobody": "Nadie"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1,6 @@
|
||||||
{}
|
{
|
||||||
|
"password": "Pasahitza",
|
||||||
|
"ok": "Ados",
|
||||||
|
"cancel": "Utzi",
|
||||||
|
"logged_out": "Saioa amaitu"
|
||||||
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
"app_access_title": "Accès à %s",
|
"app_access_title": "Accès à %s",
|
||||||
"app_debug_no_logs": "Les journaux de cette application ne sont pas disponibles",
|
"app_debug_no_logs": "Les journaux de cette application ne sont pas disponibles",
|
||||||
"app_debug_tab": "Afficher les informations de débogage",
|
"app_debug_tab": "Afficher les informations de débogage",
|
||||||
"app_info_access_desc": "Gestion des droits d'accès. Utilisateurs autorisés : %s",
|
"app_info_access_desc": "Groupes / utilisateurs actuellement autorisés à accéder à cette application :",
|
||||||
"app_info_debug_desc": "Afficher les informations de débogage pour cette application.",
|
"app_info_debug_desc": "Afficher les informations de débogage pour cette application.",
|
||||||
"app_info_default_desc": "Redirige la racine du domaine vers cette application (%s).",
|
"app_info_default_desc": "Redirige la racine du domaine vers cette application (%s).",
|
||||||
"app_info_uninstall_desc": "Supprimer cette application.",
|
"app_info_uninstall_desc": "Supprimer cette application.",
|
||||||
|
@ -444,5 +444,20 @@
|
||||||
"request_help": "besoin d'assistance",
|
"request_help": "besoin d'assistance",
|
||||||
"request_help_details": "Le responsable actuel aimerait de l'aide pour la maintenance de cette application. N'hésitez pas à y contribuer !",
|
"request_help_details": "Le responsable actuel aimerait de l'aide pour la maintenance de cette application. N'hésitez pas à y contribuer !",
|
||||||
"advanced": "Avancée",
|
"advanced": "Avancée",
|
||||||
"from_to": "de %s à %s"
|
"from_to": "de %s à %s",
|
||||||
|
"group_name": "Nom du groupe",
|
||||||
|
"nobody": "Personne",
|
||||||
|
"group": "Groupe",
|
||||||
|
"group_all_users": "Tous les utilisateurs",
|
||||||
|
"group_visitors": "Visiteurs",
|
||||||
|
"group_format_name_help": "Vous pouvez utiliser des caractères alphanumériques et des espaces",
|
||||||
|
"group_add_member": "Ajouter un utilisateur",
|
||||||
|
"group_add_permission": "Ajouter une permission",
|
||||||
|
"group_new": "Nouveau groupe",
|
||||||
|
"group_explain_all_users": "Ceci est un groupe spécial contenant tous les comptes d'utilisateurs sur le serveur",
|
||||||
|
"group_explain_visitors": "Ceci est un groupe spécial représentant les visiteurs anonymes",
|
||||||
|
"group_specific_permissions": "Autorisations spécifiques à l'utilisateur",
|
||||||
|
"groups_and_permissions": "Groupes et autorisations",
|
||||||
|
"groups_and_permissions_manage": "Gérer les groupes et les autorisations",
|
||||||
|
"permissions": "Permissions"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"administration_password": "Yönetici parolası",
|
"administration_password": "Yönetici parolası",
|
||||||
"api_not_responding": "API cevap vermiyor",
|
"api_not_responding": "API cevap vermiyor",
|
||||||
"both": "İkisi birden",
|
"both": "İkisi birden",
|
||||||
"cancel": "İptal et",
|
"cancel": "İptal etmek",
|
||||||
"close": "Kapat",
|
"close": "Kapat",
|
||||||
"confirm_access_add": "%s için bütünn kullanıcılara erişim vermek istediğinizden emin misiniz ?",
|
"confirm_access_add": "%s için bütünn kullanıcılara erişim vermek istediğinizden emin misiniz ?",
|
||||||
"confirm_access_remove_all": "%s'e bütün erişimleri kaldırmak istediğinizden emin misiniz ?",
|
"confirm_access_remove_all": "%s'e bütün erişimleri kaldırmak istediğinizden emin misiniz ?",
|
||||||
|
@ -70,5 +70,6 @@
|
||||||
"url": "URL",
|
"url": "URL",
|
||||||
"warning_first_user": "Büyük ihtimalle önce <a href='#/users/create' class='alert-link'>kullanıcı oluşturmanız</a> gerekiyor.",
|
"warning_first_user": "Büyük ihtimalle önce <a href='#/users/create' class='alert-link'>kullanıcı oluşturmanız</a> gerekiyor.",
|
||||||
"wrong_password": "Yanlış parola",
|
"wrong_password": "Yanlış parola",
|
||||||
"yes": "Evet"
|
"yes": "Evet",
|
||||||
|
"ok": "Tamam"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
<div class="btn-breadcrumb">
|
|
||||||
<a href="#/" ><i class="fa-home"></i><span class="sr-only">{{t 'home'}}</span></a>
|
|
||||||
<a href="#/apps">{{t 'applications'}}</a>
|
|
||||||
<a href="#/apps/{{name}}">{{label}}</a>
|
|
||||||
<a href="#/apps/{{name}}/debug">{{t 'debug'}}</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="separator"></div>
|
|
||||||
|
|
||||||
{{#if services}}
|
|
||||||
<div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
|
|
||||||
{{#services}}
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading" role="tab" id="heading-{{ @index }}">
|
|
||||||
<h2 class="panel-title">
|
|
||||||
<a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse-{{ @index }}" aria-expanded="true" aria-controls="collapse-{{ @index }}">
|
|
||||||
<span class="fa-fw fa-info-circle"></span> {{t 'service_log' name }}
|
|
||||||
</a>
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
<div id="collapse-{{ @index }}" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading-{{ @index }}">
|
|
||||||
<div class="panel-body">
|
|
||||||
{{#logs}}
|
|
||||||
<h3>{{file_name}}</h3>
|
|
||||||
<pre id="service-log-{{ @index }}" class="service-log">{{file_content}}</pre>
|
|
||||||
<button data-paste-content="#service-log-{{ @index }}"><i class="fa-cloud-upload"></i> {{t 'upload'}}</button>
|
|
||||||
{{/logs}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/services}}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{else}}
|
|
||||||
<div class="alert alert-warning">
|
|
||||||
<span class="fa-exclamation-triangle"></span>
|
|
||||||
{{t 'app_debug_no_logs'}}
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
|
@ -57,9 +57,9 @@
|
||||||
<hr>
|
<hr>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<p>{{t 'app_info_default_desc' settings.domain}}</p>
|
<p>{{t 'app_info_default_desc' settings.domain}}</p>
|
||||||
<a role="button" href="#/apps/{{settings.id}}/default" class="btn btn-success slide">
|
<button class="btn btn-success" data-action="set-as-default" data-app="{{settings.id}}">
|
||||||
<span class="fa-star"></span> {{t 'app_make_default'}}
|
<span class="fa-star"></span> {{t 'app_make_default'}}
|
||||||
</a>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
@ -79,16 +79,9 @@
|
||||||
<hr>
|
<hr>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<p>{{t 'app_info_uninstall_desc'}}</p>
|
<p>{{t 'app_info_uninstall_desc'}}</p>
|
||||||
<a href="#/apps/{{settings.id}}/uninstall" role="button" class="btn btn-danger slide back">
|
<button class="btn btn-danger slide back" data-action="uninstall" data-app="{{settings.id}}">
|
||||||
<span class="fa-trash-o"></span> {{t 'uninstall'}}
|
<span class="fa-trash-o"></span> {{t 'uninstall'}}
|
||||||
</a>
|
</button>
|
||||||
</div>
|
|
||||||
<hr>
|
|
||||||
<div class="container">
|
|
||||||
<p>{{t 'app_info_debug_desc'}}</p>
|
|
||||||
<a href="#/apps/{{settings.id}}/debug" role="button" class ="btn btn-warning slide">
|
|
||||||
<span class="fa-bug"></span> {{t 'app_debug_tab'}}
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,12 +3,6 @@
|
||||||
<a href="#/backup">{{t 'backup'}}</a>
|
<a href="#/backup">{{t 'backup'}}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="actions-group">
|
|
||||||
<!--<a role="button" href="#/storages/create" class="btn btn-success slide">
|
|
||||||
<span class="fa-plus"></span> {{t 'storages_new'}}
|
|
||||||
</a>-->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="separator"></div>
|
<div class="separator"></div>
|
||||||
|
|
||||||
<div class="list-group">
|
<div class="list-group">
|
||||||
|
|
|
@ -83,41 +83,11 @@
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<!--<div class="container">
|
|
||||||
<p>{{t 'backup_archive_download'}}</p>
|
|
||||||
<a role="button" class="btn btn-info slide" href="#/backup/{{storage.id}}/{{name}}/download">
|
|
||||||
<span class="fa-download"></span> {{t 'download'}}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<hr>-->
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<p>{{t 'backup_archive_delete'}}</p>
|
<p>{{t 'backup_archive_delete'}}</p>
|
||||||
<a href="#/backup/{{storage.id}}/{{name}}/delete" role="button" class="btn btn-danger slide">
|
<button class="btn btn-danger slide" data-action="delete" data-storage="{{storage.id}}" data-archive="{{name}}">
|
||||||
<span class="fa-trash-o"></span> {{t 'delete'}}
|
<span class="fa-trash-o"></span> {{t 'delete'}}
|
||||||
</a>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{{#if other_storages}}
|
|
||||||
<hr>
|
|
||||||
<div class="container">
|
|
||||||
<p>{{t 'backup_archive_copy'}}</p>
|
|
||||||
<form action="#/backup/{{storage.id}}/{{name}}/copy" method="POST" class="form-horizontal">
|
|
||||||
<div class="form-group has-feedback">
|
|
||||||
<label for="label" class="col-sm-12">{{t 'url'}}</label>
|
|
||||||
<div class="col-sm-12">
|
|
||||||
<select id="storage" name="storage" class="form-control" required>
|
|
||||||
{{#each storages}}
|
|
||||||
<option value="{{id}}">{{name}} ({{uri}})</option>
|
|
||||||
{{/each}}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="text-center">
|
|
||||||
<input type="submit" role="button" class="btn btn-success slide" value="{{t 'copy'}}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
|
|
||||||
<div class="btn-breadcrumb">
|
|
||||||
<a href="#/"><i class="fa-home"></i><span class="sr-only">{{t 'home'}}</span></a>
|
|
||||||
<a href="#/backup">{{t 'backup'}}</a>
|
|
||||||
<a href="#/backup/{{storage.id}}/create">{{t 'storage_create'}}</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="separator"></div>
|
|
||||||
|
|
||||||
<form action="#/storages" method="POST" class="form-horizontal">
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-body">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="type" class="col-sm-3 control-label">{{t 'backup_type'}}</label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<select class="form-control" name="type">
|
|
||||||
<option>sftp</option>
|
|
||||||
<option>ftp</option>
|
|
||||||
<option>rsync</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="domain" class="col-sm-3 control-label">{{t 'domain'}}</label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<input type="text" id="domain" name="domain" class="form-control" placeholder="monserver.fr" required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="username" class="col-sm-3 control-label">{{t 'user_username'}}</label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<input type="text" id="username" name="username" class="form-control" placeholder="johndoe" required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="password" class="col-sm-3 control-label">{{t 'password'}}</label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<input type="password" id="password" name="password" class="form-control" placeholder="•••••" required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="path" class="col-sm-3 control-label">{{t 'path'}}</label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<input type="text" id="path" name="path" class="form-control" placeholder="~/" required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="text-center">
|
|
||||||
<input type="submit" role="button" class="btn btn-success slide back" value="{{t 'save'}}">
|
|
||||||
</div>
|
|
||||||
</form>
|
|
|
@ -46,36 +46,36 @@
|
||||||
<p><span class="fa-fw fa-meh-o"></span>
|
<p><span class="fa-fw fa-meh-o"></span>
|
||||||
{{t 'domain_not_eligible_for_ACME'}}</p>
|
{{t 'domain_not_eligible_for_ACME'}}</p>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<a role="button" href="#/domains/{{name}}/cert-install-LE" class="btn btn-success {{#unless status.ACME_eligible}}disabled{{/unless}}">
|
<button class="btn btn-success {{#unless status.ACME_eligible}}disabled{{/unless}}" data-domain="{{name}}" data-action="install-LE" >
|
||||||
<span class="fa-star"></span> {{t 'install_letsencrypt_cert'}}
|
<span class="fa-star"></span> {{t 'install_letsencrypt_cert'}}
|
||||||
</a>
|
</button>
|
||||||
<hr>
|
<hr>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if actions_enabled.manual_renew_letsencrpt}}
|
{{#if actions_enabled.manual_renew_letsencrpt}}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<p>{{t 'manually_renew_letsencrypt_message'}}</p>
|
<p>{{t 'manually_renew_letsencrypt_message'}}</p>
|
||||||
<a role="button" href="#/domains/{{name}}/cert-renew-letsencrypt" class="btn btn-warning">
|
<button class="btn btn-warning" data-domain="{{name}}" data-action="renew-letsencrypt">
|
||||||
<span class="fa-refresh"></span> {{t 'manually_renew_letsencrypt'}}
|
<span class="fa-refresh"></span> {{t 'manually_renew_letsencrypt'}}
|
||||||
</a>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if actions_enabled.regen_selfsigned}}
|
{{#if actions_enabled.regen_selfsigned}}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<p>{{t 'regenerate_selfsigned_cert_message'}}</p>
|
<p>{{t 'regenerate_selfsigned_cert_message'}}</p>
|
||||||
<a href="#/domains/{{name}}/cert-regen-selfsigned" role="button" class="btn btn-warning">
|
<button class="btn btn-warning" data-domain="{{name}}" data-action="regen-selfsigned">
|
||||||
<span class="fa-refresh"></span> {{t 'regenerate_selfsigned_cert'}}
|
<span class="fa-refresh"></span> {{t 'regenerate_selfsigned_cert'}}
|
||||||
</a>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if actions_enabled.replace_with_selfsigned}}
|
{{#if actions_enabled.replace_with_selfsigned}}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<p>{{t 'revert_to_selfsigned_cert_message'}}</p>
|
<p>{{t 'revert_to_selfsigned_cert_message'}}</p>
|
||||||
<a href="#/domains/{{name}}/cert-replace-with-selfsigned" role="button" class="btn btn-danger">
|
<button class="btn btn-danger" data-domain="{{name}}" data-action="replace-with-selfsigned">
|
||||||
<span class="fa-exclamation-triangle"></span> {{t 'revert_to_selfsigned_cert'}}
|
<span class="fa-exclamation-triangle"></span> {{t 'revert_to_selfsigned_cert'}}
|
||||||
</a>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -12,67 +12,46 @@
|
||||||
<span class="fa-fw fa-globe"></span> {{name}}
|
<span class="fa-fw fa-globe"></span> {{name}}
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
|
||||||
{{#if main}}
|
|
||||||
<p class="alert alert-success">
|
|
||||||
<span class="fa-star" title="{{t 'default'}}"></span> {{t 'domain_default_longdesc'}}
|
|
||||||
</p>
|
|
||||||
{{/if}}
|
|
||||||
<p><a href="{{url}}" target="_blank">{{url}}</a></p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<h2 class="panel-title">
|
|
||||||
<span class="fa-fw fa-wrench"></span> {{t 'operations'}}
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<p>{{t 'domain_visit_url' url}}</p>
|
<p>{{t 'domain_visit_url' url}}</p>
|
||||||
<a role="button" href="{{url}}" class="btn btn-success" target="_blank">
|
<a role="button" href="{{url}}" class="btn btn-success" target="_blank">
|
||||||
{{t 'domain_visit'}} <span class="fa-fw fa-external-link"></span>
|
<span class="fa-fw fa-external-link"></span> {{t 'domain_visit'}}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{{#unless main}}
|
|
||||||
<hr>
|
<hr>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<p>{{t 'domain_default_desc'}}</p>
|
<p>{{t 'domain_default_desc'}}</p>
|
||||||
<form method="POST" action="#/domains">
|
{{#if main}}
|
||||||
<input type="hidden" name="domain" value="{{name}}" required class="form-control">
|
<p class="alert alert-info">
|
||||||
<button type="submit" class="btn btn-primary slide back" value="{{t 'set_default'}}">
|
<span class="fa-star" title="{{t 'default'}}"></span> {{t 'domain_default_longdesc'}}
|
||||||
{{t 'set_default'}} <span class="fa-fw fa-star"></span>
|
</p>
|
||||||
|
{{else}}
|
||||||
|
<button class="btn btn-primary" data-action="set_default" data-domain="{{name}}">
|
||||||
|
<span class="fa-fw fa-star"></span> {{t 'set_default'}}
|
||||||
</button>
|
</button>
|
||||||
</form>
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
{{/unless}}
|
|
||||||
<hr>
|
<hr>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<p>{{t 'domain_dns_longdesc'}}</p>
|
<p>{{t 'domain_dns_longdesc'}}</p>
|
||||||
<a role="button" href="#/domains/{{name}}/dns" class="btn btn-default slide">
|
<a role="button" href="#/domains/{{name}}/dns" class="btn btn-default slide">
|
||||||
{{t 'domain_dns_config'}} <span class="fa-fw fa-globe"></span>
|
<span class="fa-fw fa-globe"></span> {{t 'domain_dns_config'}}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<p>{{t 'certificate_manage'}}</p>
|
<p>{{t 'certificate_manage'}}</p>
|
||||||
{{#unless enable_cert_management}}
|
<a href="#/domains/{{name}}/cert-management" role="button" class="btn btn-default slide">
|
||||||
<p><span class="fa-fw fa-exclamation-circle"></span>
|
<span class="fa-fw fa-lock"></span> {{t 'ssl_certificate'}}
|
||||||
{{t 'certificate_old_letsencrypt_app_conflict'}}
|
|
||||||
</p>
|
|
||||||
{{/unless}}
|
|
||||||
<a href="#/domains/{{name}}/cert-management" role="button" class="btn btn-default slide {{#unless enable_cert_management}}disabled{{/unless}}">
|
|
||||||
{{t 'ssl_certificate'}} <span class="fa-fw fa-lock"></span>
|
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<p>{{t 'domain_delete_longdesc' name}}</p>
|
<p>{{t 'domain_delete_longdesc' name}}</p>
|
||||||
<a href="#/domains/{{name}}/delete" role="button" class="btn btn-danger slide back">
|
<button class="btn btn-danger" data-action="delete" data-domain="{{name}}">
|
||||||
{{t 'delete'}} <span class="fa-fw fa-trash-o"></span>
|
<span class="fa-fw fa-trash-o"></span> {{t 'delete'}}
|
||||||
</a>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -53,25 +53,25 @@
|
||||||
|
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
{{#is_loaded}}
|
{{#is_loaded}}
|
||||||
<a href="#/services/{{name}}/disable" role="button" class="btn btn-danger">
|
<button class="btn btn-danger" data-service="{{name}}" data-action="disable">
|
||||||
<span class="fa-square-o"></span> {{t 'disable'}}
|
<span class="fa-square-o"></span> {{t 'disable'}}
|
||||||
</a>
|
</button>
|
||||||
{{/is_loaded}}
|
{{/is_loaded}}
|
||||||
{{^is_loaded}}
|
{{^is_loaded}}
|
||||||
<a href="#/services/{{name}}/enable" role="button" class="btn btn-success">
|
<button class="btn btn-success" data-service="{{name}}" data-action="enable">
|
||||||
<span class="fa-check-square-o"></span> {{t 'enable'}}
|
<span class="fa-check-square-o"></span> {{t 'enable'}}
|
||||||
</a>
|
</button>
|
||||||
{{/is_loaded}}
|
{{/is_loaded}}
|
||||||
|
|
||||||
{{#is_running}}
|
{{#is_running}}
|
||||||
<a href="#/services/{{name}}/stop" role="button" class="btn btn-danger">
|
<button class="btn btn-danger" data-service="{{name}}" data-action="stop">
|
||||||
<span class="fa-stop"></span> {{t 'stop'}}
|
<span class="fa-stop"></span> {{t 'stop'}}
|
||||||
</a>
|
</button>
|
||||||
{{/is_running}}
|
{{/is_running}}
|
||||||
{{^is_running}}
|
{{^is_running}}
|
||||||
<a href="#/services/{{name}}/start" role="button" class="btn btn-success">
|
<button class="btn btn-success" data-service="{{name}}" data-action="start">
|
||||||
<span class="fa-play"></span> {{t 'start'}}
|
<span class="fa-play"></span> {{t 'start'}}
|
||||||
</a>
|
</button>
|
||||||
{{/is_running}}
|
{{/is_running}}
|
||||||
<a href="#/services/{{name}}/log" role="button" class="btn btn-default slide">
|
<a href="#/services/{{name}}/log" role="button" class="btn btn-default slide">
|
||||||
<span class="fa-book"></span> {{t 'log'}}
|
<span class="fa-book"></span> {{t 'log'}}
|
||||||
|
|
|
@ -29,20 +29,20 @@
|
||||||
<td>
|
<td>
|
||||||
{{#if this.ipv4}}
|
{{#if this.ipv4}}
|
||||||
<span class="fa-check"></span>
|
<span class="fa-check"></span>
|
||||||
<a class="btn btn-xs btn-danger" href="#/tools/firewall/port/{{@key}}/tcp/ipv4/close">{{t 'close'}}</a>
|
<button class="btn btn-xs btn-danger" data-action="close" data-port="{{@key}}" data-protocol="tcp" data-connection="ipv4">{{t 'close'}}</button>
|
||||||
{{else}}
|
{{else}}
|
||||||
<span></span>
|
<span></span>
|
||||||
<span class="fa-times"></span>
|
<span class="fa-times"></span>
|
||||||
<a class="btn btn-xs btn-success" href="#/tools/firewall/port/{{@key}}/tcp/ipv4/open">{{t 'open'}}</a>
|
<button class="btn btn-xs btn-success" data-action="open" data-port="{{@key}}" data-protocol="tcp" data-connection="ipv4">{{t 'open'}}</button>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{#if this.ipv6}}
|
{{#if this.ipv6}}
|
||||||
<span class="fa-check"></span>
|
<span class="fa-check"></span>
|
||||||
<a class="btn btn-xs btn-danger" href="#/tools/firewall/port/{{@key}}/tcp/ipv6/close">{{t 'close'}}</a>
|
<button class="btn btn-xs btn-danger" data-action="close" data-port="{{@key}}" data-protocol="tcp" data-connection="ipv6">{{t 'close'}}</button>
|
||||||
{{else}}
|
{{else}}
|
||||||
<span class="fa-times"></span>
|
<span class="fa-times"></span>
|
||||||
<a class="btn btn-xs btn-success" href="#/tools/firewall/port/{{@key}}/tcp/ipv6/open">{{t 'open'}}</a>
|
<button class="btn btn-xs btn-success" data-action="open" data-port="{{@key}}" data-protocol="tcp" data-connection="ipv6">{{t 'open'}}</button>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -75,20 +75,20 @@
|
||||||
<td>
|
<td>
|
||||||
{{#if this.ipv4}}
|
{{#if this.ipv4}}
|
||||||
<span class="fa-check"></span>
|
<span class="fa-check"></span>
|
||||||
<a class="btn btn-xs btn-danger" href="#/tools/firewall/port/{{@key}}/udp/ipv4/close">{{t 'close'}}</a>
|
<button class="btn btn-xs btn-danger" data-action="close" data-port="{{@key}}" data-protocol="udp" data-connection="ipv4">{{t 'close'}}</button>
|
||||||
{{else}}
|
{{else}}
|
||||||
<span></span>
|
<span></span>
|
||||||
<span class="fa-times"></span>
|
<span class="fa-times"></span>
|
||||||
<a class="btn btn-xs btn-success" href="#/tools/firewall/port/{{@key}}/udp/ipv4/open">{{t 'open'}}</a>
|
<button class="btn btn-xs btn-success" data-action="open" data-port="{{@key}}" data-protocol="udp" data-connection="ipv4">{{t 'open'}}</button>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{#if this.ipv6}}
|
{{#if this.ipv6}}
|
||||||
<span class="fa-check"></span>
|
<span class="fa-check"></span>
|
||||||
<a class="btn btn-xs btn-danger" href="#/tools/firewall/port/{{@key}}/udp/ipv6/close">{{t 'close'}}</a>
|
<button class="btn btn-xs btn-danger" data-action="close" data-port="{{@key}}" data-protocol="udp" data-connection="ipv6">{{t 'close'}}</button>
|
||||||
{{else}}
|
{{else}}
|
||||||
<span class="fa-times"></span>
|
<span class="fa-times"></span>
|
||||||
<a class="btn btn-xs btn-success" href="#/tools/firewall/port/{{@key}}/udp/ipv6/open">{{t 'open'}}</a>
|
<button class="btn btn-xs btn-success" data-action="open" data-port="{{@key}}" data-protocol="udp" data-connection="ipv6">{{t 'open'}}</button>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -168,10 +168,10 @@
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
{{#if upnp}}
|
{{#if upnp}}
|
||||||
<p class="text-success">{{t 'upnp_enabled'}}</p>
|
<p class="text-success">{{t 'upnp_enabled'}}</p>
|
||||||
<a role="button" href="#/tools/firewall/upnp/disable" class="btn btn-danger">{{t 'disable'}}</a>
|
<button class="btn btn-danger" data-upnp="disable">{{t 'disable'}}</button>
|
||||||
{{else}}
|
{{else}}
|
||||||
<p class="text-danger">{{t 'upnp_disabled'}}</p>
|
<p class="text-danger">{{t 'upnp_disabled'}}</p>
|
||||||
<a role="button" href="#/tools/firewall/upnp/enable" class="btn btn-success">{{t 'enable'}}</a>
|
<button class="btn btn-success" data-upnp="enable">{{t 'enable'}}</button>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -34,10 +34,6 @@
|
||||||
<h2 style="font-weight:600; padding-left:0.5em;">{{t 'advanced'}}</h2>
|
<h2 style="font-weight:600; padding-left:0.5em;">{{t 'advanced'}}</h2>
|
||||||
|
|
||||||
<div class="list-group">
|
<div class="list-group">
|
||||||
<a href="#/tools/monitor" class="list-group-item slide clearfix">
|
|
||||||
<span class="pull-right fa-chevron-right"></span>
|
|
||||||
<h2 class="list-group-item-heading">{{t 'monitoring'}}</h2>
|
|
||||||
</a>
|
|
||||||
<a href="#/tools/firewall" class="list-group-item slide clearfix">
|
<a href="#/tools/firewall" class="list-group-item slide clearfix">
|
||||||
<span class="pull-right fa-chevron-right"></span>
|
<span class="pull-right fa-chevron-right"></span>
|
||||||
<h2 class="list-group-item-heading">{{t 'firewall'}}</h2>
|
<h2 class="list-group-item-heading">{{t 'firewall'}}</h2>
|
||||||
|
|
|
@ -10,9 +10,9 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="actions-group">
|
<div class="actions-group">
|
||||||
<a href="javascript:void(null);" onclick="c.api('/logs/display?path={{#if log.name}}{{ log.name }}{{else}}{{ log.log_path }}{{/if}}&share', function(data) { $('div.loader').remove(); window.open(data.url, '_blank'); });" class="btn btn-success">
|
<button class="btn btn-success" data-action="share" data-log-id="{{#if log.name}}{{ log.name }}{{else}}{{ log.log_path }}{{/if}}">
|
||||||
<span class="fa-cloud-upload"></span> {{t 'logs_share_with_yunopaste'}}
|
<span class="fa-cloud-upload"></span> {{t 'logs_share_with_yunopaste'}}
|
||||||
</a>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="separator"></div>
|
<div class="separator"></div>
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
<div id="collapse-{{key}}" class="panel-collapse{{#if @first}}{{else}} collapse{{/if}}" role="tabpanel" aria-labelledby="heading-{{key}}">
|
<div id="collapse-{{key}}" class="panel-collapse{{#if @first}}{{else}} collapse{{/if}}" role="tabpanel" aria-labelledby="heading-{{key}}">
|
||||||
<div class="list-group">
|
<div class="list-group">
|
||||||
{{#value}}
|
{{#value}}
|
||||||
<a href="#/tools/logs/{{ name }}" class="list-group-item" title='{{formatTime started_at day="numeric" month="long" year="numeric" hour="numeric" minute="numeric"}}'><small style="margin-right:20px;" >{{formatRelative started_at}}</small>
|
<a href="#/tools/logs/{{ name }}" class="list-group-item slide" title='{{formatTime started_at day="numeric" month="long" year="numeric" hour="numeric" minute="numeric"}}'><small style="margin-right:20px;" >{{formatRelative started_at}}</small>
|
||||||
<span class="fa-fw fa-{{success_icon}}"></span> {{ description }}</a>
|
<span class="fa-fw fa-{{success_icon}}"></span> {{ description }}</a>
|
||||||
{{/value}}
|
{{/value}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<h2 class="panel-title"><span class="fa-fw fa-cogs"></span> {{t 'migrations_pending'}}
|
<h2 class="panel-title"><span class="fa-fw fa-cogs"></span> {{t 'migrations_pending'}}
|
||||||
{{#if pending_migrations}}
|
{{#if pending_migrations}}
|
||||||
<div class="btn-toolbar pull-right">
|
<div class="btn-toolbar pull-right">
|
||||||
<a href="#/tools/migrations/run" class="btn btn-sm btn-success"><span class="fa-fw fa-play"></span> {{t 'run'}}</a>
|
<button class="btn btn-sm btn-success" data-action="run"><span class="fa-fw fa-play"></span> {{t 'run'}}</button>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</h2>
|
</h2>
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
<h3 class="list-group-item-heading">
|
<h3 class="list-group-item-heading">
|
||||||
{{ number }}. {{ description }}
|
{{ number }}. {{ description }}
|
||||||
<div class="btn-toolbar pull-right">
|
<div class="btn-toolbar pull-right">
|
||||||
<a href="#/tools/migrations/skip/{{ id }}" class="btn btn-xs btn-warning" style="color:white;"><span class="fa-fw fa-close"></span> {{t 'skip'}}</a>
|
<button class="btn btn-xs btn-warning" style="color:white;" data-action="skip" data-migration="{{id}}"><span class="fa-fw fa-close"></span> {{t 'skip'}}</button>
|
||||||
</div>
|
</div>
|
||||||
</h3>
|
</h3>
|
||||||
{{#if disclaimer }}
|
{{#if disclaimer }}
|
||||||
|
|
|
@ -1,283 +0,0 @@
|
||||||
<div class="btn-breadcrumb">
|
|
||||||
<a href="#/" ><i class="fa-home"></i><span class="sr-only">{{t 'home'}}</span></a>
|
|
||||||
<a href="#/tools">{{t 'tools'}}</a>
|
|
||||||
<a href="#/tools/monitor">{{t 'monitoring'}}</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="separator"></div>
|
|
||||||
|
|
||||||
{{#if status}}
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<h2 class="panel-title"><span class="fa-fw fa-info-circle"></span> {{t 'infos'}}</h2>
|
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
<dl class="dl-horizontal">
|
|
||||||
<dt>{{t 'hostname'}}</dt>
|
|
||||||
<dd>{{system.infos.hostname}}</dd>
|
|
||||||
<dt>{{t 'os'}}</dt>
|
|
||||||
<dd>{{ucwords system.infos.linux_distro}} {{system.infos.platform}} ({{system.infos.os_name}} {{system.infos.os_version}})</dd>
|
|
||||||
<dt>{{t 'uptime'}}</dt>
|
|
||||||
<dd>{{system.uptime}}</dd>
|
|
||||||
</dl>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<h2 class="panel-title"><span class="fa-fw fa-cogs"></span> {{t 'versions'}}</h2>
|
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
<dl class="dl-horizontal">
|
|
||||||
{{#each versions}}
|
|
||||||
<dt>{{@key}}</dt>
|
|
||||||
<dd>{{version}} ({{repo}})</dd>
|
|
||||||
{{/each}}
|
|
||||||
</dl>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="panel-group" id="accordion">
|
|
||||||
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<h2 class="panel-title">
|
|
||||||
<span class="fa-fw fa-check-square-o"></span>
|
|
||||||
<a data-toggle="collapse" data-parent="#accordion" href="#check">{{t 'check'}}</a>
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
<div id="check" class="panel-collapse collapse">
|
|
||||||
<div class="panel-body">
|
|
||||||
<dl class="dl-horizontal">
|
|
||||||
<dt>{{t 'check_stmp'}}</dt>
|
|
||||||
<dd>{{network.check.smtp_check}}</dd>
|
|
||||||
<dt>{{t 'check_mx'}}</dt>
|
|
||||||
<dd>
|
|
||||||
{{#if network.check.mx_check.mx0}}
|
|
||||||
<ul>
|
|
||||||
{{#each network.check.mx_check}}
|
|
||||||
<li>{{this}}</li>
|
|
||||||
{{/each}}
|
|
||||||
</ul>
|
|
||||||
{{else}}
|
|
||||||
{{network.check.mx_check}}
|
|
||||||
{{/if}}
|
|
||||||
</dd>
|
|
||||||
</dl>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<h2 class="panel-title">
|
|
||||||
<span class="fa-fw fa-cog"></span>
|
|
||||||
<a data-toggle="collapse" data-parent="#accordion" href="#system">{{t 'system'}}</a>
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
<div id="system" class="panel-collapse collapse">
|
|
||||||
<div class="panel-body row">
|
|
||||||
|
|
||||||
<div class="col-md-4">
|
|
||||||
<h3>{{t 'memory'}}</h3>
|
|
||||||
<h4>{{t 'ram'}}</h4>
|
|
||||||
<table class="table table-condensed">
|
|
||||||
<tr>
|
|
||||||
<td>{{t 'used'}}</td>
|
|
||||||
<td>{{humanSize system.memory.ram.used}} ({{system.memory.ram.percent}} %)</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{{t 'free'}}</td>
|
|
||||||
<td>{{humanSize system.memory.ram.free}}</td>
|
|
||||||
</tr>
|
|
||||||
<tr class="active">
|
|
||||||
<td>{{t 'total'}}</td>
|
|
||||||
<td>{{humanSize system.memory.ram.total}}</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h4>{{t 'swap'}}</h4>
|
|
||||||
<table class="table table-condensed">
|
|
||||||
<tr>
|
|
||||||
<td>{{t 'used'}}</td>
|
|
||||||
<td>{{humanSize system.memory.swap.used}} ({{system.memory.swap.percent}} %)</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{{t 'free'}}</td>
|
|
||||||
<td>{{humanSize system.memory.swap.free}}</td>
|
|
||||||
</tr>
|
|
||||||
<tr class="active">
|
|
||||||
<td>{{t 'total'}}</td>
|
|
||||||
<td>{{humanSize system.memory.swap.total}}</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-4">
|
|
||||||
<h3>{{t 'cpu_load'}}</h3>
|
|
||||||
<table class="table table-condensed">
|
|
||||||
<tr>
|
|
||||||
<td>{{t 'count_min' "1"}}</td>
|
|
||||||
<td>{{system.cpu.load.min1}}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{{t 'count_min' "5"}}</td>
|
|
||||||
<td>{{system.cpu.load.min5}}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{{t 'count_min' "15"}}</td>
|
|
||||||
<td>{{system.cpu.load.min15}}</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-4">
|
|
||||||
<h3>{{t 'process'}}</h3>
|
|
||||||
<table class="table table-condensed">
|
|
||||||
<tr>
|
|
||||||
<td>{{t 'running'}}</td>
|
|
||||||
<td>{{system.process.running}}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{{t 'sleeping'}}</td>
|
|
||||||
<td>{{system.process.sleeping}}</td>
|
|
||||||
</tr>
|
|
||||||
<tr class="active">
|
|
||||||
<td>{{t 'total'}}</td>
|
|
||||||
<td>{{system.process.total}}</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<h2 class="panel-title">
|
|
||||||
<span class="fa-fw fa-cloud"></span>
|
|
||||||
<a data-toggle="collapse" data-parent="#accordion" href="#network">{{t 'network'}}</a>
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
<div id="network" class="panel-collapse collapse">
|
|
||||||
<div class="panel-body">
|
|
||||||
<b>{{t 'public_ip'}}</b>{{network.infos.public_ip}}
|
|
||||||
<br>
|
|
||||||
<b>{{t 'gateway'}}</b>{{network.infos.gateway}}
|
|
||||||
|
|
||||||
<h3>{{t 'local_ip'}}</h3>
|
|
||||||
<table class="table table-condensed">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>{{t 'interface'}}</th>
|
|
||||||
<th>{{t 'ipv4'}}</th>
|
|
||||||
<th>{{t 'ipv6'}}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{{#each network.infos.local_ip}}
|
|
||||||
<tr>
|
|
||||||
<td>{{@key}}</td>
|
|
||||||
<td>{{ ipv4 }}</td>
|
|
||||||
<td>{{ ipv6 }}</td>
|
|
||||||
</tr>
|
|
||||||
{{/each}}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h3>{{t 'usage'}}</h3>
|
|
||||||
{{#each network.usage}}
|
|
||||||
<div class="clearfix">
|
|
||||||
<table class="table table-condensed">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
<h4>
|
|
||||||
{{@key}}
|
|
||||||
<small>{{t 'time_since_update'}}{{humanTime time_since_update}}</small>
|
|
||||||
</h4>
|
|
||||||
</th>
|
|
||||||
<th>{{t 'bit_rate'}}</th>
|
|
||||||
<th>{{t 'cumulative_usage'}}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>{{t 'transmission'}}</td>
|
|
||||||
<td>{{bitRate tx time_since_update}}</td>
|
|
||||||
<td>{{humanSize cumulative_tx}}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{{t 'reception'}}</td>
|
|
||||||
<td>{{bitRate rx time_since_update}}</td>
|
|
||||||
<td>{{humanSize cumulative_rx}}</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
{{/each}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<h2 class="panel-title">
|
|
||||||
<span class="fa-fw fa-hdd-o"></span>
|
|
||||||
<a data-toggle="collapse" data-parent="#accordion" href="#disk">{{t 'disk'}}</a>
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
<div id="disk" class="panel-collapse collapse">
|
|
||||||
<div class="panel-body">
|
|
||||||
{{#each disk}}
|
|
||||||
<div class="clearfix">
|
|
||||||
<h3>{{@key}}</h3>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-6">
|
|
||||||
<h4>{{t 'filesystem'}}</h4>
|
|
||||||
<table class="table table-condensed">
|
|
||||||
<tr>
|
|
||||||
<td>{{t 'fs_type'}}</td><td>{{ filesystem.fs_type }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{{t 'mount_point'}}</td><td>{{ filesystem.mnt_point }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{{t 'size'}}</td><td>{{humanSize filesystem.size }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{{t 'used'}}</td><td>{{humanSize filesystem.used }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr class="active">
|
|
||||||
<td>{{t 'available'}}</td><td>{{humanSize filesystem.avail }}</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<h4>{{t 'io'}} <small>{{t 'time_since_update'}}{{humanTime io.time_since_update }}</small></h4>
|
|
||||||
<table class="table table-condensed">
|
|
||||||
<tr>
|
|
||||||
<td>{{t 'read'}}</td><td>{{humanSize io.read_bytes }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{{t 'write'}}</td><td>{{humanSize io.write_bytes }}</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/each}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div><!-- .panel-group -->
|
|
||||||
|
|
||||||
{{else}}
|
|
||||||
<div class="alert alert-warning">
|
|
||||||
<span class="fa-exclamation-triangle"></span>
|
|
||||||
{{t 'monitoring_disabled'}}
|
|
||||||
<br>
|
|
||||||
{{t 'monitoring_check_glances'}}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{/if}}
|
|
|
@ -15,14 +15,14 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<p>
|
<p>
|
||||||
<a role="button" href="#/tools/reboot/reboot" class="btn btn-danger">
|
<button class="btn btn-danger" data-action="reboot">
|
||||||
<i class="fa-refresh"></i> {{t 'tools_reboot_btn'}}
|
<i class="fa-refresh"></i> {{t 'tools_reboot_btn'}}
|
||||||
</a>
|
</button>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<a role="button" href="#/tools/reboot/shutdown" class="btn btn-danger">
|
<button class="btn btn-danger" data-action="shutdown">
|
||||||
<i class="fa-power-off"></i> {{t 'tools_shutdown_btn'}}
|
<i class="fa-power-off"></i> {{t 'tools_shutdown_btn'}}
|
||||||
</a>
|
</button>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
<div class="alert alert-warning"><i class="fa-refresh"></i> {{t 'tools_rebooting'}}</div>
|
|
|
@ -1 +0,0 @@
|
||||||
<div class="alert alert-warning"><i class="fa-power-off"></i> {{t 'tools_shuttingdown'}}</div>
|
|
|
@ -20,7 +20,7 @@
|
||||||
{{/system}}
|
{{/system}}
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-footer">
|
<div class="panel-footer">
|
||||||
<a href="#/upgrade/system" role="button" class="btn btn-success">{{t 'system_upgrade_all_packages_btn'}}</a>
|
<button class="btn btn-success" data-upgrade="system">{{t 'system_upgrade_all_packages_btn'}}</button>
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
|
@ -37,14 +37,14 @@
|
||||||
<div class="list-group">
|
<div class="list-group">
|
||||||
{{#apps}}
|
{{#apps}}
|
||||||
<div class="list-group-item clearfix">
|
<div class="list-group-item clearfix">
|
||||||
|
<button class="btn btn-success pull-right" data-upgrade="{{id}}">{{t 'system_upgrade_btn'}}</button>
|
||||||
<h3 class="list-group-item-heading">{{label}} <small>{{id}}</small></h3>
|
<h3 class="list-group-item-heading">{{label}} <small>{{id}}</small></h3>
|
||||||
<span class="list-group-item-text">{{t 'from_to' current_version new_version}}</span>
|
<span class="list-group-item-text">{{t 'from_to' current_version new_version}}</span>
|
||||||
<a href="#/upgrade/apps/{{id}}" role="button" class="btn btn-success pull-right">{{t 'system_upgrade_btn'}}</a>
|
|
||||||
</div>
|
</div>
|
||||||
{{/apps}}
|
{{/apps}}
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-footer">
|
<div class="panel-footer">
|
||||||
<a role="button" href="#/upgrade/apps" class="btn btn-success">{{t 'system_upgrade_all_applications_btn'}}</a>
|
<button class="btn btn-success" data-upgrade="apps">{{t 'system_upgrade_all_applications_btn'}}</button>
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
|
@ -1,18 +0,0 @@
|
||||||
<div class="btn-breadcrumb">
|
|
||||||
<a href="#/" ><i class="fa-home"></i><span class="sr-only">{{t 'home'}}</span></a>
|
|
||||||
<a href="#/update">{{t 'system_update'}}</a>
|
|
||||||
<a href="#/upgrade">{{t 'system_upgrade'}}</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="separator"></div>
|
|
||||||
|
|
||||||
{{#if logs}}
|
|
||||||
<pre id="upgrade-log" class="upgrade-log log">
|
|
||||||
{{#logs}}
|
|
||||||
{{.}}
|
|
||||||
{{/logs}}
|
|
||||||
</pre>
|
|
||||||
<button data-paste-content="#upgrade-log"><i class="fa-cloud-upload"></i> {{t 'upload'}}</button>
|
|
||||||
{{else}}
|
|
||||||
{{t 'no_log'}}
|
|
||||||
{{/if}}
|
|
|
@ -17,10 +17,10 @@
|
||||||
<span class="label label-default label-removable">
|
<span class="label label-default label-removable">
|
||||||
<span class="fa-fw fa-{{icon}}"></span>
|
<span class="fa-fw fa-{{icon}}"></span>
|
||||||
{{text}}
|
{{text}}
|
||||||
<a role="button" data-type="{{type}}s" data-operation="remove" data-item="{{value}}" data-group="{{group}}" class="group-update">
|
<button data-type="{{type}}s" data-action="remove" data-item="{{value}}" data-group="{{group}}">
|
||||||
<span class="fa-close" style="margin-left:5px"></span>
|
<span class="fa-close" style="margin-left:5px"></span>
|
||||||
<span class="sr-only">{{t 'delete'}}</span>
|
<span class="sr-only">{{t 'delete'}}</span>
|
||||||
</a>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
{{/inline}}
|
{{/inline}}
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
{{#each inv}}
|
{{#each inv}}
|
||||||
<li><a href="#" data-type="{{../type}}s" data-operation="add" data-item="{{.}}" data-group="{{../group}}" class="group-update">{{call ../display .}}</a></li>
|
<li><button data-type="{{../type}}s" data-action="add" data-item="{{.}}" data-group="{{../group}}" >{{call ../display .}}</button></li>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -53,10 +53,10 @@
|
||||||
<span class="fa-fw fa-group"></span> {{#if special}}{{t (concat 'group_' @key)}}{{else}}{{t 'group'}} "{{ucwords @key}}"{{/if}}
|
<span class="fa-fw fa-group"></span> {{#if special}}{{t (concat 'group_' @key)}}{{else}}{{t 'group'}} "{{ucwords @key}}"{{/if}}
|
||||||
</a>
|
</a>
|
||||||
{{#unless special}}
|
{{#unless special}}
|
||||||
<a href="#/groups/{{@key}}/delete" role="button" class="group-delete">
|
<button class="group-delete" data-action="delete-group" data-group="{{@key}}">
|
||||||
<span class="fa-close"></span>
|
<span class="fa-close"></span>
|
||||||
<span class="sr-only">{{t 'delete'}}</span>
|
<span class="sr-only">{{t 'delete'}}</span>
|
||||||
</a>
|
</button>
|
||||||
{{/unless}}
|
{{/unless}}
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
|
@ -122,7 +122,7 @@
|
||||||
{{#each groups}}
|
{{#each groups}}
|
||||||
{{#if primary}}
|
{{#if primary}}
|
||||||
{{#unless (or permissions display)}}
|
{{#unless (or permissions display)}}
|
||||||
<li><a href="#" data-user="{{@key}}" class="group-add-user">{{@key}}</a></li>
|
<li><button data-action="add-user-specific-permission" data-user="{{@key}}">{{@key}}</button></li>
|
||||||
{{/unless}}
|
{{/unless}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
|
@ -62,7 +62,7 @@
|
||||||
</table>
|
</table>
|
||||||
<span class="pull-right">
|
<span class="pull-right">
|
||||||
<a role="button" href="#/users/{{username}}/edit" class="btn btn-info slide"><span class="fa-pencil-square-o"/> {{t 'user_username_edit' username}}</a>
|
<a role="button" href="#/users/{{username}}/edit" class="btn btn-info slide"><span class="fa-pencil-square-o"/> {{t 'user_username_edit' username}}</a>
|
||||||
<a role="button" href="#/users/{{username}}/delete" class="btn btn-danger slide back"><span class="fa-trash-o"/> {{t 'delete'}}</a>
|
<button class="btn btn-danger" data-action="delete" data-user="{{username}}"><span class="fa-trash-o"/> {{t 'delete'}}</a>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue