From 54477e5c60b7622dd622875b99c787bf0b416fef Mon Sep 17 00:00:00 2001 From: TaykYoku Date: Tue, 27 Jul 2021 22:10:55 +0200 Subject: [PATCH 01/15] get hosts from DB --- WebApp/handler/SystemAdministrationHandler.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/WebApp/handler/SystemAdministrationHandler.py b/WebApp/handler/SystemAdministrationHandler.py index fa0f823e8..0d00a7609 100644 --- a/WebApp/handler/SystemAdministrationHandler.py +++ b/WebApp/handler/SystemAdministrationHandler.py @@ -5,9 +5,8 @@ import datetime from DIRAC import gConfig, gLogger -from DIRAC.Core.DISET.RPCClient import RPCClient from DIRAC.Core.Utilities.List import uniqueElements -import DIRAC.ConfigurationSystem.Client.Helpers.Registry as Registry +from DIRAC.FrameworkSystem.Client.MonitoringClient import gMonitor from DIRAC.FrameworkSystem.Client.NotificationClient import NotificationClient from DIRAC.FrameworkSystem.Client.SystemAdministratorClient import SystemAdministratorClient from DIRAC.FrameworkSystem.Client.ComponentMonitoringClient import ComponentMonitoringClient @@ -593,7 +592,7 @@ def web_getSelectionData(self): setup = self.getUserSetup().split('-')[-1] hosts = [] - result = Registry.getHosts() + result = ComponentMonitoringClient().getHosts() if result['OK']: hosts = [[i] for i in result['Value']] data['Hosts'] = hosts @@ -639,13 +638,11 @@ def web_getSelectionData(self): @asyncGen def web_ComponentLocation(self): - rpcClient = RPCClient("Framework/Monitoring") - _setup = self.getUserSetup() setup = _setup.split('-')[-1] hosts = [] - result = Registry.getHosts() + result = ComponentMonitoringClient().getHosts() if result['OK']: hosts = result['Value'] @@ -705,7 +702,7 @@ def web_ComponentLocation(self): condDict = {'Setup': _setup} gLogger.debug("condDict" + str(condDict)) - retVal = rpcClient.getComponentsStatus(condDict) + retVal = gMonitor.getComponentsStatus(condDict) today = datetime.datetime.today() if retVal['OK']: From a107db599129218f7b1403f377447c7ea984344e Mon Sep 17 00:00:00 2001 From: TaykYoku Date: Wed, 28 Jul 2021 21:09:02 +0200 Subject: [PATCH 02/15] update datatime field --- .../core/js/utils/DiracTimeSearchPanel.js | 176 ++++++++++-------- 1 file changed, 101 insertions(+), 75 deletions(-) diff --git a/WebApp/static/core/js/utils/DiracTimeSearchPanel.js b/WebApp/static/core/js/utils/DiracTimeSearchPanel.js index 773433355..f2771f908 100644 --- a/WebApp/static/core/js/utils/DiracTimeSearchPanel.js +++ b/WebApp/static/core/js/utils/DiracTimeSearchPanel.js @@ -2,18 +2,16 @@ * This widget is used by the Ext.dirac.utils.DiracBaseSelector widget. It * allows to select time in the selector. */ -Ext.define("Ext.dirac.utils.DiracTimeSearchPanel", { + Ext.define("Ext.dirac.utils.DiracTimeSearchPanel", { extend: "Ext.panel.Panel", requires: ["Ext.data.ArrayStore"], width: 200, autoHeight: true, border: true, bodyPadding: 5, - layout: "anchor", - anchor: "100%", + layout: "hbox", /************************************************************************* - * @property{It is the time stamp widget which contains a list with Last - * hour, Last Day...} + * @property{It is the time stamp widget which contains a list with Last hour, Last Day...} */ cmbTimeSpan: null, /** @@ -33,14 +31,12 @@ Ext.define("Ext.dirac.utils.DiracTimeSearchPanel", { calenTo: null, /** * - * @property{cmbTimeTo} is a combo box used to select the time in a given - * day. + * @property{cmbTimeTo} is a combo box used to select the time in a given day. */ cmbTimeTo: null, /** * - * @property{timeSearchPanelHidden} is a boolean which is true when the - * time search panel is hidden... + * @property{timeSearchPanelHidden} is a boolean which is true when the time search panel is hidden... */ timeSearchPanelHidden: null, getStateData: function() { @@ -57,10 +53,8 @@ Ext.define("Ext.dirac.utils.DiracTimeSearchPanel", { }, loadState: function(data) { var me = this; - if (data.timeSearchPanelHidden) { - if (!data.timeSearchPanelHidden) me.show(); - else me.hide(); - } + + data.timeSearchPanelHidden ? me.hide : me.show(); // END - For the time span searching sub-panel if (data.cmbTimeSpan) { @@ -96,47 +90,98 @@ Ext.define("Ext.dirac.utils.DiracTimeSearchPanel", { [5, "Manual Selection"] ] }), + emptyText: "For all time?", + editable: false, displayField: "text", valueField: "value", - anchor: "100%" + anchor: "100%", + onChange: function(newVal) { + if (newVal == 5) { + console.log(newVal) + GLOBAL.ME = me; + me.fromDate.items.forEach(e => e.show()); + me.toDate.items.forEach(e => e.show()); + } else { + me.fromDate.items.forEach(e => e.hide()); + me.toDate.items.forEach(e => e.hide()); + me.resetDate.items.forEach(e => e.hide()); + } + } }); - var oTimeData = []; - for (var i = 0; i < 24; i++) { - oTimeData.push([(i.toString().length == 1 ? "0" + i.toString() : i.toString()) + ":00"]); - oTimeData.push([(i.toString().length == 1 ? "0" + i.toString() : i.toString()) + ":30"]); - } - me.calenFrom = new Ext.create("Ext.form.field.Date", { - width: 100, - format: "Y-m-d" + labelAlign: "top", + fieldLabel: "From", + flex: 3, + format: "Y-m-d", + hidden: true, + onChange: function(newVal) { + if (newVal) { + me.cmbTimeFrom.enable(); + me.resetDate.items.forEach(e => e.show()); + } else { + me.cmbTimeFrom.disable(); + } + } }); - me.cmbTimeFrom = new Ext.create("Ext.form.field.ComboBox", { - width: 70, - store: new Ext.data.ArrayStore({ - fields: ["value"], - data: oTimeData - }), + me.cmbTimeFrom = new Ext.create("Ext.form.field.Time", { + format: 'H:i', + flex: 2, + increment: 30, margin: "0 0 0 10", - displayField: "value" + hidden: true, + disabled: true }); + me.fromDate = { + xtype: "panel", + layout: { + type: 'hbox', + align: 'bottom' + }, + border: false, + margin: "0 0 5 0", + items: [me.calenFrom, me.cmbTimeFrom] + }; + me.calenTo = new Ext.create("Ext.form.field.Date", { - width: 100, - format: "Y-m-d" + labelAlign: "top", + fieldLabel: "To", + labelStyle: 'width:20px', + flex: 3, + format: "Y-m-d", + hidden: true, + onChange: function(newVal) { + if (newVal) { + me.cmbTimeTo.enable(); + me.resetDate.items.forEach(e => e.show()); + } else { + me.cmbTimeTo.disable(); + } + } }); - me.cmbTimeTo = new Ext.create("Ext.form.field.ComboBox", { - width: 70, - store: new Ext.data.ArrayStore({ - fields: ["value"], - data: oTimeData - }), + me.cmbTimeTo = new Ext.create("Ext.form.field.Time", { + format: 'H:i', + flex: 2, + increment: 30, margin: "0 0 0 10", - displayField: "value" + hidden: true, + disabled: true }); + me.toDate = { + xtype: "panel", + layout: { + type: 'hbox', + align: 'bottom' + }, + border: false, + margin: "0 0 5 0", + items: [me.calenTo, me.cmbTimeTo] + }; + me.btnResetTimePanel = new Ext.Button({ text: "Reset Time Panel", margin: 3, @@ -146,47 +191,28 @@ Ext.define("Ext.dirac.utils.DiracTimeSearchPanel", { me.cmbTimeFrom.setValue(null); me.calenTo.setRawValue(""); me.calenFrom.setRawValue(""); - me.cmbTimeSpan.setValue(null); + me.btnResetTimePanel.hide() }, scope: me, - defaultAlign: "c" + hidden: true }); + + me.resetDate = { + xtype: "toolbar", + layout: { + type: "hbox", + pack: "center" + }, + border: false, + items: [me.btnResetTimePanel] + }; + Ext.apply(me, { - dockedItems: [ - { - xtype: "toolbar", - dock: "bottom", - items: [me.btnResetTimePanel], - layout: { - type: "hbox", - pack: "center" - } - } - ], items: [ me.cmbTimeSpan, - { - xtype: "tbtext", - text: "From:", - padding: "3 0 3 0" - }, - { - xtype: "panel", - layout: "column", - border: false, - items: [me.calenFrom, me.cmbTimeFrom] - }, - { - xtype: "tbtext", - text: "To:", - padding: "3 0 3 0" - }, - { - xtype: "panel", - layout: "column", - border: false, - items: [me.calenTo, me.cmbTimeTo] - } + me.fromDate, + me.toDate, + me.resetDate ] }); me.callParent(arguments); @@ -235,9 +261,9 @@ Ext.define("Ext.dirac.utils.DiracTimeSearchPanel", { // Collect data for filtration data["startDate"] = sStartDate; - data["startTime"] = sStartTime; + data["startTime"] = sStartTime ? sStartTime.getHours() + ':' + sStartTime.getMinutes() : sStartTime; data["endDate"] = sEndDate; - data["endTime"] = sEndTime; + data["endTime"] = sEndTime ? sEndTime.getHours() + ':' + sEndTime.getMinutes() : sEndTime; return data; } }); From db93f4a94a832154d5f76ec9222e09343a639f78 Mon Sep 17 00:00:00 2001 From: TaykYoku Date: Wed, 28 Jul 2021 21:16:59 +0200 Subject: [PATCH 03/15] fix --- WebApp/static/core/js/utils/DiracTimeSearchPanel.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/WebApp/static/core/js/utils/DiracTimeSearchPanel.js b/WebApp/static/core/js/utils/DiracTimeSearchPanel.js index f2771f908..8b597303f 100644 --- a/WebApp/static/core/js/utils/DiracTimeSearchPanel.js +++ b/WebApp/static/core/js/utils/DiracTimeSearchPanel.js @@ -2,14 +2,15 @@ * This widget is used by the Ext.dirac.utils.DiracBaseSelector widget. It * allows to select time in the selector. */ - Ext.define("Ext.dirac.utils.DiracTimeSearchPanel", { +Ext.define("Ext.dirac.utils.DiracTimeSearchPanel", { extend: "Ext.panel.Panel", requires: ["Ext.data.ArrayStore"], width: 200, autoHeight: true, border: true, bodyPadding: 5, - layout: "hbox", + layout: "anchor", + anchor: "100%", /************************************************************************* * @property{It is the time stamp widget which contains a list with Last hour, Last Day...} */ @@ -97,8 +98,6 @@ anchor: "100%", onChange: function(newVal) { if (newVal == 5) { - console.log(newVal) - GLOBAL.ME = me; me.fromDate.items.forEach(e => e.show()); me.toDate.items.forEach(e => e.show()); } else { From 20019ba4e5184db9bfde56cb5f9cbcaa789dbd13 Mon Sep 17 00:00:00 2001 From: TaykYoku Date: Wed, 28 Jul 2021 21:57:20 +0200 Subject: [PATCH 04/15] fix --- .../core/js/utils/DiracTimeSearchPanel.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/WebApp/static/core/js/utils/DiracTimeSearchPanel.js b/WebApp/static/core/js/utils/DiracTimeSearchPanel.js index 8b597303f..9c4029e77 100644 --- a/WebApp/static/core/js/utils/DiracTimeSearchPanel.js +++ b/WebApp/static/core/js/utils/DiracTimeSearchPanel.js @@ -116,10 +116,7 @@ Ext.define("Ext.dirac.utils.DiracTimeSearchPanel", { hidden: true, onChange: function(newVal) { if (newVal) { - me.cmbTimeFrom.enable(); me.resetDate.items.forEach(e => e.show()); - } else { - me.cmbTimeFrom.disable(); } } }); @@ -130,7 +127,11 @@ Ext.define("Ext.dirac.utils.DiracTimeSearchPanel", { increment: 30, margin: "0 0 0 10", hidden: true, - disabled: true + onChange: function(newVal) { + if (!me.calenFrom.getValue()) { + me.calenFrom.setValue(new Date()); + } + } }); me.fromDate = { @@ -153,10 +154,7 @@ Ext.define("Ext.dirac.utils.DiracTimeSearchPanel", { hidden: true, onChange: function(newVal) { if (newVal) { - me.cmbTimeTo.enable(); me.resetDate.items.forEach(e => e.show()); - } else { - me.cmbTimeTo.disable(); } } }); @@ -167,7 +165,11 @@ Ext.define("Ext.dirac.utils.DiracTimeSearchPanel", { increment: 30, margin: "0 0 0 10", hidden: true, - disabled: true + onChange: function(newVal) { + if (!me.calenTo.getValue()) { + me.calenTo.setValue(new Date()); + } + } }); me.toDate = { From 60dab2288eb1edb805fdab6df5f7557637826b34 Mon Sep 17 00:00:00 2001 From: TaykYoku Date: Sat, 27 Feb 2021 20:43:15 +0100 Subject: [PATCH 05/15] add getWebConfiguration --- Lib/SessionData.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/SessionData.py b/Lib/SessionData.py index 08a35bf95..f74ac4903 100644 --- a/Lib/SessionData.py +++ b/Lib/SessionData.py @@ -48,7 +48,7 @@ def __isGroupAuthApp(self, appLoc): """ The method checks if the application is authorized for a certain user group :param str appLoc It is the application name for example: DIRAC.JobMonitor - + :return bool -- if the handler is authorized to the user returns True otherwise False """ handlerLoc = "/".join(List.fromChar(appLoc, ".")[1:]) From 04509ae7f81e7d9b89835d611e1d4b7c4799a96e Mon Sep 17 00:00:00 2001 From: TaykYoku Date: Sat, 27 Feb 2021 20:52:01 +0100 Subject: [PATCH 06/15] add downtime to tabs --- WebApp/static/core/js/core/App.js | 42 ++++++++++++++++++++++++ WebApp/static/core/js/views/tabs/Main.js | 7 ++++ 2 files changed, 49 insertions(+) diff --git a/WebApp/static/core/js/core/App.js b/WebApp/static/core/js/core/App.js index 0eacce57d..a45b08b7d 100755 --- a/WebApp/static/core/js/core/App.js +++ b/WebApp/static/core/js/core/App.js @@ -242,6 +242,48 @@ Ext.define("Ext.dirac.core.App", { return sAppName in this.validApplications; }, + /** + * Function to get all application settings + * + * @param {String} + * sAppName The class name of the application + * @return {} + */ + getApplicationSettings: function(sAppName) { + if (GLOBAL.APP.configData.configuration.Apps && sAppName in GLOBAL.APP.configData.configuration.Apps) { + return GLOBAL.APP.configData.configuration.Apps[sAppName] + } else { + return {} + } + }, + + /** + * Function that check application downtime settings + * + * @param {String} + * sAppName The class name of the application + * @return {} + */ + applicationInDowntime: function(sAppName) { + if (!this.isValidApplication(sAppName)) { + return {}; + } + var now = Date.now(); + var sAppName = this.validApplications[sAppName]; + var app = this.getApplicationSettings(sAppName).Downtime; + + if (app) { + app.message = app.message || "Sorry, " + sAppName + " application is in downtime"; + app.message += "\n\n From: " + app.start; + app.message += "\n To: " + app.end; + + // Check time + return !app.end ? {} : ((!app.start || now > Date.parse(app.start)) && now < Date.parse(app.end)) ? app : {}; + } else { + return {} + } + }, + /** * Function that is used to get the title of an application * diff --git a/WebApp/static/core/js/views/tabs/Main.js b/WebApp/static/core/js/views/tabs/Main.js index 21251d597..dbb6042d7 100644 --- a/WebApp/static/core/js/views/tabs/Main.js +++ b/WebApp/static/core/js/views/tabs/Main.js @@ -806,6 +806,13 @@ Ext.define("Ext.dirac.views.tabs.Main", { */ createWindow: function(loadedObjectType, moduleName, setupData, oTab, cbFunction) { var me = this; + + // Do not create new window if the application in downtime + var downtime = GLOBAL.APP.applicationInDowntime(moduleName); + if (downtime.message) { + return GLOBAL.APP.CF.alert(downtime.message, "info"); + } + Ext.get("app-dirac-loading").show(); if (loadedObjectType == "app") { From 2bda255d1f941b43ded98ed54854fe799ec901fb Mon Sep 17 00:00:00 2001 From: TaykYoku Date: Fri, 23 Jul 2021 01:00:47 +0200 Subject: [PATCH 07/15] _ --- Lib/SessionData.py | 2 +- WebApp/static/core/js/core/App.js | 31 +++++++++++++++---------------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/Lib/SessionData.py b/Lib/SessionData.py index f74ac4903..08a35bf95 100644 --- a/Lib/SessionData.py +++ b/Lib/SessionData.py @@ -48,7 +48,7 @@ def __isGroupAuthApp(self, appLoc): """ The method checks if the application is authorized for a certain user group :param str appLoc It is the application name for example: DIRAC.JobMonitor - + :return bool -- if the handler is authorized to the user returns True otherwise False """ handlerLoc = "/".join(List.fromChar(appLoc, ".")[1:]) diff --git a/WebApp/static/core/js/core/App.js b/WebApp/static/core/js/core/App.js index a45b08b7d..2e524ea72 100755 --- a/WebApp/static/core/js/core/App.js +++ b/WebApp/static/core/js/core/App.js @@ -265,22 +265,21 @@ Ext.define("Ext.dirac.core.App", { * @return {} */ applicationInDowntime: function(sAppName) { - if (!this.isValidApplication(sAppName)) { - return {}; - } - var now = Date.now(); - var sAppName = this.validApplications[sAppName]; - var app = this.getApplicationSettings(sAppName).Downtime; - - if (app) { - app.message = app.message || "Sorry, " + sAppName + " application is in downtime"; - app.message += "\n\n From: " + app.start; - app.message += "\n To: " + app.end; - - // Check time - return !app.end ? {} : ((!app.start || now > Date.parse(app.start)) && now < Date.parse(app.end)) ? app : {}; - } else { - return {} + if (this.isValidApplication(sAppName)) { + var now = Date.now(); + var sAppName = this.validApplications[sAppName]; + var app = this.getApplicationSettings(sAppName).Downtime; + + if (app) { + app.message = app.message || "Sorry, " + sAppName + " application is in downtime"; + app.message += "\n\n From: " + app.start; + app.message += "\n To: " + app.end; + + // Check time + return !app.end ? {} : ((!app.start || now > Date.parse(app.start)) && now < Date.parse(app.end)) ? app : {}; + } else { + return {} + } } }, From 86d71f616bdb97517cfeb1ded49937d6b3f27bd8 Mon Sep 17 00:00:00 2001 From: TaykYoku Date: Tue, 27 Jul 2021 23:03:29 +0200 Subject: [PATCH 08/15] add downtime --- WebApp/static/core/js/core/App.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/WebApp/static/core/js/core/App.js b/WebApp/static/core/js/core/App.js index 2e524ea72..1035cb22f 100755 --- a/WebApp/static/core/js/core/App.js +++ b/WebApp/static/core/js/core/App.js @@ -250,8 +250,8 @@ Ext.define("Ext.dirac.core.App", { * @return {} */ getApplicationSettings: function(sAppName) { - if (GLOBAL.APP.configData.configuration.Apps && sAppName in GLOBAL.APP.configData.configuration.Apps) { - return GLOBAL.APP.configData.configuration.Apps[sAppName] + if (sAppName in GLOBAL.APP.configData.configuration) { + return GLOBAL.APP.configData.configuration[sAppName] } else { return {} } @@ -267,16 +267,16 @@ Ext.define("Ext.dirac.core.App", { applicationInDowntime: function(sAppName) { if (this.isValidApplication(sAppName)) { var now = Date.now(); - var sAppName = this.validApplications[sAppName]; - var app = this.getApplicationSettings(sAppName).Downtime; + var app = this.validApplications[sAppName]; + var downtime = this.getApplicationSettings(app).Downtime; - if (app) { - app.message = app.message || "Sorry, " + sAppName + " application is in downtime"; - app.message += "\n\n From: " + app.start; - app.message += "\n To: " + app.end; + if (downtime) { + downtime.message = downtime.message || "Sorry, " + app + " application is in downtime"; + downtime.message += "\n\n From: " + downtime.start; + downtime.message += "\n To: " + downtime.end; // Check time - return !app.end ? {} : ((!app.start || now > Date.parse(app.start)) && now < Date.parse(app.end)) ? app : {}; + return !downtime.end ? {} : ((!downtime.start || now > Date.parse(downtime.start)) && now < Date.parse(downtime.end)) ? downtime : {}; } else { return {} } From 6582e2526448129e76fc0838ad09c83448ba99a9 Mon Sep 17 00:00:00 2001 From: TaykYoku Date: Wed, 28 Jul 2021 16:03:40 +0200 Subject: [PATCH 09/15] add setter --- WebApp/handler/DowntimesHandler.py | 20 ++- .../static/core/js/views/tabs/ContextMenu.js | 8 ++ WebApp/static/core/js/views/tabs/SelPanel.js | 4 + .../core/js/views/tabs/StateManagement.js | 120 +++++++++++++++++- 4 files changed, 150 insertions(+), 2 deletions(-) diff --git a/WebApp/handler/DowntimesHandler.py b/WebApp/handler/DowntimesHandler.py index 8adb275b4..1d5e4902d 100644 --- a/WebApp/handler/DowntimesHandler.py +++ b/WebApp/handler/DowntimesHandler.py @@ -4,7 +4,8 @@ import json from datetime import datetime -from DIRAC import gLogger +from DIRAC import gLogger, gConfig +from DIRAC.ConfigurationSystem.Client.ConfigurationClient import ConfigurationClient from DIRAC.ResourceStatusSystem.Client.PublisherClient import PublisherClient from WebAppDIRAC.Lib.WebHandler import WebHandler, WErr, asyncGen @@ -139,3 +140,20 @@ def __requestParams(self): responseParams['endDate'] = datetime.utcnow() return responseParams + + @asyncGen + def web_setApplicationDowntime(self): + start = self.get_argument('start') + end = self.get_argument('end') + + basePath = '/WebApp/%s/Downtime/' % self.get_argument('app') + + rpcClient = ConfigurationClient(url=gConfig.getValue("/DIRAC/Configuration/MasterServer", "Configuration/Server")) + modCfg = Modificator(rpcClient) + + yield self.threadTask(modCfg.loadFromRemote) + + for option, value in [('message', self.get_argument('message')), ('start', start), ('end', end)] + yield self.threadTask(modCfg.setOptionValue, basePath + option, value) + + self.finish() \ No newline at end of file diff --git a/WebApp/static/core/js/views/tabs/ContextMenu.js b/WebApp/static/core/js/views/tabs/ContextMenu.js index a69fcc8cf..95216ea1a 100755 --- a/WebApp/static/core/js/views/tabs/ContextMenu.js +++ b/WebApp/static/core/js/views/tabs/ContextMenu.js @@ -297,6 +297,14 @@ Ext.define("Ext.dirac.views.tabs.ContextMenu", { }); } } + }, + { + text: "Create downtime for application", + iconCls: "core-desktop-icon", + value: 8, + handler: function() { + GLOBAL.APP.MAIN_VIEW.SM.formSetDowntime(me.oSelectedMenuItem.data.application) + } } ] }); diff --git a/WebApp/static/core/js/views/tabs/SelPanel.js b/WebApp/static/core/js/views/tabs/SelPanel.js index 8670d7dd2..14f2ca842 100644 --- a/WebApp/static/core/js/views/tabs/SelPanel.js +++ b/WebApp/static/core/js/views/tabs/SelPanel.js @@ -333,6 +333,10 @@ Ext.define("Ext.dirac.views.tabs.SelPanel", { var me = this; me.contextMenu.oSelectedMenuItem = record; + if (!('AdministratorCS' in GLOBAL.APP.configData.user.properties)) { + me.contextMenu.disableMenuItem(8); + } + if (record.get("type") == "desktop") { me.contextMenu.enableMenuItem(0); me.contextMenu.disableMenuItem(1); diff --git a/WebApp/static/core/js/views/tabs/StateManagement.js b/WebApp/static/core/js/views/tabs/StateManagement.js index 358058f65..ff2e8d4b1 100755 --- a/WebApp/static/core/js/views/tabs/StateManagement.js +++ b/WebApp/static/core/js/views/tabs/StateManagement.js @@ -5,8 +5,126 @@ */ Ext.define("Ext.dirac.views.tabs.StateManagement", { - requires: ["Ext.form.field.Text", "Ext.button.Button", "Ext.toolbar.Toolbar", "Ext.panel.Panel", "Ext.window.Window"], + requires: ["Ext.form.field.Text", "Ext.form.field.Date", "Ext.button.Button", "Ext.toolbar.Toolbar", "Ext.panel.Panel", "Ext.window.Window"], + /** + * Function called when the create downtime is clicked + * + * @param {String} + * sAppName Application class name + */ + formSetDowntime: function(sAppName) { + var me = this; + + me.txtReason = Ext.create("Ext.form.field.Text", { + fieldLabel: "Reason:", + labelAlign: "left", + margin: 10, + width: 400, + enableKeyEvents: true, + validateValue: function(sValue) { + sValue = Ext.util.Format.trim(sValue); + if (sValue.length < 1) { + this.markInvalid("You must specify a reason!"); + return false; + } + }, + validateOnChange: true, + validateOnBlur: false, + listeners: { + keypress: function(oTextField, e, eOpts) { + if (e.getCharCode() == 13) { + if (me.txtReason.isValid()) { + var message = me.txtReason.getValue(); + } + } + } + } + }); + + me.calendarFrom = new Ext.create("Ext.form.field.Date", { + width: 100, + format: "Y-m-d", + fieldLabel: "Initial Date", + labelAlign: "top", + hidden: true + }); + + me.calendarTo = new Ext.create("Ext.form.field.Date", { + width: 100, + format: "Y-m-d", + fieldLabel: "End Date", + labelAlign: "top", + hidden: true + }); + + // button for saving the state + me.btnAddDowntime = new Ext.Button({ + text: "Create downtime", + margin: 3, + iconCls: "dirac-icon-save", + handler: function() { + if (me.txtReason.isValid()) { + Ext.Ajax.request({ + url: GLOBAL.BASE_URL + "Downtimes/setApplicationDowntime", + params: { + app: sAppName, + message: me.txtReason.getValue(), + start: me.calendarFrom.getValue(), + end: me.calendarTo.getValue() + }, + scope: me, + success: function(response) { + GLOBAL.APP.CF.msg('Downtime added!') + }, + failure: function(response) { + GLOBAL.APP.CF.showAjaxErrorMessage(response); + } + }); + } + }, + scope: me + }); + + // button to close the save form + me.btnCancel = new Ext.Button({ + text: "Cancel", + margin: 3, + iconCls: "toolbar-other-close", + handler: function() { + me.txtReason.setValue(""); + me.start.setValue(""); + me.end.setValue(""); + me.setDowntimeWindow.hide(); + }, + scope: me + }); + + var oToolbar = new Ext.toolbar.Toolbar({ + border: false + }); + + oToolbar.add([me.btnAddDowntime, me.btnCancel]); + + var oPanel = new Ext.create("Ext.panel.Panel", { + autoHeight: true, + border: false, + items: [oToolbar, me.txtReason] + }); + + // initializing window showing the saving form + me.setDowntimeWindow = Ext.create("widget.window", { + height: 120, + width: 500, + title: "Set downtime", + layout: "fit", + modal: true, + items: oPanel + }); + + me.setDowntimeWindow.show(); + me.txtReason.focus(); + }, /** * Function called when the Save As ... button from the SAVE window menu * is clicked From 100c2a49f19ea2dcf28b980426dca0e30d3eb883 Mon Sep 17 00:00:00 2001 From: TaykYoku Date: Wed, 28 Jul 2021 22:21:36 +0200 Subject: [PATCH 10/15] keep only CS set downtime --- WebApp/handler/DowntimesHandler.py | 20 +-- WebApp/static/core/js/core/App.js | 10 ++ .../static/core/js/views/tabs/ContextMenu.js | 8 -- WebApp/static/core/js/views/tabs/SelPanel.js | 4 - .../core/js/views/tabs/StateManagement.js | 120 +----------------- 5 files changed, 12 insertions(+), 150 deletions(-) diff --git a/WebApp/handler/DowntimesHandler.py b/WebApp/handler/DowntimesHandler.py index 1d5e4902d..8adb275b4 100644 --- a/WebApp/handler/DowntimesHandler.py +++ b/WebApp/handler/DowntimesHandler.py @@ -4,8 +4,7 @@ import json from datetime import datetime -from DIRAC import gLogger, gConfig -from DIRAC.ConfigurationSystem.Client.ConfigurationClient import ConfigurationClient +from DIRAC import gLogger from DIRAC.ResourceStatusSystem.Client.PublisherClient import PublisherClient from WebAppDIRAC.Lib.WebHandler import WebHandler, WErr, asyncGen @@ -140,20 +139,3 @@ def __requestParams(self): responseParams['endDate'] = datetime.utcnow() return responseParams - - @asyncGen - def web_setApplicationDowntime(self): - start = self.get_argument('start') - end = self.get_argument('end') - - basePath = '/WebApp/%s/Downtime/' % self.get_argument('app') - - rpcClient = ConfigurationClient(url=gConfig.getValue("/DIRAC/Configuration/MasterServer", "Configuration/Server")) - modCfg = Modificator(rpcClient) - - yield self.threadTask(modCfg.loadFromRemote) - - for option, value in [('message', self.get_argument('message')), ('start', start), ('end', end)] - yield self.threadTask(modCfg.setOptionValue, basePath + option, value) - - self.finish() \ No newline at end of file diff --git a/WebApp/static/core/js/core/App.js b/WebApp/static/core/js/core/App.js index 1035cb22f..9d273b69f 100755 --- a/WebApp/static/core/js/core/App.js +++ b/WebApp/static/core/js/core/App.js @@ -276,6 +276,16 @@ Ext.define("Ext.dirac.core.App", { downtime.message += "\n To: " + downtime.end; // Check time + /* The string format should be: YYYY-MM-DDTHH:mm:ss.sssZ, where: + + YYYY-MM-DD – is the date: year-month-day. + The character "T" is used as the delimiter. + HH:mm:ss.sss – is the time: hours, minutes, seconds and milliseconds. + The optional 'Z' part denotes the time zone in the format +-hh:mm. A single letter Z would mean UTC+0. + Shorter variants are also possible, like YYYY-MM-DDTHH:mm, YYYY-MM-DD or YYYY-MM or even YYYY. + */ + + return !downtime.end ? {} : ((!downtime.start || now > Date.parse(downtime.start)) && now < Date.parse(downtime.end)) ? downtime : {}; } else { return {} diff --git a/WebApp/static/core/js/views/tabs/ContextMenu.js b/WebApp/static/core/js/views/tabs/ContextMenu.js index 95216ea1a..a69fcc8cf 100755 --- a/WebApp/static/core/js/views/tabs/ContextMenu.js +++ b/WebApp/static/core/js/views/tabs/ContextMenu.js @@ -297,14 +297,6 @@ Ext.define("Ext.dirac.views.tabs.ContextMenu", { }); } } - }, - { - text: "Create downtime for application", - iconCls: "core-desktop-icon", - value: 8, - handler: function() { - GLOBAL.APP.MAIN_VIEW.SM.formSetDowntime(me.oSelectedMenuItem.data.application) - } } ] }); diff --git a/WebApp/static/core/js/views/tabs/SelPanel.js b/WebApp/static/core/js/views/tabs/SelPanel.js index 14f2ca842..8670d7dd2 100644 --- a/WebApp/static/core/js/views/tabs/SelPanel.js +++ b/WebApp/static/core/js/views/tabs/SelPanel.js @@ -333,10 +333,6 @@ Ext.define("Ext.dirac.views.tabs.SelPanel", { var me = this; me.contextMenu.oSelectedMenuItem = record; - if (!('AdministratorCS' in GLOBAL.APP.configData.user.properties)) { - me.contextMenu.disableMenuItem(8); - } - if (record.get("type") == "desktop") { me.contextMenu.enableMenuItem(0); me.contextMenu.disableMenuItem(1); diff --git a/WebApp/static/core/js/views/tabs/StateManagement.js b/WebApp/static/core/js/views/tabs/StateManagement.js index ff2e8d4b1..358058f65 100755 --- a/WebApp/static/core/js/views/tabs/StateManagement.js +++ b/WebApp/static/core/js/views/tabs/StateManagement.js @@ -5,126 +5,8 @@ */ Ext.define("Ext.dirac.views.tabs.StateManagement", { - requires: ["Ext.form.field.Text", "Ext.form.field.Date", "Ext.button.Button", "Ext.toolbar.Toolbar", "Ext.panel.Panel", "Ext.window.Window"], + requires: ["Ext.form.field.Text", "Ext.button.Button", "Ext.toolbar.Toolbar", "Ext.panel.Panel", "Ext.window.Window"], - /** - * Function called when the create downtime is clicked - * - * @param {String} - * sAppName Application class name - */ - formSetDowntime: function(sAppName) { - var me = this; - - me.txtReason = Ext.create("Ext.form.field.Text", { - fieldLabel: "Reason:", - labelAlign: "left", - margin: 10, - width: 400, - enableKeyEvents: true, - validateValue: function(sValue) { - sValue = Ext.util.Format.trim(sValue); - if (sValue.length < 1) { - this.markInvalid("You must specify a reason!"); - return false; - } - }, - validateOnChange: true, - validateOnBlur: false, - listeners: { - keypress: function(oTextField, e, eOpts) { - if (e.getCharCode() == 13) { - if (me.txtReason.isValid()) { - var message = me.txtReason.getValue(); - } - } - } - } - }); - - me.calendarFrom = new Ext.create("Ext.form.field.Date", { - width: 100, - format: "Y-m-d", - fieldLabel: "Initial Date", - labelAlign: "top", - hidden: true - }); - - me.calendarTo = new Ext.create("Ext.form.field.Date", { - width: 100, - format: "Y-m-d", - fieldLabel: "End Date", - labelAlign: "top", - hidden: true - }); - - // button for saving the state - me.btnAddDowntime = new Ext.Button({ - text: "Create downtime", - margin: 3, - iconCls: "dirac-icon-save", - handler: function() { - if (me.txtReason.isValid()) { - Ext.Ajax.request({ - url: GLOBAL.BASE_URL + "Downtimes/setApplicationDowntime", - params: { - app: sAppName, - message: me.txtReason.getValue(), - start: me.calendarFrom.getValue(), - end: me.calendarTo.getValue() - }, - scope: me, - success: function(response) { - GLOBAL.APP.CF.msg('Downtime added!') - }, - failure: function(response) { - GLOBAL.APP.CF.showAjaxErrorMessage(response); - } - }); - } - }, - scope: me - }); - - // button to close the save form - me.btnCancel = new Ext.Button({ - text: "Cancel", - margin: 3, - iconCls: "toolbar-other-close", - handler: function() { - me.txtReason.setValue(""); - me.start.setValue(""); - me.end.setValue(""); - me.setDowntimeWindow.hide(); - }, - scope: me - }); - - var oToolbar = new Ext.toolbar.Toolbar({ - border: false - }); - - oToolbar.add([me.btnAddDowntime, me.btnCancel]); - - var oPanel = new Ext.create("Ext.panel.Panel", { - autoHeight: true, - border: false, - items: [oToolbar, me.txtReason] - }); - - // initializing window showing the saving form - me.setDowntimeWindow = Ext.create("widget.window", { - height: 120, - width: 500, - title: "Set downtime", - layout: "fit", - modal: true, - items: oPanel - }); - - me.setDowntimeWindow.show(); - me.txtReason.focus(); - }, /** * Function called when the Save As ... button from the SAVE window menu * is clicked From bea26e9bbcf48f8e0f33d084442a9c7e62c63181 Mon Sep 17 00:00:00 2001 From: TaykYoku Date: Wed, 28 Jul 2021 22:39:25 +0200 Subject: [PATCH 11/15] v4r2p5, notes --- WebApp/static/core/js/core/App.js | 2 -- __init__.py | 2 +- release.notes | 6 ++++++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/WebApp/static/core/js/core/App.js b/WebApp/static/core/js/core/App.js index 9d273b69f..b18e8e5bc 100755 --- a/WebApp/static/core/js/core/App.js +++ b/WebApp/static/core/js/core/App.js @@ -284,8 +284,6 @@ Ext.define("Ext.dirac.core.App", { The optional 'Z' part denotes the time zone in the format +-hh:mm. A single letter Z would mean UTC+0. Shorter variants are also possible, like YYYY-MM-DDTHH:mm, YYYY-MM-DD or YYYY-MM or even YYYY. */ - - return !downtime.end ? {} : ((!downtime.start || now > Date.parse(downtime.start)) && now < Date.parse(downtime.end)) ? downtime : {}; } else { return {} diff --git a/__init__.py b/__init__.py index b18d0c248..0719e0c28 100644 --- a/__init__.py +++ b/__init__.py @@ -13,7 +13,7 @@ majorVersion = 4 minorVersion = 2 -patchLevel = 4 +patchLevel = 5 preVersion = 0 version = "v%sr%s" % (majorVersion, minorVersion) diff --git a/release.notes b/release.notes index 41810ff99..a4b896304 100644 --- a/release.notes +++ b/release.notes @@ -1,3 +1,9 @@ +[v4r2p5] + +CHANGE: (#506) change datetime field behavior in selector, use Time field +CHANGE: (#505) get hosts from DB for SystemAdministrator +NEW: (#503) declare downtime for the application + [v4r2p4] FIX: (#495) copy SettingsPanel.js to desktop folder From 005acc802ab594710851b2744903e2a080dc132c Mon Sep 17 00:00:00 2001 From: TaykYoku Date: Wed, 28 Jul 2021 23:20:06 +0200 Subject: [PATCH 12/15] notes --- release.notes | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/release.notes b/release.notes index 81fd5258b..cf42a22bc 100644 --- a/release.notes +++ b/release.notes @@ -1,5 +1,6 @@ -[v4r3-pre11] +[v4r3-pre12] +NEW: (#501) add VMDIRAC application CHANGE: (#502) remove Desktop view FIX: (#500) move run_in_executor part to asyncGen decorated method FIX: (#499) Create the directory in /WebApp/StaticResourceLinkDir if it doesn't already exist From c40ef90bd49f16a03c3a8334fb637565f1fc241f Mon Sep 17 00:00:00 2001 From: TaykYoku Date: Wed, 28 Jul 2021 23:24:55 +0200 Subject: [PATCH 13/15] fix --- .../WebApp/static/core/js/core/App.js | 8 ++--- .../core/js/utils/DiracTimeSearchPanel.js | 29 ++++++++----------- .../WebApp/static/core/js/views/tabs/Main.js | 2 +- 3 files changed, 17 insertions(+), 22 deletions(-) diff --git a/src/WebAppDIRAC/WebApp/static/core/js/core/App.js b/src/WebAppDIRAC/WebApp/static/core/js/core/App.js index b18e8e5bc..451bc68e7 100755 --- a/src/WebAppDIRAC/WebApp/static/core/js/core/App.js +++ b/src/WebAppDIRAC/WebApp/static/core/js/core/App.js @@ -251,9 +251,9 @@ Ext.define("Ext.dirac.core.App", { */ getApplicationSettings: function(sAppName) { if (sAppName in GLOBAL.APP.configData.configuration) { - return GLOBAL.APP.configData.configuration[sAppName] + return GLOBAL.APP.configData.configuration[sAppName]; } else { - return {} + return {}; } }, @@ -284,9 +284,9 @@ Ext.define("Ext.dirac.core.App", { The optional 'Z' part denotes the time zone in the format +-hh:mm. A single letter Z would mean UTC+0. Shorter variants are also possible, like YYYY-MM-DDTHH:mm, YYYY-MM-DD or YYYY-MM or even YYYY. */ - return !downtime.end ? {} : ((!downtime.start || now > Date.parse(downtime.start)) && now < Date.parse(downtime.end)) ? downtime : {}; + return !downtime.end ? {} : (!downtime.start || now > Date.parse(downtime.start)) && now < Date.parse(downtime.end) ? downtime : {}; } else { - return {} + return {}; } } }, diff --git a/src/WebAppDIRAC/WebApp/static/core/js/utils/DiracTimeSearchPanel.js b/src/WebAppDIRAC/WebApp/static/core/js/utils/DiracTimeSearchPanel.js index 9c4029e77..0f9a1d558 100644 --- a/src/WebAppDIRAC/WebApp/static/core/js/utils/DiracTimeSearchPanel.js +++ b/src/WebAppDIRAC/WebApp/static/core/js/utils/DiracTimeSearchPanel.js @@ -54,7 +54,7 @@ Ext.define("Ext.dirac.utils.DiracTimeSearchPanel", { }, loadState: function(data) { var me = this; - + data.timeSearchPanelHidden ? me.hide : me.show(); // END - For the time span searching sub-panel @@ -122,7 +122,7 @@ Ext.define("Ext.dirac.utils.DiracTimeSearchPanel", { }); me.cmbTimeFrom = new Ext.create("Ext.form.field.Time", { - format: 'H:i', + format: "H:i", flex: 2, increment: 30, margin: "0 0 0 10", @@ -137,8 +137,8 @@ Ext.define("Ext.dirac.utils.DiracTimeSearchPanel", { me.fromDate = { xtype: "panel", layout: { - type: 'hbox', - align: 'bottom' + type: "hbox", + align: "bottom" }, border: false, margin: "0 0 5 0", @@ -148,7 +148,7 @@ Ext.define("Ext.dirac.utils.DiracTimeSearchPanel", { me.calenTo = new Ext.create("Ext.form.field.Date", { labelAlign: "top", fieldLabel: "To", - labelStyle: 'width:20px', + labelStyle: "width:20px", flex: 3, format: "Y-m-d", hidden: true, @@ -160,7 +160,7 @@ Ext.define("Ext.dirac.utils.DiracTimeSearchPanel", { }); me.cmbTimeTo = new Ext.create("Ext.form.field.Time", { - format: 'H:i', + format: "H:i", flex: 2, increment: 30, margin: "0 0 0 10", @@ -175,8 +175,8 @@ Ext.define("Ext.dirac.utils.DiracTimeSearchPanel", { me.toDate = { xtype: "panel", layout: { - type: 'hbox', - align: 'bottom' + type: "hbox", + align: "bottom" }, border: false, margin: "0 0 5 0", @@ -192,7 +192,7 @@ Ext.define("Ext.dirac.utils.DiracTimeSearchPanel", { me.cmbTimeFrom.setValue(null); me.calenTo.setRawValue(""); me.calenFrom.setRawValue(""); - me.btnResetTimePanel.hide() + me.btnResetTimePanel.hide(); }, scope: me, hidden: true @@ -209,12 +209,7 @@ Ext.define("Ext.dirac.utils.DiracTimeSearchPanel", { }; Ext.apply(me, { - items: [ - me.cmbTimeSpan, - me.fromDate, - me.toDate, - me.resetDate - ] + items: [me.cmbTimeSpan, me.fromDate, me.toDate, me.resetDate] }); me.callParent(arguments); }, @@ -262,9 +257,9 @@ Ext.define("Ext.dirac.utils.DiracTimeSearchPanel", { // Collect data for filtration data["startDate"] = sStartDate; - data["startTime"] = sStartTime ? sStartTime.getHours() + ':' + sStartTime.getMinutes() : sStartTime; + data["startTime"] = sStartTime ? sStartTime.getHours() + ":" + sStartTime.getMinutes() : sStartTime; data["endDate"] = sEndDate; - data["endTime"] = sEndTime ? sEndTime.getHours() + ':' + sEndTime.getMinutes() : sEndTime; + data["endTime"] = sEndTime ? sEndTime.getHours() + ":" + sEndTime.getMinutes() : sEndTime; return data; } }); diff --git a/src/WebAppDIRAC/WebApp/static/core/js/views/tabs/Main.js b/src/WebAppDIRAC/WebApp/static/core/js/views/tabs/Main.js index cae1d3b71..2459914d9 100644 --- a/src/WebAppDIRAC/WebApp/static/core/js/views/tabs/Main.js +++ b/src/WebAppDIRAC/WebApp/static/core/js/views/tabs/Main.js @@ -812,7 +812,7 @@ Ext.define("Ext.dirac.views.tabs.Main", { if (downtime.message) { return GLOBAL.APP.CF.alert(downtime.message, "info"); } - + Ext.get("app-dirac-loading").show(); if (loadedObjectType == "app") { From e8530bbac0bf2697c854a8b5334100702a1cf6b6 Mon Sep 17 00:00:00 2001 From: TaykYoku Date: Wed, 28 Jul 2021 23:32:42 +0200 Subject: [PATCH 14/15] fix deprecated --- src/WebAppDIRAC/Lib/SessionData.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WebAppDIRAC/Lib/SessionData.py b/src/WebAppDIRAC/Lib/SessionData.py index 92e149fe6..25e00666e 100644 --- a/src/WebAppDIRAC/Lib/SessionData.py +++ b/src/WebAppDIRAC/Lib/SessionData.py @@ -9,7 +9,7 @@ from DIRAC.Core.DISET.AuthManager import AuthManager from DIRAC.Core.DISET.ThreadConfig import ThreadConfig from DIRAC.ConfigurationSystem.Client.Helpers import Registry -from DIRAC.ConfigurationSystem.Client.Helpers import CSGlobals +from DIRAC.Core.Utilities.Extensions import extensionsByPriority from WebAppDIRAC.Lib import Conf @@ -36,7 +36,7 @@ def setHandlers(cls, handlers): cls.__handlers[handler.LOCATION.strip("/")] = handler # Calculate extensions # TODO: Remove use of deprecated function - cls.__extensions = CSGlobals.getInstalledExtensions() + cls.__extensions = extensionsByPriority() for ext in ['DIRAC', 'WebAppDIRAC']: if ext in cls.__extensions: cls.__extensions.append(cls.__extensions.pop(cls.__extensions.index(ext))) From aaddb9a1fa317a2f014e9be12f71d45c3b2c40c4 Mon Sep 17 00:00:00 2001 From: TaykYoku Date: Wed, 28 Jul 2021 23:37:09 +0200 Subject: [PATCH 15/15] fix deprecated --- src/WebAppDIRAC/Lib/Conf.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/WebAppDIRAC/Lib/Conf.py b/src/WebAppDIRAC/Lib/Conf.py index 375c2d5c1..8ffb19e58 100644 --- a/src/WebAppDIRAC/Lib/Conf.py +++ b/src/WebAppDIRAC/Lib/Conf.py @@ -3,9 +3,9 @@ import uuid import tempfile import tornado.process + from DIRAC import gConfig from DIRAC.Core.Security import Locations, X509Chain, X509CRL -from DIRAC.Core.Utilities.Decorators import deprecated __RCSID__ = "$Id$" @@ -253,11 +253,6 @@ def getIcon(): return getCSValue("Icon", "/static/core/img/icons/system/favicon.ico") -@deprecated("Please, use SSLProtocol instead.") -def SSLProrocol(): - return SSLProtocol() - - def SSLProtocol(): """ Get ssl protocol