diff --git a/server/src/uds/REST/methods/services_pools.py b/server/src/uds/REST/methods/services_pools.py index 28d1c7bb8..1e0af5de8 100644 --- a/server/src/uds/REST/methods/services_pools.py +++ b/server/src/uds/REST/methods/services_pools.py @@ -77,7 +77,7 @@ class ServicesPools(ModelHandler): {'parent': {'title': _('Parent Service')}}, {'state': {'title': _('status'), 'type': 'dict', 'dict': State.dictionary()}}, {'show_transports': {'title': _('Shows transports'), 'type': 'callback'}}, - {'servicesPoolGroup': {'title': _('Pool Group')}}, + {'pool_group_name': {'title': _('Pool Group')}}, {'tags': {'title': _('tags'), 'visible': False}}, ] # Field from where to get "class" and prefix for that class, so this will generate "row-state-A, row-state-X, .... @@ -89,6 +89,14 @@ class ServicesPools(ModelHandler): def item_as_dict(self, item): # if item does not have an associated service, hide it (the case, for example, for a removed service) # Access from dict will raise an exception, and item will be skipped + poolGroupId = None + poolGroupName = _('Default') + poolGroupThumb = DEFAULT_THUMB_BASE64 + if item.servicesPoolGroup is not None: + poolGroupId = item.servicesPoolGroup.uuid + poolGroupName = item.servicesPoolGroup.name + if item.servicesPoolGroup.image is not None: + poolGroupThumb = item.servicesPoolGroup.image.thumb64 val = { 'id': item.uuid, 'name': item.name, @@ -101,8 +109,9 @@ class ServicesPools(ModelHandler): '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': item.servicesPoolGroup.uuid if item.servicesPoolGroup is not None else None, - 'servicesPoolGroup': item.servicesPoolGroup.name if item.servicesPoolGroup is not None else _('Default'), + 'pool_group_id': poolGroupId, + 'pool_group_name': poolGroupName, + 'pool_group_thumb': poolGroupThumb, 'initial_srvs': item.initial_srvs, 'cache_l1_srvs': item.cache_l1_srvs, 'cache_l2_srvs': item.cache_l2_srvs, diff --git a/server/src/uds/REST/methods/user_services.py b/server/src/uds/REST/methods/user_services.py index 9c3bea3bd..84e2b5ff6 100644 --- a/server/src/uds/REST/methods/user_services.py +++ b/server/src/uds/REST/methods/user_services.py @@ -86,6 +86,10 @@ class AssignedService(DetailHandler): else: val.update({ 'owner': item.user.manager.name + "-" + item.user.name, + 'owner_info': { + 'auth_id': item.user.manager.uuid, + 'user_id': item.user.uuid + }, 'in_use': item.in_use, 'in_use_date': item.in_use_date, 'source_host': item.src_hostname, @@ -204,6 +208,7 @@ class Groups(DetailHandler): def getItems(self, parent, item): return [{ 'id': i.uuid, + 'auth_id': i.manager.uuid, 'name': i.name, 'comments': i.comments, 'state': i.state, diff --git a/server/src/uds/static/adm/js/gui-d-authenticators.coffee b/server/src/uds/static/adm/js/gui-d-authenticators.coffee index dcf22acbb..5c3cccda4 100644 --- a/server/src/uds/static/adm/js/gui-d-authenticators.coffee +++ b/server/src/uds/static/adm/js/gui-d-authenticators.coffee @@ -1,14 +1,14 @@ -# jshint strict: true +# jshint strict: true gui.authenticators = new GuiElement(api.authenticators, "auth") gui.authenticators.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 @@ -21,7 +21,7 @@ gui.authenticators.link = (event) -> $("#users-log-placeholder").empty() return - + # Clears the details # Memory saver :-) prevTables = [] @@ -41,7 +41,7 @@ gui.authenticators.link = (event) -> prevTables = [] return - + # Search button event generator for user/group searchForm = (parentModalId, type, id, title, searchLabel, resultsLabel) -> errorModal = gui.failRequestModalFnc(gettext("Search error")) @@ -108,7 +108,7 @@ gui.authenticators.link = (event) -> logs: "logs-placeholder" ) gui.setLinksEvents() - + # Append tabs click events $(".bottom_tabs").on "click", (event) -> gui.doLog event.target @@ -130,6 +130,21 @@ gui.authenticators.link = (event) -> "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 authenticators' clearDetails() @@ -141,10 +156,10 @@ gui.authenticators.link = (event) -> 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 @@ -185,7 +200,7 @@ gui.authenticators.link = (event) -> modalId = gui.launchModal(gettext("Edit group") + " " + item.name + "", api.templates.evaluate(tmpl, id: item.id type: item.type - meta_if_any: item.meta_if_any + meta_if_any: item.meta_if_any groupname: item.name groupname_label: type.groupNameLabel comments: item.comments @@ -215,7 +230,7 @@ gui.authenticators.link = (event) -> return if value.type is "meta" - + # Meta will get all groups group.rest.overview (groups) -> exec groups @@ -273,7 +288,7 @@ gui.authenticators.link = (event) -> onDelete: gui.methods.del(group, gettext("Delete group"), gettext("Group deletion error")) ) tmpLogTable = null - + # New button will only be shown on authenticators that can create new users usrButtons = [ "edit" @@ -322,7 +337,7 @@ gui.authenticators.link = (event) -> 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") + " " + value.name + "", api.templates.evaluate(tmpl, id: item.id @@ -345,7 +360,7 @@ gui.authenticators.link = (event) -> 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 @@ -385,7 +400,7 @@ gui.authenticators.link = (event) -> 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 @@ -408,7 +423,7 @@ gui.authenticators.link = (event) -> container: "logs-placeholder" doNotLoadData: true ) - + # So we can destroy the tables beforing adding new ones prevTables.push grpTable prevTables.push usrTable @@ -421,4 +436,4 @@ gui.authenticators.link = (event) -> ) return - false \ No newline at end of file + false diff --git a/server/src/uds/static/adm/js/gui-d-services.coffee b/server/src/uds/static/adm/js/gui-d-services.coffee index 67a263f4d..91a816e2b 100644 --- a/server/src/uds/static/adm/js/gui-d-services.coffee +++ b/server/src/uds/static/adm/js/gui-d-services.coffee @@ -50,8 +50,16 @@ gui.providers.link = (event) -> onCheck: (check, items) -> # Check if item can be deleted true + onFoundUuid: (item) -> + # Invoked if our table has found a "desirable" item (uuid) + setTimeout( () -> + $('a[href="#services-placeholder_tab"]').tab('show') + $("#services-placeholder_tab span.fa-refresh").click() + , 500) + gui.lookupUuid = gui.lookup2Uuid + gui.lookup2Uuid = null + onRefresh: (tbl) -> - gui.doLog 'Invoked onRefresh for a provider' clearDetails() return @@ -116,7 +124,8 @@ gui.providers.link = (event) -> api.templates.get "service-info", (tmpl) -> content = api.templates.evaluate(tmpl, id: 'information', - pools: pools + pools: pools, + goClass: 'goLink' ) modalId = gui.launchModal(gettext('Service information'), content, actionButton: " " @@ -151,6 +160,16 @@ gui.providers.link = (event) -> language: gui.config.dataTablesLanguage ) + $('.goLink').on('click', (event) -> + $this = $(this); + event.preventDefault(); + gui.lookupUuid = $this.attr('href').substr(1) + $(modalId).modal('hide') + setTimeout( -> + $(".lnk-deployed_services").click(); + , 500); + ) + return select: (vals, value, btn, tbl, refreshFnc) -> diff --git a/server/src/uds/static/adm/js/gui-d-servicespools-actions.coffee b/server/src/uds/static/adm/js/gui-d-servicespools-actions.coffee index a10821e54..86d10f8ec 100644 --- a/server/src/uds/static/adm/js/gui-d-servicespools-actions.coffee +++ b/server/src/uds/static/adm/js/gui-d-servicespools-actions.coffee @@ -42,7 +42,7 @@ gui.servicesPools.actionsCalendars = (servPool, info) -> click: (val, value, btn, tbl, refreshFnc) -> if val.length != 1 return - + gui.doLog val, val[0] gui.forms.confirmModal gettext("Execute action"), gettext("Launch action execution right now?"), onYes: -> @@ -80,6 +80,7 @@ gui.servicesPools.actionsCalendars = (servPool, info) -> $.each data, (index, value) -> value.params = ( k + "=" + value.params[k] for k in Object.keys(value.params)).toString() value.atStart = if value.atStart then gettext('Beginning') else gettext('Ending') + value.calendar = gui.fastLink(value.calendar, value.calendarId, 'gui.servicesPools.fastLink', 'goCalendarLink') onNew: (value, table, refreshFnc) -> diff --git a/server/src/uds/static/adm/js/gui-d-servicespools-calendars.coffee b/server/src/uds/static/adm/js/gui-d-servicespools-calendars.coffee index f56f15745..dd862af7b 100644 --- a/server/src/uds/static/adm/js/gui-d-servicespools-calendars.coffee +++ b/server/src/uds/static/adm/js/gui-d-servicespools-calendars.coffee @@ -23,6 +23,9 @@ gui.servicesPools.accessCalendars = (servPool, info) -> return true onData: (data) -> + $.each data, (index, value) -> + # value.calendar = "#{value.calendar}" + value.calendar = gui.fastLink(value.calendar, value.calendarId, 'gui.servicesPools.fastLink', 'goCalendarLink') data.push id: -1, calendar: '-', diff --git a/server/src/uds/static/adm/js/gui-d-servicespools-transports.coffee b/server/src/uds/static/adm/js/gui-d-servicespools-transports.coffee index 0641a3a5d..06cc86162 100644 --- a/server/src/uds/static/adm/js/gui-d-servicespools-transports.coffee +++ b/server/src/uds/static/adm/js/gui-d-servicespools-transports.coffee @@ -52,7 +52,7 @@ gui.servicesPools.transports = (servPool, info) -> $.each data, (undefined_, value) -> style = "display:inline-block; background: url(data:image/png;base64," + value.type.icon + "); ; background-size: 16px 16px; background-repeat: no-repeat; width: 16px; height: 16px; vertical-align: middle;" value.trans_type = value.type.name - value.name = " " + value.name + value.name = gui.fastLink(" #{value.name}", value.id, 'gui.servicesPools.fastLink', 'goTransportLink') return return diff --git a/server/src/uds/static/adm/js/gui-d-servicespools.coffee b/server/src/uds/static/adm/js/gui-d-servicespools.coffee index 3f282f3a5..480e7cf88 100644 --- a/server/src/uds/static/adm/js/gui-d-servicespools.coffee +++ b/server/src/uds/static/adm/js/gui-d-servicespools.coffee @@ -1,5 +1,47 @@ # jshint strict: true gui.servicesPools = new GuiElement(api.servicesPools, "servicespools") + +# To allow fast admin navigation +gui.servicesPools.fastLink = (event, obj) -> + gui.doLog 'FastLink clicked', obj + event.preventDefault(); + event.stopPropagation(); + $obj = $(obj); + if $obj.hasClass('goServiceLink') + vals = $obj.attr('href').substr(1).split(',') + gui.lookupUuid = vals[0] + gui.lookup2Uuid = vals[1] + setTimeout( -> + $(".lnk-service_providers").click(); + , 50 + ) + else if $obj.hasClass('goPoolGroupLink') + gui.lookupUuid = $obj.attr('href').substr(1) + setTimeout( -> + $(".lnk-spoolsgroup").click(); + , 50 + ) + else if $obj.hasClass('goAuthLink') + vals = $obj.attr('href').substr(1).split(',') + gui.lookupUuid = vals[0] + gui.lookup2Uuid = vals[1] + setTimeout( -> + $(".lnk-authenticators").click(); + , 50) + else if $obj.hasClass('goTransportLink') + gui.lookupUuid = $obj.attr('href').substr(1) + setTimeout( -> + $(".lnk-connectivity").click(); + , 50) + else if $obj.hasClass('goCalendarLink') + gui.lookupUuid = $obj.attr('href').substr(1) + setTimeout( -> + $(".lnk-calendars").click(); + , 50) + + + + gui.servicesPools.link = (event) -> "use strict" gui.clearWorkspace() @@ -306,13 +348,14 @@ gui.servicesPools.link = (event) -> return - onDelete: gui.methods.del(groups, gettext("Remove group"), gettext("Group removal error")) onData: (data) -> $.each data, (undefined_, value) -> - value.group_name = "" + value.auth_name + "\\" + value.name + value.group_name = gui.fastLink(value.auth_name, "#{value.auth_id},g#{value.id}", 'gui.servicesPools.fastLink', 'goAuthLink') return return + + onDelete: gui.methods.del(groups, gettext("Remove group"), gettext("Group removal error")) ) prevTables.push groupsTable else @@ -344,6 +387,7 @@ gui.servicesPools.link = (event) -> value.in_use = gettext('Yes') else value.in_use = gettext('No') + value.owner = gui.fastLink(value.owner, "#{value.owner_info.auth_id},u#{value.owner_info.user_id}", 'gui.servicesPools.fastLink', 'goAuthLink') return @@ -401,15 +445,17 @@ gui.servicesPools.link = (event) -> prevTables.push logTable return - # Pre-process data received to add "icon" to deployed service onData: (data) -> - gui.doLog "onData", data + gui.doLog "onData for services pools", data $.each data, (index, value) -> - gui.doLog value.thumb try style = "display:inline-block; background: url(data:image/png;base64," + value.thumb + "); background-size: 16px 16px; background-repeat: no-repeat; width: 16px; height: 16px; vertical-align: middle;" - gui.doLog style + style_grp = "display:inline-block; background: url(data:image/png;base64," + value.pool_group_thumb + "); background-size: 16px 16px; background-repeat: no-repeat; width: 16px; height: 16px; vertical-align: middle;" + value.parent = gui.fastLink(value.parent, "#{value.provider_id},#{value.service_id}", 'gui.servicesPools.fastLink', 'goServiceLink') + value.pool_group_name = " #{value.pool_group_name}" + if value.pool_group_id? + value.pool_group_name = gui.fastLink(value.pool_group_name, value.pool_group_id, 'gui.servicesPools.fastLink', 'goPoolGroupLink') if value.restrained value.name = " " + value.name value.state = gettext("Restrained") diff --git a/server/src/uds/static/adm/js/gui-element.coffee b/server/src/uds/static/adm/js/gui-element.coffee index 97169deaa..481d59a15 100644 --- a/server/src/uds/static/adm/js/gui-element.coffee +++ b/server/src/uds/static/adm/js/gui-element.coffee @@ -214,6 +214,23 @@ columns.push column return + lookupUuid = (dTable) -> + if gui.lookupUuid? + gui.doLog "Looking up #{gui.lookupUuid}" + dTable.rows().every( (rowIdx, tableLoop, rowLoop) -> + # rowLoop holds the position in sorted table + try + if this.data().id == gui.lookupUuid + gui.doLog "Found: #{this.data()}" + gui.lookupUuid = null + page = Math.floor(rowLoop / dTable.page.info().length) + dTable.page(page).draw(false) + this.select() + if tblParams.onFoundUuid? + tblParams.onFoundUuid(this) + catch error + ; + ) # Responsive style for tables, using tables.css and this code generates the "titles" for vertical display on small sizes initTable = (data) -> @@ -249,6 +266,7 @@ selCallback null, tbl, null, null gui.doLog "onRefresh", tblParams.onRefresh tblParams.onRefresh self + lookupUuid(tbl) gui.tools.unblockUI()), gui.failRequestModalFnc(gettext("Refresh operation failed")) ) return @@ -559,6 +577,10 @@ tableTop = $("#" + tableId).offset().top $("html, body").scrollTop tableTop + gui.test = dTable + # Try to locate gui.lookupUuid as last action + lookupUuid(dTable) + # if table rendered event tblParams.onLoad self if tblParams.onLoad return diff --git a/server/src/uds/static/adm/js/gui.coffee b/server/src/uds/static/adm/js/gui.coffee index ab3aea581..f1e41f142 100644 --- a/server/src/uds/static/adm/js/gui.coffee +++ b/server/src/uds/static/adm/js/gui.coffee @@ -5,6 +5,10 @@ # Public attributes gui.debug = on + # Used for lookup items on some circustances + gui.lookupUuid = null + gui.lookup2Uuid = null # Used for going to second level of tables. Take into account that this is used by some guis + # "public" methods gui.doLog = (args...)-> if gui.debug @@ -162,6 +166,9 @@ return + gui.fastLink = (text, href, onClick, clas) -> + "#{text} " + gui.setLinksEvents = -> sidebarLinks = [ { diff --git a/server/src/uds/templates/uds/admin/index.html b/server/src/uds/templates/uds/admin/index.html index 63e47c97c..36d4be29f 100644 --- a/server/src/uds/templates/uds/admin/index.html +++ b/server/src/uds/templates/uds/admin/index.html @@ -59,8 +59,6 @@ {% compress js %} - diff --git a/server/src/uds/templates/uds/admin/tmpl/service-info.html b/server/src/uds/templates/uds/admin/tmpl/service-info.html index 7b94ba7cf..51c5d9fbf 100644 --- a/server/src/uds/templates/uds/admin/tmpl/service-info.html +++ b/server/src/uds/templates/uds/admin/tmpl/service-info.html @@ -21,13 +21,13 @@