mirror of
https://github.com/dkmstr/openuds.git
synced 2025-03-20 06:50:23 +03:00
Fixed 0024 migration to include also tags
Started accounts admin gui
This commit is contained in:
parent
4401985f3c
commit
5897cf33f2
75
server/src/uds/REST/methods/accounts.py
Normal file
75
server/src/uds/REST/methods/accounts.py
Normal file
@ -0,0 +1,75 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@itemor: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _, ugettext
|
||||
from uds.models import Account, AccountUsage
|
||||
from uds.core.util import permissions
|
||||
|
||||
from uds.REST.model import ModelHandler
|
||||
|
||||
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Enclosed methods under /item path
|
||||
|
||||
|
||||
class Accounts(ModelHandler):
|
||||
'''
|
||||
Processes REST requests about calendars
|
||||
'''
|
||||
model = Account
|
||||
detail = {'usage': AccountUsage}
|
||||
|
||||
save_fields = ['name', 'comments', 'tags']
|
||||
|
||||
table_title = _('Accounts')
|
||||
table_fields = [
|
||||
{'name': {'title': _('Name'), 'visible': True, 'type': 'iconType'}},
|
||||
{'comments': {'title': _('Comments')}},
|
||||
{'tags': {'title': _('tags'), 'visible': False}},
|
||||
]
|
||||
|
||||
def item_as_dict(self, calendar):
|
||||
return {
|
||||
'id': calendar.uuid,
|
||||
'name': calendar.name,
|
||||
'tags': [tag.tag for tag in calendar.tags.all()],
|
||||
'comments': calendar.comments,
|
||||
'permission': permissions.getEffectivePermission(self._user, calendar)
|
||||
}
|
||||
|
||||
def getGui(self, type_):
|
||||
return self.addDefaultFields([], ['name', 'comments', 'tags'])
|
@ -33,7 +33,7 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.utils.translation import ugettext, ugettext_lazy as _
|
||||
from uds.models import DeployedService, OSManager, Service, Image, ServicesPoolGroup
|
||||
from uds.models import DeployedService, OSManager, Service, Image, ServicesPoolGroup, Account
|
||||
from uds.models.CalendarAction import CALENDAR_ACTION_INITIAL, CALENDAR_ACTION_MAX, CALENDAR_ACTION_CACHE_L1, CALENDAR_ACTION_CACHE_L2, CALENDAR_ACTION_PUBLISH
|
||||
from uds.core.ui.images import DEFAULT_THUMB_BASE64
|
||||
from uds.core.util.State import State
|
||||
@ -69,7 +69,21 @@ class ServicesPools(ModelHandler):
|
||||
'actions': ActionsCalendars
|
||||
}
|
||||
|
||||
save_fields = ['name', 'comments', 'tags', 'service_id', 'osmanager_id', 'image_id', 'servicesPoolGroup_id', 'initial_srvs', 'cache_l1_srvs', 'cache_l2_srvs', 'max_srvs', 'show_transports']
|
||||
save_fields = [
|
||||
'name',
|
||||
'comments',
|
||||
'tags',
|
||||
'service_id',
|
||||
'osmanager_id',
|
||||
'image_id',
|
||||
'account_id',
|
||||
'servicesPoolGroup_id',
|
||||
'initial_srvs',
|
||||
'cache_l1_srvs',
|
||||
'cache_l2_srvs',
|
||||
'max_srvs',
|
||||
'show_transports'
|
||||
]
|
||||
remove_fields = ['osmanager_id', 'service_id']
|
||||
|
||||
table_title = _('Service Pools')
|
||||
@ -116,10 +130,12 @@ class ServicesPools(ModelHandler):
|
||||
'comments': item.comments,
|
||||
'state': state,
|
||||
'thumb': item.image.thumb64 if item.image is not None else DEFAULT_THUMB_BASE64,
|
||||
'account': item.account.name if item.account is not None else '',
|
||||
'service_id': item.service.uuid,
|
||||
'provider_id': item.service.provider.uuid,
|
||||
'image_id': item.image.uuid if item.image is not None else None,
|
||||
'servicesPoolGroup_id': poolGroupId,
|
||||
'account_id': item.account.uuid if item.account is not None else None,
|
||||
'pool_group_name': poolGroupName,
|
||||
'pool_group_thumb': poolGroupThumb,
|
||||
'initial_srvs': item.initial_srvs,
|
||||
@ -165,13 +181,20 @@ class ServicesPools(ModelHandler):
|
||||
'type': gui.InputField.CHOICE_TYPE,
|
||||
'rdonly': True,
|
||||
'order': 101,
|
||||
}, {
|
||||
'name': 'account_id',
|
||||
'values': [gui.choiceItem(-1, '')] + gui.sortedChoices([gui.choiceItem(v.uuid, v.name) for v in Account.objects.all()]),
|
||||
'label': ugettext('Account'),
|
||||
'tooltip': ugettext('Account associated to this service pool'),
|
||||
'type': gui.InputField.CHOICE_TYPE,
|
||||
'order': 102,
|
||||
}, {
|
||||
'name': 'image_id',
|
||||
'values': [gui.choiceImage(-1, '--------', DEFAULT_THUMB_BASE64)] + gui.sortedChoices([gui.choiceImage(v.uuid, v.name, v.thumb64) for v in Image.objects.all()]),
|
||||
'label': ugettext('Associated Image'),
|
||||
'tooltip': ugettext('Image assocciated with this service'),
|
||||
'type': gui.InputField.IMAGECHOICE_TYPE,
|
||||
'order': 102,
|
||||
'order': 105,
|
||||
'tab': ugettext('Display'),
|
||||
}, {
|
||||
'name': 'servicesPoolGroup_id',
|
||||
@ -179,7 +202,7 @@ class ServicesPools(ModelHandler):
|
||||
'label': ugettext('Pool group'),
|
||||
'tooltip': ugettext('Pool group for this pool (for pool clasify on display)'),
|
||||
'type': gui.InputField.IMAGECHOICE_TYPE,
|
||||
'order': 103,
|
||||
'order': 106,
|
||||
'tab': ugettext('Display'),
|
||||
}, {
|
||||
'name': 'initial_srvs',
|
||||
@ -270,6 +293,18 @@ class ServicesPools(ModelHandler):
|
||||
# If max < initial or cache_1 or cache_l2
|
||||
fields['max_srvs'] = max((int(fields['initial_srvs']), int(fields['cache_l1_srvs']), int(fields['max_srvs'])))
|
||||
|
||||
|
||||
accountId = fields['account_id']
|
||||
fields['account_id'] = None
|
||||
logger.debug('Account id: {}'.format(accountId))
|
||||
|
||||
if accountId != '-1':
|
||||
try:
|
||||
fields['account_id'] = Account.objects.get(uuid=processUuid(accountId)).id
|
||||
except Exception:
|
||||
logger.exception('Getting account ID')
|
||||
|
||||
|
||||
imgId = fields['image_id']
|
||||
fields['image_id'] = None
|
||||
logger.debug('Image id: {}'.format(imgId))
|
||||
|
@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10 on 2016-10-10 07:53
|
||||
# Generated by Django 1.10.5 on 2017-01-17 08:45
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import datetime
|
||||
@ -21,6 +21,7 @@ class Migration(migrations.Migration):
|
||||
('uuid', models.CharField(default=None, max_length=50, null=True, unique=True)),
|
||||
('name', models.CharField(db_index=True, max_length=128)),
|
||||
('comments', models.CharField(max_length=256)),
|
||||
('tags', models.ManyToManyField(to='uds.Tag')),
|
||||
],
|
||||
options={
|
||||
'db_table': 'uds_accounts',
|
@ -31,11 +31,12 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
__updated__ = '2016-09-21'
|
||||
__updated__ = '2017-01-17'
|
||||
|
||||
from django.db import models
|
||||
|
||||
from uds.models.UUIDModel import UUIDModel
|
||||
from uds.models.Tag import TaggingMixin
|
||||
from uds.models.Util import getSqlDatetime
|
||||
from django.db.models import signals
|
||||
|
||||
@ -44,11 +45,9 @@ import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Account(UUIDModel):
|
||||
class Account(UUIDModel, TaggingMixin):
|
||||
'''
|
||||
Account storing on DB model
|
||||
This is intended for small images (i will limit them to 128x128), so storing at db is fine
|
||||
|
||||
'''
|
||||
name = models.CharField(max_length=128, unique=False, db_index=True)
|
||||
comments = models.CharField(max_length=256)
|
||||
|
@ -57,7 +57,7 @@ import six
|
||||
import pickle
|
||||
import logging
|
||||
|
||||
__updated__ = '2017-01-12'
|
||||
__updated__ = '2017-01-17'
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@ -368,7 +368,7 @@ class UserService(UUIDModel):
|
||||
# 1.- If do not have any account associated, do nothing
|
||||
# 2.- If called but already accounting, do nothing
|
||||
# 3.- If called and not accounting, start accounting
|
||||
if self.deployed_service.account is None or hasattr(self, 'accounting'):
|
||||
if self.deployed_service.account is None or hasattr(self, 'accounting'): # accounting comes from AccountUsage, and is a OneToOneRelation with UserService
|
||||
return
|
||||
|
||||
self.deployed_service.account.startUsageAccounting(self)
|
||||
|
@ -444,6 +444,7 @@ api.sPoolGroups = new BasicModelRest("gallery/servicespoolgroups")
|
||||
api.system = new BasicModelRest("system")
|
||||
api.reports = new BasicModelRest("reports") # Not fully used, but basic usage is common
|
||||
api.calendars = new BasicModelRest("calendars")
|
||||
api.accounts = new BasicModelRest("accounts")
|
||||
|
||||
# In fact, reports do not have any type
|
||||
api.reports.types = (success_fnc, fail_fnc) ->
|
||||
|
439
server/src/uds/static/adm/js/gui-d-account.coffee
Normal file
439
server/src/uds/static/adm/js/gui-d-account.coffee
Normal file
@ -0,0 +1,439 @@
|
||||
# jshint strict: true
|
||||
gui.accounts = new GuiElement(api.accounts, "accounts")
|
||||
gui.accounts.link = (event) ->
|
||||
"use strict"
|
||||
|
||||
# Button definition to trigger "Test" action
|
||||
testButton = testButton:
|
||||
text: gettext("Test")
|
||||
css: "btn-info"
|
||||
|
||||
|
||||
# Clears the log of the detail, in this case, the log of "users"
|
||||
# Memory saver :-)
|
||||
detailLogTable = null
|
||||
clearDetailLog = ->
|
||||
if detailLogTable?
|
||||
$tbl = $(detailLogTable).dataTable()
|
||||
$tbl.fnClearTable()
|
||||
$tbl.fnDestroy()
|
||||
detailLogTable = null
|
||||
$("#users-log-placeholder").empty()
|
||||
return
|
||||
|
||||
|
||||
# Clears the details
|
||||
# Memory saver :-)
|
||||
prevTables = []
|
||||
clearDetails = ->
|
||||
clearDetailLog()
|
||||
|
||||
$.each prevTables, (undefined_, tbl) ->
|
||||
$tbl = $(tbl).dataTable()
|
||||
$tbl.fnClearTable()
|
||||
$tbl.fnDestroy()
|
||||
return
|
||||
|
||||
$("#users-placeholder").empty()
|
||||
$("#groups-placeholder").empty()
|
||||
$("#logs-placeholder").empty()
|
||||
$("#detail-placeholder").addClass "hidden"
|
||||
prevTables = []
|
||||
return
|
||||
|
||||
|
||||
# Search button event generator for user/group
|
||||
searchForm = (parentModalId, type, id, title, searchLabel, resultsLabel) ->
|
||||
errorModal = gui.failRequestModalFnc(gettext("Search error"))
|
||||
srcSelector = parentModalId + " input[name=\"name\"]"
|
||||
$(parentModalId + " .button-search").on "click", ->
|
||||
api.templates.get "search", (tmpl) -> # Get form template
|
||||
modalId = gui.launchModal(title, api.templates.evaluate(tmpl,
|
||||
search_label: searchLabel
|
||||
results_label: resultsLabel
|
||||
),
|
||||
actionButton: "<button type=\"button\" class=\"btn btn-success button-accept\">" + gettext("Accept") + "</button>"
|
||||
)
|
||||
$searchInput = $(modalId + " input[name=\"search\"]")
|
||||
$select = $(modalId + " select[name=\"results\"]")
|
||||
$searchButton = $(modalId + " .button-do-search")
|
||||
$saveButton = $(modalId + " .button-accept")
|
||||
$searchInput.val $(srcSelector).val()
|
||||
$saveButton.on "click", ->
|
||||
value = $select.val()
|
||||
if value
|
||||
$(srcSelector).val value
|
||||
$(modalId).modal "hide"
|
||||
return
|
||||
|
||||
$searchButton.on "click", ->
|
||||
$searchButton.addClass "disabled"
|
||||
term = $searchInput.val()
|
||||
api.accounts.search id, type, term, ((data) ->
|
||||
$searchButton.removeClass "disabled"
|
||||
$select.empty()
|
||||
gui.doLog data
|
||||
$.each data, (undefined_, value) ->
|
||||
$select.append "<option value=\"" + value.id + "\">" + value.id + " (" + value.name + ")</option>"
|
||||
return
|
||||
|
||||
return
|
||||
), (jqXHR, textStatus, errorThrown) ->
|
||||
$searchButton.removeClass "disabled"
|
||||
errorModal jqXHR, textStatus, errorThrown
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
$(modalId + " form").submit (event) ->
|
||||
event.preventDefault()
|
||||
$searchButton.click()
|
||||
return
|
||||
|
||||
$searchButton.click() if $searchInput.val() isnt ""
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
api.templates.get "accounts", (tmpl) ->
|
||||
gui.clearWorkspace()
|
||||
gui.appendToWorkspace api.templates.evaluate(tmpl,
|
||||
auths: "auths-placeholder"
|
||||
auths_info: "auths-info-placeholder"
|
||||
users: "users-placeholder"
|
||||
users_log: "users-log-placeholder"
|
||||
groups: "groups-placeholder"
|
||||
logs: "logs-placeholder"
|
||||
)
|
||||
gui.setLinksEvents()
|
||||
|
||||
# Append tabs click events
|
||||
$(".bottom_tabs").on "click", (event) ->
|
||||
gui.doLog event.target
|
||||
setTimeout (->
|
||||
$($(event.target).attr("href") + " span.fa-refresh").click()
|
||||
return
|
||||
), 10
|
||||
return
|
||||
|
||||
tableId = gui.accounts.table(
|
||||
icon: 'accounts'
|
||||
container: "auths-placeholder"
|
||||
rowSelect: "multi"
|
||||
buttons: [
|
||||
"new"
|
||||
"edit"
|
||||
"delete"
|
||||
"xls"
|
||||
"permissions"
|
||||
]
|
||||
|
||||
onFoundUuid: (item) ->
|
||||
# Invoked if our table has found a "desirable" item (uuid)
|
||||
if gui.lookup2Uuid?
|
||||
type = gui.lookup2Uuid[0]
|
||||
gui.lookupUuid = gui.lookup2Uuid.substr(1)
|
||||
gui.lookup2Uuid = null
|
||||
setTimeout( () ->
|
||||
if type == 'g'
|
||||
$('a[href="#groups-placeholder"]').tab('show')
|
||||
$("#groups-placeholder span.fa-refresh").click()
|
||||
else
|
||||
$('a[href="#users-placeholder_tab"]').tab('show')
|
||||
$("#users-placeholder_tab span.fa-refresh").click()
|
||||
, 500)
|
||||
|
||||
onRefresh: (tbl) ->
|
||||
gui.doLog 'Refresh called for accounts'
|
||||
clearDetails()
|
||||
return
|
||||
|
||||
onRowDeselect: (deselected, dtable) ->
|
||||
clearDetails()
|
||||
return
|
||||
|
||||
onRowSelect: (selected) ->
|
||||
clearDetails()
|
||||
|
||||
if selected.length > 1
|
||||
return
|
||||
|
||||
# We can have lots of users, so memory can grow up rapidly if we do not keep thins clean
|
||||
# To do so, we empty previous table contents before storing new table contents
|
||||
# Anyway, TabletTools will keep "leaking" memory, but we can handle a little "leak" that will be fixed as soon as we change the section
|
||||
$("#detail-placeholder").removeClass "hidden"
|
||||
$('#detail-placeholder a[href="#auths-info-placeholder"]').tab('show')
|
||||
|
||||
gui.tools.blockUI()
|
||||
|
||||
# Load provider "info"
|
||||
gui.methods.typedShow gui.accounts, selected[0], '#auths-info-placeholder .well', gettext('Error accessing data')
|
||||
|
||||
id = selected[0].id
|
||||
type = gui.accounts.types[selected[0].type]
|
||||
gui.doLog "Type", type
|
||||
user = new GuiElement(api.accounts.detail(id, "users", { permission: selected[0].permission }), "users")
|
||||
group = new GuiElement(api.accounts.detail(id, "groups", { permission: selected[0].permission }), "groups")
|
||||
grpTable = group.table(
|
||||
icon: 'groups'
|
||||
container: "groups-placeholder"
|
||||
doNotLoadData: true
|
||||
rowSelect: "multi"
|
||||
buttons: [
|
||||
"new"
|
||||
"edit"
|
||||
"delete"
|
||||
"xls"
|
||||
]
|
||||
onLoad: (k) ->
|
||||
gui.tools.unblockUI()
|
||||
return
|
||||
|
||||
onEdit: (value, event, table, refreshFnc) ->
|
||||
exec = (groups_all) ->
|
||||
gui.tools.blockUI()
|
||||
api.templates.get "group", (tmpl) -> # Get form template
|
||||
group.rest.item value.id, (item) -> # Get item to edit
|
||||
# Creates modal
|
||||
modalId = gui.launchModal(gettext("Edit group") + " <b>" + item.name + "</b>", api.templates.evaluate(tmpl,
|
||||
id: item.id
|
||||
type: item.type
|
||||
meta_if_any: item.meta_if_any
|
||||
groupname: item.name
|
||||
groupname_label: type.groupNameLabel
|
||||
comments: item.comments
|
||||
state: item.state
|
||||
external: type.isExternal
|
||||
canSearchGroups: type.canSearchGroups
|
||||
groups: item.groups
|
||||
groups_all: groups_all
|
||||
))
|
||||
gui.tools.applyCustoms modalId
|
||||
gui.tools.unblockUI()
|
||||
$(modalId + " .button-accept").click ->
|
||||
fields = gui.forms.read(modalId)
|
||||
gui.doLog "Fields", fields
|
||||
group.rest.save fields, ((data) -> # Success on put
|
||||
$(modalId).modal "hide"
|
||||
refreshFnc()
|
||||
gui.notify gettext("Group saved"), "success"
|
||||
return
|
||||
), gui.failRequestModalFnc("Error saving group", true)
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
if value.type is "meta"
|
||||
|
||||
# Meta will get all groups
|
||||
group.rest.overview (groups) ->
|
||||
exec groups
|
||||
return
|
||||
|
||||
else
|
||||
exec()
|
||||
return
|
||||
|
||||
onNew: (t, table, refreshFnc) ->
|
||||
exec = (groups_all) ->
|
||||
gui.tools.blockUI()
|
||||
api.templates.get "group", (tmpl) -> # Get form template
|
||||
# Creates modal
|
||||
if t is "meta"
|
||||
title = gettext("New meta group")
|
||||
else
|
||||
title = gettext("New group")
|
||||
modalId = gui.launchModal(title, api.templates.evaluate(tmpl,
|
||||
type: t
|
||||
groupname_label: type.groupNameLabel
|
||||
external: type.isExternal
|
||||
canSearchGroups: type.canSearchGroups
|
||||
groups: []
|
||||
groups_all: groups_all
|
||||
))
|
||||
gui.tools.unblockUI()
|
||||
gui.tools.applyCustoms modalId
|
||||
searchForm modalId, "group", id, gettext("Search groups"), gettext("Group"), gettext("Groups found") # Enable search button click, if it exist ofc
|
||||
$(modalId + " .button-accept").click ->
|
||||
fields = gui.forms.read(modalId)
|
||||
gui.doLog "Fields", fields
|
||||
group.rest.create fields, ((data) -> # Success on put
|
||||
$(modalId).modal "hide"
|
||||
refreshFnc()
|
||||
gui.notify gettext("Group saved"), "success"
|
||||
return
|
||||
), gui.failRequestModalFnc(gettext("Group saving error"), true)
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
if t is "meta"
|
||||
# Meta will get all groups
|
||||
group.rest.overview (groups) ->
|
||||
exec groups
|
||||
return
|
||||
|
||||
else
|
||||
exec()
|
||||
return
|
||||
|
||||
onDelete: gui.methods.del(group, gettext("Delete group"), gettext("Group deletion error"))
|
||||
)
|
||||
tmpLogTable = null
|
||||
|
||||
# New button will only be shown on accounts that can create new users
|
||||
usrButtons = [
|
||||
"edit"
|
||||
"delete"
|
||||
"xls"
|
||||
]
|
||||
usrButtons = ["new"].concat(usrButtons) if type.canCreateUsers # New is first button
|
||||
usrTable = user.table(
|
||||
icon: 'users'
|
||||
container: "users-placeholder"
|
||||
doNotLoadData: true
|
||||
rowSelect: "multi"
|
||||
onRowSelect: (uselected) ->
|
||||
gui.doLog 'User row selected ', uselected
|
||||
gui.tools.blockUI()
|
||||
uId = uselected[0].id
|
||||
clearDetailLog()
|
||||
tmpLogTable = user.logTable(uId,
|
||||
container: "users-log-placeholder"
|
||||
onLoad: ->
|
||||
detailLogTable = tmpLogTable
|
||||
gui.tools.unblockUI()
|
||||
return
|
||||
)
|
||||
return
|
||||
|
||||
onRowDeselect: ->
|
||||
clearDetailLog()
|
||||
return
|
||||
|
||||
buttons: usrButtons
|
||||
deferedRender: true # Use defered rendering for users, this table can be "huge"
|
||||
scrollToTable: false
|
||||
onLoad: (k) ->
|
||||
gui.tools.unblockUI()
|
||||
return
|
||||
|
||||
onRefresh: ->
|
||||
gui.doLog "Refreshing"
|
||||
clearDetailLog()
|
||||
return
|
||||
|
||||
onEdit: (value, event, table, refreshFnc) ->
|
||||
password = "#æð~¬ŋ@æß”¢€~½¬@#~þ¬@|" # Garbage for password (to detect change)
|
||||
gui.tools.blockUI()
|
||||
api.templates.get "user", (tmpl) -> # Get form template
|
||||
group.rest.overview (groups) -> # Get groups
|
||||
user.rest.item value.id, (item) -> # Get item to edit
|
||||
|
||||
# Creates modal
|
||||
modalId = gui.launchModal(gettext("Edit user") + " <b>" + value.name + "</b>", api.templates.evaluate(tmpl,
|
||||
id: item.id
|
||||
username: item.name
|
||||
username_label: type.userNameLabel
|
||||
realname: item.real_name
|
||||
comments: item.comments
|
||||
state: item.state
|
||||
staff_member: item.staff_member
|
||||
is_admin: item.is_admin
|
||||
needs_password: type.needsPassword
|
||||
password: (if type.needsPassword then password else undefined)
|
||||
password_label: type.passwordLabel
|
||||
groups_all: groups
|
||||
groups: item.groups
|
||||
external: type.isExternal
|
||||
canSearchUsers: type.canSearchUsers
|
||||
))
|
||||
gui.tools.applyCustoms modalId
|
||||
gui.tools.unblockUI()
|
||||
$(modalId + " .button-accept").click ->
|
||||
fields = gui.forms.read(modalId)
|
||||
|
||||
# If needs password, and password has changed
|
||||
gui.doLog "passwords", type.needsPassword, password, fields.password
|
||||
delete fields.password if fields.password is password if type.needsPassword
|
||||
gui.doLog "Fields", fields
|
||||
user.rest.save fields, ((data) -> # Success on put
|
||||
$(modalId).modal "hide"
|
||||
refreshFnc()
|
||||
gui.notify gettext("User saved"), "success"
|
||||
return
|
||||
), gui.failRequestModalFnc(gettext("User saving error"), true)
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
onNew: (undefined_, table, refreshFnc) ->
|
||||
gui.tools.blockUI()
|
||||
api.templates.get "user", (tmpl) -> # Get form template
|
||||
group.rest.overview (groups) -> # Get groups
|
||||
# Creates modal
|
||||
modalId = gui.launchModal(gettext("New user"), api.templates.evaluate(tmpl,
|
||||
username_label: type.userNameLabel
|
||||
needs_password: type.needsPassword
|
||||
password_label: type.passwordLabel
|
||||
groups_all: groups
|
||||
groups: []
|
||||
external: type.isExternal
|
||||
canSearchUsers: type.canSearchUsers
|
||||
))
|
||||
gui.tools.applyCustoms modalId
|
||||
gui.tools.unblockUI()
|
||||
searchForm modalId, "user", id, gettext("Search users"), gettext("User"), gettext("Users found") # Enable search button click, if it exist ofc
|
||||
$(modalId + " .button-accept").click ->
|
||||
fields = gui.forms.read(modalId)
|
||||
|
||||
# If needs password, and password has changed
|
||||
gui.doLog "Fields", fields
|
||||
user.rest.create fields, ((data) -> # Success on put
|
||||
$(modalId).modal "hide"
|
||||
refreshFnc()
|
||||
gui.notify gettext("User saved"), "success"
|
||||
return
|
||||
), gui.failRequestModalFnc(gettext("User saving error"), true)
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
onDelete: gui.methods.del(user, gettext("Delete user"), gettext("User deletion error"))
|
||||
)
|
||||
logTable = gui.accounts.logTable(id,
|
||||
container: "logs-placeholder"
|
||||
doNotLoadData: true
|
||||
)
|
||||
|
||||
# So we can destroy the tables beforing adding new ones
|
||||
prevTables.push grpTable
|
||||
prevTables.push usrTable
|
||||
prevTables.push logTable
|
||||
false
|
||||
|
||||
onNew: gui.methods.typedNew(gui.accounts, gettext("New authenticator"), gettext("Authenticator creation error"), testButton)
|
||||
onEdit: gui.methods.typedEdit(gui.accounts, gettext("Edit authenticator"), gettext("Authenticator saving error"), testButton)
|
||||
onDelete: gui.methods.del(gui.accounts, gettext("Delete authenticator"), gettext("Authenticator deletion error"))
|
||||
)
|
||||
return
|
||||
|
||||
false
|
@ -127,6 +127,8 @@
|
||||
<script type="text/coffeescript" charset="utf-8" src="{% get_static_prefix %}adm/js/gui-d-servicespoolsgroup.coffee"></script>
|
||||
<script type="text/coffeescript" charset="utf-8" src="{% get_static_prefix %}adm/js/gui-d-reports.coffee"></script>
|
||||
<script type="text/coffeescript" charset="utf-8" src="{% get_static_prefix %}adm/js/gui-d-calendar.coffee"></script>
|
||||
<script type="text/coffeescript" charset="utf-8" src="{% get_static_prefix %}adm/js/gui-d-account.coffee"></script>
|
||||
|
||||
<!-- base64 encoding -->
|
||||
<script src="{% get_static_prefix %}adm/js/base64.js"></script>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user