refactoring of Settings view. WIP
This commit is contained in:
@@ -150,8 +150,8 @@ export default angular.module('xoWebApp', [
|
||||
}
|
||||
|
||||
// The user must have the `admin` permission to access the
|
||||
// settings and admin pages.
|
||||
if (/^admin\..*|settings|tree$/.test(state.name)) {
|
||||
// settings pages.
|
||||
if (/^settings\..*|tree$/.test(state.name)) {
|
||||
event.preventDefault();
|
||||
notify.error({
|
||||
title: 'Restricted area',
|
||||
|
||||
@@ -105,7 +105,7 @@ nav.navbar.navbar-inverse.navbar-fixed-top(role = 'navigation')
|
||||
ui-sref-active = 'active'
|
||||
ng-class = '{ disabled: navbar.user.permission !== "admin" }'
|
||||
)
|
||||
a(ui-sref="settings")
|
||||
a(ui-sref="settings.index")
|
||||
i.fa.fa-cog
|
||||
| Settings
|
||||
li.divider
|
||||
|
||||
80
app/modules/settings/acls/index.js
Normal file
80
app/modules/settings/acls/index.js
Normal file
@@ -0,0 +1,80 @@
|
||||
import angular from 'angular';
|
||||
import uiRouter from 'angular-ui-router';
|
||||
import uiSelect from 'angular-ui-select';
|
||||
|
||||
import filter from 'lodash.filter';
|
||||
|
||||
import xoApi from 'xo-api';
|
||||
import xoServices from 'xo-services';
|
||||
|
||||
import view from './view';
|
||||
|
||||
export default angular.module('settings.acls', [
|
||||
uiRouter,
|
||||
uiSelect,
|
||||
|
||||
xoApi,
|
||||
xoServices,
|
||||
])
|
||||
.config(function ($stateProvider) {
|
||||
$stateProvider.state('settings.acls', {
|
||||
controller: 'SettingsAcls as ctrl',
|
||||
url: '/acls',
|
||||
resolve: {
|
||||
acls(xo) {
|
||||
return xo.acl.get();
|
||||
},
|
||||
users(xo) {
|
||||
return xo.user.getAll();
|
||||
},
|
||||
},
|
||||
template: view,
|
||||
});
|
||||
})
|
||||
.controller('SettingsAcls', function ($scope, acls, users, xoApi, xo) {
|
||||
this.acls = acls;
|
||||
|
||||
this.users = users;
|
||||
{
|
||||
let usersById = this.usersById = Object.create(null);
|
||||
for (let user of users) {
|
||||
usersById[user.id] = user;
|
||||
}
|
||||
}
|
||||
|
||||
this.objects = xoApi.all;
|
||||
|
||||
let refreshAcls = () => {
|
||||
xo.acl.get().then(acls => {
|
||||
this.acls = acls;
|
||||
});
|
||||
};
|
||||
|
||||
this.getUser = (id) => {
|
||||
for (let user of this.users) {
|
||||
if (user.id === id) {
|
||||
return user;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.addAcl = () => {
|
||||
xo.acl.add(this.subject.id, this.object.id).then(refreshAcls);
|
||||
};
|
||||
this.removeAcl = (subject, object) => {
|
||||
xo.acl.remove(subject, object).then(refreshAcls);
|
||||
};
|
||||
})
|
||||
.filter('selectHighLevel', () => {
|
||||
const HIGH_LEVEL_OBJECTS = {
|
||||
pool: true,
|
||||
host: true,
|
||||
VM: true,
|
||||
SR: true,
|
||||
};
|
||||
let isHighLevel = (object) => HIGH_LEVEL_OBJECTS[object.type];
|
||||
|
||||
return (objects) => filter(objects, isHighLevel);
|
||||
})
|
||||
.name
|
||||
;
|
||||
14
app/modules/settings/acls/view.jade
Normal file
14
app/modules/settings/acls/view.jade
Normal file
@@ -0,0 +1,14 @@
|
||||
//- .container-fluid: .row
|
||||
|
||||
//- //- Side menu
|
||||
//- .col-md-2.acl-menu: .panel.panel-default: .panel-body: .side-menu
|
||||
//- ul.nav
|
||||
//- li
|
||||
//- a(ui-sref = '.acls', ui-sref-active = 'active')
|
||||
//- i.fa.fa-fw.fa-users
|
||||
//- | ACLs
|
||||
|
||||
//- //- Content
|
||||
//- .col-md-10: div(ui-view = '')
|
||||
|
||||
div(ui-view = '')
|
||||
@@ -1,179 +0,0 @@
|
||||
angular = require 'angular'
|
||||
|
||||
#=====================================================================
|
||||
|
||||
# FIXME: Mutualize the code between users and servers.
|
||||
|
||||
# FIXME: should be merged in admin module.
|
||||
|
||||
module.exports = angular.module 'xoWebApp.settings', [
|
||||
require 'angular-ui-router'
|
||||
]
|
||||
.config ($stateProvider) ->
|
||||
$stateProvider.state 'settings',
|
||||
url: '/settings'
|
||||
controller: 'SettingsCtrl'
|
||||
template: require './view'
|
||||
.controller 'SettingsCtrl', ($scope, xo) ->
|
||||
$scope.permissions = [
|
||||
{
|
||||
label: 'User'
|
||||
value: 'none'
|
||||
}
|
||||
{
|
||||
label: 'Admin'
|
||||
value: 'admin'
|
||||
}
|
||||
]
|
||||
|
||||
# Users
|
||||
do ->
|
||||
# Fetches them.
|
||||
$scope.users = []
|
||||
xo.user.getAll().then (users) ->
|
||||
$scope.users = users
|
||||
|
||||
# Which ones are selected?
|
||||
selected = $scope.selectedUsers = {}
|
||||
|
||||
# New users to create.
|
||||
$scope.newUsers = []
|
||||
|
||||
# Add a new user to be created.
|
||||
$scope.addUser = ->
|
||||
$scope.newUsers.push {
|
||||
# Fake (unique) identifier needed by Angular.JS
|
||||
id: Math.random()
|
||||
|
||||
# Default permission.
|
||||
permission: 'none'
|
||||
}
|
||||
$scope.addUser()
|
||||
|
||||
# Saves any modifications.
|
||||
$scope.saveUsers = ->
|
||||
{users, newUsers} = $scope
|
||||
|
||||
# This will be the new list of users with those marked to
|
||||
# delete removed.
|
||||
updateUsers = []
|
||||
|
||||
for user in users
|
||||
{id} = user
|
||||
if selected[id]
|
||||
delete selected[id]
|
||||
|
||||
# FIXME: this cast should not be necessary.
|
||||
xo.user.delete "#{id}"
|
||||
else
|
||||
# Only sets the password if not empty.
|
||||
delete user.password unless user.password
|
||||
|
||||
# TODO: only update users which have been modified.
|
||||
xo.user.set user
|
||||
|
||||
# Remove the password from the interface.
|
||||
delete user.password
|
||||
|
||||
updateUsers.push user
|
||||
|
||||
for user in newUsers
|
||||
{email, permission, password} = user
|
||||
|
||||
# Required field.
|
||||
continue unless email
|
||||
|
||||
# Sends the order to XO-Server.
|
||||
xo.user.create {email, permission, password}
|
||||
.then (id) ->
|
||||
# Update user identifier.
|
||||
user.id = id
|
||||
return
|
||||
|
||||
# The password should not be displayed.
|
||||
delete user.password
|
||||
|
||||
# Adds the user to out local list.
|
||||
updateUsers.push user
|
||||
|
||||
$scope.users = updateUsers
|
||||
$scope.newUsers = []
|
||||
$scope.addUser()
|
||||
|
||||
# TODO: Retrieves an up to date users list from the server.
|
||||
|
||||
# Servers
|
||||
do ->
|
||||
# Fetches them.
|
||||
$scope.servers = []
|
||||
|
||||
refreshServers = ->
|
||||
xo.server.getAll().then (servers) ->
|
||||
$scope.servers = servers
|
||||
refreshServers()
|
||||
|
||||
# Which ones are selected?
|
||||
selected = $scope.selectedServers = {}
|
||||
|
||||
# New servers to create.
|
||||
$scope.newServers = []
|
||||
|
||||
# Add a new server to be created.
|
||||
$scope.addServer = ->
|
||||
$scope.newServers.push {
|
||||
# Fake (unique) identifier needed by Angular.JS
|
||||
id: Math.random()
|
||||
}
|
||||
$scope.addServer()
|
||||
|
||||
# Saves any modifications.
|
||||
$scope.saveServers = ->
|
||||
{servers, newServers} = $scope
|
||||
|
||||
# This will be the new list of servers with those marked to
|
||||
# delete removed.
|
||||
updateServers = []
|
||||
|
||||
for server in servers
|
||||
{id} = server
|
||||
if selected[id]
|
||||
delete selected[id]
|
||||
xo.server.remove id
|
||||
else
|
||||
# Only sets the password if not empty.
|
||||
delete server.password unless server.password
|
||||
|
||||
# TODO: only update servers which have been modified.
|
||||
xo.server.set server
|
||||
|
||||
# Remove the password from the interface.
|
||||
delete server.password
|
||||
|
||||
updateServers.push server
|
||||
|
||||
for server in newServers
|
||||
{host, username, password} = server
|
||||
|
||||
# Required field.
|
||||
continue unless host
|
||||
|
||||
# Sends the order to XO-Server.
|
||||
xo.server.add {host, username, password}
|
||||
.then (id) ->
|
||||
server.id = id
|
||||
return
|
||||
|
||||
# The password should not be displayed.
|
||||
delete server.password
|
||||
|
||||
# Adds the server to out local list.
|
||||
updateServers.push server
|
||||
|
||||
$scope.servers = updateServers
|
||||
$scope.newServers = []
|
||||
$scope.addServer()
|
||||
|
||||
# TODO: Retrieves an up to date servers list from the server.
|
||||
|
||||
# A module exports its name.
|
||||
.name
|
||||
33
app/modules/settings/index.js
Normal file
33
app/modules/settings/index.js
Normal file
@@ -0,0 +1,33 @@
|
||||
import angular from 'angular';
|
||||
import uiRouter from 'angular-ui-router';
|
||||
|
||||
import acls from './acls';
|
||||
import servers from './servers';
|
||||
import users from './users';
|
||||
|
||||
import view from './view';
|
||||
|
||||
export default angular.module('settings', [
|
||||
uiRouter,
|
||||
|
||||
acls,
|
||||
servers,
|
||||
users,
|
||||
])
|
||||
.config(function ($stateProvider) {
|
||||
$stateProvider.state('settings', {
|
||||
abstract: true,
|
||||
template: view,
|
||||
url: '/settings',
|
||||
});
|
||||
|
||||
// Redirect to default sub-state.
|
||||
$stateProvider.state('settings.index', {
|
||||
url: '',
|
||||
controller: function ($state) {
|
||||
$state.go('settings.servers');
|
||||
}
|
||||
});
|
||||
})
|
||||
.name
|
||||
;
|
||||
106
app/modules/settings/servers/index.js
Normal file
106
app/modules/settings/servers/index.js
Normal file
@@ -0,0 +1,106 @@
|
||||
import angular from 'angular';
|
||||
import uiRouter from 'angular-ui-router';
|
||||
import uiSelect from 'angular-ui-select';
|
||||
|
||||
import filter from 'lodash.filter';
|
||||
|
||||
import xoApi from 'xo-api';
|
||||
import xoServices from 'xo-services';
|
||||
|
||||
import view from './view';
|
||||
|
||||
export default angular.module('settings.servers', [
|
||||
uiRouter,
|
||||
uiSelect,
|
||||
|
||||
xoApi,
|
||||
xoServices,
|
||||
])
|
||||
.config(function ($stateProvider) {
|
||||
$stateProvider.state('settings.servers', {
|
||||
controller: 'SettingsServers as ctrl',
|
||||
url: '/servers',
|
||||
resolve: {
|
||||
servers(xo) {
|
||||
return xo.server.getAll();
|
||||
},
|
||||
},
|
||||
template: view,
|
||||
});
|
||||
})
|
||||
.controller('SettingsServers', function ($scope, $interval, servers, xoApi, xo, notify) {
|
||||
this.servers = servers;
|
||||
const selected = this.selectedServers = {};
|
||||
const newServers = this.newServers = [];
|
||||
|
||||
const refreshServers = () => {
|
||||
xo.server.getAll().then(servers => {
|
||||
this.servers = servers;
|
||||
});
|
||||
};
|
||||
|
||||
const interval = $interval(refreshServers, 5e3)
|
||||
$scope.$on('$destroy', () => {
|
||||
$interval.cancel(interval)
|
||||
})
|
||||
|
||||
this.addServer = () => {
|
||||
newServers.push({
|
||||
// Fake (unique) id needed by Angular.JS
|
||||
id: Math.random(),
|
||||
status: 'connecting'
|
||||
});
|
||||
};
|
||||
|
||||
this.addServer();
|
||||
this.saveServers = () => {
|
||||
const newServers = this.newServers;
|
||||
const servers = this.servers;
|
||||
const updateServers = [];
|
||||
|
||||
for (let i = 0, len = servers.length; i < len; i++) {
|
||||
const server = servers[i];
|
||||
const {id} = server;
|
||||
if (selected[id]) {
|
||||
delete selected[id];
|
||||
xo.server.remove(id);
|
||||
}
|
||||
else {
|
||||
if (!server.password) {
|
||||
delete server.password;
|
||||
}
|
||||
xo.server.set(server);
|
||||
delete server.password;
|
||||
updateServers.push(server);
|
||||
}
|
||||
}
|
||||
for (let i = 0, len = newServers.length; i < len; i++) {
|
||||
const server = newServers[i];
|
||||
const {host, username, password} = server;
|
||||
if (!host) {
|
||||
continue;
|
||||
}
|
||||
xo.server.add({
|
||||
host,
|
||||
username,
|
||||
password,
|
||||
autoConnect: false,
|
||||
}).then(function(id) {
|
||||
server.id = id;
|
||||
xo.server.connect(id).catch(error => {
|
||||
notify.error({
|
||||
title: 'Server connection error',
|
||||
message: error.message
|
||||
});
|
||||
});
|
||||
});
|
||||
delete server.password;
|
||||
updateServers.push(server);
|
||||
}
|
||||
this.servers = updateServers;
|
||||
this.newServers.length = 0;
|
||||
this.addServer();
|
||||
};
|
||||
})
|
||||
.name
|
||||
;
|
||||
58
app/modules/settings/servers/view.jade
Normal file
58
app/modules/settings/servers/view.jade
Normal file
@@ -0,0 +1,58 @@
|
||||
.grid
|
||||
.panel.panel-default
|
||||
.panel-heading.panel-title
|
||||
i.fa.fa-cloud(style="color: #e25440;")
|
||||
| Servers
|
||||
form(ng-submit="ctrl.saveServers()", autocomplete="off").panel-body
|
||||
table.table.table-hover
|
||||
tr
|
||||
th.col-md-5 Host
|
||||
th.col-md-3 User
|
||||
th.col-md-3 Password
|
||||
th.col-md-1.text-center
|
||||
i.fa.fa-trash-o.fa-lg(tooltip="Forget server")
|
||||
tr(ng-repeat="server in ctrl.servers | orderBy:natural('host') track by server.id")
|
||||
td
|
||||
.input-group
|
||||
span.input-group-addon(ng-if="server.status === 'connected'")
|
||||
i.fa.fa-check-circle.fa-lg.text-success(tooltip="Connected")
|
||||
span.input-group-addon(ng-if="server.status === 'disconnected'")
|
||||
i.fa.fa-times-circle.fa-lg.text-danger(tooltip="Disconnected")
|
||||
span.input-group-addon(ng-if="server.status === 'connecting'")
|
||||
i.fa.fa-cog.fa-lg.fa-spin(tooltip="Connecting...")
|
||||
input.form-control(type="text", ng-model="server.host")
|
||||
td
|
||||
input.form-control(type="text", ng-model="server.username")
|
||||
td
|
||||
input.form-control(type="password", ng-model="server.password", placeholder="Fill to change the password")
|
||||
td.text-center
|
||||
input(type="checkbox", ng-model="ctrl.selectedServers[server.id]")
|
||||
tr(ng-repeat="server in ctrl.newServers")
|
||||
td
|
||||
input.form-control(
|
||||
type = "text"
|
||||
ng-model = "server.host"
|
||||
placeholder = "address[:port]"
|
||||
)
|
||||
td
|
||||
input.form-control(
|
||||
type = "text"
|
||||
ng-model = "server.username"
|
||||
ng-required = "server.host"
|
||||
placeholder = "user"
|
||||
)
|
||||
td
|
||||
input.form-control(
|
||||
type="password"
|
||||
ng-model="server.password"
|
||||
ng-required = "server.host"
|
||||
placeholder="password"
|
||||
)
|
||||
td  
|
||||
p.text-center
|
||||
button.btn.btn-primary(type="submit")
|
||||
i.fa.fa-save
|
||||
| Save
|
||||
|
|
||||
button.btn.btn-success(type="button", ng-click="ctrl.addServer()")
|
||||
i.fa.fa-plus
|
||||
35
app/modules/settings/users/index.js
Normal file
35
app/modules/settings/users/index.js
Normal file
@@ -0,0 +1,35 @@
|
||||
import angular from 'angular';
|
||||
import uiRouter from 'angular-ui-router';
|
||||
import uiSelect from 'angular-ui-select';
|
||||
|
||||
import filter from 'lodash.filter';
|
||||
|
||||
import xoApi from 'xo-api';
|
||||
import xoServices from 'xo-services';
|
||||
|
||||
import view from './view';
|
||||
|
||||
export default angular.module('settings.users', [
|
||||
uiRouter,
|
||||
uiSelect,
|
||||
|
||||
xoApi,
|
||||
xoServices,
|
||||
])
|
||||
.config(function ($stateProvider) {
|
||||
$stateProvider.state('settings.users', {
|
||||
controller: 'SettingsUsers as ctrl',
|
||||
url: '/users',
|
||||
resolve: {
|
||||
users(xo) {
|
||||
return xo.acl.get();
|
||||
},
|
||||
},
|
||||
template: view,
|
||||
});
|
||||
})
|
||||
.controller('SettingsUsers', function ($scope, users, xoApi, xo) {
|
||||
this.users = users;
|
||||
})
|
||||
.name
|
||||
;
|
||||
50
app/modules/settings/users/view.jade
Normal file
50
app/modules/settings/users/view.jade
Normal file
@@ -0,0 +1,50 @@
|
||||
.grid
|
||||
.panel.panel-default
|
||||
.panel-heading.panel-title
|
||||
i.fa.fa-users(style="color: #e25440;")
|
||||
| Users
|
||||
form(ng-submit="saveUsers()", autocomplete="off").panel-body
|
||||
table.table.table-hover
|
||||
tr
|
||||
th.col-md-4 Email
|
||||
th.col-md-4 Permissions
|
||||
th.col-md-3 Password
|
||||
th.col-md-1.text-center
|
||||
i.fa.fa-trash-o.fa-lg(tooltip="Remove user")
|
||||
tr(ng-repeat="user in users | orderBy:natural('email') track by user.id")
|
||||
td
|
||||
input.form-control(type="text", ng-model="user.email")
|
||||
td
|
||||
select.form-control(ng-options="p.value as p.label for p in permissions", ng-model="user.permission")
|
||||
td
|
||||
input.form-control(type="password", ng-model="user.password", placeholder="Fill to change the password")
|
||||
td.text-center
|
||||
input(type="checkbox", ng-model="selectedUsers[user.id]")
|
||||
tr(ng-repeat="user in newUsers")
|
||||
td
|
||||
input.form-control(
|
||||
type = "text"
|
||||
ng-model = "user.email"
|
||||
placeholder = "email"
|
||||
)
|
||||
td
|
||||
select.form-control(
|
||||
ng-options = "p.value as p.label for p in permissions"
|
||||
ng-model = "user.permission"
|
||||
ng-required = "user.email"
|
||||
)
|
||||
td
|
||||
input.form-control(
|
||||
type = "password"
|
||||
ng-model = "user.password"
|
||||
ng-required = "user.email"
|
||||
placeholder = "password"
|
||||
)
|
||||
td  
|
||||
p.text-center
|
||||
button.btn.btn-primary(type="submit")
|
||||
i.fa.fa-save
|
||||
| Save
|
||||
|
|
||||
button.btn.btn-success(type="button", ng-click="addUser()")
|
||||
i.fa.fa-plus
|
||||
@@ -1,114 +1,17 @@
|
||||
//- TODO: lots of stuff.
|
||||
.grid
|
||||
.panel.panel-default
|
||||
p.page-title
|
||||
i.fa.fa-cog
|
||||
| XO Settings
|
||||
//- Add server panel
|
||||
.grid
|
||||
.panel.panel-default
|
||||
.panel-heading.panel-title
|
||||
i.fa.fa-cloud(style="color: #e25440;")
|
||||
| Servers
|
||||
form(ng-submit="saveServers()", autocomplete="off").panel-body
|
||||
table.table.table-hover
|
||||
tr
|
||||
th.col-md-5 Host
|
||||
th.col-md-3 User
|
||||
th.col-md-3 Password
|
||||
th.col-md-1.text-center
|
||||
i.fa.fa-trash-o.fa-lg(tooltip="Forget server")
|
||||
tr(ng-repeat="server in servers | orderBy:natural('host') track by server.id")
|
||||
td
|
||||
.input-group
|
||||
span.input-group-addon(ng-if="server.status === 'connected'")
|
||||
i.fa.fa-check-circle.fa-lg.text-success(tooltip="Connected")
|
||||
span.input-group-addon(ng-if="server.status === 'disconnected'")
|
||||
i.fa.fa-times-circle.fa-lg.text-danger(tooltip="Disconnected")
|
||||
span.input-group-addon(ng-if="server.status === 'connecting'")
|
||||
i.fa.fa-circleo-notch.fa-lg.fa-spin(tooltip="Connecting...")
|
||||
input.form-control(type="text", ng-model="server.host")
|
||||
td
|
||||
input.form-control(type="text", ng-model="server.username")
|
||||
td
|
||||
input.form-control(type="password", ng-model="server.password", placeholder="Fill to change the password")
|
||||
td.text-center
|
||||
input(type="checkbox", ng-model="selectedServers[server.id]")
|
||||
tr(ng-repeat="server in newServers")
|
||||
td
|
||||
input.form-control(
|
||||
type = "text"
|
||||
ng-model = "server.host"
|
||||
placeholder = "address[:port]"
|
||||
)
|
||||
td
|
||||
input.form-control(
|
||||
type = "text"
|
||||
ng-model = "server.username"
|
||||
ng-required = "server.host"
|
||||
placeholder = "user"
|
||||
)
|
||||
td
|
||||
input.form-control(
|
||||
type="password"
|
||||
ng-model="server.password"
|
||||
ng-required = "server.host"
|
||||
placeholder="password"
|
||||
)
|
||||
td  
|
||||
p.text-center
|
||||
button.btn.btn-primary(type="submit")
|
||||
i.fa.fa-save
|
||||
| Save
|
||||
|
|
||||
button.btn.btn-success(type="button", ng-click="addServer()")
|
||||
i.fa.fa-plus
|
||||
.panel.panel-default
|
||||
.panel-heading.panel-title
|
||||
i.fa.fa-users(style="color: #e25440;")
|
||||
| Users
|
||||
form(ng-submit="saveUsers()", autocomplete="off").panel-body
|
||||
table.table.table-hover
|
||||
tr
|
||||
th.col-md-4 Email
|
||||
th.col-md-4 Permissions
|
||||
th.col-md-3 Password
|
||||
th.col-md-1.text-center
|
||||
i.fa.fa-trash-o.fa-lg(tooltip="Remove user")
|
||||
tr(ng-repeat="user in users | orderBy:natural('email') track by user.id")
|
||||
td
|
||||
input.form-control(type="text", ng-model="user.email")
|
||||
td
|
||||
select.form-control(ng-options="p.value as p.label for p in permissions", ng-model="user.permission")
|
||||
td
|
||||
input.form-control(type="password", ng-model="user.password", placeholder="Fill to change the password")
|
||||
td.text-center
|
||||
input(type="checkbox", ng-model="selectedUsers[user.id]")
|
||||
tr(ng-repeat="user in newUsers")
|
||||
td
|
||||
input.form-control(
|
||||
type = "text"
|
||||
ng-model = "user.email"
|
||||
placeholder = "email"
|
||||
)
|
||||
td
|
||||
select.form-control(
|
||||
ng-options = "p.value as p.label for p in permissions"
|
||||
ng-model = "user.permission"
|
||||
ng-required = "user.email"
|
||||
)
|
||||
td
|
||||
input.form-control(
|
||||
type = "password"
|
||||
ng-model = "user.password"
|
||||
ng-required = "user.email"
|
||||
placeholder = "password"
|
||||
)
|
||||
td  
|
||||
p.text-center
|
||||
button.btn.btn-primary(type="submit")
|
||||
i.fa.fa-save
|
||||
| Save
|
||||
|
|
||||
button.btn.btn-success(type="button", ng-click="addUser()")
|
||||
i.fa.fa-plus
|
||||
//- Side menu
|
||||
.settings-menu
|
||||
ul.nav
|
||||
li
|
||||
a(ui-sref = '.servers', ui-sref-active = 'active')
|
||||
i.fa.fa-fw.fa-cloud
|
||||
| Servers
|
||||
a(ui-sref = '.users')
|
||||
i.fa.fa-fw.fa-users
|
||||
| Users
|
||||
a(ui-sref = '.acls')
|
||||
i.fa.fa-fw.fa-key
|
||||
| ACLs
|
||||
|
||||
//- Content
|
||||
div.settings-content(ui-view = '')
|
||||
|
||||
@@ -118,7 +118,7 @@ div(ng-if="!pools.length")
|
||||
h1 Welcome on Xen Orchestra!
|
||||
h3 It seems you aren't connected to any Xen server:
|
||||
br
|
||||
a.btn.btn-success.big(ui-sref="settings")
|
||||
a.btn.btn-success.big(ui-sref="settings.index")
|
||||
i.fa.fa-plus-circle
|
||||
| Add server
|
||||
br
|
||||
|
||||
3
app/node_modules/xo-services/index.coffee
generated
vendored
3
app/node_modules/xo-services/index.coffee
generated
vendored
@@ -88,6 +88,7 @@ module.exports = angular.module 'xoWebApp.services', [
|
||||
argsMapper: (subject, object) => {subject, object},
|
||||
})
|
||||
|
||||
|
||||
pool:
|
||||
disconnect: action 'Disconnect pool'
|
||||
new_sr: action 'New SR' #temp fix before creating SR
|
||||
@@ -124,6 +125,8 @@ module.exports = angular.module 'xoWebApp.services', [
|
||||
set: action 'Save server', 'server.set', {
|
||||
argsMapper: (params) -> angular.copy(params)
|
||||
}
|
||||
connect: action 'Connect to a server', 'server.connect', notification: false, argsMapper: (id) -> {id}
|
||||
disconnect: action 'Disconnect from a server', 'server.disconnect', argsMapper: (id) -> {id}
|
||||
|
||||
task:
|
||||
cancel: action 'Cancel task', 'task.cancel', argsMapper: (id) -> {id}
|
||||
|
||||
@@ -605,3 +605,37 @@ img.navbar-logo {
|
||||
font-variant: small-caps;
|
||||
padding-top: 0.8em;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Settings
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
.settings-menu {
|
||||
position: fixed;
|
||||
padding-top: 1em;
|
||||
top: 51px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1000;
|
||||
display: block;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */
|
||||
background-color: #242628;
|
||||
border-right: 1px solid #eee;
|
||||
width: 212px;
|
||||
}
|
||||
|
||||
.settings-menu li a {
|
||||
font-size: 1em;
|
||||
padding-: 1em;
|
||||
padding-left: 2em;
|
||||
display: block;
|
||||
color: #f8f8f8;
|
||||
&:hover, &:focus {
|
||||
background-color: #2e3133;
|
||||
}
|
||||
}
|
||||
|
||||
.settings-content {
|
||||
margin-left: 212px;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user