Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/zabbix/zabbix.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Shubin <aleksandrs.subins@zabbix.com>2022-11-04 19:49:18 +0300
committerAndrejs Verza <andrejs.verza@zabbix.com>2022-11-04 19:49:18 +0300
commit2181d67326038b8a3ef2f420fa26579f13046278 (patch)
treea3879879bc80ff262345771b2487bda8061c397e
parent013f74ffb5d098cde3f86e6baba2a135c517373a (diff)
parent953c2171dcb59a87e1c854c6ae1a855bd3073d57 (diff)
..F....... [ZBXNEXT-7469] simplified creation of dashboard widgets; moved widgets to modules; updated modules framework
Merge in ZBX/zabbix from feature/ZBXNEXT-7469-6.3 to master * commit '953c2171dcb59a87e1c854c6ae1a855bd3073d57': (152 commits) ..F....... [ZBXNEXT-7469] implemented dashboard configuration monitoring #4 ..F....... [ZBXNEXT-7469] implemented dashboard configuration monitoring #3 ..F....... [ZBXNEXT-7469] implemented dashboard configuration monitoring #2 ..F....... [ZBXNEXT-7469] implemented dashboard configuration monitoring ..F....... [ZBXNEXT-7469] added phpdocs to Widget form view ..F....... [ZBXNEXT-7469] fixed page loading errors #4 ..F....... [ZBXNEXT-7469] fixed page loading errors #3 ..F....... [ZBXNEXT-7469] fixed page loading errors #2 ..F....... [ZBXNEXT-7469] fixed page loading errors ..F....... [ZBXNEXT-7469] fixed inaccessible widget ..F....... [ZBXNEXT-7469] fixed console errors when no widget modules are available ..F....... [ZBXNEXT-7469] fixed widget placeholder freeze when no modules are enabled .......... [ZBXNEXT-7469] updated widget type remembering test after intentional change of behavior ..F....... [ZBXNEXT-7469] fixed style of inaccessible widgets ..F....... [ZBXNEXT-7469] fixed saving new dashboards ..F....... [ZBXNEXT-7469] fixed saving templated dashboards ..F....... [ZBXNEXT-7469] fixed saving the last used type of added widgets ..F....... [ZBXNEXT-7469] fixed copying and pasting inaccessible widgets ..F....... [ZBXNEXT-7469] fixed addition of widgets when no widgets available ..F....... [ZBXNEXT-7469] fixed static header of inaccessible widgets ...
-rwxr-xr-xChangeLog.d/feature/ZBXNEXT-74691
-rw-r--r--create/src/data.tmpl26
-rw-r--r--create/src/schema.tmpl4
-rw-r--r--sass/stylesheets/sass/components/_columns-wrapper.scss79
-rw-r--r--sass/stylesheets/sass/components/_section.scss72
-rw-r--r--sass/stylesheets/sass/components/dashboard/_dashboard.scss4
-rw-r--r--sass/stylesheets/sass/components/dashboard/_widget-clock.scss55
-rwxr-xr-xsass/stylesheets/sass/components/dashboard/_widget-inaccessible.scss8
-rw-r--r--sass/stylesheets/sass/components/dashboard/_widget-item.scss112
-rw-r--r--sass/stylesheets/sass/components/dashboard/_widget-svggraph.scss187
-rw-r--r--sass/stylesheets/sass/hc-dark.scss40
-rw-r--r--sass/stylesheets/sass/hc-light.scss35
-rw-r--r--sass/stylesheets/sass/layout/_form-grid.scss6
-rw-r--r--sass/stylesheets/sass/screen.scss172
-rw-r--r--sass/stylesheets/sass/utils/_sortable.scss8
-rw-r--r--src/libs/zbxdbupgrade/dbupgrade_6030.c88
-rw-r--r--ui/app/controllers/CControllerDashboardConfigurationHashGet.php98
-rw-r--r--ui/app/controllers/CControllerDashboardPrint.php2
-rw-r--r--ui/app/controllers/CControllerDashboardUpdate.php194
-rw-r--r--ui/app/controllers/CControllerDashboardView.php55
-rw-r--r--ui/app/controllers/CControllerDashboardWidgetCheck.php34
-rw-r--r--ui/app/controllers/CControllerDashboardWidgetConfigure.php87
-rw-r--r--ui/app/controllers/CControllerDashboardWidgetEdit.php174
-rw-r--r--ui/app/controllers/CControllerDashboardWidgetRfRate.php2
-rw-r--r--ui/app/controllers/CControllerDashboardWidgetView.php107
-rw-r--r--ui/app/controllers/CControllerDashboardWidgetsSanitize.php69
-rw-r--r--ui/app/controllers/CControllerFavoriteCreate.php (renamed from ui/app/controllers/CControllerFavouriteCreate.php)2
-rw-r--r--ui/app/controllers/CControllerFavoriteDelete.php (renamed from ui/app/controllers/CControllerFavouriteDelete.php)18
-rw-r--r--ui/app/controllers/CControllerHintboxEventlist.php2
-rw-r--r--ui/app/controllers/CControllerHostDashboardView.php8
-rw-r--r--ui/app/controllers/CControllerModuleEdit.php26
-rw-r--r--ui/app/controllers/CControllerModuleList.php15
-rw-r--r--ui/app/controllers/CControllerModuleScan.php56
-rw-r--r--ui/app/controllers/CControllerModuleUpdate.php16
-rw-r--r--ui/app/controllers/CControllerProblem.php2
-rw-r--r--ui/app/controllers/CControllerProblemView.php2
-rw-r--r--ui/app/controllers/CControllerProblemViewRefresh.php4
-rw-r--r--ui/app/controllers/CControllerProfileUpdate.php21
-rw-r--r--ui/app/controllers/CControllerTemplateDashboardEdit.php18
-rw-r--r--ui/app/controllers/CControllerTemplateDashboardUpdate.php158
-rw-r--r--ui/app/controllers/CControllerUserEdit.php37
-rw-r--r--ui/app/controllers/CControllerUserroleEdit.php43
-rw-r--r--ui/app/controllers/CControllerUserroleEditGeneral.php8
-rw-r--r--ui/app/controllers/CControllerWidget.php148
-rw-r--r--ui/app/controllers/CControllerWidgetIterator.php46
-rw-r--r--ui/app/controllers/CControllerWidgetProblemsBySvView.php74
-rw-r--r--ui/app/controllers/CControllerWidgetSvgGraphView.php183
-rw-r--r--ui/app/controllers/CControllerWidgetTrigOverView.php73
-rw-r--r--ui/app/partials/configuration.hostgroup.edit.html.php2
-rw-r--r--ui/app/partials/configuration.templategroup.edit.html.php2
-rw-r--r--ui/app/partials/layout.htmlpage.header.php67
-rw-r--r--ui/app/partials/monitoring.host.filter.php4
-rw-r--r--ui/app/partials/monitoring.latest.filter.php4
-rw-r--r--ui/app/partials/monitoring.problem.filter.php8
-rw-r--r--ui/app/views/administration.audit.settings.edit.php6
-rw-r--r--ui/app/views/administration.authentication.edit.php6
-rw-r--r--ui/app/views/administration.autoreg.edit.php6
-rw-r--r--ui/app/views/administration.geomaps.edit.php6
-rw-r--r--ui/app/views/administration.gui.edit.php6
-rw-r--r--ui/app/views/administration.housekeeping.edit.php6
-rw-r--r--ui/app/views/administration.iconmap.edit.php6
-rw-r--r--ui/app/views/administration.iconmap.list.php4
-rw-r--r--ui/app/views/administration.image.edit.php6
-rw-r--r--ui/app/views/administration.image.list.php8
-rw-r--r--ui/app/views/administration.macros.edit.php6
-rw-r--r--ui/app/views/administration.mediatype.edit.php8
-rw-r--r--ui/app/views/administration.mediatype.list.php6
-rw-r--r--ui/app/views/administration.miscconfig.edit.php6
-rw-r--r--ui/app/views/administration.module.edit.php13
-rw-r--r--ui/app/views/administration.module.list.php11
-rw-r--r--ui/app/views/administration.queue.details.php4
-rw-r--r--ui/app/views/administration.queue.overview.php4
-rw-r--r--ui/app/views/administration.queue.overview.proxy.php4
-rw-r--r--ui/app/views/administration.regex.edit.php6
-rw-r--r--ui/app/views/administration.regex.list.php4
-rw-r--r--ui/app/views/administration.script.edit.php8
-rw-r--r--ui/app/views/administration.script.list.php4
-rw-r--r--ui/app/views/administration.token.list.php4
-rw-r--r--ui/app/views/administration.trigdisplay.edit.php6
-rw-r--r--ui/app/views/administration.user.edit.php22
-rw-r--r--ui/app/views/administration.user.list.php4
-rw-r--r--ui/app/views/administration.user.token.list.php4
-rw-r--r--ui/app/views/administration.usergroup.edit.php10
-rw-r--r--ui/app/views/administration.usergroup.list.php7
-rw-r--r--ui/app/views/administration.userrole.edit.php39
-rw-r--r--ui/app/views/administration.userrole.list.php7
-rw-r--r--ui/app/views/configuration.correlation.edit.php10
-rw-r--r--ui/app/views/configuration.correlation.list.php8
-rw-r--r--ui/app/views/configuration.dashboard.edit.php16
-rw-r--r--ui/app/views/configuration.dashboard.list.php2
-rw-r--r--ui/app/views/configuration.discovery.edit.php10
-rw-r--r--ui/app/views/configuration.discovery.list.php9
-rw-r--r--ui/app/views/configuration.host.edit.php2
-rw-r--r--ui/app/views/configuration.host.list.php6
-rw-r--r--ui/app/views/configuration.hostgroup.edit.php2
-rw-r--r--ui/app/views/configuration.hostgroup.list.php4
-rw-r--r--ui/app/views/configuration.templategroup.edit.php2
-rw-r--r--ui/app/views/configuration.templategroup.list.php4
-rw-r--r--ui/app/views/js/configuration.dashboard.edit.js.php10
-rw-r--r--ui/app/views/js/monitoring.dashboard.print.js.php1
-rw-r--r--ui/app/views/js/monitoring.dashboard.view.js.php48
-rw-r--r--ui/app/views/js/monitoring.host.dashboard.view.js.php12
-rw-r--r--ui/app/views/js/popup.massupdate.tmpl.js.php2
-rw-r--r--ui/app/views/monitoring.charts.view.php12
-rw-r--r--ui/app/views/monitoring.dashboard.list.php9
-rw-r--r--ui/app/views/monitoring.dashboard.print.php14
-rw-r--r--ui/app/views/monitoring.dashboard.view.php31
-rw-r--r--ui/app/views/monitoring.dashboard.widget.edit.php84
-rw-r--r--ui/app/views/monitoring.discovery.view.php4
-rw-r--r--ui/app/views/monitoring.host.dashboard.view.php22
-rw-r--r--ui/app/views/monitoring.host.view.php17
-rw-r--r--ui/app/views/monitoring.latest.view.php18
-rw-r--r--ui/app/views/monitoring.map.view.php4
-rw-r--r--ui/app/views/monitoring.problem.view.php6
-rw-r--r--ui/app/views/monitoring.web.view.php2
-rw-r--r--ui/app/views/monitoring.widget.dataover.view.php47
-rw-r--r--ui/app/views/monitoring.widget.graph.view.php55
-rw-r--r--ui/app/views/monitoring.widget.map.view.php43
-rw-r--r--ui/app/views/monitoring.widget.svggraph.view.php52
-rw-r--r--ui/app/views/monitoring.widget.trigover.view.php47
-rw-r--r--ui/app/views/popup.massupdate.service.php2
-rw-r--r--ui/app/views/popup.service.edit.php4
-rw-r--r--ui/app/views/popup.sla.edit.php2
-rw-r--r--ui/app/views/popup.view.php2
-rw-r--r--ui/app/views/proxy.list.php2
-rw-r--r--ui/app/views/report.status.php2
-rw-r--r--ui/app/views/reports.auditlog.list.php4
-rw-r--r--ui/app/views/reports.scheduledreport.edit.php6
-rw-r--r--ui/app/views/reports.scheduledreport.list.php4
-rw-r--r--ui/app/views/search.php58
-rw-r--r--ui/app/views/service.list.edit.php2
-rw-r--r--ui/app/views/service.list.php2
-rw-r--r--ui/app/views/sla.list.php2
-rw-r--r--ui/app/views/slareport.list.php4
-rw-r--r--ui/app/views/system.warning.php10
-rwxr-xr-xui/app/views/widget.edit.php29
-rwxr-xr-xui/app/views/widget.view.php29
-rw-r--r--ui/assets/styles/blue-theme.css633
-rw-r--r--ui/assets/styles/dark-theme.css633
-rw-r--r--ui/assets/styles/hc-dark.css647
-rw-r--r--ui/assets/styles/hc-light.css646
-rw-r--r--ui/hostinventoriesoverview.php2
-rw-r--r--ui/httpdetails.php2
-rw-r--r--ui/include/classes/api/services/CConfiguration.php6
-rw-r--r--ui/include/classes/api/services/CModule.php8
-rw-r--r--ui/include/classes/api/services/CRole.php15
-rw-r--r--ui/include/classes/core/CModule.php138
-rw-r--r--ui/include/classes/core/CModuleManager.php396
-rwxr-xr-xui/include/classes/core/CWidget.php164
-rw-r--r--ui/include/classes/core/ZBase.php296
-rw-r--r--ui/include/classes/helpers/CDashboardHelper.php216
-rw-r--r--ui/include/classes/helpers/CDocHelper.php6
-rw-r--r--ui/include/classes/helpers/CMessageHelper.php7
-rw-r--r--ui/include/classes/helpers/CSvgGraphHelper.php8
-rw-r--r--ui/include/classes/html/CBarGauge.php3
-rw-r--r--ui/include/classes/html/CCollapsibleUiWidget.php103
-rw-r--r--ui/include/classes/html/CColor.php6
-rw-r--r--ui/include/classes/html/CHtmlPage.php (renamed from ui/include/classes/html/widget/CWidget.php)94
-rw-r--r--ui/include/classes/html/CHtmlPageHeader.php181
-rw-r--r--ui/include/classes/html/CLabel.php12
-rw-r--r--ui/include/classes/html/CRadioButtonList.php2
-rw-r--r--ui/include/classes/html/CSection.php68
-rwxr-xr-xui/include/classes/html/CSectionCollapsible.php59
-rw-r--r--ui/include/classes/html/CTemplateTag.php34
-rw-r--r--ui/include/classes/html/CUiWidget.php136
-rw-r--r--ui/include/classes/html/pageheader/CPageHeader.php190
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldCheckBoxListView.php59
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldCheckBoxView.php40
-rwxr-xr-x[-rw-r--r--]ui/include/classes/html/widgets/CWidgetFieldColorView.php (renamed from ui/include/classes/html/CScriptTemplate.php)39
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldColumnsListView.php91
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldDatePickerView.php62
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldGraphDataSetView.php440
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldGraphOverrideView.php348
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldHostPatternSelectView.php65
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldIntegerBoxView.php37
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldLatLngView.php72
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldMultiSelectGraphPrototypeView.php42
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldMultiSelectGraphView.php42
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldMultiSelectGroupView.php42
-rwxr-xr-x[-rw-r--r--]ui/include/classes/html/widgets/CWidgetFieldMultiSelectHostView.php (renamed from ui/app/views/js/monitoring.dashboard.widget.edit.js.php)29
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldMultiSelectItemPrototypeView.php40
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldMultiSelectItemView.php40
-rwxr-xr-x[-rw-r--r--]ui/include/classes/html/widgets/CWidgetFieldMultiSelectServiceView.php (renamed from ui/include/classes/widgets/views/js/widget.problems.form.view.js.php)20
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldMultiSelectSlaView.php40
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldMultiSelectView.php106
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldNumericBoxView.php58
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldRadioButtonListView.php43
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldRangeControlView.php52
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldSelectResourceView.php54
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldSelectView.php55
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldSeveritiesView.php36
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldTagsView.php118
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldTextAreaView.php59
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldTextBoxView.php71
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldThresholdsView.php100
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldTimeZoneView.php47
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldUrlView.php35
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldView.php91
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFieldWidgetSelectView.php72
-rwxr-xr-xui/include/classes/html/widgets/CWidgetFormView.php281
-rwxr-xr-xui/include/classes/html/widgets/CWidgetView.php69
-rw-r--r--ui/include/classes/import/converters/C62ImportConverter.php43
-rw-r--r--ui/include/classes/import/converters/CImportConverterFactory.php38
-rw-r--r--ui/include/classes/import/validators/C64XmlValidator.php11
-rw-r--r--ui/include/classes/mvc/CControllerResponse.php2
-rw-r--r--ui/include/classes/mvc/CRouter.php85
-rw-r--r--ui/include/classes/mvc/CView.php128
-rw-r--r--ui/include/classes/setup/CSetupWizard.php4
-rw-r--r--ui/include/classes/widgets/CWidgetConfig.php501
-rw-r--r--ui/include/classes/widgets/CWidgetField.php (renamed from ui/include/classes/widgets/fields/CWidgetField.php)274
-rw-r--r--ui/include/classes/widgets/CWidgetForm.php (renamed from ui/include/classes/widgets/forms/CWidgetForm.php)181
-rw-r--r--ui/include/classes/widgets/CWidgetHelper.php1611
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldCheckBox.php29
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldCheckBoxList.php31
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldColor.php38
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldColumnsList.php132
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldDatePicker.php54
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldGraphDataSet.php160
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldGraphOverride.php119
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldHidden.php35
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldHostPatternSelect.php51
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldIntegerBox.php48
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldLatLng.php36
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldMsHost.php52
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldMultiSelect.php (renamed from ui/include/classes/widgets/fields/CWidgetFieldMs.php)86
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldMultiSelectGraph.php (renamed from ui/include/classes/widgets/fields/CWidgetFieldMsGraph.php)16
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldMultiSelectGraphPrototype.php (renamed from ui/include/classes/widgets/fields/CWidgetFieldMsGraphPrototype.php)16
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldMultiSelectGroup.php (renamed from ui/include/classes/widgets/fields/CWidgetFieldMsGroup.php)8
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldMultiSelectHost.php31
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldMultiSelectItem.php (renamed from ui/include/classes/widgets/fields/CWidgetFieldMsItem.php)16
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldMultiSelectItemPrototype.php (renamed from ui/include/classes/widgets/fields/CWidgetFieldMsItemPrototype.php)16
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldMultiSelectService.php (renamed from ui/include/classes/widgets/fields/CWidgetFieldMsService.php)14
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldMultiSelectSla.php (renamed from ui/include/classes/widgets/fields/CWidgetFieldMsSla.php)14
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldNavTree.php78
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldNumericBox.php48
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldRadioButtonList.php37
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldRangeControl.php57
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldReference.php22
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldSelect.php33
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldSelectResource.php98
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldSeverities.php6
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldTags.php70
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldTextArea.php43
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldTextBox.php50
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldThresholds.php57
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldTimeZone.php71
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldUrl.php36
-rw-r--r--ui/include/classes/widgets/fields/CWidgetFieldWidgetSelect.php71
-rw-r--r--ui/include/classes/widgets/forms/CWidgetFormActionLog.php60
-rw-r--r--ui/include/classes/widgets/forms/CWidgetFormClock.php255
-rw-r--r--ui/include/classes/widgets/forms/CWidgetFormDataOver.php97
-rw-r--r--ui/include/classes/widgets/forms/CWidgetFormGeoMap.php83
-rw-r--r--ui/include/classes/widgets/forms/CWidgetFormGraph.php95
-rw-r--r--ui/include/classes/widgets/forms/CWidgetFormGraphPrototype.php95
-rw-r--r--ui/include/classes/widgets/forms/CWidgetFormHostAvail.php71
-rw-r--r--ui/include/classes/widgets/forms/CWidgetFormItem.php461
-rw-r--r--ui/include/classes/widgets/forms/CWidgetFormMap.php80
-rw-r--r--ui/include/classes/widgets/forms/CWidgetFormNavTree.php60
-rw-r--r--ui/include/classes/widgets/forms/CWidgetFormPlainText.php87
-rw-r--r--ui/include/classes/widgets/forms/CWidgetFormProblemHosts.php136
-rw-r--r--ui/include/classes/widgets/forms/CWidgetFormProblems.php243
-rw-r--r--ui/include/classes/widgets/forms/CWidgetFormProblemsBySv.php202
-rw-r--r--ui/include/classes/widgets/forms/CWidgetFormSlaReport.php145
-rw-r--r--ui/include/classes/widgets/forms/CWidgetFormSvgGraph.php635
-rw-r--r--ui/include/classes/widgets/forms/CWidgetFormSystemInfo.php43
-rw-r--r--ui/include/classes/widgets/forms/CWidgetFormTopHosts.php171
-rw-r--r--ui/include/classes/widgets/forms/CWidgetFormTrigOver.php113
-rw-r--r--ui/include/classes/widgets/forms/CWidgetFormUrl.php51
-rw-r--r--ui/include/classes/widgets/forms/CWidgetFormWeb.php93
-rw-r--r--ui/include/classes/widgets/views/js/widget.clock.form.view.js.php102
-rw-r--r--ui/include/classes/widgets/views/widget.clock.form.view.php179
-rw-r--r--ui/include/classes/widgets/views/widget.dataover.form.view.php90
-rw-r--r--ui/include/classes/widgets/views/widget.geomap.form.view.php96
-rw-r--r--ui/include/classes/widgets/views/widget.graph.form.view.php89
-rw-r--r--ui/include/classes/widgets/views/widget.graphprototype.form.view.php101
-rw-r--r--ui/include/classes/widgets/views/widget.hostavail.form.view.php80
-rw-r--r--ui/include/classes/widgets/views/widget.item.form.view.php262
-rw-r--r--ui/include/classes/widgets/views/widget.map.form.view.php85
-rw-r--r--ui/include/classes/widgets/views/widget.navtree.form.view.php72
-rw-r--r--ui/include/classes/widgets/views/widget.plaintext.form.view.php81
-rw-r--r--ui/include/classes/widgets/views/widget.problemhosts.form.view.php118
-rw-r--r--ui/include/classes/widgets/views/widget.problems.form.view.php178
-rw-r--r--ui/include/classes/widgets/views/widget.problemsbysv.form.view.php142
-rw-r--r--ui/include/classes/widgets/views/widget.slareport.form.view.php98
-rw-r--r--ui/include/classes/widgets/views/widget.svggraph.form.view.php328
-rw-r--r--ui/include/classes/widgets/views/widget.tophosts.form.view.php118
-rw-r--r--ui/include/classes/widgets/views/widget.trigover.form.view.php96
-rw-r--r--ui/include/classes/widgets/views/widget.url.form.view.php56
-rw-r--r--ui/include/classes/widgets/views/widget.web.form.view.php94
-rw-r--r--ui/include/defines.inc.php126
-rw-r--r--ui/include/func.inc.php16
-rw-r--r--ui/include/html.inc.php10
-rw-r--r--ui/include/page_header.php83
-rw-r--r--ui/include/validate.inc.php2
-rw-r--r--ui/include/views/administration.auditacts.list.php11
-rw-r--r--ui/include/views/configuration.action.edit.php11
-rw-r--r--ui/include/views/configuration.action.list.php9
-rw-r--r--ui/include/views/configuration.copy.elements.php10
-rw-r--r--ui/include/views/configuration.graph.edit.php15
-rw-r--r--ui/include/views/configuration.graph.list.php15
-rw-r--r--ui/include/views/configuration.host.discovery.edit.php8
-rw-r--r--ui/include/views/configuration.host.discovery.list.php13
-rw-r--r--ui/include/views/configuration.host.prototype.edit.php9
-rw-r--r--ui/include/views/configuration.host.prototype.list.php9
-rw-r--r--ui/include/views/configuration.httpconf.edit.php10
-rw-r--r--ui/include/views/configuration.httpconf.list.php13
-rw-r--r--ui/include/views/configuration.item.edit.php10
-rw-r--r--ui/include/views/configuration.item.list.php13
-rw-r--r--ui/include/views/configuration.item.prototype.edit.php10
-rw-r--r--ui/include/views/configuration.item.prototype.list.php9
-rw-r--r--ui/include/views/configuration.maintenance.edit.php10
-rw-r--r--ui/include/views/configuration.maintenance.list.php9
-rw-r--r--ui/include/views/configuration.template.edit.php11
-rw-r--r--ui/include/views/configuration.template.list.php8
-rw-r--r--ui/include/views/configuration.trigger.prototype.edit.php10
-rw-r--r--ui/include/views/configuration.trigger.prototype.list.php9
-rw-r--r--ui/include/views/configuration.triggers.edit.php12
-rw-r--r--ui/include/views/configuration.triggers.list.php13
-rw-r--r--ui/include/views/general.warning.php10
-rw-r--r--ui/include/views/inventory.host.list.php10
-rw-r--r--ui/include/views/inventory.host.view.php9
-rw-r--r--ui/include/views/monitoring.history.php28
-rw-r--r--ui/include/views/monitoring.sysmap.constructor.php2
-rw-r--r--ui/include/views/monitoring.sysmap.edit.php9
-rw-r--r--ui/include/views/monitoring.sysmap.list.php9
-rw-r--r--ui/include/views/reports.toptriggers.php2
-rw-r--r--ui/js/class.dashboard.js357
-rw-r--r--ui/js/class.dashboard.page.js64
-rw-r--r--ui/js/class.sortable.js9
-rw-r--r--ui/js/class.tabfilter.js2
-rw-r--r--ui/js/class.widget.inaccessible.js74
-rw-r--r--ui/js/class.widget.iterator.js (renamed from ui/js/widgets/class.widget.iterator.js)1
-rw-r--r--ui/js/class.widget.js (renamed from ui/js/widgets/class.widget.js)38
-rw-r--r--ui/js/class.widget.paste-placeholder.js (renamed from ui/js/widgets/class.widget.paste-placeholder.js)0
-rw-r--r--ui/js/common.js42
-rw-r--r--ui/js/main.js40
-rw-r--r--ui/js/menupopup.js3
-rw-r--r--ui/jsLoader.php71
-rw-r--r--ui/report2.php12
-rw-r--r--ui/report4.php6
-rw-r--r--ui/setup.php9
-rw-r--r--ui/tests/include/web/elements/CWidgetElement.php6
-rw-r--r--ui/tests/selenium/dashboard/testDashboardItemValueWidget.php5
-rw-r--r--ui/tests/selenium/dashboard/testPageDashboardWidgets.php13
-rw-r--r--ui/tests/selenium/data/sources/CopyWidgetsDashboards.php4
-rw-r--r--ui/tests/selenium/data/sources/TopHostsWidget.php2
-rw-r--r--ui/tests/selenium/modules/module_number_1/Module.php2
-rw-r--r--ui/tests/selenium/modules/module_number_1/manifest.json2
-rw-r--r--ui/tests/selenium/modules/module_number_1/views/first.module.php2
-rw-r--r--ui/tests/selenium/modules/module_number_2/Module.php2
-rw-r--r--ui/tests/selenium/modules/module_number_2/manifest.json2
-rw-r--r--ui/tests/selenium/modules/module_number_2/views/second.module.php2
-rw-r--r--ui/tests/selenium/modules/module_number_3/Module.php2
-rw-r--r--ui/tests/selenium/modules/module_number_3/manifest.json2
-rw-r--r--ui/tests/selenium/modules/module_number_3/views/third.module.php2
-rw-r--r--ui/tests/selenium/modules/module_number_4/Module.php2
-rw-r--r--ui/tests/selenium/modules/module_number_4/manifest.json2
-rw-r--r--ui/tests/selenium/modules/module_number_4/views/forth.module.php2
-rw-r--r--ui/tests/selenium/modules/module_number_5/Module.php2
-rw-r--r--ui/tests/selenium/modules/module_number_5/manifest.json2
-rw-r--r--ui/tests/selenium/modules/module_number_5/views/fifth.module.php2
-rw-r--r--ui/tests/selenium/modules/module_number_6/Module.php2
-rw-r--r--ui/tests/selenium/modules/module_number_6/manifest.json2
-rw-r--r--ui/tests/selenium/problems/testFormUpdateProblem.php4
-rw-r--r--ui/tests/selenium/roles/testFormUserRoles.php10
-rw-r--r--ui/tests/selenium/testDocumentationLinks.php4
-rw-r--r--ui/tests/selenium/testPageAdministrationGeneralModules.php71
-rw-r--r--ui/tests/selenium/testSID.php21
-rw-r--r--ui/tests/selenium/users/testFormUserPermissions.php26
-rw-r--r--ui/tests/unit/bootstrap.php3
-rw-r--r--ui/tests/unit/include/classes/import/CImportDataAdapterTest.php4
-rw-r--r--ui/tr_events.php47
-rwxr-xr-xui/widgets/actionlog/Widget.php31
-rw-r--r--ui/widgets/actionlog/actions/WidgetView.php (renamed from ui/app/controllers/CControllerWidgetActionLogView.php)60
-rw-r--r--ui/widgets/actionlog/includes/WidgetForm.php59
-rwxr-xr-xui/widgets/actionlog/manifest.json9
-rwxr-xr-xui/widgets/actionlog/views/widget.edit.php36
-rw-r--r--ui/widgets/actionlog/views/widget.view.php (renamed from ui/app/views/monitoring.widget.actionlog.view.php)27
-rwxr-xr-xui/widgets/clock/Widget.php48
-rwxr-xr-x[-rw-r--r--]ui/widgets/clock/actions/WidgetView.php (renamed from ui/app/controllers/CControllerWidgetClockView.php)218
-rwxr-xr-x[-rw-r--r--]ui/widgets/clock/assets/js/class.widget.js (renamed from ui/js/widgets/class.widget.clock.js)4
-rwxr-xr-xui/widgets/clock/includes/WidgetForm.php142
-rwxr-xr-xui/widgets/clock/manifest.json21
-rwxr-xr-xui/widgets/clock/views/widget.edit.js.php105
-rwxr-xr-xui/widgets/clock/views/widget.edit.php130
-rwxr-xr-x[-rw-r--r--]ui/widgets/clock/views/widget.view.php (renamed from ui/app/views/monitoring.widget.clock.view.php)48
-rwxr-xr-xui/widgets/dataover/Widget.php35
-rw-r--r--ui/widgets/dataover/actions/WidgetView.php (renamed from ui/app/controllers/CControllerWidgetDataOverView.php)33
-rw-r--r--ui/widgets/dataover/includes/WidgetForm.php66
-rwxr-xr-xui/widgets/dataover/manifest.json9
-rwxr-xr-xui/widgets/dataover/views/widget.edit.php51
-rw-r--r--ui/widgets/dataover/views/widget.view.php34
-rwxr-xr-xui/widgets/discovery/Widget.php31
-rw-r--r--ui/widgets/discovery/actions/WidgetView.php (renamed from ui/app/controllers/CControllerWidgetDiscoveryView.php)25
-rwxr-xr-xui/widgets/discovery/manifest.json15
-rw-r--r--ui/widgets/discovery/views/widget.view.php (renamed from ui/app/views/monitoring.widget.discovery.view.php)26
-rwxr-xr-xui/widgets/favgraphs/Widget.php31
-rw-r--r--ui/widgets/favgraphs/actions/WidgetView.php (renamed from ui/app/controllers/CControllerWidgetFavGraphsView.php)29
-rwxr-xr-xui/widgets/favgraphs/manifest.json16
-rw-r--r--ui/widgets/favgraphs/views/widget.view.php (renamed from ui/app/views/monitoring.widget.favgraphs.view.php)23
-rwxr-xr-xui/widgets/favmaps/Widget.php31
-rw-r--r--ui/widgets/favmaps/actions/WidgetView.php (renamed from ui/app/controllers/CControllerWidgetFavMapsView.php)29
-rwxr-xr-xui/widgets/favmaps/manifest.json16
-rw-r--r--ui/widgets/favmaps/views/widget.view.php (renamed from ui/app/views/monitoring.widget.favmaps.view.php)23
-rwxr-xr-xui/widgets/geomap/Widget.php57
-rw-r--r--ui/widgets/geomap/actions/WidgetView.php (renamed from ui/app/controllers/CControllerWidgetGeoMapView.php)145
-rwxr-xr-x[-rw-r--r--]ui/widgets/geomap/assets/js/class.widget.js (renamed from ui/js/widgets/class.widget.geomap.js)43
-rw-r--r--ui/widgets/geomap/includes/WidgetForm.php60
-rwxr-xr-xui/widgets/geomap/manifest.json15
-rwxr-xr-xui/widgets/geomap/views/widget.edit.php48
-rw-r--r--ui/widgets/geomap/views/widget.view.php34
-rwxr-xr-xui/widgets/graph/Widget.php40
-rw-r--r--ui/widgets/graph/actions/WidgetView.php (renamed from ui/app/controllers/CControllerWidgetGraphView.php)83
-rwxr-xr-x[-rw-r--r--]ui/widgets/graph/assets/js/class.widget.js (renamed from ui/js/widgets/class.widget.graph.js)8
-rw-r--r--ui/widgets/graph/includes/WidgetForm.php84
-rwxr-xr-xui/widgets/graph/manifest.json17
-rwxr-xr-x[-rw-r--r--]ui/widgets/graph/views/widget.edit.php (renamed from ui/include/classes/widgets/views/widget.actionlog.form.view.php)48
-rw-r--r--ui/widgets/graph/views/widget.view.php49
-rwxr-xr-xui/widgets/graphprototype/Widget.php31
-rw-r--r--ui/widgets/graphprototype/actions/WidgetView.php (renamed from ui/app/controllers/CControllerWidgetIteratorGraphPrototypeView.php)141
-rwxr-xr-x[-rw-r--r--]ui/widgets/graphprototype/assets/js/class.widget.js (renamed from ui/js/widgets/class.widget.graph-prototype.js)4
-rw-r--r--ui/widgets/graphprototype/includes/WidgetForm.php102
-rwxr-xr-xui/widgets/graphprototype/manifest.json27
-rwxr-xr-xui/widgets/graphprototype/views/widget.edit.php58
-rwxr-xr-xui/widgets/hostavail/Widget.php31
-rw-r--r--ui/widgets/hostavail/actions/WidgetView.php (renamed from ui/app/controllers/CControllerWidgetHostAvailView.php)38
-rw-r--r--ui/widgets/hostavail/assets/js/class.widget.js27
-rw-r--r--ui/widgets/hostavail/includes/WidgetForm.php61
-rwxr-xr-xui/widgets/hostavail/manifest.json20
-rwxr-xr-x[-rw-r--r--]ui/widgets/hostavail/views/widget.edit.php (renamed from ui/include/classes/widgets/views/widget.discovery.form.view.php)30
-rw-r--r--ui/widgets/hostavail/views/widget.view.php (renamed from ui/app/views/monitoring.widget.hostavail.view.php)22
-rwxr-xr-xui/widgets/item/Widget.php55
-rw-r--r--ui/widgets/item/actions/WidgetView.php (renamed from ui/app/controllers/CControllerWidgetItemView.php)281
-rwxr-xr-x[-rw-r--r--]ui/widgets/item/assets/js/class.widget.js (renamed from ui/js/widgets/class.widget.item.js)4
-rw-r--r--ui/widgets/item/includes/WidgetForm.php247
-rwxr-xr-xui/widgets/item/manifest.json20
-rwxr-xr-x[-rw-r--r--]ui/widgets/item/views/widget.edit.js.php (renamed from ui/include/classes/widgets/views/js/widget.item.form.view.js.php)127
-rwxr-xr-xui/widgets/item/views/widget.edit.php237
-rw-r--r--ui/widgets/item/views/widget.view.php (renamed from ui/app/views/monitoring.widget.item.view.php)57
-rwxr-xr-xui/widgets/map/Widget.php34
-rw-r--r--ui/widgets/map/actions/WidgetView.php (renamed from ui/app/controllers/CControllerWidgetMapView.php)41
-rwxr-xr-x[-rw-r--r--]ui/widgets/map/assets/js/class.widget.js (renamed from ui/js/widgets/class.widget.map.js)44
-rw-r--r--ui/widgets/map/includes/WidgetForm.php73
-rw-r--r--ui/widgets/map/includes/WidgetMap.php (renamed from ui/include/classes/html/CDashboardWidgetMap.php)130
-rwxr-xr-xui/widgets/map/manifest.json20
-rwxr-xr-x[-rw-r--r--]ui/widgets/map/views/widget.edit.php (renamed from ui/app/views/monitoring.widget.geomap.view.php)34
-rw-r--r--ui/widgets/map/views/widget.view.php36
-rwxr-xr-xui/widgets/navtree/Widget.php49
-rw-r--r--ui/widgets/navtree/actions/NavTreeItemEdit.php (renamed from ui/app/controllers/CControllerWidgetNavTreeItemEdit.php)26
-rw-r--r--ui/widgets/navtree/actions/NavTreeItemUpdate.php (renamed from ui/app/controllers/CControllerWidgetNavTreeItemUpdate.php)31
-rw-r--r--ui/widgets/navtree/actions/WidgetView.php (renamed from ui/app/controllers/CControllerWidgetNavTreeView.php)227
-rwxr-xr-x[-rw-r--r--]ui/widgets/navtree/assets/js/class.widget.js (renamed from ui/js/widgets/class.widget.navtree.js)24
-rw-r--r--ui/widgets/navtree/includes/NavigationTree.php (renamed from ui/include/classes/html/CNavigationTree.php)40
-rw-r--r--ui/widgets/navtree/includes/WidgetForm.php49
-rwxr-xr-xui/widgets/navtree/manifest.json31
-rw-r--r--ui/widgets/navtree/views/navtreeitem.edit.js.php (renamed from ui/app/views/js/monitoring.widget.navtreeitem.edit.js.php)6
-rw-r--r--ui/widgets/navtree/views/navtreeitem.edit.php (renamed from ui/app/views/monitoring.widget.navtreeitem.edit.php)58
-rwxr-xr-xui/widgets/navtree/views/widget.edit.php53
-rw-r--r--ui/widgets/navtree/views/widget.view.php (renamed from ui/app/views/monitoring.widget.navtree.view.php)33
-rwxr-xr-xui/widgets/plaintext/Widget.php31
-rw-r--r--ui/widgets/plaintext/actions/WidgetView.php (renamed from ui/app/controllers/CControllerWidgetPlainTextView.php)53
-rw-r--r--ui/widgets/plaintext/includes/WidgetForm.php68
-rwxr-xr-xui/widgets/plaintext/manifest.json16
-rwxr-xr-x[-rw-r--r--]ui/widgets/plaintext/views/widget.edit.php (renamed from ui/include/classes/widgets/views/widget.systeminfo.form.view.php)40
-rw-r--r--ui/widgets/plaintext/views/widget.view.php (renamed from ui/app/views/monitoring.widget.plaintext.view.php)29
-rwxr-xr-xui/widgets/problemhosts/Widget.php31
-rw-r--r--ui/widgets/problemhosts/actions/WidgetView.php (renamed from ui/app/controllers/CControllerWidgetProblemHostsView.php)62
-rw-r--r--ui/widgets/problemhosts/includes/WidgetForm.php86
-rwxr-xr-xui/widgets/problemhosts/manifest.json9
-rwxr-xr-xui/widgets/problemhosts/views/widget.edit.php65
-rw-r--r--ui/widgets/problemhosts/views/widget.view.php (renamed from ui/app/views/monitoring.widget.problemhosts.view.php)28
-rwxr-xr-xui/widgets/problems/Widget.php31
-rw-r--r--ui/widgets/problems/actions/WidgetView.php (renamed from ui/app/controllers/CControllerWidgetProblemsView.php)97
-rwxr-xr-x[-rw-r--r--]ui/widgets/problems/assets/js/class.widget.js (renamed from ui/js/widgets/class.widget.problems.js)0
-rw-r--r--ui/widgets/problems/includes/WidgetForm.php159
-rwxr-xr-xui/widgets/problems/manifest.json15
-rwxr-xr-xui/widgets/problems/views/widget.edit.js.php59
-rwxr-xr-xui/widgets/problems/views/widget.edit.php93
-rw-r--r--ui/widgets/problems/views/widget.view.php (renamed from ui/app/views/monitoring.widget.problems.view.php)34
-rwxr-xr-xui/widgets/problemsbysv/Widget.php34
-rw-r--r--ui/widgets/problemsbysv/actions/WidgetView.php77
-rwxr-xr-x[-rw-r--r--]ui/widgets/problemsbysv/assets/js/class.widget.js (renamed from ui/js/widgets/class.widget.problemsbysv.js)8
-rw-r--r--ui/widgets/problemsbysv/includes/WidgetForm.php123
-rwxr-xr-xui/widgets/problemsbysv/manifest.json15
-rwxr-xr-xui/widgets/problemsbysv/views/widget.edit.js.php44
-rwxr-xr-xui/widgets/problemsbysv/views/widget.edit.php79
-rw-r--r--ui/widgets/problemsbysv/views/widget.view.php (renamed from ui/app/views/monitoring.widget.problemsbysv.view.php)36
-rwxr-xr-xui/widgets/slareport/Widget.php31
-rw-r--r--ui/widgets/slareport/actions/WidgetView.php (renamed from ui/app/controllers/CControllerWidgetSlaReportView.php)52
-rw-r--r--ui/widgets/slareport/includes/WidgetForm.php127
-rwxr-xr-xui/widgets/slareport/manifest.json12
-rwxr-xr-x[-rw-r--r--]ui/widgets/slareport/views/widget.edit.js.php (renamed from ui/include/classes/widgets/views/js/widget.slareport.form.view.js.php)8
-rwxr-xr-xui/widgets/slareport/views/widget.edit.php55
-rw-r--r--ui/widgets/slareport/views/widget.view.php (renamed from ui/app/views/monitoring.widget.slareport.view.php)22
-rwxr-xr-xui/widgets/svggraph/Widget.php46
-rw-r--r--ui/widgets/svggraph/actions/WidgetView.php195
-rwxr-xr-x[-rw-r--r--]ui/widgets/svggraph/assets/js/class.widget.js (renamed from ui/js/widgets/class.widget.svggraph.js)4
-rw-r--r--ui/widgets/svggraph/includes/WidgetForm.php470
-rwxr-xr-xui/widgets/svggraph/manifest.json15
-rwxr-xr-x[-rw-r--r--]ui/widgets/svggraph/views/widget.edit.js.php (renamed from ui/include/classes/widgets/views/js/widget.svggraph.form.view.js.php)39
-rwxr-xr-xui/widgets/svggraph/views/widget.edit.php289
-rw-r--r--ui/widgets/svggraph/views/widget.view.php (renamed from ui/include/classes/widgets/views/widget.favmaps.form.view.php)21
-rwxr-xr-xui/widgets/systeminfo/Widget.php31
-rw-r--r--ui/widgets/systeminfo/actions/WidgetView.php (renamed from ui/app/controllers/CControllerWidgetSystemInfoView.php)27
-rw-r--r--ui/widgets/systeminfo/includes/WidgetForm.php42
-rwxr-xr-xui/widgets/systeminfo/manifest.json12
-rwxr-xr-xui/widgets/systeminfo/views/widget.edit.php33
-rw-r--r--ui/widgets/systeminfo/views/widget.view.php (renamed from ui/app/views/monitoring.widget.systeminfo.view.php)22
-rwxr-xr-xui/widgets/tophosts/Widget.php36
-rw-r--r--ui/widgets/tophosts/actions/ColumnEdit.php (renamed from ui/app/controllers/CControllerPopupTopHostsColumnEdit.php)102
-rw-r--r--ui/widgets/tophosts/actions/WidgetView.php (renamed from ui/app/controllers/CControllerWidgetTopHostsView.php)89
-rw-r--r--ui/widgets/tophosts/includes/WidgetForm.php139
-rwxr-xr-xui/widgets/tophosts/manifest.json16
-rw-r--r--ui/widgets/tophosts/views/column.edit.js.php (renamed from ui/app/views/js/popup.tophosts.column.edit.js.php)5
-rw-r--r--ui/widgets/tophosts/views/column.edit.php (renamed from ui/app/views/popup.tophosts.column.edit.php)28
-rwxr-xr-x[-rw-r--r--]ui/widgets/tophosts/views/widget.edit.js.php (renamed from ui/include/classes/widgets/views/js/widget.tophosts.form.view.js.php)11
-rwxr-xr-xui/widgets/tophosts/views/widget.edit.php85
-rw-r--r--ui/widgets/tophosts/views/widget.view.php (renamed from ui/app/views/monitoring.widget.tophosts.view.php)30
-rwxr-xr-xui/widgets/trigover/Widget.php31
-rw-r--r--ui/widgets/trigover/actions/WidgetView.php78
-rwxr-xr-x[-rw-r--r--]ui/widgets/trigover/assets/js/class.widget.js (renamed from ui/js/widgets/class.widget.trigerover.js)0
-rw-r--r--ui/widgets/trigover/includes/WidgetForm.php73
-rwxr-xr-xui/widgets/trigover/manifest.json15
-rw-r--r--ui/widgets/trigover/partials/table.left.php (renamed from ui/app/partials/trigoverview.table.left.php)0
-rw-r--r--ui/widgets/trigover/partials/table.top.php (renamed from ui/app/partials/trigoverview.table.top.php)0
-rwxr-xr-xui/widgets/trigover/views/widget.edit.php54
-rw-r--r--ui/widgets/trigover/views/widget.view.php34
-rwxr-xr-xui/widgets/url/Widget.php31
-rw-r--r--ui/widgets/url/actions/WidgetView.php (renamed from ui/app/controllers/CControllerWidgetUrlView.php)44
-rw-r--r--ui/widgets/url/assets/js/class.widget.js26
-rw-r--r--ui/widgets/url/includes/WidgetForm.php50
-rwxr-xr-xui/widgets/url/manifest.json17
-rwxr-xr-x[-rw-r--r--]ui/widgets/url/views/widget.edit.php (renamed from ui/include/classes/widgets/views/widget.favgraphs.form.view.php)25
-rw-r--r--ui/widgets/url/views/widget.view.php (renamed from ui/app/views/monitoring.widget.url.view.php)23
-rwxr-xr-xui/widgets/web/Widget.php31
-rw-r--r--ui/widgets/web/actions/WidgetView.php (renamed from ui/app/controllers/CControllerWidgetWebView.php)47
-rw-r--r--ui/widgets/web/includes/WidgetForm.php63
-rwxr-xr-xui/widgets/web/manifest.json15
-rwxr-xr-xui/widgets/web/views/widget.edit.php53
-rw-r--r--ui/widgets/web/views/widget.view.php (renamed from ui/app/views/monitoring.widget.web.view.php)28
540 files changed, 16583 insertions, 15873 deletions
diff --git a/ChangeLog.d/feature/ZBXNEXT-7469 b/ChangeLog.d/feature/ZBXNEXT-7469
new file mode 100755
index 00000000000..5cf2410476c
--- /dev/null
+++ b/ChangeLog.d/feature/ZBXNEXT-7469
@@ -0,0 +1 @@
+..F....... [ZBXNEXT-7469] simplified creation of dashboard widgets; moved widgets to modules; updated modules framework (ashubin, averza)
diff --git a/create/src/data.tmpl b/create/src/data.tmpl
index 28ae0e9ed47..4e132af5593 100644
--- a/create/src/data.tmpl
+++ b/create/src/data.tmpl
@@ -1002,3 +1002,29 @@ ROW |25 |4 |0 |modules.default_access|1 | |NULL
ROW |26 |4 |0 |api.access |0 | |NULL |NULL |
ROW |27 |4 |0 |actions.default_access|0 | |NULL |NULL |
+TABLE |module
+FIELDS|moduleid|id |relative_path |status|config|
+ROW |1 |actionlog |widgets/actionlog |1 |[] |
+ROW |2 |clock |widgets/clock |1 |[] |
+ROW |3 |dataover |widgets/dataover |1 |[] |
+ROW |4 |discovery |widgets/discovery |1 |[] |
+ROW |5 |favgraphs |widgets/favgraphs |1 |[] |
+ROW |6 |favmaps |widgets/favmaps |1 |[] |
+ROW |7 |geomap |widgets/geomap |1 |[] |
+ROW |8 |graph |widgets/graph |1 |[] |
+ROW |9 |graphprototype |widgets/graphprototype|1 |[] |
+ROW |10 |hostavail |widgets/hostavail |1 |[] |
+ROW |11 |item |widgets/item |1 |[] |
+ROW |12 |map |widgets/map |1 |[] |
+ROW |13 |navtree |widgets/navtree |1 |[] |
+ROW |14 |plaintext |widgets/plaintext |1 |[] |
+ROW |15 |problemhosts |widgets/problemhosts |1 |[] |
+ROW |16 |problems |widgets/problems |1 |[] |
+ROW |17 |problemsbysv |widgets/problemsbysv |1 |[] |
+ROW |18 |slareport |widgets/slareport |1 |[] |
+ROW |19 |svggraph |widgets/svggraph |1 |[] |
+ROW |20 |systeminfo |widgets/systeminfo |1 |[] |
+ROW |21 |tophosts |widgets/tophosts |1 |[] |
+ROW |22 |trigover |widgets/trigover |1 |[] |
+ROW |23 |url |widgets/url |1 |[] |
+ROW |24 |web |widgets/web |1 |[] |
diff --git a/create/src/schema.tmpl b/create/src/schema.tmpl
index 3151cedbaca..24a1eefee6f 100644
--- a/create/src/schema.tmpl
+++ b/create/src/schema.tmpl
@@ -1683,7 +1683,7 @@ FIELD |tls_psk_identity|t_varchar(128)|'' |NOT NULL |ZBX_PROXY
FIELD |tls_psk |t_varchar(512) |'' |NOT NULL |ZBX_PROXY
UNIQUE |1 |tls_psk_identity
-TABLE|module|moduleid|
+TABLE|module|moduleid|ZBX_DATA
FIELD |moduleid |t_id | |NOT NULL |0
FIELD |id |t_varchar(255) |'' |NOT NULL |0
FIELD |relative_path |t_varchar(255) |'' |NOT NULL |0
@@ -1987,4 +1987,4 @@ TABLE|dbversion|dbversionid|
FIELD |dbversionid |t_id | |NOT NULL |0
FIELD |mandatory |t_integer |'0' |NOT NULL |
FIELD |optional |t_integer |'0' |NOT NULL |
-ROW |1 |6030061 |6030061
+ROW |1 |6030063 |6030063
diff --git a/sass/stylesheets/sass/components/_columns-wrapper.scss b/sass/stylesheets/sass/components/_columns-wrapper.scss
new file mode 100644
index 00000000000..3f10c77bf29
--- /dev/null
+++ b/sass/stylesheets/sass/components/_columns-wrapper.scss
@@ -0,0 +1,79 @@
+.columns-wrapper {
+ $column-count: (2, 3);
+ $column-size: (
+ 5: 5%,
+ 10: 10%,
+ 15: 15%,
+ 20: 20%,
+ 33: 33.33333%,
+ 35: 35%,
+ 40: 40%,
+ 50: 50%,
+ 75: 75%,
+ 90: 90%,
+ 95: 95%
+ );
+
+ display: flex;
+ flex-wrap: wrap;
+ align-items: start;
+
+ &.columns-nowrap {
+ flex-wrap: nowrap;
+ }
+
+ // Dynamically generated classes for the columns count:
+ // .columns-2
+ // .columns-3
+ @each $count in $column-count {
+ &.columns-#{$count} > {
+ div,
+ li {
+ display: block;
+ flex: 0 0 (100% / $count);
+ max-width: (100% / $count);
+ }
+ }
+ }
+
+ // Dynamically generated classes for the column width:
+ // .column-5
+ // .column-10
+ // .column-15
+ // .column-20
+ // .column-33
+ // .column-35
+ // .column-40
+ // .column-50
+ // .column-75
+ // .column-90
+ // .column-95
+ @each $class, $width in $column-size {
+ .column-#{$class} {
+ flex: 0 0 $width;
+ max-width: $width;
+ }
+ }
+
+ .column-center {
+ display: flex;
+ justify-content: center;
+ text-align: center;
+ }
+
+ .column-middle {
+ display: flex;
+ align-items: center;
+ }
+
+ & > {
+ div,
+ ul {
+ &:not(:last-child) {
+ section {
+ margin-right: 10px;
+ }
+ }
+ }
+ }
+}
diff --git a/sass/stylesheets/sass/components/_section.scss b/sass/stylesheets/sass/components/_section.scss
new file mode 100644
index 00000000000..e0c21a3aaf2
--- /dev/null
+++ b/sass/stylesheets/sass/components/_section.scss
@@ -0,0 +1,72 @@
+section {
+ background-color: $ui-bg-color;
+ border: 1px solid $ui-border-color;
+
+ .section-head {
+ display: flex;
+ height: 32px;
+ line-height: 32px;
+
+ h4 {
+ padding: 0 10px;
+ margin-right: auto;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ font-weight: bold;
+ line-height: inherit;
+ color: lighten($font-color, 15%);
+ }
+ }
+
+ .section-toggle {
+ @extend %btn-widget-defaults;
+
+ width: 24px;
+ height: 24px;
+ margin: 2px 2px 0 auto;
+ background: url($sprite-path) no-repeat -6px -654px;
+ }
+
+ .section-foot {
+ padding: 0 10px;
+ text-align: right;
+ line-height: 32px;
+ color: $font-alt-color;
+ }
+
+ &.section-collapsed {
+ .section-body,
+ .section-foot {
+ display: none;
+ }
+
+ .section-toggle {
+ background-position: -6px -689px;
+ }
+ }
+
+ &:not(:last-child) {
+ margin-bottom: 10px;
+ }
+
+ .list-table {
+ border: 0;
+
+ tbody tr:last-child {
+ td {
+ border-bottom: 1px solid $table-border-color;
+ }
+ }
+
+ td,
+ th {
+ &:first-child {
+ padding-left: 10px;
+ }
+
+ &:last-child {
+ padding-right: 10px;
+ }
+ }
+ }
+}
diff --git a/sass/stylesheets/sass/components/dashboard/_dashboard.scss b/sass/stylesheets/sass/components/dashboard/_dashboard.scss
index 726e26674ff..6855839e555 100644
--- a/sass/stylesheets/sass/components/dashboard/_dashboard.scss
+++ b/sass/stylesheets/sass/components/dashboard/_dashboard.scss
@@ -978,10 +978,6 @@
.msg-warning {
margin: 0 10px;
}
-
- &.dashboard-widget-fluid {
- margin-right: 0;
- }
}
%dashboard-widget-td {
diff --git a/sass/stylesheets/sass/components/dashboard/_widget-clock.scss b/sass/stylesheets/sass/components/dashboard/_widget-clock.scss
index 41497454cf9..638de52aaed 100644
--- a/sass/stylesheets/sass/components/dashboard/_widget-clock.scss
+++ b/sass/stylesheets/sass/components/dashboard/_widget-clock.scss
@@ -1,39 +1,40 @@
// Widget configuration.
form.dashboard-widget-clock {
- .fields-group-date,
- .fields-group-time,
- .fields-group-tzone {
- display: grid;
- grid-template-columns: 60px 120px repeat(2, minmax(60px, max-content) auto);
- align-items: center;
- column-gap: 10px;
- row-gap: 5px;
-
- label {
- text-align: right;
- }
+ .fields-group {
+ &.fields-group-date,
+ &.fields-group-time,
+ &.fields-group-tzone {
+ display: grid;
+ grid-template-columns: 60px 120px repeat(2, minmax(60px, max-content) auto);
+ align-items: center;
+ column-gap: 10px;
+ row-gap: 5px;
- .field-size {
- input {
- margin-right: 5px;
+ label {
+ text-align: right;
}
- }
- }
- .fields-group-time {
- .field-format {
- grid-column: 4 / -1;
+ .field-size {
+ input {
+ margin-right: 5px;
+ }
+ }
}
- }
- .fields-group-tzone {
- .field-format {
- grid-column: 2 / -1;
+ &.fields-group-time {
+ .field-format {
+ grid-column: 4 / -1;
+ }
}
- .field-timezone {
- grid-column: 2 / -1;
+ &.fields-group-tzone {
+ .form-field {
+ &.field-tzone-timezone,
+ &.field-tzone-format {
+ grid-column: 2 / -1;
+ }
+ }
}
}
}
@@ -41,7 +42,7 @@ form.dashboard-widget-clock {
// Widget view.
div.dashboard-widget-clock {
- &.clock-digital {
+ .clock-digital {
$line-height: 1.14;
box-sizing: border-box;
diff --git a/sass/stylesheets/sass/components/dashboard/_widget-inaccessible.scss b/sass/stylesheets/sass/components/dashboard/_widget-inaccessible.scss
new file mode 100755
index 00000000000..8349b4eb3c2
--- /dev/null
+++ b/sass/stylesheets/sass/components/dashboard/_widget-inaccessible.scss
@@ -0,0 +1,8 @@
+.dashboard-widget-inaccessible {
+ display: grid;
+ align-items: center;
+ padding-right: 10px;
+ padding-left: 10px;
+ text-align: center;
+ color: $font-alt-color;
+}
diff --git a/sass/stylesheets/sass/components/dashboard/_widget-item.scss b/sass/stylesheets/sass/components/dashboard/_widget-item.scss
index f3a36d2d73a..3c1c86646d9 100644
--- a/sass/stylesheets/sass/components/dashboard/_widget-item.scss
+++ b/sass/stylesheets/sass/components/dashboard/_widget-item.scss
@@ -1,71 +1,73 @@
// Widget configuration.
form.dashboard-widget-item {
- .fields-group-description,
- .fields-group-value,
- .fields-group-time,
- .fields-group-change-indicator {
- display: grid;
- grid-template-columns: minmax(100px, max-content) 3fr max-content auto;
- align-items: center;
- column-gap: 10px;
- row-gap: 5px;
-
- label {
- text-align: right;
- }
+ .fields-group {
+ &.fields-group-description,
+ &.fields-group-value,
+ &.fields-group-time,
+ &.fields-group-change-indicator {
+ display: grid;
+ grid-template-columns: minmax(100px, max-content) 3fr max-content auto;
+ align-items: center;
+ column-gap: 10px;
+ row-gap: 5px;
+
+ label {
+ text-align: right;
+ }
- hr {
- grid-column: 1 / -1;
- margin: 0;
- width: 100%;
- border: solid $table-border-color;
- border-width: 1px 0 0 0;
- }
+ hr {
+ grid-column: 1 / -1;
+ margin: 0;
+ width: 100%;
+ border: solid $table-border-color;
+ border-width: 1px 0 0 0;
+ }
- .field-fluid {
- grid-column: 2 / -1;
- }
+ .field-fluid {
+ grid-column: 2 / -1;
+ }
- .offset-3 {
- grid-column-start: 3;
- }
+ .offset-3 {
+ grid-column-start: 3;
+ }
- .field-size {
- input {
- margin-right: 5px;
+ .field-size {
+ input {
+ margin-right: 5px;
+ }
}
- }
- .form-field {
- line-height: 24px;
+ .form-field {
+ line-height: 24px;
+ }
}
- }
- .fields-group-description {
- .form-field:nth-child(1) {
- grid-column: 1 / -1;
+ &.fields-group-description {
+ .form-field:nth-child(1) {
+ grid-column: 1 / -1;
+ }
}
- }
- .fields-group-value {
- grid-template-columns: minmax(100px, max-content) 3fr max-content auto;
+ &.fields-group-value {
+ grid-template-columns: minmax(100px, max-content) 3fr max-content auto;
- .units-show {
- display: flex;
+ .units-show {
+ display: flex;
- label[for='units'] {
- width: 100%;
+ label[for='units'] {
+ width: 100%;
+ }
}
}
- }
- .fields-group-change-indicator {
- grid-template-columns: repeat(3, max-content 96px);
- }
+ &.fields-group-change-indicator {
+ grid-template-columns: repeat(3, max-content 96px);
- .fields-group-change-indicator .input-color-picker {
- display: block;
+ .input-color-picker {
+ display: block;
+ }
+ }
}
}
@@ -74,12 +76,14 @@ form.dashboard-widget-item {
div.dashboard-widget-item {
$line-height: 1.14;
- box-sizing: border-box;
- height: 100%;
- padding: 10px;
- overflow-x: hidden;
+ > div {
+ box-sizing: border-box;
+ height: 100%;
+ padding: 10px;
+ overflow-x: hidden;
- @extend %webkit-scrollbar;
+ @extend %webkit-scrollbar;
+ }
a {
box-sizing: border-box;
diff --git a/sass/stylesheets/sass/components/dashboard/_widget-svggraph.scss b/sass/stylesheets/sass/components/dashboard/_widget-svggraph.scss
index e32ad97b80a..671d18331ff 100644
--- a/sass/stylesheets/sass/components/dashboard/_widget-svggraph.scss
+++ b/sass/stylesheets/sass/components/dashboard/_widget-svggraph.scss
@@ -1,12 +1,30 @@
// Widget configuration.
form.dashboard-widget-svggraph {
+ .svg-graph-preview,
.graph-widget-config-tabs {
- padding: 10px 0;
+ grid-column: 1 / -1;
+ }
+
+ .svg-graph-preview {
+ position: relative;
+ min-width: 1110px;
+ height: 300px;
+
+ > div {
+ position: absolute;
+ top: 0;
+ right: 0;
+ left: 0;
+ margin: 0 -10px;
+ height: 300px;
+ background: $ui-bg-color;
+ z-index: 3;
+ }
+ }
+ .graph-widget-config-tabs {
> .tabs-nav {
- margin-right: 0;
- margin-left: 0;
border-top: 1px solid $ui-border-color;
}
@@ -19,6 +37,7 @@ form.dashboard-widget-svggraph {
}
.table-forms-container {
+ margin: -10px 0 0 0;
border: 1px solid $ui-border-color;
border-top: none;
}
@@ -27,32 +46,30 @@ form.dashboard-widget-svggraph {
padding: 0;
}
- .dataset-head {
- display: grid;
- grid-template-columns: 24px 24px 1fr 1fr 24px;
- grid-gap: 10px;
- align-items: start;
+ .dataset-head,
+ .dataset-body.list-accordion-item-body {
+ display: contents;
}
- .dataset-body.list-accordion-item-body {
- display: grid;
- grid-template-columns: 24px 1fr 1fr 24px;
- grid-gap: 10px;
- align-items: start;
- position: relative;
- margin-top: 10px;
+ .dataset-head {
+ .multiselect {
+ width: 100%;
+ }
+ }
+ .dataset-body {
.form-grid {
padding-top: 0;
&:first-child {
- grid-column-start: 2;
+ grid-column-start: 3;
}
}
}
.drag-icon {
position: absolute;
+ top: 5px;
left: -14px;
}
@@ -88,17 +105,15 @@ form.dashboard-widget-svggraph {
margin-top: -5px;
margin-bottom: -5px;
}
-
- .list-accordion-item-head {
- padding: 0;
- }
}
.list-accordion-item {
position: relative;
- width: 100%;
+ display: grid;
+ grid-template-columns: 24px 24px 1fr 1fr 24px;
+ grid-gap: 10px;
+ align-items: start;
padding: 5px 0;
- list-style-type: none;
&.list-accordion-item-opened {
&::before {
@@ -119,10 +134,6 @@ form.dashboard-widget-svggraph {
overflow: hidden;
}
- .dataset-body {
- display: none;
- }
-
.dataset-head {
.table-forms-separator {
border: none;
@@ -138,6 +149,10 @@ form.dashboard-widget-svggraph {
}
}
+ .dataset-body {
+ display: none;
+ }
+
.items-list {
padding-left: 0;
}
@@ -167,9 +182,129 @@ form.dashboard-widget-svggraph {
}
}
+ .overrides-list {
+ position: relative;
+ margin: -5px 0 -5px 15px;
+ }
+
+ .overrides-list-item {
+ position: relative;
+ display: grid;
+ grid-template-columns: 1fr 1fr 24px;
+ grid-gap: 5px 10px;
+ align-items: start;
+ padding: 5px 0;
+
+ &.sortable {
+ overflow: visible;
+ margin-top: -5px;
+ margin-bottom: -5px;
+ }
+
+ .multiselect {
+ width: 100%;
+ }
+
+ .btn-remove {
+ right: 0;
+ top: 0;
+ vertical-align: baseline;
+ }
+ }
+
+ .overrides-foot {
+ padding: 5px 0;
+ }
+
+ .overrides-options-list {
+ grid-column: 1 / -1;
+ padding: 0 24px 8px 0;
+ border-bottom: 1px solid $table-border-color;
+ white-space: normal;
+
+ > li {
+ display: inline-block;
+ margin-right: 5px;
+ margin-bottom: 2px;
+ line-height: 22px;
+ white-space: nowrap;
+
+ .color-picker {
+ line-height: 22px;
+ }
+
+ > div {
+ position: relative;
+ padding: 1px 18px 1px 1px;
+ background-color: $ui-bg-selected-color;
+ border-radius: 2px;
+
+ > span {
+ color: lighten($ui-bg-selected-color, 100%);
+ padding-left: 8px;
+ line-height: 22px;
+ }
+
+ > input[type=text] {
+ border-style: none;
+ line-height: 22px;
+ min-height: 22px;
+ width: 85px;
+ }
+
+ > .subfilter-disable-btn {
+ position: absolute;
+ right: 0;
+ top: 0;
+ min-height: 24px;
+ }
+ }
+ }
+
+ .btn-alt {
+ .plus-icon {
+ margin-right: 0;
+ }
+ }
+
+ .color-picker {
+ .color-picker-preview {
+ margin: 1px;
+ width: 20px;
+ min-height: 20px;
+ background-position: -323px -411px;
+ }
+ }
+ }
+
.no-items-message {
display: none;
line-height: 24px;
color: $font-alt-color;
}
}
+
+[theme="hc-dark"] form.dashboard-widget-svggraph {
+ .overrides-options-list {
+ > li > div {
+ border: 1px solid $ui-tab-bg-selected-color;
+ background-color: transparent !important;
+
+ > .subfilter-disable-btn {
+ border: none !important;
+ top: 0;
+ }
+ }
+ }
+}
+
+[theme="hc-light"] form.dashboard-widget-svggraph {
+ .overrides-options-list {
+ > li > div {
+ > .subfilter-disable-btn {
+ border: none !important;
+ top: 0;
+ }
+ }
+ }
+}
diff --git a/sass/stylesheets/sass/hc-dark.scss b/sass/stylesheets/sass/hc-dark.scss
index 9c09a085b52..0b7410f1e30 100644
--- a/sass/stylesheets/sass/hc-dark.scss
+++ b/sass/stylesheets/sass/hc-dark.scss
@@ -1206,6 +1206,7 @@ td.inactive-bg {
}
// Multiline input control.
+
.multilineinput-control {
button {
&::after {
@@ -1231,6 +1232,7 @@ td.inactive-bg {
}
// Time selection.
+
.ui-tabs-nav {
.btn-info {
&::after {
@@ -1480,19 +1482,6 @@ td.inactive-bg {
}
}
-// Overrides.
-.overrides-options-list {
- > li > div {
- border: 1px solid $ui-tab-bg-selected-color;
- background-color: transparent !important;
-
- > .subfilter-disable-btn {
- border: none !important;
- top: 0;
- }
- }
-}
-
.totals-list {
> div {
border-top: 1px solid $ui-border-color;
@@ -1511,6 +1500,7 @@ td.inactive-bg {
}
// Widget "Host availability".
+
.host-avail-widget {
td:not(:first-child) {
border-left: 1px solid $ui-border-color;
@@ -1524,7 +1514,8 @@ td.inactive-bg {
}
}
-// Widget "Navigation tree"
+// Widget "Navigation tree".
+
.navtree {
.tree .tree-item > .tree-row {
min-width: 410px;
@@ -1532,6 +1523,7 @@ td.inactive-bg {
}
// Widget "Problems by severity".
+
.by-severity-widget {
> div {
min-width: 65px;
@@ -1544,13 +1536,13 @@ td.inactive-bg {
}
}
-// InputSecret and ButtonDropdown
+// InputSecret and ButtonDropdown.
.btn-undo.is-focused {
box-shadow: 0 1px 0px $blue, 0 -1px 0px $blue;
}
-// Tabfilter
+// Tabfilter.
.filter-container.tabfilter-container {
.icon-filter::before {
@@ -1574,7 +1566,7 @@ td.inactive-bg {
}
}
-// HOST INTERFACES
+// Host interfaces.
.interfaces {
.interface-row {
@@ -1591,3 +1583,17 @@ td.inactive-bg {
}
}
}
+
+// Section (components/_section.scss).
+
+section {
+ .section-toggle {
+ background-position: -318px -654px;
+ }
+
+ &.section-collapsed {
+ .section-toggle {
+ background-position: -318px -690px;
+ }
+ }
+}
diff --git a/sass/stylesheets/sass/hc-light.scss b/sass/stylesheets/sass/hc-light.scss
index 6f7675dc024..681db702d8c 100644
--- a/sass/stylesheets/sass/hc-light.scss
+++ b/sass/stylesheets/sass/hc-light.scss
@@ -1314,18 +1314,6 @@ td.inactive-bg {
}
}
-// Overrides.
-.overrides-options-list {
- > li > div {
- background-color: $ui-bg-selected-color !important;
-
- > .subfilter-disable-btn {
- border: none !important;
- top: 0;
- }
- }
-}
-
.totals-list {
> div {
border-top: 1px solid $ui-border-color;
@@ -1344,6 +1332,7 @@ td.inactive-bg {
}
// Widget "Host availability".
+
.host-avail-widget {
td:not(:first-child) {
border-left: 1px solid $ui-border-color;
@@ -1357,7 +1346,8 @@ td.inactive-bg {
}
}
-// Widget "Navigation tree"
+// Widget "Navigation tree".
+
.navtree {
.tree .tree-item > .tree-row {
min-width: 410px;
@@ -1365,6 +1355,7 @@ td.inactive-bg {
}
// Widget "Problems by severity".
+
.by-severity-widget {
> div {
min-width: 65px;
@@ -1377,7 +1368,7 @@ td.inactive-bg {
}
}
-// InputSecret and ButtonDropdown
+// InputSecret and ButtonDropdown.
.btn-undo.is-focused {
box-shadow: 0 1px 0px $blue, 0 -1px 0px $blue;
@@ -1403,7 +1394,7 @@ td.inactive-bg {
}
}
-// HOST INTERFACES
+// Host interfaces.
.interfaces {
.interface-row {
@@ -1420,3 +1411,17 @@ td.inactive-bg {
}
}
}
+
+// Section (components/_section.scss).
+
+section {
+ .section-toggle {
+ background-position: -165px -654px;
+ }
+
+ &.section-collapsed {
+ .section-toggle {
+ background-position: -165px -690px;
+ }
+ }
+}
diff --git a/sass/stylesheets/sass/layout/_form-grid.scss b/sass/stylesheets/sass/layout/_form-grid.scss
index dedda435665..ebd643498df 100644
--- a/sass/stylesheets/sass/layout/_form-grid.scss
+++ b/sass/stylesheets/sass/layout/_form-grid.scss
@@ -1,6 +1,5 @@
.form-grid {
display: grid;
- padding: 5px;
row-gap: 10px;
column-gap: 10px;
@@ -26,6 +25,11 @@
&.fields-group-label {
padding-top: 5px;
}
+
+ .icon-help-hint,
+ .icon-info {
+ margin-left: 5px;
+ }
}
> .form-field,
diff --git a/sass/stylesheets/sass/screen.scss b/sass/stylesheets/sass/screen.scss
index b9908891d6f..2710253f8b9 100644
--- a/sass/stylesheets/sass/screen.scss
+++ b/sass/stylesheets/sass/screen.scss
@@ -30,8 +30,10 @@ $browser-sprite-path: '../img/browser-sprite.png?20220722';
@import "components/buttons";
@import "components/color-picker";
+@import "components/columns-wrapper";
@import "components/dashboard/dashboard";
@import "components/dashboard/widget-clock";
+@import "components/dashboard/widget-inaccessible";
@import "components/dashboard/widget-item";
@import "components/dashboard/widget-slareport";
@import "components/dashboard/widget-svggraph";
@@ -45,6 +47,7 @@ $browser-sprite-path: '../img/browser-sprite.png?20220722';
@import "components/message-box";
@import "components/radio-list-control";
@import "components/range-control";
+@import "components/section";
@import "components/service/info";
@import "components/subfilter";
@import "components/svg-graph";
@@ -2616,10 +2619,10 @@ $var-icons: (
}
$trigger-expression-tree-icons: (
- top-bottom: url($sprite-path) no-repeat -84px -300px,
- top-bottom-right: url($sprite-path) no-repeat -84px -334px,
- top-right: url($sprite-path) no-repeat -84px -372px,
- empty: url($sprite-path) no-repeat -84px -350px
+ top-bottom: -84px -300px,
+ top-bottom-right: -84px -334px,
+ top-right: -84px -372px,
+ empty: -84px -350px
);
%trigger-expression-tree-icons-common {
@@ -3082,7 +3085,7 @@ $form-icon-btn: (
margin: 0 10px;
.dashboard-widget-head {
- margin-bottom: 14px;
+ margin-bottom: 12px;
.icon-doc-link {
margin-right: -26px;
@@ -3101,11 +3104,15 @@ $form-icon-btn: (
width: 100%;
max-height: calc(100vh - 220px);
max-width: inherit;
- margin: 0 -10px 10px;
+ margin: 0 -10px 8px;
padding: 0 10px;
position: relative;
@extend %webkit-scrollbar;
+ > form {
+ padding: 2px 0;
+ }
+
.table-forms {
.table-forms-td-right {
padding-right: 8px;
@@ -3740,23 +3747,6 @@ $form-icon-btn: (
stroke-width: 2px;
}
-.svg-graph-preview {
- margin-top: 10px;
- min-width: 1120px;
- height: 300px;
- position: relative;
-
- > div {
- background: $ui-bg-color;
- height: 300px;
- position: absolute;
- left: 0;
- right: 0;
- top: 0;
- z-index: 3; // More than z-index of form controls, less than z-index of .msg-*.
- }
-}
-
.svg-graph-hintbox {
font-size: 12px;
line-height: 18px;
@@ -4727,73 +4717,6 @@ svg {
word-break: break-word;
}
-.overrides-list {
- display: table;
- width: 90%;
- max-width: 738px;
- padding-left: 15px;
-
- .overrides-list-item {
- display: table-row;
-
- .btn-remove {
- position: relative;
- right: -73px;
- top: 3px;
- }
- }
-}
-
-.overrides-options-list {
- white-space: normal;
- padding: 5px 0 8px;
- margin-bottom: 10px;
- border-bottom: 1px solid $table-border-color;
-
- > li {
- display: inline-block;
- margin: 2px 7px 2px 0;
- white-space: nowrap;
- vertical-align: middle;
-
- > div {
- position: relative;
- padding: 1px 18px 1px 1px;
- background-color: $ui-bg-selected-color;
- border-radius: 2px;
-
- > span {
- color: lighten($ui-bg-selected-color, 100%);
- padding-left: 8px;
- line-height: 22px;
- }
-
- > input[type=text] {
- border-style: none;
- line-height: 22px;
- min-height: 22px;
- width: 85px;
- }
-
- > .subfilter-disable-btn {
- position: absolute;
- right: 0;
- top: 0;
- min-height: 24px;
- }
- }
- }
-
- .color-picker {
- .color-picker-preview {
- margin: 1px;
- width: 20px;
- min-height: 20px;
- background-position: -323px -411px;
- }
- }
-}
-
.list-accordion-foot {
> div {
display: table-cell;
@@ -4871,75 +4794,6 @@ svg {
}
}
-.columns-wrapper {
- $column-count: (2, 3);
- $column-size: (
- 5: 5%,
- 10: 10%,
- 15: 15%,
- 20: 20%,
- 33: 33.33333%,
- 35: 35%,
- 40: 40%,
- 50: 50%,
- 75: 75%,
- 90: 90%,
- 95: 95%
- );
-
- display: flex;
- flex-wrap: wrap;
- align-items: start;
-
- &.columns-nowrap {
- flex-wrap: nowrap;
- }
-
- // Dynamically generated classes for the columns count:
- // .columns-2
- // .columns-3
- @each $count in $column-count {
- &.columns-#{$count} > {
- div,
- li {
- display: block;
- flex: 0 0 (100% / $count);
- max-width: (100% / $count);
- }
- }
- }
-
- // Dynamically generated classes for the column width:
- // .column-5
- // .column-10
- // .column-15
- // .column-20
- // .column-33
- // .column-35
- // .column-40
- // .column-50
- // .column-75
- // .column-90
- // .column-95
- @each $class, $width in $column-size {
- .column-#{$class} {
- flex: 0 0 $width;
- max-width: $width;
- }
- }
-
- .column-center {
- display: flex;
- justify-content: center;
- text-align: center;
- }
-
- .column-middle {
- display: flex;
- align-items: center;
- }
-}
-
.preprocessing-list {
$name-width: 295px;
$on-fail-width: 100px;
diff --git a/sass/stylesheets/sass/utils/_sortable.scss b/sass/stylesheets/sass/utils/_sortable.scss
index 34bce40cd69..f5c8c857f4f 100644
--- a/sass/stylesheets/sass/utils/_sortable.scss
+++ b/sass/stylesheets/sass/utils/_sortable.scss
@@ -9,8 +9,14 @@
@if $ui-transitions {
transition: left .2s, top .2s;
+ }
+ }
- .sortable-item:not(.sortable-dragging) {
+ .sortable-item {
+ box-sizing: border-box;
+
+ @if $ui-transitions {
+ &:not(.sortable-dragging) {
transition: left .2s, top .2s;
}
}
diff --git a/src/libs/zbxdbupgrade/dbupgrade_6030.c b/src/libs/zbxdbupgrade/dbupgrade_6030.c
index a5313d6bb5c..5a0499ec53d 100644
--- a/src/libs/zbxdbupgrade/dbupgrade_6030.c
+++ b/src/libs/zbxdbupgrade/dbupgrade_6030.c
@@ -476,6 +476,92 @@ static int DBpatch_6030061(void)
return DBmodify_field_type("triggers", &field, NULL);
}
+static int DBpatch_6030062(void)
+{
+ DB_RESULT result;
+ DB_ROW row;
+ char *sql;
+ size_t sql_alloc = 4096, sql_offset = 0;
+ int ret = SUCCEED;
+
+ if (0 == (program_type & ZBX_PROGRAM_TYPE_SERVER))
+ return SUCCEED;
+
+ sql = zbx_malloc(NULL, sql_alloc);
+
+ zbx_DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset);
+
+ result = DBselect("select moduleid,relative_path from module");
+
+ while (NULL != (row = DBfetch(result)))
+ {
+ const char *rel_path = row[1];
+ char *updated_path, *updated_path_esc;
+
+ if (NULL == rel_path || '\0' == *rel_path)
+ continue;
+
+ updated_path = zbx_dsprintf(NULL, "modules/%s", rel_path);
+
+ updated_path_esc = DBdyn_escape_string(updated_path);
+
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "update module set relative_path='%s' "
+ "where moduleid=%s;\n", updated_path_esc, row[0]);
+
+ zbx_free(updated_path);
+ zbx_free(updated_path_esc);
+
+ ret = DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset);
+ }
+ DBfree_result(result);
+
+ zbx_DBend_multiple_update(&sql, &sql_alloc, &sql_offset);
+
+ if (SUCCEED == ret && 16 < sql_offset)
+ {
+ if (ZBX_DB_OK > DBexecute("%s", sql))
+ ret = FAIL;
+ }
+
+ zbx_free(sql);
+
+ return ret;
+}
+
+static int DBpatch_6030063(void)
+{
+ zbx_db_insert_t db_insert;
+ int i, ret = FAIL;
+
+ const char *modules[] = {
+ "actionlog", "clock", "dataover", "discovery", "favgraphs", "favmaps", "geomap", "graph",
+ "graphprototype", "hostavail", "item", "map", "navtree", "plaintext", "problemhosts",
+ "problems", "problemsbysv", "slareport", "svggraph", "systeminfo", "tophosts", "trigover",
+ "url", "web"
+ };
+
+ if (0 == (program_type & ZBX_PROGRAM_TYPE_SERVER))
+ return SUCCEED;
+
+ zbx_db_insert_prepare(&db_insert, "module", "moduleid", "id", "relative_path", "status", "config", NULL);
+
+ for (i = 0; i < (int)ARRSIZE(modules); i++)
+ {
+ char *path;
+
+ path = zbx_dsprintf(NULL, "widgets/%s", modules[i]);
+ zbx_db_insert_add_values(&db_insert, __UINT64_C(0), modules[i], path, 1, "[]");
+ zbx_free(path);
+ }
+
+ zbx_db_insert_autoincrement(&db_insert, "moduleid");
+ ret = zbx_db_insert_execute(&db_insert);
+
+ zbx_db_insert_clean(&db_insert);
+
+ return ret;
+}
+
#endif
DBPATCH_START(6030)
@@ -544,5 +630,7 @@ DBPATCH_ADD(6030058, 0, 1)
DBPATCH_ADD(6030059, 0, 1)
DBPATCH_ADD(6030060, 0, 1)
DBPATCH_ADD(6030061, 0, 1)
+DBPATCH_ADD(6030062, 0, 1)
+DBPATCH_ADD(6030063, 0, 1)
DBPATCH_END()
diff --git a/ui/app/controllers/CControllerDashboardConfigurationHashGet.php b/ui/app/controllers/CControllerDashboardConfigurationHashGet.php
new file mode 100644
index 00000000000..3e7f789a3ff
--- /dev/null
+++ b/ui/app/controllers/CControllerDashboardConfigurationHashGet.php
@@ -0,0 +1,98 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+class CControllerDashboardConfigurationHashGet extends CController {
+
+ protected function init(): void {
+ $this->setPostContentType(self::POST_CONTENT_TYPE_JSON);
+ }
+
+ /**
+ * @throws JsonException
+ */
+ protected function checkInput(): bool {
+ $fields = [
+ 'dashboardid' => 'required|db dashboard.dashboardid|not_empty',
+ 'templateid' => 'db dashboard.dashboardid|not_empty'
+ ];
+
+ $ret = $this->validateInput($fields);
+
+ if (!$ret) {
+ $this->setResponse(
+ new CControllerResponseData(['main_block' => json_encode([
+ 'error' => [
+ 'messages' => array_column(get_and_clear_messages(), 'message')
+ ]
+ ], JSON_THROW_ON_ERROR)])
+ );
+ }
+
+ return $ret;
+ }
+
+ protected function checkPermissions(): bool {
+ return true;
+ }
+
+ /**
+ * @throws APIException|JsonException
+ */
+ protected function doAction(): void {
+ $configuration_hash = null;
+
+ if ($this->checkAccess(CRoleHelper::UI_MONITORING_DASHBOARD)) {
+ if ($this->hasInput('templateid')) {
+ $db_dashboards = API::TemplateDashboard()->get([
+ 'output' => ['name', 'display_period', 'auto_start'],
+ 'selectPages' => ['dashboard_pageid', 'name', 'display_period', 'widgets'],
+ 'dashboardids' => $this->getInput('dashboardid')
+ ]);
+ }
+ else {
+ $db_dashboards = API::Dashboard()->get([
+ 'output' => ['name', 'display_period', 'auto_start'],
+ 'selectPages' => ['dashboard_pageid', 'name', 'display_period', 'widgets'],
+ 'dashboardids' => $this->getInput('dashboardid')
+ ]);
+ }
+
+ if ($db_dashboards) {
+ $db_dashboard = $db_dashboards[0];
+
+ $db_dashboard['pages'] = CDashboardHelper::preparePagesForGrid($db_dashboard['pages'],
+ $this->hasInput('templateid') ? $this->getInput('templateid') : null,
+ true
+ );
+
+ $widget_defaults = APP::ModuleManager()->getWidgetsDefaults($this->hasInput('templateid'));
+
+ $configuration_hash = CDashboardHelper::getConfigurationHash($db_dashboard, $widget_defaults);
+ }
+ }
+
+ $output = [
+ 'configuration_hash' => $configuration_hash
+ ];
+
+ $this->setResponse(new CControllerResponseData(['main_block' => json_encode($output, JSON_THROW_ON_ERROR)]));
+ }
+}
diff --git a/ui/app/controllers/CControllerDashboardPrint.php b/ui/app/controllers/CControllerDashboardPrint.php
index 724ae1d15b4..4dc3a5886a6 100644
--- a/ui/app/controllers/CControllerDashboardPrint.php
+++ b/ui/app/controllers/CControllerDashboardPrint.php
@@ -63,7 +63,7 @@ class CControllerDashboardPrint extends CController {
$data = [
'dashboard' => $dashboard,
- 'widget_defaults' => CWidgetConfig::getDefaults(CWidgetConfig::CONTEXT_DASHBOARD),
+ 'widget_defaults' => APP::ModuleManager()->getWidgetsDefaults(),
'time_period' => getTimeSelectorPeriod($time_selector_options)
];
diff --git a/ui/app/controllers/CControllerDashboardUpdate.php b/ui/app/controllers/CControllerDashboardUpdate.php
index 899e2263ded..3ed6849c0fa 100644
--- a/ui/app/controllers/CControllerDashboardUpdate.php
+++ b/ui/app/controllers/CControllerDashboardUpdate.php
@@ -21,7 +21,9 @@
class CControllerDashboardUpdate extends CController {
- private $dashboard_pages;
+ private ?array $db_dashboard = null;
+
+ private ?array $dashboard_pages = null;
protected function init() {
$this->setPostContentType(self::POST_CONTENT_TYPE_JSON);
@@ -35,17 +37,32 @@ class CControllerDashboardUpdate extends CController {
'display_period' => 'required|db dashboard.display_period|in '.implode(',', DASHBOARD_DISPLAY_PERIODS),
'auto_start' => 'required|db dashboard.auto_start|in 0,1',
'pages' => 'array',
- 'sharing' => 'array'
+ 'sharing' => 'array',
+ 'clone' => 'in 1'
];
$ret = $this->validateInput($fields);
+ if ($ret && $this->hasInput('clone')) {
+ $validator = new CNewValidator($this->getInputAll(), [
+ 'dashboardid' => 'required'
+ ]);
+
+ foreach ($validator->getAllErrors() as $error) {
+ info($error);
+ }
+
+ if ($validator->isErrorFatal() || $validator->isError()) {
+ $ret = false;
+ }
+ }
+
if ($ret) {
$sharing_errors = $this->validateSharing();
[
'dashboard_pages' => $this->dashboard_pages,
'errors' => $dashboard_pages_errors
- ] = CDashboardHelper::validateDashboardPages($this->getInput('pages', []), null);
+ ] = CDashboardHelper::validateDashboardPages($this->getInput('pages', []));
$errors = array_merge($sharing_errors, $dashboard_pages_errors);
@@ -70,90 +87,135 @@ class CControllerDashboardUpdate extends CController {
}
protected function checkPermissions() {
- return $this->checkAccess(CRoleHelper::UI_MONITORING_DASHBOARD)
- && $this->checkAccess(CRoleHelper::ACTIONS_EDIT_DASHBOARDS);
+ if (!$this->checkAccess(CRoleHelper::UI_MONITORING_DASHBOARD)
+ || !$this->checkAccess(CRoleHelper::ACTIONS_EDIT_DASHBOARDS)) {
+ return false;
+ }
+
+ if ($this->hasInput('dashboardid')) {
+ $db_dashboards = API::Dashboard()->get([
+ 'output' => ['dashboardid'],
+ 'selectPages' => ['widgets'],
+ 'dashboardids' => $this->getInput('dashboardid'),
+ 'editable' => true
+ ]);
+
+ if (!$db_dashboards) {
+ return false;
+ }
+
+ $this->db_dashboard = $db_dashboards[0];
+ }
+
+ return true;
}
protected function doAction() {
- $save_dashboard = [
- 'name' => $this->getInput('name'),
- 'userid' => $this->getInput('userid', 0),
- 'display_period' => $this->getInput('display_period'),
- 'auto_start' => $this->getInput('auto_start'),
- 'pages' => []
- ];
+ $output = [];
- if ($this->hasInput('dashboardid')) {
- $save_dashboard['dashboardid'] = $this->getInput('dashboardid');
- }
+ try {
+ $db_widgets = [];
+
+ if ($this->db_dashboard !== null) {
+ foreach ($this->db_dashboard['pages'] as $db_dashboard_page) {
+ foreach ($db_dashboard_page['widgets'] as $db_widget) {
+ $db_widgets[$db_widget['widgetid']] = $db_widget;
+ }
+ }
+ }
- foreach ($this->dashboard_pages as $dashboard_page) {
- $save_dashboard_page = [
- 'name' => $dashboard_page['name'],
- 'display_period' => $dashboard_page['display_period'],
- 'widgets' => []
+ $save_dashboard = [
+ 'name' => $this->getInput('name'),
+ 'userid' => $this->getInput('userid', 0),
+ 'display_period' => $this->getInput('display_period'),
+ 'auto_start' => $this->getInput('auto_start'),
+ 'pages' => []
];
- // Set dashboard_pageid if it exists and not cloning the dashboard.
- if (array_key_exists('dashboardid', $save_dashboard)
- && array_key_exists('dashboard_pageid', $dashboard_page)) {
- $save_dashboard_page['dashboard_pageid'] = $dashboard_page['dashboard_pageid'];
+ if ($this->db_dashboard !== null && !$this->hasInput('clone')) {
+ $save_dashboard['dashboardid'] = $this->db_dashboard['dashboardid'];
}
- foreach ($dashboard_page['widgets'] as $widget) {
- $save_widget = [
- 'x' => $widget['pos']['x'],
- 'y' => $widget['pos']['y'],
- 'width' => $widget['pos']['width'],
- 'height' => $widget['pos']['height'],
- 'type' => $widget['type'],
- 'name' => $widget['name'],
- 'view_mode' => $widget['view_mode'],
- 'fields' => $widget['form']->fieldsToApi()
+ foreach ($this->dashboard_pages as $dashboard_page) {
+ $save_dashboard_page = [
+ 'name' => $dashboard_page['name'],
+ 'display_period' => $dashboard_page['display_period'],
+ 'widgets' => []
];
- // Set widgetid if it exists and not cloning the dashboard.
- if (array_key_exists('dashboardid', $save_dashboard) && array_key_exists('widgetid', $widget)) {
- $save_widget['widgetid'] = $widget['widgetid'];
+ if (array_key_exists('dashboard_pageid', $dashboard_page) && !$this->hasInput('clone')) {
+ $save_dashboard_page['dashboard_pageid'] = $dashboard_page['dashboard_pageid'];
}
- $save_dashboard_page['widgets'][] = $save_widget;
- }
+ foreach ($dashboard_page['widgets'] as $widget) {
+ $save_widget = [
+ 'x' => $widget['pos']['x'],
+ 'y' => $widget['pos']['y'],
+ 'width' => $widget['pos']['width'],
+ 'height' => $widget['pos']['height']
+ ];
+
+ if ($widget['type'] !== ZBX_WIDGET_INACCESSIBLE) {
+ $save_widget += [
+ 'type' => $widget['type'],
+ 'name' => $widget['name'],
+ 'view_mode' => $widget['view_mode'],
+ 'fields' => $widget['form']->fieldsToApi()
+ ];
+ }
+ else {
+ if (!array_key_exists('widgetid', $widget)
+ || !array_key_exists($widget['widgetid'], $db_widgets)) {
+ error(_('No permissions to referred object or it does not exist!'));
- $save_dashboard['pages'][] = $save_dashboard_page;
- }
+ throw new InvalidArgumentException();
+ }
- if ($this->hasInput('sharing')) {
- $sharing = $this->getInput('sharing');
+ $db_widget = $db_widgets[$widget['widgetid']];
- $save_dashboard['private'] = $sharing['private'];
+ $save_widget += [
+ 'type' => $db_widget['type'],
+ 'name' => $db_widget['name'],
+ 'view_mode' => $db_widget['view_mode'],
+ 'fields' => $db_widget['fields']
+ ];
+ }
- if (array_key_exists('users', $sharing)) {
- $save_dashboard['users'] = $sharing['users'];
- }
+ if (array_key_exists('widgetid', $widget) && !$this->hasInput('clone')) {
+ $save_widget['widgetid'] = $widget['widgetid'];
+ }
+
+ $save_dashboard_page['widgets'][] = $save_widget;
+ }
- if (array_key_exists('userGroups', $sharing)) {
- $save_dashboard['userGroups'] = $sharing['userGroups'];
+ $save_dashboard['pages'][] = $save_dashboard_page;
}
- }
- if (array_key_exists('dashboardid', $save_dashboard)) {
- $result = API::Dashboard()->update($save_dashboard);
+ if ($this->hasInput('sharing')) {
+ $sharing = $this->getInput('sharing');
- $success_title = _('Dashboard updated');
- $error_title = _('Failed to update dashboard');
- }
- else {
- $result = API::Dashboard()->create($save_dashboard);
+ $save_dashboard['private'] = $sharing['private'];
- $success_title = _('Dashboard created');
- $error_title = _('Failed to create dashboard');
- }
+ if (array_key_exists('users', $sharing)) {
+ $save_dashboard['users'] = $sharing['users'];
+ }
- $output = [];
+ if (array_key_exists('userGroups', $sharing)) {
+ $save_dashboard['userGroups'] = $sharing['userGroups'];
+ }
+ }
+
+ $result = $this->db_dashboard !== null && !$this->hasInput('clone')
+ ? API::Dashboard()->update($save_dashboard)
+ : API::Dashboard()->create($save_dashboard);
+
+ if (!$result) {
+ throw new InvalidArgumentException();
+ }
- if ($result) {
- $output['success']['title'] = $success_title;
+ $output['success']['title'] = $this->db_dashboard !== null && !$this->hasInput('clone')
+ ? _('Dashboard updated')
+ : _('Dashboard created');
if ($messages = get_and_clear_messages()) {
$output['success']['messages'] = array_column($messages, 'message');
@@ -161,9 +223,11 @@ class CControllerDashboardUpdate extends CController {
$output['dashboardid'] = $result['dashboardids'][0];
}
- else {
+ catch (InvalidArgumentException $e) {
$output['error'] = [
- 'title' => $error_title,
+ 'title' => $this->db_dashboard !== null && !$this->hasInput('clone')
+ ? _('Failed to update dashboard')
+ : _('Failed to create dashboard'),
'messages' => array_column(get_and_clear_messages(), 'message')
];
}
diff --git a/ui/app/controllers/CControllerDashboardView.php b/ui/app/controllers/CControllerDashboardView.php
index ef207da6776..8ea10a11570 100644
--- a/ui/app/controllers/CControllerDashboardView.php
+++ b/ui/app/controllers/CControllerDashboardView.php
@@ -28,10 +28,10 @@ class CControllerDashboardView extends CController {
protected function checkInput() {
$fields = [
'dashboardid' => 'db dashboard.dashboardid',
- 'source_dashboardid' => 'db dashboard.dashboardid',
'hostid' => 'db hosts.hostid',
'new' => 'in 1',
'cancel' => 'in 1',
+ 'clone' => 'in 1',
'from' => 'range_time',
'to' => 'range_time',
'slideshow' => 'in 1'
@@ -39,6 +39,20 @@ class CControllerDashboardView extends CController {
$ret = $this->validateInput($fields) && $this->validateTimeSelectorPeriod();
+ if ($ret && $this->hasInput('clone')) {
+ $validator = new CNewValidator($this->getInputAll(), [
+ 'dashboardid' => 'required'
+ ]);
+
+ foreach ($validator->getAllErrors() as $error) {
+ info($error);
+ }
+
+ if ($validator->isErrorFatal() || $validator->isError()) {
+ $ret = false;
+ }
+ }
+
if (!$ret) {
$this->setResponse(new CControllerResponseFatal());
}
@@ -51,7 +65,7 @@ class CControllerDashboardView extends CController {
return false;
}
- if ($this->hasInput('new') || $this->hasInput('source_dashboardid')) {
+ if ($this->hasInput('new') || $this->hasInput('clone')) {
return $this->checkAccess(CRoleHelper::ACTIONS_EDIT_DASHBOARDS);
}
@@ -69,6 +83,9 @@ class CControllerDashboardView extends CController {
return true;
}
+ /**
+ * @throws JsonException
+ */
protected function doAction() {
[$dashboard, $error] = $this->getDashboard();
@@ -99,18 +116,25 @@ class CControllerDashboardView extends CController {
$time_selector_options = [
'profileIdx' => 'web.dashboard.filter',
- 'profileIdx2' => ($dashboard['dashboardid'] !== null) ? $dashboard['dashboardid'] : 0,
+ 'profileIdx2' => $dashboard['dashboardid'] ?? 0,
'from' => $this->hasInput('from') ? $this->getInput('from') : null,
'to' => $this->hasInput('to') ? $this->getInput('to') : null
];
updateTimeSelectorPeriod($time_selector_options);
+ $widget_defaults = APP::ModuleManager()->getWidgetsDefaults();
+
$data = [
'dashboard' => $dashboard,
- 'widget_defaults' => CWidgetConfig::getDefaults(CWidgetConfig::CONTEXT_DASHBOARD),
+ 'widget_defaults' => $widget_defaults,
+ 'widget_last_type' => CDashboardHelper::getWidgetLastType(),
+ 'configuration_hash' => $dashboard['dashboardid'] !== null
+ ? CDashboardHelper::getConfigurationHash($dashboard, $widget_defaults)
+ : null,
'has_time_selector' => CDashboardHelper::hasTimeSelector($dashboard['pages']),
'time_period' => getTimeSelectorPeriod($time_selector_options),
+ 'clone' => $this->hasInput('clone'),
'active_tab' => CProfile::get('web.dashboard.filter.active', 1)
];
@@ -143,10 +167,8 @@ class CControllerDashboardView extends CController {
/**
* Get dashboard data from API.
- *
- * @return array
*/
- private function getDashboard() {
+ private function getDashboard(): array {
$dashboard = null;
$error = null;
@@ -172,19 +194,18 @@ class CControllerDashboardView extends CController {
'has_related_reports' => false
];
}
- elseif ($this->hasInput('source_dashboardid')) {
- // Clone dashboard and show as new.
+ elseif ($this->hasInput('clone')) {
$dashboards = API::Dashboard()->get([
- 'output' => ['name', 'private', 'display_period', 'auto_start'],
+ 'output' => ['dashboardid', 'name', 'private', 'display_period', 'auto_start'],
'selectPages' => ['dashboard_pageid', 'name', 'display_period', 'widgets'],
'selectUsers' => ['userid', 'permission'],
'selectUserGroups' => ['usrgrpid', 'permission'],
- 'dashboardids' => [$this->getInput('source_dashboardid')]
+ 'dashboardids' => $this->getInput('dashboardid')
]);
if ($dashboards) {
$dashboard = [
- 'dashboardid' => null,
+ 'dashboardid' => $dashboards[0]['dashboardid'],
'name' => $dashboards[0]['name'],
'display_period' => $dashboards[0]['display_period'],
'auto_start' => $dashboards[0]['auto_start'],
@@ -231,7 +252,7 @@ class CControllerDashboardView extends CController {
$dashboards = API::Dashboard()->get([
'output' => ['dashboardid', 'name', 'userid', 'display_period', 'auto_start'],
'selectPages' => ['dashboard_pageid', 'name', 'display_period', 'widgets'],
- 'dashboardids' => [$dashboardid],
+ 'dashboardids' => $dashboardid,
'preservekeys' => true
]);
@@ -266,14 +287,8 @@ class CControllerDashboardView extends CController {
/**
* Checks, if any of widgets has checked dynamic field.
- *
- * @param array $grid_pages
- *
- * @static
- *
- * @return bool
*/
- private static function hasDynamicWidgets($grid_pages) {
+ private static function hasDynamicWidgets($grid_pages): bool {
foreach ($grid_pages as $page) {
foreach ($page['widgets'] as $widget) {
if (array_key_exists('dynamic', $widget['fields']) && $widget['fields']['dynamic'] == 1) {
diff --git a/ui/app/controllers/CControllerDashboardWidgetCheck.php b/ui/app/controllers/CControllerDashboardWidgetCheck.php
index 5c1c159bddc..6c9d3208dbf 100644
--- a/ui/app/controllers/CControllerDashboardWidgetCheck.php
+++ b/ui/app/controllers/CControllerDashboardWidgetCheck.php
@@ -19,9 +19,14 @@
**/
+use Zabbix\Core\{
+ CModule,
+ CWidget
+};
+
class CControllerDashboardWidgetCheck extends CController {
- private $context;
+ private ?CWidget $widget = null;
protected function init() {
$this->setPostContentType(self::POST_CONTENT_TYPE_JSON);
@@ -29,26 +34,33 @@ class CControllerDashboardWidgetCheck extends CController {
protected function checkInput() {
$fields = [
- 'templateid' => 'db dashboard.templateid',
'type' => 'required|string',
- 'name' => 'required|string',
- 'fields' => 'json'
+ 'fields' => 'array',
+ 'templateid' => 'db dashboard.templateid',
+ 'name' => 'required|string'
];
$ret = $this->validateInput($fields);
if ($ret) {
- $this->context = $this->hasInput('templateid')
- ? CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD
- : CWidgetConfig::CONTEXT_DASHBOARD;
+ $widget = APP::ModuleManager()->getModule($this->getInput('type'));
- if (!CWidgetConfig::isWidgetTypeSupportedInContext($this->getInput('type'), $this->context)) {
- error(_('Widget type is not supported in this context.'));
+ if ($widget !== null && $widget->getType() === CModule::TYPE_WIDGET) {
+ $this->widget = $widget;
+ }
+ else {
+ error(_('Inaccessible widget type.'));
$ret = false;
}
}
+ if ($ret && $this->hasInput('templateid') && !$this->widget->hasTemplateSupport()) {
+ error(_('Widget type is not supported in this context.'));
+
+ $ret = false;
+ }
+
if (!$ret) {
$this->setResponse(
new CControllerResponseData(['main_block' => json_encode([
@@ -67,8 +79,8 @@ class CControllerDashboardWidgetCheck extends CController {
}
protected function doAction() {
- $form = CWidgetConfig::getForm($this->getInput('type'), $this->getInput('fields', '{}'),
- ($this->context === CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD) ? $this->getInput('templateid') : null
+ $form = $this->widget->getForm($this->getInput('fields', []),
+ $this->hasInput('templateid') ? $this->getInput('templateid') : null
);
$output = [];
diff --git a/ui/app/controllers/CControllerDashboardWidgetConfigure.php b/ui/app/controllers/CControllerDashboardWidgetConfigure.php
deleted file mode 100644
index 9c34138eac8..00000000000
--- a/ui/app/controllers/CControllerDashboardWidgetConfigure.php
+++ /dev/null
@@ -1,87 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-class CControllerDashboardWidgetConfigure extends CController {
-
- private $context;
-
- protected function init() {
- $this->setPostContentType(self::POST_CONTENT_TYPE_JSON);
- }
-
- protected function checkInput() {
- $fields = [
- 'templateid' => 'db dashboard.templateid',
- 'type' => 'required|string',
- 'fields' => 'json',
- 'view_mode' => 'required|in '.implode(',', [ZBX_WIDGET_VIEW_MODE_NORMAL, ZBX_WIDGET_VIEW_MODE_HIDDEN_HEADER])
- ];
-
- $ret = $this->validateInput($fields);
-
- if ($ret) {
- $this->context = $this->hasInput('templateid')
- ? CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD
- : CWidgetConfig::CONTEXT_DASHBOARD;
-
- if (!CWidgetConfig::isWidgetTypeSupportedInContext($this->getInput('type'), $this->context)) {
- error(_('Widget type is not supported in this context.'));
-
- $ret = false;
- }
- }
-
- if (!$ret) {
- $this->setResponse(
- new CControllerResponseData(['main_block' => json_encode([
- 'error' => [
- 'messages' => array_column(get_and_clear_messages(), 'message')
- ]
- ])])
- );
- }
-
- return $ret;
- }
-
- protected function checkPermissions() {
- return ($this->getUserType() >= USER_TYPE_ZABBIX_USER);
- }
-
- protected function doAction() {
- $type = $this->getInput('type');
-
- $form = CWidgetConfig::getForm($type, $this->getInput('fields', '{}'),
- ($this->context === CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD) ? $this->getInput('templateid') : null
- );
-
- // Fix possibly corrupted data to the defaults.
- $form->validate();
-
- $output = [
- 'configuration' => CWidgetConfig::getConfiguration($type, $form->getFieldsData(),
- $this->getInput('view_mode')
- )
- ];
-
- $this->setResponse(new CControllerResponseData(['main_block' => json_encode($output)]));
- }
-}
diff --git a/ui/app/controllers/CControllerDashboardWidgetEdit.php b/ui/app/controllers/CControllerDashboardWidgetEdit.php
index bf020dfe72d..7390872df0d 100644
--- a/ui/app/controllers/CControllerDashboardWidgetEdit.php
+++ b/ui/app/controllers/CControllerDashboardWidgetEdit.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,18 +19,36 @@
**/
+use Zabbix\Core\{
+ CModule,
+ CWidget
+};
+
+use Zabbix\Widgets\CWidgetForm;
+
+use Zabbix\Widgets\Fields\{
+ CWidgetFieldMultiSelectGraph,
+ CWidgetFieldMultiSelectGraphPrototype,
+ CWidgetFieldMultiSelectGroup,
+ CWidgetFieldMultiSelectHost,
+ CWidgetFieldMultiSelectItem,
+ CWidgetFieldMultiSelectItemPrototype,
+ CWidgetFieldMultiSelectService,
+ CWidgetFieldMultiSelectSla,
+ CWidgetFieldSelectResource
+};
+
class CControllerDashboardWidgetEdit extends CController {
- private $context;
+ private ?CWidget $widget;
- protected function checkInput() {
+ protected function checkInput(): bool {
$fields = [
+ 'type' => 'string|required',
+ 'fields' => 'array',
'templateid' => 'db dashboard.templateid',
- 'type' => 'string',
'name' => 'string',
'view_mode' => 'in '.implode(',', [ZBX_WIDGET_VIEW_MODE_NORMAL, ZBX_WIDGET_VIEW_MODE_HIDDEN_HEADER]),
- 'prev_type' => 'string',
- 'fields' => 'json',
'unique_id' => 'string',
'dashboard_page_unique_id' => 'string'
];
@@ -38,94 +56,92 @@ class CControllerDashboardWidgetEdit extends CController {
$ret = $this->validateInput($fields);
if ($ret) {
- $this->context = $this->hasInput('templateid')
- ? CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD
- : CWidgetConfig::CONTEXT_DASHBOARD;
+ $widget = APP::ModuleManager()->getModule($this->getInput('type'));
- if ($this->hasInput('type')) {
- if (!CWidgetConfig::isWidgetTypeSupportedInContext($this->getInput('type'), $this->context)) {
- error(_('Widget type is not supported in this context.'));
+ if ($widget !== null && $widget->getType() === CModule::TYPE_WIDGET) {
+ $this->widget = $widget;
+ }
+ else {
+ error(_('Inaccessible widget type.'));
- $ret = false;
- }
+ $ret = false;
}
}
+ if ($ret && $this->hasInput('templateid') && !$this->widget->hasTemplateSupport()) {
+ error(_('Widget type is not supported in this context.'));
+
+ $ret = false;
+ }
+
if (!$ret) {
$this->setResponse(
- (new CControllerResponseData(['main_block' => json_encode([
- 'error' => [
- 'messages' => array_column(get_and_clear_messages(), 'message')
- ]
- ])]))->disableView()
+ (new CControllerResponseData([
+ 'main_block' => json_encode([
+ 'header' => $this->hasInput('unique_id') ? _('Edit widget') : _('Add widget'),
+ 'error' => [
+ 'messages' => array_column(get_and_clear_messages(), 'message')
+ ]
+ ], JSON_THROW_ON_ERROR)
+ ]))->disableView()
);
}
return $ret;
}
- protected function checkPermissions() {
- return ($this->context === CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD)
+ protected function checkPermissions(): bool {
+ return $this->hasInput('templateid')
? ($this->getUserType() >= USER_TYPE_ZABBIX_ADMIN)
: ($this->getUserType() >= USER_TYPE_ZABBIX_USER);
}
- protected function doAction() {
- $known_widget_types = CWidgetConfig::getKnownWidgetTypes($this->context);
-
- natsort($known_widget_types);
+ protected function doAction(): void {
+ $known_types = [];
+ $deprecated_types = [];
- if ($this->hasInput('type')) {
- $type = $this->getInput('type');
-
- if (!array_key_exists($type, $known_widget_types) || $this->getInput('prev_type', $type) !== $type) {
- CProfile::update('web.dashboard.last_widget_type', $type, PROFILE_TYPE_STR);
+ /** @var CWidget $widget */
+ foreach (APP::ModuleManager()->getWidgets($this->hasInput('templateid')) as $widget) {
+ if (!$widget->isDeprecated()) {
+ $known_types[$widget->getId()] = $widget->getDefaultName();
}
- }
- else {
- $type = CProfile::get('web.dashboard.last_widget_type');
- if (!array_key_exists($type, $known_widget_types)) {
- $type = array_keys($known_widget_types)[0];
+ else {
+ $deprecated_types[$widget->getId()] = $widget->getDefaultName();
}
}
- $templateid = ($this->context === CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD)
- ? $this->getInput('templateid')
- : null;
+ natcasesort($known_types);
+ natcasesort($deprecated_types);
- $form = CWidgetConfig::getForm($type, $this->getInput('fields', '{}'), $templateid);
+ $form = $this->widget->getForm($this->getInput('fields', []),
+ $this->hasInput('templateid') ? $this->getInput('templateid') : null
+ );
// Transforms corrupted data to default values.
$form->validate();
$this->setResponse(new CControllerResponseData([
- 'user' => [
- 'debug_mode' => $this->getDebugMode()
- ],
- 'dialogue' => [
- 'type' => $type,
- 'name' => $this->getInput('name', ''),
- 'view_mode' => $this->getInput('view_mode', ZBX_WIDGET_VIEW_MODE_NORMAL),
- 'fields' => $form->getFields()
- ],
- 'templateid' => $templateid,
+ 'name' => $this->getInput('name', ''),
+ 'type' => $this->getInput('type'),
+ 'known_types' => $known_types,
+ 'deprecated_types' => $deprecated_types,
+ 'fields' => $form->getFields(),
+ 'view_mode' => $this->getInput('view_mode', ZBX_WIDGET_VIEW_MODE_NORMAL),
'unique_id' => $this->hasInput('unique_id') ? $this->getInput('unique_id') : null,
'dashboard_page_unique_id' => $this->hasInput('dashboard_page_unique_id')
? $this->getInput('dashboard_page_unique_id')
: null,
- 'known_widget_types' => $known_widget_types,
- 'captions' => $this->getCaptions($form)
+ 'captions' => $this->getCaptions($form),
+ 'user' => [
+ 'debug_mode' => $this->getDebugMode()
+ ]
]));
}
/**
* Prepares mapped list of names for all required resources.
- *
- * @param CWidgetForm $form
- *
- * @return array
*/
- private function getCaptions($form) {
+ private function getCaptions(CWidgetForm $form): array {
$captions = ['simple' => [], 'ms' => []];
foreach ($form->getFields() as $field) {
@@ -137,12 +153,8 @@ class CControllerDashboardWidgetEdit extends CController {
$captions['simple'][$resource_type] = [];
}
- if ($id != 0) {
- switch ($resource_type) {
- case WIDGET_FIELD_SELECT_RES_SYSMAP:
- $captions['simple'][$resource_type][$id] = _('Inaccessible map');
- break;
- }
+ if ($id != 0 && $resource_type == CWidgetFieldSelectResource::RESOURCE_TYPE_SYSMAP) {
+ $captions['simple'][$resource_type][$id] = _('Inaccessible map');
}
}
}
@@ -152,19 +164,17 @@ class CControllerDashboardWidgetEdit extends CController {
continue;
}
- switch ($resource_type) {
- case WIDGET_FIELD_SELECT_RES_SYSMAP:
- $maps = API::Map()->get([
- 'sysmapids' => array_keys($list),
- 'output' => ['sysmapid', 'name']
- ]);
-
- if ($maps) {
- foreach ($maps as $map) {
- $list[$map['sysmapid']] = $map['name'];
- }
+ if ($resource_type == CWidgetFieldSelectResource::RESOURCE_TYPE_SYSMAP) {
+ $maps = API::Map()->get([
+ 'sysmapids' => array_keys($list),
+ 'output' => ['sysmapid', 'name']
+ ]);
+
+ if ($maps) {
+ foreach ($maps as $map) {
+ $list[$map['sysmapid']] = $map['name'];
}
- break;
+ }
}
}
unset($list);
@@ -182,35 +192,35 @@ class CControllerDashboardWidgetEdit extends CController {
];
foreach ($form->getFields() as $field) {
- if ($field instanceof CWidgetFieldMsGroup) {
+ if ($field instanceof CWidgetFieldMultiSelectGroup) {
$key = 'groups';
$var = 'group';
}
- elseif ($field instanceof CWidgetFieldMsHost) {
+ elseif ($field instanceof CWidgetFieldMultiSelectHost) {
$key = 'hosts';
$var = 'host';
}
- elseif ($field instanceof CWidgetFieldMsItem) {
+ elseif ($field instanceof CWidgetFieldMultiSelectItem) {
$key = 'items';
$var = 'item';
}
- elseif ($field instanceof CWidgetFieldMsGraph) {
+ elseif ($field instanceof CWidgetFieldMultiSelectGraph) {
$key = 'graphs';
$var = 'graph';
}
- elseif ($field instanceof CWidgetFieldMsItemPrototype) {
+ elseif ($field instanceof CWidgetFieldMultiSelectItemPrototype) {
$key = 'item_prototypes';
$var = 'prototype_item';
}
- elseif ($field instanceof CWidgetFieldMsGraphPrototype) {
+ elseif ($field instanceof CWidgetFieldMultiSelectGraphPrototype) {
$key = 'graph_prototypes';
$var = 'prototype_graph';
}
- elseif ($field instanceof CWidgetFieldMsService) {
+ elseif ($field instanceof CWidgetFieldMultiSelectService) {
$key = 'services';
$var = 'service';
}
- elseif ($field instanceof CWidgetFieldMsSla) {
+ elseif ($field instanceof CWidgetFieldMultiSelectSla) {
$key = 'slas';
$var = 'sla';
}
diff --git a/ui/app/controllers/CControllerDashboardWidgetRfRate.php b/ui/app/controllers/CControllerDashboardWidgetRfRate.php
index a7f8a2e603a..d8bc3432d47 100644
--- a/ui/app/controllers/CControllerDashboardWidgetRfRate.php
+++ b/ui/app/controllers/CControllerDashboardWidgetRfRate.php
@@ -19,8 +19,6 @@
**/
-require_once dirname(__FILE__).'/../../include/blocks.inc.php';
-
class CControllerDashboardWidgetRfRate extends CController {
protected function init() {
diff --git a/ui/app/controllers/CControllerDashboardWidgetView.php b/ui/app/controllers/CControllerDashboardWidgetView.php
new file mode 100644
index 00000000000..f589e96f726
--- /dev/null
+++ b/ui/app/controllers/CControllerDashboardWidgetView.php
@@ -0,0 +1,107 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Core\CWidget;
+
+use Zabbix\Widgets\CWidgetForm;
+
+/**
+ * Class containing methods for operations with widgets.
+ */
+abstract class CControllerDashboardWidgetView extends CController {
+
+ protected ?CWidget $widget;
+ protected CWidgetForm $form;
+
+ protected array $validation_rules = [];
+ protected array $fields_values = [];
+
+ protected function init(): void {
+ $this->setPostContentType(self::POST_CONTENT_TYPE_JSON);
+
+ $this->setValidationRules([
+ 'name' => 'string',
+ 'fields' => 'array'
+ ]);
+ }
+
+ protected function setValidationRules(array $validation_rules): self {
+ $this->validation_rules = $validation_rules;
+
+ return $this;
+ }
+
+ protected function addValidationRules(array $validation_rules): self {
+ $this->validation_rules = array_merge($this->validation_rules, $validation_rules);
+
+ return $this;
+ }
+
+ protected function checkPermissions(): bool {
+ return $this->getUserType() >= USER_TYPE_ZABBIX_USER;
+ }
+
+ protected function checkInput(): bool {
+ $this->widget = APP::ModuleManager()->getActionModule();
+
+ $validation_rules = $this->validation_rules;
+
+ if ($this->widget->hasTemplateSupport()) {
+ $validation_rules['templateid'] = 'db dashboard.templateid';
+ }
+
+ $ret = $this->validateInput($validation_rules);
+
+ if ($ret) {
+ $this->form = $this->widget->getForm($this->getInput('fields', []),
+ $this->hasInput('templateid') ? $this->getInput('templateid') : null
+ );
+
+ if ($errors = $this->form->validate()) {
+ foreach ($errors as $error) {
+ error($error);
+ }
+
+ $ret = false;
+ }
+ }
+
+ if ($ret) {
+ $this->fields_values = $this->form->getFieldsValues();
+ }
+
+ if (!$ret) {
+ $this->setResponse(
+ (new CControllerResponseData(['main_block' => json_encode([
+ 'error' => [
+ 'messages' => array_column(get_and_clear_messages(), 'message')
+ ]
+ ], JSON_THROW_ON_ERROR)]))->disableView()
+ );
+ }
+
+ return $ret;
+ }
+
+ protected function getForm(): CWidgetForm {
+ return $this->form;
+ }
+}
diff --git a/ui/app/controllers/CControllerDashboardWidgetsSanitize.php b/ui/app/controllers/CControllerDashboardWidgetsSanitize.php
index 5d2f8d8a07a..7137ffd41b6 100644
--- a/ui/app/controllers/CControllerDashboardWidgetsSanitize.php
+++ b/ui/app/controllers/CControllerDashboardWidgetsSanitize.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,19 +19,20 @@
**/
+use Zabbix\Core\CModule;
+
/**
* Controller for sanitizing fields of widgets before pasting previously copied widget.
*/
class CControllerDashboardWidgetsSanitize extends CController {
- private $context;
- private $widgets = [];
+ private array $widgets_data = [];
- protected function init() {
+ protected function init(): void {
$this->setPostContentType(self::POST_CONTENT_TYPE_JSON);
}
- protected function checkInput() {
+ protected function checkInput(): bool {
$fields = [
'templateid' => 'db dashboard.templateid',
'widgets' => 'array'
@@ -40,14 +41,10 @@ class CControllerDashboardWidgetsSanitize extends CController {
$ret = $this->validateInput($fields);
if ($ret) {
- $this->context = $this->hasInput('templateid')
- ? CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD
- : CWidgetConfig::CONTEXT_DASHBOARD;
-
foreach ($this->getInput('widgets', []) as $widget) {
$validator = new CNewValidator($widget, [
'type' => 'required|string',
- 'fields' => 'required|json'
+ 'fields' => 'required|array'
]);
foreach ($validator->getAllErrors() as $error) {
@@ -60,9 +57,17 @@ class CControllerDashboardWidgetsSanitize extends CController {
break;
}
- $widget = $validator->getValidInput();
+ $widget_input = $validator->getValidInput();
+
+ $widget = APP::ModuleManager()->getModule($widget_input['type']);
+
+ if ($widget === null || $widget->getType() !== CModule::TYPE_WIDGET) {
+ $this->widgets_data[] = null;
- if (!CWidgetConfig::isWidgetTypeSupportedInContext($widget['type'], $this->context)) {
+ continue;
+ }
+
+ if ($this->hasInput('templateid') && !$widget->hasTemplateSupport()) {
error(_('Widget type is not supported in this context.'));
$ret = false;
@@ -70,7 +75,12 @@ class CControllerDashboardWidgetsSanitize extends CController {
break;
}
- $this->widgets[] = $widget;
+ $this->widgets_data[] = [
+ 'type' => $widget_input['type'],
+ 'form' => $widget->getForm($widget_input['fields'],
+ $this->hasInput('templateid') ? $this->getInput('templateid') : null
+ )
+ ];
}
}
@@ -80,29 +90,27 @@ class CControllerDashboardWidgetsSanitize extends CController {
'error' => [
'messages' => array_column(get_and_clear_messages(), 'message')
]
- ])])
+ ], JSON_THROW_ON_ERROR)])
);
}
return $ret;
}
- protected function checkPermissions() {
+ protected function checkPermissions(): bool {
return ($this->getUserType() >= USER_TYPE_ZABBIX_USER);
}
- protected function doAction() {
+ protected function doAction(): void {
$widgets = [];
- foreach ($this->widgets as $widget) {
- $form = CWidgetConfig::getForm($widget['type'], $widget['fields'],
- ($this->context === CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD) ? $this->getInput('templateid') : null
- );
-
- $widgets[] = ['fields' => $form->fieldsToApi()];
+ foreach ($this->widgets_data as $index => $widget_data) {
+ if ($widget_data !== null) {
+ $widgets[$index] = ['fields' => $widget_data['form']->fieldsToApi()];
+ }
}
- if ($this->context === CWidgetConfig::CONTEXT_DASHBOARD) {
+ if (!$this->hasInput('templateid')) {
$widgets = CDashboardHelper::unsetInaccessibleFields([['widgets' => $widgets]]);
$widgets = $widgets[0]['widgets'];
}
@@ -111,11 +119,16 @@ class CControllerDashboardWidgetsSanitize extends CController {
'widgets' => []
];
- foreach ($widgets as $widget_index => $widget) {
- $output_fields = [];
+ foreach ($this->widgets_data as $index => $widget_data) {
+ if ($widget_data === null) {
+ $output['widgets'][$index] = null;
- foreach ($widget['fields'] as $field) {
+ continue;
+ }
+
+ $output_fields = [];
+ foreach ($widgets[$index]['fields'] as $field) {
if (array_key_exists($field['name'], $output_fields)) {
if (!is_array($output_fields[$field['name']])) {
$output_fields[$field['name']] = [$output_fields[$field['name']]];
@@ -128,9 +141,9 @@ class CControllerDashboardWidgetsSanitize extends CController {
}
}
- $output['widgets'][$widget_index]['fields'] = $output_fields;
+ $output['widgets'][$index]['fields'] = $output_fields;
}
- $this->setResponse(new CControllerResponseData(['main_block' => json_encode($output)]));
+ $this->setResponse(new CControllerResponseData(['main_block' => json_encode($output, JSON_THROW_ON_ERROR)]));
}
}
diff --git a/ui/app/controllers/CControllerFavouriteCreate.php b/ui/app/controllers/CControllerFavoriteCreate.php
index bdc2ae6256c..33b7e6b29c0 100644
--- a/ui/app/controllers/CControllerFavouriteCreate.php
+++ b/ui/app/controllers/CControllerFavoriteCreate.php
@@ -19,7 +19,7 @@
**/
-class CControllerFavouriteCreate extends CController {
+class CControllerFavoriteCreate extends CController {
protected function checkInput() {
$fields = [
diff --git a/ui/app/controllers/CControllerFavouriteDelete.php b/ui/app/controllers/CControllerFavoriteDelete.php
index 1a7cf92c1ab..468d0a88373 100644
--- a/ui/app/controllers/CControllerFavouriteDelete.php
+++ b/ui/app/controllers/CControllerFavoriteDelete.php
@@ -19,7 +19,12 @@
**/
-class CControllerFavouriteDelete extends CController {
+use Zabbix\Core\CWidget;
+
+class CControllerFavoriteDelete extends CController {
+
+ private const WIDGET_FAV_GRAPHS = 'favgraphs';
+ private const WIDGET_FAV_MAPS = 'favmaps';
protected function checkInput() {
$fields = [
@@ -46,10 +51,10 @@ class CControllerFavouriteDelete extends CController {
'sysmapid' => 'web.favorite.sysmapids'
];
- $widgetids = [
- 'graphid' => WIDGET_FAV_GRAPHS,
- 'itemid' => WIDGET_FAV_GRAPHS,
- 'sysmapid' => WIDGET_FAV_MAPS
+ $affected_widget_types = [
+ 'graphid' => self::WIDGET_FAV_GRAPHS,
+ 'itemid' => self::WIDGET_FAV_GRAPHS,
+ 'sysmapid' => self::WIDGET_FAV_MAPS
];
$object = $this->getInput('object');
@@ -73,7 +78,8 @@ class CControllerFavouriteDelete extends CController {
}
else {
ZABBIX.Dashboard.getSelectedDashboardPage().getWidgets().forEach((widget) => {
- if (widget.getType() === "'.$widgetids[$object].'") {
+ if (widget.getType() === "'.$affected_widget_types[$object].'"
+ && widget.getState() === WIDGET_STATE_ACTIVE) {
widget._startUpdating();
}
});
diff --git a/ui/app/controllers/CControllerHintboxEventlist.php b/ui/app/controllers/CControllerHintboxEventlist.php
index 73f20d4f297..a6ccad55510 100644
--- a/ui/app/controllers/CControllerHintboxEventlist.php
+++ b/ui/app/controllers/CControllerHintboxEventlist.php
@@ -34,7 +34,7 @@ class CControllerHintboxEventlist extends CController {
$fields = [
'triggerid' => 'required|db triggers.triggerid',
'eventid_till' => 'required|db events.eventid',
- 'show_timeline' => 'required|in 0,1',
+ 'show_timeline' => 'required|in '.implode(',', [ZBX_TIMELINE_OFF, ZBX_TIMELINE_ON]),
'show_tags' => 'required|in '.implode(',', [SHOW_TAGS_NONE, SHOW_TAGS_1, SHOW_TAGS_2, SHOW_TAGS_3]),
'filter_tags' => 'array',
'tag_name_format' => 'required|in '.implode(',', [TAG_NAME_FULL, TAG_NAME_SHORTENED, TAG_NAME_NONE]),
diff --git a/ui/app/controllers/CControllerHostDashboardView.php b/ui/app/controllers/CControllerHostDashboardView.php
index e738c79f444..b2062fe2d2c 100644
--- a/ui/app/controllers/CControllerHostDashboardView.php
+++ b/ui/app/controllers/CControllerHostDashboardView.php
@@ -60,6 +60,9 @@ class CControllerHostDashboardView extends CController {
return (bool) $this->host;
}
+ /**
+ * @throws APIException|JsonException
+ */
protected function doAction() {
$host_dashboards = $this->getSortedHostDashboards();
@@ -101,11 +104,14 @@ class CControllerHostDashboardView extends CController {
updateTimeSelectorPeriod($time_selector_options);
+ $widget_defaults = APP::ModuleManager()->getWidgetsDefaults(true);
+
$data = [
'host' => $this->host,
'host_dashboards' => $host_dashboards,
'dashboard' => $dashboard,
- 'widget_defaults' => CWidgetConfig::getDefaults(CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD),
+ 'widget_defaults' => $widget_defaults,
+ 'configuration_hash' => CDashboardHelper::getConfigurationHash($dashboard, $widget_defaults),
'has_time_selector' => CDashboardHelper::hasTimeSelector($dashboard['pages']),
'time_period' => getTimeSelectorPeriod($time_selector_options),
'active_tab' => CProfile::get('web.dashboard.filter.active', 1)
diff --git a/ui/app/controllers/CControllerModuleEdit.php b/ui/app/controllers/CControllerModuleEdit.php
index 0f0405e107a..faec576705d 100644
--- a/ui/app/controllers/CControllerModuleEdit.php
+++ b/ui/app/controllers/CControllerModuleEdit.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -26,16 +26,14 @@ class CControllerModuleEdit extends CController {
/**
* Current module data.
- *
- * @var array
*/
- private $module = [];
+ private array $module = [];
- protected function init() {
+ protected function init(): void {
$this->disableSIDValidation();
}
- protected function checkInput() {
+ protected function checkInput(): bool {
$fields = [
'moduleid' => 'required|db module.moduleid',
@@ -53,7 +51,7 @@ class CControllerModuleEdit extends CController {
return $ret;
}
- protected function checkPermissions() {
+ protected function checkPermissions(): bool {
if (!$this->checkAccess(CRoleHelper::UI_ADMINISTRATION_GENERAL)) {
return false;
}
@@ -72,12 +70,12 @@ class CControllerModuleEdit extends CController {
return true;
}
- protected function doAction() {
- $module_manager = new CModuleManager(APP::ModuleManager()->getModulesDir());
+ protected function doAction(): void {
+ $module_manager = new CModuleManager(APP::getRootDir());
$manifest = $module_manager->addModule($this->module['relative_path']);
- if ($manifest) {
+ if ($manifest !== null) {
$data = [
'moduleid' => $this->getInput('moduleid'),
'name' => $manifest['name'],
@@ -88,15 +86,12 @@ class CControllerModuleEdit extends CController {
'namespace' => $manifest['namespace'],
'url' => array_key_exists('url', $manifest) ? $manifest['url'] : null,
'status' => $this->hasInput('form_refresh')
- ? $this->hasInput('status')
- ? MODULE_STATUS_ENABLED
- : MODULE_STATUS_DISABLED
+ ? ($this->hasInput('status') ? MODULE_STATUS_ENABLED : MODULE_STATUS_DISABLED)
: $this->module['status']
];
$response = new CControllerResponseData($data);
$response->setTitle(_('Modules'));
- $this->setResponse($response);
}
else {
$response = new CControllerResponseRedirect((new CUrl('zabbix.php'))
@@ -104,7 +99,8 @@ class CControllerModuleEdit extends CController {
->setArgument('page', CPagerHelper::loadPage('module.list', null))
);
CMessageHelper::setErrorTitle(_s('Cannot load module at: %1$s.', $this->module['relative_path']));
- $this->setResponse($response);
}
+
+ $this->setResponse($response);
}
}
diff --git a/ui/app/controllers/CControllerModuleList.php b/ui/app/controllers/CControllerModuleList.php
index 9c953b870a9..7b9ac9b8abe 100644
--- a/ui/app/controllers/CControllerModuleList.php
+++ b/ui/app/controllers/CControllerModuleList.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -24,11 +24,11 @@
*/
class CControllerModuleList extends CController {
- protected function init() {
+ protected function init(): void {
$this->disableSIDValidation();
}
- protected function checkInput() {
+ protected function checkInput(): bool {
$fields = [
'sort' => 'in name',
'sortorder' => 'in '.ZBX_SORT_DOWN.','.ZBX_SORT_UP,
@@ -48,11 +48,11 @@ class CControllerModuleList extends CController {
return $ret;
}
- protected function checkPermissions() {
+ protected function checkPermissions(): bool {
return $this->checkAccess(CRoleHelper::UI_ADMINISTRATION_GENERAL);
}
- protected function doAction() {
+ protected function doAction(): void {
// sort fields
$sort_field = $this->getInput('sort', CProfile::get('web.modules.sort', 'name'));
$sort_order = $this->getInput('sortorder', CProfile::get('web.modules.sortorder', ZBX_SORT_UP));
@@ -87,13 +87,14 @@ class CControllerModuleList extends CController {
'preservekeys' => true
]);
- $module_manager = new CModuleManager(APP::ModuleManager()->getModulesDir());
+ $module_manager = new CModuleManager(APP::getRootDir());
$modules = [];
foreach ($db_modules as $moduleid => $db_module) {
$manifest = $module_manager->addModule($db_module['relative_path']);
- if ($manifest && ($filter['name'] === '' || mb_stripos($manifest['name'], $filter['name']) !== false)) {
+ if ($manifest !== null
+ && ($filter['name'] === '' || mb_stripos($manifest['name'], $filter['name']) !== false)) {
$modules[$moduleid] = $db_module + $manifest;
}
}
diff --git a/ui/app/controllers/CControllerModuleScan.php b/ui/app/controllers/CControllerModuleScan.php
index 257852a8a6e..832ee6e0b81 100644
--- a/ui/app/controllers/CControllerModuleScan.php
+++ b/ui/app/controllers/CControllerModuleScan.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -24,15 +24,15 @@
*/
class CControllerModuleScan extends CController {
- protected function checkInput() {
+ protected function checkInput(): bool {
return true;
}
- protected function checkPermissions() {
+ protected function checkPermissions(): bool {
return $this->checkAccess(CRoleHelper::UI_ADMINISTRATION_GENERAL);
}
- protected function doAction() {
+ protected function doAction(): void {
get_and_clear_messages();
$db_modules_create = [];
@@ -53,36 +53,38 @@ class CControllerModuleScan extends CController {
$db_moduleids[$db_module['relative_path']] = $moduleid;
}
- $module_manager = new CModuleManager(APP::ModuleManager()->getModulesDir());
+ $module_manager = new CModuleManager(APP::getRootDir());
- foreach (new DirectoryIterator($module_manager->getModulesDir()) as $item) {
- if (!$item->isDir() || $item->isDot()) {
- continue;
- }
+ foreach (['widgets', 'modules'] as $modules_dir) {
+ foreach (new DirectoryIterator(APP::getRootDir().'/'.$modules_dir) as $item) {
+ if (!$item->isDir() || $item->isDot()) {
+ continue;
+ }
- $relative_path = $item->getFilename();
+ $relative_path = $modules_dir.'/'.$item->getFilename();
- $manifest = $module_manager->addModule($relative_path);
+ $manifest = $module_manager->addModule($relative_path);
- if (!$manifest) {
- continue;
- }
+ if (!$manifest) {
+ continue;
+ }
- $is_stored = array_key_exists($relative_path, $db_moduleids);
- $is_healthy = !$is_stored || $db_modules[$db_moduleids[$relative_path]]['id'] === $manifest['id'];
+ $is_stored = array_key_exists($relative_path, $db_moduleids);
+ $is_healthy = !$is_stored || $db_modules[$db_moduleids[$relative_path]]['id'] === $manifest['id'];
- if ($is_healthy) {
- $healthy_modules[] = $relative_path;
- }
+ if ($is_healthy) {
+ $healthy_modules[] = $relative_path;
+ }
- if (!$is_stored || !$is_healthy) {
- $db_modules_create[] = [
- 'id' => $manifest['id'],
- 'relative_path' => $relative_path,
- 'status' => MODULE_STATUS_DISABLED,
- 'config' => $manifest['config']
- ];
- $db_modules_create_names[] = $manifest['name'];
+ if (!$is_stored || !$is_healthy) {
+ $db_modules_create[] = [
+ 'id' => $manifest['id'],
+ 'relative_path' => $relative_path,
+ 'status' => MODULE_STATUS_DISABLED,
+ 'config' => $manifest['config']
+ ];
+ $db_modules_create_names[] = $manifest['name'];
+ }
}
}
diff --git a/ui/app/controllers/CControllerModuleUpdate.php b/ui/app/controllers/CControllerModuleUpdate.php
index 3fcd763c5c1..f4a8a592df8 100644
--- a/ui/app/controllers/CControllerModuleUpdate.php
+++ b/ui/app/controllers/CControllerModuleUpdate.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -26,12 +26,10 @@ class CControllerModuleUpdate extends CController {
/**
* List of modules to update.
- *
- * @var array
*/
- private $modules = [];
+ private array $modules = [];
- protected function checkInput() {
+ protected function checkInput(): bool {
$fields = [
'moduleids' => 'required|array_db module.moduleid',
@@ -49,7 +47,7 @@ class CControllerModuleUpdate extends CController {
return $ret;
}
- protected function checkPermissions() {
+ protected function checkPermissions(): bool {
if (!$this->checkAccess(CRoleHelper::UI_ADMINISTRATION_GENERAL)) {
return false;
}
@@ -65,7 +63,7 @@ class CControllerModuleUpdate extends CController {
return (count($this->modules) == count($moduleids));
}
- protected function doAction() {
+ protected function doAction(): void {
$set_status = ($this->getAction() === 'module.update')
? ($this->hasInput('status') ? MODULE_STATUS_ENABLED : MODULE_STATUS_DISABLED)
: ($this->getAction() === 'module.enable' ? MODULE_STATUS_ENABLED : MODULE_STATUS_DISABLED);
@@ -78,8 +76,8 @@ class CControllerModuleUpdate extends CController {
'preservekeys' => true
]);
- $module_manager = new CModuleManager(APP::ModuleManager()->getModulesDir());
- $module_manager_enabled = new CModuleManager(APP::ModuleManager()->getModulesDir());
+ $module_manager = new CModuleManager(APP::getRootDir());
+ $module_manager_enabled = new CModuleManager(APP::getRootDir());
foreach ($db_modules as $moduleid => $db_module) {
$new_status = array_key_exists($moduleid, $this->modules) ? $set_status : $db_module['status'];
diff --git a/ui/app/controllers/CControllerProblem.php b/ui/app/controllers/CControllerProblem.php
index 642fa9d21bb..e1fe131309e 100644
--- a/ui/app/controllers/CControllerProblem.php
+++ b/ui/app/controllers/CControllerProblem.php
@@ -44,7 +44,7 @@ abstract class CControllerProblem extends CController {
'show_suppressed' => 0,
'unacknowledged' => 0,
'compact_view' => 0,
- 'show_timeline' => 1,
+ 'show_timeline' => ZBX_TIMELINE_ON,
'details' => 0,
'highlight_row' => 0,
'show_opdata' => OPERATIONAL_DATA_SHOW_NONE,
diff --git a/ui/app/controllers/CControllerProblemView.php b/ui/app/controllers/CControllerProblemView.php
index 1c2fb8d5bcf..b5bbe1420b3 100644
--- a/ui/app/controllers/CControllerProblemView.php
+++ b/ui/app/controllers/CControllerProblemView.php
@@ -45,7 +45,7 @@ class CControllerProblemView extends CControllerProblem {
'show_suppressed' => 'in 0,1',
'unacknowledged' => 'in 0,1',
'compact_view' => 'in 0,1',
- 'show_timeline' => 'in 0,1',
+ 'show_timeline' => 'in '.ZBX_TIMELINE_OFF.','.ZBX_TIMELINE_ON,
'details' => 'in 0,1',
'highlight_row' => 'in 0,1',
'show_opdata' => 'in '.OPERATIONAL_DATA_SHOW_NONE.','.OPERATIONAL_DATA_SHOW_SEPARATELY.','.OPERATIONAL_DATA_SHOW_WITH_PROBLEM,
diff --git a/ui/app/controllers/CControllerProblemViewRefresh.php b/ui/app/controllers/CControllerProblemViewRefresh.php
index 8bf640164b4..7753a6a52e1 100644
--- a/ui/app/controllers/CControllerProblemViewRefresh.php
+++ b/ui/app/controllers/CControllerProblemViewRefresh.php
@@ -49,7 +49,7 @@ class CControllerProblemViewRefresh extends CControllerProblemView {
'show_suppressed' => 'in 0,1',
'unacknowledged' => 'in 0,1',
'compact_view' => 'in 0,1',
- 'show_timeline' => 'in 0,1',
+ 'show_timeline' => 'in '.ZBX_TIMELINE_OFF.','.ZBX_TIMELINE_ON,
'details' => 'in 0,1',
'highlight_row' => 'in 0,1',
'show_opdata' => 'in '.OPERATIONAL_DATA_SHOW_NONE.','.OPERATIONAL_DATA_SHOW_SEPARATELY.','.OPERATIONAL_DATA_SHOW_WITH_PROBLEM,
@@ -132,7 +132,7 @@ class CControllerProblemViewRefresh extends CControllerProblemView {
'show_suppressed' => $this->getInput('show_suppressed', ZBX_PROBLEM_SUPPRESSED_FALSE),
'unacknowledged' => $this->getInput('unacknowledged', 0),
'compact_view' => $this->getInput('compact_view', 0),
- 'show_timeline' => $this->getInput('show_timeline', 0),
+ 'show_timeline' => $this->getInput('show_timeline', ZBX_TIMELINE_OFF),
'details' => $this->getInput('details', 0),
'highlight_row' => $this->getInput('highlight_row', 0),
'show_opdata' => $this->getInput('show_opdata', OPERATIONAL_DATA_SHOW_NONE),
diff --git a/ui/app/controllers/CControllerProfileUpdate.php b/ui/app/controllers/CControllerProfileUpdate.php
index aedc4491e8d..c164d456109 100644
--- a/ui/app/controllers/CControllerProfileUpdate.php
+++ b/ui/app/controllers/CControllerProfileUpdate.php
@@ -41,6 +41,7 @@ class CControllerProfileUpdate extends CController {
case 'web.correlation.filter.active':
case 'web.dashboard.filter.active':
case 'web.dashboard.hostid':
+ case 'web.dashboard.last_widget_type':
case 'web.discovery.filter.active':
case 'web.discoveryconf.filter.active':
case 'web.hostgroups.filter.active':
@@ -63,9 +64,9 @@ class CControllerProfileUpdate extends CController {
case 'web.proxies.filter.active':
case 'web.scheduledreport.filter.active':
case 'web.scripts.filter.active':
- case 'web.search.hats.'.WIDGET_SEARCH_HOSTS.'.state':
- case 'web.search.hats.'.WIDGET_SEARCH_TEMPLATES.'.state':
- case 'web.search.hats.'.WIDGET_SEARCH_HOSTGROUP.'.state':
+ case 'web.search.hats.'.SECTION_SEARCH_HOSTS.'.state':
+ case 'web.search.hats.'.SECTION_SEARCH_TEMPLATES.'.state':
+ case 'web.search.hats.'.SECTION_SEARCH_HOSTGROUP.'.state':
case 'web.service.filter.active':
case 'web.service_actions.filter.active':
case 'web.sidebar.mode':
@@ -81,8 +82,8 @@ class CControllerProfileUpdate extends CController {
case 'web.templates.triggers.filter.active':
case 'web.token.filter.active':
case 'web.toptriggers.filter.active':
- case 'web.tr_events.hats.'.WIDGET_HAT_EVENTACTIONS.'.state':
- case 'web.tr_events.hats.'.WIDGET_HAT_EVENTLIST.'.state':
+ case 'web.tr_events.hats.'.SECTION_HAT_EVENTACTIONS.'.state':
+ case 'web.tr_events.hats.'.SECTION_HAT_EVENTLIST.'.state':
case 'web.user.filter.active':
case 'web.user.token.filter.active':
case 'web.usergroup.filter.active':
@@ -104,6 +105,7 @@ class CControllerProfileUpdate extends CController {
if ($ret) {
switch ($this->getInput('idx')) {
+ case 'web.dashboard.last_widget_type':
case 'web.dashboard.widget.geomap.default_view':
case 'web.dashboard.widget.geomap.severity_filter':
$ret = $this->hasInput('value_str');
@@ -132,6 +134,15 @@ class CControllerProfileUpdate extends CController {
DBstart();
switch ($idx) {
// PROFILE_TYPE_STR
+ case 'web.dashboard.last_widget_type':
+ $value_str = $this->getInput('value_str');
+ if ($value_str === '') {
+ CProfile::delete($idx);
+ }
+ else {
+ CProfile::update($idx, $value_str, PROFILE_TYPE_STR);
+ }
+ break;
case 'web.dashboard.widget.geomap.default_view':
case 'web.dashboard.widget.geomap.severity_filter':
$value_str = $this->getInput('value_str');
diff --git a/ui/app/controllers/CControllerTemplateDashboardEdit.php b/ui/app/controllers/CControllerTemplateDashboardEdit.php
index b500e89857e..bc32eb03d6e 100644
--- a/ui/app/controllers/CControllerTemplateDashboardEdit.php
+++ b/ui/app/controllers/CControllerTemplateDashboardEdit.php
@@ -21,13 +21,13 @@
class CControllerTemplateDashboardEdit extends CController {
- private $dashboard;
+ private array $dashboard;
- protected function init() {
+ protected function init(): void {
$this->disableSIDValidation();
}
- protected function checkInput() {
+ protected function checkInput(): bool {
$fields = [
'templateid' => 'db dashboard.templateid',
'dashboardid' => 'db dashboard.dashboardid'
@@ -44,7 +44,7 @@ class CControllerTemplateDashboardEdit extends CController {
return $ret;
}
- protected function checkPermissions() {
+ protected function checkPermissions(): bool {
if ($this->getUserType() < USER_TYPE_ZABBIX_ADMIN) {
return false;
}
@@ -61,12 +61,11 @@ class CControllerTemplateDashboardEdit extends CController {
return (bool) $this->dashboard;
}
- else {
- return isWritableHostTemplates((array) $this->getInput('templateid'));
- }
+
+ return isWritableHostTemplates((array) $this->getInput('templateid'));
}
- protected function doAction() {
+ protected function doAction(): void {
if ($this->hasInput('dashboardid')) {
$dashboard = $this->dashboard;
$dashboard['pages'] = CDashboardHelper::preparePagesForGrid($dashboard['pages'], $dashboard['templateid'],
@@ -93,7 +92,8 @@ class CControllerTemplateDashboardEdit extends CController {
$data = [
'dashboard' => $dashboard,
- 'widget_defaults' => CWidgetConfig::getDefaults(CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD),
+ 'widget_defaults' => APP::ModuleManager()->getWidgetsDefaults(true),
+ 'widget_last_type' => CDashboardHelper::getWidgetLastType(true),
'time_period' => getTimeSelectorPeriod([]),
'page' => CPagerHelper::loadPage('template.dashboard.list', null)
];
diff --git a/ui/app/controllers/CControllerTemplateDashboardUpdate.php b/ui/app/controllers/CControllerTemplateDashboardUpdate.php
index dba47d81081..7070aff5335 100644
--- a/ui/app/controllers/CControllerTemplateDashboardUpdate.php
+++ b/ui/app/controllers/CControllerTemplateDashboardUpdate.php
@@ -21,7 +21,9 @@
class CControllerTemplateDashboardUpdate extends CController {
- private $dashboard_pages;
+ private ?array $db_dashboard = null;
+
+ private ?array $dashboard_pages = null;
protected function init() {
$this->setPostContentType(self::POST_CONTENT_TYPE_JSON);
@@ -71,83 +73,121 @@ class CControllerTemplateDashboardUpdate extends CController {
}
if ($this->hasInput('dashboardid')) {
- return (bool) API::TemplateDashboard()->get([
- 'output' => [],
- 'dashboardids' => [$this->getInput('dashboardid')],
- 'templateids' => [$this->getInput('templateid')],
+ $db_dashboards = API::TemplateDashboard()->get([
+ 'output' => ['dashboardid'],
+ 'selectPages' => ['widgets'],
+ 'dashboardids' => $this->getInput('dashboardid'),
+ 'templateids' => $this->getInput('templateid'),
'editable' => true
]);
+
+ if (!$db_dashboards) {
+ return false;
+ }
+
+ $this->db_dashboard = $db_dashboards[0];
+
+ return true;
}
else {
- return isWritableHostTemplates((array) $this->getInput('templateid'));
+ return isWritableHostTemplates([$this->getInput('templateid')]);
}
}
protected function doAction() {
- $save_dashboard = [
- 'name' => $this->getInput('name'),
- 'display_period' => $this->getInput('display_period'),
- 'auto_start' => $this->getInput('auto_start'),
- 'pages' => []
- ];
+ $output = [];
- if ($this->hasInput('dashboardid')) {
- $save_dashboard['dashboardid'] = $this->getInput('dashboardid');
- }
- else {
- $save_dashboard['templateid'] = $this->getInput('templateid');
- }
+ try {
+ $db_widgets = [];
+
+ if ($this->db_dashboard !== null) {
+ foreach ($this->db_dashboard['pages'] as $db_dashboard_page) {
+ foreach ($db_dashboard_page['widgets'] as $db_widget) {
+ $db_widgets[$db_widget['widgetid']] = $db_widget;
+ }
+ }
+ }
- foreach ($this->dashboard_pages as $dashboard_page) {
- $save_dashboard_page = [
- 'name' => $dashboard_page['name'],
- 'display_period' => $dashboard_page['display_period'],
- 'widgets' => []
+ $save_dashboard = [
+ 'name' => $this->getInput('name'),
+ 'display_period' => $this->getInput('display_period'),
+ 'auto_start' => $this->getInput('auto_start'),
+ 'pages' => []
];
- if (array_key_exists('dashboard_pageid', $dashboard_page)) {
- $save_dashboard_page['dashboard_pageid'] = $dashboard_page['dashboard_pageid'];
+ if ($this->db_dashboard !== null) {
+ $save_dashboard['dashboardid'] = $this->db_dashboard['dashboardid'];
+ }
+ else {
+ $save_dashboard['templateid'] = $this->getInput('templateid');
}
- foreach ($dashboard_page['widgets'] as $widget) {
- $save_widget = [
- 'x' => $widget['pos']['x'],
- 'y' => $widget['pos']['y'],
- 'width' => $widget['pos']['width'],
- 'height' => $widget['pos']['height'],
- 'type' => $widget['type'],
- 'name' => $widget['name'],
- 'view_mode' => $widget['view_mode'],
- 'fields' => $widget['form']->fieldsToApi()
+ foreach ($this->dashboard_pages as $dashboard_page) {
+ $save_dashboard_page = [
+ 'name' => $dashboard_page['name'],
+ 'display_period' => $dashboard_page['display_period'],
+ 'widgets' => []
];
- if (array_key_exists('widgetid', $widget)) {
- $save_widget['widgetid'] = $widget['widgetid'];
+ if (array_key_exists('dashboard_pageid', $dashboard_page)) {
+ $save_dashboard_page['dashboard_pageid'] = $dashboard_page['dashboard_pageid'];
}
- $save_dashboard_page['widgets'][] = $save_widget;
- }
-
- $save_dashboard['pages'][] = $save_dashboard_page;
- }
-
- if ($this->hasInput('dashboardid')) {
- $result = API::TemplateDashboard()->update($save_dashboard);
+ foreach ($dashboard_page['widgets'] as $widget) {
+ $save_widget = [
+ 'x' => $widget['pos']['x'],
+ 'y' => $widget['pos']['y'],
+ 'width' => $widget['pos']['width'],
+ 'height' => $widget['pos']['height']
+ ];
+
+ if ($widget['type'] !== ZBX_WIDGET_INACCESSIBLE) {
+ $save_widget += [
+ 'type' => $widget['type'],
+ 'name' => $widget['name'],
+ 'view_mode' => $widget['view_mode'],
+ 'fields' => $widget['form']->fieldsToApi()
+ ];
+ }
+ else {
+ if (!array_key_exists('widgetid', $widget)
+ || !array_key_exists($widget['widgetid'], $db_widgets)) {
+ error(_('No permissions to referred object or it does not exist!'));
+
+ throw new InvalidArgumentException();
+ }
+
+ $db_widget = $db_widgets[$widget['widgetid']];
+
+ $save_widget += [
+ 'type' => $db_widget['type'],
+ 'name' => $db_widget['name'],
+ 'view_mode' => $db_widget['view_mode'],
+ 'fields' => $db_widget['fields']
+ ];
+ }
+
+ if (array_key_exists('widgetid', $widget)) {
+ $save_widget['widgetid'] = $widget['widgetid'];
+ }
+
+ $save_dashboard_page['widgets'][] = $save_widget;
+ }
- $success_title = _('Dashboard updated');
- $error_title = _('Failed to update dashboard');
- }
- else {
- $result = API::TemplateDashboard()->create($save_dashboard);
+ $save_dashboard['pages'][] = $save_dashboard_page;
+ }
- $success_title = _('Dashboard created');
- $error_title = _('Failed to create dashboard');
- }
+ $result = $this->db_dashboard !== null
+ ? API::TemplateDashboard()->update($save_dashboard)
+ : API::TemplateDashboard()->create($save_dashboard);
- $output = [];
+ if (!$result) {
+ throw new InvalidArgumentException();
+ }
- if ($result) {
- $output['success']['title'] = $success_title;
+ $output['success']['title'] = $this->db_dashboard !== null
+ ? _('Dashboard updated')
+ : _('Dashboard created');
if ($messages = get_and_clear_messages()) {
$output['success']['messages'] = array_column($messages, 'message');
@@ -155,9 +195,11 @@ class CControllerTemplateDashboardUpdate extends CController {
$output['dashboardid'] = $result['dashboardids'][0];
}
- else {
+ catch (InvalidArgumentException $e) {
$output['error'] = [
- 'title' => $error_title,
+ 'title' => $this->db_dashboard !== null && !$this->hasInput('clone')
+ ? _('Failed to update dashboard')
+ : _('Failed to create dashboard'),
'messages' => array_column(get_and_clear_messages(), 'message')
];
}
diff --git a/ui/app/controllers/CControllerUserEdit.php b/ui/app/controllers/CControllerUserEdit.php
index 8d1c892cb38..d4938c53669 100644
--- a/ui/app/controllers/CControllerUserEdit.php
+++ b/ui/app/controllers/CControllerUserEdit.php
@@ -113,6 +113,7 @@ class CControllerUserEdit extends CControllerUserEditGeneral {
'new_media' => [],
'roleid' => '',
'role' => [],
+ 'modules_rules' => [],
'user_type' => '',
'sid' => $this->getUserSID(),
'form_refresh' => 0,
@@ -175,7 +176,7 @@ class CControllerUserEdit extends CControllerUserEditGeneral {
$roles = API::Role()->get([
'output' => ['name', 'type'],
'selectRules' => ['services.read.mode', 'services.read.list', 'services.read.tag',
- 'services.write.mode', 'services.write.list', 'services.write.tag'
+ 'services.write.mode', 'services.write.list', 'services.write.tag', 'modules'
],
'roleids' => $data['roleid']
]);
@@ -217,6 +218,10 @@ class CControllerUserEdit extends CControllerUserEditGeneral {
'serviceids' => array_column($role['rules']['services.write.list'], 'serviceid')
]);
$data['service_write_tag'] = $role['rules']['services.write.tag'];
+
+ foreach ($role['rules']['modules'] as $rule) {
+ $data['modules_rules'][$rule['moduleid']] = $rule['status'];
+ }
}
}
@@ -241,12 +246,34 @@ class CControllerUserEdit extends CControllerUserEditGeneral {
$data['templategroups_rights'] = collapseGroupRights(getTemplateGroupsRights($user_groups));
}
- $data['modules'] = API::Module()->get([
- 'output' => ['id'],
- 'filter' => ['status' => MODULE_STATUS_ENABLED],
- 'preservekeys' => true
+ $data['modules'] = [];
+
+ $db_modules = API::Module()->get([
+ 'output' => ['moduleid', 'relative_path', 'status']
]);
+ if ($db_modules) {
+ $module_manager = new CModuleManager(APP::getRootDir());
+
+ foreach ($db_modules as $db_module) {
+ $manifest = $module_manager->addModule($db_module['relative_path']);
+
+ if ($manifest !== null) {
+ $data['modules'][$db_module['moduleid']] = $manifest['name'];
+ }
+ }
+ }
+
+ natcasesort($data['modules']);
+
+ $disabled_modules = array_filter($db_modules,
+ static function(array $db_module): bool {
+ return $db_module['status'] == MODULE_STATUS_DISABLED;
+ }
+ );
+
+ $data['disabled_moduleids'] = array_column($disabled_modules, 'moduleid', 'moduleid');
+
$data['mediatypes'] = API::MediaType()->get([
'output' => ['status'],
'preservekeys' => true
diff --git a/ui/app/controllers/CControllerUserroleEdit.php b/ui/app/controllers/CControllerUserroleEdit.php
index f18e80d3c09..bc4f96d72f3 100644
--- a/ui/app/controllers/CControllerUserroleEdit.php
+++ b/ui/app/controllers/CControllerUserroleEdit.php
@@ -180,7 +180,19 @@ class CControllerUserroleEdit extends CControllerUserroleEditGeneral {
];
}
- $data['labels'] = $this->getLabels();
+ $db_modules = API::Module()->get([
+ 'output' => ['moduleid', 'relative_path', 'status']
+ ]);
+
+ $disabled_modules = array_filter($db_modules,
+ static function(array $db_module): bool {
+ return $db_module['status'] == MODULE_STATUS_DISABLED;
+ }
+ );
+
+ $data['disabled_moduleids'] = array_column($disabled_modules, 'moduleid', 'moduleid');
+
+ $data['labels'] = $this->getLabels($db_modules);
$data['rules']['service_read_list'] = API::Service()->get([
'output' => ['serviceid', 'name'],
@@ -291,10 +303,7 @@ class CControllerUserroleEdit extends CControllerUserroleEditGeneral {
return $data;
}
- /**
- * @throws APIException
- */
- private function getLabels(): array {
+ private function getLabels(array $db_modules): array {
$labels = [
'sections' => CRoleHelper::getUiSectionsLabels(USER_TYPE_SUPER_ADMIN),
'actions' => CRoleHelper::getActionsLabels(USER_TYPE_SUPER_ADMIN)
@@ -304,23 +313,21 @@ class CControllerUserroleEdit extends CControllerUserroleEditGeneral {
$labels['rules'][$section] = CRoleHelper::getUiSectionRulesLabels($section, USER_TYPE_SUPER_ADMIN);
}
- $db_modules = API::Module()->get([
- 'output' => ['moduleid', 'relative_path'],
- 'filter' => [
- 'status' => MODULE_STATUS_ENABLED
- ]
- ]);
+ $labels['modules'] = [];
if ($db_modules) {
- $module_manager = new CModuleManager(APP::ModuleManager()->getModulesDir());
- foreach ($db_modules as $module) {
- $manifest = $module_manager->addModule($module['relative_path']);
- $labels['modules'][$module['moduleid']] = $manifest['name'];
+ $module_manager = new CModuleManager(APP::getRootDir());
+
+ foreach ($db_modules as $db_module) {
+ $manifest = $module_manager->addModule($db_module['relative_path']);
+
+ if ($manifest !== null) {
+ $labels['modules'][$db_module['moduleid']] = $manifest['name'];
+ }
}
}
- else {
- $labels['modules'] = [];
- }
+
+ natcasesort($labels['modules']);
return $labels;
}
diff --git a/ui/app/controllers/CControllerUserroleEditGeneral.php b/ui/app/controllers/CControllerUserroleEditGeneral.php
index 5abbc45d05d..e5a5a9479f1 100644
--- a/ui/app/controllers/CControllerUserroleEditGeneral.php
+++ b/ui/app/controllers/CControllerUserroleEditGeneral.php
@@ -97,10 +97,8 @@ abstract class CControllerUserroleEditGeneral extends CController {
*/
private function getModuleSectionRules(): array {
$db_modules = API::Module()->get([
- 'output' => ['moduleid'],
- 'filter' => [
- 'status' => MODULE_STATUS_ENABLED
- ]
+ 'output' => [],
+ 'preservekeys' => true
]);
$modules = $this->getInput('modules', []);
@@ -113,7 +111,7 @@ abstract class CControllerUserroleEditGeneral extends CController {
'status' => $modules[$moduleid]
];
},
- array_column($db_modules, 'moduleid')
+ array_keys($db_modules)
),
'modules.default_access' => $this->getInput('modules_default_access')
];
diff --git a/ui/app/controllers/CControllerWidget.php b/ui/app/controllers/CControllerWidget.php
deleted file mode 100644
index 2c9404ed442..00000000000
--- a/ui/app/controllers/CControllerWidget.php
+++ /dev/null
@@ -1,148 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Class containing methods for operations with widgets.
- */
-abstract class CControllerWidget extends CController {
-
- /**
- * @var int $type Widget type WIDGET_*.
- */
- private $type;
-
- /**
- * @var array $validation_rules Validation rules for input parameters.
- */
- private $validation_rules = [];
-
- /**
- * @var object $form CWidgetForm object.
- */
- private $form;
-
- /**
- * Initialization function.
- */
- protected function init() {
- $this->setPostContentType(self::POST_CONTENT_TYPE_JSON);
- }
-
- /**
- * Check user permissions.
- *
- * @return bool
- */
- protected function checkPermissions() {
- return ($this->getUserType() >= USER_TYPE_ZABBIX_USER);
- }
-
- /**
- * Set widget type.
- *
- * @param int $type Widget type WIDGET_*.
- *
- * @return object
- */
- protected function setType($type) {
- $this->type = $type;
-
- return $this;
- }
-
- protected function getContext(): string {
- return $this->hasInput('templateid')
- ? CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD
- : CWidgetConfig::CONTEXT_DASHBOARD;
- }
-
- /**
- * Set validation rules for input parameters.
- *
- * @param array $validation_rules Validation rules for input parameters.
- *
- * @return object
- */
- protected function setValidationRules(array $validation_rules) {
- $this->validation_rules = $validation_rules;
-
- return $this;
- }
-
- /**
- * Returns default widget name.
- *
- * @return string
- */
- protected function getDefaultName() {
- return CWidgetConfig::getKnownWidgetTypes($this->getContext())[$this->type];
- }
-
- /**
- * Validate input parameters.
- *
- * @return bool
- */
- protected function checkInput() {
- $validation_rules = $this->validation_rules;
-
- if (CWidgetConfig::isWidgetTypeSupportedInContext($this->type, CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD)) {
- $validation_rules['templateid'] = 'db dashboard.templateid';
- }
-
- $ret = $this->validateInput($validation_rules);
-
- if ($ret) {
- $this->form = CWidgetConfig::getForm($this->type, $this->getInput('fields', '{}'),
- $this->hasInput('templateid') ? $this->getInput('templateid') : null
- );
-
- if ($errors = $this->form->validate()) {
- foreach ($errors as $error) {
- error($error);
- }
-
- $ret = false;
- }
- }
-
- if (!$ret) {
- $this->setResponse(
- (new CControllerResponseData(['main_block' => json_encode([
- 'error' => [
- 'messages' => array_column(get_and_clear_messages(), 'message')
- ]
- ])]))->disableView()
- );
- }
-
- return $ret;
- }
-
- /**
- * Returns form object.
- *
- * @return object
- */
- protected function getForm() {
- return $this->form;
- }
-}
diff --git a/ui/app/controllers/CControllerWidgetIterator.php b/ui/app/controllers/CControllerWidgetIterator.php
index 5ac5b1169cb..4dde652dd62 100644
--- a/ui/app/controllers/CControllerWidgetIterator.php
+++ b/ui/app/controllers/CControllerWidgetIterator.php
@@ -22,50 +22,28 @@
/**
* Class containing methods for operations with widget iterators.
*/
-abstract class CControllerWidgetIterator extends CControllerWidget {
+abstract class CControllerWidgetIterator extends CControllerDashboardWidgetView {
- /**
- * @var array $iterator_validation_rules Validation rules for input parameters of the iterator.
- */
- private static $iterator_validation_rules = [
- 'page' => 'required|ge 1'
- ];
+ protected function init(): void {
+ parent::init();
- public function __construct() {
- parent::__construct();
-
- $this->setValidationRules(self::$iterator_validation_rules);
- }
-
- /**
- * Set validation rules for input parameters.
- *
- * @param array $validation_rules Validation rules for input parameters.
- *
- * @return object
- */
- protected function setValidationRules(array $validation_rules) {
- return parent::setValidationRules(array_merge(self::$iterator_validation_rules, $validation_rules));
+ $this->addValidationRules([
+ 'page' => 'required|ge 1'
+ ]);
}
/**
* Get realistic page number for given number of child widgets.
- *
- * @param int $num_widgets Number of child widgets.
- *
- * @return int Page number.
*/
- protected function getIteratorPage($num_widgets) {
+ protected function getIteratorPage(int $num_widgets): int {
return max(1, min((int) $this->getInput('page'), $this->getIteratorPageCount($num_widgets)));
}
/**
* Get number of child widgets to show on a single page.
- *
- * @return int Number of child widgets.
*/
- protected function getIteratorPageSize() {
- $fields_data = $this->getForm()->getFieldsData();
+ protected function getIteratorPageSize(): int {
+ $fields_data = $this->getForm()->getFieldsValues();
return min($fields_data['rows'] * $fields_data['columns'],
floor(DASHBOARD_MAX_COLUMNS * DASHBOARD_WIDGET_MAX_ROWS / DASHBOARD_WIDGET_MIN_ROWS)
@@ -74,12 +52,8 @@ abstract class CControllerWidgetIterator extends CControllerWidget {
/**
* Get number of pages for given number of child widgets.
- *
- * @param int $num_widgets Number of child widgets.
- *
- * @return int Number of pages.
*/
- protected function getIteratorPageCount($num_widgets) {
+ protected function getIteratorPageCount(int $num_widgets): int {
return (floor(max(0, $num_widgets - 1) / $this->getIteratorPageSize()) + 1);
}
}
diff --git a/ui/app/controllers/CControllerWidgetProblemsBySvView.php b/ui/app/controllers/CControllerWidgetProblemsBySvView.php
deleted file mode 100644
index 0478bd98a75..00000000000
--- a/ui/app/controllers/CControllerWidgetProblemsBySvView.php
+++ /dev/null
@@ -1,74 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-require_once dirname(__FILE__).'/../../include/blocks.inc.php';
-
-class CControllerWidgetProblemsBySvView extends CControllerWidget {
-
- public function __construct() {
- parent::__construct();
-
- $this->setType(WIDGET_PROBLEMS_BY_SV);
- $this->setValidationRules([
- 'name' => 'string',
- 'fields' => 'json',
- 'initial_load' => 'in 0,1'
- ]);
- }
-
- protected function doAction() {
- $fields = $this->getForm()->getFieldsData();
-
- $filter = [
- 'groupids' => getSubGroups($fields['groupids']),
- 'exclude_groupids' => getSubGroups($fields['exclude_groupids']),
- 'hostids' => $fields['hostids'],
- 'problem' => $fields['problem'],
- 'severities' => $fields['severities'],
- 'show_type' => $fields['show_type'],
- 'layout' => $fields['layout'],
- 'show_suppressed' => $fields['show_suppressed'],
- 'hide_empty_groups' => $fields['hide_empty_groups'],
- 'show_opdata' => $fields['show_opdata'],
- 'ext_ack' => $fields['ext_ack'],
- 'show_timeline' => $fields['show_timeline'],
- 'evaltype' => $fields['evaltype'],
- 'tags' => $fields['tags']
- ];
-
- $data = getSystemStatusData($filter);
-
- if ($filter['show_type'] == WIDGET_PROBLEMS_BY_SV_SHOW_TOTALS) {
- $data['groups'] = getSystemStatusTotals($data);
- }
-
- $this->setResponse(new CControllerResponseData([
- 'name' => $this->getInput('name', $this->getDefaultName()),
- 'initial_load' => (bool) $this->getInput('initial_load', 0),
- 'data' => $data,
- 'filter' => $filter,
- 'user' => [
- 'debug_mode' => $this->getDebugMode()
- ],
- 'allowed' => $data['allowed']
- ]));
- }
-}
diff --git a/ui/app/controllers/CControllerWidgetSvgGraphView.php b/ui/app/controllers/CControllerWidgetSvgGraphView.php
deleted file mode 100644
index 50913d4110a..00000000000
--- a/ui/app/controllers/CControllerWidgetSvgGraphView.php
+++ /dev/null
@@ -1,183 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-require_once dirname(__FILE__).'/../../include/blocks.inc.php';
-
-class CControllerWidgetSvgGraphView extends CControllerWidget {
-
- const GRAPH_WIDTH_MIN = 1;
- const GRAPH_WIDTH_MAX = 65535;
- const GRAPH_HEIGHT_MIN = 1;
- const GRAPH_HEIGHT_MAX = 65535;
-
- public function __construct() {
- parent::__construct();
-
- $this->setType(WIDGET_SVG_GRAPH);
- $this->setValidationRules([
- 'name' => 'string',
- 'edit_mode' => 'in 0,1',
- 'content_width' => 'int32|ge '.self::GRAPH_WIDTH_MIN.'|le '.self::GRAPH_WIDTH_MAX,
- 'content_height' => 'int32|ge '.self::GRAPH_HEIGHT_MIN.'|le '.self::GRAPH_HEIGHT_MAX,
- 'preview' => 'in 1',
- 'from' => 'string',
- 'to' => 'string',
- 'fields' => 'json'
- ]);
- }
-
- protected function doAction(): void {
- $fields = $this->getForm()->getFieldsData();
- $edit_mode = $this->getInput('edit_mode', 0);
- $width = (int) $this->getInput('content_width', self::GRAPH_WIDTH_MIN);
- $height = (int) $this->getInput('content_height', self::GRAPH_HEIGHT_MIN);
- $preview = (bool) $this->getInput('preview', 0); // Configuration preview.
-
- $dashboard_time = !CWidgetFormSvgGraph::hasOverrideTime($fields);
-
- if ($dashboard_time && !$preview) {
- $from = $this->getInput('from');
- $to = $this->getInput('to');
- }
- else {
- $from = $fields['time_from'];
- $to = $fields['time_to'];
- }
-
- $range_time_parser = new CRangeTimeParser();
-
- $range_time_parser->parse($from);
- $time_from = $range_time_parser->getDateTime(true)->getTimestamp();
-
- $range_time_parser->parse($to);
- $time_to = $range_time_parser->getDateTime(false)->getTimestamp();
-
- $parser = new CNumberParser(['with_size_suffix' => true, 'with_time_suffix' => true]);
-
- $percentile_left_value = $parser->parse($fields['percentile_left_value']) == CParser::PARSE_SUCCESS
- ? $parser->calcValue()
- : null;
-
- $percentile_right_value = $parser->parse($fields['percentile_right_value']) == CParser::PARSE_SUCCESS
- ? $parser->calcValue()
- : null;
-
- $lefty_min = $parser->parse($fields['lefty_min']) == CParser::PARSE_SUCCESS ? $parser->calcValue() : null;
- $lefty_max = $parser->parse($fields['lefty_max']) == CParser::PARSE_SUCCESS ? $parser->calcValue() : null;
- $righty_min = $parser->parse($fields['righty_min']) == CParser::PARSE_SUCCESS ? $parser->calcValue() : null;
- $righty_max = $parser->parse($fields['righty_max']) == CParser::PARSE_SUCCESS ? $parser->calcValue() : null;
-
- $graph_data = [
- 'data_sets' => array_values($fields['ds']),
- 'data_source' => $fields['source'],
- 'dashboard_time' => $dashboard_time,
- 'displaying' => [
- 'show_simple_triggers' => $fields['simple_triggers'] == SVG_GRAPH_SIMPLE_TRIGGERS_ON,
- 'show_working_time' => $fields['working_time'] == SVG_GRAPH_WORKING_TIME_ON,
- 'show_percentile_left' => $fields['percentile_left'] == SVG_GRAPH_PERCENTILE_LEFT_ON,
- 'percentile_left_value' => $percentile_left_value,
- 'show_percentile_right' => $fields['percentile_right'] == SVG_GRAPH_PERCENTILE_RIGHT_ON,
- 'percentile_right_value' => $percentile_right_value
- ],
- 'time_period' => [
- 'time_from' => $time_from,
- 'time_to' => $time_to
- ],
- 'axes' => [
- 'show_left_y_axis' => $fields['lefty'] == SVG_GRAPH_AXIS_SHOW,
- 'left_y_min' => $lefty_min,
- 'left_y_max' => $lefty_max,
- 'left_y_units' => $fields['lefty_units'] == SVG_GRAPH_AXIS_UNITS_STATIC
- ? $fields['lefty_static_units']
- : null,
- 'show_right_y_axis' => $fields['righty'] == SVG_GRAPH_AXIS_SHOW,
- 'right_y_min' => $righty_min,
- 'right_y_max' => $righty_max,
- 'right_y_units' => $fields['righty_units'] == SVG_GRAPH_AXIS_UNITS_STATIC
- ? $fields['righty_static_units']
- : null,
- 'show_x_axis' => $fields['axisx'] == SVG_GRAPH_AXIS_SHOW
- ],
- 'legend' => [
- 'show_legend' => $fields['legend'] == SVG_GRAPH_LEGEND_ON,
- 'legend_columns' => $fields['legend_columns'],
- 'legend_lines' => $fields['legend_lines'],
- 'legend_statistic' => $fields['legend_statistic']
- ],
- 'problems' => [
- 'show_problems' => $fields['show_problems'] == SVG_GRAPH_PROBLEMS_SHOW,
- 'graph_item_problems' => $fields['graph_item_problems'] == SVG_GRAPH_SELECTED_ITEM_PROBLEMS,
- 'problemhosts' => $fields['problemhosts'],
- 'severities' => $fields['severities'],
- 'problem_name' => $fields['problem_name'],
- 'evaltype' => $fields['evaltype'],
- 'tags' => $fields['tags']
- ],
- 'overrides' => array_values($fields['or'])
- ];
-
- $svg_options = CSvgGraphHelper::get($graph_data, $width, $height);
- if ($svg_options['errors']) {
- error($svg_options['errors']);
- }
-
- if (!$preview) {
- $svg_options['data'] = zbx_array_merge($svg_options['data'], [
- 'sbox' => $graph_data['dashboard_time'] && !$edit_mode,
- 'show_problems' => $graph_data['problems']['show_problems'],
- 'show_simple_triggers' => $graph_data['displaying']['show_simple_triggers'],
- 'time_from' => $graph_data['time_period']['time_from'],
- 'hint_max_rows' => ZBX_WIDGET_ROWS
- ]);
- }
-
- $this->setResponse(new CControllerResponseData([
- 'name' => $this->getInput('name', $this->getDefaultName()),
- 'svg' => $svg_options['svg'].$svg_options['legend'],
- 'svg_options' => $svg_options,
- 'preview' => $preview,
- 'info' => self::makeWidgetInfo($fields),
- 'user' => [
- 'debug_mode' => $this->getDebugMode()
- ]
- ]));
- }
-
- /**
- * Make widget specific info to show in widget's header.
- *
- * @param array $fields
- *
- * @return array
- */
- private static function makeWidgetInfo(array $fields) {
- $info = [];
-
- if (CWidgetFormSvgGraph::hasOverrideTime($fields)) {
- $info[] = [
- 'icon' => 'btn-info-clock',
- 'hint' => relativeDateToText($fields['time_from'], $fields['time_to'])
- ];
- }
-
- return $info;
- }
-}
diff --git a/ui/app/controllers/CControllerWidgetTrigOverView.php b/ui/app/controllers/CControllerWidgetTrigOverView.php
deleted file mode 100644
index bd2a6590536..00000000000
--- a/ui/app/controllers/CControllerWidgetTrigOverView.php
+++ /dev/null
@@ -1,73 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-class CControllerWidgetTrigOverView extends CControllerWidget {
-
- public function __construct() {
- parent::__construct();
-
- $this->setType(WIDGET_TRIG_OVER);
- $this->setValidationRules([
- 'name' => 'string',
- 'fields' => 'json',
- 'initial_load' => 'in 0,1'
- ]);
- }
-
- protected function doAction() {
- $fields = $this->getForm()->getFieldsData();
-
- $data = [
- 'name' => $this->getInput('name', $this->getDefaultName()),
- 'initial_load' => (bool) $this->getInput('initial_load', 0),
- 'style' => $fields['style'],
- 'user' => [
- 'debug_mode' => $this->getDebugMode()
- ]
- ];
-
- $trigger_options = [
- 'skipDependent' => ($fields['show'] == TRIGGERS_OPTION_ALL) ? null : true,
- 'only_true' => ($fields['show'] == TRIGGERS_OPTION_RECENT_PROBLEM) ? true : null,
- 'filter' => [
- 'value' => ($fields['show'] == TRIGGERS_OPTION_IN_PROBLEM) ? TRIGGER_VALUE_TRUE : null
- ]
- ];
-
- $problem_options = [
- 'show_suppressed' => $fields['show_suppressed'],
- 'show_recent' => ($fields['show'] == TRIGGERS_OPTION_RECENT_PROBLEM) ? true : null,
- 'tags' => (array_key_exists('tags', $fields) && $fields['tags']) ? $fields['tags'] : null,
- 'evaltype' => array_key_exists('evaltype', $fields) ? $fields['evaltype'] : TAG_EVAL_TYPE_AND_OR
- ];
-
- $host_options = [
- 'hostids' => $fields['hostids'] ? $fields['hostids'] : null
- ];
-
- [$data['db_hosts'], $data['db_triggers'], $data['dependencies'], $data['triggers_by_name'],
- $data['hosts_by_name'], $data['exceeded_limit']
- ] = getTriggersOverviewData(getSubGroups($fields['groupids']), $host_options, $trigger_options, $problem_options
- );
-
- $this->setResponse(new CControllerResponseData($data));
- }
-}
diff --git a/ui/app/partials/configuration.hostgroup.edit.html.php b/ui/app/partials/configuration.hostgroup.edit.html.php
index a2f87f6e3b7..c74febd3b3d 100644
--- a/ui/app/partials/configuration.hostgroup.edit.html.php
+++ b/ui/app/partials/configuration.hostgroup.edit.html.php
@@ -27,7 +27,7 @@
$form = (new CForm())
->setId('hostgroupForm')
->setName('hostgroupForm')
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE)
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID)
->addVar('groupid', $data['groupid'])
->addItem((new CInput('submit', null))->addStyle('display: none;'));
diff --git a/ui/app/partials/configuration.templategroup.edit.html.php b/ui/app/partials/configuration.templategroup.edit.html.php
index fb51ba8ae3a..105b525f78d 100644
--- a/ui/app/partials/configuration.templategroup.edit.html.php
+++ b/ui/app/partials/configuration.templategroup.edit.html.php
@@ -27,7 +27,7 @@
$form = (new CForm())
->setId('templategroupForm')
->setName('templategroupForm')
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE)
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID)
->addVar('groupid', $data['groupid'])
->addItem((new CInput('submit'))->addStyle('display: none;'));
diff --git a/ui/app/partials/layout.htmlpage.header.php b/ui/app/partials/layout.htmlpage.header.php
index 5a343ccc248..fd124e61b49 100644
--- a/ui/app/partials/layout.htmlpage.header.php
+++ b/ui/app/partials/layout.htmlpage.header.php
@@ -26,7 +26,6 @@
global $DB, $ZBX_SERVER_NAME;
-$theme = ZBX_DEFAULT_THEME;
$scripts = $data['javascript']['files'];
$page_title = $data['page']['title'];
@@ -34,12 +33,11 @@ if (isset($ZBX_SERVER_NAME) && $ZBX_SERVER_NAME !== '') {
$page_title = $ZBX_SERVER_NAME.NAME_DELIMITER.$page_title;
}
-$pageHeader = new CPageHeader($page_title, CWebUser::getLang());
+$page_header = new CHtmlPageHeader($page_title, CWebUser::getLang());
if (!empty($DB['DB'])) {
- $theme = getUserTheme($data['user']);
-
- $pageHeader
+ $page_header
+ ->setTheme(getUserTheme($data['user']))
->addStyle(getTriggerSeverityCss())
->addStyle(getTriggerStatusCss());
@@ -50,16 +48,28 @@ if (!empty($DB['DB'])) {
}
// Show GUI messages in pages with menus and in kiosk mode.
-$show_gui_messaging = (!defined('ZBX_PAGE_NO_MENU') || $data['web_layout_mode'] == ZBX_LAYOUT_KIOSKMODE)
- ? intval(!CWebUser::isGuest())
+$show_gui_messaging = !defined('ZBX_PAGE_NO_MENU') || $data['web_layout_mode'] == ZBX_LAYOUT_KIOSKMODE
+ ? (int)!CWebUser::isGuest()
: null;
-$pageHeader
- ->addCssFile('assets/styles/'.CHtml::encode($theme).'.css')
- ->addJsBeforeScripts(
- 'var PHP_TZ_OFFSET = '.date('Z').','.
- 'PHP_ZBX_FULL_DATE_TIME = "'.ZBX_FULL_DATE_TIME.'";'
- )
+$modules_assets = APP::ModuleManager()->getAssets();
+
+$page_header->addCssFile('assets/styles/'.$page_header->getTheme().'.css');
+
+foreach ($modules_assets as $module_id => $assets) {
+ $module = APP::ModuleManager()->getModule($module_id);
+ $relative_path = $module->getRelativePath().'/assets/css';
+
+ foreach ($assets['css'] as $css_file) {
+ $page_header->addCssFile((new CUrl($relative_path.'/'.$css_file))->getUrl());
+ }
+}
+
+$page_header
+ ->addJavaScript('
+ const PHP_TZ_OFFSET = '.date('Z').';
+ const PHP_ZBX_FULL_DATE_TIME = "'.ZBX_FULL_DATE_TIME.'";
+ ')
->addJsFile((new CUrl('js/browsers.js'))->getUrl())
->addJsFile((new CUrl('jsLoader.php'))
->setArgument('lang', $data['user']['lang'])
@@ -69,18 +79,35 @@ $pageHeader
);
foreach ($data['stylesheet']['files'] as $css_file) {
- $pageHeader->addCssFile($css_file);
+ $page_header->addCssFile($css_file);
}
if ($scripts) {
- $pageHeader->addJsFile((new CUrl('jsLoader.php'))
- ->setArgument('ver', ZABBIX_VERSION)
- ->setArgument('lang', $data['user']['lang'])
- ->setArgument('files', $scripts)
- ->getUrl()
+ $page_header->addJsFile(
+ (new CUrl('jsLoader.php'))
+ ->setArgument('ver', ZABBIX_VERSION)
+ ->setArgument('lang', $data['user']['lang'])
+ ->setArgument('files', $scripts)
+ ->getUrl()
);
+
+ $page_header->addJavaScript('if (locale === undefined) { var locale = {}; }');
+
+ foreach ($modules_assets as $module_id => $assets) {
+ $module = APP::ModuleManager()->getModule($module_id);
+ $relative_path = $module->getRelativePath().'/assets/js';
+ $translation_strings = $module->getTranslationStrings();
+
+ foreach ($assets['js'] as $js_file) {
+ $page_header->addJsFile((new CUrl($relative_path.'/'.$js_file))->getUrl());
+
+ if (array_key_exists($js_file, $translation_strings)) {
+ $page_header->addJsTranslationStrings($translation_strings[$js_file]);
+ }
+ }
+ }
}
-$pageHeader->display();
+$page_header->show();
echo '<body>';
diff --git a/ui/app/partials/monitoring.host.filter.php b/ui/app/partials/monitoring.host.filter.php
index 9395bcb62da..abf6c43f0bc 100644
--- a/ui/app/partials/monitoring.host.filter.php
+++ b/ui/app/partials/monitoring.host.filter.php
@@ -178,12 +178,12 @@ if (array_key_exists('render_html', $data)) {
return;
}
-(new CScriptTemplate('filter-monitoring-hosts'))
+(new CTemplateTag('filter-monitoring-hosts'))
->setAttribute('data-template', 'monitoring.host.filter')
->addItem($template)
->show();
-(new CScriptTemplate('filter-tag-row-tmpl'))
+(new CTemplateTag('filter-tag-row-tmpl'))
->addItem(
(new CRow([
(new CTextBox('tags[#{rowNum}][tag]', '#{tag}'))
diff --git a/ui/app/partials/monitoring.latest.filter.php b/ui/app/partials/monitoring.latest.filter.php
index e411a032f8b..370dcd4ec2c 100644
--- a/ui/app/partials/monitoring.latest.filter.php
+++ b/ui/app/partials/monitoring.latest.filter.php
@@ -220,12 +220,12 @@ if (array_key_exists('render_html', $data)) {
return;
}
-(new CScriptTemplate('filter-monitoring-latest'))
+(new CTemplateTag('filter-monitoring-latest'))
->setAttribute('data-template', 'monitoring.latest.filter')
->addItem($template)
->show();
-(new CScriptTemplate('filter-tag-row-tmpl'))
+(new CTemplateTag('filter-tag-row-tmpl'))
->addItem(
(new CRow([
(new CTextBox('tags[#{rowNum}][tag]', '#{tag}'))
diff --git a/ui/app/partials/monitoring.problem.filter.php b/ui/app/partials/monitoring.problem.filter.php
index fd5c3bdece8..1c9d69605ec 100644
--- a/ui/app/partials/monitoring.problem.filter.php
+++ b/ui/app/partials/monitoring.problem.filter.php
@@ -268,7 +268,7 @@ $right_column = (new CFormList())
(new CDiv([
(new CLabel(_('Show timeline'), 'show_timeline_#{uniqid}'))->addClass(ZBX_STYLE_SECOND_COLUMN_LABEL),
(new CCheckBox('show_timeline'))
- ->setChecked($data['show_timeline'] == 1)
+ ->setChecked($data['show_timeline'] == ZBX_TIMELINE_ON)
->setEnabled($data['compact_view'] == 0)
->setUncheckedValue(0)
->setId('show_timeline_#{uniqid}')
@@ -323,12 +323,12 @@ if (array_key_exists('render_html', $data)) {
return;
}
-(new CScriptTemplate('filter-monitoring-problem'))
+(new CTemplateTag('filter-monitoring-problem'))
->setAttribute('data-template', 'monitoring.problem.filter')
->addItem($template)
->show();
-(new CScriptTemplate('filter-inventory-row'))
+(new CTemplateTag('filter-inventory-row'))
->addItem(
(new CRow([
(new CSelect('inventory[#{rowNum}][field]'))
@@ -346,7 +346,7 @@ if (array_key_exists('render_html', $data)) {
)
->show();
-(new CScriptTemplate('filter-tag-row-tmpl'))
+(new CTemplateTag('filter-tag-row-tmpl'))
->addItem(
(new CRow([
(new CTextBox('tags[#{rowNum}][tag]', '#{tag}'))
diff --git a/ui/app/views/administration.audit.settings.edit.php b/ui/app/views/administration.audit.settings.edit.php
index 687a178cf9a..a3839c367a2 100644
--- a/ui/app/views/administration.audit.settings.edit.php
+++ b/ui/app/views/administration.audit.settings.edit.php
@@ -25,7 +25,7 @@
$this->includeJsFile('administration.audit.settings.edit.js.php');
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Audit log'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::ADMINISTRATION_AUDITLOG_EDIT));
@@ -36,7 +36,7 @@ $form = (new CForm())
->setArgument('action', 'audit.settings.update')
->getUrl()
)
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE);
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID);
$audit_settings_tab = (new CFormGrid())
->addItem([
@@ -66,6 +66,6 @@ $form->addItem(
))
);
-$widget
+$html_page
->addItem($form)
->show();
diff --git a/ui/app/views/administration.authentication.edit.php b/ui/app/views/administration.authentication.edit.php
index fa4966f40cc..b8261f12705 100644
--- a/ui/app/views/administration.authentication.edit.php
+++ b/ui/app/views/administration.authentication.edit.php
@@ -335,14 +335,14 @@ $saml_tab = (new CFormGrid())
)
]);
-(new CWidget())
+(new CHtmlPage())
->setTitle(_('Authentication'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::USERS_AUTHENTICATION_EDIT))
->addItem((new CForm())
->addVar('action', $data['action_submit'])
->addVar('ldap_removed_userdirectoryids', $data['ldap_removed_userdirectoryids'])
->setId('authentication-form')
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE)
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID)
->disablePasswordAutofill()
->addItem((new CTabView())
->setSelected($data['form_refresh'] ? null : 0)
@@ -358,7 +358,7 @@ $saml_tab = (new CFormGrid())
->show();
(new CScriptTag(
- 'view.init('. json_encode([
+ 'view.init('.json_encode([
'ldap_servers' => $data['ldap_servers'],
'ldap_default_row_index' => $data['ldap_default_row_index'],
'db_authentication_type' => $data['db_authentication_type']
diff --git a/ui/app/views/administration.autoreg.edit.php b/ui/app/views/administration.autoreg.edit.php
index 8d4d1563356..dcf0fa249e2 100644
--- a/ui/app/views/administration.autoreg.edit.php
+++ b/ui/app/views/administration.autoreg.edit.php
@@ -25,7 +25,7 @@
$this->includeJsFile('administration.autoreg.edit.js.php');
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Autoregistration'))
->setTitleSubmenu(getAdministrationGeneralSubmenu())
->setDocUrl(CDocHelper::getUrl(CDocHelper::ADMINISTRATION_AUTOREG_EDIT));
@@ -37,7 +37,7 @@ $autoreg_form = (new CForm())
->setArgument('action', 'autoreg.edit')
->getUrl()
)
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE)
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID)
->addVar('tls_accept', $data['tls_accept']);
$autoreg_tab = (new CFormList())
@@ -92,6 +92,6 @@ $autoreg_view = (new CTabView())
$autoreg_form->addItem($autoreg_view);
-$widget
+$html_page
->addItem($autoreg_form)
->show();
diff --git a/ui/app/views/administration.geomaps.edit.php b/ui/app/views/administration.geomaps.edit.php
index 458040020e4..aefa0dde59e 100644
--- a/ui/app/views/administration.geomaps.edit.php
+++ b/ui/app/views/administration.geomaps.edit.php
@@ -114,7 +114,7 @@ $form = (new CForm())
->setArgument('action', 'geomaps.update')
->getUrl()
)
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE)
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID)
->addItem(
(new CTabView())
->addTab('geomaps_tab', _('Geographical maps'), $form_grid)
@@ -123,7 +123,7 @@ $form = (new CForm())
))
);
-(new CWidget())
+(new CHtmlPage())
->setTitle(_('Geographical maps'))
->setTitleSubmenu(getAdministrationGeneralSubmenu())
->setDocUrl(CDocHelper::getUrl(CDocHelper::ADMINISTRATION_GEOMAPS_EDIT))
@@ -131,7 +131,7 @@ $form = (new CForm())
->show();
(new CScriptTag(
- 'view.init('. json_encode([
+ 'view.init('.json_encode([
'tile_providers' => $data['tile_providers']
]).');'
))
diff --git a/ui/app/views/administration.gui.edit.php b/ui/app/views/administration.gui.edit.php
index e0f9dc6e495..8a53e919ee0 100644
--- a/ui/app/views/administration.gui.edit.php
+++ b/ui/app/views/administration.gui.edit.php
@@ -25,7 +25,7 @@
$this->includeJsFile('administration.gui.edit.js.php');
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('GUI'))
->setTitleSubmenu(getAdministrationGeneralSubmenu())
->setDocUrl(CDocHelper::getUrl(CDocHelper::ADMINISTRATION_GUI_EDIT));
@@ -149,13 +149,13 @@ $gui_view = (new CTabView())
));
$form = (new CForm())
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE)
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID)
->setAction((new CUrl('zabbix.php'))
->setArgument('action', 'gui.update')
->getUrl()
)
->addItem($gui_view);
-$widget
+$html_page
->addItem($form)
->show();
diff --git a/ui/app/views/administration.housekeeping.edit.php b/ui/app/views/administration.housekeeping.edit.php
index 12dcf91afab..0fc45fc2462 100644
--- a/ui/app/views/administration.housekeeping.edit.php
+++ b/ui/app/views/administration.housekeeping.edit.php
@@ -25,7 +25,7 @@
$this->includeJsFile('administration.housekeeping.edit.js.php');
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Housekeeping'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::ADMINISTRATION_HOUSEKEEPING_EDIT));
@@ -35,7 +35,7 @@ $form = (new CForm())
->setArgument('action', 'housekeeping.update')
->getUrl()
)
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE);
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID);
$house_keeper_tab = (new CFormList())
->addRow((new CTag('h4', true, _('Events and alerts')))->addClass('input-section-header'))
@@ -267,6 +267,6 @@ $form->addItem(
))
);
-$widget
+$html_page
->addItem($form)
->show();
diff --git a/ui/app/views/administration.iconmap.edit.php b/ui/app/views/administration.iconmap.edit.php
index a629a7fbe42..9ca537f5552 100644
--- a/ui/app/views/administration.iconmap.edit.php
+++ b/ui/app/views/administration.iconmap.edit.php
@@ -25,7 +25,7 @@
$this->includeJsFile('administration.iconmap.edit.js.php');
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Icon mapping'))
->setTitleSubmenu(getAdministrationGeneralSubmenu())
->setDocUrl(CDocHelper::getUrl(CDocHelper::ADMINISTRATION_ICONMAP_EDIT));
@@ -46,7 +46,7 @@ $form = (new CForm())
->setArgument('action', ($data['iconmapid'] != 0) ? 'iconmap.update' : 'iconmap.create')
->getUrl()
)
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE)
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID)
->addVar('form', 1);
if ($data['iconmapid'] != 0) {
@@ -162,4 +162,4 @@ else {
$form->addItem($tab);
-$widget->addItem($form)->show();
+$html_page->addItem($form)->show();
diff --git a/ui/app/views/administration.iconmap.list.php b/ui/app/views/administration.iconmap.list.php
index f3aca4fac78..69d978214c7 100644
--- a/ui/app/views/administration.iconmap.list.php
+++ b/ui/app/views/administration.iconmap.list.php
@@ -23,7 +23,7 @@
* @var CView $this
*/
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Icon mapping'))
->setTitleSubmenu(getAdministrationGeneralSubmenu())
->setDocUrl(CDocHelper::getUrl(CDocHelper::ADMINISTRATION_ICONMAP_LIST))
@@ -52,4 +52,4 @@ foreach ($data['iconmaps'] as $icon_map) {
), $row]);
}
-$widget->addItem($table)->show();
+$html_page->addItem($table)->show();
diff --git a/ui/app/views/administration.image.edit.php b/ui/app/views/administration.image.edit.php
index 25da1e73c7d..c3c2ba5bd7e 100644
--- a/ui/app/views/administration.image.edit.php
+++ b/ui/app/views/administration.image.edit.php
@@ -25,7 +25,7 @@
$this->includeJsFile('administration.image.edit.js.php');
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Images'))
->setTitleSubmenu(getAdministrationGeneralSubmenu())
->setDocUrl(CDocHelper::getUrl(CDocHelper::ADMINISTRATION_IMAGE_EDIT));
@@ -34,7 +34,7 @@ $form = (new CForm('post', (new CUrl('zabbix.php'))
->setArgument('action', ($data['imageid'] == 0) ? 'image.create' : 'image.update')
->getUrl(), 'multipart/form-data')
)
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE)
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID)
->addVar('imagetype', $data['imagetype']);
if ($data['imageid'] != 0) {
@@ -103,4 +103,4 @@ else {
));
}
-$widget->addItem($form->addItem($tab_view))->show();
+$html_page->addItem($form->addItem($tab_view))->show();
diff --git a/ui/app/views/administration.image.list.php b/ui/app/views/administration.image.list.php
index 742da721d01..de68260aa3c 100644
--- a/ui/app/views/administration.image.list.php
+++ b/ui/app/views/administration.image.list.php
@@ -26,7 +26,7 @@
$this->includeJsFile('administration.image.list.js.php');
$page_url = (new CUrl('zabbix.php'))->setArgument('action', 'image.list');
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Images'))
->setTitleSubmenu(getAdministrationGeneralSubmenu())
->setDocUrl(CDocHelper::getUrl(CDocHelper::ADMINISTRATION_IMAGE_LIST))
@@ -72,7 +72,7 @@ $widget = (new CWidget())
);
if (!$data['images']) {
- $widget->addItem(new CTableInfo());
+ $html_page->addItem(new CTableInfo());
}
else {
$image_table = (new CDiv())
@@ -113,14 +113,14 @@ else {
$image_table->addItem($image_row);
}
- $widget->addItem(
+ $html_page->addItem(
(new CForm())->addItem(
(new CTabView())->addTab('image', null, $image_table)
)
);
}
-$widget->show();
+$html_page->show();
(new CScriptTag('
view.init('.json_encode([
diff --git a/ui/app/views/administration.macros.edit.php b/ui/app/views/administration.macros.edit.php
index 5b32bcf530c..00136237c58 100644
--- a/ui/app/views/administration.macros.edit.php
+++ b/ui/app/views/administration.macros.edit.php
@@ -25,7 +25,7 @@
$this->includeJsFile('administration.macros.edit.js.php');
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Macros'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::ADMINISTRATION_MACROS_EDIT));
@@ -103,9 +103,9 @@ $form = (new CForm())
->setName('macrosForm')
->disablePasswordAutofill()
->setAction((new CUrl('zabbix.php'))->setArgument('action', 'macros.update')->getUrl())
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE)
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID)
->addItem($tab_view);
-$widget
+$html_page
->addItem($form)
->show();
diff --git a/ui/app/views/administration.mediatype.edit.php b/ui/app/views/administration.mediatype.edit.php
index 560ae0df974..53abc87b13b 100644
--- a/ui/app/views/administration.mediatype.edit.php
+++ b/ui/app/views/administration.mediatype.edit.php
@@ -28,7 +28,7 @@ $this->addJsFile('multilineinput.js');
$this->includeJsFile('administration.mediatype.edit.js.php');
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Media types'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::ALERTS_MEDIATYPE_EDIT));
@@ -45,7 +45,7 @@ $mediaTypeForm = (new CForm())
->addVar('mediatypeid', $data['mediatypeid'])
->addItem((new CVar('status', MEDIA_TYPE_STATUS_DISABLED))->removeId())
->disablePasswordAutofill()
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE);
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID);
// Create form list.
$mediatype_formlist = (new CFormList())
@@ -201,7 +201,7 @@ $row_template = (new CTag('script', true))
]))->addClass('form_row')
);
-$widget->addItem($row_template);
+$html_page->addItem($row_template);
$parameters_table->addRow([(new CButton('parameter_add', _('Add')))
->addClass(ZBX_STYLE_BTN_LINK)
@@ -389,4 +389,4 @@ else {
$mediaTypeForm->addItem($tabs);
// append form to widget
-$widget->addItem($mediaTypeForm)->show();
+$html_page->addItem($mediaTypeForm)->show();
diff --git a/ui/app/views/administration.mediatype.list.php b/ui/app/views/administration.mediatype.list.php
index 31deae8e74a..18c59826cd5 100644
--- a/ui/app/views/administration.mediatype.list.php
+++ b/ui/app/views/administration.mediatype.list.php
@@ -27,7 +27,7 @@ if ($data['uncheck']) {
uncheckTableRows('mediatype');
}
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Media types'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::ALERTS_MEDIATYPE_LIST))
->setControls((new CTag('nav', true,
@@ -201,4 +201,6 @@ $mediaTypeForm->addItem([
]);
// append form to widget
-$widget->addItem($mediaTypeForm)->show();
+$html_page
+ ->addItem($mediaTypeForm)
+ ->show();
diff --git a/ui/app/views/administration.miscconfig.edit.php b/ui/app/views/administration.miscconfig.edit.php
index d3acc4377fe..5bc136c70f2 100644
--- a/ui/app/views/administration.miscconfig.edit.php
+++ b/ui/app/views/administration.miscconfig.edit.php
@@ -26,7 +26,7 @@
$this->includeJsFile('administration.miscconfig.edit.js.php');
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Other configuration parameters'))
->setTitleSubmenu(getAdministrationGeneralSubmenu())
->setDocUrl(CDocHelper::getUrl(CDocHelper::ADMINISTRATION_MISCCONFIG_EDIT));
@@ -189,7 +189,7 @@ $form = (new CForm())
->setArgument('action', 'miscconfig.update')
->getUrl()
)
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE)
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID)
->addItem(
(new CTabView())
->addTab('other', _('Other parameters'), $from_list)
@@ -199,7 +199,7 @@ $form = (new CForm())
))
);
-$widget
+$html_page
->addItem($form)
->show();
diff --git a/ui/app/views/administration.module.edit.php b/ui/app/views/administration.module.edit.php
index 8b6f3394e79..3a094bf0b3f 100644
--- a/ui/app/views/administration.module.edit.php
+++ b/ui/app/views/administration.module.edit.php
@@ -19,7 +19,12 @@
**/
-$widget = (new CWidget())
+/**
+ * @var CView $this
+ * @var array $data
+ */
+
+$html_page = (new CHtmlPage())
->setTitle(_('Modules'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::ADMINISTRATION_MODULE_EDIT))
->setTitleSubmenu(getAdministrationGeneralSubmenu());
@@ -32,7 +37,7 @@ $form = (new CForm())
->setArgument('moduleids[]', $data['moduleid'])
->getUrl()
)
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE);
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID);
// create module tab
$module_tab = (new CFormList())
@@ -70,6 +75,6 @@ $tabs->setFooter(makeFormFooter(
$form->addItem($tabs);
// append form to widget
-$widget->addItem($form);
+$html_page->addItem($form);
-$widget->show();
+$html_page->show();
diff --git a/ui/app/views/administration.module.list.php b/ui/app/views/administration.module.list.php
index 8dec962295e..66d1671fb72 100644
--- a/ui/app/views/administration.module.list.php
+++ b/ui/app/views/administration.module.list.php
@@ -19,11 +19,16 @@
**/
+/**
+ * @var CView $this
+ * @var array $data
+ */
+
if ($data['uncheck']) {
uncheckTableRows('modules');
}
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Modules'))
->setTitleSubmenu(getAdministrationGeneralSubmenu())
->setDocUrl(CDocHelper::getUrl(CDocHelper::ADMINISTRATION_MODULE_LIST))
@@ -127,6 +132,6 @@ $form->addItem([
]);
// append form to widget
-$widget->addItem($form);
+$html_page->addItem($form);
-$widget->show();
+$html_page->show();
diff --git a/ui/app/views/administration.queue.details.php b/ui/app/views/administration.queue.details.php
index ca7401d07b3..efd243912a5 100644
--- a/ui/app/views/administration.queue.details.php
+++ b/ui/app/views/administration.queue.details.php
@@ -23,7 +23,7 @@
* @var CView $this
*/
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Queue details'))
->setTitleSubmenu([
'main_section' => [
@@ -75,7 +75,7 @@ if (CWebUser::getRefresh()) {
->show();
}
-$widget
+$html_page
->addItem($table)
->addItem((new CDiv())
->addClass(ZBX_STYLE_TABLE_PAGING)
diff --git a/ui/app/views/administration.queue.overview.php b/ui/app/views/administration.queue.overview.php
index 70f6479f84c..10f70776376 100644
--- a/ui/app/views/administration.queue.overview.php
+++ b/ui/app/views/administration.queue.overview.php
@@ -23,7 +23,7 @@
* @var CView $this
*/
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Queue overview'))
->setTitleSubmenu([
'main_section' => [
@@ -87,6 +87,6 @@ if (CWebUser::getRefresh()) {
->show();
}
-$widget
+$html_page
->addItem($table)
->show();
diff --git a/ui/app/views/administration.queue.overview.proxy.php b/ui/app/views/administration.queue.overview.proxy.php
index e0bc7d038cd..0d8d286aa89 100644
--- a/ui/app/views/administration.queue.overview.proxy.php
+++ b/ui/app/views/administration.queue.overview.proxy.php
@@ -23,7 +23,7 @@
* @var CView $this
*/
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Queue overview by proxy'))
->setTitleSubmenu([
'main_section' => [
@@ -87,7 +87,7 @@ if (CWebUser::getRefresh()) {
->show();
}
-$widget
+$html_page
->addItem($table)
->addItem((new CDiv())
->addClass(ZBX_STYLE_TABLE_PAGING)
diff --git a/ui/app/views/administration.regex.edit.php b/ui/app/views/administration.regex.edit.php
index 74bb5612be7..b00a9b5b942 100644
--- a/ui/app/views/administration.regex.edit.php
+++ b/ui/app/views/administration.regex.edit.php
@@ -25,7 +25,7 @@
$this->includeJsFile('administration.regex.edit.js.php');
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Regular expressions'))
->setTitleSubmenu(getAdministrationGeneralSubmenu())
->setDocUrl(CDocHelper::getUrl(CDocHelper::ADMINISTRATION_REGEX_EDIT));
@@ -39,7 +39,7 @@ if ($data['regexid'] != 0) {
$form = (new CForm())
->setId('regex')
->setAction($action->getUrl())
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE);
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID);
$table = (new CTable())
->setId('tbl_expr')
@@ -172,6 +172,6 @@ else {
$form->addItem($reg_exp_view);
-$widget
+$html_page
->addItem($form)
->show();
diff --git a/ui/app/views/administration.regex.list.php b/ui/app/views/administration.regex.list.php
index a018be5308b..0084f79667c 100644
--- a/ui/app/views/administration.regex.list.php
+++ b/ui/app/views/administration.regex.list.php
@@ -27,7 +27,7 @@ if ($data['uncheck']) {
uncheckTableRows('regex');
}
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Regular expressions'))
->setTitleSubmenu(getAdministrationGeneralSubmenu())
->setDocUrl(CDocHelper::getUrl(CDocHelper::ADMINISTRATION_REGEX_LIST))
@@ -82,4 +82,4 @@ $form->addItem([
], 'regex')
]);
-$widget->addItem($form)->show();
+$html_page->addItem($form)->show();
diff --git a/ui/app/views/administration.script.edit.php b/ui/app/views/administration.script.edit.php
index c1e2eb0d08d..4811b6cfc53 100644
--- a/ui/app/views/administration.script.edit.php
+++ b/ui/app/views/administration.script.edit.php
@@ -27,7 +27,7 @@ $this->addJsFile('multilineinput.js');
$this->includeJsFile('administration.script.edit.js.php');
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Scripts'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::ALERTS_SCRIPT_EDIT));
@@ -50,12 +50,12 @@ $row_template = (new CTag('script', true))
]))->addClass('form_row')
);
-$widget->addItem($row_template);
+$html_page->addItem($row_template);
$form = (new CForm())
->setId('script-form')
->setName('scripts')
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE)
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID)
->addVar('form', 1)
->addVar('scriptid', $data['scriptid']);
@@ -314,4 +314,4 @@ else {
$form->addItem($scriptView);
-$widget->addItem($form)->show();
+$html_page->addItem($form)->show();
diff --git a/ui/app/views/administration.script.list.php b/ui/app/views/administration.script.list.php
index 37efe676307..a720894830d 100644
--- a/ui/app/views/administration.script.list.php
+++ b/ui/app/views/administration.script.list.php
@@ -27,7 +27,7 @@ if ($data['uncheck']) {
uncheckTableRows('script');
}
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Scripts'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::ALERTS_SCRIPT_LIST))
->setControls((new CTag('nav', true,
@@ -223,6 +223,6 @@ $scriptsForm->addItem([
]);
// append form to widget
-$widget
+$html_page
->addItem($scriptsForm)
->show();
diff --git a/ui/app/views/administration.token.list.php b/ui/app/views/administration.token.list.php
index afeef1cd41f..364997a3475 100644
--- a/ui/app/views/administration.token.list.php
+++ b/ui/app/views/administration.token.list.php
@@ -100,7 +100,7 @@ $filter = (new CFilter())
)
]);
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('API tokens'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::USERS_TOKEN_LIST))
->setControls(
@@ -210,7 +210,7 @@ $token_form->addItem([
], 'token')
]);
-$widget
+$html_page
->addItem($token_form)
->show();
diff --git a/ui/app/views/administration.trigdisplay.edit.php b/ui/app/views/administration.trigdisplay.edit.php
index 6d41f7d30ed..992e6246f9f 100644
--- a/ui/app/views/administration.trigdisplay.edit.php
+++ b/ui/app/views/administration.trigdisplay.edit.php
@@ -27,7 +27,7 @@ $this->addJsFile('colorpicker.js');
$this->includeJsFile('administration.trigdisplay.edit.js.php');
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Trigger displaying options'))
->setTitleSubmenu(getAdministrationGeneralSubmenu())
->setDocUrl(CDocHelper::getUrl(CDocHelper::ADMINISTRATION_TRIGDISPLAY_EDIT));
@@ -156,7 +156,7 @@ $form_list = (new CFormList())
->addInfo(_('Custom severity names affect all locales and require manual translation!'));
$form = (new CForm())
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE)
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID)
->setAction((new CUrl('zabbix.php'))
->setArgument('action', 'trigdisplay.update')
->getUrl()
@@ -170,4 +170,4 @@ $form = (new CForm())
))
);
-$widget->addItem($form)->show();
+$html_page->addItem($form)->show();
diff --git a/ui/app/views/administration.user.edit.php b/ui/app/views/administration.user.edit.php
index e6e15ede54b..eae9f85cf28 100644
--- a/ui/app/views/administration.user.edit.php
+++ b/ui/app/views/administration.user.edit.php
@@ -29,7 +29,7 @@ $this->includeJsFile(($data['action'] === 'user.edit')
: 'administration.userprofile.edit.js.php'
);
-$widget = new CWidget();
+$html_page = new CHtmlPage();
if ($data['action'] === 'user.edit') {
$widget_name = _('Users');
@@ -40,13 +40,14 @@ else {
$widget_name .= ($data['name'] !== '' || $data['surname'] !== '')
? $data['name'].' '.$data['surname']
: $data['username'];
- $widget->setTitleSubmenu(getUserSettingsSubmenu());
+ $html_page->setTitleSubmenu(getUserSettingsSubmenu());
$doc_url = CDocHelper::USERS_USERPROFILE_EDIT;
}
-$widget
+$html_page
->setTitle($widget_name)
->setDocUrl(CDocHelper::getUrl($doc_url));
+
$tabs = new CTabView();
if ($data['form_refresh'] == 0) {
@@ -57,7 +58,7 @@ if ($data['form_refresh'] == 0) {
$user_form = (new CForm())
->setId('user-form')
->setName('user_form')
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE)
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID)
->addVar('action', $data['action'])
->addVar('userid', $data['userid']);
@@ -615,11 +616,12 @@ if ($data['action'] === 'user.edit') {
else {
$elements = [];
- foreach ($data['modules'] as $moduleid => $module) {
- $elements[] = (new CSpan($module['id']))->addClass(
- CRoleHelper::checkAccess('modules.module.'.$moduleid, $data['roleid'])
- ? ZBX_STYLE_STATUS_GREEN
- : ZBX_STYLE_STATUS_GREY
+ foreach ($data['modules'] as $moduleid => $module_name) {
+ $elements[] = (new CSpan($module_name))->addClass(
+ array_key_exists($moduleid, $data['disabled_moduleids'])
+ || $data['modules_rules'][$moduleid] == MODULE_STATUS_DISABLED
+ ? ZBX_STYLE_STATUS_GREY
+ : ZBX_STYLE_STATUS_GREEN
);
}
@@ -824,6 +826,6 @@ else {
// Append tab to form.
$user_form->addItem($tabs);
-$widget
+$html_page
->addItem($user_form)
->show();
diff --git a/ui/app/views/administration.user.list.php b/ui/app/views/administration.user.list.php
index 0d534a0fb4d..5d66a4eed16 100644
--- a/ui/app/views/administration.user.list.php
+++ b/ui/app/views/administration.user.list.php
@@ -29,7 +29,7 @@ if ($data['uncheck']) {
uncheckTableRows('user');
}
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Users'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::USERS_USER_LIST))
->setControls((new CList([
@@ -253,6 +253,6 @@ $form->addItem([
]);
// Append form to widget.
-$widget
+$html_page
->addItem($form)
->show();
diff --git a/ui/app/views/administration.user.token.list.php b/ui/app/views/administration.user.token.list.php
index 481e31648bd..0541adf051a 100644
--- a/ui/app/views/administration.user.token.list.php
+++ b/ui/app/views/administration.user.token.list.php
@@ -66,7 +66,7 @@ $filter = (new CFilter())
)
]);
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('API tokens'))
->setTitleSubmenu(getUserSettingsSubmenu())
->setDocUrl(CDocHelper::getUrl(CDocHelper::USERS_USER_TOKEN_LIST))
@@ -163,7 +163,7 @@ $token_form->addItem([
], 'user.token')
]);
-$widget
+$html_page
->addItem($token_form)
->show();
diff --git a/ui/app/views/administration.usergroup.edit.php b/ui/app/views/administration.usergroup.edit.php
index 5074c3811f8..058e2077f77 100644
--- a/ui/app/views/administration.usergroup.edit.php
+++ b/ui/app/views/administration.usergroup.edit.php
@@ -26,14 +26,14 @@
$this->includeJsFile('administration.usergroup.edit.js.php');
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('User groups'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::USERS_USERGROUP_EDIT));
$form = (new CForm())
->setId('user-group-form')
->setName('user_group_form')
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE);
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID);
if ($data['usrgrpid'] != 0) {
$form->addVar('usrgrpid', $data['usrgrpid']);
@@ -347,5 +347,7 @@ else {
// append tab to form
$form->addItem($tabs);
-$widget->addItem($form);
-$widget->show();
+
+$html_page
+ ->addItem($form)
+ ->show();
diff --git a/ui/app/views/administration.usergroup.list.php b/ui/app/views/administration.usergroup.list.php
index e3fd2111fd6..352e983ec32 100644
--- a/ui/app/views/administration.usergroup.list.php
+++ b/ui/app/views/administration.usergroup.list.php
@@ -27,7 +27,7 @@ if ($data['uncheck']) {
uncheckTableRows('usergroup');
}
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('User groups'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::USERS_USERGROUP_LIST))
->setControls(
@@ -240,5 +240,6 @@ $form->addItem([
], 'usergroup')
]);
-$widget->addItem($form);
-$widget->show();
+$html_page
+ ->addItem($form)
+ ->show();
diff --git a/ui/app/views/administration.userrole.edit.php b/ui/app/views/administration.userrole.edit.php
index 56566463447..ad5eaf50179 100644
--- a/ui/app/views/administration.userrole.edit.php
+++ b/ui/app/views/administration.userrole.edit.php
@@ -26,14 +26,14 @@
$this->includeJsFile('administration.userrole.edit.js.php');
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('User roles'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::USERS_USERROLE_EDIT));
$form = (new CForm())
->setId('userrole-form')
->setName('user_role_form')
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE);
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID);
if ($data['roleid'] !== null) {
$form->addVar('roleid', $data['roleid']);
@@ -244,28 +244,31 @@ $form_grid->addItem(
);
$modules = [];
-foreach ($data['labels']['modules'] as $moduleid => $label) {
- $modules[] = new CDiv(
+
+foreach ($data['labels']['modules'] as $moduleid => $module_name) {
+ $module = new CDiv(
(new CCheckBox('modules['.$moduleid.']', 1))
->setChecked(
- array_key_exists($moduleid, $data['rules']['modules']) ? $data['rules']['modules'][$moduleid] : true
+ array_key_exists($moduleid, $data['rules']['modules'])
+ ? $data['rules']['modules'][$moduleid]
+ : !array_key_exists($moduleid, $data['disabled_moduleids'])
)
->setReadonly($data['readonly'])
- ->setLabel($label)
+ ->setLabel($module_name)
->setUncheckedValue(0)
);
+
+ if (array_key_exists($moduleid, $data['disabled_moduleids'])) {
+ $module->addItem((new CSpan([' (', _('Disabled'), ')']))->addClass(ZBX_STYLE_RED));
+ }
+
+ $modules[] = $module;
}
if ($modules) {
- $form_grid->addItem([
- new CFormField(
- (new CDiv(
- (new CDiv($modules))
- ->addClass(ZBX_STYLE_COLUMNS)
- ->addClass(ZBX_STYLE_COLUMNS_3)
- ))->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
- )
- ]);
+ $form_grid->addItem(
+ new CFormField($modules)
+ );
}
else {
$form_grid->addItem(
@@ -405,8 +408,10 @@ $form_grid->addItem(
$tabs = (new CTabView())->addTab('user_role_tab', _('User role'), $form_grid);
$form->addItem((new CTabView())->addTab('user_role_tab', _('User role'), $form_grid));
-$widget->addItem($form);
-$widget->show();
+
+$html_page
+ ->addItem($form)
+ ->show();
(new CScriptTag('
view.init('.json_encode([
diff --git a/ui/app/views/administration.userrole.list.php b/ui/app/views/administration.userrole.list.php
index 29dd580cd01..d331d0ebb2a 100644
--- a/ui/app/views/administration.userrole.list.php
+++ b/ui/app/views/administration.userrole.list.php
@@ -27,7 +27,7 @@ if ($data['uncheck']) {
uncheckTableRows('userrole');
}
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('User roles'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::USERS_USERROLE_LIST))
->setControls(
@@ -130,5 +130,6 @@ $form->addItem([
], 'userrole')
]);
-$widget->addItem($form);
-$widget->show();
+$html_page
+ ->addItem($form)
+ ->show();
diff --git a/ui/app/views/configuration.correlation.edit.php b/ui/app/views/configuration.correlation.edit.php
index 0c0d1d868fb..60b75563b31 100644
--- a/ui/app/views/configuration.correlation.edit.php
+++ b/ui/app/views/configuration.correlation.edit.php
@@ -26,7 +26,7 @@
$this->addJsFile('popup.condition.common.js');
$this->includeJsFile('configuration.correlation.edit.js.php');
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Event correlation rules'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::DATA_COLLECTION_CORRELATION_EDIT));
@@ -37,7 +37,7 @@ $form = (new CForm())
->setArgument('action', 'correlation.condition.add')
->getUrl()
)
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE);
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID);
if ($data['correlationid'] != 0) {
$form->addVar('correlationid', $data['correlationid']);
@@ -193,6 +193,6 @@ else {
$form->addItem($correlation_tabs);
-$widget->addItem($form);
-
-$widget->show();
+$html_page
+ ->addItem($form)
+ ->show();
diff --git a/ui/app/views/configuration.correlation.list.php b/ui/app/views/configuration.correlation.list.php
index 6c8b6a37d6c..cdcd91514a6 100644
--- a/ui/app/views/configuration.correlation.list.php
+++ b/ui/app/views/configuration.correlation.list.php
@@ -27,7 +27,7 @@ if ($data['uncheck']) {
uncheckTableRows('correlation');
}
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Event correlation'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::DATA_COLLECTION_CORRELATION_LIST))
->setControls(
@@ -148,6 +148,6 @@ $form->addItem([
], 'correlation')
]);
-$widget->addItem($form);
-
-$widget->show();
+$html_page
+ ->addItem($form)
+ ->show();
diff --git a/ui/app/views/configuration.dashboard.edit.php b/ui/app/views/configuration.dashboard.edit.php
index ffade88dad0..e000f6be98c 100644
--- a/ui/app/views/configuration.dashboard.edit.php
+++ b/ui/app/views/configuration.dashboard.edit.php
@@ -30,23 +30,14 @@ $this->addJsFile('class.dashboard.js');
$this->addJsFile('class.dashboard.page.js');
$this->addJsFile('class.dashboard.widget.placeholder.js');
$this->addJsFile('class.widget.js');
+$this->addJsFile('class.widget.inaccessible.js');
$this->addJsFile('class.widget.iterator.js');
-$this->addJsFile('class.widget.clock.js');
-$this->addJsFile('class.widget.graph.js');
-$this->addJsFile('class.widget.graph-prototype.js');
-$this->addJsFile('class.widget.item.js');
-$this->addJsFile('class.widget.map.js');
-$this->addJsFile('class.widget.navtree.js');
$this->addJsFile('class.widget.paste-placeholder.js');
-$this->addJsFile('class.widget.problems.js');
-$this->addJsFile('class.widget.problemsbysv.js');
-$this->addJsFile('class.widget.svggraph.js');
-$this->addJsFile('class.widget.trigerover.js');
$this->addJsFile('class.sortable.js');
$this->includeJsFile('configuration.dashboard.edit.js.php');
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Dashboards'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::CONFIGURATION_DASHBOARDS_EDIT))
->setControls(
@@ -105,7 +96,7 @@ $dashboard->addItem(
$dashboard->addItem((new CDiv())->addClass(ZBX_STYLE_DASHBOARD_GRID));
-$widget
+$html_page
->addItem($dashboard)
->show();
@@ -113,6 +104,7 @@ $widget
view.init('.json_encode([
'dashboard' => $data['dashboard'],
'widget_defaults' => $data['widget_defaults'],
+ 'widget_last_type' => $data['widget_last_type'],
'time_period' => $data['time_period'],
'page' => $data['page']
]).');
diff --git a/ui/app/views/configuration.dashboard.list.php b/ui/app/views/configuration.dashboard.list.php
index 9cf4790743d..9d761d37a72 100644
--- a/ui/app/views/configuration.dashboard.list.php
+++ b/ui/app/views/configuration.dashboard.list.php
@@ -70,7 +70,7 @@ $form->addItem([
], $checkbox_hash)
]);
-(new CWidget())
+(new CHtmlPage())
->setTitle(_('Dashboards'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::CONFIGURATION_DASHBOARDS_LIST))
->setControls(
diff --git a/ui/app/views/configuration.discovery.edit.php b/ui/app/views/configuration.discovery.edit.php
index 71831c0bffd..729b59a626a 100644
--- a/ui/app/views/configuration.discovery.edit.php
+++ b/ui/app/views/configuration.discovery.edit.php
@@ -25,7 +25,7 @@
require_once dirname(__FILE__).'/js/configuration.discovery.edit.js.php';
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Discovery rules'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::DATA_COLLECTION_DISCOVERY_EDIT));
@@ -33,7 +33,7 @@ $widget = (new CWidget())
$discoveryForm = (new CForm())
->setId('discoveryForm')
->setName('discoveryForm')
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE);
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID);
if (!empty($this->data['druleid'])) {
$discoveryForm->addVar('druleid', $this->data['druleid']);
@@ -174,6 +174,6 @@ else {
$discoveryForm->addItem($discoveryTabs);
-$widget->addItem($discoveryForm);
-
-$widget->show();
+$html_page
+ ->addItem($discoveryForm)
+ ->show();
diff --git a/ui/app/views/configuration.discovery.list.php b/ui/app/views/configuration.discovery.list.php
index 0ac9244e180..d3b247c308b 100644
--- a/ui/app/views/configuration.discovery.list.php
+++ b/ui/app/views/configuration.discovery.list.php
@@ -27,7 +27,7 @@ if ($data['uncheck']) {
uncheckTableRows('discovery');
}
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Discovery rules'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::DATA_COLLECTION_DISCOVERY_LIST))
->setControls(
@@ -121,7 +121,6 @@ $discoveryForm->addItem([
], 'discovery')
]);
-// append form to widget
-$widget->addItem($discoveryForm);
-
-$widget->show();
+$html_page
+ ->addItem($discoveryForm)
+ ->show();
diff --git a/ui/app/views/configuration.host.edit.php b/ui/app/views/configuration.host.edit.php
index 7d336fa09e1..5a0484d69ea 100644
--- a/ui/app/views/configuration.host.edit.php
+++ b/ui/app/views/configuration.host.edit.php
@@ -62,7 +62,7 @@ if ($data['warning']) {
$data['warning'] = null;
}
-(new CWidget())
+(new CHtmlPage())
->setTitle(($data['hostid'] == 0) ? _('New host') : _('Host'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::DATA_COLLECTION_HOST_EDIT))
->addItem(new CPartial('configuration.host.edit.html', $data))
diff --git a/ui/app/views/configuration.host.list.php b/ui/app/views/configuration.host.list.php
index ec2fb854499..cc265e8adb9 100644
--- a/ui/app/views/configuration.host.list.php
+++ b/ui/app/views/configuration.host.list.php
@@ -31,7 +31,7 @@ if ($data['uncheck']) {
uncheckTableRows('hosts');
}
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Hosts'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::DATA_COLLECTION_HOST_LIST))
->setControls((new CTag('nav', true, (new CList())
@@ -166,7 +166,7 @@ $filter = (new CFilter())
])
]);
-$widget->addItem($filter);
+$html_page->addItem($filter);
// table hosts
$form = (new CForm())->setName('hosts');
@@ -545,7 +545,7 @@ $form->addItem([
], 'hosts')
]);
-$widget
+$html_page
->addItem($form)
->show();
diff --git a/ui/app/views/configuration.hostgroup.edit.php b/ui/app/views/configuration.hostgroup.edit.php
index f8036856dc9..e1131f78201 100644
--- a/ui/app/views/configuration.hostgroup.edit.php
+++ b/ui/app/views/configuration.hostgroup.edit.php
@@ -48,7 +48,7 @@ $data += [
]
];
-(new CWidget())
+(new CHtmlPage())
->setTitle(($data['groupid'] == 0) ? _('New host group') : _('Host group'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::DATA_COLLECTION_HOSTGROUPS_EDIT))
->addItem(new CPartial('configuration.hostgroup.edit.html', $data))
diff --git a/ui/app/views/configuration.hostgroup.list.php b/ui/app/views/configuration.hostgroup.list.php
index 34a6d781ead..969125349a4 100644
--- a/ui/app/views/configuration.hostgroup.list.php
+++ b/ui/app/views/configuration.hostgroup.list.php
@@ -26,7 +26,7 @@
$this->includeJsFile('configuration.hostgroup.list.js.php');
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Host groups'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::DATA_COLLECTION_HOSTGROUPS_LIST))
->setControls(
@@ -201,7 +201,7 @@ $form->addItem([
], 'hostgroup')
]);
-$widget
+$html_page
->addItem($form)
->show();
diff --git a/ui/app/views/configuration.templategroup.edit.php b/ui/app/views/configuration.templategroup.edit.php
index 732a8abe1b7..9ee12f1b36a 100644
--- a/ui/app/views/configuration.templategroup.edit.php
+++ b/ui/app/views/configuration.templategroup.edit.php
@@ -48,7 +48,7 @@ $data += [
]
];
-(new CWidget())
+(new CHtmlPage())
->setTitle(($data['groupid'] == 0) ? _('New template group') : _('Template group'))
->addItem(new CPartial('configuration.templategroup.edit.html', $data))
->show();
diff --git a/ui/app/views/configuration.templategroup.list.php b/ui/app/views/configuration.templategroup.list.php
index add2c591c7c..6e5c81b9384 100644
--- a/ui/app/views/configuration.templategroup.list.php
+++ b/ui/app/views/configuration.templategroup.list.php
@@ -26,7 +26,7 @@
$this->includeJsFile('configuration.templategroup.list.js.php');
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Template groups'))
->setControls((new CTag('nav', true, (new CList())
->addItem(CWebUser::getType() == USER_TYPE_SUPER_ADMIN
@@ -148,7 +148,7 @@ $form->addItem([
], 'templategroup')
]);
-$widget
+$html_page
->addItem($filter)
->addItem($form)
->show();
diff --git a/ui/app/views/js/configuration.dashboard.edit.js.php b/ui/app/views/js/configuration.dashboard.edit.js.php
index 6bfa2ab1a9c..58fdff1fd51 100644
--- a/ui/app/views/js/configuration.dashboard.edit.js.php
+++ b/ui/app/views/js/configuration.dashboard.edit.js.php
@@ -26,12 +26,10 @@
<script>
const view = {
- dashboard: null,
- page: null,
is_busy: false,
is_busy_saving: false,
- init({dashboard, widget_defaults, time_period, page}) {
+ init({dashboard, widget_defaults, widget_last_type, time_period, page}) {
this.dashboard = dashboard;
this.page = page;
@@ -60,19 +58,19 @@
max_rows: <?= DASHBOARD_MAX_ROWS ?>,
widget_min_rows: <?= DASHBOARD_WIDGET_MIN_ROWS ?>,
widget_max_rows: <?= DASHBOARD_WIDGET_MAX_ROWS ?>,
- widget_defaults: widget_defaults,
+ widget_defaults,
+ widget_last_type,
is_editable: true,
is_edit_mode: true,
can_edit_dashboards: true,
is_kiosk_mode: false,
- time_period: time_period,
+ time_period,
dynamic_hostid: null
});
for (const page of dashboard.pages) {
for (const widget of page.widgets) {
widget.fields = (typeof widget.fields === 'object') ? widget.fields : {};
- widget.configuration = (typeof widget.configuration === 'object') ? widget.configuration : {};
}
ZABBIX.Dashboard.addDashboardPage(page);
diff --git a/ui/app/views/js/monitoring.dashboard.print.js.php b/ui/app/views/js/monitoring.dashboard.print.js.php
index cfd11d78048..0031fc1812b 100644
--- a/ui/app/views/js/monitoring.dashboard.print.js.php
+++ b/ui/app/views/js/monitoring.dashboard.print.js.php
@@ -67,7 +67,6 @@
for (const page of dashboard.pages) {
for (const widget of page.widgets) {
widget.fields = (typeof widget.fields === 'object') ? widget.fields : {};
- widget.configuration = (typeof widget.configuration === 'object') ? widget.configuration : {};
}
ZABBIX.Dashboard.addDashboardPage(page);
diff --git a/ui/app/views/js/monitoring.dashboard.view.js.php b/ui/app/views/js/monitoring.dashboard.view.js.php
index 9f6dc5cd740..c1a623d43f4 100644
--- a/ui/app/views/js/monitoring.dashboard.view.js.php
+++ b/ui/app/views/js/monitoring.dashboard.view.js.php
@@ -26,18 +26,25 @@
<script>
const view = {
- dashboard: null,
- time_period: null,
- dynamic: null,
- has_time_selector: null,
is_busy: false,
is_busy_saving: false,
- init({dashboard, time_period, dynamic, has_time_selector, widget_defaults, web_layout_mode}) {
+ init({
+ dashboard,
+ widget_defaults,
+ widget_last_type,
+ configuration_hash,
+ has_time_selector,
+ time_period,
+ dynamic,
+ web_layout_mode,
+ clone
+ }) {
this.dashboard = dashboard;
+ this.has_time_selector = has_time_selector;
this.time_period = time_period;
this.dynamic = dynamic;
- this.has_time_selector = has_time_selector;
+ this.clone = clone;
timeControl.refreshPage = false;
@@ -73,20 +80,21 @@
max_rows: <?= DASHBOARD_MAX_ROWS ?>,
widget_min_rows: <?= DASHBOARD_WIDGET_MIN_ROWS ?>,
widget_max_rows: <?= DASHBOARD_WIDGET_MAX_ROWS ?>,
- widget_defaults: widget_defaults,
+ widget_defaults,
+ widget_last_type,
+ configuration_hash,
is_editable: dashboard.can_edit_dashboards && dashboard.editable
&& web_layout_mode != <?= ZBX_LAYOUT_KIOSKMODE ?>,
- is_edit_mode: dashboard.dashboardid === null,
+ is_edit_mode: dashboard.dashboardid === null || clone,
can_edit_dashboards: dashboard.can_edit_dashboards,
is_kiosk_mode: web_layout_mode == <?= ZBX_LAYOUT_KIOSKMODE ?>,
- time_period: time_period,
+ time_period,
dynamic_hostid: dynamic.host ? dynamic.host.id : null
});
for (const page of dashboard.pages) {
for (const widget of page.widgets) {
widget.fields = (typeof widget.fields === 'object') ? widget.fields : {};
- widget.configuration = (typeof widget.configuration === 'object') ? widget.configuration : {};
}
ZABBIX.Dashboard.addDashboardPage(page);
@@ -102,7 +110,7 @@
jQuery('#dynamic_hostid').on('change', this.events.dynamicHostChange);
}
- if (dashboard.dashboardid === null) {
+ if (dashboard.dashboardid === null || clone) {
this.edit();
ZABBIX.Dashboard.editProperties();
}
@@ -116,6 +124,8 @@
}
}
+ ZABBIX.Dashboard.on(DASHBOARD_EVENT_CONFIGURATION_OUTDATED, this.events.configurationOutdated);
+
if (dynamic.has_dynamic_widgets) {
// Perform dynamic host switch when browser back/previous buttons are pressed.
window.addEventListener('popstate', this.events.popState);
@@ -183,6 +193,10 @@
request_data.sharing = this.dashboard.sharing;
+ if (this.clone) {
+ request_data.clone = '1';
+ }
+
const curl = new Curl('zabbix.php');
curl.setArgument('action', 'dashboard.update');
@@ -224,7 +238,7 @@
messages = exception.error.messages;
}
else {
- title = this.dashboard.dashboardid === null
+ title = this.dashboard.dashboardid === null || this.clone
? <?= json_encode(_('Failed to create dashboard')) ?>
: <?= json_encode(_('Failed to update dashboard')) ?>;
}
@@ -311,14 +325,14 @@
clickCallback: () => ZABBIX.Dashboard.pasteWidget(
ZABBIX.Dashboard.getStoredWidgetDataCopy()
),
- disabled: (ZABBIX.Dashboard.getStoredWidgetDataCopy() === null)
+ disabled: ZABBIX.Dashboard.getStoredWidgetDataCopy() === null
},
{
label: <?= json_encode(_('Paste page')) ?>,
clickCallback: () => ZABBIX.Dashboard.pasteDashboardPage(
ZABBIX.Dashboard.getStoredDashboardPageDataCopy()
),
- disabled: (ZABBIX.Dashboard.getStoredDashboardPageDataCopy() === null)
+ disabled: ZABBIX.Dashboard.getStoredDashboardPageDataCopy() === null
}
]
}
@@ -380,10 +394,14 @@
applyProperties() {
const dashboard_data = ZABBIX.Dashboard.getData();
- document.getElementById('<?= ZBX_STYLE_PAGE_TITLE ?>').textContent = dashboard_data.name;
+ document.getElementById('<?= CHtmlPage::PAGE_TITLE_ID ?>').textContent = dashboard_data.name;
document.getElementById('dashboard-direct-link').textContent = dashboard_data.name;
},
+ configurationOutdated() {
+ location.href = location.href;
+ },
+
busy() {
view.is_busy = true;
view.updateBusy();
diff --git a/ui/app/views/js/monitoring.host.dashboard.view.js.php b/ui/app/views/js/monitoring.host.dashboard.view.js.php
index c65356010cf..7b7adbbaf5d 100644
--- a/ui/app/views/js/monitoring.host.dashboard.view.js.php
+++ b/ui/app/views/js/monitoring.host.dashboard.view.js.php
@@ -26,7 +26,7 @@
<script>
const view = {
- init({host, dashboard, widget_defaults, time_period, web_layout_mode}) {
+ init({host, dashboard, widget_defaults, configuration_hash, time_period, web_layout_mode}) {
timeControl.refreshPage = false;
ZABBIX.Dashboard = new CDashboard(document.querySelector('.<?= ZBX_STYLE_DASHBOARD ?>'), {
@@ -61,7 +61,8 @@
max_rows: <?= DASHBOARD_MAX_ROWS ?>,
widget_min_rows: <?= DASHBOARD_WIDGET_MIN_ROWS ?>,
widget_max_rows: <?= DASHBOARD_WIDGET_MAX_ROWS ?>,
- widget_defaults: widget_defaults,
+ widget_defaults,
+ configuration_hash,
is_editable: false,
is_edit_mode: false,
can_edit_dashboards: false,
@@ -73,7 +74,6 @@
for (const page of dashboard.pages) {
for (const widget of page.widgets) {
widget.fields = (typeof widget.fields === 'object') ? widget.fields : {};
- widget.configuration = (typeof widget.configuration === 'object') ? widget.configuration : {};
}
ZABBIX.Dashboard.addDashboardPage(page);
@@ -81,6 +81,8 @@
ZABBIX.Dashboard.activate();
+ ZABBIX.Dashboard.on(DASHBOARD_EVENT_CONFIGURATION_OUTDATED, this.events.configurationOutdated);
+
if (web_layout_mode == <?= ZBX_LAYOUT_NORMAL ?>) {
document.getElementById('dashboardid').addEventListener('change', this.events.dashboardChange);
}
@@ -89,6 +91,10 @@
},
events: {
+ configurationOutdated() {
+ location.href = location.href;
+ },
+
dashboardChange(e) {
e.target.closest('form').submit();
}
diff --git a/ui/app/views/js/popup.massupdate.tmpl.js.php b/ui/app/views/js/popup.massupdate.tmpl.js.php
index f4761332b6c..b792eb51230 100644
--- a/ui/app/views/js/popup.massupdate.tmpl.js.php
+++ b/ui/app/views/js/popup.massupdate.tmpl.js.php
@@ -24,7 +24,7 @@
* @var array $data
*/
?>
-<?= (new CScriptTemplate('valuemap-rename-row-tmpl'))->addItem(
+<?= (new CTemplateTag('valuemap-rename-row-tmpl'))->addItem(
(new CRow([
(new CTextBox('valuemap_rename[#{rowNum}][from]', '', false, DB::getFieldLength('valuemap', 'name')))
->addStyle('width: 100%;'),
diff --git a/ui/app/views/monitoring.charts.view.php b/ui/app/views/monitoring.charts.view.php
index e031f3c433e..7fe528b8638 100644
--- a/ui/app/views/monitoring.charts.view.php
+++ b/ui/app/views/monitoring.charts.view.php
@@ -36,7 +36,7 @@ $this->includeJsFile('monitoring.charts.view.js.php');
$this->enableLayoutModes();
$web_layout_mode = $this->getLayoutMode();
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Graphs'))
->setWebLayoutMode($web_layout_mode)
->setDocUrl(CDocHelper::getUrl(CDocHelper::MONITORING_CHARTS_VIEW))
@@ -89,24 +89,24 @@ if ($web_layout_mode == ZBX_LAYOUT_NORMAL) {
new CPartial('monitoring.charts.subfilter', $data['subfilters']));
}
-$widget->addItem($filter);
+$html_page->addItem($filter);
if (!$data['filter_hostids']) {
- $widget->addItem((new CTableInfo())->setNoDataMessage(_('Specify host to see the graphs.')));
+ $html_page->addItem((new CTableInfo())->setNoDataMessage(_('Specify host to see the graphs.')));
}
elseif ($data['charts']) {
$table = (new CTable())
->setAttribute('style', 'width: 100%;')
->setId('charts');
- $widget
+ $html_page
->addItem($table)
->addItem($data['paging']);
}
else {
- $widget->addItem(new CTableInfo());
+ $html_page->addItem(new CTableInfo());
}
-$widget->show();
+$html_page->show();
(new CScriptTag('
view.init('.json_encode([
diff --git a/ui/app/views/monitoring.dashboard.list.php b/ui/app/views/monitoring.dashboard.list.php
index 50730374c9f..cdc4205e740 100644
--- a/ui/app/views/monitoring.dashboard.list.php
+++ b/ui/app/views/monitoring.dashboard.list.php
@@ -31,7 +31,7 @@ $this->addJsFile('layout.mode.js');
$this->enableLayoutModes();
$web_layout_mode = $this->getLayoutMode();
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Dashboards'))
->setWebLayoutMode($web_layout_mode)
->setDocUrl(CDocHelper::getUrl(CDocHelper::DASHBOARDS_LIST))
@@ -52,7 +52,7 @@ $widget = (new CWidget())
);
if ($web_layout_mode == ZBX_LAYOUT_NORMAL) {
- $widget
+ $html_page
->addItem((new CFilter())
->setResetUrl((new CUrl('zabbix.php'))->setArgument('action', 'dashboard.list'))
->setProfile($data['profileIdx'])
@@ -128,5 +128,6 @@ $form->addItem([
], 'dashboard')
]);
-$widget->addItem($form);
-$widget->show();
+$html_page
+ ->addItem($form)
+ ->show();
diff --git a/ui/app/views/monitoring.dashboard.print.php b/ui/app/views/monitoring.dashboard.print.php
index d0fb077c6b8..911f46aac8f 100644
--- a/ui/app/views/monitoring.dashboard.print.php
+++ b/ui/app/views/monitoring.dashboard.print.php
@@ -38,19 +38,9 @@ $this->addJsFile('class.dashboard.page.js');
$this->addJsFile('class.dashboard.widget.placeholder.js');
$this->addJsFile('class.geomaps.js');
$this->addJsFile('class.widget.js');
+$this->addJsFile('class.widget.inaccessible.js');
$this->addJsFile('class.widget.iterator.js');
-$this->addJsFile('class.widget.clock.js');
-$this->addJsFile('class.widget.geomap.js');
-$this->addJsFile('class.widget.graph.js');
-$this->addJsFile('class.widget.graph-prototype.js');
-$this->addJsFile('class.widget.item.js');
-$this->addJsFile('class.widget.map.js');
-$this->addJsFile('class.widget.navtree.js');
$this->addJsFile('class.widget.paste-placeholder.js');
-$this->addJsFile('class.widget.problems.js');
-$this->addJsFile('class.widget.problemsbysv.js');
-$this->addJsFile('class.widget.svggraph.js');
-$this->addJsFile('class.widget.trigerover.js');
$this->addJsFile('class.csvggraph.js');
$this->addJsFile('class.svg.canvas.js');
$this->addJsFile('class.svg.map.js');
@@ -63,7 +53,7 @@ $this->addCssFile('assets/styles/vendors/Leaflet/Leaflet/leaflet.css');
$this->enableLayoutModes();
$this->setLayoutMode(ZBX_LAYOUT_KIOSKMODE);
-(new CWidget())
+(new CHtmlPage())
->addItem(
(new CDiv())
->addClass(ZBX_STYLE_DASHBOARD)
diff --git a/ui/app/views/monitoring.dashboard.view.php b/ui/app/views/monitoring.dashboard.view.php
index e34b71a6d41..0623b5f8968 100644
--- a/ui/app/views/monitoring.dashboard.view.php
+++ b/ui/app/views/monitoring.dashboard.view.php
@@ -39,19 +39,9 @@ $this->addJsFile('class.dashboard.page.js');
$this->addJsFile('class.dashboard.widget.placeholder.js');
$this->addJsFile('class.geomaps.js');
$this->addJsFile('class.widget.js');
+$this->addJsFile('class.widget.inaccessible.js');
$this->addJsFile('class.widget.iterator.js');
-$this->addJsFile('class.widget.clock.js');
-$this->addJsFile('class.widget.geomap.js');
-$this->addJsFile('class.widget.graph.js');
-$this->addJsFile('class.widget.graph-prototype.js');
-$this->addJsFile('class.widget.item.js');
-$this->addJsFile('class.widget.map.js');
-$this->addJsFile('class.widget.navtree.js');
$this->addJsFile('class.widget.paste-placeholder.js');
-$this->addJsFile('class.widget.problems.js');
-$this->addJsFile('class.widget.problemsbysv.js');
-$this->addJsFile('class.widget.svggraph.js');
-$this->addJsFile('class.widget.trigerover.js');
$this->addJsFile('class.calendar.js');
$this->addJsFile('layout.mode.js');
$this->addJsFile('class.coverride.js');
@@ -100,7 +90,7 @@ if ($data['dynamic']['has_dynamic_widgets']) {
]);
}
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle($data['dashboard']['name'])
->setWebLayoutMode($web_layout_mode)
->setDocUrl(CDocHelper::getUrl(CDocHelper::DASHBOARDS_VIEW))
@@ -137,9 +127,11 @@ $widget = (new CWidget())
(new CButton('dashboard-config'))->addClass(ZBX_STYLE_BTN_DASHBOARD_CONF),
(new CList())
->addClass(ZBX_STYLE_BTN_SPLIT)
- ->addItem((new CButton('dashboard-add-widget',
- [(new CSpan())->addClass(ZBX_STYLE_PLUS_ICON), _('Add')]
- ))->addClass(ZBX_STYLE_BTN_ALT))
+ ->addItem(
+ (new CButton('dashboard-add-widget',
+ [(new CSpan())->addClass(ZBX_STYLE_PLUS_ICON), _('Add')]
+ ))->addClass(ZBX_STYLE_BTN_ALT)
+ )
->addItem(
(new CButton('dashboard-add', '&#8203;'))
->addClass(ZBX_STYLE_BTN_ALT)
@@ -197,7 +189,7 @@ $widget = (new CWidget())
])));
if ($data['has_time_selector']) {
- $widget->addItem(
+ $html_page->addItem(
(new CFilter())
->setProfile($data['time_period']['profileIdx'], $data['time_period']['profileIdx2'])
->setActiveTab($data['active_tab'])
@@ -252,7 +244,7 @@ if ($web_layout_mode != ZBX_LAYOUT_KIOSKMODE) {
$dashboard->addItem((new CDiv())->addClass(ZBX_STYLE_DASHBOARD_GRID));
-$widget
+$html_page
->addItem($dashboard)
->show();
@@ -260,10 +252,13 @@ $widget
view.init('.json_encode([
'dashboard' => $data['dashboard'],
'widget_defaults' => $data['widget_defaults'],
+ 'widget_last_type' => $data['widget_last_type'],
+ 'configuration_hash' => $data['configuration_hash'],
'has_time_selector' => $data['has_time_selector'],
'time_period' => $data['time_period'],
'dynamic' => $data['dynamic'],
- 'web_layout_mode' => $web_layout_mode
+ 'web_layout_mode' => $web_layout_mode,
+ 'clone' => $data['clone']
]).');
'))
->setOnDocumentReady()
diff --git a/ui/app/views/monitoring.dashboard.widget.edit.php b/ui/app/views/monitoring.dashboard.widget.edit.php
deleted file mode 100644
index b137f5f9257..00000000000
--- a/ui/app/views/monitoring.dashboard.widget.edit.php
+++ /dev/null
@@ -1,84 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * @var CView $this
- * @var array $data
- */
-
-$widget_view = include('include/classes/widgets/views/widget.'.$data['dialogue']['type'].'.form.view.php');
-
-$form = $widget_view['form']->addClass('dashboard-widget-'.$data['dialogue']['type']);
-
-// Submit button is needed to enable submit event on Enter on inputs.
-$form->addItem((new CInput('submit', 'dashboard_widget_config_submit'))->addStyle('display: none;'));
-
-$output = [
- 'header' => $data['unique_id'] !== null ? _s('Edit widget') : _s('Add widget'),
- 'doc_url' => CDocHelper::getUrl(CDocHelper::DASHBOARDS_WIDGET_EDIT),
- 'body' => '',
- 'buttons' => [
- [
- 'title' => $data['unique_id'] !== null ? _s('Apply') : _s('Add'),
- 'class' => 'dialogue-widget-save',
- 'keepOpen' => true,
- 'isSubmit' => true,
- 'action' => 'ZABBIX.Dashboard.applyWidgetProperties();'
- ]
- ],
- 'data' => [
- 'original_properties' => [
- 'type' => $data['dialogue']['type'],
- 'unique_id' => $data['unique_id'],
- 'dashboard_page_unique_id' => $data['dashboard_page_unique_id']
- ]
- ]
-];
-
-if (($messages = getMessages()) !== null) {
- $output['body'] .= $messages->toString();
-}
-
-$output['body'] .= $form->toString();
-
-if (array_key_exists('jq_templates', $widget_view)) {
- foreach ($widget_view['jq_templates'] as $id => $jq_template) {
- $output['body'] .= '<script type="text/x-jquery-tmpl" id="'.$id.'">'.$jq_template.'</script>';
- }
-}
-
-$scripts = [
- $this->readJsFile('monitoring.dashboard.widget.edit.js.php'),
- 'widget_form.init();'
-];
-
-if (array_key_exists('scripts', $widget_view)) {
- $scripts = array_merge($scripts, $widget_view['scripts']);
-}
-
-$output['body'] .= get_js(implode("\n", $scripts));
-
-if ($data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
- CProfiler::getInstance()->stop();
- $output['debug'] = CProfiler::getInstance()->make()->toString();
-}
-
-echo json_encode($output);
diff --git a/ui/app/views/monitoring.discovery.view.php b/ui/app/views/monitoring.discovery.view.php
index bd156a5824f..76cf3e5db47 100644
--- a/ui/app/views/monitoring.discovery.view.php
+++ b/ui/app/views/monitoring.discovery.view.php
@@ -30,7 +30,7 @@ $this->addJsFile('layout.mode.js');
$this->enableLayoutModes();
$web_layout_mode = $this->getLayoutMode();
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Status of discovery'))
->setWebLayoutMode($web_layout_mode)
->setDocUrl(CDocHelper::getUrl(CDocHelper::MONITORING_DISCOVERY_VIEW))
@@ -77,4 +77,4 @@ $discovery_table = CScreenBuilder::getScreen([
]
])->get();
-$widget->addItem($discovery_table)->show();
+$html_page->addItem($discovery_table)->show();
diff --git a/ui/app/views/monitoring.host.dashboard.view.php b/ui/app/views/monitoring.host.dashboard.view.php
index 95461164381..5b154ebbd4f 100644
--- a/ui/app/views/monitoring.host.dashboard.view.php
+++ b/ui/app/views/monitoring.host.dashboard.view.php
@@ -28,7 +28,7 @@ if (array_key_exists('error', $data)) {
}
if (array_key_exists('no_data', $data)) {
- (new CWidget())
+ (new CHtmlPage())
->setTitle(_('Dashboards'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::MONITORING_HOST_DASHBOARD_VIEW))
->addItem(new CTableInfo())
@@ -44,18 +44,9 @@ $this->addJsFile('class.dashboard.js');
$this->addJsFile('class.dashboard.page.js');
$this->addJsFile('class.dashboard.widget.placeholder.js');
$this->addJsFile('class.widget.js');
+$this->addJsFile('class.widget.inaccessible.js');
$this->addJsFile('class.widget.iterator.js');
-$this->addJsFile('class.widget.clock.js');
-$this->addJsFile('class.widget.graph.js');
-$this->addJsFile('class.widget.graph-prototype.js');
-$this->addJsFile('class.widget.item.js');
-$this->addJsFile('class.widget.map.js');
-$this->addJsFile('class.widget.navtree.js');
$this->addJsFile('class.widget.paste-placeholder.js');
-$this->addJsFile('class.widget.problems.js');
-$this->addJsFile('class.widget.problemsbysv.js');
-$this->addJsFile('class.widget.svggraph.js');
-$this->addJsFile('class.widget.trigerover.js');
$this->addJsFile('layout.mode.js');
$this->addJsFile('class.sortable.js');
@@ -64,7 +55,7 @@ $this->includeJsFile('monitoring.host.dashboard.view.js.php');
$this->enableLayoutModes();
$web_layout_mode = $this->getLayoutMode();
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle($data['dashboard']['name'])
->setWebLayoutMode($web_layout_mode)
->setDocUrl(CDocHelper::getUrl(CDocHelper::MONITORING_HOST_DASHBOARD_VIEW))
@@ -129,7 +120,7 @@ $widget = (new CWidget())
])));
if ($data['has_time_selector']) {
- $widget->addItem(
+ $html_page->addItem(
(new CFilter())
->setProfile($data['time_period']['profileIdx'], $data['time_period']['profileIdx2'])
->setActiveTab($data['active_tab'])
@@ -182,7 +173,7 @@ if (count($data['dashboard']['pages']) > 1
$dashboard->addItem((new CDiv())->addClass(ZBX_STYLE_DASHBOARD_GRID));
- $widget
+ $html_page
->addItem($dashboard)
->show();
@@ -191,6 +182,7 @@ if (count($data['dashboard']['pages']) > 1
'host' => $data['host'],
'dashboard' => $data['dashboard'],
'widget_defaults' => $data['widget_defaults'],
+ 'configuration_hash' => $data['configuration_hash'],
'time_period' => $data['time_period'],
'web_layout_mode' => $web_layout_mode
]).');
@@ -199,7 +191,7 @@ if (count($data['dashboard']['pages']) > 1
->show();
}
else {
- $widget
+ $html_page
->addItem(new CTableInfo())
->show();
}
diff --git a/ui/app/views/monitoring.host.view.php b/ui/app/views/monitoring.host.view.php
index f50e9c56edd..fcee4d1d6ed 100644
--- a/ui/app/views/monitoring.host.view.php
+++ b/ui/app/views/monitoring.host.view.php
@@ -45,7 +45,7 @@ if ($data['can_create_hosts']) {
$nav_items->addItem(get_icon('kioskmode', ['mode' => $web_layout_mode]));
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Hosts'))
->setWebLayoutMode($web_layout_mode)
->setDocUrl(CDocHelper::getUrl(CDocHelper::MONITORING_HOST_VIEW))
@@ -66,18 +66,19 @@ if ($web_layout_mode == ZBX_LAYOUT_NORMAL) {
// Set javascript options for tab filter initialization in monitoring.host.view.js.php file.
$data['filter_options'] = $filter->options;
- $widget->addItem($filter);
+ $html_page->addItem($filter);
}
else {
$data['filter_options'] = null;
}
-$widget->addItem((new CForm())
- ->setName('host_view')
- ->addClass('is-loading')
-);
-
-$widget->show();
+$html_page
+ ->addItem(
+ (new CForm())
+ ->setName('host_view')
+ ->addClass('is-loading')
+ )
+ ->show();
(new CScriptTag('
view.init('.json_encode([
diff --git a/ui/app/views/monitoring.latest.view.php b/ui/app/views/monitoring.latest.view.php
index d95fdaf18a8..965166b187d 100644
--- a/ui/app/views/monitoring.latest.view.php
+++ b/ui/app/views/monitoring.latest.view.php
@@ -39,7 +39,7 @@ if ($data['uncheck']) {
uncheckTableRows('latest');
}
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Latest data'))
->setWebLayoutMode($web_layout_mode)
->setDocUrl(CDocHelper::getUrl(CDocHelper::MONITORING_LATEST_VIEW))
@@ -64,19 +64,19 @@ if ($web_layout_mode == ZBX_LAYOUT_NORMAL) {
// Set javascript options for tab filter initialization in monitoring.latest.view.js.php file.
$data['filter_options'] = $filter->options;
- $widget->addItem($filter);
+ $html_page->addItem($filter);
}
else {
$data['filter_options'] = null;
}
-$widget->addItem(new CPartial('monitoring.latest.view.html', array_intersect_key($data,
- array_flip(['filter', 'sort_field', 'sort_order', 'view_curl', 'paging', 'hosts', 'items', 'history', 'config',
- 'tags', 'maintenances', 'items_rw'
- ])
-)));
-
-$widget->show();
+$html_page
+ ->addItem(new CPartial('monitoring.latest.view.html', array_intersect_key($data,
+ array_flip(['filter', 'sort_field', 'sort_order', 'view_curl', 'paging', 'hosts', 'items', 'history', 'config',
+ 'tags', 'maintenances', 'items_rw'
+ ])
+ )))
+ ->show();
(new CScriptTag('
view.init('.json_encode([
diff --git a/ui/app/views/monitoring.map.view.php b/ui/app/views/monitoring.map.view.php
index 5afe2dcf90a..ebfe9b5f8e3 100644
--- a/ui/app/views/monitoring.map.view.php
+++ b/ui/app/views/monitoring.map.view.php
@@ -33,7 +33,7 @@ $this->includeJsFile('monitoring.map.view.js.php');
$this->enableLayoutModes();
$web_layout_mode = $this->getLayoutMode();
-(new CWidget())
+(new CHtmlPage())
->setTitle(_('Maps'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::MONITORING_MAP_VIEW))
->setWebLayoutMode($web_layout_mode)
@@ -62,7 +62,7 @@ $web_layout_mode = $this->getLayoutMode();
))->setEnabled($data['allowed_edit'])
: null
)
- ->addItem(get_icon('favourite', [
+ ->addItem(get_icon('favorite', [
'fav' => 'web.favorite.sysmapids',
'elname' => 'sysmapid',
'elid' => $data['map']['sysmapid']
diff --git a/ui/app/views/monitoring.problem.view.php b/ui/app/views/monitoring.problem.view.php
index 41b26a66a8b..49e2cc9beee 100644
--- a/ui/app/views/monitoring.problem.view.php
+++ b/ui/app/views/monitoring.problem.view.php
@@ -39,7 +39,7 @@ if ($data['action'] === 'problem.view') {
uncheckTableRows('problem');
}
- $widget = (new CWidget())
+ $html_page = (new CHtmlPage())
->setTitle(_('Problems'))
->setWebLayoutMode($web_layout_mode)
->setDocUrl(CDocHelper::getUrl(CDocHelper::MONITORING_PROBLEMS_VIEW))
@@ -66,14 +66,14 @@ if ($data['action'] === 'problem.view') {
// Set javascript options for tab filter initialization in monitoring.problem.view.js.php file.
$data['filter_options'] = $filter->options;
- $widget->addItem($filter);
+ $html_page->addItem($filter);
}
else {
$data['filter_options'] = null;
}
$this->includeJsFile('monitoring.problem.view.js.php', $data);
- $widget
+ $html_page
->addItem(new CPartial('monitoring.problem.view.html', array_intersect_key($data,
array_flip(['page', 'action', 'sort', 'sortorder', 'filter', 'tabfilter_idx'])
)))
diff --git a/ui/app/views/monitoring.web.view.php b/ui/app/views/monitoring.web.view.php
index 20595245dfb..242e54f0703 100644
--- a/ui/app/views/monitoring.web.view.php
+++ b/ui/app/views/monitoring.web.view.php
@@ -33,7 +33,7 @@ $this->includeJsFile('monitoring.web.view.js.php');
$this->enableLayoutModes();
$web_layout_mode = $this->getLayoutMode();
-(new CWidget())
+(new CHtmlPage())
->setTitle(_('Web monitoring'))
->setWebLayoutMode($web_layout_mode)
->setDocUrl(CDocHelper::getUrl(CDocHelper::MONITORING_WEB_VIEW))
diff --git a/ui/app/views/monitoring.widget.dataover.view.php b/ui/app/views/monitoring.widget.dataover.view.php
deleted file mode 100644
index dcca9a7703b..00000000000
--- a/ui/app/views/monitoring.widget.dataover.view.php
+++ /dev/null
@@ -1,47 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * @var CView $this
- */
-
-if ($data['style'] == STYLE_TOP) {
- $table = (new CPartial('dataoverview.table.top', $data))->getOutput();
-}
-else {
- $table = (new CPartial('dataoverview.table.left', $data))->getOutput();
-}
-
-$output = [
- 'name' => $data['name'],
- 'body' => $table
-];
-
-if ($messages = get_and_clear_messages()) {
- $output['messages'] = array_column($messages, 'message');
-}
-
-if ($data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
- CProfiler::getInstance()->stop();
- $output['debug'] = CProfiler::getInstance()->make()->toString();
-}
-
-echo json_encode($output);
diff --git a/ui/app/views/monitoring.widget.graph.view.php b/ui/app/views/monitoring.widget.graph.view.php
deleted file mode 100644
index 3a85991c624..00000000000
--- a/ui/app/views/monitoring.widget.graph.view.php
+++ /dev/null
@@ -1,55 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * @var CView $this
- */
-
-$output = [
- 'name' => $data['name']
-];
-
-if ($data['is_resource_available']) {
- $link_url = ($data['widget']['graph_url'] !== null) ? $data['widget']['graph_url'] : 'javascript:void(0)';
-
- $output['body'] = (new CDiv())
- ->addClass('flickerfreescreen')
- ->addItem((new CLink(null, $link_url))->addClass(ZBX_STYLE_DASHBOARD_WIDGET_GRAPH_LINK))
- ->toString();
-
- $output['async_data'] = $data['widget'];
-}
-else {
- $output['body'] = (new CTableInfo())
- ->setNoDataMessage(_('No permissions to referred object or it does not exist!'))
- ->toString();
-}
-
-if ($messages = get_and_clear_messages()) {
- $output['messages'] = array_column($messages, 'message');
-}
-
-if ($data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
- CProfiler::getInstance()->stop();
- $output['debug'] = CProfiler::getInstance()->make()->toString();
-}
-
-echo json_encode($output);
diff --git a/ui/app/views/monitoring.widget.map.view.php b/ui/app/views/monitoring.widget.map.view.php
deleted file mode 100644
index 293c9e151eb..00000000000
--- a/ui/app/views/monitoring.widget.map.view.php
+++ /dev/null
@@ -1,43 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * @var CView $this
- */
-
-$item = new CDashboardWidgetMap($data['sysmap_data'], $data['widget_settings']);
-
-$output = [
- 'name' => $data['name'],
- 'body' => $item->toString(),
- 'sysmap_data' => $item->getScriptData()
-];
-
-if ($messages = get_and_clear_messages()) {
- $output['messages'] = array_column($messages, 'message');
-}
-
-if ($this->data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
- CProfiler::getInstance()->stop();
- $output['debug'] = CProfiler::getInstance()->make()->toString();
-}
-
-echo json_encode($output);
diff --git a/ui/app/views/monitoring.widget.svggraph.view.php b/ui/app/views/monitoring.widget.svggraph.view.php
deleted file mode 100644
index b081a44c305..00000000000
--- a/ui/app/views/monitoring.widget.svggraph.view.php
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * @var CView $this
- */
-
-$output = [
- 'body' => $data['svg']
-];
-
-if (!$data['preview']) {
- $output += [
- 'name' => $data['name'],
- 'svg_options' => $data['svg_options']
- ];
-
- if ($data['info'] !== null) {
- $output += [
- 'info' => $data['info']
- ];
- }
-}
-
-if ($messages = get_and_clear_messages()) {
- $output['messages'] = array_column($messages, 'message');
-}
-
-if (!$data['preview'] && $data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
- CProfiler::getInstance()->stop();
- $output['debug'] = CProfiler::getInstance()->make()->toString();
-}
-
-echo json_encode($output);
diff --git a/ui/app/views/monitoring.widget.trigover.view.php b/ui/app/views/monitoring.widget.trigover.view.php
deleted file mode 100644
index 9b9c93d1571..00000000000
--- a/ui/app/views/monitoring.widget.trigover.view.php
+++ /dev/null
@@ -1,47 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * @var CView $this
- */
-
-if ($data['style'] == STYLE_TOP) {
- $table = (new CPartial('trigoverview.table.top', $data))->getOutput();
-}
-else {
- $table = (new CPartial('trigoverview.table.left', $data))->getOutput();
-}
-
-$output = [
- 'name' => $data['name'],
- 'body' => $table
-];
-
-if ($messages = get_and_clear_messages()) {
- $output['messages'] = array_column($messages, 'message');
-}
-
-if ($data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
- CProfiler::getInstance()->stop();
- $output['debug'] = CProfiler::getInstance()->make()->toString();
-}
-
-echo json_encode($output);
diff --git a/ui/app/views/popup.massupdate.service.php b/ui/app/views/popup.massupdate.service.php
index ed88a153f74..fa3bd38ba93 100644
--- a/ui/app/views/popup.massupdate.service.php
+++ b/ui/app/views/popup.massupdate.service.php
@@ -45,7 +45,7 @@ $tags_form_grid = (new CFormGrid())
renderTagTable([['tag' => '', 'value' => '']])
->setHeader([_('Name'), _('Value'), _('Action')])
->addClass('tags-table'),
- (new CScriptTemplate('tag-row-tmpl'))
+ (new CTemplateTag('tag-row-tmpl'))
->addItem(renderTagTableRow('#{rowNum}', '', '', ZBX_TAG_MANUAL, ['add_post_js' => false]))
]))
->setId('tags-div')
diff --git a/ui/app/views/popup.service.edit.php b/ui/app/views/popup.service.edit.php
index 7db4c330145..006852a8bce 100644
--- a/ui/app/views/popup.service.edit.php
+++ b/ui/app/views/popup.service.edit.php
@@ -73,7 +73,7 @@ $service_tab = (new CFormGrid())
->addClass('element-table-add')
))
),
- (new CScriptTemplate('problem-tag-row-tmpl'))
+ (new CTemplateTag('problem-tag-row-tmpl'))
->addItem(
(new CRow([
(new CTextBox('problem_tags[#{rowNum}][tag]', '#{tag}', false,
@@ -252,7 +252,7 @@ $tags_tab = (new CFormGrid())
renderTagTable($data['form']['tags'])
->addClass('tags-table')
->setHeader((new CRowHeader([_('Name'), _('Value'), _('Action')]))->addClass(ZBX_STYLE_GREY)),
- (new CScriptTemplate('tag-row-tmpl'))
+ (new CTemplateTag('tag-row-tmpl'))
->addItem(renderTagTableRow('#{rowNum}', '', '', ZBX_TAG_MANUAL, ['add_post_js' => false]))
])
)
diff --git a/ui/app/views/popup.sla.edit.php b/ui/app/views/popup.sla.edit.php
index 555cb46cd37..e7c08919817 100644
--- a/ui/app/views/popup.sla.edit.php
+++ b/ui/app/views/popup.sla.edit.php
@@ -136,7 +136,7 @@ $sla_tab = (new CFormGrid())
->addClass('element-table-add')
))
),
- (new CScriptTemplate('service-tag-row-tmpl'))
+ (new CTemplateTag('service-tag-row-tmpl'))
->addItem(
(new CRow([
(new CTextBox('service_tags[#{rowNum}][tag]', '#{tag}', false,
diff --git a/ui/app/views/popup.view.php b/ui/app/views/popup.view.php
index e616e7f2b58..51f560851b4 100644
--- a/ui/app/views/popup.view.php
+++ b/ui/app/views/popup.view.php
@@ -25,7 +25,7 @@
$this->addJsFile('class.calendar.js');
-(new CWidget())->show();
+(new CHtmlPage())->show();
(new CScriptTag(
'PopUp("'.$data['popup']['action'].'", '.json_encode($data['popup']['options']).');'.
diff --git a/ui/app/views/proxy.list.php b/ui/app/views/proxy.list.php
index 48f331ea475..64861b44e54 100644
--- a/ui/app/views/proxy.list.php
+++ b/ui/app/views/proxy.list.php
@@ -229,7 +229,7 @@ $form->addItem(
], 'proxy')
);
-(new CWidget())
+(new CHtmlPage())
->setTitle(_('Proxies'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::ADMINISTRATION_PROXY_LIST))
->setControls(
diff --git a/ui/app/views/report.status.php b/ui/app/views/report.status.php
index ae5f6c38152..0658436199b 100644
--- a/ui/app/views/report.status.php
+++ b/ui/app/views/report.status.php
@@ -26,7 +26,7 @@
require_once __DIR__.'/../../include/blocks.inc.php';
-(new CWidget())
+(new CHtmlPage())
->setTitle(_('System information'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::REPORT_STATUS))
->addItem(
diff --git a/ui/app/views/reports.auditlog.list.php b/ui/app/views/reports.auditlog.list.php
index 7f1adddbba6..911fd046805 100644
--- a/ui/app/views/reports.auditlog.list.php
+++ b/ui/app/views/reports.auditlog.list.php
@@ -53,7 +53,7 @@ $filter_actions = (new CCheckBoxList('filter_actions'))
->addClass(ZBX_STYLE_COLUMNS_3)
->setOptions($filter_actions_options);
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Audit log'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::REPORTS_AUDITLOG_LIST))
->addItem($filter
@@ -157,7 +157,7 @@ $obj = [
'timeControl.processObjects();')
)->show();
-$widget
+$html_page
->addItem(
(new CForm('get'))
->setName('auditForm')
diff --git a/ui/app/views/reports.scheduledreport.edit.php b/ui/app/views/reports.scheduledreport.edit.php
index 105f9055853..83a38bc9a1b 100644
--- a/ui/app/views/reports.scheduledreport.edit.php
+++ b/ui/app/views/reports.scheduledreport.edit.php
@@ -29,7 +29,7 @@ $this->includeJsFile('reports.scheduledreport.edit.js.php', [
'dashboard_inaccessible' => $data['dashboard_inaccessible']
]);
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Scheduled reports'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::REPORTS_SCHEDULEDREPORT_EDIT));
@@ -41,7 +41,7 @@ $form = (new CForm())
->setArgument('action', ($data['reportid'] == 0) ? 'scheduledreport.create' : 'scheduledreport.update')
->getUrl()
)
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE);
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID);
if ($data['reportid'] != 0) {
$form->addVar('reportid', $data['reportid']);
@@ -58,6 +58,6 @@ $form_grid = new CPartial('scheduledreport.formgrid.html', [
$form->addItem((new CTabView())->addTab('scheduledreport_tab', _('Scheduled report'), $form_grid));
-$widget
+$html_page
->addItem($form)
->show();
diff --git a/ui/app/views/reports.scheduledreport.list.php b/ui/app/views/reports.scheduledreport.list.php
index 9f645997285..6bcfd395267 100644
--- a/ui/app/views/reports.scheduledreport.list.php
+++ b/ui/app/views/reports.scheduledreport.list.php
@@ -27,7 +27,7 @@ if ($data['uncheck']) {
uncheckTableRows('scheduledreport');
}
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Scheduled reports'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::REPORTS_SCHEDULEDREPORT_LIST))
->setControls(
@@ -100,6 +100,6 @@ $form->addItem([
], 'scheduledreport')
]);
-$widget
+$html_page
->addItem($form)
->show();
diff --git a/ui/app/views/search.php b/ui/app/views/search.php
index c69680f1514..13553001022 100644
--- a/ui/app/views/search.php
+++ b/ui/app/views/search.php
@@ -26,7 +26,7 @@
$this->includeJsFile('search.js.php');
-$widgets = [];
+$sections = [];
$table = (new CTableInfo())
->setHeader((new CRowHeader())
@@ -179,13 +179,12 @@ foreach ($data['hosts'] as $hostid => $host) {
]);
}
-$widgets[] = (new CCollapsibleUiWidget(WIDGET_SEARCH_HOSTS, $table))
- ->addClass(ZBX_STYLE_DASHBOARD_WIDGET_FLUID)
- ->setExpanded((bool) CProfile::get('web.search.hats.'.WIDGET_SEARCH_HOSTS.'.state', true))
- ->setHeader(_('Hosts'), [], 'web.search.hats.'.WIDGET_SEARCH_HOSTS.'.state')
- ->setFooter(new CList([
- _s('Displaying %1$s of %2$s found', count($data['hosts']), $data['total_hosts_cnt'])
- ]));
+$sections[] = (new CSectionCollapsible($table))
+ ->setId(SECTION_SEARCH_HOSTS)
+ ->setHeader(new CTag('h4', true, _('Hosts')))
+ ->setFooter(_s('Displaying %1$s of %2$s found', count($data['hosts']), $data['total_hosts_cnt']))
+ ->setProfileIdx('web.search.hats.'.SECTION_SEARCH_HOSTS.'.state')
+ ->setExpanded((bool) CProfile::get('web.search.hats.'.SECTION_SEARCH_HOSTS.'.state', true));
$table = (new CTableInfo())
->setHeader((new CRowHeader())
@@ -260,13 +259,12 @@ foreach ($data['host_groups'] as $groupid => $group) {
]);
}
-$widgets[] = (new CCollapsibleUiWidget(WIDGET_SEARCH_HOSTGROUP, $table))
- ->addClass(ZBX_STYLE_DASHBOARD_WIDGET_FLUID)
- ->setExpanded((bool) CProfile::get('web.search.hats.'.WIDGET_SEARCH_HOSTGROUP.'.state', true))
- ->setHeader(_('Host groups'), [], 'web.search.hats.'.WIDGET_SEARCH_HOSTGROUP.'.state')
- ->setFooter(new CList([
- _s('Displaying %1$s of %2$s found', count($data['host_groups']), $data['total_host_groups_cnt'])
- ]));
+$sections[] = (new CSectionCollapsible($table))
+ ->setId(SECTION_SEARCH_HOSTGROUP)
+ ->setHeader(new CTag('h4', true, _('Host groups')))
+ ->setFooter(_s('Displaying %1$s of %2$s found', count($data['host_groups']), $data['total_host_groups_cnt']))
+ ->setProfileIdx('web.search.hats.'.SECTION_SEARCH_HOSTGROUP.'.state')
+ ->setExpanded((bool) CProfile::get('web.search.hats.'.SECTION_SEARCH_HOSTGROUP.'.state', true));
if ($data['admin']) {
$table = (new CTableInfo())
@@ -359,13 +357,12 @@ if ($data['admin']) {
]);
}
- $widgets[] = (new CCollapsibleUiWidget(WIDGET_SEARCH_TEMPLATES, $table))
- ->addClass(ZBX_STYLE_DASHBOARD_WIDGET_FLUID)
- ->setExpanded((bool) CProfile::get('web.search.hats.'.WIDGET_SEARCH_TEMPLATES.'.state', true))
- ->setHeader(_('Templates'), [], 'web.search.hats.'.WIDGET_SEARCH_TEMPLATES.'.state')
- ->setFooter(new CList([
- _s('Displaying %1$s of %2$s found', count($data['templates']), $data['total_templates_cnt'])
- ]));
+ $sections[] = (new CSectionCollapsible($table))
+ ->setId(SECTION_SEARCH_TEMPLATES)
+ ->setHeader(new CTag('h4', true, _('Templates')))
+ ->setFooter(_s('Displaying %1$s of %2$s found', count($data['templates']), $data['total_templates_cnt']))
+ ->setProfileIdx('web.search.hats.'.SECTION_SEARCH_TEMPLATES.'.state')
+ ->setExpanded((bool) CProfile::get('web.search.hats.'.SECTION_SEARCH_TEMPLATES.'.state', true));
}
$table = (new CTableInfo())
@@ -404,18 +401,19 @@ foreach ($data['template_groups'] as $groupid => $group) {
$table->addRow([$name_link, $templates_link]);
}
-$widgets[] = (new CCollapsibleUiWidget(WIDGET_SEARCH_TEMPLATEGROUP, $table))
- ->addClass(ZBX_STYLE_DASHBOARD_WIDGET_FLUID)
- ->setExpanded((bool) CProfile::get('web.search.hats.'.WIDGET_SEARCH_TEMPLATEGROUP.'.state', true))
- ->setHeader(_('Template groups'), [], 'web.search.hats.'.WIDGET_SEARCH_TEMPLATEGROUP.'.state')
- ->setFooter(new CList([
+$sections[] = (new CSectionCollapsible($table))
+ ->setId(SECTION_SEARCH_TEMPLATEGROUP)
+ ->setHeader(new CTag('h4', true, _('Template groups')))
+ ->setFooter(
_s('Displaying %1$s of %2$s found', count($data['template_groups']), $data['total_template_groups_cnt'])
- ]));
+ )
+ ->setProfileIdx('web.search.hats.'.SECTION_SEARCH_TEMPLATEGROUP.'.state')
+ ->setExpanded((bool) CProfile::get('web.search.hats.'.SECTION_SEARCH_TEMPLATEGROUP.'.state', true));
-(new CWidget())
+(new CHtmlPage())
->setTitle(_('Search').': '.$data['search'])
->setDocUrl(CDocHelper::getUrl(CDocHelper::SEARCH))
- ->addItem(new CDiv($widgets))
+ ->addItem(new CDiv($sections))
->show();
(new CScriptTag('view.init();'))
diff --git a/ui/app/views/service.list.edit.php b/ui/app/views/service.list.edit.php
index 0204c4dd2cb..c3af2b06971 100644
--- a/ui/app/views/service.list.edit.php
+++ b/ui/app/views/service.list.edit.php
@@ -119,7 +119,7 @@ $filter->addFilterTab(_('Filter'), [
])
]);
-(new CWidget())
+(new CHtmlPage())
->setTitle(_('Services'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::SERVICES_SERVICE_EDIT))
->setControls(
diff --git a/ui/app/views/service.list.php b/ui/app/views/service.list.php
index c7ef9a32212..b82e443341c 100644
--- a/ui/app/views/service.list.php
+++ b/ui/app/views/service.list.php
@@ -101,7 +101,7 @@ if ($web_layout_mode == ZBX_LAYOUT_NORMAL) {
]);
}
-(new CWidget())
+(new CHtmlPage())
->setTitle(_('Services'))
->setWebLayoutMode($web_layout_mode)
->setDocUrl(CDocHelper::getUrl(CDocHelper::SERVICES_SERVICE_LIST))
diff --git a/ui/app/views/sla.list.php b/ui/app/views/sla.list.php
index 67e1ecc8461..41b76b4206a 100644
--- a/ui/app/views/sla.list.php
+++ b/ui/app/views/sla.list.php
@@ -181,7 +181,7 @@ if ($data['has_access'][CRoleHelper::ACTIONS_MANAGE_SLA]) {
);
}
-(new CWidget())
+(new CHtmlPage())
->setTitle(_('SLA'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::SERVICES_SLA_LIST))
->setControls(
diff --git a/ui/app/views/slareport.list.php b/ui/app/views/slareport.list.php
index 6e4865306b4..7d534b1b4d3 100644
--- a/ui/app/views/slareport.list.php
+++ b/ui/app/views/slareport.list.php
@@ -88,7 +88,7 @@ $filter = (new CFilter())
])
]);
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('SLA report'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::SERVICES_SLAREPORT_LIST))
->addItem($filter);
@@ -196,7 +196,7 @@ else {
$form->addItem($report);
}
-$widget
+$html_page
->addItem($form)
->show();
diff --git a/ui/app/views/system.warning.php b/ui/app/views/system.warning.php
index a03ab3f4061..20543ac8a3b 100644
--- a/ui/app/views/system.warning.php
+++ b/ui/app/views/system.warning.php
@@ -21,11 +21,15 @@
/**
* @var CView $this
+ * @var array $data
*/
-$pageHeader = (new CPageHeader(_('Fatal error, please report to the Zabbix team'), CWebUser::getLang()))
- ->addCssFile('assets/styles/'.CHtml::encode($data['theme']).'.css')
- ->display();
+$page_header = (new CHtmlPageHeader(_('Fatal error, please report to the Zabbix team'), CWebUser::getLang()));
+
+$page_header
+ ->setTheme($data['theme'])
+ ->addCssFile('assets/styles/'.$page_header->getTheme().'.css')
+ ->show();
$buttons = [
(new CButton('back', _s('Go to "%1$s"', CMenuHelper::getFirstLabel())))
diff --git a/ui/app/views/widget.edit.php b/ui/app/views/widget.edit.php
new file mode 100755
index 00000000000..8a57fcd6fb4
--- /dev/null
+++ b/ui/app/views/widget.edit.php
@@ -0,0 +1,29 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+/**
+ * Widget default form view.
+ *
+ * @var CView $this
+ * @var array $data
+ */
+
+(new CWidgetFormView($data))->show();
diff --git a/ui/app/views/widget.view.php b/ui/app/views/widget.view.php
new file mode 100755
index 00000000000..deb9f49f584
--- /dev/null
+++ b/ui/app/views/widget.view.php
@@ -0,0 +1,29 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+/**
+ * Widget default view.
+ *
+ * @var CView $this
+ * @var array $data
+ */
+
+(new CWidgetView($data))->show();
diff --git a/ui/assets/styles/blue-theme.css b/ui/assets/styles/blue-theme.css
index 0565707ee38..d59fa10f67e 100644
--- a/ui/assets/styles/blue-theme.css
+++ b/ui/assets/styles/blue-theme.css
@@ -336,7 +336,9 @@ svg a {
top: 0;
left: 0;
transition: left .2s, top .2s; }
- .sortable .sortable-list .sortable-item:not(.sortable-dragging) {
+ .sortable .sortable-item {
+ box-sizing: border-box; }
+ .sortable .sortable-item:not(.sortable-dragging) {
transition: left .2s, top .2s; }
.sortable.sortable-dragging .sortable-item {
position: absolute; }
@@ -654,7 +656,6 @@ footer {
.form-grid {
display: grid;
- padding: 5px;
row-gap: 10px;
column-gap: 10px;
grid-template-columns: minmax(15%, max-content) auto; }
@@ -670,6 +671,9 @@ footer {
word-wrap: break-word; }
.form-grid > label.fields-group-label {
padding-top: 5px; }
+ .form-grid > label .icon-help-hint,
+ .form-grid > label .icon-info {
+ margin-left: 5px; }
.form-grid > .form-field,
.form-grid > .field-fluid,
.form-grid .form-actions {
@@ -872,6 +876,66 @@ footer {
.color-picker-dialogue .color-picker-input input {
padding-left: 25px; }
+.columns-wrapper {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: start; }
+ .columns-wrapper.columns-nowrap {
+ flex-wrap: nowrap; }
+ .columns-wrapper.columns-2 > div,
+ .columns-wrapper.columns-2 > li {
+ display: block;
+ flex: 0 0 50%;
+ max-width: 50%; }
+ .columns-wrapper.columns-3 > div,
+ .columns-wrapper.columns-3 > li {
+ display: block;
+ flex: 0 0 33.33333%;
+ max-width: 33.33333%; }
+ .columns-wrapper .column-5 {
+ flex: 0 0 5%;
+ max-width: 5%; }
+ .columns-wrapper .column-10 {
+ flex: 0 0 10%;
+ max-width: 10%; }
+ .columns-wrapper .column-15 {
+ flex: 0 0 15%;
+ max-width: 15%; }
+ .columns-wrapper .column-20 {
+ flex: 0 0 20%;
+ max-width: 20%; }
+ .columns-wrapper .column-33 {
+ flex: 0 0 33.33333%;
+ max-width: 33.33333%; }
+ .columns-wrapper .column-35 {
+ flex: 0 0 35%;
+ max-width: 35%; }
+ .columns-wrapper .column-40 {
+ flex: 0 0 40%;
+ max-width: 40%; }
+ .columns-wrapper .column-50 {
+ flex: 0 0 50%;
+ max-width: 50%; }
+ .columns-wrapper .column-75 {
+ flex: 0 0 75%;
+ max-width: 75%; }
+ .columns-wrapper .column-90 {
+ flex: 0 0 90%;
+ max-width: 90%; }
+ .columns-wrapper .column-95 {
+ flex: 0 0 95%;
+ max-width: 95%; }
+ .columns-wrapper .column-center {
+ display: flex;
+ justify-content: center;
+ text-align: center; }
+ .columns-wrapper .column-middle {
+ display: flex;
+ align-items: center; }
+ .columns-wrapper > div:not(:last-child) section,
+ .columns-wrapper > ul:not(:last-child) section {
+ margin-right: 10px; }
+
.header-kioskmode-controls .dashboard-kioskmode-controls li {
margin-right: 6px; }
@@ -1421,8 +1485,6 @@ footer {
.dashboard-widget .msg-good,
.dashboard-widget .msg-warning {
margin: 0 10px; }
- .dashboard-widget.dashboard-widget-fluid {
- margin-right: 0; }
.dashboard-grid-widget-content .list-table th:first-child, .dashboard-grid-widget-content .list-table td:first-child, .dashboard-grid-iterator.iterator-alt-content .dashboard-grid-iterator-content > div .list-table th:first-child, .dashboard-grid-iterator.iterator-alt-content .dashboard-grid-iterator-content > div .list-table td:first-child, .dashboard-widget .list-table th:first-child, .dashboard-widget .list-table td:first-child, .overlay-dialogue .list-table th:first-child, .overlay-dialogue .list-table td:first-child {
padding-left: 10px; }
@@ -1483,30 +1545,22 @@ footer {
.wrapper.layout-kioskmode .dashboard-navigation {
display: none; }
-form.dashboard-widget-clock .fields-group-date,
-form.dashboard-widget-clock .fields-group-time,
-form.dashboard-widget-clock .fields-group-tzone {
+form.dashboard-widget-clock .fields-group.fields-group-date, form.dashboard-widget-clock .fields-group.fields-group-time, form.dashboard-widget-clock .fields-group.fields-group-tzone {
display: grid;
grid-template-columns: 60px 120px repeat(2, minmax(60px, max-content) auto);
align-items: center;
column-gap: 10px;
row-gap: 5px; }
- form.dashboard-widget-clock .fields-group-date label,
- form.dashboard-widget-clock .fields-group-time label,
- form.dashboard-widget-clock .fields-group-tzone label {
+ form.dashboard-widget-clock .fields-group.fields-group-date label, form.dashboard-widget-clock .fields-group.fields-group-time label, form.dashboard-widget-clock .fields-group.fields-group-tzone label {
text-align: right; }
- form.dashboard-widget-clock .fields-group-date .field-size input,
- form.dashboard-widget-clock .fields-group-time .field-size input,
- form.dashboard-widget-clock .fields-group-tzone .field-size input {
+ form.dashboard-widget-clock .fields-group.fields-group-date .field-size input, form.dashboard-widget-clock .fields-group.fields-group-time .field-size input, form.dashboard-widget-clock .fields-group.fields-group-tzone .field-size input {
margin-right: 5px; }
-form.dashboard-widget-clock .fields-group-time .field-format {
+form.dashboard-widget-clock .fields-group.fields-group-time .field-format {
grid-column: 4 / -1; }
-form.dashboard-widget-clock .fields-group-tzone .field-format {
- grid-column: 2 / -1; }
-form.dashboard-widget-clock .fields-group-tzone .field-timezone {
+form.dashboard-widget-clock .fields-group.fields-group-tzone .form-field.field-tzone-timezone, form.dashboard-widget-clock .fields-group.fields-group-tzone .form-field.field-tzone-format {
grid-column: 2 / -1; }
-div.dashboard-widget-clock.clock-digital {
+div.dashboard-widget-clock .clock-digital {
box-sizing: border-box;
min-height: 100%;
padding: 10px;
@@ -1514,9 +1568,9 @@ div.dashboard-widget-clock.clock-digital {
flex-direction: column;
justify-content: center;
align-items: center; }
- div.dashboard-widget-clock.clock-digital .clock-date,
- div.dashboard-widget-clock.clock-digital .clock-time,
- div.dashboard-widget-clock.clock-digital .clock-time-zone {
+ div.dashboard-widget-clock .clock-digital .clock-date,
+ div.dashboard-widget-clock .clock-digital .clock-time,
+ div.dashboard-widget-clock .clock-digital .clock-time-zone {
max-width: 100%;
white-space: nowrap;
overflow: hidden;
@@ -1524,150 +1578,137 @@ div.dashboard-widget-clock.clock-digital {
font-size: calc(var(--content-height) * var(--widget-clock-font) / 1.14);
line-height: 1.14;
flex-shrink: 0; }
- div.dashboard-widget-clock.clock-digital .bold {
+ div.dashboard-widget-clock .clock-digital .bold {
font-weight: bold; }
- div.dashboard-widget-clock.clock-digital .clock-disabled {
+ div.dashboard-widget-clock .clock-digital .clock-disabled {
font-size: calc(var(--content-height) * 0.6 / 1.14);
color: #768d99;
font-weight: bold; }
-form.dashboard-widget-item .fields-group-description,
-form.dashboard-widget-item .fields-group-value,
-form.dashboard-widget-item .fields-group-time,
-form.dashboard-widget-item .fields-group-change-indicator {
+.dashboard-widget-inaccessible {
+ display: grid;
+ align-items: center;
+ padding-right: 10px;
+ padding-left: 10px;
+ text-align: center;
+ color: #768d99; }
+
+form.dashboard-widget-item .fields-group.fields-group-description, form.dashboard-widget-item .fields-group.fields-group-value, form.dashboard-widget-item .fields-group.fields-group-time, form.dashboard-widget-item .fields-group.fields-group-change-indicator {
display: grid;
grid-template-columns: minmax(100px, max-content) 3fr max-content auto;
align-items: center;
column-gap: 10px;
row-gap: 5px; }
- form.dashboard-widget-item .fields-group-description label,
- form.dashboard-widget-item .fields-group-value label,
- form.dashboard-widget-item .fields-group-time label,
- form.dashboard-widget-item .fields-group-change-indicator label {
+ form.dashboard-widget-item .fields-group.fields-group-description label, form.dashboard-widget-item .fields-group.fields-group-value label, form.dashboard-widget-item .fields-group.fields-group-time label, form.dashboard-widget-item .fields-group.fields-group-change-indicator label {
text-align: right; }
- form.dashboard-widget-item .fields-group-description hr,
- form.dashboard-widget-item .fields-group-value hr,
- form.dashboard-widget-item .fields-group-time hr,
- form.dashboard-widget-item .fields-group-change-indicator hr {
+ form.dashboard-widget-item .fields-group.fields-group-description hr, form.dashboard-widget-item .fields-group.fields-group-value hr, form.dashboard-widget-item .fields-group.fields-group-time hr, form.dashboard-widget-item .fields-group.fields-group-change-indicator hr {
grid-column: 1 / -1;
margin: 0;
width: 100%;
border: solid #ebeef0;
border-width: 1px 0 0 0; }
- form.dashboard-widget-item .fields-group-description .field-fluid,
- form.dashboard-widget-item .fields-group-value .field-fluid,
- form.dashboard-widget-item .fields-group-time .field-fluid,
- form.dashboard-widget-item .fields-group-change-indicator .field-fluid {
+ form.dashboard-widget-item .fields-group.fields-group-description .field-fluid, form.dashboard-widget-item .fields-group.fields-group-value .field-fluid, form.dashboard-widget-item .fields-group.fields-group-time .field-fluid, form.dashboard-widget-item .fields-group.fields-group-change-indicator .field-fluid {
grid-column: 2 / -1; }
- form.dashboard-widget-item .fields-group-description .offset-3,
- form.dashboard-widget-item .fields-group-value .offset-3,
- form.dashboard-widget-item .fields-group-time .offset-3,
- form.dashboard-widget-item .fields-group-change-indicator .offset-3 {
+ form.dashboard-widget-item .fields-group.fields-group-description .offset-3, form.dashboard-widget-item .fields-group.fields-group-value .offset-3, form.dashboard-widget-item .fields-group.fields-group-time .offset-3, form.dashboard-widget-item .fields-group.fields-group-change-indicator .offset-3 {
grid-column-start: 3; }
- form.dashboard-widget-item .fields-group-description .field-size input,
- form.dashboard-widget-item .fields-group-value .field-size input,
- form.dashboard-widget-item .fields-group-time .field-size input,
- form.dashboard-widget-item .fields-group-change-indicator .field-size input {
+ form.dashboard-widget-item .fields-group.fields-group-description .field-size input, form.dashboard-widget-item .fields-group.fields-group-value .field-size input, form.dashboard-widget-item .fields-group.fields-group-time .field-size input, form.dashboard-widget-item .fields-group.fields-group-change-indicator .field-size input {
margin-right: 5px; }
- form.dashboard-widget-item .fields-group-description .form-field,
- form.dashboard-widget-item .fields-group-value .form-field,
- form.dashboard-widget-item .fields-group-time .form-field,
- form.dashboard-widget-item .fields-group-change-indicator .form-field {
+ form.dashboard-widget-item .fields-group.fields-group-description .form-field, form.dashboard-widget-item .fields-group.fields-group-value .form-field, form.dashboard-widget-item .fields-group.fields-group-time .form-field, form.dashboard-widget-item .fields-group.fields-group-change-indicator .form-field {
line-height: 24px; }
-form.dashboard-widget-item .fields-group-description .form-field:nth-child(1) {
+form.dashboard-widget-item .fields-group.fields-group-description .form-field:nth-child(1) {
grid-column: 1 / -1; }
-form.dashboard-widget-item .fields-group-value {
+form.dashboard-widget-item .fields-group.fields-group-value {
grid-template-columns: minmax(100px, max-content) 3fr max-content auto; }
- form.dashboard-widget-item .fields-group-value .units-show {
+ form.dashboard-widget-item .fields-group.fields-group-value .units-show {
display: flex; }
- form.dashboard-widget-item .fields-group-value .units-show label[for='units'] {
+ form.dashboard-widget-item .fields-group.fields-group-value .units-show label[for='units'] {
width: 100%; }
-form.dashboard-widget-item .fields-group-change-indicator {
+form.dashboard-widget-item .fields-group.fields-group-change-indicator {
grid-template-columns: repeat(3, max-content 96px); }
-form.dashboard-widget-item .fields-group-change-indicator .input-color-picker {
- display: block; }
+ form.dashboard-widget-item .fields-group.fields-group-change-indicator .input-color-picker {
+ display: block; }
-div.dashboard-widget-item {
+div.dashboard-widget-item > div {
box-sizing: border-box;
height: 100%;
padding: 10px;
overflow-x: hidden; }
- div.dashboard-widget-item a {
- box-sizing: border-box;
- display: flex;
- flex-direction: column;
- height: 100%;
- color: inherit; }
- div.dashboard-widget-item a:focus, div.dashboard-widget-item a:hover, div.dashboard-widget-item a:visited {
- border: none; }
- div.dashboard-widget-item a > div {
- display: flex;
- flex: 1 1 calc(100% / 3); }
- div.dashboard-widget-item .item-description,
- div.dashboard-widget-item .item-value,
- div.dashboard-widget-item .item-time {
- flex: 1 1 auto;
- max-width: 100%; }
- div.dashboard-widget-item .item-value {
+div.dashboard-widget-item a {
+ box-sizing: border-box;
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ color: inherit; }
+ div.dashboard-widget-item a:focus, div.dashboard-widget-item a:hover, div.dashboard-widget-item a:visited {
+ border: none; }
+ div.dashboard-widget-item a > div {
display: flex;
- flex-wrap: wrap;
- margin: 0 5px; }
- div.dashboard-widget-item .item-value > .units:first-child, div.dashboard-widget-item .item-value > .units:last-child {
- flex: 0 0 100%; }
- div.dashboard-widget-item .item-value > .units:first-child {
- margin-bottom: -0.07em; }
- div.dashboard-widget-item .item-value > .units:last-child {
- margin-top: -0.07em; }
- div.dashboard-widget-item .item-value.type-text {
+ flex: 1 1 calc(100% / 3); }
+div.dashboard-widget-item .item-description,
+div.dashboard-widget-item .item-value,
+div.dashboard-widget-item .item-time {
+ flex: 1 1 auto;
+ max-width: 100%; }
+div.dashboard-widget-item .item-value {
+ display: flex;
+ flex-wrap: wrap;
+ margin: 0 5px; }
+ div.dashboard-widget-item .item-value > .units:first-child, div.dashboard-widget-item .item-value > .units:last-child {
+ flex: 0 0 100%; }
+ div.dashboard-widget-item .item-value > .units:first-child {
+ margin-bottom: -0.07em; }
+ div.dashboard-widget-item .item-value > .units:last-child {
+ margin-top: -0.07em; }
+ div.dashboard-widget-item .item-value.type-text {
+ min-width: 0; }
+ div.dashboard-widget-item .item-value.type-text .item-value-content {
min-width: 0; }
- div.dashboard-widget-item .item-value.type-text .item-value-content {
- min-width: 0; }
- div.dashboard-widget-item .item-value-content {
- display: flex;
- align-items: baseline;
- overflow: hidden; }
- div.dashboard-widget-item .item-description,
- div.dashboard-widget-item .item-time,
- div.dashboard-widget-item .type-text .value {
- display: block;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis; }
- div.dashboard-widget-item .item-description,
- div.dashboard-widget-item .value,
- div.dashboard-widget-item .decimals,
- div.dashboard-widget-item .units,
- div.dashboard-widget-item .item-time {
- font-size: calc(var(--content-height) * var(--widget-item-font) / 1.14);
- line-height: 1.14; }
- div.dashboard-widget-item .units:not(:last-child),
- div.dashboard-widget-item .change-indicator:not(:last-child) {
- margin-right: 5px; }
- div.dashboard-widget-item .units:not(:first-child),
- div.dashboard-widget-item .change-indicator:not(:first-child) {
- margin-left: 5px; }
- div.dashboard-widget-item .svg-arrow {
- height: calc(var(--content-height) * var(--widget-item-font) * 0.72 / 1.14); }
- div.dashboard-widget-item .item-value-no-data {
- color: #768d99; }
- div.dashboard-widget-item .left {
- justify-content: flex-start;
- max-width: max-content;
- margin-right: auto; }
- div.dashboard-widget-item .center {
- justify-content: center; }
- div.dashboard-widget-item .right {
- justify-content: flex-end;
- max-width: max-content;
- margin-left: auto; }
- div.dashboard-widget-item .top {
- align-self: flex-start; }
- div.dashboard-widget-item .middle {
- align-self: center; }
- div.dashboard-widget-item .bottom {
- align-self: flex-end; }
- div.dashboard-widget-item .bold {
- font-weight: bold; }
+div.dashboard-widget-item .item-value-content {
+ display: flex;
+ align-items: baseline;
+ overflow: hidden; }
+div.dashboard-widget-item .item-description,
+div.dashboard-widget-item .item-time,
+div.dashboard-widget-item .type-text .value {
+ display: block;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis; }
+div.dashboard-widget-item .item-description,
+div.dashboard-widget-item .value,
+div.dashboard-widget-item .decimals,
+div.dashboard-widget-item .units,
+div.dashboard-widget-item .item-time {
+ font-size: calc(var(--content-height) * var(--widget-item-font) / 1.14);
+ line-height: 1.14; }
+div.dashboard-widget-item .units:not(:last-child),
+div.dashboard-widget-item .change-indicator:not(:last-child) {
+ margin-right: 5px; }
+div.dashboard-widget-item .units:not(:first-child),
+div.dashboard-widget-item .change-indicator:not(:first-child) {
+ margin-left: 5px; }
+div.dashboard-widget-item .svg-arrow {
+ height: calc(var(--content-height) * var(--widget-item-font) * 0.72 / 1.14); }
+div.dashboard-widget-item .item-value-no-data {
+ color: #768d99; }
+div.dashboard-widget-item .left {
+ justify-content: flex-start;
+ max-width: max-content;
+ margin-right: auto; }
+div.dashboard-widget-item .center {
+ justify-content: center; }
+div.dashboard-widget-item .right {
+ justify-content: flex-end;
+ max-width: max-content;
+ margin-left: auto; }
+div.dashboard-widget-item .top {
+ align-self: flex-start; }
+div.dashboard-widget-item .middle {
+ align-self: center; }
+div.dashboard-widget-item .bottom {
+ align-self: flex-end; }
+div.dashboard-widget-item .bold {
+ font-weight: bold; }
.dashboard-widget-item .svg-arrow-up {
fill: #3DC51D; }
@@ -1680,40 +1721,47 @@ div.dashboard-widget-slareport .date-vertical {
writing-mode: vertical-lr;
transform: rotate(180deg); }
+form.dashboard-widget-svggraph .svg-graph-preview,
form.dashboard-widget-svggraph .graph-widget-config-tabs {
- padding: 10px 0; }
- form.dashboard-widget-svggraph .graph-widget-config-tabs > .tabs-nav {
- margin-right: 0;
- margin-left: 0;
- border-top: 1px solid #dfe4e7; }
- form.dashboard-widget-svggraph .graph-widget-config-tabs .ui-tabs-nav {
- position: sticky;
+ grid-column: 1 / -1; }
+form.dashboard-widget-svggraph .svg-graph-preview {
+ position: relative;
+ min-width: 1110px;
+ height: 300px; }
+ form.dashboard-widget-svggraph .svg-graph-preview > div {
+ position: absolute;
top: 0;
+ right: 0;
+ left: 0;
+ margin: 0 -10px;
+ height: 300px;
background: #ffffff;
z-index: 3; }
+form.dashboard-widget-svggraph .graph-widget-config-tabs > .tabs-nav {
+ border-top: 1px solid #dfe4e7; }
+form.dashboard-widget-svggraph .graph-widget-config-tabs .ui-tabs-nav {
+ position: sticky;
+ top: 0;
+ background: #ffffff;
+ z-index: 3; }
form.dashboard-widget-svggraph .table-forms-container, form.dashboard-widget-svggraph .browser-warning-container {
+ margin: -10px 0 0 0;
border: 1px solid #dfe4e7;
border-top: none; }
form.dashboard-widget-svggraph .table-forms-separator {
padding: 0; }
-form.dashboard-widget-svggraph .dataset-head {
- display: grid;
- grid-template-columns: 24px 24px 1fr 1fr 24px;
- grid-gap: 10px;
- align-items: start; }
+form.dashboard-widget-svggraph .dataset-head,
form.dashboard-widget-svggraph .dataset-body.list-accordion-item-body {
- display: grid;
- grid-template-columns: 24px 1fr 1fr 24px;
- grid-gap: 10px;
- align-items: start;
- position: relative;
- margin-top: 10px; }
- form.dashboard-widget-svggraph .dataset-body.list-accordion-item-body .form-grid {
- padding-top: 0; }
- form.dashboard-widget-svggraph .dataset-body.list-accordion-item-body .form-grid:first-child {
- grid-column-start: 2; }
+ display: contents; }
+form.dashboard-widget-svggraph .dataset-head .multiselect {
+ width: 100%; }
+form.dashboard-widget-svggraph .dataset-body .form-grid {
+ padding-top: 0; }
+ form.dashboard-widget-svggraph .dataset-body .form-grid:first-child {
+ grid-column-start: 3; }
form.dashboard-widget-svggraph .drag-icon {
position: absolute;
+ top: 5px;
left: -14px; }
form.dashboard-widget-svggraph .td-drag-icon .drag-icon {
top: 0;
@@ -1735,13 +1783,13 @@ form.dashboard-widget-svggraph .list-vertical-accordion {
overflow: visible;
margin-top: -5px;
margin-bottom: -5px; }
- form.dashboard-widget-svggraph .list-vertical-accordion .list-accordion-item-head {
- padding: 0; }
form.dashboard-widget-svggraph .list-accordion-item {
position: relative;
- width: 100%;
- padding: 5px 0;
- list-style-type: none; }
+ display: grid;
+ grid-template-columns: 24px 24px 1fr 1fr 24px;
+ grid-gap: 10px;
+ align-items: start;
+ padding: 5px 0; }
form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-opened::before {
content: ' ';
position: absolute;
@@ -1753,8 +1801,6 @@ form.dashboard-widget-svggraph .list-accordion-item {
form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .multiselect {
height: 24px;
overflow: hidden; }
- form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .dataset-body {
- display: none; }
form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .dataset-head .table-forms-separator {
border: none; }
form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .dataset-head .single-item-table thead,
@@ -1762,6 +1808,8 @@ form.dashboard-widget-svggraph .list-accordion-item {
form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .dataset-head .single-item-table .table-col-handle,
form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .dataset-head .single-item-table .table-col-action {
display: none; }
+ form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .dataset-body {
+ display: none; }
form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .items-list {
padding-left: 0; }
form.dashboard-widget-svggraph .single-item-table .table-col-handle {
@@ -1780,11 +1828,83 @@ form.dashboard-widget-svggraph .single-item-table .single-item-table-row:last-ch
padding-bottom: 0; }
form.dashboard-widget-svggraph .single-item-table tfoot td {
padding: 5px 5px 5px 10px; }
+form.dashboard-widget-svggraph .overrides-list {
+ position: relative;
+ margin: -5px 0 -5px 15px; }
+form.dashboard-widget-svggraph .overrides-list-item {
+ position: relative;
+ display: grid;
+ grid-template-columns: 1fr 1fr 24px;
+ grid-gap: 5px 10px;
+ align-items: start;
+ padding: 5px 0; }
+ form.dashboard-widget-svggraph .overrides-list-item.sortable {
+ overflow: visible;
+ margin-top: -5px;
+ margin-bottom: -5px; }
+ form.dashboard-widget-svggraph .overrides-list-item .multiselect {
+ width: 100%; }
+ form.dashboard-widget-svggraph .overrides-list-item .btn-remove {
+ right: 0;
+ top: 0;
+ vertical-align: baseline; }
+form.dashboard-widget-svggraph .overrides-foot {
+ padding: 5px 0; }
+form.dashboard-widget-svggraph .overrides-options-list {
+ grid-column: 1 / -1;
+ padding: 0 24px 8px 0;
+ border-bottom: 1px solid #ebeef0;
+ white-space: normal; }
+ form.dashboard-widget-svggraph .overrides-options-list > li {
+ display: inline-block;
+ margin-right: 5px;
+ margin-bottom: 2px;
+ line-height: 22px;
+ white-space: nowrap; }
+ form.dashboard-widget-svggraph .overrides-options-list > li .color-picker {
+ line-height: 22px; }
+ form.dashboard-widget-svggraph .overrides-options-list > li > div {
+ position: relative;
+ padding: 1px 18px 1px 1px;
+ background-color: #768d99;
+ border-radius: 2px; }
+ form.dashboard-widget-svggraph .overrides-options-list > li > div > span {
+ color: white;
+ padding-left: 8px;
+ line-height: 22px; }
+ form.dashboard-widget-svggraph .overrides-options-list > li > div > input[type=text] {
+ border-style: none;
+ line-height: 22px;
+ min-height: 22px;
+ width: 85px; }
+ form.dashboard-widget-svggraph .overrides-options-list > li > div > .subfilter-disable-btn {
+ position: absolute;
+ right: 0;
+ top: 0;
+ min-height: 24px; }
+ form.dashboard-widget-svggraph .overrides-options-list .btn-alt .plus-icon {
+ margin-right: 0; }
+ form.dashboard-widget-svggraph .overrides-options-list .color-picker .color-picker-preview {
+ margin: 1px;
+ width: 20px;
+ min-height: 20px;
+ background-position: -323px -411px; }
form.dashboard-widget-svggraph .no-items-message {
display: none;
line-height: 24px;
color: #768d99; }
+[theme="hc-dark"] form.dashboard-widget-svggraph .overrides-options-list > li > div {
+ border: 1px solid #0275b8;
+ background-color: transparent !important; }
+ [theme="hc-dark"] form.dashboard-widget-svggraph .overrides-options-list > li > div > .subfilter-disable-btn {
+ border: none !important;
+ top: 0; }
+
+[theme="hc-light"] form.dashboard-widget-svggraph .overrides-options-list > li > div > .subfilter-disable-btn {
+ border: none !important;
+ top: 0; }
+
form.dashboard-widget-tophosts #list_columns .text {
max-width: 250px; }
form.dashboard-widget-tophosts #column {
@@ -2557,6 +2677,49 @@ div.dashboard-widget-tophosts z-bar-gauge {
font-size: 0;
border-left: 1px solid #ebeef0; }
+section {
+ background-color: #ffffff;
+ border: 1px solid #dfe4e7; }
+ section .section-head {
+ display: flex;
+ height: 32px;
+ line-height: 32px; }
+ section .section-head h4 {
+ padding: 0 10px;
+ margin-right: auto;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ font-weight: bold;
+ line-height: inherit;
+ color: #3c5563; }
+ section .section-toggle {
+ width: 24px;
+ height: 24px;
+ margin: 2px 2px 0 auto;
+ background: url("../img/icon-sprite.svg?20220722") no-repeat -6px -654px; }
+ section .section-foot {
+ padding: 0 10px;
+ text-align: right;
+ line-height: 32px;
+ color: #768d99; }
+ section.section-collapsed .section-body,
+ section.section-collapsed .section-foot {
+ display: none; }
+ section.section-collapsed .section-toggle {
+ background-position: -6px -689px; }
+ section:not(:last-child) {
+ margin-bottom: 10px; }
+ section .list-table {
+ border: 0; }
+ section .list-table tbody tr:last-child td {
+ border-bottom: 1px solid #ebeef0; }
+ section .list-table td:first-child,
+ section .list-table th:first-child {
+ padding-left: 10px; }
+ section .list-table td:last-child,
+ section .list-table th:last-child {
+ padding-right: 10px; }
+
.service-info {
margin: -10px 0;
border-left: 4px solid #429e47; }
@@ -4536,13 +4699,13 @@ button {
width: 24px;
height: 24px; }
-.filter-container.tabfilter-container .icon-edit, .btn-dashboard-page-properties, .btn-iterator-page-previous, .btn-iterator-page-next, .btn-widget-action, .btn-widget-collapse, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle, .btn-widget-expand, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle, .btn-widget-edit, .btn-alarm-on, .btn-alarm-off, .btn-sound-on, .btn-sound-off, .btn-info-clock, .btn-dashboard-conf, .interfaces .interface-row[data-type="2"] .interface-btn-toggle {
+section .section-toggle, .filter-container.tabfilter-container .icon-edit, .btn-dashboard-page-properties, .btn-iterator-page-previous, .btn-iterator-page-next, .btn-widget-action, .btn-widget-collapse, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle, .btn-widget-expand, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle, .btn-widget-edit, .btn-alarm-on, .btn-alarm-off, .btn-sound-on, .btn-sound-off, .btn-info-clock, .btn-dashboard-conf, .interfaces .interface-row[data-type="2"] .interface-btn-toggle {
border: 0;
min-height: 0;
padding: 0;
opacity: .5;
transition: opacity .2s ease-out; }
- .filter-container.tabfilter-container [disabled].icon-edit, [disabled].btn-dashboard-page-properties, [disabled].btn-iterator-page-previous, [disabled].btn-iterator-page-next, [disabled].btn-widget-action, [disabled].btn-widget-collapse, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle, [disabled].btn-widget-expand, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle, [disabled].btn-widget-edit, [disabled].btn-alarm-on, [disabled].btn-alarm-off, [disabled].btn-sound-on, [disabled].btn-sound-off, [disabled].btn-info-clock, [disabled].btn-dashboard-conf, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle, .filter-container.tabfilter-container [disabled].icon-edit:hover, [disabled].btn-dashboard-page-properties:hover, [disabled].btn-iterator-page-previous:hover, [disabled].btn-iterator-page-next:hover, [disabled].btn-widget-action:hover, [disabled].btn-widget-collapse:hover, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle:hover, [disabled].btn-widget-expand:hover, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle:hover, [disabled].btn-widget-edit:hover, [disabled].btn-alarm-on:hover, [disabled].btn-alarm-off:hover, [disabled].btn-sound-on:hover, [disabled].btn-sound-off:hover, [disabled].btn-info-clock:hover, [disabled].btn-dashboard-conf:hover, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle:hover, .filter-container.tabfilter-container [disabled].icon-edit:focus, [disabled].btn-dashboard-page-properties:focus, [disabled].btn-iterator-page-previous:focus, [disabled].btn-iterator-page-next:focus, [disabled].btn-widget-action:focus, [disabled].btn-widget-collapse:focus, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle:focus, [disabled].btn-widget-expand:focus, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle:focus, [disabled].btn-widget-edit:focus, [disabled].btn-alarm-on:focus, [disabled].btn-alarm-off:focus, [disabled].btn-sound-on:focus, [disabled].btn-sound-off:focus, [disabled].btn-info-clock:focus, [disabled].btn-dashboard-conf:focus, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle:focus, .filter-container.tabfilter-container [disabled].icon-edit:active, [disabled].btn-dashboard-page-properties:active, [disabled].btn-iterator-page-previous:active, [disabled].btn-iterator-page-next:active, [disabled].btn-widget-action:active, [disabled].btn-widget-collapse:active, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle:active, [disabled].btn-widget-expand:active, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle:active, [disabled].btn-widget-edit:active, [disabled].btn-alarm-on:active, [disabled].btn-alarm-off:active, [disabled].btn-sound-on:active, [disabled].btn-sound-off:active, [disabled].btn-info-clock:active, [disabled].btn-dashboard-conf:active, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle:active {
+ section [disabled].section-toggle, .filter-container.tabfilter-container [disabled].icon-edit, [disabled].btn-dashboard-page-properties, [disabled].btn-iterator-page-previous, [disabled].btn-iterator-page-next, [disabled].btn-widget-action, [disabled].btn-widget-collapse, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle, [disabled].btn-widget-expand, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle, [disabled].btn-widget-edit, [disabled].btn-alarm-on, [disabled].btn-alarm-off, [disabled].btn-sound-on, [disabled].btn-sound-off, [disabled].btn-info-clock, [disabled].btn-dashboard-conf, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle, section [disabled].section-toggle:hover, .filter-container.tabfilter-container [disabled].icon-edit:hover, [disabled].btn-dashboard-page-properties:hover, [disabled].btn-iterator-page-previous:hover, [disabled].btn-iterator-page-next:hover, [disabled].btn-widget-action:hover, [disabled].btn-widget-collapse:hover, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle:hover, [disabled].btn-widget-expand:hover, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle:hover, [disabled].btn-widget-edit:hover, [disabled].btn-alarm-on:hover, [disabled].btn-alarm-off:hover, [disabled].btn-sound-on:hover, [disabled].btn-sound-off:hover, [disabled].btn-info-clock:hover, [disabled].btn-dashboard-conf:hover, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle:hover, section [disabled].section-toggle:focus, .filter-container.tabfilter-container [disabled].icon-edit:focus, [disabled].btn-dashboard-page-properties:focus, [disabled].btn-iterator-page-previous:focus, [disabled].btn-iterator-page-next:focus, [disabled].btn-widget-action:focus, [disabled].btn-widget-collapse:focus, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle:focus, [disabled].btn-widget-expand:focus, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle:focus, [disabled].btn-widget-edit:focus, [disabled].btn-alarm-on:focus, [disabled].btn-alarm-off:focus, [disabled].btn-sound-on:focus, [disabled].btn-sound-off:focus, [disabled].btn-info-clock:focus, [disabled].btn-dashboard-conf:focus, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle:focus, section [disabled].section-toggle:active, .filter-container.tabfilter-container [disabled].icon-edit:active, [disabled].btn-dashboard-page-properties:active, [disabled].btn-iterator-page-previous:active, [disabled].btn-iterator-page-next:active, [disabled].btn-widget-action:active, [disabled].btn-widget-collapse:active, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle:active, [disabled].btn-widget-expand:active, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle:active, [disabled].btn-widget-edit:active, [disabled].btn-alarm-on:active, [disabled].btn-alarm-off:active, [disabled].btn-sound-on:active, [disabled].btn-sound-off:active, [disabled].btn-info-clock:active, [disabled].btn-dashboard-conf:active, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle:active {
background-color: transparent;
opacity: .25; }
@@ -4570,7 +4733,7 @@ button[disabled], button[disabled]:hover, button[disabled]:active {
.inaccessible .subfilter-enabled {
color: #bfbfbf; }
-.filter-container.tabfilter-container .icon-edit:hover, .btn-dashboard-page-properties:hover, .btn-iterator-page-previous:hover, .btn-iterator-page-next:hover, .btn-widget-action:hover, .btn-widget-collapse:hover, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle:hover, .btn-widget-expand:hover, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle:hover, .btn-widget-edit:hover, .btn-alarm-on:hover, .btn-alarm-off:hover, .btn-sound-on:hover, .btn-sound-off:hover, .btn-info-clock:hover, .btn-dashboard-conf:hover, .interfaces .interface-row[data-type="2"] .interface-btn-toggle:hover, .filter-container.tabfilter-container .icon-edit:focus, .btn-dashboard-page-properties:focus, .btn-iterator-page-previous:focus, .btn-iterator-page-next:focus, .btn-widget-action:focus, .btn-widget-collapse:focus, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle:focus, .btn-widget-expand:focus, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle:focus, .btn-widget-edit:focus, .btn-alarm-on:focus, .btn-alarm-off:focus, .btn-sound-on:focus, .btn-sound-off:focus, .btn-info-clock:focus, .btn-dashboard-conf:focus, .interfaces .interface-row[data-type="2"] .interface-btn-toggle:focus, .filter-container.tabfilter-container .icon-edit:active, .btn-dashboard-page-properties:active, .btn-iterator-page-previous:active, .btn-iterator-page-next:active, .btn-widget-action:active, .btn-widget-collapse:active, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle:active, .btn-widget-expand:active, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle:active, .btn-widget-edit:active, .btn-alarm-on:active, .btn-alarm-off:active, .btn-sound-on:active, .btn-sound-off:active, .btn-info-clock:active, .btn-dashboard-conf:active, .interfaces .interface-row[data-type="2"] .interface-btn-toggle:active {
+section .section-toggle:hover, .filter-container.tabfilter-container .icon-edit:hover, .btn-dashboard-page-properties:hover, .btn-iterator-page-previous:hover, .btn-iterator-page-next:hover, .btn-widget-action:hover, .btn-widget-collapse:hover, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle:hover, .btn-widget-expand:hover, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle:hover, .btn-widget-edit:hover, .btn-alarm-on:hover, .btn-alarm-off:hover, .btn-sound-on:hover, .btn-sound-off:hover, .btn-info-clock:hover, .btn-dashboard-conf:hover, .interfaces .interface-row[data-type="2"] .interface-btn-toggle:hover, section .section-toggle:focus, .filter-container.tabfilter-container .icon-edit:focus, .btn-dashboard-page-properties:focus, .btn-iterator-page-previous:focus, .btn-iterator-page-next:focus, .btn-widget-action:focus, .btn-widget-collapse:focus, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle:focus, .btn-widget-expand:focus, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle:focus, .btn-widget-edit:focus, .btn-alarm-on:focus, .btn-alarm-off:focus, .btn-sound-on:focus, .btn-sound-off:focus, .btn-info-clock:focus, .btn-dashboard-conf:focus, .interfaces .interface-row[data-type="2"] .interface-btn-toggle:focus, section .section-toggle:active, .filter-container.tabfilter-container .icon-edit:active, .btn-dashboard-page-properties:active, .btn-iterator-page-previous:active, .btn-iterator-page-next:active, .btn-widget-action:active, .btn-widget-collapse:active, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle:active, .btn-widget-expand:active, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle:active, .btn-widget-edit:active, .btn-alarm-on:active, .btn-alarm-off:active, .btn-sound-on:active, .btn-sound-off:active, .btn-info-clock:active, .btn-dashboard-conf:active, .interfaces .interface-row[data-type="2"] .interface-btn-toggle:active {
background-color: transparent;
opacity: 1; }
@@ -4663,16 +4826,16 @@ button[disabled], button[disabled]:hover, button[disabled]:active {
content: ''; }
.icon-tree-top-bottom::before {
- background-position: url("../img/icon-sprite.svg?20220722") no-repeat -84px -300px; }
+ background-position: -84px -300px; }
.icon-tree-top-bottom-right::before {
- background-position: url("../img/icon-sprite.svg?20220722") no-repeat -84px -334px; }
+ background-position: -84px -334px; }
.icon-tree-top-right::before {
- background-position: url("../img/icon-sprite.svg?20220722") no-repeat -84px -372px; }
+ background-position: -84px -372px; }
.icon-tree-empty::before {
- background-position: url("../img/icon-sprite.svg?20220722") no-repeat -84px -350px; }
+ background-position: -84px -350px; }
.icon-cal {
background: transparent url("../img/icon-sprite.svg?20220722") no-repeat -42px -834px; }
@@ -4953,7 +5116,7 @@ button[disabled], button[disabled]:hover, button[disabled]:active {
overflow: hidden;
margin: 0 10px; }
.overlay-dialogue.modal .dashboard-widget-head {
- margin-bottom: 14px; }
+ margin-bottom: 12px; }
.overlay-dialogue.modal .dashboard-widget-head .icon-doc-link {
margin-right: -26px; }
.overlay-dialogue.modal .dashboard-widget-head .overlay-close-btn {
@@ -4966,9 +5129,11 @@ button[disabled], button[disabled]:hover, button[disabled]:active {
width: 100%;
max-height: calc(100vh - 220px);
max-width: inherit;
- margin: 0 -10px 10px;
+ margin: 0 -10px 8px;
padding: 0 10px;
position: relative; }
+ .overlay-dialogue.modal .overlay-dialogue-body > form {
+ padding: 2px 0; }
.overlay-dialogue.modal .overlay-dialogue-body .table-forms .table-forms-td-right {
padding-right: 8px; }
.overlay-dialogue.modal .overlay-dialogue-body .table-forms .table-forms-row-with-second-field {
@@ -5365,20 +5530,6 @@ button[disabled], button[disabled]:hover, button[disabled]:active {
stroke: #e33734;
stroke-width: 2px; }
-.svg-graph-preview {
- margin-top: 10px;
- min-width: 1120px;
- height: 300px;
- position: relative; }
- .svg-graph-preview > div {
- background: #ffffff;
- height: 300px;
- position: absolute;
- left: 0;
- right: 0;
- top: 0;
- z-index: 3; }
-
.svg-graph-hintbox {
font-size: 12px;
line-height: 18px;
@@ -5931,22 +6082,22 @@ span.is-loading {
padding: 10px 0 0;
text-align: center; }
-.dashboard-grid-widget-content, div.dashboard-widget-item, .msg-details ul, z-select button.focusable,
+.dashboard-grid-widget-content, div.dashboard-widget-item > div, .msg-details ul, z-select button.focusable,
.z-select button.focusable, z-select .list,
.z-select .list, .multiselect-available, textarea, select, .setup-right-body, .overlay-dialogue.modal .overlay-dialogue-body, .overlay-dialogue .hintbox-wrap, .overlay-dialogue .maps-container, .notif-body, .debug-output, .overlay-descr, .overflow-table, .import-compare .toc,
.import-compare .diff {
scrollbar-width: thin; }
- .dashboard-grid-widget-content::-webkit-scrollbar, div.dashboard-widget-item::-webkit-scrollbar, .msg-details ul::-webkit-scrollbar, z-select button.focusable::-webkit-scrollbar,
+ .dashboard-grid-widget-content::-webkit-scrollbar, div.dashboard-widget-item > div::-webkit-scrollbar, .msg-details ul::-webkit-scrollbar, z-select button.focusable::-webkit-scrollbar,
.z-select button.focusable::-webkit-scrollbar, z-select .list::-webkit-scrollbar,
.z-select .list::-webkit-scrollbar, .multiselect-available::-webkit-scrollbar, textarea::-webkit-scrollbar, select::-webkit-scrollbar, .setup-right-body::-webkit-scrollbar, .overlay-dialogue.modal .overlay-dialogue-body::-webkit-scrollbar, .overlay-dialogue .hintbox-wrap::-webkit-scrollbar, .overlay-dialogue .maps-container::-webkit-scrollbar, .notif-body::-webkit-scrollbar, .debug-output::-webkit-scrollbar, .overlay-descr::-webkit-scrollbar, .overflow-table::-webkit-scrollbar, .import-compare .toc::-webkit-scrollbar,
.import-compare .diff::-webkit-scrollbar {
width: 9px; }
- .dashboard-grid-widget-content::-webkit-scrollbar-track, div.dashboard-widget-item::-webkit-scrollbar-track, .msg-details ul::-webkit-scrollbar-track, z-select button.focusable::-webkit-scrollbar-track,
+ .dashboard-grid-widget-content::-webkit-scrollbar-track, div.dashboard-widget-item > div::-webkit-scrollbar-track, .msg-details ul::-webkit-scrollbar-track, z-select button.focusable::-webkit-scrollbar-track,
.z-select button.focusable::-webkit-scrollbar-track, z-select .list::-webkit-scrollbar-track,
.z-select .list::-webkit-scrollbar-track, .multiselect-available::-webkit-scrollbar-track, textarea::-webkit-scrollbar-track, select::-webkit-scrollbar-track, .setup-right-body::-webkit-scrollbar-track, .overlay-dialogue.modal .overlay-dialogue-body::-webkit-scrollbar-track, .overlay-dialogue .hintbox-wrap::-webkit-scrollbar-track, .overlay-dialogue .maps-container::-webkit-scrollbar-track, .notif-body::-webkit-scrollbar-track, .debug-output::-webkit-scrollbar-track, .overlay-descr::-webkit-scrollbar-track, .overflow-table::-webkit-scrollbar-track, .import-compare .toc::-webkit-scrollbar-track,
.import-compare .diff::-webkit-scrollbar-track {
background-color: rgba(172, 187, 194, 0.55); }
- .dashboard-grid-widget-content::-webkit-scrollbar-thumb, div.dashboard-widget-item::-webkit-scrollbar-thumb, .msg-details ul::-webkit-scrollbar-thumb, z-select button.focusable::-webkit-scrollbar-thumb,
+ .dashboard-grid-widget-content::-webkit-scrollbar-thumb, div.dashboard-widget-item > div::-webkit-scrollbar-thumb, .msg-details ul::-webkit-scrollbar-thumb, z-select button.focusable::-webkit-scrollbar-thumb,
.z-select button.focusable::-webkit-scrollbar-thumb, z-select .list::-webkit-scrollbar-thumb,
.z-select .list::-webkit-scrollbar-thumb, .multiselect-available::-webkit-scrollbar-thumb, textarea::-webkit-scrollbar-thumb, select::-webkit-scrollbar-thumb, .setup-right-body::-webkit-scrollbar-thumb, .overlay-dialogue.modal .overlay-dialogue-body::-webkit-scrollbar-thumb, .overlay-dialogue .hintbox-wrap::-webkit-scrollbar-thumb, .overlay-dialogue .maps-container::-webkit-scrollbar-thumb, .notif-body::-webkit-scrollbar-thumb, .debug-output::-webkit-scrollbar-thumb, .overlay-descr::-webkit-scrollbar-thumb, .overflow-table::-webkit-scrollbar-thumb, .import-compare .toc::-webkit-scrollbar-thumb,
.import-compare .diff::-webkit-scrollbar-thumb {
@@ -6087,53 +6238,6 @@ svg {
white-space: normal;
word-break: break-word; }
-.overrides-list {
- display: table;
- width: 90%;
- max-width: 738px;
- padding-left: 15px; }
- .overrides-list .overrides-list-item {
- display: table-row; }
- .overrides-list .overrides-list-item .btn-remove {
- position: relative;
- right: -73px;
- top: 3px; }
-
-.overrides-options-list {
- white-space: normal;
- padding: 5px 0 8px;
- margin-bottom: 10px;
- border-bottom: 1px solid #ebeef0; }
- .overrides-options-list > li {
- display: inline-block;
- margin: 2px 7px 2px 0;
- white-space: nowrap;
- vertical-align: middle; }
- .overrides-options-list > li > div {
- position: relative;
- padding: 1px 18px 1px 1px;
- background-color: #768d99;
- border-radius: 2px; }
- .overrides-options-list > li > div > span {
- color: white;
- padding-left: 8px;
- line-height: 22px; }
- .overrides-options-list > li > div > input[type=text] {
- border-style: none;
- line-height: 22px;
- min-height: 22px;
- width: 85px; }
- .overrides-options-list > li > div > .subfilter-disable-btn {
- position: absolute;
- right: 0;
- top: 0;
- min-height: 24px; }
- .overrides-options-list .color-picker .color-picker-preview {
- margin: 1px;
- width: 20px;
- min-height: 20px;
- background-position: -323px -411px; }
-
.list-accordion-foot > div {
display: table-cell;
padding-top: 10px; }
@@ -6179,63 +6283,6 @@ svg {
text-overflow: ellipsis;
line-height: 24px; }
-.columns-wrapper {
- display: flex;
- flex-wrap: wrap;
- align-items: start; }
- .columns-wrapper.columns-nowrap {
- flex-wrap: nowrap; }
- .columns-wrapper.columns-2 > div,
- .columns-wrapper.columns-2 > li {
- display: block;
- flex: 0 0 50%;
- max-width: 50%; }
- .columns-wrapper.columns-3 > div,
- .columns-wrapper.columns-3 > li {
- display: block;
- flex: 0 0 33.33333%;
- max-width: 33.33333%; }
- .columns-wrapper .column-5 {
- flex: 0 0 5%;
- max-width: 5%; }
- .columns-wrapper .column-10 {
- flex: 0 0 10%;
- max-width: 10%; }
- .columns-wrapper .column-15 {
- flex: 0 0 15%;
- max-width: 15%; }
- .columns-wrapper .column-20 {
- flex: 0 0 20%;
- max-width: 20%; }
- .columns-wrapper .column-33 {
- flex: 0 0 33.33333%;
- max-width: 33.33333%; }
- .columns-wrapper .column-35 {
- flex: 0 0 35%;
- max-width: 35%; }
- .columns-wrapper .column-40 {
- flex: 0 0 40%;
- max-width: 40%; }
- .columns-wrapper .column-50 {
- flex: 0 0 50%;
- max-width: 50%; }
- .columns-wrapper .column-75 {
- flex: 0 0 75%;
- max-width: 75%; }
- .columns-wrapper .column-90 {
- flex: 0 0 90%;
- max-width: 90%; }
- .columns-wrapper .column-95 {
- flex: 0 0 95%;
- max-width: 95%; }
- .columns-wrapper .column-center {
- display: flex;
- justify-content: center;
- text-align: center; }
- .columns-wrapper .column-middle {
- display: flex;
- align-items: center; }
-
.preprocessing-list {
display: block;
max-width: 930px;
diff --git a/ui/assets/styles/dark-theme.css b/ui/assets/styles/dark-theme.css
index 6e4aaf7960b..238ffee0199 100644
--- a/ui/assets/styles/dark-theme.css
+++ b/ui/assets/styles/dark-theme.css
@@ -349,7 +349,9 @@ svg a {
top: 0;
left: 0;
transition: left .2s, top .2s; }
- .sortable .sortable-list .sortable-item:not(.sortable-dragging) {
+ .sortable .sortable-item {
+ box-sizing: border-box; }
+ .sortable .sortable-item:not(.sortable-dragging) {
transition: left .2s, top .2s; }
.sortable.sortable-dragging .sortable-item {
position: absolute; }
@@ -667,7 +669,6 @@ footer {
.form-grid {
display: grid;
- padding: 5px;
row-gap: 10px;
column-gap: 10px;
grid-template-columns: minmax(15%, max-content) auto; }
@@ -683,6 +684,9 @@ footer {
word-wrap: break-word; }
.form-grid > label.fields-group-label {
padding-top: 5px; }
+ .form-grid > label .icon-help-hint,
+ .form-grid > label .icon-info {
+ margin-left: 5px; }
.form-grid > .form-field,
.form-grid > .field-fluid,
.form-grid .form-actions {
@@ -885,6 +889,66 @@ footer {
.color-picker-dialogue .color-picker-input input {
padding-left: 25px; }
+.columns-wrapper {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: start; }
+ .columns-wrapper.columns-nowrap {
+ flex-wrap: nowrap; }
+ .columns-wrapper.columns-2 > div,
+ .columns-wrapper.columns-2 > li {
+ display: block;
+ flex: 0 0 50%;
+ max-width: 50%; }
+ .columns-wrapper.columns-3 > div,
+ .columns-wrapper.columns-3 > li {
+ display: block;
+ flex: 0 0 33.33333%;
+ max-width: 33.33333%; }
+ .columns-wrapper .column-5 {
+ flex: 0 0 5%;
+ max-width: 5%; }
+ .columns-wrapper .column-10 {
+ flex: 0 0 10%;
+ max-width: 10%; }
+ .columns-wrapper .column-15 {
+ flex: 0 0 15%;
+ max-width: 15%; }
+ .columns-wrapper .column-20 {
+ flex: 0 0 20%;
+ max-width: 20%; }
+ .columns-wrapper .column-33 {
+ flex: 0 0 33.33333%;
+ max-width: 33.33333%; }
+ .columns-wrapper .column-35 {
+ flex: 0 0 35%;
+ max-width: 35%; }
+ .columns-wrapper .column-40 {
+ flex: 0 0 40%;
+ max-width: 40%; }
+ .columns-wrapper .column-50 {
+ flex: 0 0 50%;
+ max-width: 50%; }
+ .columns-wrapper .column-75 {
+ flex: 0 0 75%;
+ max-width: 75%; }
+ .columns-wrapper .column-90 {
+ flex: 0 0 90%;
+ max-width: 90%; }
+ .columns-wrapper .column-95 {
+ flex: 0 0 95%;
+ max-width: 95%; }
+ .columns-wrapper .column-center {
+ display: flex;
+ justify-content: center;
+ text-align: center; }
+ .columns-wrapper .column-middle {
+ display: flex;
+ align-items: center; }
+ .columns-wrapper > div:not(:last-child) section,
+ .columns-wrapper > ul:not(:last-child) section {
+ margin-right: 10px; }
+
.header-kioskmode-controls .dashboard-kioskmode-controls li {
margin-right: 6px; }
@@ -1434,8 +1498,6 @@ footer {
.dashboard-widget .msg-good,
.dashboard-widget .msg-warning {
margin: 0 10px; }
- .dashboard-widget.dashboard-widget-fluid {
- margin-right: 0; }
.dashboard-grid-widget-content .list-table th:first-child, .dashboard-grid-widget-content .list-table td:first-child, .dashboard-grid-iterator.iterator-alt-content .dashboard-grid-iterator-content > div .list-table th:first-child, .dashboard-grid-iterator.iterator-alt-content .dashboard-grid-iterator-content > div .list-table td:first-child, .dashboard-widget .list-table th:first-child, .dashboard-widget .list-table td:first-child, .overlay-dialogue .list-table th:first-child, .overlay-dialogue .list-table td:first-child {
padding-left: 10px; }
@@ -1496,30 +1558,22 @@ footer {
.wrapper.layout-kioskmode .dashboard-navigation {
display: none; }
-form.dashboard-widget-clock .fields-group-date,
-form.dashboard-widget-clock .fields-group-time,
-form.dashboard-widget-clock .fields-group-tzone {
+form.dashboard-widget-clock .fields-group.fields-group-date, form.dashboard-widget-clock .fields-group.fields-group-time, form.dashboard-widget-clock .fields-group.fields-group-tzone {
display: grid;
grid-template-columns: 60px 120px repeat(2, minmax(60px, max-content) auto);
align-items: center;
column-gap: 10px;
row-gap: 5px; }
- form.dashboard-widget-clock .fields-group-date label,
- form.dashboard-widget-clock .fields-group-time label,
- form.dashboard-widget-clock .fields-group-tzone label {
+ form.dashboard-widget-clock .fields-group.fields-group-date label, form.dashboard-widget-clock .fields-group.fields-group-time label, form.dashboard-widget-clock .fields-group.fields-group-tzone label {
text-align: right; }
- form.dashboard-widget-clock .fields-group-date .field-size input,
- form.dashboard-widget-clock .fields-group-time .field-size input,
- form.dashboard-widget-clock .fields-group-tzone .field-size input {
+ form.dashboard-widget-clock .fields-group.fields-group-date .field-size input, form.dashboard-widget-clock .fields-group.fields-group-time .field-size input, form.dashboard-widget-clock .fields-group.fields-group-tzone .field-size input {
margin-right: 5px; }
-form.dashboard-widget-clock .fields-group-time .field-format {
+form.dashboard-widget-clock .fields-group.fields-group-time .field-format {
grid-column: 4 / -1; }
-form.dashboard-widget-clock .fields-group-tzone .field-format {
- grid-column: 2 / -1; }
-form.dashboard-widget-clock .fields-group-tzone .field-timezone {
+form.dashboard-widget-clock .fields-group.fields-group-tzone .form-field.field-tzone-timezone, form.dashboard-widget-clock .fields-group.fields-group-tzone .form-field.field-tzone-format {
grid-column: 2 / -1; }
-div.dashboard-widget-clock.clock-digital {
+div.dashboard-widget-clock .clock-digital {
box-sizing: border-box;
min-height: 100%;
padding: 10px;
@@ -1527,9 +1581,9 @@ div.dashboard-widget-clock.clock-digital {
flex-direction: column;
justify-content: center;
align-items: center; }
- div.dashboard-widget-clock.clock-digital .clock-date,
- div.dashboard-widget-clock.clock-digital .clock-time,
- div.dashboard-widget-clock.clock-digital .clock-time-zone {
+ div.dashboard-widget-clock .clock-digital .clock-date,
+ div.dashboard-widget-clock .clock-digital .clock-time,
+ div.dashboard-widget-clock .clock-digital .clock-time-zone {
max-width: 100%;
white-space: nowrap;
overflow: hidden;
@@ -1537,150 +1591,137 @@ div.dashboard-widget-clock.clock-digital {
font-size: calc(var(--content-height) * var(--widget-clock-font) / 1.14);
line-height: 1.14;
flex-shrink: 0; }
- div.dashboard-widget-clock.clock-digital .bold {
+ div.dashboard-widget-clock .clock-digital .bold {
font-weight: bold; }
- div.dashboard-widget-clock.clock-digital .clock-disabled {
+ div.dashboard-widget-clock .clock-digital .clock-disabled {
font-size: calc(var(--content-height) * 0.6 / 1.14);
color: #737373;
font-weight: bold; }
-form.dashboard-widget-item .fields-group-description,
-form.dashboard-widget-item .fields-group-value,
-form.dashboard-widget-item .fields-group-time,
-form.dashboard-widget-item .fields-group-change-indicator {
+.dashboard-widget-inaccessible {
+ display: grid;
+ align-items: center;
+ padding-right: 10px;
+ padding-left: 10px;
+ text-align: center;
+ color: #737373; }
+
+form.dashboard-widget-item .fields-group.fields-group-description, form.dashboard-widget-item .fields-group.fields-group-value, form.dashboard-widget-item .fields-group.fields-group-time, form.dashboard-widget-item .fields-group.fields-group-change-indicator {
display: grid;
grid-template-columns: minmax(100px, max-content) 3fr max-content auto;
align-items: center;
column-gap: 10px;
row-gap: 5px; }
- form.dashboard-widget-item .fields-group-description label,
- form.dashboard-widget-item .fields-group-value label,
- form.dashboard-widget-item .fields-group-time label,
- form.dashboard-widget-item .fields-group-change-indicator label {
+ form.dashboard-widget-item .fields-group.fields-group-description label, form.dashboard-widget-item .fields-group.fields-group-value label, form.dashboard-widget-item .fields-group.fields-group-time label, form.dashboard-widget-item .fields-group.fields-group-change-indicator label {
text-align: right; }
- form.dashboard-widget-item .fields-group-description hr,
- form.dashboard-widget-item .fields-group-value hr,
- form.dashboard-widget-item .fields-group-time hr,
- form.dashboard-widget-item .fields-group-change-indicator hr {
+ form.dashboard-widget-item .fields-group.fields-group-description hr, form.dashboard-widget-item .fields-group.fields-group-value hr, form.dashboard-widget-item .fields-group.fields-group-time hr, form.dashboard-widget-item .fields-group.fields-group-change-indicator hr {
grid-column: 1 / -1;
margin: 0;
width: 100%;
border: solid #383838;
border-width: 1px 0 0 0; }
- form.dashboard-widget-item .fields-group-description .field-fluid,
- form.dashboard-widget-item .fields-group-value .field-fluid,
- form.dashboard-widget-item .fields-group-time .field-fluid,
- form.dashboard-widget-item .fields-group-change-indicator .field-fluid {
+ form.dashboard-widget-item .fields-group.fields-group-description .field-fluid, form.dashboard-widget-item .fields-group.fields-group-value .field-fluid, form.dashboard-widget-item .fields-group.fields-group-time .field-fluid, form.dashboard-widget-item .fields-group.fields-group-change-indicator .field-fluid {
grid-column: 2 / -1; }
- form.dashboard-widget-item .fields-group-description .offset-3,
- form.dashboard-widget-item .fields-group-value .offset-3,
- form.dashboard-widget-item .fields-group-time .offset-3,
- form.dashboard-widget-item .fields-group-change-indicator .offset-3 {
+ form.dashboard-widget-item .fields-group.fields-group-description .offset-3, form.dashboard-widget-item .fields-group.fields-group-value .offset-3, form.dashboard-widget-item .fields-group.fields-group-time .offset-3, form.dashboard-widget-item .fields-group.fields-group-change-indicator .offset-3 {
grid-column-start: 3; }
- form.dashboard-widget-item .fields-group-description .field-size input,
- form.dashboard-widget-item .fields-group-value .field-size input,
- form.dashboard-widget-item .fields-group-time .field-size input,
- form.dashboard-widget-item .fields-group-change-indicator .field-size input {
+ form.dashboard-widget-item .fields-group.fields-group-description .field-size input, form.dashboard-widget-item .fields-group.fields-group-value .field-size input, form.dashboard-widget-item .fields-group.fields-group-time .field-size input, form.dashboard-widget-item .fields-group.fields-group-change-indicator .field-size input {
margin-right: 5px; }
- form.dashboard-widget-item .fields-group-description .form-field,
- form.dashboard-widget-item .fields-group-value .form-field,
- form.dashboard-widget-item .fields-group-time .form-field,
- form.dashboard-widget-item .fields-group-change-indicator .form-field {
+ form.dashboard-widget-item .fields-group.fields-group-description .form-field, form.dashboard-widget-item .fields-group.fields-group-value .form-field, form.dashboard-widget-item .fields-group.fields-group-time .form-field, form.dashboard-widget-item .fields-group.fields-group-change-indicator .form-field {
line-height: 24px; }
-form.dashboard-widget-item .fields-group-description .form-field:nth-child(1) {
+form.dashboard-widget-item .fields-group.fields-group-description .form-field:nth-child(1) {
grid-column: 1 / -1; }
-form.dashboard-widget-item .fields-group-value {
+form.dashboard-widget-item .fields-group.fields-group-value {
grid-template-columns: minmax(100px, max-content) 3fr max-content auto; }
- form.dashboard-widget-item .fields-group-value .units-show {
+ form.dashboard-widget-item .fields-group.fields-group-value .units-show {
display: flex; }
- form.dashboard-widget-item .fields-group-value .units-show label[for='units'] {
+ form.dashboard-widget-item .fields-group.fields-group-value .units-show label[for='units'] {
width: 100%; }
-form.dashboard-widget-item .fields-group-change-indicator {
+form.dashboard-widget-item .fields-group.fields-group-change-indicator {
grid-template-columns: repeat(3, max-content 96px); }
-form.dashboard-widget-item .fields-group-change-indicator .input-color-picker {
- display: block; }
+ form.dashboard-widget-item .fields-group.fields-group-change-indicator .input-color-picker {
+ display: block; }
-div.dashboard-widget-item {
+div.dashboard-widget-item > div {
box-sizing: border-box;
height: 100%;
padding: 10px;
overflow-x: hidden; }
- div.dashboard-widget-item a {
- box-sizing: border-box;
- display: flex;
- flex-direction: column;
- height: 100%;
- color: inherit; }
- div.dashboard-widget-item a:focus, div.dashboard-widget-item a:hover, div.dashboard-widget-item a:visited {
- border: none; }
- div.dashboard-widget-item a > div {
- display: flex;
- flex: 1 1 calc(100% / 3); }
- div.dashboard-widget-item .item-description,
- div.dashboard-widget-item .item-value,
- div.dashboard-widget-item .item-time {
- flex: 1 1 auto;
- max-width: 100%; }
- div.dashboard-widget-item .item-value {
+div.dashboard-widget-item a {
+ box-sizing: border-box;
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ color: inherit; }
+ div.dashboard-widget-item a:focus, div.dashboard-widget-item a:hover, div.dashboard-widget-item a:visited {
+ border: none; }
+ div.dashboard-widget-item a > div {
display: flex;
- flex-wrap: wrap;
- margin: 0 5px; }
- div.dashboard-widget-item .item-value > .units:first-child, div.dashboard-widget-item .item-value > .units:last-child {
- flex: 0 0 100%; }
- div.dashboard-widget-item .item-value > .units:first-child {
- margin-bottom: -0.07em; }
- div.dashboard-widget-item .item-value > .units:last-child {
- margin-top: -0.07em; }
- div.dashboard-widget-item .item-value.type-text {
+ flex: 1 1 calc(100% / 3); }
+div.dashboard-widget-item .item-description,
+div.dashboard-widget-item .item-value,
+div.dashboard-widget-item .item-time {
+ flex: 1 1 auto;
+ max-width: 100%; }
+div.dashboard-widget-item .item-value {
+ display: flex;
+ flex-wrap: wrap;
+ margin: 0 5px; }
+ div.dashboard-widget-item .item-value > .units:first-child, div.dashboard-widget-item .item-value > .units:last-child {
+ flex: 0 0 100%; }
+ div.dashboard-widget-item .item-value > .units:first-child {
+ margin-bottom: -0.07em; }
+ div.dashboard-widget-item .item-value > .units:last-child {
+ margin-top: -0.07em; }
+ div.dashboard-widget-item .item-value.type-text {
+ min-width: 0; }
+ div.dashboard-widget-item .item-value.type-text .item-value-content {
min-width: 0; }
- div.dashboard-widget-item .item-value.type-text .item-value-content {
- min-width: 0; }
- div.dashboard-widget-item .item-value-content {
- display: flex;
- align-items: baseline;
- overflow: hidden; }
- div.dashboard-widget-item .item-description,
- div.dashboard-widget-item .item-time,
- div.dashboard-widget-item .type-text .value {
- display: block;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis; }
- div.dashboard-widget-item .item-description,
- div.dashboard-widget-item .value,
- div.dashboard-widget-item .decimals,
- div.dashboard-widget-item .units,
- div.dashboard-widget-item .item-time {
- font-size: calc(var(--content-height) * var(--widget-item-font) / 1.14);
- line-height: 1.14; }
- div.dashboard-widget-item .units:not(:last-child),
- div.dashboard-widget-item .change-indicator:not(:last-child) {
- margin-right: 5px; }
- div.dashboard-widget-item .units:not(:first-child),
- div.dashboard-widget-item .change-indicator:not(:first-child) {
- margin-left: 5px; }
- div.dashboard-widget-item .svg-arrow {
- height: calc(var(--content-height) * var(--widget-item-font) * 0.72 / 1.14); }
- div.dashboard-widget-item .item-value-no-data {
- color: #737373; }
- div.dashboard-widget-item .left {
- justify-content: flex-start;
- max-width: max-content;
- margin-right: auto; }
- div.dashboard-widget-item .center {
- justify-content: center; }
- div.dashboard-widget-item .right {
- justify-content: flex-end;
- max-width: max-content;
- margin-left: auto; }
- div.dashboard-widget-item .top {
- align-self: flex-start; }
- div.dashboard-widget-item .middle {
- align-self: center; }
- div.dashboard-widget-item .bottom {
- align-self: flex-end; }
- div.dashboard-widget-item .bold {
- font-weight: bold; }
+div.dashboard-widget-item .item-value-content {
+ display: flex;
+ align-items: baseline;
+ overflow: hidden; }
+div.dashboard-widget-item .item-description,
+div.dashboard-widget-item .item-time,
+div.dashboard-widget-item .type-text .value {
+ display: block;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis; }
+div.dashboard-widget-item .item-description,
+div.dashboard-widget-item .value,
+div.dashboard-widget-item .decimals,
+div.dashboard-widget-item .units,
+div.dashboard-widget-item .item-time {
+ font-size: calc(var(--content-height) * var(--widget-item-font) / 1.14);
+ line-height: 1.14; }
+div.dashboard-widget-item .units:not(:last-child),
+div.dashboard-widget-item .change-indicator:not(:last-child) {
+ margin-right: 5px; }
+div.dashboard-widget-item .units:not(:first-child),
+div.dashboard-widget-item .change-indicator:not(:first-child) {
+ margin-left: 5px; }
+div.dashboard-widget-item .svg-arrow {
+ height: calc(var(--content-height) * var(--widget-item-font) * 0.72 / 1.14); }
+div.dashboard-widget-item .item-value-no-data {
+ color: #737373; }
+div.dashboard-widget-item .left {
+ justify-content: flex-start;
+ max-width: max-content;
+ margin-right: auto; }
+div.dashboard-widget-item .center {
+ justify-content: center; }
+div.dashboard-widget-item .right {
+ justify-content: flex-end;
+ max-width: max-content;
+ margin-left: auto; }
+div.dashboard-widget-item .top {
+ align-self: flex-start; }
+div.dashboard-widget-item .middle {
+ align-self: center; }
+div.dashboard-widget-item .bottom {
+ align-self: flex-end; }
+div.dashboard-widget-item .bold {
+ font-weight: bold; }
.dashboard-widget-item .svg-arrow-up {
fill: #3DC51D; }
@@ -1693,40 +1734,47 @@ div.dashboard-widget-slareport .date-vertical {
writing-mode: vertical-lr;
transform: rotate(180deg); }
+form.dashboard-widget-svggraph .svg-graph-preview,
form.dashboard-widget-svggraph .graph-widget-config-tabs {
- padding: 10px 0; }
- form.dashboard-widget-svggraph .graph-widget-config-tabs > .tabs-nav {
- margin-right: 0;
- margin-left: 0;
- border-top: 1px solid #303030; }
- form.dashboard-widget-svggraph .graph-widget-config-tabs .ui-tabs-nav {
- position: sticky;
+ grid-column: 1 / -1; }
+form.dashboard-widget-svggraph .svg-graph-preview {
+ position: relative;
+ min-width: 1110px;
+ height: 300px; }
+ form.dashboard-widget-svggraph .svg-graph-preview > div {
+ position: absolute;
top: 0;
+ right: 0;
+ left: 0;
+ margin: 0 -10px;
+ height: 300px;
background: #2b2b2b;
z-index: 3; }
+form.dashboard-widget-svggraph .graph-widget-config-tabs > .tabs-nav {
+ border-top: 1px solid #303030; }
+form.dashboard-widget-svggraph .graph-widget-config-tabs .ui-tabs-nav {
+ position: sticky;
+ top: 0;
+ background: #2b2b2b;
+ z-index: 3; }
form.dashboard-widget-svggraph .table-forms-container, form.dashboard-widget-svggraph .browser-warning-container {
+ margin: -10px 0 0 0;
border: 1px solid #303030;
border-top: none; }
form.dashboard-widget-svggraph .table-forms-separator {
padding: 0; }
-form.dashboard-widget-svggraph .dataset-head {
- display: grid;
- grid-template-columns: 24px 24px 1fr 1fr 24px;
- grid-gap: 10px;
- align-items: start; }
+form.dashboard-widget-svggraph .dataset-head,
form.dashboard-widget-svggraph .dataset-body.list-accordion-item-body {
- display: grid;
- grid-template-columns: 24px 1fr 1fr 24px;
- grid-gap: 10px;
- align-items: start;
- position: relative;
- margin-top: 10px; }
- form.dashboard-widget-svggraph .dataset-body.list-accordion-item-body .form-grid {
- padding-top: 0; }
- form.dashboard-widget-svggraph .dataset-body.list-accordion-item-body .form-grid:first-child {
- grid-column-start: 2; }
+ display: contents; }
+form.dashboard-widget-svggraph .dataset-head .multiselect {
+ width: 100%; }
+form.dashboard-widget-svggraph .dataset-body .form-grid {
+ padding-top: 0; }
+ form.dashboard-widget-svggraph .dataset-body .form-grid:first-child {
+ grid-column-start: 3; }
form.dashboard-widget-svggraph .drag-icon {
position: absolute;
+ top: 5px;
left: -14px; }
form.dashboard-widget-svggraph .td-drag-icon .drag-icon {
top: 0;
@@ -1748,13 +1796,13 @@ form.dashboard-widget-svggraph .list-vertical-accordion {
overflow: visible;
margin-top: -5px;
margin-bottom: -5px; }
- form.dashboard-widget-svggraph .list-vertical-accordion .list-accordion-item-head {
- padding: 0; }
form.dashboard-widget-svggraph .list-accordion-item {
position: relative;
- width: 100%;
- padding: 5px 0;
- list-style-type: none; }
+ display: grid;
+ grid-template-columns: 24px 24px 1fr 1fr 24px;
+ grid-gap: 10px;
+ align-items: start;
+ padding: 5px 0; }
form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-opened::before {
content: ' ';
position: absolute;
@@ -1766,8 +1814,6 @@ form.dashboard-widget-svggraph .list-accordion-item {
form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .multiselect {
height: 24px;
overflow: hidden; }
- form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .dataset-body {
- display: none; }
form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .dataset-head .table-forms-separator {
border: none; }
form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .dataset-head .single-item-table thead,
@@ -1775,6 +1821,8 @@ form.dashboard-widget-svggraph .list-accordion-item {
form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .dataset-head .single-item-table .table-col-handle,
form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .dataset-head .single-item-table .table-col-action {
display: none; }
+ form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .dataset-body {
+ display: none; }
form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .items-list {
padding-left: 0; }
form.dashboard-widget-svggraph .single-item-table .table-col-handle {
@@ -1793,11 +1841,83 @@ form.dashboard-widget-svggraph .single-item-table .single-item-table-row:last-ch
padding-bottom: 0; }
form.dashboard-widget-svggraph .single-item-table tfoot td {
padding: 5px 5px 5px 10px; }
+form.dashboard-widget-svggraph .overrides-list {
+ position: relative;
+ margin: -5px 0 -5px 15px; }
+form.dashboard-widget-svggraph .overrides-list-item {
+ position: relative;
+ display: grid;
+ grid-template-columns: 1fr 1fr 24px;
+ grid-gap: 5px 10px;
+ align-items: start;
+ padding: 5px 0; }
+ form.dashboard-widget-svggraph .overrides-list-item.sortable {
+ overflow: visible;
+ margin-top: -5px;
+ margin-bottom: -5px; }
+ form.dashboard-widget-svggraph .overrides-list-item .multiselect {
+ width: 100%; }
+ form.dashboard-widget-svggraph .overrides-list-item .btn-remove {
+ right: 0;
+ top: 0;
+ vertical-align: baseline; }
+form.dashboard-widget-svggraph .overrides-foot {
+ padding: 5px 0; }
+form.dashboard-widget-svggraph .overrides-options-list {
+ grid-column: 1 / -1;
+ padding: 0 24px 8px 0;
+ border-bottom: 1px solid #383838;
+ white-space: normal; }
+ form.dashboard-widget-svggraph .overrides-options-list > li {
+ display: inline-block;
+ margin-right: 5px;
+ margin-bottom: 2px;
+ line-height: 22px;
+ white-space: nowrap; }
+ form.dashboard-widget-svggraph .overrides-options-list > li .color-picker {
+ line-height: 22px; }
+ form.dashboard-widget-svggraph .overrides-options-list > li > div {
+ position: relative;
+ padding: 1px 18px 1px 1px;
+ background-color: #4f4f4f;
+ border-radius: 2px; }
+ form.dashboard-widget-svggraph .overrides-options-list > li > div > span {
+ color: white;
+ padding-left: 8px;
+ line-height: 22px; }
+ form.dashboard-widget-svggraph .overrides-options-list > li > div > input[type=text] {
+ border-style: none;
+ line-height: 22px;
+ min-height: 22px;
+ width: 85px; }
+ form.dashboard-widget-svggraph .overrides-options-list > li > div > .subfilter-disable-btn {
+ position: absolute;
+ right: 0;
+ top: 0;
+ min-height: 24px; }
+ form.dashboard-widget-svggraph .overrides-options-list .btn-alt .plus-icon {
+ margin-right: 0; }
+ form.dashboard-widget-svggraph .overrides-options-list .color-picker .color-picker-preview {
+ margin: 1px;
+ width: 20px;
+ min-height: 20px;
+ background-position: -323px -411px; }
form.dashboard-widget-svggraph .no-items-message {
display: none;
line-height: 24px;
color: #737373; }
+[theme="hc-dark"] form.dashboard-widget-svggraph .overrides-options-list > li > div {
+ border: 1px solid #69808d;
+ background-color: transparent !important; }
+ [theme="hc-dark"] form.dashboard-widget-svggraph .overrides-options-list > li > div > .subfilter-disable-btn {
+ border: none !important;
+ top: 0; }
+
+[theme="hc-light"] form.dashboard-widget-svggraph .overrides-options-list > li > div > .subfilter-disable-btn {
+ border: none !important;
+ top: 0; }
+
form.dashboard-widget-tophosts #list_columns .text {
max-width: 250px; }
form.dashboard-widget-tophosts #column {
@@ -2570,6 +2690,49 @@ div.dashboard-widget-tophosts z-bar-gauge {
font-size: 0;
border-left: 1px solid #0e1012; }
+section {
+ background-color: #2b2b2b;
+ border: 1px solid #303030; }
+ section .section-head {
+ display: flex;
+ height: 32px;
+ line-height: 32px; }
+ section .section-head h4 {
+ padding: 0 10px;
+ margin-right: auto;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ font-weight: bold;
+ line-height: inherit;
+ color: white; }
+ section .section-toggle {
+ width: 24px;
+ height: 24px;
+ margin: 2px 2px 0 auto;
+ background: url("../img/icon-sprite.svg?20220722") no-repeat -6px -654px; }
+ section .section-foot {
+ padding: 0 10px;
+ text-align: right;
+ line-height: 32px;
+ color: #737373; }
+ section.section-collapsed .section-body,
+ section.section-collapsed .section-foot {
+ display: none; }
+ section.section-collapsed .section-toggle {
+ background-position: -6px -689px; }
+ section:not(:last-child) {
+ margin-bottom: 10px; }
+ section .list-table {
+ border: 0; }
+ section .list-table tbody tr:last-child td {
+ border-bottom: 1px solid #383838; }
+ section .list-table td:first-child,
+ section .list-table th:first-child {
+ padding-left: 10px; }
+ section .list-table td:last-child,
+ section .list-table th:last-child {
+ padding-right: 10px; }
+
.service-info {
margin: -10px 0;
border-left: 4px solid #59db8f; }
@@ -4547,13 +4710,13 @@ button {
width: 24px;
height: 24px; }
-.filter-container.tabfilter-container .icon-edit, .btn-dashboard-page-properties, .btn-iterator-page-previous, .btn-iterator-page-next, .btn-widget-action, .btn-widget-collapse, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle, .btn-widget-expand, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle, .btn-widget-edit, .btn-alarm-on, .btn-alarm-off, .btn-sound-on, .btn-sound-off, .btn-info-clock, .btn-dashboard-conf, .interfaces .interface-row[data-type="2"] .interface-btn-toggle {
+section .section-toggle, .filter-container.tabfilter-container .icon-edit, .btn-dashboard-page-properties, .btn-iterator-page-previous, .btn-iterator-page-next, .btn-widget-action, .btn-widget-collapse, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle, .btn-widget-expand, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle, .btn-widget-edit, .btn-alarm-on, .btn-alarm-off, .btn-sound-on, .btn-sound-off, .btn-info-clock, .btn-dashboard-conf, .interfaces .interface-row[data-type="2"] .interface-btn-toggle {
border: 0;
min-height: 0;
padding: 0;
opacity: .5;
transition: opacity .2s ease-out; }
- .filter-container.tabfilter-container [disabled].icon-edit, [disabled].btn-dashboard-page-properties, [disabled].btn-iterator-page-previous, [disabled].btn-iterator-page-next, [disabled].btn-widget-action, [disabled].btn-widget-collapse, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle, [disabled].btn-widget-expand, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle, [disabled].btn-widget-edit, [disabled].btn-alarm-on, [disabled].btn-alarm-off, [disabled].btn-sound-on, [disabled].btn-sound-off, [disabled].btn-info-clock, [disabled].btn-dashboard-conf, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle, .filter-container.tabfilter-container [disabled].icon-edit:hover, [disabled].btn-dashboard-page-properties:hover, [disabled].btn-iterator-page-previous:hover, [disabled].btn-iterator-page-next:hover, [disabled].btn-widget-action:hover, [disabled].btn-widget-collapse:hover, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle:hover, [disabled].btn-widget-expand:hover, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle:hover, [disabled].btn-widget-edit:hover, [disabled].btn-alarm-on:hover, [disabled].btn-alarm-off:hover, [disabled].btn-sound-on:hover, [disabled].btn-sound-off:hover, [disabled].btn-info-clock:hover, [disabled].btn-dashboard-conf:hover, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle:hover, .filter-container.tabfilter-container [disabled].icon-edit:focus, [disabled].btn-dashboard-page-properties:focus, [disabled].btn-iterator-page-previous:focus, [disabled].btn-iterator-page-next:focus, [disabled].btn-widget-action:focus, [disabled].btn-widget-collapse:focus, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle:focus, [disabled].btn-widget-expand:focus, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle:focus, [disabled].btn-widget-edit:focus, [disabled].btn-alarm-on:focus, [disabled].btn-alarm-off:focus, [disabled].btn-sound-on:focus, [disabled].btn-sound-off:focus, [disabled].btn-info-clock:focus, [disabled].btn-dashboard-conf:focus, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle:focus, .filter-container.tabfilter-container [disabled].icon-edit:active, [disabled].btn-dashboard-page-properties:active, [disabled].btn-iterator-page-previous:active, [disabled].btn-iterator-page-next:active, [disabled].btn-widget-action:active, [disabled].btn-widget-collapse:active, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle:active, [disabled].btn-widget-expand:active, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle:active, [disabled].btn-widget-edit:active, [disabled].btn-alarm-on:active, [disabled].btn-alarm-off:active, [disabled].btn-sound-on:active, [disabled].btn-sound-off:active, [disabled].btn-info-clock:active, [disabled].btn-dashboard-conf:active, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle:active {
+ section [disabled].section-toggle, .filter-container.tabfilter-container [disabled].icon-edit, [disabled].btn-dashboard-page-properties, [disabled].btn-iterator-page-previous, [disabled].btn-iterator-page-next, [disabled].btn-widget-action, [disabled].btn-widget-collapse, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle, [disabled].btn-widget-expand, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle, [disabled].btn-widget-edit, [disabled].btn-alarm-on, [disabled].btn-alarm-off, [disabled].btn-sound-on, [disabled].btn-sound-off, [disabled].btn-info-clock, [disabled].btn-dashboard-conf, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle, section [disabled].section-toggle:hover, .filter-container.tabfilter-container [disabled].icon-edit:hover, [disabled].btn-dashboard-page-properties:hover, [disabled].btn-iterator-page-previous:hover, [disabled].btn-iterator-page-next:hover, [disabled].btn-widget-action:hover, [disabled].btn-widget-collapse:hover, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle:hover, [disabled].btn-widget-expand:hover, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle:hover, [disabled].btn-widget-edit:hover, [disabled].btn-alarm-on:hover, [disabled].btn-alarm-off:hover, [disabled].btn-sound-on:hover, [disabled].btn-sound-off:hover, [disabled].btn-info-clock:hover, [disabled].btn-dashboard-conf:hover, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle:hover, section [disabled].section-toggle:focus, .filter-container.tabfilter-container [disabled].icon-edit:focus, [disabled].btn-dashboard-page-properties:focus, [disabled].btn-iterator-page-previous:focus, [disabled].btn-iterator-page-next:focus, [disabled].btn-widget-action:focus, [disabled].btn-widget-collapse:focus, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle:focus, [disabled].btn-widget-expand:focus, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle:focus, [disabled].btn-widget-edit:focus, [disabled].btn-alarm-on:focus, [disabled].btn-alarm-off:focus, [disabled].btn-sound-on:focus, [disabled].btn-sound-off:focus, [disabled].btn-info-clock:focus, [disabled].btn-dashboard-conf:focus, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle:focus, section [disabled].section-toggle:active, .filter-container.tabfilter-container [disabled].icon-edit:active, [disabled].btn-dashboard-page-properties:active, [disabled].btn-iterator-page-previous:active, [disabled].btn-iterator-page-next:active, [disabled].btn-widget-action:active, [disabled].btn-widget-collapse:active, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle:active, [disabled].btn-widget-expand:active, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle:active, [disabled].btn-widget-edit:active, [disabled].btn-alarm-on:active, [disabled].btn-alarm-off:active, [disabled].btn-sound-on:active, [disabled].btn-sound-off:active, [disabled].btn-info-clock:active, [disabled].btn-dashboard-conf:active, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle:active {
background-color: transparent;
opacity: .25; }
@@ -4581,7 +4744,7 @@ button[disabled], button[disabled]:hover, button[disabled]:active {
.inaccessible .subfilter-enabled {
color: #b2b2b2; }
-.filter-container.tabfilter-container .icon-edit:hover, .btn-dashboard-page-properties:hover, .btn-iterator-page-previous:hover, .btn-iterator-page-next:hover, .btn-widget-action:hover, .btn-widget-collapse:hover, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle:hover, .btn-widget-expand:hover, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle:hover, .btn-widget-edit:hover, .btn-alarm-on:hover, .btn-alarm-off:hover, .btn-sound-on:hover, .btn-sound-off:hover, .btn-info-clock:hover, .btn-dashboard-conf:hover, .interfaces .interface-row[data-type="2"] .interface-btn-toggle:hover, .filter-container.tabfilter-container .icon-edit:focus, .btn-dashboard-page-properties:focus, .btn-iterator-page-previous:focus, .btn-iterator-page-next:focus, .btn-widget-action:focus, .btn-widget-collapse:focus, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle:focus, .btn-widget-expand:focus, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle:focus, .btn-widget-edit:focus, .btn-alarm-on:focus, .btn-alarm-off:focus, .btn-sound-on:focus, .btn-sound-off:focus, .btn-info-clock:focus, .btn-dashboard-conf:focus, .interfaces .interface-row[data-type="2"] .interface-btn-toggle:focus, .filter-container.tabfilter-container .icon-edit:active, .btn-dashboard-page-properties:active, .btn-iterator-page-previous:active, .btn-iterator-page-next:active, .btn-widget-action:active, .btn-widget-collapse:active, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle:active, .btn-widget-expand:active, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle:active, .btn-widget-edit:active, .btn-alarm-on:active, .btn-alarm-off:active, .btn-sound-on:active, .btn-sound-off:active, .btn-info-clock:active, .btn-dashboard-conf:active, .interfaces .interface-row[data-type="2"] .interface-btn-toggle:active {
+section .section-toggle:hover, .filter-container.tabfilter-container .icon-edit:hover, .btn-dashboard-page-properties:hover, .btn-iterator-page-previous:hover, .btn-iterator-page-next:hover, .btn-widget-action:hover, .btn-widget-collapse:hover, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle:hover, .btn-widget-expand:hover, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle:hover, .btn-widget-edit:hover, .btn-alarm-on:hover, .btn-alarm-off:hover, .btn-sound-on:hover, .btn-sound-off:hover, .btn-info-clock:hover, .btn-dashboard-conf:hover, .interfaces .interface-row[data-type="2"] .interface-btn-toggle:hover, section .section-toggle:focus, .filter-container.tabfilter-container .icon-edit:focus, .btn-dashboard-page-properties:focus, .btn-iterator-page-previous:focus, .btn-iterator-page-next:focus, .btn-widget-action:focus, .btn-widget-collapse:focus, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle:focus, .btn-widget-expand:focus, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle:focus, .btn-widget-edit:focus, .btn-alarm-on:focus, .btn-alarm-off:focus, .btn-sound-on:focus, .btn-sound-off:focus, .btn-info-clock:focus, .btn-dashboard-conf:focus, .interfaces .interface-row[data-type="2"] .interface-btn-toggle:focus, section .section-toggle:active, .filter-container.tabfilter-container .icon-edit:active, .btn-dashboard-page-properties:active, .btn-iterator-page-previous:active, .btn-iterator-page-next:active, .btn-widget-action:active, .btn-widget-collapse:active, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle:active, .btn-widget-expand:active, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle:active, .btn-widget-edit:active, .btn-alarm-on:active, .btn-alarm-off:active, .btn-sound-on:active, .btn-sound-off:active, .btn-info-clock:active, .btn-dashboard-conf:active, .interfaces .interface-row[data-type="2"] .interface-btn-toggle:active {
background-color: transparent;
opacity: 1; }
@@ -4674,16 +4837,16 @@ button[disabled], button[disabled]:hover, button[disabled]:active {
content: ''; }
.icon-tree-top-bottom::before {
- background-position: url("../img/icon-sprite.svg?20220722") no-repeat -84px -300px; }
+ background-position: -84px -300px; }
.icon-tree-top-bottom-right::before {
- background-position: url("../img/icon-sprite.svg?20220722") no-repeat -84px -334px; }
+ background-position: -84px -334px; }
.icon-tree-top-right::before {
- background-position: url("../img/icon-sprite.svg?20220722") no-repeat -84px -372px; }
+ background-position: -84px -372px; }
.icon-tree-empty::before {
- background-position: url("../img/icon-sprite.svg?20220722") no-repeat -84px -350px; }
+ background-position: -84px -350px; }
.icon-cal {
background: transparent url("../img/icon-sprite.svg?20220722") no-repeat -42px -834px; }
@@ -4964,7 +5127,7 @@ button[disabled], button[disabled]:hover, button[disabled]:active {
overflow: hidden;
margin: 0 10px; }
.overlay-dialogue.modal .dashboard-widget-head {
- margin-bottom: 14px; }
+ margin-bottom: 12px; }
.overlay-dialogue.modal .dashboard-widget-head .icon-doc-link {
margin-right: -26px; }
.overlay-dialogue.modal .dashboard-widget-head .overlay-close-btn {
@@ -4977,9 +5140,11 @@ button[disabled], button[disabled]:hover, button[disabled]:active {
width: 100%;
max-height: calc(100vh - 220px);
max-width: inherit;
- margin: 0 -10px 10px;
+ margin: 0 -10px 8px;
padding: 0 10px;
position: relative; }
+ .overlay-dialogue.modal .overlay-dialogue-body > form {
+ padding: 2px 0; }
.overlay-dialogue.modal .overlay-dialogue-body .table-forms .table-forms-td-right {
padding-right: 8px; }
.overlay-dialogue.modal .overlay-dialogue-body .table-forms .table-forms-row-with-second-field {
@@ -5376,20 +5541,6 @@ button[disabled], button[disabled]:hover, button[disabled]:active {
stroke: #e45959;
stroke-width: 2px; }
-.svg-graph-preview {
- margin-top: 10px;
- min-width: 1120px;
- height: 300px;
- position: relative; }
- .svg-graph-preview > div {
- background: #2b2b2b;
- height: 300px;
- position: absolute;
- left: 0;
- right: 0;
- top: 0;
- z-index: 3; }
-
.svg-graph-hintbox {
font-size: 12px;
line-height: 18px;
@@ -5942,22 +6093,22 @@ span.is-loading {
padding: 10px 0 0;
text-align: center; }
-.dashboard-grid-widget-content, div.dashboard-widget-item, .msg-details ul, z-select button.focusable,
+.dashboard-grid-widget-content, div.dashboard-widget-item > div, .msg-details ul, z-select button.focusable,
.z-select button.focusable, z-select .list,
.z-select .list, .multiselect-available, textarea, select, .setup-right-body, .overlay-dialogue.modal .overlay-dialogue-body, .overlay-dialogue .hintbox-wrap, .overlay-dialogue .maps-container, .notif-body, .debug-output, .overlay-descr, .overflow-table, .import-compare .toc,
.import-compare .diff {
scrollbar-width: thin; }
- .dashboard-grid-widget-content::-webkit-scrollbar, div.dashboard-widget-item::-webkit-scrollbar, .msg-details ul::-webkit-scrollbar, z-select button.focusable::-webkit-scrollbar,
+ .dashboard-grid-widget-content::-webkit-scrollbar, div.dashboard-widget-item > div::-webkit-scrollbar, .msg-details ul::-webkit-scrollbar, z-select button.focusable::-webkit-scrollbar,
.z-select button.focusable::-webkit-scrollbar, z-select .list::-webkit-scrollbar,
.z-select .list::-webkit-scrollbar, .multiselect-available::-webkit-scrollbar, textarea::-webkit-scrollbar, select::-webkit-scrollbar, .setup-right-body::-webkit-scrollbar, .overlay-dialogue.modal .overlay-dialogue-body::-webkit-scrollbar, .overlay-dialogue .hintbox-wrap::-webkit-scrollbar, .overlay-dialogue .maps-container::-webkit-scrollbar, .notif-body::-webkit-scrollbar, .debug-output::-webkit-scrollbar, .overlay-descr::-webkit-scrollbar, .overflow-table::-webkit-scrollbar, .import-compare .toc::-webkit-scrollbar,
.import-compare .diff::-webkit-scrollbar {
width: 9px; }
- .dashboard-grid-widget-content::-webkit-scrollbar-track, div.dashboard-widget-item::-webkit-scrollbar-track, .msg-details ul::-webkit-scrollbar-track, z-select button.focusable::-webkit-scrollbar-track,
+ .dashboard-grid-widget-content::-webkit-scrollbar-track, div.dashboard-widget-item > div::-webkit-scrollbar-track, .msg-details ul::-webkit-scrollbar-track, z-select button.focusable::-webkit-scrollbar-track,
.z-select button.focusable::-webkit-scrollbar-track, z-select .list::-webkit-scrollbar-track,
.z-select .list::-webkit-scrollbar-track, .multiselect-available::-webkit-scrollbar-track, textarea::-webkit-scrollbar-track, select::-webkit-scrollbar-track, .setup-right-body::-webkit-scrollbar-track, .overlay-dialogue.modal .overlay-dialogue-body::-webkit-scrollbar-track, .overlay-dialogue .hintbox-wrap::-webkit-scrollbar-track, .overlay-dialogue .maps-container::-webkit-scrollbar-track, .notif-body::-webkit-scrollbar-track, .debug-output::-webkit-scrollbar-track, .overlay-descr::-webkit-scrollbar-track, .overflow-table::-webkit-scrollbar-track, .import-compare .toc::-webkit-scrollbar-track,
.import-compare .diff::-webkit-scrollbar-track {
background-color: #1f1f1f; }
- .dashboard-grid-widget-content::-webkit-scrollbar-thumb, div.dashboard-widget-item::-webkit-scrollbar-thumb, .msg-details ul::-webkit-scrollbar-thumb, z-select button.focusable::-webkit-scrollbar-thumb,
+ .dashboard-grid-widget-content::-webkit-scrollbar-thumb, div.dashboard-widget-item > div::-webkit-scrollbar-thumb, .msg-details ul::-webkit-scrollbar-thumb, z-select button.focusable::-webkit-scrollbar-thumb,
.z-select button.focusable::-webkit-scrollbar-thumb, z-select .list::-webkit-scrollbar-thumb,
.z-select .list::-webkit-scrollbar-thumb, .multiselect-available::-webkit-scrollbar-thumb, textarea::-webkit-scrollbar-thumb, select::-webkit-scrollbar-thumb, .setup-right-body::-webkit-scrollbar-thumb, .overlay-dialogue.modal .overlay-dialogue-body::-webkit-scrollbar-thumb, .overlay-dialogue .hintbox-wrap::-webkit-scrollbar-thumb, .overlay-dialogue .maps-container::-webkit-scrollbar-thumb, .notif-body::-webkit-scrollbar-thumb, .debug-output::-webkit-scrollbar-thumb, .overlay-descr::-webkit-scrollbar-thumb, .overflow-table::-webkit-scrollbar-thumb, .import-compare .toc::-webkit-scrollbar-thumb,
.import-compare .diff::-webkit-scrollbar-thumb {
@@ -6098,53 +6249,6 @@ svg {
white-space: normal;
word-break: break-word; }
-.overrides-list {
- display: table;
- width: 90%;
- max-width: 738px;
- padding-left: 15px; }
- .overrides-list .overrides-list-item {
- display: table-row; }
- .overrides-list .overrides-list-item .btn-remove {
- position: relative;
- right: -73px;
- top: 3px; }
-
-.overrides-options-list {
- white-space: normal;
- padding: 5px 0 8px;
- margin-bottom: 10px;
- border-bottom: 1px solid #383838; }
- .overrides-options-list > li {
- display: inline-block;
- margin: 2px 7px 2px 0;
- white-space: nowrap;
- vertical-align: middle; }
- .overrides-options-list > li > div {
- position: relative;
- padding: 1px 18px 1px 1px;
- background-color: #4f4f4f;
- border-radius: 2px; }
- .overrides-options-list > li > div > span {
- color: white;
- padding-left: 8px;
- line-height: 22px; }
- .overrides-options-list > li > div > input[type=text] {
- border-style: none;
- line-height: 22px;
- min-height: 22px;
- width: 85px; }
- .overrides-options-list > li > div > .subfilter-disable-btn {
- position: absolute;
- right: 0;
- top: 0;
- min-height: 24px; }
- .overrides-options-list .color-picker .color-picker-preview {
- margin: 1px;
- width: 20px;
- min-height: 20px;
- background-position: -323px -411px; }
-
.list-accordion-foot > div {
display: table-cell;
padding-top: 10px; }
@@ -6190,63 +6294,6 @@ svg {
text-overflow: ellipsis;
line-height: 24px; }
-.columns-wrapper {
- display: flex;
- flex-wrap: wrap;
- align-items: start; }
- .columns-wrapper.columns-nowrap {
- flex-wrap: nowrap; }
- .columns-wrapper.columns-2 > div,
- .columns-wrapper.columns-2 > li {
- display: block;
- flex: 0 0 50%;
- max-width: 50%; }
- .columns-wrapper.columns-3 > div,
- .columns-wrapper.columns-3 > li {
- display: block;
- flex: 0 0 33.33333%;
- max-width: 33.33333%; }
- .columns-wrapper .column-5 {
- flex: 0 0 5%;
- max-width: 5%; }
- .columns-wrapper .column-10 {
- flex: 0 0 10%;
- max-width: 10%; }
- .columns-wrapper .column-15 {
- flex: 0 0 15%;
- max-width: 15%; }
- .columns-wrapper .column-20 {
- flex: 0 0 20%;
- max-width: 20%; }
- .columns-wrapper .column-33 {
- flex: 0 0 33.33333%;
- max-width: 33.33333%; }
- .columns-wrapper .column-35 {
- flex: 0 0 35%;
- max-width: 35%; }
- .columns-wrapper .column-40 {
- flex: 0 0 40%;
- max-width: 40%; }
- .columns-wrapper .column-50 {
- flex: 0 0 50%;
- max-width: 50%; }
- .columns-wrapper .column-75 {
- flex: 0 0 75%;
- max-width: 75%; }
- .columns-wrapper .column-90 {
- flex: 0 0 90%;
- max-width: 90%; }
- .columns-wrapper .column-95 {
- flex: 0 0 95%;
- max-width: 95%; }
- .columns-wrapper .column-center {
- display: flex;
- justify-content: center;
- text-align: center; }
- .columns-wrapper .column-middle {
- display: flex;
- align-items: center; }
-
.preprocessing-list {
display: block;
max-width: 930px;
diff --git a/ui/assets/styles/hc-dark.css b/ui/assets/styles/hc-dark.css
index 21c633bc729..089bb7af81a 100644
--- a/ui/assets/styles/hc-dark.css
+++ b/ui/assets/styles/hc-dark.css
@@ -336,7 +336,9 @@ svg a {
top: 0;
left: 0;
transition: left .2s, top .2s; }
- .sortable .sortable-list .sortable-item:not(.sortable-dragging) {
+ .sortable .sortable-item {
+ box-sizing: border-box; }
+ .sortable .sortable-item:not(.sortable-dragging) {
transition: left .2s, top .2s; }
.sortable.sortable-dragging .sortable-item {
position: absolute; }
@@ -654,7 +656,6 @@ footer {
.form-grid {
display: grid;
- padding: 5px;
row-gap: 10px;
column-gap: 10px;
grid-template-columns: minmax(15%, max-content) auto; }
@@ -670,6 +671,9 @@ footer {
word-wrap: break-word; }
.form-grid > label.fields-group-label {
padding-top: 5px; }
+ .form-grid > label .icon-help-hint,
+ .form-grid > label .icon-info {
+ margin-left: 5px; }
.form-grid > .form-field,
.form-grid > .field-fluid,
.form-grid .form-actions {
@@ -872,6 +876,66 @@ footer {
.color-picker-dialogue .color-picker-input input {
padding-left: 25px; }
+.columns-wrapper {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: start; }
+ .columns-wrapper.columns-nowrap {
+ flex-wrap: nowrap; }
+ .columns-wrapper.columns-2 > div,
+ .columns-wrapper.columns-2 > li {
+ display: block;
+ flex: 0 0 50%;
+ max-width: 50%; }
+ .columns-wrapper.columns-3 > div,
+ .columns-wrapper.columns-3 > li {
+ display: block;
+ flex: 0 0 33.33333%;
+ max-width: 33.33333%; }
+ .columns-wrapper .column-5 {
+ flex: 0 0 5%;
+ max-width: 5%; }
+ .columns-wrapper .column-10 {
+ flex: 0 0 10%;
+ max-width: 10%; }
+ .columns-wrapper .column-15 {
+ flex: 0 0 15%;
+ max-width: 15%; }
+ .columns-wrapper .column-20 {
+ flex: 0 0 20%;
+ max-width: 20%; }
+ .columns-wrapper .column-33 {
+ flex: 0 0 33.33333%;
+ max-width: 33.33333%; }
+ .columns-wrapper .column-35 {
+ flex: 0 0 35%;
+ max-width: 35%; }
+ .columns-wrapper .column-40 {
+ flex: 0 0 40%;
+ max-width: 40%; }
+ .columns-wrapper .column-50 {
+ flex: 0 0 50%;
+ max-width: 50%; }
+ .columns-wrapper .column-75 {
+ flex: 0 0 75%;
+ max-width: 75%; }
+ .columns-wrapper .column-90 {
+ flex: 0 0 90%;
+ max-width: 90%; }
+ .columns-wrapper .column-95 {
+ flex: 0 0 95%;
+ max-width: 95%; }
+ .columns-wrapper .column-center {
+ display: flex;
+ justify-content: center;
+ text-align: center; }
+ .columns-wrapper .column-middle {
+ display: flex;
+ align-items: center; }
+ .columns-wrapper > div:not(:last-child) section,
+ .columns-wrapper > ul:not(:last-child) section {
+ margin-right: 10px; }
+
.header-kioskmode-controls .dashboard-kioskmode-controls li {
margin-right: 6px; }
@@ -1421,8 +1485,6 @@ footer {
.dashboard-widget .msg-good,
.dashboard-widget .msg-warning {
margin: 0 10px; }
- .dashboard-widget.dashboard-widget-fluid {
- margin-right: 0; }
.dashboard-grid-widget-content .list-table th:first-child, .dashboard-grid-widget-content .list-table td:first-child, .dashboard-grid-iterator.iterator-alt-content .dashboard-grid-iterator-content > div .list-table th:first-child, .dashboard-grid-iterator.iterator-alt-content .dashboard-grid-iterator-content > div .list-table td:first-child, .dashboard-widget .list-table th:first-child, .dashboard-widget .list-table td:first-child, .overlay-dialogue .list-table th:first-child, .overlay-dialogue .list-table td:first-child {
padding-left: 10px; }
@@ -1483,30 +1545,22 @@ footer {
.wrapper.layout-kioskmode .dashboard-navigation {
display: none; }
-form.dashboard-widget-clock .fields-group-date,
-form.dashboard-widget-clock .fields-group-time,
-form.dashboard-widget-clock .fields-group-tzone {
+form.dashboard-widget-clock .fields-group.fields-group-date, form.dashboard-widget-clock .fields-group.fields-group-time, form.dashboard-widget-clock .fields-group.fields-group-tzone {
display: grid;
grid-template-columns: 60px 120px repeat(2, minmax(60px, max-content) auto);
align-items: center;
column-gap: 10px;
row-gap: 5px; }
- form.dashboard-widget-clock .fields-group-date label,
- form.dashboard-widget-clock .fields-group-time label,
- form.dashboard-widget-clock .fields-group-tzone label {
+ form.dashboard-widget-clock .fields-group.fields-group-date label, form.dashboard-widget-clock .fields-group.fields-group-time label, form.dashboard-widget-clock .fields-group.fields-group-tzone label {
text-align: right; }
- form.dashboard-widget-clock .fields-group-date .field-size input,
- form.dashboard-widget-clock .fields-group-time .field-size input,
- form.dashboard-widget-clock .fields-group-tzone .field-size input {
+ form.dashboard-widget-clock .fields-group.fields-group-date .field-size input, form.dashboard-widget-clock .fields-group.fields-group-time .field-size input, form.dashboard-widget-clock .fields-group.fields-group-tzone .field-size input {
margin-right: 5px; }
-form.dashboard-widget-clock .fields-group-time .field-format {
+form.dashboard-widget-clock .fields-group.fields-group-time .field-format {
grid-column: 4 / -1; }
-form.dashboard-widget-clock .fields-group-tzone .field-format {
- grid-column: 2 / -1; }
-form.dashboard-widget-clock .fields-group-tzone .field-timezone {
+form.dashboard-widget-clock .fields-group.fields-group-tzone .form-field.field-tzone-timezone, form.dashboard-widget-clock .fields-group.fields-group-tzone .form-field.field-tzone-format {
grid-column: 2 / -1; }
-div.dashboard-widget-clock.clock-digital {
+div.dashboard-widget-clock .clock-digital {
box-sizing: border-box;
min-height: 100%;
padding: 10px;
@@ -1514,9 +1568,9 @@ div.dashboard-widget-clock.clock-digital {
flex-direction: column;
justify-content: center;
align-items: center; }
- div.dashboard-widget-clock.clock-digital .clock-date,
- div.dashboard-widget-clock.clock-digital .clock-time,
- div.dashboard-widget-clock.clock-digital .clock-time-zone {
+ div.dashboard-widget-clock .clock-digital .clock-date,
+ div.dashboard-widget-clock .clock-digital .clock-time,
+ div.dashboard-widget-clock .clock-digital .clock-time-zone {
max-width: 100%;
white-space: nowrap;
overflow: hidden;
@@ -1524,150 +1578,137 @@ div.dashboard-widget-clock.clock-digital {
font-size: calc(var(--content-height) * var(--widget-clock-font) / 1.14);
line-height: 1.14;
flex-shrink: 0; }
- div.dashboard-widget-clock.clock-digital .bold {
+ div.dashboard-widget-clock .clock-digital .bold {
font-weight: bold; }
- div.dashboard-widget-clock.clock-digital .clock-disabled {
+ div.dashboard-widget-clock .clock-digital .clock-disabled {
font-size: calc(var(--content-height) * 0.6 / 1.14);
color: #cacaca;
font-weight: bold; }
-form.dashboard-widget-item .fields-group-description,
-form.dashboard-widget-item .fields-group-value,
-form.dashboard-widget-item .fields-group-time,
-form.dashboard-widget-item .fields-group-change-indicator {
+.dashboard-widget-inaccessible {
+ display: grid;
+ align-items: center;
+ padding-right: 10px;
+ padding-left: 10px;
+ text-align: center;
+ color: #cacaca; }
+
+form.dashboard-widget-item .fields-group.fields-group-description, form.dashboard-widget-item .fields-group.fields-group-value, form.dashboard-widget-item .fields-group.fields-group-time, form.dashboard-widget-item .fields-group.fields-group-change-indicator {
display: grid;
grid-template-columns: minmax(100px, max-content) 3fr max-content auto;
align-items: center;
column-gap: 10px;
row-gap: 5px; }
- form.dashboard-widget-item .fields-group-description label,
- form.dashboard-widget-item .fields-group-value label,
- form.dashboard-widget-item .fields-group-time label,
- form.dashboard-widget-item .fields-group-change-indicator label {
+ form.dashboard-widget-item .fields-group.fields-group-description label, form.dashboard-widget-item .fields-group.fields-group-value label, form.dashboard-widget-item .fields-group.fields-group-time label, form.dashboard-widget-item .fields-group.fields-group-change-indicator label {
text-align: right; }
- form.dashboard-widget-item .fields-group-description hr,
- form.dashboard-widget-item .fields-group-value hr,
- form.dashboard-widget-item .fields-group-time hr,
- form.dashboard-widget-item .fields-group-change-indicator hr {
+ form.dashboard-widget-item .fields-group.fields-group-description hr, form.dashboard-widget-item .fields-group.fields-group-value hr, form.dashboard-widget-item .fields-group.fields-group-time hr, form.dashboard-widget-item .fields-group.fields-group-change-indicator hr {
grid-column: 1 / -1;
margin: 0;
width: 100%;
border: solid #333333;
border-width: 1px 0 0 0; }
- form.dashboard-widget-item .fields-group-description .field-fluid,
- form.dashboard-widget-item .fields-group-value .field-fluid,
- form.dashboard-widget-item .fields-group-time .field-fluid,
- form.dashboard-widget-item .fields-group-change-indicator .field-fluid {
+ form.dashboard-widget-item .fields-group.fields-group-description .field-fluid, form.dashboard-widget-item .fields-group.fields-group-value .field-fluid, form.dashboard-widget-item .fields-group.fields-group-time .field-fluid, form.dashboard-widget-item .fields-group.fields-group-change-indicator .field-fluid {
grid-column: 2 / -1; }
- form.dashboard-widget-item .fields-group-description .offset-3,
- form.dashboard-widget-item .fields-group-value .offset-3,
- form.dashboard-widget-item .fields-group-time .offset-3,
- form.dashboard-widget-item .fields-group-change-indicator .offset-3 {
+ form.dashboard-widget-item .fields-group.fields-group-description .offset-3, form.dashboard-widget-item .fields-group.fields-group-value .offset-3, form.dashboard-widget-item .fields-group.fields-group-time .offset-3, form.dashboard-widget-item .fields-group.fields-group-change-indicator .offset-3 {
grid-column-start: 3; }
- form.dashboard-widget-item .fields-group-description .field-size input,
- form.dashboard-widget-item .fields-group-value .field-size input,
- form.dashboard-widget-item .fields-group-time .field-size input,
- form.dashboard-widget-item .fields-group-change-indicator .field-size input {
+ form.dashboard-widget-item .fields-group.fields-group-description .field-size input, form.dashboard-widget-item .fields-group.fields-group-value .field-size input, form.dashboard-widget-item .fields-group.fields-group-time .field-size input, form.dashboard-widget-item .fields-group.fields-group-change-indicator .field-size input {
margin-right: 5px; }
- form.dashboard-widget-item .fields-group-description .form-field,
- form.dashboard-widget-item .fields-group-value .form-field,
- form.dashboard-widget-item .fields-group-time .form-field,
- form.dashboard-widget-item .fields-group-change-indicator .form-field {
+ form.dashboard-widget-item .fields-group.fields-group-description .form-field, form.dashboard-widget-item .fields-group.fields-group-value .form-field, form.dashboard-widget-item .fields-group.fields-group-time .form-field, form.dashboard-widget-item .fields-group.fields-group-change-indicator .form-field {
line-height: 24px; }
-form.dashboard-widget-item .fields-group-description .form-field:nth-child(1) {
+form.dashboard-widget-item .fields-group.fields-group-description .form-field:nth-child(1) {
grid-column: 1 / -1; }
-form.dashboard-widget-item .fields-group-value {
+form.dashboard-widget-item .fields-group.fields-group-value {
grid-template-columns: minmax(100px, max-content) 3fr max-content auto; }
- form.dashboard-widget-item .fields-group-value .units-show {
+ form.dashboard-widget-item .fields-group.fields-group-value .units-show {
display: flex; }
- form.dashboard-widget-item .fields-group-value .units-show label[for='units'] {
+ form.dashboard-widget-item .fields-group.fields-group-value .units-show label[for='units'] {
width: 100%; }
-form.dashboard-widget-item .fields-group-change-indicator {
+form.dashboard-widget-item .fields-group.fields-group-change-indicator {
grid-template-columns: repeat(3, max-content 96px); }
-form.dashboard-widget-item .fields-group-change-indicator .input-color-picker {
- display: block; }
+ form.dashboard-widget-item .fields-group.fields-group-change-indicator .input-color-picker {
+ display: block; }
-div.dashboard-widget-item {
+div.dashboard-widget-item > div {
box-sizing: border-box;
height: 100%;
padding: 10px;
overflow-x: hidden; }
- div.dashboard-widget-item a {
- box-sizing: border-box;
- display: flex;
- flex-direction: column;
- height: 100%;
- color: inherit; }
- div.dashboard-widget-item a:focus, div.dashboard-widget-item a:hover, div.dashboard-widget-item a:visited {
- border: none; }
- div.dashboard-widget-item a > div {
- display: flex;
- flex: 1 1 calc(100% / 3); }
- div.dashboard-widget-item .item-description,
- div.dashboard-widget-item .item-value,
- div.dashboard-widget-item .item-time {
- flex: 1 1 auto;
- max-width: 100%; }
- div.dashboard-widget-item .item-value {
+div.dashboard-widget-item a {
+ box-sizing: border-box;
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ color: inherit; }
+ div.dashboard-widget-item a:focus, div.dashboard-widget-item a:hover, div.dashboard-widget-item a:visited {
+ border: none; }
+ div.dashboard-widget-item a > div {
display: flex;
- flex-wrap: wrap;
- margin: 0 5px; }
- div.dashboard-widget-item .item-value > .units:first-child, div.dashboard-widget-item .item-value > .units:last-child {
- flex: 0 0 100%; }
- div.dashboard-widget-item .item-value > .units:first-child {
- margin-bottom: -0.07em; }
- div.dashboard-widget-item .item-value > .units:last-child {
- margin-top: -0.07em; }
- div.dashboard-widget-item .item-value.type-text {
+ flex: 1 1 calc(100% / 3); }
+div.dashboard-widget-item .item-description,
+div.dashboard-widget-item .item-value,
+div.dashboard-widget-item .item-time {
+ flex: 1 1 auto;
+ max-width: 100%; }
+div.dashboard-widget-item .item-value {
+ display: flex;
+ flex-wrap: wrap;
+ margin: 0 5px; }
+ div.dashboard-widget-item .item-value > .units:first-child, div.dashboard-widget-item .item-value > .units:last-child {
+ flex: 0 0 100%; }
+ div.dashboard-widget-item .item-value > .units:first-child {
+ margin-bottom: -0.07em; }
+ div.dashboard-widget-item .item-value > .units:last-child {
+ margin-top: -0.07em; }
+ div.dashboard-widget-item .item-value.type-text {
+ min-width: 0; }
+ div.dashboard-widget-item .item-value.type-text .item-value-content {
min-width: 0; }
- div.dashboard-widget-item .item-value.type-text .item-value-content {
- min-width: 0; }
- div.dashboard-widget-item .item-value-content {
- display: flex;
- align-items: baseline;
- overflow: hidden; }
- div.dashboard-widget-item .item-description,
- div.dashboard-widget-item .item-time,
- div.dashboard-widget-item .type-text .value {
- display: block;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis; }
- div.dashboard-widget-item .item-description,
- div.dashboard-widget-item .value,
- div.dashboard-widget-item .decimals,
- div.dashboard-widget-item .units,
- div.dashboard-widget-item .item-time {
- font-size: calc(var(--content-height) * var(--widget-item-font) / 1.14);
- line-height: 1.14; }
- div.dashboard-widget-item .units:not(:last-child),
- div.dashboard-widget-item .change-indicator:not(:last-child) {
- margin-right: 5px; }
- div.dashboard-widget-item .units:not(:first-child),
- div.dashboard-widget-item .change-indicator:not(:first-child) {
- margin-left: 5px; }
- div.dashboard-widget-item .svg-arrow {
- height: calc(var(--content-height) * var(--widget-item-font) * 0.72 / 1.14); }
- div.dashboard-widget-item .item-value-no-data {
- color: #cacaca; }
- div.dashboard-widget-item .left {
- justify-content: flex-start;
- max-width: max-content;
- margin-right: auto; }
- div.dashboard-widget-item .center {
- justify-content: center; }
- div.dashboard-widget-item .right {
- justify-content: flex-end;
- max-width: max-content;
- margin-left: auto; }
- div.dashboard-widget-item .top {
- align-self: flex-start; }
- div.dashboard-widget-item .middle {
- align-self: center; }
- div.dashboard-widget-item .bottom {
- align-self: flex-end; }
- div.dashboard-widget-item .bold {
- font-weight: bold; }
+div.dashboard-widget-item .item-value-content {
+ display: flex;
+ align-items: baseline;
+ overflow: hidden; }
+div.dashboard-widget-item .item-description,
+div.dashboard-widget-item .item-time,
+div.dashboard-widget-item .type-text .value {
+ display: block;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis; }
+div.dashboard-widget-item .item-description,
+div.dashboard-widget-item .value,
+div.dashboard-widget-item .decimals,
+div.dashboard-widget-item .units,
+div.dashboard-widget-item .item-time {
+ font-size: calc(var(--content-height) * var(--widget-item-font) / 1.14);
+ line-height: 1.14; }
+div.dashboard-widget-item .units:not(:last-child),
+div.dashboard-widget-item .change-indicator:not(:last-child) {
+ margin-right: 5px; }
+div.dashboard-widget-item .units:not(:first-child),
+div.dashboard-widget-item .change-indicator:not(:first-child) {
+ margin-left: 5px; }
+div.dashboard-widget-item .svg-arrow {
+ height: calc(var(--content-height) * var(--widget-item-font) * 0.72 / 1.14); }
+div.dashboard-widget-item .item-value-no-data {
+ color: #cacaca; }
+div.dashboard-widget-item .left {
+ justify-content: flex-start;
+ max-width: max-content;
+ margin-right: auto; }
+div.dashboard-widget-item .center {
+ justify-content: center; }
+div.dashboard-widget-item .right {
+ justify-content: flex-end;
+ max-width: max-content;
+ margin-left: auto; }
+div.dashboard-widget-item .top {
+ align-self: flex-start; }
+div.dashboard-widget-item .middle {
+ align-self: center; }
+div.dashboard-widget-item .bottom {
+ align-self: flex-end; }
+div.dashboard-widget-item .bold {
+ font-weight: bold; }
.dashboard-widget-item .svg-arrow-up {
fill: #3DC51D; }
@@ -1683,40 +1724,47 @@ div.dashboard-widget-slareport .date-vertical {
writing-mode: vertical-lr;
transform: rotate(180deg); }
+form.dashboard-widget-svggraph .svg-graph-preview,
form.dashboard-widget-svggraph .graph-widget-config-tabs {
- padding: 10px 0; }
- form.dashboard-widget-svggraph .graph-widget-config-tabs > .tabs-nav {
- margin-right: 0;
- margin-left: 0;
- border-top: 1px solid #444444; }
- form.dashboard-widget-svggraph .graph-widget-config-tabs .ui-tabs-nav {
- position: sticky;
+ grid-column: 1 / -1; }
+form.dashboard-widget-svggraph .svg-graph-preview {
+ position: relative;
+ min-width: 1110px;
+ height: 300px; }
+ form.dashboard-widget-svggraph .svg-graph-preview > div {
+ position: absolute;
top: 0;
- background: #070707;
+ right: 0;
+ left: 0;
+ margin: 0 -10px;
+ height: 300px;
+ background: #000000;
z-index: 3; }
+form.dashboard-widget-svggraph .graph-widget-config-tabs > .tabs-nav {
+ border-top: 1px solid #444444; }
+form.dashboard-widget-svggraph .graph-widget-config-tabs .ui-tabs-nav {
+ position: sticky;
+ top: 0;
+ background: #070707;
+ z-index: 3; }
form.dashboard-widget-svggraph .table-forms-container, form.dashboard-widget-svggraph .browser-warning-container {
+ margin: -10px 0 0 0;
border: 1px solid #444444;
border-top: none; }
form.dashboard-widget-svggraph .table-forms-separator {
padding: 0; }
-form.dashboard-widget-svggraph .dataset-head {
- display: grid;
- grid-template-columns: 24px 24px 1fr 1fr 24px;
- grid-gap: 10px;
- align-items: start; }
+form.dashboard-widget-svggraph .dataset-head,
form.dashboard-widget-svggraph .dataset-body.list-accordion-item-body {
- display: grid;
- grid-template-columns: 24px 1fr 1fr 24px;
- grid-gap: 10px;
- align-items: start;
- position: relative;
- margin-top: 10px; }
- form.dashboard-widget-svggraph .dataset-body.list-accordion-item-body .form-grid {
- padding-top: 0; }
- form.dashboard-widget-svggraph .dataset-body.list-accordion-item-body .form-grid:first-child {
- grid-column-start: 2; }
+ display: contents; }
+form.dashboard-widget-svggraph .dataset-head .multiselect {
+ width: 100%; }
+form.dashboard-widget-svggraph .dataset-body .form-grid {
+ padding-top: 0; }
+ form.dashboard-widget-svggraph .dataset-body .form-grid:first-child {
+ grid-column-start: 3; }
form.dashboard-widget-svggraph .drag-icon {
position: absolute;
+ top: 5px;
left: -14px; }
form.dashboard-widget-svggraph .td-drag-icon .drag-icon {
top: 0;
@@ -1738,13 +1786,13 @@ form.dashboard-widget-svggraph .list-vertical-accordion {
overflow: visible;
margin-top: -5px;
margin-bottom: -5px; }
- form.dashboard-widget-svggraph .list-vertical-accordion .list-accordion-item-head {
- padding: 0; }
form.dashboard-widget-svggraph .list-accordion-item {
position: relative;
- width: 100%;
- padding: 5px 0;
- list-style-type: none; }
+ display: grid;
+ grid-template-columns: 24px 24px 1fr 1fr 24px;
+ grid-gap: 10px;
+ align-items: start;
+ padding: 5px 0; }
form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-opened::before {
content: ' ';
position: absolute;
@@ -1756,8 +1804,6 @@ form.dashboard-widget-svggraph .list-accordion-item {
form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .multiselect {
height: 24px;
overflow: hidden; }
- form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .dataset-body {
- display: none; }
form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .dataset-head .table-forms-separator {
border: none; }
form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .dataset-head .single-item-table thead,
@@ -1765,6 +1811,8 @@ form.dashboard-widget-svggraph .list-accordion-item {
form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .dataset-head .single-item-table .table-col-handle,
form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .dataset-head .single-item-table .table-col-action {
display: none; }
+ form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .dataset-body {
+ display: none; }
form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .items-list {
padding-left: 0; }
form.dashboard-widget-svggraph .single-item-table .table-col-handle {
@@ -1783,11 +1831,83 @@ form.dashboard-widget-svggraph .single-item-table .single-item-table-row:last-ch
padding-bottom: 0; }
form.dashboard-widget-svggraph .single-item-table tfoot td {
padding: 5px 5px 5px 10px; }
+form.dashboard-widget-svggraph .overrides-list {
+ position: relative;
+ margin: -5px 0 -5px 15px; }
+form.dashboard-widget-svggraph .overrides-list-item {
+ position: relative;
+ display: grid;
+ grid-template-columns: 1fr 1fr 24px;
+ grid-gap: 5px 10px;
+ align-items: start;
+ padding: 5px 0; }
+ form.dashboard-widget-svggraph .overrides-list-item.sortable {
+ overflow: visible;
+ margin-top: -5px;
+ margin-bottom: -5px; }
+ form.dashboard-widget-svggraph .overrides-list-item .multiselect {
+ width: 100%; }
+ form.dashboard-widget-svggraph .overrides-list-item .btn-remove {
+ right: 0;
+ top: 0;
+ vertical-align: baseline; }
+form.dashboard-widget-svggraph .overrides-foot {
+ padding: 5px 0; }
+form.dashboard-widget-svggraph .overrides-options-list {
+ grid-column: 1 / -1;
+ padding: 0 24px 8px 0;
+ border-bottom: 1px solid #333333;
+ white-space: normal; }
+ form.dashboard-widget-svggraph .overrides-options-list > li {
+ display: inline-block;
+ margin-right: 5px;
+ margin-bottom: 2px;
+ line-height: 22px;
+ white-space: nowrap; }
+ form.dashboard-widget-svggraph .overrides-options-list > li .color-picker {
+ line-height: 22px; }
+ form.dashboard-widget-svggraph .overrides-options-list > li > div {
+ position: relative;
+ padding: 1px 18px 1px 1px;
+ background-color: #dddddd;
+ border-radius: 2px; }
+ form.dashboard-widget-svggraph .overrides-options-list > li > div > span {
+ color: white;
+ padding-left: 8px;
+ line-height: 22px; }
+ form.dashboard-widget-svggraph .overrides-options-list > li > div > input[type=text] {
+ border-style: none;
+ line-height: 22px;
+ min-height: 22px;
+ width: 85px; }
+ form.dashboard-widget-svggraph .overrides-options-list > li > div > .subfilter-disable-btn {
+ position: absolute;
+ right: 0;
+ top: 0;
+ min-height: 24px; }
+ form.dashboard-widget-svggraph .overrides-options-list .btn-alt .plus-icon {
+ margin-right: 0; }
+ form.dashboard-widget-svggraph .overrides-options-list .color-picker .color-picker-preview {
+ margin: 1px;
+ width: 20px;
+ min-height: 20px;
+ background-position: -323px -411px; }
form.dashboard-widget-svggraph .no-items-message {
display: none;
line-height: 24px;
color: #cacaca; }
+[theme="hc-dark"] form.dashboard-widget-svggraph .overrides-options-list > li > div {
+ border: 1px solid #ffffff;
+ background-color: transparent !important; }
+ [theme="hc-dark"] form.dashboard-widget-svggraph .overrides-options-list > li > div > .subfilter-disable-btn {
+ border: none !important;
+ top: 0; }
+
+[theme="hc-light"] form.dashboard-widget-svggraph .overrides-options-list > li > div > .subfilter-disable-btn {
+ border: none !important;
+ top: 0; }
+
form.dashboard-widget-tophosts #list_columns .text {
max-width: 250px; }
form.dashboard-widget-tophosts #column {
@@ -2542,6 +2662,49 @@ div.dashboard-widget-tophosts z-bar-gauge {
font-size: 0;
border-left: 1px solid #111111; }
+section {
+ background-color: #000000;
+ border: 1px solid #444444; }
+ section .section-head {
+ display: flex;
+ height: 32px;
+ line-height: 32px; }
+ section .section-head h4 {
+ padding: 0 10px;
+ margin-right: auto;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ font-weight: bold;
+ line-height: inherit;
+ color: white; }
+ section .section-toggle {
+ width: 24px;
+ height: 24px;
+ margin: 2px 2px 0 auto;
+ background: url("../img/icon-sprite.svg?20220722") no-repeat -6px -654px; }
+ section .section-foot {
+ padding: 0 10px;
+ text-align: right;
+ line-height: 32px;
+ color: #cacaca; }
+ section.section-collapsed .section-body,
+ section.section-collapsed .section-foot {
+ display: none; }
+ section.section-collapsed .section-toggle {
+ background-position: -6px -689px; }
+ section:not(:last-child) {
+ margin-bottom: 10px; }
+ section .list-table {
+ border: 0; }
+ section .list-table tbody tr:last-child td {
+ border-bottom: 1px solid #333333; }
+ section .list-table td:first-child,
+ section .list-table th:first-child {
+ padding-left: 10px; }
+ section .list-table td:last-child,
+ section .list-table th:last-child {
+ padding-right: 10px; }
+
.service-info {
margin: -10px 0;
border-left: 4px solid #23d545; }
@@ -4498,13 +4661,13 @@ button {
width: 24px;
height: 24px; }
-.filter-container.tabfilter-container .icon-edit, .btn-dashboard-page-properties, .btn-iterator-page-previous, .btn-iterator-page-next, .btn-widget-action, .btn-widget-collapse, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle, .btn-widget-expand, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle, .btn-widget-edit, .btn-alarm-on, .btn-alarm-off, .btn-sound-on, .btn-sound-off, .btn-info-clock, .btn-dashboard-conf, .interfaces .interface-row[data-type="2"] .interface-btn-toggle {
+section .section-toggle, .filter-container.tabfilter-container .icon-edit, .btn-dashboard-page-properties, .btn-iterator-page-previous, .btn-iterator-page-next, .btn-widget-action, .btn-widget-collapse, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle, .btn-widget-expand, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle, .btn-widget-edit, .btn-alarm-on, .btn-alarm-off, .btn-sound-on, .btn-sound-off, .btn-info-clock, .btn-dashboard-conf, .interfaces .interface-row[data-type="2"] .interface-btn-toggle {
border: 0;
min-height: 0;
padding: 0;
opacity: .5;
transition: opacity .2s ease-out; }
- .filter-container.tabfilter-container [disabled].icon-edit, [disabled].btn-dashboard-page-properties, [disabled].btn-iterator-page-previous, [disabled].btn-iterator-page-next, [disabled].btn-widget-action, [disabled].btn-widget-collapse, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle, [disabled].btn-widget-expand, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle, [disabled].btn-widget-edit, [disabled].btn-alarm-on, [disabled].btn-alarm-off, [disabled].btn-sound-on, [disabled].btn-sound-off, [disabled].btn-info-clock, [disabled].btn-dashboard-conf, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle, .filter-container.tabfilter-container [disabled].icon-edit:hover, [disabled].btn-dashboard-page-properties:hover, [disabled].btn-iterator-page-previous:hover, [disabled].btn-iterator-page-next:hover, [disabled].btn-widget-action:hover, [disabled].btn-widget-collapse:hover, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle:hover, [disabled].btn-widget-expand:hover, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle:hover, [disabled].btn-widget-edit:hover, [disabled].btn-alarm-on:hover, [disabled].btn-alarm-off:hover, [disabled].btn-sound-on:hover, [disabled].btn-sound-off:hover, [disabled].btn-info-clock:hover, [disabled].btn-dashboard-conf:hover, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle:hover, .filter-container.tabfilter-container [disabled].icon-edit:focus, [disabled].btn-dashboard-page-properties:focus, [disabled].btn-iterator-page-previous:focus, [disabled].btn-iterator-page-next:focus, [disabled].btn-widget-action:focus, [disabled].btn-widget-collapse:focus, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle:focus, [disabled].btn-widget-expand:focus, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle:focus, [disabled].btn-widget-edit:focus, [disabled].btn-alarm-on:focus, [disabled].btn-alarm-off:focus, [disabled].btn-sound-on:focus, [disabled].btn-sound-off:focus, [disabled].btn-info-clock:focus, [disabled].btn-dashboard-conf:focus, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle:focus, .filter-container.tabfilter-container [disabled].icon-edit:active, [disabled].btn-dashboard-page-properties:active, [disabled].btn-iterator-page-previous:active, [disabled].btn-iterator-page-next:active, [disabled].btn-widget-action:active, [disabled].btn-widget-collapse:active, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle:active, [disabled].btn-widget-expand:active, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle:active, [disabled].btn-widget-edit:active, [disabled].btn-alarm-on:active, [disabled].btn-alarm-off:active, [disabled].btn-sound-on:active, [disabled].btn-sound-off:active, [disabled].btn-info-clock:active, [disabled].btn-dashboard-conf:active, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle:active {
+ section [disabled].section-toggle, .filter-container.tabfilter-container [disabled].icon-edit, [disabled].btn-dashboard-page-properties, [disabled].btn-iterator-page-previous, [disabled].btn-iterator-page-next, [disabled].btn-widget-action, [disabled].btn-widget-collapse, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle, [disabled].btn-widget-expand, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle, [disabled].btn-widget-edit, [disabled].btn-alarm-on, [disabled].btn-alarm-off, [disabled].btn-sound-on, [disabled].btn-sound-off, [disabled].btn-info-clock, [disabled].btn-dashboard-conf, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle, section [disabled].section-toggle:hover, .filter-container.tabfilter-container [disabled].icon-edit:hover, [disabled].btn-dashboard-page-properties:hover, [disabled].btn-iterator-page-previous:hover, [disabled].btn-iterator-page-next:hover, [disabled].btn-widget-action:hover, [disabled].btn-widget-collapse:hover, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle:hover, [disabled].btn-widget-expand:hover, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle:hover, [disabled].btn-widget-edit:hover, [disabled].btn-alarm-on:hover, [disabled].btn-alarm-off:hover, [disabled].btn-sound-on:hover, [disabled].btn-sound-off:hover, [disabled].btn-info-clock:hover, [disabled].btn-dashboard-conf:hover, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle:hover, section [disabled].section-toggle:focus, .filter-container.tabfilter-container [disabled].icon-edit:focus, [disabled].btn-dashboard-page-properties:focus, [disabled].btn-iterator-page-previous:focus, [disabled].btn-iterator-page-next:focus, [disabled].btn-widget-action:focus, [disabled].btn-widget-collapse:focus, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle:focus, [disabled].btn-widget-expand:focus, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle:focus, [disabled].btn-widget-edit:focus, [disabled].btn-alarm-on:focus, [disabled].btn-alarm-off:focus, [disabled].btn-sound-on:focus, [disabled].btn-sound-off:focus, [disabled].btn-info-clock:focus, [disabled].btn-dashboard-conf:focus, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle:focus, section [disabled].section-toggle:active, .filter-container.tabfilter-container [disabled].icon-edit:active, [disabled].btn-dashboard-page-properties:active, [disabled].btn-iterator-page-previous:active, [disabled].btn-iterator-page-next:active, [disabled].btn-widget-action:active, [disabled].btn-widget-collapse:active, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle:active, [disabled].btn-widget-expand:active, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle:active, [disabled].btn-widget-edit:active, [disabled].btn-alarm-on:active, [disabled].btn-alarm-off:active, [disabled].btn-sound-on:active, [disabled].btn-sound-off:active, [disabled].btn-info-clock:active, [disabled].btn-dashboard-conf:active, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle:active {
background-color: transparent;
opacity: .25; }
@@ -4532,7 +4695,7 @@ button[disabled], button[disabled]:hover, button[disabled]:active {
.inaccessible .subfilter-enabled {
color: #bfbfbf; }
-.filter-container.tabfilter-container .icon-edit:hover, .btn-dashboard-page-properties:hover, .btn-iterator-page-previous:hover, .btn-iterator-page-next:hover, .btn-widget-action:hover, .btn-widget-collapse:hover, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle:hover, .btn-widget-expand:hover, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle:hover, .btn-widget-edit:hover, .btn-alarm-on:hover, .btn-alarm-off:hover, .btn-sound-on:hover, .btn-sound-off:hover, .btn-info-clock:hover, .btn-dashboard-conf:hover, .interfaces .interface-row[data-type="2"] .interface-btn-toggle:hover, .filter-container.tabfilter-container .icon-edit:focus, .btn-dashboard-page-properties:focus, .btn-iterator-page-previous:focus, .btn-iterator-page-next:focus, .btn-widget-action:focus, .btn-widget-collapse:focus, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle:focus, .btn-widget-expand:focus, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle:focus, .btn-widget-edit:focus, .btn-alarm-on:focus, .btn-alarm-off:focus, .btn-sound-on:focus, .btn-sound-off:focus, .btn-info-clock:focus, .btn-dashboard-conf:focus, .interfaces .interface-row[data-type="2"] .interface-btn-toggle:focus, .filter-container.tabfilter-container .icon-edit:active, .btn-dashboard-page-properties:active, .btn-iterator-page-previous:active, .btn-iterator-page-next:active, .btn-widget-action:active, .btn-widget-collapse:active, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle:active, .btn-widget-expand:active, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle:active, .btn-widget-edit:active, .btn-alarm-on:active, .btn-alarm-off:active, .btn-sound-on:active, .btn-sound-off:active, .btn-info-clock:active, .btn-dashboard-conf:active, .interfaces .interface-row[data-type="2"] .interface-btn-toggle:active {
+section .section-toggle:hover, .filter-container.tabfilter-container .icon-edit:hover, .btn-dashboard-page-properties:hover, .btn-iterator-page-previous:hover, .btn-iterator-page-next:hover, .btn-widget-action:hover, .btn-widget-collapse:hover, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle:hover, .btn-widget-expand:hover, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle:hover, .btn-widget-edit:hover, .btn-alarm-on:hover, .btn-alarm-off:hover, .btn-sound-on:hover, .btn-sound-off:hover, .btn-info-clock:hover, .btn-dashboard-conf:hover, .interfaces .interface-row[data-type="2"] .interface-btn-toggle:hover, section .section-toggle:focus, .filter-container.tabfilter-container .icon-edit:focus, .btn-dashboard-page-properties:focus, .btn-iterator-page-previous:focus, .btn-iterator-page-next:focus, .btn-widget-action:focus, .btn-widget-collapse:focus, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle:focus, .btn-widget-expand:focus, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle:focus, .btn-widget-edit:focus, .btn-alarm-on:focus, .btn-alarm-off:focus, .btn-sound-on:focus, .btn-sound-off:focus, .btn-info-clock:focus, .btn-dashboard-conf:focus, .interfaces .interface-row[data-type="2"] .interface-btn-toggle:focus, section .section-toggle:active, .filter-container.tabfilter-container .icon-edit:active, .btn-dashboard-page-properties:active, .btn-iterator-page-previous:active, .btn-iterator-page-next:active, .btn-widget-action:active, .btn-widget-collapse:active, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle:active, .btn-widget-expand:active, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle:active, .btn-widget-edit:active, .btn-alarm-on:active, .btn-alarm-off:active, .btn-sound-on:active, .btn-sound-off:active, .btn-info-clock:active, .btn-dashboard-conf:active, .interfaces .interface-row[data-type="2"] .interface-btn-toggle:active {
background-color: transparent;
opacity: 1; }
@@ -4625,16 +4788,16 @@ button[disabled], button[disabled]:hover, button[disabled]:active {
content: ''; }
.icon-tree-top-bottom::before {
- background-position: url("../img/icon-sprite.svg?20220722") no-repeat -84px -300px; }
+ background-position: -84px -300px; }
.icon-tree-top-bottom-right::before {
- background-position: url("../img/icon-sprite.svg?20220722") no-repeat -84px -334px; }
+ background-position: -84px -334px; }
.icon-tree-top-right::before {
- background-position: url("../img/icon-sprite.svg?20220722") no-repeat -84px -372px; }
+ background-position: -84px -372px; }
.icon-tree-empty::before {
- background-position: url("../img/icon-sprite.svg?20220722") no-repeat -84px -350px; }
+ background-position: -84px -350px; }
.icon-cal {
background: transparent url("../img/icon-sprite.svg?20220722") no-repeat -42px -834px; }
@@ -4915,7 +5078,7 @@ button[disabled], button[disabled]:hover, button[disabled]:active {
overflow: hidden;
margin: 0 10px; }
.overlay-dialogue.modal .dashboard-widget-head {
- margin-bottom: 14px; }
+ margin-bottom: 12px; }
.overlay-dialogue.modal .dashboard-widget-head .icon-doc-link {
margin-right: -26px; }
.overlay-dialogue.modal .dashboard-widget-head .overlay-close-btn {
@@ -4928,9 +5091,11 @@ button[disabled], button[disabled]:hover, button[disabled]:active {
width: 100%;
max-height: calc(100vh - 220px);
max-width: inherit;
- margin: 0 -10px 10px;
+ margin: 0 -10px 8px;
padding: 0 10px;
position: relative; }
+ .overlay-dialogue.modal .overlay-dialogue-body > form {
+ padding: 2px 0; }
.overlay-dialogue.modal .overlay-dialogue-body .table-forms .table-forms-td-right {
padding-right: 8px; }
.overlay-dialogue.modal .overlay-dialogue-body .table-forms .table-forms-row-with-second-field {
@@ -5327,20 +5492,6 @@ button[disabled], button[disabled]:hover, button[disabled]:active {
stroke: #ff5050;
stroke-width: 2px; }
-.svg-graph-preview {
- margin-top: 10px;
- min-width: 1120px;
- height: 300px;
- position: relative; }
- .svg-graph-preview > div {
- background: #000000;
- height: 300px;
- position: absolute;
- left: 0;
- right: 0;
- top: 0;
- z-index: 3; }
-
.svg-graph-hintbox {
font-size: 12px;
line-height: 18px;
@@ -5884,22 +6035,22 @@ span.is-loading {
padding: 10px 0 0;
text-align: center; }
-.dashboard-grid-widget-content, div.dashboard-widget-item, .msg-details ul, z-select button.focusable,
+.dashboard-grid-widget-content, div.dashboard-widget-item > div, .msg-details ul, z-select button.focusable,
.z-select button.focusable, z-select .list,
.z-select .list, .multiselect-available, textarea, select, .setup-right-body, .overlay-dialogue.modal .overlay-dialogue-body, .overlay-dialogue .hintbox-wrap, .overlay-dialogue .maps-container, .notif-body, .debug-output, .overlay-descr, .overflow-table, .import-compare .toc,
.import-compare .diff {
scrollbar-width: thin; }
- .dashboard-grid-widget-content::-webkit-scrollbar, div.dashboard-widget-item::-webkit-scrollbar, .msg-details ul::-webkit-scrollbar, z-select button.focusable::-webkit-scrollbar,
+ .dashboard-grid-widget-content::-webkit-scrollbar, div.dashboard-widget-item > div::-webkit-scrollbar, .msg-details ul::-webkit-scrollbar, z-select button.focusable::-webkit-scrollbar,
.z-select button.focusable::-webkit-scrollbar, z-select .list::-webkit-scrollbar,
.z-select .list::-webkit-scrollbar, .multiselect-available::-webkit-scrollbar, textarea::-webkit-scrollbar, select::-webkit-scrollbar, .setup-right-body::-webkit-scrollbar, .overlay-dialogue.modal .overlay-dialogue-body::-webkit-scrollbar, .overlay-dialogue .hintbox-wrap::-webkit-scrollbar, .overlay-dialogue .maps-container::-webkit-scrollbar, .notif-body::-webkit-scrollbar, .debug-output::-webkit-scrollbar, .overlay-descr::-webkit-scrollbar, .overflow-table::-webkit-scrollbar, .import-compare .toc::-webkit-scrollbar,
.import-compare .diff::-webkit-scrollbar {
width: 9px; }
- .dashboard-grid-widget-content::-webkit-scrollbar-track, div.dashboard-widget-item::-webkit-scrollbar-track, .msg-details ul::-webkit-scrollbar-track, z-select button.focusable::-webkit-scrollbar-track,
+ .dashboard-grid-widget-content::-webkit-scrollbar-track, div.dashboard-widget-item > div::-webkit-scrollbar-track, .msg-details ul::-webkit-scrollbar-track, z-select button.focusable::-webkit-scrollbar-track,
.z-select button.focusable::-webkit-scrollbar-track, z-select .list::-webkit-scrollbar-track,
.z-select .list::-webkit-scrollbar-track, .multiselect-available::-webkit-scrollbar-track, textarea::-webkit-scrollbar-track, select::-webkit-scrollbar-track, .setup-right-body::-webkit-scrollbar-track, .overlay-dialogue.modal .overlay-dialogue-body::-webkit-scrollbar-track, .overlay-dialogue .hintbox-wrap::-webkit-scrollbar-track, .overlay-dialogue .maps-container::-webkit-scrollbar-track, .notif-body::-webkit-scrollbar-track, .debug-output::-webkit-scrollbar-track, .overlay-descr::-webkit-scrollbar-track, .overflow-table::-webkit-scrollbar-track, .import-compare .toc::-webkit-scrollbar-track,
.import-compare .diff::-webkit-scrollbar-track {
background-color: #1f1f1f; }
- .dashboard-grid-widget-content::-webkit-scrollbar-thumb, div.dashboard-widget-item::-webkit-scrollbar-thumb, .msg-details ul::-webkit-scrollbar-thumb, z-select button.focusable::-webkit-scrollbar-thumb,
+ .dashboard-grid-widget-content::-webkit-scrollbar-thumb, div.dashboard-widget-item > div::-webkit-scrollbar-thumb, .msg-details ul::-webkit-scrollbar-thumb, z-select button.focusable::-webkit-scrollbar-thumb,
.z-select button.focusable::-webkit-scrollbar-thumb, z-select .list::-webkit-scrollbar-thumb,
.z-select .list::-webkit-scrollbar-thumb, .multiselect-available::-webkit-scrollbar-thumb, textarea::-webkit-scrollbar-thumb, select::-webkit-scrollbar-thumb, .setup-right-body::-webkit-scrollbar-thumb, .overlay-dialogue.modal .overlay-dialogue-body::-webkit-scrollbar-thumb, .overlay-dialogue .hintbox-wrap::-webkit-scrollbar-thumb, .overlay-dialogue .maps-container::-webkit-scrollbar-thumb, .notif-body::-webkit-scrollbar-thumb, .debug-output::-webkit-scrollbar-thumb, .overlay-descr::-webkit-scrollbar-thumb, .overflow-table::-webkit-scrollbar-thumb, .import-compare .toc::-webkit-scrollbar-thumb,
.import-compare .diff::-webkit-scrollbar-thumb {
@@ -6040,53 +6191,6 @@ svg {
white-space: normal;
word-break: break-word; }
-.overrides-list {
- display: table;
- width: 90%;
- max-width: 738px;
- padding-left: 15px; }
- .overrides-list .overrides-list-item {
- display: table-row; }
- .overrides-list .overrides-list-item .btn-remove {
- position: relative;
- right: -73px;
- top: 3px; }
-
-.overrides-options-list {
- white-space: normal;
- padding: 5px 0 8px;
- margin-bottom: 10px;
- border-bottom: 1px solid #333333; }
- .overrides-options-list > li {
- display: inline-block;
- margin: 2px 7px 2px 0;
- white-space: nowrap;
- vertical-align: middle; }
- .overrides-options-list > li > div {
- position: relative;
- padding: 1px 18px 1px 1px;
- background-color: #dddddd;
- border-radius: 2px; }
- .overrides-options-list > li > div > span {
- color: white;
- padding-left: 8px;
- line-height: 22px; }
- .overrides-options-list > li > div > input[type=text] {
- border-style: none;
- line-height: 22px;
- min-height: 22px;
- width: 85px; }
- .overrides-options-list > li > div > .subfilter-disable-btn {
- position: absolute;
- right: 0;
- top: 0;
- min-height: 24px; }
- .overrides-options-list .color-picker .color-picker-preview {
- margin: 1px;
- width: 20px;
- min-height: 20px;
- background-position: -323px -411px; }
-
.list-accordion-foot > div {
display: table-cell;
padding-top: 10px; }
@@ -6132,63 +6236,6 @@ svg {
text-overflow: ellipsis;
line-height: 24px; }
-.columns-wrapper {
- display: flex;
- flex-wrap: wrap;
- align-items: start; }
- .columns-wrapper.columns-nowrap {
- flex-wrap: nowrap; }
- .columns-wrapper.columns-2 > div,
- .columns-wrapper.columns-2 > li {
- display: block;
- flex: 0 0 50%;
- max-width: 50%; }
- .columns-wrapper.columns-3 > div,
- .columns-wrapper.columns-3 > li {
- display: block;
- flex: 0 0 33.33333%;
- max-width: 33.33333%; }
- .columns-wrapper .column-5 {
- flex: 0 0 5%;
- max-width: 5%; }
- .columns-wrapper .column-10 {
- flex: 0 0 10%;
- max-width: 10%; }
- .columns-wrapper .column-15 {
- flex: 0 0 15%;
- max-width: 15%; }
- .columns-wrapper .column-20 {
- flex: 0 0 20%;
- max-width: 20%; }
- .columns-wrapper .column-33 {
- flex: 0 0 33.33333%;
- max-width: 33.33333%; }
- .columns-wrapper .column-35 {
- flex: 0 0 35%;
- max-width: 35%; }
- .columns-wrapper .column-40 {
- flex: 0 0 40%;
- max-width: 40%; }
- .columns-wrapper .column-50 {
- flex: 0 0 50%;
- max-width: 50%; }
- .columns-wrapper .column-75 {
- flex: 0 0 75%;
- max-width: 75%; }
- .columns-wrapper .column-90 {
- flex: 0 0 90%;
- max-width: 90%; }
- .columns-wrapper .column-95 {
- flex: 0 0 95%;
- max-width: 95%; }
- .columns-wrapper .column-center {
- display: flex;
- justify-content: center;
- text-align: center; }
- .columns-wrapper .column-middle {
- display: flex;
- align-items: center; }
-
.preprocessing-list {
display: block;
max-width: 930px;
@@ -8024,13 +8071,6 @@ td.inactive-bg {
.problem-icon-list .status-disaster-bg::before {
background-position: -472px -432px; }
-.overrides-options-list > li > div {
- border: 1px solid #ffffff;
- background-color: transparent !important; }
- .overrides-options-list > li > div > .subfilter-disable-btn {
- border: none !important;
- top: 0; }
-
.totals-list > div {
border-top: 1px solid #444444;
color: #ffffff; }
@@ -8074,3 +8114,8 @@ td.inactive-bg {
background-position: -318px -690px; }
.interfaces .interface-row[data-type="2"].list-accordion-item-opened .interface-btn-toggle {
background-position: -318px -655px; }
+
+section .section-toggle {
+ background-position: -318px -654px; }
+section.section-collapsed .section-toggle {
+ background-position: -318px -690px; }
diff --git a/ui/assets/styles/hc-light.css b/ui/assets/styles/hc-light.css
index 83cdcd1f8b2..09919987373 100644
--- a/ui/assets/styles/hc-light.css
+++ b/ui/assets/styles/hc-light.css
@@ -336,7 +336,9 @@ svg a {
top: 0;
left: 0;
transition: left .2s, top .2s; }
- .sortable .sortable-list .sortable-item:not(.sortable-dragging) {
+ .sortable .sortable-item {
+ box-sizing: border-box; }
+ .sortable .sortable-item:not(.sortable-dragging) {
transition: left .2s, top .2s; }
.sortable.sortable-dragging .sortable-item {
position: absolute; }
@@ -654,7 +656,6 @@ footer {
.form-grid {
display: grid;
- padding: 5px;
row-gap: 10px;
column-gap: 10px;
grid-template-columns: minmax(15%, max-content) auto; }
@@ -670,6 +671,9 @@ footer {
word-wrap: break-word; }
.form-grid > label.fields-group-label {
padding-top: 5px; }
+ .form-grid > label .icon-help-hint,
+ .form-grid > label .icon-info {
+ margin-left: 5px; }
.form-grid > .form-field,
.form-grid > .field-fluid,
.form-grid .form-actions {
@@ -872,6 +876,66 @@ footer {
.color-picker-dialogue .color-picker-input input {
padding-left: 25px; }
+.columns-wrapper {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: start; }
+ .columns-wrapper.columns-nowrap {
+ flex-wrap: nowrap; }
+ .columns-wrapper.columns-2 > div,
+ .columns-wrapper.columns-2 > li {
+ display: block;
+ flex: 0 0 50%;
+ max-width: 50%; }
+ .columns-wrapper.columns-3 > div,
+ .columns-wrapper.columns-3 > li {
+ display: block;
+ flex: 0 0 33.33333%;
+ max-width: 33.33333%; }
+ .columns-wrapper .column-5 {
+ flex: 0 0 5%;
+ max-width: 5%; }
+ .columns-wrapper .column-10 {
+ flex: 0 0 10%;
+ max-width: 10%; }
+ .columns-wrapper .column-15 {
+ flex: 0 0 15%;
+ max-width: 15%; }
+ .columns-wrapper .column-20 {
+ flex: 0 0 20%;
+ max-width: 20%; }
+ .columns-wrapper .column-33 {
+ flex: 0 0 33.33333%;
+ max-width: 33.33333%; }
+ .columns-wrapper .column-35 {
+ flex: 0 0 35%;
+ max-width: 35%; }
+ .columns-wrapper .column-40 {
+ flex: 0 0 40%;
+ max-width: 40%; }
+ .columns-wrapper .column-50 {
+ flex: 0 0 50%;
+ max-width: 50%; }
+ .columns-wrapper .column-75 {
+ flex: 0 0 75%;
+ max-width: 75%; }
+ .columns-wrapper .column-90 {
+ flex: 0 0 90%;
+ max-width: 90%; }
+ .columns-wrapper .column-95 {
+ flex: 0 0 95%;
+ max-width: 95%; }
+ .columns-wrapper .column-center {
+ display: flex;
+ justify-content: center;
+ text-align: center; }
+ .columns-wrapper .column-middle {
+ display: flex;
+ align-items: center; }
+ .columns-wrapper > div:not(:last-child) section,
+ .columns-wrapper > ul:not(:last-child) section {
+ margin-right: 10px; }
+
.header-kioskmode-controls .dashboard-kioskmode-controls li {
margin-right: 6px; }
@@ -1421,8 +1485,6 @@ footer {
.dashboard-widget .msg-good,
.dashboard-widget .msg-warning {
margin: 0 10px; }
- .dashboard-widget.dashboard-widget-fluid {
- margin-right: 0; }
.dashboard-grid-widget-content .list-table th:first-child, .dashboard-grid-widget-content .list-table td:first-child, .dashboard-grid-iterator.iterator-alt-content .dashboard-grid-iterator-content > div .list-table th:first-child, .dashboard-grid-iterator.iterator-alt-content .dashboard-grid-iterator-content > div .list-table td:first-child, .dashboard-widget .list-table th:first-child, .dashboard-widget .list-table td:first-child, .overlay-dialogue .list-table th:first-child, .overlay-dialogue .list-table td:first-child {
padding-left: 10px; }
@@ -1483,30 +1545,22 @@ footer {
.wrapper.layout-kioskmode .dashboard-navigation {
display: none; }
-form.dashboard-widget-clock .fields-group-date,
-form.dashboard-widget-clock .fields-group-time,
-form.dashboard-widget-clock .fields-group-tzone {
+form.dashboard-widget-clock .fields-group.fields-group-date, form.dashboard-widget-clock .fields-group.fields-group-time, form.dashboard-widget-clock .fields-group.fields-group-tzone {
display: grid;
grid-template-columns: 60px 120px repeat(2, minmax(60px, max-content) auto);
align-items: center;
column-gap: 10px;
row-gap: 5px; }
- form.dashboard-widget-clock .fields-group-date label,
- form.dashboard-widget-clock .fields-group-time label,
- form.dashboard-widget-clock .fields-group-tzone label {
+ form.dashboard-widget-clock .fields-group.fields-group-date label, form.dashboard-widget-clock .fields-group.fields-group-time label, form.dashboard-widget-clock .fields-group.fields-group-tzone label {
text-align: right; }
- form.dashboard-widget-clock .fields-group-date .field-size input,
- form.dashboard-widget-clock .fields-group-time .field-size input,
- form.dashboard-widget-clock .fields-group-tzone .field-size input {
+ form.dashboard-widget-clock .fields-group.fields-group-date .field-size input, form.dashboard-widget-clock .fields-group.fields-group-time .field-size input, form.dashboard-widget-clock .fields-group.fields-group-tzone .field-size input {
margin-right: 5px; }
-form.dashboard-widget-clock .fields-group-time .field-format {
+form.dashboard-widget-clock .fields-group.fields-group-time .field-format {
grid-column: 4 / -1; }
-form.dashboard-widget-clock .fields-group-tzone .field-format {
- grid-column: 2 / -1; }
-form.dashboard-widget-clock .fields-group-tzone .field-timezone {
+form.dashboard-widget-clock .fields-group.fields-group-tzone .form-field.field-tzone-timezone, form.dashboard-widget-clock .fields-group.fields-group-tzone .form-field.field-tzone-format {
grid-column: 2 / -1; }
-div.dashboard-widget-clock.clock-digital {
+div.dashboard-widget-clock .clock-digital {
box-sizing: border-box;
min-height: 100%;
padding: 10px;
@@ -1514,9 +1568,9 @@ div.dashboard-widget-clock.clock-digital {
flex-direction: column;
justify-content: center;
align-items: center; }
- div.dashboard-widget-clock.clock-digital .clock-date,
- div.dashboard-widget-clock.clock-digital .clock-time,
- div.dashboard-widget-clock.clock-digital .clock-time-zone {
+ div.dashboard-widget-clock .clock-digital .clock-date,
+ div.dashboard-widget-clock .clock-digital .clock-time,
+ div.dashboard-widget-clock .clock-digital .clock-time-zone {
max-width: 100%;
white-space: nowrap;
overflow: hidden;
@@ -1524,150 +1578,137 @@ div.dashboard-widget-clock.clock-digital {
font-size: calc(var(--content-height) * var(--widget-clock-font) / 1.14);
line-height: 1.14;
flex-shrink: 0; }
- div.dashboard-widget-clock.clock-digital .bold {
+ div.dashboard-widget-clock .clock-digital .bold {
font-weight: bold; }
- div.dashboard-widget-clock.clock-digital .clock-disabled {
+ div.dashboard-widget-clock .clock-digital .clock-disabled {
font-size: calc(var(--content-height) * 0.6 / 1.14);
color: #333333;
font-weight: bold; }
-form.dashboard-widget-item .fields-group-description,
-form.dashboard-widget-item .fields-group-value,
-form.dashboard-widget-item .fields-group-time,
-form.dashboard-widget-item .fields-group-change-indicator {
+.dashboard-widget-inaccessible {
+ display: grid;
+ align-items: center;
+ padding-right: 10px;
+ padding-left: 10px;
+ text-align: center;
+ color: #333333; }
+
+form.dashboard-widget-item .fields-group.fields-group-description, form.dashboard-widget-item .fields-group.fields-group-value, form.dashboard-widget-item .fields-group.fields-group-time, form.dashboard-widget-item .fields-group.fields-group-change-indicator {
display: grid;
grid-template-columns: minmax(100px, max-content) 3fr max-content auto;
align-items: center;
column-gap: 10px;
row-gap: 5px; }
- form.dashboard-widget-item .fields-group-description label,
- form.dashboard-widget-item .fields-group-value label,
- form.dashboard-widget-item .fields-group-time label,
- form.dashboard-widget-item .fields-group-change-indicator label {
+ form.dashboard-widget-item .fields-group.fields-group-description label, form.dashboard-widget-item .fields-group.fields-group-value label, form.dashboard-widget-item .fields-group.fields-group-time label, form.dashboard-widget-item .fields-group.fields-group-change-indicator label {
text-align: right; }
- form.dashboard-widget-item .fields-group-description hr,
- form.dashboard-widget-item .fields-group-value hr,
- form.dashboard-widget-item .fields-group-time hr,
- form.dashboard-widget-item .fields-group-change-indicator hr {
+ form.dashboard-widget-item .fields-group.fields-group-description hr, form.dashboard-widget-item .fields-group.fields-group-value hr, form.dashboard-widget-item .fields-group.fields-group-time hr, form.dashboard-widget-item .fields-group.fields-group-change-indicator hr {
grid-column: 1 / -1;
margin: 0;
width: 100%;
border: solid #888888;
border-width: 1px 0 0 0; }
- form.dashboard-widget-item .fields-group-description .field-fluid,
- form.dashboard-widget-item .fields-group-value .field-fluid,
- form.dashboard-widget-item .fields-group-time .field-fluid,
- form.dashboard-widget-item .fields-group-change-indicator .field-fluid {
+ form.dashboard-widget-item .fields-group.fields-group-description .field-fluid, form.dashboard-widget-item .fields-group.fields-group-value .field-fluid, form.dashboard-widget-item .fields-group.fields-group-time .field-fluid, form.dashboard-widget-item .fields-group.fields-group-change-indicator .field-fluid {
grid-column: 2 / -1; }
- form.dashboard-widget-item .fields-group-description .offset-3,
- form.dashboard-widget-item .fields-group-value .offset-3,
- form.dashboard-widget-item .fields-group-time .offset-3,
- form.dashboard-widget-item .fields-group-change-indicator .offset-3 {
+ form.dashboard-widget-item .fields-group.fields-group-description .offset-3, form.dashboard-widget-item .fields-group.fields-group-value .offset-3, form.dashboard-widget-item .fields-group.fields-group-time .offset-3, form.dashboard-widget-item .fields-group.fields-group-change-indicator .offset-3 {
grid-column-start: 3; }
- form.dashboard-widget-item .fields-group-description .field-size input,
- form.dashboard-widget-item .fields-group-value .field-size input,
- form.dashboard-widget-item .fields-group-time .field-size input,
- form.dashboard-widget-item .fields-group-change-indicator .field-size input {
+ form.dashboard-widget-item .fields-group.fields-group-description .field-size input, form.dashboard-widget-item .fields-group.fields-group-value .field-size input, form.dashboard-widget-item .fields-group.fields-group-time .field-size input, form.dashboard-widget-item .fields-group.fields-group-change-indicator .field-size input {
margin-right: 5px; }
- form.dashboard-widget-item .fields-group-description .form-field,
- form.dashboard-widget-item .fields-group-value .form-field,
- form.dashboard-widget-item .fields-group-time .form-field,
- form.dashboard-widget-item .fields-group-change-indicator .form-field {
+ form.dashboard-widget-item .fields-group.fields-group-description .form-field, form.dashboard-widget-item .fields-group.fields-group-value .form-field, form.dashboard-widget-item .fields-group.fields-group-time .form-field, form.dashboard-widget-item .fields-group.fields-group-change-indicator .form-field {
line-height: 24px; }
-form.dashboard-widget-item .fields-group-description .form-field:nth-child(1) {
+form.dashboard-widget-item .fields-group.fields-group-description .form-field:nth-child(1) {
grid-column: 1 / -1; }
-form.dashboard-widget-item .fields-group-value {
+form.dashboard-widget-item .fields-group.fields-group-value {
grid-template-columns: minmax(100px, max-content) 3fr max-content auto; }
- form.dashboard-widget-item .fields-group-value .units-show {
+ form.dashboard-widget-item .fields-group.fields-group-value .units-show {
display: flex; }
- form.dashboard-widget-item .fields-group-value .units-show label[for='units'] {
+ form.dashboard-widget-item .fields-group.fields-group-value .units-show label[for='units'] {
width: 100%; }
-form.dashboard-widget-item .fields-group-change-indicator {
+form.dashboard-widget-item .fields-group.fields-group-change-indicator {
grid-template-columns: repeat(3, max-content 96px); }
-form.dashboard-widget-item .fields-group-change-indicator .input-color-picker {
- display: block; }
+ form.dashboard-widget-item .fields-group.fields-group-change-indicator .input-color-picker {
+ display: block; }
-div.dashboard-widget-item {
+div.dashboard-widget-item > div {
box-sizing: border-box;
height: 100%;
padding: 10px;
overflow-x: hidden; }
- div.dashboard-widget-item a {
- box-sizing: border-box;
- display: flex;
- flex-direction: column;
- height: 100%;
- color: inherit; }
- div.dashboard-widget-item a:focus, div.dashboard-widget-item a:hover, div.dashboard-widget-item a:visited {
- border: none; }
- div.dashboard-widget-item a > div {
- display: flex;
- flex: 1 1 calc(100% / 3); }
- div.dashboard-widget-item .item-description,
- div.dashboard-widget-item .item-value,
- div.dashboard-widget-item .item-time {
- flex: 1 1 auto;
- max-width: 100%; }
- div.dashboard-widget-item .item-value {
+div.dashboard-widget-item a {
+ box-sizing: border-box;
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ color: inherit; }
+ div.dashboard-widget-item a:focus, div.dashboard-widget-item a:hover, div.dashboard-widget-item a:visited {
+ border: none; }
+ div.dashboard-widget-item a > div {
display: flex;
- flex-wrap: wrap;
- margin: 0 5px; }
- div.dashboard-widget-item .item-value > .units:first-child, div.dashboard-widget-item .item-value > .units:last-child {
- flex: 0 0 100%; }
- div.dashboard-widget-item .item-value > .units:first-child {
- margin-bottom: -0.07em; }
- div.dashboard-widget-item .item-value > .units:last-child {
- margin-top: -0.07em; }
- div.dashboard-widget-item .item-value.type-text {
+ flex: 1 1 calc(100% / 3); }
+div.dashboard-widget-item .item-description,
+div.dashboard-widget-item .item-value,
+div.dashboard-widget-item .item-time {
+ flex: 1 1 auto;
+ max-width: 100%; }
+div.dashboard-widget-item .item-value {
+ display: flex;
+ flex-wrap: wrap;
+ margin: 0 5px; }
+ div.dashboard-widget-item .item-value > .units:first-child, div.dashboard-widget-item .item-value > .units:last-child {
+ flex: 0 0 100%; }
+ div.dashboard-widget-item .item-value > .units:first-child {
+ margin-bottom: -0.07em; }
+ div.dashboard-widget-item .item-value > .units:last-child {
+ margin-top: -0.07em; }
+ div.dashboard-widget-item .item-value.type-text {
+ min-width: 0; }
+ div.dashboard-widget-item .item-value.type-text .item-value-content {
min-width: 0; }
- div.dashboard-widget-item .item-value.type-text .item-value-content {
- min-width: 0; }
- div.dashboard-widget-item .item-value-content {
- display: flex;
- align-items: baseline;
- overflow: hidden; }
- div.dashboard-widget-item .item-description,
- div.dashboard-widget-item .item-time,
- div.dashboard-widget-item .type-text .value {
- display: block;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis; }
- div.dashboard-widget-item .item-description,
- div.dashboard-widget-item .value,
- div.dashboard-widget-item .decimals,
- div.dashboard-widget-item .units,
- div.dashboard-widget-item .item-time {
- font-size: calc(var(--content-height) * var(--widget-item-font) / 1.14);
- line-height: 1.14; }
- div.dashboard-widget-item .units:not(:last-child),
- div.dashboard-widget-item .change-indicator:not(:last-child) {
- margin-right: 5px; }
- div.dashboard-widget-item .units:not(:first-child),
- div.dashboard-widget-item .change-indicator:not(:first-child) {
- margin-left: 5px; }
- div.dashboard-widget-item .svg-arrow {
- height: calc(var(--content-height) * var(--widget-item-font) * 0.72 / 1.14); }
- div.dashboard-widget-item .item-value-no-data {
- color: #333333; }
- div.dashboard-widget-item .left {
- justify-content: flex-start;
- max-width: max-content;
- margin-right: auto; }
- div.dashboard-widget-item .center {
- justify-content: center; }
- div.dashboard-widget-item .right {
- justify-content: flex-end;
- max-width: max-content;
- margin-left: auto; }
- div.dashboard-widget-item .top {
- align-self: flex-start; }
- div.dashboard-widget-item .middle {
- align-self: center; }
- div.dashboard-widget-item .bottom {
- align-self: flex-end; }
- div.dashboard-widget-item .bold {
- font-weight: bold; }
+div.dashboard-widget-item .item-value-content {
+ display: flex;
+ align-items: baseline;
+ overflow: hidden; }
+div.dashboard-widget-item .item-description,
+div.dashboard-widget-item .item-time,
+div.dashboard-widget-item .type-text .value {
+ display: block;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis; }
+div.dashboard-widget-item .item-description,
+div.dashboard-widget-item .value,
+div.dashboard-widget-item .decimals,
+div.dashboard-widget-item .units,
+div.dashboard-widget-item .item-time {
+ font-size: calc(var(--content-height) * var(--widget-item-font) / 1.14);
+ line-height: 1.14; }
+div.dashboard-widget-item .units:not(:last-child),
+div.dashboard-widget-item .change-indicator:not(:last-child) {
+ margin-right: 5px; }
+div.dashboard-widget-item .units:not(:first-child),
+div.dashboard-widget-item .change-indicator:not(:first-child) {
+ margin-left: 5px; }
+div.dashboard-widget-item .svg-arrow {
+ height: calc(var(--content-height) * var(--widget-item-font) * 0.72 / 1.14); }
+div.dashboard-widget-item .item-value-no-data {
+ color: #333333; }
+div.dashboard-widget-item .left {
+ justify-content: flex-start;
+ max-width: max-content;
+ margin-right: auto; }
+div.dashboard-widget-item .center {
+ justify-content: center; }
+div.dashboard-widget-item .right {
+ justify-content: flex-end;
+ max-width: max-content;
+ margin-left: auto; }
+div.dashboard-widget-item .top {
+ align-self: flex-start; }
+div.dashboard-widget-item .middle {
+ align-self: center; }
+div.dashboard-widget-item .bottom {
+ align-self: flex-end; }
+div.dashboard-widget-item .bold {
+ font-weight: bold; }
.dashboard-widget-item .svg-arrow-up {
fill: #3DC51D; }
@@ -1683,40 +1724,47 @@ div.dashboard-widget-slareport .date-vertical {
writing-mode: vertical-lr;
transform: rotate(180deg); }
+form.dashboard-widget-svggraph .svg-graph-preview,
form.dashboard-widget-svggraph .graph-widget-config-tabs {
- padding: 10px 0; }
- form.dashboard-widget-svggraph .graph-widget-config-tabs > .tabs-nav {
- margin-right: 0;
- margin-left: 0;
- border-top: 1px solid #9f9f9f; }
- form.dashboard-widget-svggraph .graph-widget-config-tabs .ui-tabs-nav {
- position: sticky;
+ grid-column: 1 / -1; }
+form.dashboard-widget-svggraph .svg-graph-preview {
+ position: relative;
+ min-width: 1110px;
+ height: 300px; }
+ form.dashboard-widget-svggraph .svg-graph-preview > div {
+ position: absolute;
top: 0;
- background: #f3f3f3;
+ right: 0;
+ left: 0;
+ margin: 0 -10px;
+ height: 300px;
+ background: #ffffff;
z-index: 3; }
+form.dashboard-widget-svggraph .graph-widget-config-tabs > .tabs-nav {
+ border-top: 1px solid #9f9f9f; }
+form.dashboard-widget-svggraph .graph-widget-config-tabs .ui-tabs-nav {
+ position: sticky;
+ top: 0;
+ background: #f3f3f3;
+ z-index: 3; }
form.dashboard-widget-svggraph .table-forms-container, form.dashboard-widget-svggraph .browser-warning-container {
+ margin: -10px 0 0 0;
border: 1px solid #9f9f9f;
border-top: none; }
form.dashboard-widget-svggraph .table-forms-separator {
padding: 0; }
-form.dashboard-widget-svggraph .dataset-head {
- display: grid;
- grid-template-columns: 24px 24px 1fr 1fr 24px;
- grid-gap: 10px;
- align-items: start; }
+form.dashboard-widget-svggraph .dataset-head,
form.dashboard-widget-svggraph .dataset-body.list-accordion-item-body {
- display: grid;
- grid-template-columns: 24px 1fr 1fr 24px;
- grid-gap: 10px;
- align-items: start;
- position: relative;
- margin-top: 10px; }
- form.dashboard-widget-svggraph .dataset-body.list-accordion-item-body .form-grid {
- padding-top: 0; }
- form.dashboard-widget-svggraph .dataset-body.list-accordion-item-body .form-grid:first-child {
- grid-column-start: 2; }
+ display: contents; }
+form.dashboard-widget-svggraph .dataset-head .multiselect {
+ width: 100%; }
+form.dashboard-widget-svggraph .dataset-body .form-grid {
+ padding-top: 0; }
+ form.dashboard-widget-svggraph .dataset-body .form-grid:first-child {
+ grid-column-start: 3; }
form.dashboard-widget-svggraph .drag-icon {
position: absolute;
+ top: 5px;
left: -14px; }
form.dashboard-widget-svggraph .td-drag-icon .drag-icon {
top: 0;
@@ -1738,13 +1786,13 @@ form.dashboard-widget-svggraph .list-vertical-accordion {
overflow: visible;
margin-top: -5px;
margin-bottom: -5px; }
- form.dashboard-widget-svggraph .list-vertical-accordion .list-accordion-item-head {
- padding: 0; }
form.dashboard-widget-svggraph .list-accordion-item {
position: relative;
- width: 100%;
- padding: 5px 0;
- list-style-type: none; }
+ display: grid;
+ grid-template-columns: 24px 24px 1fr 1fr 24px;
+ grid-gap: 10px;
+ align-items: start;
+ padding: 5px 0; }
form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-opened::before {
content: ' ';
position: absolute;
@@ -1756,8 +1804,6 @@ form.dashboard-widget-svggraph .list-accordion-item {
form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .multiselect {
height: 24px;
overflow: hidden; }
- form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .dataset-body {
- display: none; }
form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .dataset-head .table-forms-separator {
border: none; }
form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .dataset-head .single-item-table thead,
@@ -1765,6 +1811,8 @@ form.dashboard-widget-svggraph .list-accordion-item {
form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .dataset-head .single-item-table .table-col-handle,
form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .dataset-head .single-item-table .table-col-action {
display: none; }
+ form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .dataset-body {
+ display: none; }
form.dashboard-widget-svggraph .list-accordion-item.list-accordion-item-closed .items-list {
padding-left: 0; }
form.dashboard-widget-svggraph .single-item-table .table-col-handle {
@@ -1783,11 +1831,83 @@ form.dashboard-widget-svggraph .single-item-table .single-item-table-row:last-ch
padding-bottom: 0; }
form.dashboard-widget-svggraph .single-item-table tfoot td {
padding: 5px 5px 5px 10px; }
+form.dashboard-widget-svggraph .overrides-list {
+ position: relative;
+ margin: -5px 0 -5px 15px; }
+form.dashboard-widget-svggraph .overrides-list-item {
+ position: relative;
+ display: grid;
+ grid-template-columns: 1fr 1fr 24px;
+ grid-gap: 5px 10px;
+ align-items: start;
+ padding: 5px 0; }
+ form.dashboard-widget-svggraph .overrides-list-item.sortable {
+ overflow: visible;
+ margin-top: -5px;
+ margin-bottom: -5px; }
+ form.dashboard-widget-svggraph .overrides-list-item .multiselect {
+ width: 100%; }
+ form.dashboard-widget-svggraph .overrides-list-item .btn-remove {
+ right: 0;
+ top: 0;
+ vertical-align: baseline; }
+form.dashboard-widget-svggraph .overrides-foot {
+ padding: 5px 0; }
+form.dashboard-widget-svggraph .overrides-options-list {
+ grid-column: 1 / -1;
+ padding: 0 24px 8px 0;
+ border-bottom: 1px solid #888888;
+ white-space: normal; }
+ form.dashboard-widget-svggraph .overrides-options-list > li {
+ display: inline-block;
+ margin-right: 5px;
+ margin-bottom: 2px;
+ line-height: 22px;
+ white-space: nowrap; }
+ form.dashboard-widget-svggraph .overrides-options-list > li .color-picker {
+ line-height: 22px; }
+ form.dashboard-widget-svggraph .overrides-options-list > li > div {
+ position: relative;
+ padding: 1px 18px 1px 1px;
+ background-color: #333333;
+ border-radius: 2px; }
+ form.dashboard-widget-svggraph .overrides-options-list > li > div > span {
+ color: white;
+ padding-left: 8px;
+ line-height: 22px; }
+ form.dashboard-widget-svggraph .overrides-options-list > li > div > input[type=text] {
+ border-style: none;
+ line-height: 22px;
+ min-height: 22px;
+ width: 85px; }
+ form.dashboard-widget-svggraph .overrides-options-list > li > div > .subfilter-disable-btn {
+ position: absolute;
+ right: 0;
+ top: 0;
+ min-height: 24px; }
+ form.dashboard-widget-svggraph .overrides-options-list .btn-alt .plus-icon {
+ margin-right: 0; }
+ form.dashboard-widget-svggraph .overrides-options-list .color-picker .color-picker-preview {
+ margin: 1px;
+ width: 20px;
+ min-height: 20px;
+ background-position: -323px -411px; }
form.dashboard-widget-svggraph .no-items-message {
display: none;
line-height: 24px;
color: #333333; }
+[theme="hc-dark"] form.dashboard-widget-svggraph .overrides-options-list > li > div {
+ border: 1px solid #888888;
+ background-color: transparent !important; }
+ [theme="hc-dark"] form.dashboard-widget-svggraph .overrides-options-list > li > div > .subfilter-disable-btn {
+ border: none !important;
+ top: 0; }
+
+[theme="hc-light"] form.dashboard-widget-svggraph .overrides-options-list > li > div > .subfilter-disable-btn {
+ border: none !important;
+ top: 0; }
+
form.dashboard-widget-tophosts #list_columns .text {
max-width: 250px; }
form.dashboard-widget-tophosts #column {
@@ -2542,6 +2662,49 @@ div.dashboard-widget-tophosts z-bar-gauge {
font-size: 0;
border-left: 1px solid #ffffff; }
+section {
+ background-color: #ffffff;
+ border: 1px solid #9f9f9f; }
+ section .section-head {
+ display: flex;
+ height: 32px;
+ line-height: 32px; }
+ section .section-head h4 {
+ padding: 0 10px;
+ margin-right: auto;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ font-weight: bold;
+ line-height: inherit;
+ color: #262626; }
+ section .section-toggle {
+ width: 24px;
+ height: 24px;
+ margin: 2px 2px 0 auto;
+ background: url("../img/icon-sprite.svg?20220722") no-repeat -6px -654px; }
+ section .section-foot {
+ padding: 0 10px;
+ text-align: right;
+ line-height: 32px;
+ color: #333333; }
+ section.section-collapsed .section-body,
+ section.section-collapsed .section-foot {
+ display: none; }
+ section.section-collapsed .section-toggle {
+ background-position: -6px -689px; }
+ section:not(:last-child) {
+ margin-bottom: 10px; }
+ section .list-table {
+ border: 0; }
+ section .list-table tbody tr:last-child td {
+ border-bottom: 1px solid #888888; }
+ section .list-table td:first-child,
+ section .list-table th:first-child {
+ padding-left: 10px; }
+ section .list-table td:last-child,
+ section .list-table th:last-child {
+ padding-right: 10px; }
+
.service-info {
margin: -10px 0;
border-left: 4px solid #009900; }
@@ -4498,13 +4661,13 @@ button {
width: 24px;
height: 24px; }
-.filter-container.tabfilter-container .icon-edit, .btn-dashboard-page-properties, .btn-iterator-page-previous, .btn-iterator-page-next, .btn-widget-action, .btn-widget-collapse, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle, .btn-widget-expand, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle, .btn-widget-edit, .btn-alarm-on, .btn-alarm-off, .btn-sound-on, .btn-sound-off, .btn-info-clock, .btn-dashboard-conf, .interfaces .interface-row[data-type="2"] .interface-btn-toggle {
+section .section-toggle, .filter-container.tabfilter-container .icon-edit, .btn-dashboard-page-properties, .btn-iterator-page-previous, .btn-iterator-page-next, .btn-widget-action, .btn-widget-collapse, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle, .btn-widget-expand, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle, .btn-widget-edit, .btn-alarm-on, .btn-alarm-off, .btn-sound-on, .btn-sound-off, .btn-info-clock, .btn-dashboard-conf, .interfaces .interface-row[data-type="2"] .interface-btn-toggle {
border: 0;
min-height: 0;
padding: 0;
opacity: .5;
transition: opacity .2s ease-out; }
- .filter-container.tabfilter-container [disabled].icon-edit, [disabled].btn-dashboard-page-properties, [disabled].btn-iterator-page-previous, [disabled].btn-iterator-page-next, [disabled].btn-widget-action, [disabled].btn-widget-collapse, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle, [disabled].btn-widget-expand, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle, [disabled].btn-widget-edit, [disabled].btn-alarm-on, [disabled].btn-alarm-off, [disabled].btn-sound-on, [disabled].btn-sound-off, [disabled].btn-info-clock, [disabled].btn-dashboard-conf, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle, .filter-container.tabfilter-container [disabled].icon-edit:hover, [disabled].btn-dashboard-page-properties:hover, [disabled].btn-iterator-page-previous:hover, [disabled].btn-iterator-page-next:hover, [disabled].btn-widget-action:hover, [disabled].btn-widget-collapse:hover, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle:hover, [disabled].btn-widget-expand:hover, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle:hover, [disabled].btn-widget-edit:hover, [disabled].btn-alarm-on:hover, [disabled].btn-alarm-off:hover, [disabled].btn-sound-on:hover, [disabled].btn-sound-off:hover, [disabled].btn-info-clock:hover, [disabled].btn-dashboard-conf:hover, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle:hover, .filter-container.tabfilter-container [disabled].icon-edit:focus, [disabled].btn-dashboard-page-properties:focus, [disabled].btn-iterator-page-previous:focus, [disabled].btn-iterator-page-next:focus, [disabled].btn-widget-action:focus, [disabled].btn-widget-collapse:focus, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle:focus, [disabled].btn-widget-expand:focus, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle:focus, [disabled].btn-widget-edit:focus, [disabled].btn-alarm-on:focus, [disabled].btn-alarm-off:focus, [disabled].btn-sound-on:focus, [disabled].btn-sound-off:focus, [disabled].btn-info-clock:focus, [disabled].btn-dashboard-conf:focus, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle:focus, .filter-container.tabfilter-container [disabled].icon-edit:active, [disabled].btn-dashboard-page-properties:active, [disabled].btn-iterator-page-previous:active, [disabled].btn-iterator-page-next:active, [disabled].btn-widget-action:active, [disabled].btn-widget-collapse:active, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle:active, [disabled].btn-widget-expand:active, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle:active, [disabled].btn-widget-edit:active, [disabled].btn-alarm-on:active, [disabled].btn-alarm-off:active, [disabled].btn-sound-on:active, [disabled].btn-sound-off:active, [disabled].btn-info-clock:active, [disabled].btn-dashboard-conf:active, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle:active {
+ section [disabled].section-toggle, .filter-container.tabfilter-container [disabled].icon-edit, [disabled].btn-dashboard-page-properties, [disabled].btn-iterator-page-previous, [disabled].btn-iterator-page-next, [disabled].btn-widget-action, [disabled].btn-widget-collapse, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle, [disabled].btn-widget-expand, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle, [disabled].btn-widget-edit, [disabled].btn-alarm-on, [disabled].btn-alarm-off, [disabled].btn-sound-on, [disabled].btn-sound-off, [disabled].btn-info-clock, [disabled].btn-dashboard-conf, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle, section [disabled].section-toggle:hover, .filter-container.tabfilter-container [disabled].icon-edit:hover, [disabled].btn-dashboard-page-properties:hover, [disabled].btn-iterator-page-previous:hover, [disabled].btn-iterator-page-next:hover, [disabled].btn-widget-action:hover, [disabled].btn-widget-collapse:hover, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle:hover, [disabled].btn-widget-expand:hover, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle:hover, [disabled].btn-widget-edit:hover, [disabled].btn-alarm-on:hover, [disabled].btn-alarm-off:hover, [disabled].btn-sound-on:hover, [disabled].btn-sound-off:hover, [disabled].btn-info-clock:hover, [disabled].btn-dashboard-conf:hover, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle:hover, section [disabled].section-toggle:focus, .filter-container.tabfilter-container [disabled].icon-edit:focus, [disabled].btn-dashboard-page-properties:focus, [disabled].btn-iterator-page-previous:focus, [disabled].btn-iterator-page-next:focus, [disabled].btn-widget-action:focus, [disabled].btn-widget-collapse:focus, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle:focus, [disabled].btn-widget-expand:focus, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle:focus, [disabled].btn-widget-edit:focus, [disabled].btn-alarm-on:focus, [disabled].btn-alarm-off:focus, [disabled].btn-sound-on:focus, [disabled].btn-sound-off:focus, [disabled].btn-info-clock:focus, [disabled].btn-dashboard-conf:focus, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle:focus, section [disabled].section-toggle:active, .filter-container.tabfilter-container [disabled].icon-edit:active, [disabled].btn-dashboard-page-properties:active, [disabled].btn-iterator-page-previous:active, [disabled].btn-iterator-page-next:active, [disabled].btn-widget-action:active, [disabled].btn-widget-collapse:active, .list-vertical-accordion .list-accordion-item-opened [disabled].list-accordion-item-toggle:active, [disabled].btn-widget-expand:active, .list-vertical-accordion .list-accordion-item-closed [disabled].list-accordion-item-toggle:active, [disabled].btn-widget-edit:active, [disabled].btn-alarm-on:active, [disabled].btn-alarm-off:active, [disabled].btn-sound-on:active, [disabled].btn-sound-off:active, [disabled].btn-info-clock:active, [disabled].btn-dashboard-conf:active, .interfaces .interface-row[data-type="2"] [disabled].interface-btn-toggle:active {
background-color: transparent;
opacity: .25; }
@@ -4532,7 +4695,7 @@ button[disabled], button[disabled]:hover, button[disabled]:active {
.inaccessible .subfilter-enabled {
color: #bfbfbf; }
-.filter-container.tabfilter-container .icon-edit:hover, .btn-dashboard-page-properties:hover, .btn-iterator-page-previous:hover, .btn-iterator-page-next:hover, .btn-widget-action:hover, .btn-widget-collapse:hover, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle:hover, .btn-widget-expand:hover, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle:hover, .btn-widget-edit:hover, .btn-alarm-on:hover, .btn-alarm-off:hover, .btn-sound-on:hover, .btn-sound-off:hover, .btn-info-clock:hover, .btn-dashboard-conf:hover, .interfaces .interface-row[data-type="2"] .interface-btn-toggle:hover, .filter-container.tabfilter-container .icon-edit:focus, .btn-dashboard-page-properties:focus, .btn-iterator-page-previous:focus, .btn-iterator-page-next:focus, .btn-widget-action:focus, .btn-widget-collapse:focus, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle:focus, .btn-widget-expand:focus, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle:focus, .btn-widget-edit:focus, .btn-alarm-on:focus, .btn-alarm-off:focus, .btn-sound-on:focus, .btn-sound-off:focus, .btn-info-clock:focus, .btn-dashboard-conf:focus, .interfaces .interface-row[data-type="2"] .interface-btn-toggle:focus, .filter-container.tabfilter-container .icon-edit:active, .btn-dashboard-page-properties:active, .btn-iterator-page-previous:active, .btn-iterator-page-next:active, .btn-widget-action:active, .btn-widget-collapse:active, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle:active, .btn-widget-expand:active, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle:active, .btn-widget-edit:active, .btn-alarm-on:active, .btn-alarm-off:active, .btn-sound-on:active, .btn-sound-off:active, .btn-info-clock:active, .btn-dashboard-conf:active, .interfaces .interface-row[data-type="2"] .interface-btn-toggle:active {
+section .section-toggle:hover, .filter-container.tabfilter-container .icon-edit:hover, .btn-dashboard-page-properties:hover, .btn-iterator-page-previous:hover, .btn-iterator-page-next:hover, .btn-widget-action:hover, .btn-widget-collapse:hover, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle:hover, .btn-widget-expand:hover, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle:hover, .btn-widget-edit:hover, .btn-alarm-on:hover, .btn-alarm-off:hover, .btn-sound-on:hover, .btn-sound-off:hover, .btn-info-clock:hover, .btn-dashboard-conf:hover, .interfaces .interface-row[data-type="2"] .interface-btn-toggle:hover, section .section-toggle:focus, .filter-container.tabfilter-container .icon-edit:focus, .btn-dashboard-page-properties:focus, .btn-iterator-page-previous:focus, .btn-iterator-page-next:focus, .btn-widget-action:focus, .btn-widget-collapse:focus, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle:focus, .btn-widget-expand:focus, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle:focus, .btn-widget-edit:focus, .btn-alarm-on:focus, .btn-alarm-off:focus, .btn-sound-on:focus, .btn-sound-off:focus, .btn-info-clock:focus, .btn-dashboard-conf:focus, .interfaces .interface-row[data-type="2"] .interface-btn-toggle:focus, section .section-toggle:active, .filter-container.tabfilter-container .icon-edit:active, .btn-dashboard-page-properties:active, .btn-iterator-page-previous:active, .btn-iterator-page-next:active, .btn-widget-action:active, .btn-widget-collapse:active, .list-vertical-accordion .list-accordion-item-opened .list-accordion-item-toggle:active, .btn-widget-expand:active, .list-vertical-accordion .list-accordion-item-closed .list-accordion-item-toggle:active, .btn-widget-edit:active, .btn-alarm-on:active, .btn-alarm-off:active, .btn-sound-on:active, .btn-sound-off:active, .btn-info-clock:active, .btn-dashboard-conf:active, .interfaces .interface-row[data-type="2"] .interface-btn-toggle:active {
background-color: transparent;
opacity: 1; }
@@ -4625,16 +4788,16 @@ button[disabled], button[disabled]:hover, button[disabled]:active {
content: ''; }
.icon-tree-top-bottom::before {
- background-position: url("../img/icon-sprite.svg?20220722") no-repeat -84px -300px; }
+ background-position: -84px -300px; }
.icon-tree-top-bottom-right::before {
- background-position: url("../img/icon-sprite.svg?20220722") no-repeat -84px -334px; }
+ background-position: -84px -334px; }
.icon-tree-top-right::before {
- background-position: url("../img/icon-sprite.svg?20220722") no-repeat -84px -372px; }
+ background-position: -84px -372px; }
.icon-tree-empty::before {
- background-position: url("../img/icon-sprite.svg?20220722") no-repeat -84px -350px; }
+ background-position: -84px -350px; }
.icon-cal {
background: transparent url("../img/icon-sprite.svg?20220722") no-repeat -42px -834px; }
@@ -4915,7 +5078,7 @@ button[disabled], button[disabled]:hover, button[disabled]:active {
overflow: hidden;
margin: 0 10px; }
.overlay-dialogue.modal .dashboard-widget-head {
- margin-bottom: 14px; }
+ margin-bottom: 12px; }
.overlay-dialogue.modal .dashboard-widget-head .icon-doc-link {
margin-right: -26px; }
.overlay-dialogue.modal .dashboard-widget-head .overlay-close-btn {
@@ -4928,9 +5091,11 @@ button[disabled], button[disabled]:hover, button[disabled]:active {
width: 100%;
max-height: calc(100vh - 220px);
max-width: inherit;
- margin: 0 -10px 10px;
+ margin: 0 -10px 8px;
padding: 0 10px;
position: relative; }
+ .overlay-dialogue.modal .overlay-dialogue-body > form {
+ padding: 2px 0; }
.overlay-dialogue.modal .overlay-dialogue-body .table-forms .table-forms-td-right {
padding-right: 8px; }
.overlay-dialogue.modal .overlay-dialogue-body .table-forms .table-forms-row-with-second-field {
@@ -5327,20 +5492,6 @@ button[disabled], button[disabled]:hover, button[disabled]:active {
stroke: #990000;
stroke-width: 2px; }
-.svg-graph-preview {
- margin-top: 10px;
- min-width: 1120px;
- height: 300px;
- position: relative; }
- .svg-graph-preview > div {
- background: #ffffff;
- height: 300px;
- position: absolute;
- left: 0;
- right: 0;
- top: 0;
- z-index: 3; }
-
.svg-graph-hintbox {
font-size: 12px;
line-height: 18px;
@@ -5884,22 +6035,22 @@ span.is-loading {
padding: 10px 0 0;
text-align: center; }
-.dashboard-grid-widget-content, div.dashboard-widget-item, .msg-details ul, z-select button.focusable,
+.dashboard-grid-widget-content, div.dashboard-widget-item > div, .msg-details ul, z-select button.focusable,
.z-select button.focusable, z-select .list,
.z-select .list, .multiselect-available, textarea, select, .setup-right-body, .overlay-dialogue.modal .overlay-dialogue-body, .overlay-dialogue .hintbox-wrap, .overlay-dialogue .maps-container, .notif-body, .debug-output, .overlay-descr, .overflow-table, .import-compare .toc,
.import-compare .diff {
scrollbar-width: thin; }
- .dashboard-grid-widget-content::-webkit-scrollbar, div.dashboard-widget-item::-webkit-scrollbar, .msg-details ul::-webkit-scrollbar, z-select button.focusable::-webkit-scrollbar,
+ .dashboard-grid-widget-content::-webkit-scrollbar, div.dashboard-widget-item > div::-webkit-scrollbar, .msg-details ul::-webkit-scrollbar, z-select button.focusable::-webkit-scrollbar,
.z-select button.focusable::-webkit-scrollbar, z-select .list::-webkit-scrollbar,
.z-select .list::-webkit-scrollbar, .multiselect-available::-webkit-scrollbar, textarea::-webkit-scrollbar, select::-webkit-scrollbar, .setup-right-body::-webkit-scrollbar, .overlay-dialogue.modal .overlay-dialogue-body::-webkit-scrollbar, .overlay-dialogue .hintbox-wrap::-webkit-scrollbar, .overlay-dialogue .maps-container::-webkit-scrollbar, .notif-body::-webkit-scrollbar, .debug-output::-webkit-scrollbar, .overlay-descr::-webkit-scrollbar, .overflow-table::-webkit-scrollbar, .import-compare .toc::-webkit-scrollbar,
.import-compare .diff::-webkit-scrollbar {
width: 9px; }
- .dashboard-grid-widget-content::-webkit-scrollbar-track, div.dashboard-widget-item::-webkit-scrollbar-track, .msg-details ul::-webkit-scrollbar-track, z-select button.focusable::-webkit-scrollbar-track,
+ .dashboard-grid-widget-content::-webkit-scrollbar-track, div.dashboard-widget-item > div::-webkit-scrollbar-track, .msg-details ul::-webkit-scrollbar-track, z-select button.focusable::-webkit-scrollbar-track,
.z-select button.focusable::-webkit-scrollbar-track, z-select .list::-webkit-scrollbar-track,
.z-select .list::-webkit-scrollbar-track, .multiselect-available::-webkit-scrollbar-track, textarea::-webkit-scrollbar-track, select::-webkit-scrollbar-track, .setup-right-body::-webkit-scrollbar-track, .overlay-dialogue.modal .overlay-dialogue-body::-webkit-scrollbar-track, .overlay-dialogue .hintbox-wrap::-webkit-scrollbar-track, .overlay-dialogue .maps-container::-webkit-scrollbar-track, .notif-body::-webkit-scrollbar-track, .debug-output::-webkit-scrollbar-track, .overlay-descr::-webkit-scrollbar-track, .overflow-table::-webkit-scrollbar-track, .import-compare .toc::-webkit-scrollbar-track,
.import-compare .diff::-webkit-scrollbar-track {
background-color: #999999; }
- .dashboard-grid-widget-content::-webkit-scrollbar-thumb, div.dashboard-widget-item::-webkit-scrollbar-thumb, .msg-details ul::-webkit-scrollbar-thumb, z-select button.focusable::-webkit-scrollbar-thumb,
+ .dashboard-grid-widget-content::-webkit-scrollbar-thumb, div.dashboard-widget-item > div::-webkit-scrollbar-thumb, .msg-details ul::-webkit-scrollbar-thumb, z-select button.focusable::-webkit-scrollbar-thumb,
.z-select button.focusable::-webkit-scrollbar-thumb, z-select .list::-webkit-scrollbar-thumb,
.z-select .list::-webkit-scrollbar-thumb, .multiselect-available::-webkit-scrollbar-thumb, textarea::-webkit-scrollbar-thumb, select::-webkit-scrollbar-thumb, .setup-right-body::-webkit-scrollbar-thumb, .overlay-dialogue.modal .overlay-dialogue-body::-webkit-scrollbar-thumb, .overlay-dialogue .hintbox-wrap::-webkit-scrollbar-thumb, .overlay-dialogue .maps-container::-webkit-scrollbar-thumb, .notif-body::-webkit-scrollbar-thumb, .debug-output::-webkit-scrollbar-thumb, .overlay-descr::-webkit-scrollbar-thumb, .overflow-table::-webkit-scrollbar-thumb, .import-compare .toc::-webkit-scrollbar-thumb,
.import-compare .diff::-webkit-scrollbar-thumb {
@@ -6040,53 +6191,6 @@ svg {
white-space: normal;
word-break: break-word; }
-.overrides-list {
- display: table;
- width: 90%;
- max-width: 738px;
- padding-left: 15px; }
- .overrides-list .overrides-list-item {
- display: table-row; }
- .overrides-list .overrides-list-item .btn-remove {
- position: relative;
- right: -73px;
- top: 3px; }
-
-.overrides-options-list {
- white-space: normal;
- padding: 5px 0 8px;
- margin-bottom: 10px;
- border-bottom: 1px solid #888888; }
- .overrides-options-list > li {
- display: inline-block;
- margin: 2px 7px 2px 0;
- white-space: nowrap;
- vertical-align: middle; }
- .overrides-options-list > li > div {
- position: relative;
- padding: 1px 18px 1px 1px;
- background-color: #333333;
- border-radius: 2px; }
- .overrides-options-list > li > div > span {
- color: white;
- padding-left: 8px;
- line-height: 22px; }
- .overrides-options-list > li > div > input[type=text] {
- border-style: none;
- line-height: 22px;
- min-height: 22px;
- width: 85px; }
- .overrides-options-list > li > div > .subfilter-disable-btn {
- position: absolute;
- right: 0;
- top: 0;
- min-height: 24px; }
- .overrides-options-list .color-picker .color-picker-preview {
- margin: 1px;
- width: 20px;
- min-height: 20px;
- background-position: -323px -411px; }
-
.list-accordion-foot > div {
display: table-cell;
padding-top: 10px; }
@@ -6132,63 +6236,6 @@ svg {
text-overflow: ellipsis;
line-height: 24px; }
-.columns-wrapper {
- display: flex;
- flex-wrap: wrap;
- align-items: start; }
- .columns-wrapper.columns-nowrap {
- flex-wrap: nowrap; }
- .columns-wrapper.columns-2 > div,
- .columns-wrapper.columns-2 > li {
- display: block;
- flex: 0 0 50%;
- max-width: 50%; }
- .columns-wrapper.columns-3 > div,
- .columns-wrapper.columns-3 > li {
- display: block;
- flex: 0 0 33.33333%;
- max-width: 33.33333%; }
- .columns-wrapper .column-5 {
- flex: 0 0 5%;
- max-width: 5%; }
- .columns-wrapper .column-10 {
- flex: 0 0 10%;
- max-width: 10%; }
- .columns-wrapper .column-15 {
- flex: 0 0 15%;
- max-width: 15%; }
- .columns-wrapper .column-20 {
- flex: 0 0 20%;
- max-width: 20%; }
- .columns-wrapper .column-33 {
- flex: 0 0 33.33333%;
- max-width: 33.33333%; }
- .columns-wrapper .column-35 {
- flex: 0 0 35%;
- max-width: 35%; }
- .columns-wrapper .column-40 {
- flex: 0 0 40%;
- max-width: 40%; }
- .columns-wrapper .column-50 {
- flex: 0 0 50%;
- max-width: 50%; }
- .columns-wrapper .column-75 {
- flex: 0 0 75%;
- max-width: 75%; }
- .columns-wrapper .column-90 {
- flex: 0 0 90%;
- max-width: 90%; }
- .columns-wrapper .column-95 {
- flex: 0 0 95%;
- max-width: 95%; }
- .columns-wrapper .column-center {
- display: flex;
- justify-content: center;
- text-align: center; }
- .columns-wrapper .column-middle {
- display: flex;
- align-items: center; }
-
.preprocessing-list {
display: block;
max-width: 930px;
@@ -7938,12 +7985,6 @@ td.inactive-bg {
.problem-icon-list .status-disaster-bg::before {
background-position: -472px -409px; }
-.overrides-options-list > li > div {
- background-color: #333333 !important; }
- .overrides-options-list > li > div > .subfilter-disable-btn {
- border: none !important;
- top: 0; }
-
.totals-list > div {
border-top: 1px solid #9f9f9f;
color: #000000; }
@@ -7985,3 +8026,8 @@ td.inactive-bg {
background-position: -165px -690px; }
.interfaces .interface-row[data-type="2"].list-accordion-item-opened .interface-btn-toggle {
background-position: -165px -655px; }
+
+section .section-toggle {
+ background-position: -165px -654px; }
+section.section-collapsed .section-toggle {
+ background-position: -165px -690px; }
diff --git a/ui/hostinventoriesoverview.php b/ui/hostinventoriesoverview.php
index 97750f5e7b2..d1e3ed30286 100644
--- a/ui/hostinventoriesoverview.php
+++ b/ui/hostinventoriesoverview.php
@@ -142,7 +142,7 @@ $select_groupby = (new CSelect('filter_groupby'))
->addOption(new CSelectOption('', _('not selected')))
->addOptions(CSelect::createOptionsFromArray($inventories));
-(new CWidget())
+(new CHtmlPage())
->setTitle(_('Host inventory overview'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::INVENTORY_HOST_OVERVIEW))
->addItem(
diff --git a/ui/httpdetails.php b/ui/httpdetails.php
index 0aa84c36788..61a14f9a76b 100644
--- a/ui/httpdetails.php
+++ b/ui/httpdetails.php
@@ -181,7 +181,7 @@ $graph_time->insertFlickerfreeJs();
CScreenBuilder::insertScreenStandardJs($graph_in->timeline);
// Create graphs widget.
-$widget = (new CWidget())
+(new CHtmlPage())
->setTitle(_('Details of web scenario').': '.$http_test_name)
->setWebLayoutMode($page['web_layout_mode'])
->setControls((new CTag('nav', true,
diff --git a/ui/include/classes/api/services/CConfiguration.php b/ui/include/classes/api/services/CConfiguration.php
index fe93d89239d..fe3f85c7f23 100644
--- a/ui/include/classes/api/services/CConfiguration.php
+++ b/ui/include/classes/api/services/CConfiguration.php
@@ -209,9 +209,7 @@ class CConfiguration extends CApiService {
->setStrict(true)
->validate($data, '/');
- $all_versions = ['1.0', '2.0', '3.0', '3.2', '3.4', '4.0', '4.2', '4.4', '5.0', '5.2', '5.4', '6.0', '6.2'];
-
- foreach ($all_versions as $version) {
+ foreach ($import_converter_factory::getSequentialVersions() as $version) {
if ($data['zabbix_export']['version'] !== $version) {
continue;
}
@@ -281,7 +279,7 @@ class CConfiguration extends CApiService {
->setPreview(true)
->validate($data, '/');
- foreach (['1.0', '2.0', '3.0', '3.2', '3.4', '4.0', '4.2', '4.4', '5.0', '5.2', '5.4', '6.0'] as $version) {
+ foreach ($import_converter_factory::getSequentialVersions() as $version) {
if ($data['zabbix_export']['version'] !== $version) {
continue;
}
diff --git a/ui/include/classes/api/services/CModule.php b/ui/include/classes/api/services/CModule.php
index b2190d10e98..9b060c26e7e 100644
--- a/ui/include/classes/api/services/CModule.php
+++ b/ui/include/classes/api/services/CModule.php
@@ -132,7 +132,7 @@ class CModule extends CApiService {
*
* @param array $modules
*
- * @throws APIException if the input is invalid.
+ * @throws APIException|JsonException
*/
private static function validateCreate(array &$modules): void {
$api_input_rules = ['type' => API_OBJECTS, 'flags' => API_NOT_EMPTY | API_NORMALIZE, 'fields' => [
@@ -147,7 +147,7 @@ class CModule extends CApiService {
}
foreach ($modules as &$module) {
- $module['config'] = json_encode($module['config']);
+ $module['config'] = json_encode($module['config'], JSON_THROW_ON_ERROR);
}
unset($module);
}
@@ -196,7 +196,7 @@ class CModule extends CApiService {
* @param array $modules
* @param array|null $db_modules
*
- * @throws APIException if the input is invalid.
+ * @throws APIException|JsonException
*/
private static function validateUpdate(array &$modules, array &$db_modules = null): void {
$api_input_rules = ['type' => API_OBJECTS, 'flags' => API_NOT_EMPTY | API_NORMALIZE, 'uniq' => [['moduleid']], 'fields' => [
@@ -221,7 +221,7 @@ class CModule extends CApiService {
foreach ($modules as &$module) {
if (array_key_exists('config', $module)) {
- $module['config'] = json_encode($module['config']);
+ $module['config'] = json_encode($module['config'], JSON_THROW_ON_ERROR);
}
}
unset($module);
diff --git a/ui/include/classes/api/services/CRole.php b/ui/include/classes/api/services/CRole.php
index 34ff83732d4..fb87a1d1c20 100644
--- a/ui/include/classes/api/services/CRole.php
+++ b/ui/include/classes/api/services/CRole.php
@@ -700,7 +700,7 @@ class CRole extends CApiService {
return;
}
- $unavailable_moduleids = array_diff(array_keys($moduleids), self::getEnabledModuleIds());
+ $unavailable_moduleids = array_diff(array_keys($moduleids), self::getModuleIds());
if ($unavailable_moduleids) {
self::exception(ZBX_API_ERROR_PARAMETERS,
@@ -1036,7 +1036,7 @@ class CRole extends CApiService {
$index = 0;
- foreach (self::getEnabledModuleIds() as $moduleid) {
+ foreach (self::getModuleIds() as $moduleid) {
if (array_key_exists($moduleid, $new_modules_rules)) {
$module_status = $new_modules_rules[$moduleid]['status'];
}
@@ -1154,7 +1154,7 @@ class CRole extends CApiService {
* @return array
*/
protected function applyQueryFilterOptions($table_name, $table_alias, array $options, array $sql_parts): array {
- $sqlParts = parent::applyQueryFilterOptions($table_name, $table_alias, $options, $sql_parts);
+ $sql_parts = parent::applyQueryFilterOptions($table_name, $table_alias, $options, $sql_parts);
if (self::$userData['type'] != USER_TYPE_SUPER_ADMIN) {
$sql_parts['from']['users'] = 'users u';
@@ -1162,7 +1162,7 @@ class CRole extends CApiService {
$sql_parts['where'][] = 'u.userid='.self::$userData['userid'];
}
- return $sqlParts;
+ return $sql_parts;
}
/**
@@ -1417,7 +1417,7 @@ class CRole extends CApiService {
if (in_array('modules', $output, true)) {
$modules = [];
- foreach (self::getEnabledModuleIds() as $moduleid) {
+ foreach (self::getModuleIds() as $moduleid) {
$modules[$moduleid] = [
'moduleid' => $moduleid,
'status' => $modules_default_access
@@ -1520,12 +1520,9 @@ class CRole extends CApiService {
*
* @throws APIException
*/
- private static function getEnabledModuleIds(): array {
+ private static function getModuleIds(): array {
$modules = API::getApiService('module')->get([
'output' => [],
- 'filter' => [
- 'status' => MODULE_STATUS_ENABLED
- ],
'preservekeys' => true
], false);
diff --git a/ui/include/classes/core/CModule.php b/ui/include/classes/core/CModule.php
index 86cac8653ba..41c52c44492 100644
--- a/ui/include/classes/core/CModule.php
+++ b/ui/include/classes/core/CModule.php
@@ -19,119 +19,115 @@
**/
-namespace Core;
+namespace Zabbix\Core;
-use CController as CAction;
+use API,
+ CController as CAction;
/**
* Base class for user modules. If Module.php is not provided by user module, this class will be instantiated instead.
*/
class CModule {
- /**
- * Module directory path.
- *
- * @var string
- */
- private $dir;
+ public const TYPE_MODULE = 'module';
+ public const TYPE_WIDGET = 'widget';
- /**
- * Module manifest.
- *
- * @var array
- */
- private $manifest;
+ protected array $manifest;
+ protected string $moduleid;
+ protected string $relative_path;
- /**
- * @param string $dir Module directory path.
- * @param array $manifest Module manifest.
- */
- public function __construct(string $dir, array $manifest) {
- $this->dir = $dir;
+ public function __construct(array $manifest, string $moduleid, string $relative_path) {
$this->manifest = $manifest;
+ $this->moduleid = $moduleid;
+ $this->relative_path = $relative_path;
}
- /**
- * Initialize module.
- */
public function init(): void {
}
- /**
- * Get module directory path.
- *
- * @return string
- */
- final public function getDir(): string {
- return $this->dir;
- }
-
- /**
- * Get module manifest.
- *
- * @return array
- */
- final public function getManifest(): array {
+ public function getManifest(): array {
return $this->manifest;
}
- /**
- * Get module id.
- *
- * @return string
- */
- final public function getId(): string {
+ public function getId(): string {
return $this->manifest['id'];
}
- /**
- * Get module namespace.
- *
- * @return string
- */
- final public function getNamespace(): string {
+ public function getName(): string {
+ return $this->manifest['name'];
+ }
+
+ public function getNamespace(): string {
return $this->manifest['namespace'];
}
- /**
- * Get module version.
- *
- * @return string
- */
- final public function getVersion(): string {
+ public function getVersion(): string {
return $this->manifest['version'];
}
- /**
- * Get module actions.
- *
- * @return array
- */
- final public function getActions(): array {
+ public function getType(): string {
+ return $this->manifest['type'];
+ }
+
+ public function getAuthor(): string {
+ return $this->manifest['author'];
+ }
+
+ public function getUrl(): string {
+ return $this->manifest['url'];
+ }
+
+ public function getDescription(): string {
+ return $this->manifest['description'];
+ }
+
+ public function getActions(): array {
return $this->manifest['actions'];
}
- /**
- * Get module configuration.
- *
- * @return array
- */
- final public function getConfig(): array {
+ public function getAssets(): array {
+ return $this->manifest['assets'];
+ }
+
+ public function getConfig(): array {
return $this->manifest['config'];
}
+ public function setConfig(array $config): self {
+ $this->manifest['config'] = $config;
+
+ API::Module()->update([[
+ 'moduleid' => $this->moduleid,
+ 'config' => $config
+ ]]);
+
+ return $this;
+ }
+
/**
* Get module configuration option.
*
- * @param string $name Option name.
- * @param mixed $default Default value.
+ * @param string|null $name Option name.
+ * @param mixed $default Default value.
*
* @return mixed Configuration option (if exists) or the $default value.
*/
- final public function getOption(string $name = null, $default = null) {
+ public function getOption(string $name = null, $default = null) {
return array_key_exists($name, $this->manifest['config']) ? $this->manifest['config'][$name] : $default;
}
+ public function getModuleId(): string {
+ return $this->moduleid;
+ }
+
+ public function getRelativePath(): string {
+ return $this->relative_path;
+ }
+
+ public function getTranslationStrings(): array {
+ return [];
+ }
+
/**
* Event handler, triggered before executing the action.
*
diff --git a/ui/include/classes/core/CModuleManager.php b/ui/include/classes/core/CModuleManager.php
index d54a96b593c..cf3f1229dbb 100644
--- a/ui/include/classes/core/CModuleManager.php
+++ b/ui/include/classes/core/CModuleManager.php
@@ -19,8 +19,12 @@
**/
-use Core\CModule,
- CController as CAction;
+use CController as CAction;
+
+use Zabbix\Core\{
+ CModule,
+ CWidget
+};
/**
* Module manager class for testing and loading user modules.
@@ -28,64 +32,65 @@ use Core\CModule,
final class CModuleManager {
/**
+ * Lowest supported manifest version.
+ */
+ private const MIN_MANIFEST_VERSION = 2;
+
+ /**
* Highest supported manifest version.
*/
- const MAX_MANIFEST_VERSION = 1;
+ private const MAX_MANIFEST_VERSION = 2;
/**
- * Home path of modules.
- *
- * @var string
+ * Root path of modules.
+ */
+ private string $root_path;
+
+ /**
+ * Current action name.
*/
- private $modules_dir;
+ private string $action_name;
/**
* Manifest data of added modules.
- *
- * @var array
*/
- private $manifests = [];
+ private array $manifests = [];
/**
- * List of instantiated, initialized modules.
- *
- * @var array
+ * DB moduleids of added modules.
*/
- private $modules = [];
+ private array $moduleids = [];
/**
- * List of errors caused by module initialization.
- *
- * @var array
+ * List of instantiated, initialized modules.
*/
- private $errors = [];
+ private array $modules = [];
/**
- * @param string $modules_dir Home path of modules.
+ * List of errors caused by module initialization.
*/
- public function __construct(string $modules_dir) {
- $this->modules_dir = $modules_dir;
- }
+ private array $errors = [];
/**
- * Get home path of modules.
- *
- * @return string
+ * @param string $root_path Root path of modules.
*/
- public function getModulesDir(): string {
- return $this->modules_dir;
+ public function __construct(string $root_path) {
+ $this->root_path = $root_path;
}
/**
* Add module and prepare it's manifest data.
*
* @param string $relative_path Relative path to the module.
- * @param string $id Stored module ID to optionally check the manifest module ID against.
+ * @param string|null $moduleid DB module ID.
+ * @param string|null $id Stored module ID to optionally check the manifest module ID against.
* @param array|null $config Override configuration to use instead of one stored in the manifest file.
*
* @return array|null Either manifest data or null if manifest file had errors or IDs didn't match.
*/
- public function addModule(string $relative_path, string $id = null, array $config = null): ?array {
+ public function addModule(string $relative_path, string $moduleid = null, string $id = null,
+ array $config = null): ?array {
+
$manifest = $this->loadManifest($relative_path);
// Ignore module without a valid manifest.
@@ -104,88 +109,12 @@ final class CModuleManager {
}
$this->manifests[$relative_path] = $manifest;
+ $this->moduleids[$relative_path] = $moduleid;
return $manifest;
}
- /**
- * Get namespaces of all added modules.
- *
- * @return array
- */
- public function getNamespaces(): array {
- $namespaces = [];
-
- foreach ($this->manifests as $relative_path => $manifest) {
- $module_path = $this->modules_dir.'/'.$relative_path;
- $namespaces['Modules\\'.$manifest['namespace']] = [$module_path];
- }
-
- return $namespaces;
- }
-
- /**
- * Check added modules for conflicts.
- *
- * @return array Lists of conflicts and conflicting modules.
- */
- public function checkConflicts(): array {
- $ids = [];
- $namespaces = [];
- $actions = [];
-
- foreach ($this->manifests as $relative_path => $manifest) {
- $ids[$manifest['id']][] = $relative_path;
- $namespaces[$manifest['namespace']][] = $relative_path;
- foreach (array_keys($manifest['actions']) as $action_name) {
- $actions[$action_name][] = $relative_path;
- }
- }
-
- foreach (['ids', 'namespaces', 'actions'] as $var) {
- $$var = array_filter($$var, function($list) {
- return count($list) > 1;
- });
- }
-
- $conflicts = [];
- $conflicting_manifests = [];
-
- foreach ($ids as $id => $relative_paths) {
- $conflicts[] = _s('Identical ID (%1$s) is used by modules located at %2$s.', $id,
- implode(', ', $relative_paths)
- );
- $conflicting_manifests = array_merge($conflicting_manifests, $relative_paths);
- }
-
- foreach ($namespaces as $namespace => $relative_paths) {
- $conflicts[] = _s('Identical namespace (%1$s) is used by modules located at %2$s.', $namespace,
- implode(', ', $relative_paths)
- );
- $conflicting_manifests = array_merge($conflicting_manifests, $relative_paths);
- }
-
- $relative_paths = array_unique(array_reduce($actions, function($carry, $item) {
- return array_merge($carry, $item);
- }, []));
-
- if ($relative_paths) {
- $conflicts[] = _s('Identical actions are used by modules located at %1$s.', implode(', ', $relative_paths));
- $conflicting_manifests = array_merge($conflicting_manifests, $relative_paths);
- }
-
- return [
- 'conflicts' => $conflicts,
- 'conflicting_manifests' => array_unique($conflicting_manifests)
- ];
- }
-
- /**
- * Check, instantiate and initialize all added modules.
- *
- * @return array List of initialized modules.
- */
- public function initModules(): array {
+ public function initModules(): void {
[
'conflicts' => $this->errors,
'conflicting_manifests' => $conflicting_manifests
@@ -194,63 +123,66 @@ final class CModuleManager {
$non_conflicting_manifests = array_diff_key($this->manifests, array_flip($conflicting_manifests));
foreach ($non_conflicting_manifests as $relative_path => $manifest) {
- $path = $this->modules_dir.'/'.$relative_path;
+ $base_classname = $manifest['type'] === CModule::TYPE_WIDGET ? CWidget::class : CModule::class;
+ $classname = $manifest['type'] === CModule::TYPE_WIDGET ? 'Widget' : 'Module';
- if (is_file($path.'/Module.php')) {
- $module_class = implode('\\', ['Modules', $manifest['namespace'], 'Module']);
+ $module_class = $base_classname;
+
+ try {
+ if (is_file($this->root_path.'/'.$relative_path.'/'.$classname.'.php')) {
+ $module_class = implode('\\', [$manifest['namespace'], $classname]);
- if (!class_exists($module_class, true)) {
- $this->errors[] = _s('Wrong Module.php class name for module located at %1$s.', $relative_path);
+ if (!class_exists($module_class)) {
+ $this->errors[] = _s('Wrong %1$s.php class name for module located at %2$s.', $classname,
+ $relative_path
+ );
- continue;
+ return;
+ }
}
- }
- else {
- $module_class = CModule::class;
- }
- try {
/** @var CModule $instance */
- $instance = new $module_class($path, $manifest);
+ $instance = new $module_class($manifest, $this->moduleids[$relative_path], $relative_path);
- if ($instance instanceof CModule) {
+ if ($instance instanceof $base_classname) {
$instance->init();
$this->modules[$instance->getId()] = $instance;
}
else {
- $this->errors[] = _s('Module.php class must extend %1$s for module located at %2$s.',
- CModule::class, $relative_path
+ $this->errors[] = _s('%1$s.php class must extend %2$s for module located at %3$s.',
+ $classname, $base_classname, $relative_path
);
}
}
- catch (Exception $e) {
+ catch (Throwable $e) {
$this->errors[] = _s('%1$s - thrown by module located at %2$s.', $e->getMessage(), $relative_path);
}
}
-
- return $this->modules;
}
/**
- * Get add initialized modules.
- *
- * @return array
+ * Get initialized modules.
*/
public function getModules(): array {
return $this->modules;
}
+ public function setActionName(string $action_name): self {
+ $this->action_name = $action_name;
+
+ return $this;
+ }
+
/**
- * Get loaded module instance associated with given action name.
- *
- * @param string $action_name
+ * Get loaded module instance associated with action.
*
* @return CModule|null
*/
- public function getModuleByActionName(string $action_name): ?CModule {
+ public function getActionModule(): ?CModule {
+ /** @var CModule $module */
foreach ($this->modules as $module) {
- if (array_key_exists($action_name, $module->getActions())) {
+ if (array_key_exists($this->action_name, $module->getActions())) {
return $module;
}
}
@@ -259,17 +191,69 @@ final class CModuleManager {
}
/**
+ * Get initialized widget modules.
+ */
+ public function getWidgets(bool $for_template_dashboard_only = false): array {
+ $widgets = [];
+
+ /** @var CWidget $widget */
+ foreach ($this->modules as $widget) {
+ if (!($widget instanceof CWidget) || ($for_template_dashboard_only && !$widget->hasTemplateSupport())) {
+ continue;
+ }
+ $widgets[$widget->getId()] = $widget;
+ }
+
+ return $widgets;
+ }
+
+ public function getWidgetsDefaults(bool $for_template_dashboard_only = false): array {
+ $widget_defaults = [];
+
+ /** @var CWidget $widget */
+ foreach (APP::ModuleManager()->getWidgets($for_template_dashboard_only) as $widget) {
+ $widget_defaults[$widget->getId()] = $widget->getDefaults();
+ }
+
+ return $widget_defaults;
+ }
+
+ public function getModule($module_id): ?CModule {
+ if (!array_key_exists($module_id, $this->modules)) {
+ return null;
+ }
+
+ return $this->modules[$module_id];
+ }
+
+ public function getManifests(): array {
+ return $this->manifests;
+ }
+
+ /**
+ * Get namespaces of all added modules.
+ */
+ public function getNamespaces(): array {
+ $namespaces = [];
+
+ foreach ($this->manifests as $relative_path => $manifest) {
+ $namespaces[$manifest['namespace']] = [$this->root_path.'/'.$relative_path];
+ }
+
+ return $namespaces;
+ }
+
+ /**
* Get actions of all initialized modules.
- *
- * @return array
*/
public function getActions(): array {
$actions = [];
+ /** @var CModule $module */
foreach ($this->modules as $module) {
foreach ($module->getActions() as $name => $data) {
$actions[$name] = [
- 'class' => implode('\\', ['Modules', $module->getNamespace(), 'Actions',
+ 'class' => implode('\\', [$module->getNamespace(), 'Actions',
str_replace('/', '\\', $data['class'])
]),
'layout' => array_key_exists('layout', $data) ? $data['layout'] : 'layout.htmlpage',
@@ -281,6 +265,86 @@ final class CModuleManager {
return $actions;
}
+ public function getAssets(): array {
+ $assets = [];
+
+ /** @var CModule $module */
+ foreach ($this->modules as $module) {
+ if ($module->getType() === CModule::TYPE_WIDGET && !CRouter::isDashboardAction($this->action_name)) {
+ continue;
+ }
+
+ $assets[$module->getId()] = $module->getAssets();
+ }
+
+ return $assets;
+ }
+
+ /**
+ * Get errors encountered while module initialization.
+ */
+ public function getErrors(): array {
+ return $this->errors;
+ }
+
+ /**
+ * Check added modules for conflicts.
+ *
+ * @return array Lists of conflicts and conflicting modules.
+ */
+ public function checkConflicts(): array {
+ $ids = [];
+ $namespaces = [];
+ $actions = [];
+
+ foreach ($this->manifests as $relative_path => $manifest) {
+ $ids[$manifest['id']][] = $relative_path;
+ $namespaces[$manifest['namespace']][] = $relative_path;
+ foreach (array_keys($manifest['actions']) as $action_name) {
+ $actions[$action_name][] = $relative_path;
+ }
+ }
+
+ foreach (['ids', 'namespaces', 'actions'] as $var) {
+ $$var = array_filter($$var, static function($list) {
+ return count($list) > 1;
+ });
+ }
+
+ $conflicts = [];
+ $conflicting_manifests = [];
+
+ foreach ($ids as $id => $relative_paths) {
+ $conflicts[] = _s('Identical ID (%1$s) is used by modules located at %2$s.', $id,
+ implode(', ', $relative_paths)
+ );
+ $conflicting_manifests = array_merge($conflicting_manifests, $relative_paths);
+ }
+
+ foreach ($namespaces as $namespace => $relative_paths) {
+ $conflicts[] = _s('Identical namespace (%1$s) is used by modules located at %2$s.', $namespace,
+ implode(', ', $relative_paths)
+ );
+ $conflicting_manifests = array_merge($conflicting_manifests, $relative_paths);
+ }
+
+ $relative_paths = array_unique(array_reduce($actions, static function($carry, $item) {
+ return array_merge($carry, $item);
+ }, []));
+
+ if ($relative_paths) {
+ $conflicts[] = _s('Identical actions are used by modules located at %1$s.', implode(', ', $relative_paths));
+ $conflicting_manifests = array_merge($conflicting_manifests, $relative_paths);
+ }
+
+ $this->errors = $conflicts;
+
+ return [
+ 'conflicts' => $conflicts,
+ 'conflicting_manifests' => array_unique($conflicting_manifests)
+ ];
+ }
+
/**
* Publish an event to all loaded modules. The module of the responsible action will be served last.
*
@@ -288,7 +352,7 @@ final class CModuleManager {
* @param string $event Event to publish.
*/
public function publishEvent(CAction $action, string $event): void {
- $action_module = $this->getModuleByActionName($action->getAction());
+ $action_module = $this->getActionModule();
foreach ($this->modules as $module) {
if ($module != $action_module) {
@@ -302,15 +366,6 @@ final class CModuleManager {
}
/**
- * Get errors encountered while module initialization.
- *
- * @return array
- */
- public function getErrors(): array {
- return $this->errors;
- }
-
- /**
* Load and parse module manifest file.
*
* @param string $relative_path Relative path to the module.
@@ -318,8 +373,13 @@ final class CModuleManager {
* @return array|null Either manifest data or null if manifest file had errors.
*/
private function loadManifest(string $relative_path): ?array {
- $module_path = $this->modules_dir.'/'.$relative_path;
- $manifest_file_name = $module_path.'/manifest.json';
+ $relative_path_parts = explode('/', $relative_path, 2);
+
+ if (count($relative_path_parts) != 2) {
+ return null;
+ }
+
+ $manifest_file_name = $this->root_path.'/'.$relative_path.'/manifest.json';
if (!is_file($manifest_file_name) || !is_readable($manifest_file_name)) {
return null;
@@ -343,24 +403,60 @@ final class CModuleManager {
}
// Check manifest version.
- if (!is_numeric($manifest['manifest_version']) || $manifest['manifest_version'] > self::MAX_MANIFEST_VERSION) {
+ if (!is_numeric($manifest['manifest_version']) || $manifest['manifest_version'] < self::MIN_MANIFEST_VERSION
+ || $manifest['manifest_version'] > self::MAX_MANIFEST_VERSION) {
+ return null;
+ }
+
+ if (trim($manifest['id']) === '' || trim($manifest['name']) === '') {
return null;
}
// Check manifest namespace syntax.
- if (!preg_match('/^[a-z_]+$/i', $manifest['namespace'])) {
+ if (!preg_match('/^[0-9a-z_]+$/i', $manifest['namespace'])) {
+ return null;
+ }
+
+ $manifest['namespace'] = ucfirst($relative_path_parts[0]).'\\'.$manifest['namespace'];
+
+ // Check module type.
+ if (array_key_exists('type', $manifest)
+ && !in_array($manifest['type'], [CModule::TYPE_MODULE, CModule::TYPE_WIDGET], true)) {
return null;
}
// Ensure empty defaults.
$manifest += [
+ 'type' => CModule::TYPE_MODULE,
'author' => '',
'url' => '',
'description' => '',
'actions' => [],
+ 'assets' => [],
'config' => []
];
+ $manifest['assets'] += [
+ 'css' => [],
+ 'js' => []
+ ];
+
+ if ($manifest['type'] === CModule::TYPE_WIDGET) {
+ if (!array_key_exists('widget', $manifest)) {
+ $manifest['widget'] = [];
+ }
+
+ $manifest['widget'] += [
+ 'name' => '',
+ 'form_class' => CWidget::DEFAULT_FORM_CLASS,
+ 'js_class' => CWidget::DEFAULT_JS_CLASS,
+ 'size' => CWidget::DEFAULT_SIZE,
+ 'refresh_rate' => CWidget::DEFAULT_REFRESH_RATE,
+ 'template_support' => false,
+ 'use_time_selector' => false
+ ];
+ }
+
return $manifest;
}
}
diff --git a/ui/include/classes/core/CWidget.php b/ui/include/classes/core/CWidget.php
new file mode 100755
index 00000000000..9824972d19c
--- /dev/null
+++ b/ui/include/classes/core/CWidget.php
@@ -0,0 +1,164 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Zabbix\Core;
+
+use CControllerDashboardWidgetEdit;
+
+use Zabbix\Widgets\CWidgetForm;
+
+use Zabbix\Widgets\Fields\CWidgetFieldSelect;
+
+/**
+ * Base class for user widgets. If Widget.php is not provided by user widget, this class will be instantiated instead.
+ */
+class CWidget extends CModule {
+
+ public const DEFAULT_FORM_CLASS = 'WidgetForm';
+ public const DEFAULT_JS_CLASS = 'CWidget';
+ public const DEFAULT_SIZE = ['width' => 12, 'height' => 5];
+ public const DEFAULT_REFRESH_RATE = 60;
+
+ // Dashboard widget dynamic state.
+ public const SIMPLE_ITEM = 0;
+ public const DYNAMIC_ITEM = 1;
+
+ final public function getForm(array $values, ?string $templateid): CWidgetForm {
+ $form_class = implode('\\', [$this->getNamespace(), 'Includes', $this->manifest['widget']['form_class']]);
+
+ if (!class_exists($form_class)) {
+ $form_class = CWidgetForm::class;
+ }
+
+ $form = new $form_class($values, $templateid);
+
+ if ($templateid === null) {
+ $refresh_rates = self::getRefreshRates();
+
+ $form->addField(
+ (new CWidgetFieldSelect('rf_rate', _('Refresh interval'),
+ [
+ -1 => _('Default').' ('.$refresh_rates[$this->getDefaultRefreshRate()].')'
+ ] + $refresh_rates
+ ))->setDefault(-1)
+ );
+ }
+
+ return $form
+ ->addFields()
+ ->setFieldsValues();
+ }
+
+ final public function getActions(): array {
+ $actions = parent::getActions() + [
+ 'widget.'.$this->getId().'.view' => [],
+ 'widget.'.$this->getId().'.edit' => []
+ ];
+
+ $actions['widget.'.$this->getId().'.view'] += [
+ 'class' => 'WidgetView',
+ 'view' => 'widget.view',
+ 'layout' => 'layout.widget'
+ ];
+
+ $actions['widget.'.$this->getId().'.edit'] += [
+ 'class' => CControllerDashboardWidgetEdit::class,
+ 'view' => 'widget.edit',
+ 'layout' => 'layout.json'
+ ];
+
+ return $actions;
+ }
+
+ public function getDefaults(): array {
+ return [
+ 'name' => $this->getDefaultName(),
+ 'size' => $this->getDefaultSize(),
+ 'js_class' => $this->getJSClass()
+ ];
+ }
+
+ public function isDeprecated(): bool {
+ return false;
+ }
+
+ public function getDefaultName(): string {
+ return $this->manifest['widget']['name'] !== ''
+ ? $this->manifest['widget']['name']
+ : $this->getName();
+ }
+
+ public function getDefaultSize(): array {
+ $size = $this->manifest['widget']['size'];
+
+ if (!array_key_exists('width', $size) || !array_key_exists('height', $size)) {
+ return self::DEFAULT_SIZE;
+ }
+
+ if ($size['width'] < 1) {
+ $size['width'] = 1;
+ }
+
+ if ($size['width'] > DASHBOARD_MAX_COLUMNS) {
+ $size['width'] = DASHBOARD_MAX_COLUMNS;
+ }
+
+ if ($size['height'] < DASHBOARD_WIDGET_MIN_ROWS) {
+ $size['height'] = DASHBOARD_WIDGET_MIN_ROWS;
+ }
+
+ if ($size['height'] > DASHBOARD_WIDGET_MAX_ROWS) {
+ $size['height'] = DASHBOARD_WIDGET_MAX_ROWS;
+ }
+
+ return $size;
+ }
+
+ public function getJSClass(): string {
+ return $this->manifest['widget']['js_class'];
+ }
+
+ public function getDefaultRefreshRate(): int {
+ return array_key_exists($this->manifest['widget']['refresh_rate'], self::getRefreshRates())
+ ? (int) $this->manifest['widget']['refresh_rate']
+ : self::DEFAULT_REFRESH_RATE;
+ }
+
+ public function hasTemplateSupport(): bool {
+ return (bool) $this->manifest['widget']['template_support'];
+ }
+
+ public function usesTimeSelector(array $fields_values): bool {
+ return (bool) $this->manifest['widget']['use_time_selector'];
+ }
+
+ private static function getRefreshRates(): array {
+ return [
+ 0 => _('No refresh'),
+ 10 => _n('%1$s second', '%1$s seconds', 10),
+ 30 => _n('%1$s second', '%1$s seconds', 30),
+ 60 => _n('%1$s minute', '%1$s minutes', 1),
+ 120 => _n('%1$s minute', '%1$s minutes', 2),
+ 600 => _n('%1$s minute', '%1$s minutes', 10),
+ 900 => _n('%1$s minute', '%1$s minutes', 15)
+ ];
+ }
+}
diff --git a/ui/include/classes/core/ZBase.php b/ui/include/classes/core/ZBase.php
index 21e406536b7..697c6b28500 100644
--- a/ui/include/classes/core/ZBase.php
+++ b/ui/include/classes/core/ZBase.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,8 +19,9 @@
**/
-use Core\CModule,
- CController as CAction;
+use Zabbix\Core\CModule;
+
+use CController as CAction;
require_once dirname(__FILE__).'/CAutoloader.php';
@@ -42,7 +43,7 @@ class ZBase {
*
* @var string
*/
- protected $rootDir;
+ protected $root_dir;
/**
* @var array of config data from zabbix config file
@@ -71,10 +72,9 @@ class ZBase {
*/
private $mode;
- /**
- * @var CModuleManager
- */
- private $module_manager;
+ private CModuleManager $module_manager;
+
+ private ?CView $view = null;
/**
* Returns the current instance of APP.
@@ -83,7 +83,7 @@ class ZBase {
*
* @return APP
*/
- public static function getInstance() {
+ public static function getInstance(): APP {
if (self::$instance === null) {
self::$instance = new static;
}
@@ -96,7 +96,7 @@ class ZBase {
*
* @return CComponentRegistry
*/
- public static function Component() {
+ public static function Component(): CComponentRegistry {
return self::getInstance()->component_registry;
}
@@ -105,15 +105,22 @@ class ZBase {
*
* @return CModuleManager
*/
- public static function ModuleManager() {
+ public static function ModuleManager(): CModuleManager {
return self::getInstance()->module_manager;
}
/**
+ * @return CView|null
+ */
+ public static function View(): ?CView {
+ return self::getInstance()->view;
+ }
+
+ /**
* Init modules required to run frontend.
*/
protected function init() {
- $this->rootDir = $this->findRootDir();
+ $this->root_dir = $this->findRootDir();
$this->initAutoloader();
$this->component_registry = new CComponentRegistry;
@@ -195,6 +202,7 @@ class ZBase {
$this->initComponents();
$this->initModuleManager();
+ /** @var CRouter $router */
$router = $this->component_registry->get('router');
$router->addActions($this->module_manager->getActions());
$router->setAction($action_name);
@@ -268,11 +276,9 @@ class ZBase {
/**
* Returns the absolute path to the root dir.
- *
- * @return string
*/
- public static function getRootDir() {
- return self::getInstance()->rootDir;
+ public static function getRootDir(): string {
+ return self::getInstance()->root_dir;
}
/**
@@ -291,68 +297,64 @@ class ZBase {
*/
private function getIncludePaths() {
return [
- $this->rootDir.'/include/classes/api',
- $this->rootDir.'/include/classes/api/services',
- $this->rootDir.'/include/classes/api/helpers',
- $this->rootDir.'/include/classes/api/item_types',
- $this->rootDir.'/include/classes/api/managers',
- $this->rootDir.'/include/classes/api/clients',
- $this->rootDir.'/include/classes/api/wrappers',
- $this->rootDir.'/include/classes/core',
- $this->rootDir.'/include/classes/data',
- $this->rootDir.'/include/classes/mvc',
- $this->rootDir.'/include/classes/db',
- $this->rootDir.'/include/classes/debug',
- $this->rootDir.'/include/classes/validators',
- $this->rootDir.'/include/classes/validators/schema',
- $this->rootDir.'/include/classes/validators/string',
- $this->rootDir.'/include/classes/validators/object',
- $this->rootDir.'/include/classes/validators/hostgroup',
- $this->rootDir.'/include/classes/validators/host',
- $this->rootDir.'/include/classes/validators/hostprototype',
- $this->rootDir.'/include/classes/validators/event',
- $this->rootDir.'/include/classes/export',
- $this->rootDir.'/include/classes/export/writers',
- $this->rootDir.'/include/classes/export/elements',
- $this->rootDir.'/include/classes/graph',
- $this->rootDir.'/include/classes/graphdraw',
- $this->rootDir.'/include/classes/import',
- $this->rootDir.'/include/classes/import/converters',
- $this->rootDir.'/include/classes/import/importers',
- $this->rootDir.'/include/classes/import/preprocessors',
- $this->rootDir.'/include/classes/import/readers',
- $this->rootDir.'/include/classes/import/validators',
- $this->rootDir.'/include/classes/items',
- $this->rootDir.'/include/classes/triggers',
- $this->rootDir.'/include/classes/server',
- $this->rootDir.'/include/classes/screens',
- $this->rootDir.'/include/classes/services',
- $this->rootDir.'/include/classes/sysmaps',
- $this->rootDir.'/include/classes/helpers',
- $this->rootDir.'/include/classes/helpers/trigger',
- $this->rootDir.'/include/classes/macros',
- $this->rootDir.'/include/classes/html',
- $this->rootDir.'/include/classes/html/pageheader',
- $this->rootDir.'/include/classes/html/svg',
- $this->rootDir.'/include/classes/html/widget',
- $this->rootDir.'/include/classes/html/interfaces',
- $this->rootDir.'/include/classes/parsers',
- $this->rootDir.'/include/classes/parsers/results',
- $this->rootDir.'/include/classes/controllers',
- $this->rootDir.'/include/classes/routing',
- $this->rootDir.'/include/classes/json',
- $this->rootDir.'/include/classes/user',
- $this->rootDir.'/include/classes/setup',
- $this->rootDir.'/include/classes/regexp',
- $this->rootDir.'/include/classes/ldap',
- $this->rootDir.'/include/classes/pagefilter',
- $this->rootDir.'/include/classes/widgets/fields',
- $this->rootDir.'/include/classes/widgets/forms',
- $this->rootDir.'/include/classes/widgets',
- $this->rootDir.'/include/classes/xml',
- $this->rootDir.'/include/classes/vaults',
- $this->rootDir.'/local/app/controllers',
- $this->rootDir.'/app/controllers'
+ $this->root_dir.'/include/classes/api',
+ $this->root_dir.'/include/classes/api/services',
+ $this->root_dir.'/include/classes/api/helpers',
+ $this->root_dir.'/include/classes/api/item_types',
+ $this->root_dir.'/include/classes/api/managers',
+ $this->root_dir.'/include/classes/api/clients',
+ $this->root_dir.'/include/classes/api/wrappers',
+ $this->root_dir.'/include/classes/core',
+ $this->root_dir.'/include/classes/data',
+ $this->root_dir.'/include/classes/mvc',
+ $this->root_dir.'/include/classes/db',
+ $this->root_dir.'/include/classes/debug',
+ $this->root_dir.'/include/classes/validators',
+ $this->root_dir.'/include/classes/validators/schema',
+ $this->root_dir.'/include/classes/validators/string',
+ $this->root_dir.'/include/classes/validators/object',
+ $this->root_dir.'/include/classes/validators/hostgroup',
+ $this->root_dir.'/include/classes/validators/host',
+ $this->root_dir.'/include/classes/validators/hostprototype',
+ $this->root_dir.'/include/classes/validators/event',
+ $this->root_dir.'/include/classes/export',
+ $this->root_dir.'/include/classes/export/writers',
+ $this->root_dir.'/include/classes/export/elements',
+ $this->root_dir.'/include/classes/graph',
+ $this->root_dir.'/include/classes/graphdraw',
+ $this->root_dir.'/include/classes/import',
+ $this->root_dir.'/include/classes/import/converters',
+ $this->root_dir.'/include/classes/import/importers',
+ $this->root_dir.'/include/classes/import/preprocessors',
+ $this->root_dir.'/include/classes/import/readers',
+ $this->root_dir.'/include/classes/import/validators',
+ $this->root_dir.'/include/classes/items',
+ $this->root_dir.'/include/classes/triggers',
+ $this->root_dir.'/include/classes/server',
+ $this->root_dir.'/include/classes/screens',
+ $this->root_dir.'/include/classes/services',
+ $this->root_dir.'/include/classes/sysmaps',
+ $this->root_dir.'/include/classes/helpers',
+ $this->root_dir.'/include/classes/helpers/trigger',
+ $this->root_dir.'/include/classes/macros',
+ $this->root_dir.'/include/classes/html',
+ $this->root_dir.'/include/classes/html/svg',
+ $this->root_dir.'/include/classes/html/widgets',
+ $this->root_dir.'/include/classes/html/interfaces',
+ $this->root_dir.'/include/classes/parsers',
+ $this->root_dir.'/include/classes/parsers/results',
+ $this->root_dir.'/include/classes/controllers',
+ $this->root_dir.'/include/classes/routing',
+ $this->root_dir.'/include/classes/json',
+ $this->root_dir.'/include/classes/user',
+ $this->root_dir.'/include/classes/setup',
+ $this->root_dir.'/include/classes/regexp',
+ $this->root_dir.'/include/classes/ldap',
+ $this->root_dir.'/include/classes/pagefilter',
+ $this->root_dir.'/include/classes/xml',
+ $this->root_dir.'/include/classes/vaults',
+ $this->root_dir.'/local/app/controllers',
+ $this->root_dir.'/app/controllers'
];
}
@@ -389,7 +391,7 @@ class ZBase {
* Load zabbix config file.
*/
protected function loadConfigFile(): void {
- $configFile = $this->getRootDir().CConfigFile::CONFIG_FILE_PATH;
+ $configFile = $this->root_dir.CConfigFile::CONFIG_FILE_PATH;
$config = new CConfigFile($configFile);
@@ -401,10 +403,11 @@ class ZBase {
*/
protected function initAutoloader() {
// Register base directory path for 'include' and 'require' functions.
- set_include_path(get_include_path().PATH_SEPARATOR.$this->rootDir);
+ set_include_path(get_include_path().PATH_SEPARATOR.$this->root_dir);
$autoloader = new CAutoloader;
$autoloader->addNamespace('', $this->getIncludePaths());
- $autoloader->addNamespace('Core', [$this->rootDir.'/include/classes/core']);
+ $autoloader->addNamespace('Zabbix\\Core', [$this->root_dir.'/include/classes/core']);
+ $autoloader->addNamespace('Zabbix\\Widgets', [$this->root_dir.'/include/classes/widgets']);
$autoloader->register();
$this->autoloader = $autoloader;
}
@@ -490,7 +493,7 @@ class ZBase {
error($error);
}
- require_once $this->getRootDir().'/include/translateDefines.inc.php';
+ require_once $this->root_dir.'/include/translateDefines.inc.php';
}
/**
@@ -559,11 +562,24 @@ class ZBase {
try {
if ($action_class === null) {
- throw new Exception(_('Class not found.'));
+ throw new Exception(_('Page not found'));
}
if (!class_exists($action_class)) {
- throw new Exception(_s('Class %1$s not found for action %2$s.', $action_class, $action_name));
+ $namespace_parts = explode('\\', $action_class);
+
+ if (count($namespace_parts) > 1) {
+ $action_class_fallback = end($namespace_parts);
+
+ if (!class_exists($action_class_fallback)) {
+ throw new Exception(_s('Class %1$s not found for action %2$s.', $action_class, $action_name));
+ }
+
+ $action_class = $action_class_fallback;
+ }
+ else {
+ throw new Exception(_s('Class %1$s not found for action %2$s.', $action_class, $action_name));
+ }
}
$action = new $action_class();
@@ -573,19 +589,25 @@ class ZBase {
}
$action->setAction($action_name);
+ $this->module_manager->setActionName($action_name);
$modules = $this->module_manager->getModules();
- $action_module = $this->module_manager->getModuleByActionName($action_name);
+ $action_module = $this->module_manager->getActionModule();
- if ($action_module) {
+ if ($action_module !== null) {
$modules = array_replace([$action_module->getId() => $action_module], $modules);
+
+ if ($action_module->getType() === CModule::TYPE_WIDGET) {
+ CView::registerDirectory($this->root_dir.'/'.$action_module->getRelativePath().'/views');
+ CPartial::registerDirectory($this->root_dir.'/'.$action_module->getRelativePath().'/partials');
+ }
}
foreach (array_reverse($modules) as $module) {
- if (is_subclass_of($module, CModule::class)) {
- CView::registerDirectory($module->getDir().'/views');
- CPartial::registerDirectory($module->getDir().'/partials');
+ if ($module->getType() === CModule::TYPE_MODULE) {
+ CView::registerDirectory($this->root_dir.'/'.$module->getRelativePath().'/views');
+ CPartial::registerDirectory($this->root_dir.'/'.$module->getRelativePath().'/partials');
}
}
@@ -605,29 +627,7 @@ class ZBase {
$this->denyPageAccess($router);
}
catch (Exception $e) {
- switch ($router->getLayout()) {
- case 'layout.json':
- case 'layout.widget':
- echo (new CView('layout.json', [
- 'main_block' => json_encode([
- 'error' => [
- 'title' => $e->getMessage()
- ]
- ])
- ]))->getOutput();
-
- break;
-
- default:
- echo (new CView('general.warning', [
- 'header' => $e->getMessage(),
- 'messages' => [],
- 'theme' => getUserTheme(CWebUser::$data)
- ]))->getOutput();
- }
-
- session_write_close();
- exit();
+ self::terminateWithError($router, $e->getMessage());
}
}
@@ -687,17 +687,23 @@ class ZBase {
];
if ($router->getView() !== null && $response->isViewEnabled()) {
- $view = new CView($router->getView(), $response->getData());
+ $this->view = new CView($router->getView(), $response->getData());
+
+ $module = $this->module_manager->getActionModule();
+
+ if ($module !== null) {
+ $this->view->setAssetsPath($module->getRelativePath().'/assets');
+ }
$layout_data = array_replace($layout_data_defaults, [
- 'main_block' => $view->getOutput(),
+ 'main_block' => $this->view->getOutput(),
'javascript' => [
- 'files' => $view->getJsFiles()
+ 'files' => $this->view->getJsFiles()
],
'stylesheet' => [
- 'files' => $view->getCssFiles()
+ 'files' => $this->view->getCssFiles()
],
- 'web_layout_mode' => $view->getLayoutMode()
+ 'web_layout_mode' => $this->view->getLayoutMode()
]);
}
else {
@@ -782,6 +788,52 @@ class ZBase {
exit();
}
+ private static function terminateWithError(CRouter $router, string $error): void {
+ switch ($router->getLayout()) {
+ case 'layout.json':
+ case 'layout.widget':
+ $layout = 'layout.json';
+ break;
+
+ case null:
+ if ((array_key_exists('CONTENT_TYPE', $_SERVER) && $_SERVER['CONTENT_TYPE'] === 'application/json')
+ || (array_key_exists('HTTP_X_REQUESTED_WITH', $_SERVER)
+ && strcasecmp($_SERVER['HTTP_X_REQUESTED_WITH'], 'XMLHttpRequest') == 0)) {
+ $layout = 'layout.json';
+ }
+ else {
+ $layout = 'general.warning';
+ }
+ break;
+
+ default:
+ $layout = 'general.warning';
+ }
+
+ switch ($layout) {
+ case 'layout.json':
+ echo (new CView('layout.json', [
+ 'main_block' => json_encode([
+ 'error' => [
+ 'title' => $error
+ ]
+ ])
+ ]))->getOutput();
+
+ break;
+
+ default:
+ echo (new CView('general.warning', [
+ 'header' => $error,
+ 'messages' => [],
+ 'theme' => getUserTheme(CWebUser::$data)
+ ]))->getOutput();
+ }
+
+ session_write_close();
+ exit();
+ }
+
/**
* Set layout mode using URL parameters.
*/
@@ -797,7 +849,7 @@ class ZBase {
/**
* Initialize menu for main navigation. Register instance as component with 'menu.main' key.
*/
- private function initComponents() {
+ private function initComponents(): void {
$this->component_registry->register('router', new CRouter());
$this->component_registry->register('menu.main', CMenuHelper::getMainMenu());
$this->component_registry->register('menu.user', CMenuHelper::getUserMenu());
@@ -806,8 +858,8 @@ class ZBase {
/**
* Initialize module manager and load all enabled and allowed modules according to user role settings.
*/
- private function initModuleManager() {
- $this->module_manager = new CModuleManager($this->rootDir.'/modules');
+ private function initModuleManager(): void {
+ $this->module_manager = new CModuleManager($this->root_dir);
$db_modules = API::getApiService('module')->get([
'output' => ['moduleid', 'id', 'relative_path', 'config'],
@@ -822,8 +874,8 @@ class ZBase {
continue;
}
- $manifest = $this->module_manager->addModule($db_module['relative_path'], $db_module['id'],
- $db_module['config']
+ $manifest = $this->module_manager->addModule($db_module['relative_path'], $db_module['moduleid'],
+ $db_module['id'], $db_module['config']
);
if (!$manifest) {
diff --git a/ui/include/classes/helpers/CDashboardHelper.php b/ui/include/classes/helpers/CDashboardHelper.php
index 59969e79e51..9dcff28757c 100644
--- a/ui/include/classes/helpers/CDashboardHelper.php
+++ b/ui/include/classes/helpers/CDashboardHelper.php
@@ -19,26 +19,23 @@
**/
+use Zabbix\Core\{
+ CModule,
+ CWidget
+};
+
class CDashboardHelper {
/**
* Get dashboard owner name.
- *
- * @static
- *
- * @param string $userid
- *
- * @return string
*/
- public static function getOwnerName($userid): string {
+ public static function getOwnerName(string $userid): string {
$users = API::User()->get([
'output' => ['name', 'surname', 'username'],
'userids' => $userid
]);
- $name = $users ? getUserFullname($users[0]) : _('Inaccessible user');
-
- return $name;
+ return $users ? getUserFullname($users[0]) : _('Inaccessible user');
}
/**
@@ -64,14 +61,6 @@ class CDashboardHelper {
/**
* Prepare widget pages for dashboard grid.
- *
- * @static
- *
- * @param array $pages
- * @param string $templateid
- * @param bool $with_rf_rate
- *
- * @return array
*/
public static function preparePagesForGrid(array $pages, ?string $templateid, bool $with_rf_rate): array {
if (!$pages) {
@@ -80,63 +69,58 @@ class CDashboardHelper {
$grid_pages = [];
- $context = ($templateid === null)
- ? CWidgetConfig::CONTEXT_DASHBOARD
- : CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD;
-
- $known_widget_types = array_keys(CWidgetConfig::getKnownWidgetTypes($context));
-
foreach ($pages as $page) {
$grid_page_widgets = [];
CArrayHelper::sort($page['widgets'], ['y', 'x']);
- foreach ($page['widgets'] as $widget) {
- if (!in_array($widget['type'], $known_widget_types)) {
- continue;
- }
-
- $widgetid = $widget['widgetid'];
- $fields_orig = self::convertWidgetFields($widget['fields']);
-
- // Transforms corrupted data to default values.
- $widget_form = CWidgetConfig::getForm($widget['type'], json_encode($fields_orig), $templateid);
- $widget_form->validate();
- $fields = $widget_form->getFieldsData();
-
- if ($with_rf_rate) {
- $rf_rate = (int) CProfile::get('web.dashboard.widget.rf_rate', -1, $widgetid);
+ foreach ($page['widgets'] as $widget_data) {
+ $grid_page_widget = [
+ 'widgetid' => $widget_data['widgetid'],
+ 'type' => $widget_data['type'],
+ 'name' => $widget_data['name'],
+ 'view_mode' => $widget_data['view_mode'],
+ 'pos' => [
+ 'x' => (int) $widget_data['x'],
+ 'y' => (int) $widget_data['y'],
+ 'width' => (int) $widget_data['width'],
+ 'height' => (int) $widget_data['height']
+ ],
+ 'rf_rate' => 0,
+ 'fields' => []
+ ];
- if ($rf_rate == -1) {
- if ($context === CWidgetConfig::CONTEXT_DASHBOARD) {
- $rf_rate = ($fields['rf_rate'] == -1)
- ? CWidgetConfig::getDefaultRfRate($widget['type'])
- : $fields['rf_rate'];
- }
- else {
- $rf_rate = CWidgetConfig::getDefaultRfRate($widget['type']);
+ /** @var CWidget $widget */
+ $widget = APP::ModuleManager()->getModule($widget_data['type']);
+
+ if ($widget !== null && $widget->getType() === CModule::TYPE_WIDGET
+ && ($templateid === null || $widget->hasTemplateSupport())) {
+ $grid_page_widget['fields'] = self::convertWidgetFields($widget_data['fields']);
+
+ if ($with_rf_rate) {
+ $rf_rate = (int) CProfile::get('web.dashboard.widget.rf_rate', -1, $widget_data['widgetid']);
+
+ if ($rf_rate == -1) {
+ if ($templateid === null) {
+ // Transforms corrupted data to default values.
+ $widget_form = $widget->getForm($grid_page_widget['fields'], $templateid);
+ $widget_form->validate();
+ $values = $widget_form->getFieldsValues();
+
+ $rf_rate = $values['rf_rate'] == -1
+ ? $widget->getDefaultRefreshRate()
+ : $values['rf_rate'];
+ }
+ else {
+ $rf_rate = $widget->getDefaultRefreshRate();
+ }
}
+
+ $grid_page_widget['rf_rate'] = $rf_rate;
}
}
- else {
- $rf_rate = 0;
- }
- $grid_page_widgets[] = [
- 'widgetid' => $widgetid,
- 'type' => $widget['type'],
- 'name' => $widget['name'],
- 'view_mode' => $widget['view_mode'],
- 'pos' => [
- 'x' => (int) $widget['x'],
- 'y' => (int) $widget['y'],
- 'width' => (int) $widget['width'],
- 'height' => (int) $widget['height']
- ],
- 'rf_rate' => $rf_rate,
- 'fields' => $fields_orig,
- 'configuration' => CWidgetConfig::getConfiguration($widget['type'], $fields, $widget['view_mode'])
- ];
+ $grid_page_widgets[] = $grid_page_widget;
}
$grid_pages[] = [
@@ -358,8 +342,11 @@ class CDashboardHelper {
*/
public static function hasTimeSelector(array $pages): bool {
foreach ($pages as $page) {
- foreach ($page['widgets'] as $widget) {
- if (CWidgetConfig::usesTimeSelector($widget['type'], $widget['fields'])) {
+ foreach ($page['widgets'] as $widget_data) {
+ $widget = App::ModuleManager()->getModule($widget_data['type']);
+
+ if ($widget !== null && $widget->getType() === CModule::TYPE_WIDGET
+ && $widget->usesTimeSelector($widget_data['fields'])) {
return true;
}
}
@@ -411,10 +398,10 @@ class CDashboardHelper {
$dashboard_page['widgets'] = [];
}
- foreach ($dashboard_page['widgets'] as $widget_index => &$widget) {
+ foreach ($dashboard_page['widgets'] as $widget_index => &$widget_data) {
$widget_errors = [];
- if (!array_key_exists('pos', $widget)) {
+ if (!array_key_exists('pos', $widget_data)) {
$widget_errors[] = _s('Invalid parameter "%1$s": %2$s.',
'pages['.$dashboard_page_index.'][widgets]['.$widget_index.']',
_s('the parameter "%1$s" is missing', 'pos')
@@ -422,7 +409,7 @@ class CDashboardHelper {
}
else {
foreach (['x', 'y', 'width', 'height'] as $field) {
- if (!is_array($widget['pos']) || !array_key_exists($field, $widget['pos'])) {
+ if (!is_array($widget_data['pos']) || !array_key_exists($field, $widget_data['pos'])) {
$widget_errors[] = _s('Invalid parameter "%1$s": %2$s.',
'pages['.$dashboard_page_index.'][widgets]['.$widget_index.'][pos]',
_s('the parameter "%1$s" is missing', $field)
@@ -432,7 +419,7 @@ class CDashboardHelper {
}
foreach (['type', 'name', 'view_mode'] as $field) {
- if (!array_key_exists($field, $widget)) {
+ if (!array_key_exists($field, $widget_data)) {
$widget_errors[] = _s('Invalid parameter "%1$s": %2$s.',
'pages['.$dashboard_page_index.'][widgets]['.$widget_index.']',
_s('the parameter "%1$s" is missing', $field)
@@ -446,28 +433,45 @@ class CDashboardHelper {
break 2;
}
- $widget_fields = array_key_exists('fields', $widget) ? $widget['fields'] : '{}';
- $widget['form'] = CWidgetConfig::getForm($widget['type'], $widget_fields, $templateid);
- unset($widget['fields']);
+ $widget_fields = array_key_exists('fields', $widget_data) ? $widget_data['fields'] : [];
+ unset($widget_data['fields']);
+
+ if ($widget_data['type'] === ZBX_WIDGET_INACCESSIBLE) {
+ continue;
+ }
- if ($widget_errors = $widget['form']->validate()) {
- if ($widget['name'] === '') {
- $context = $templateid !== null
- ? CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD
- : CWidgetConfig::CONTEXT_DASHBOARD;
+ $widget = APP::ModuleManager()->getModule($widget_data['type']);
- $widget_name = CWidgetConfig::getKnownWidgetTypes($context)[$widget['type']];
+ if ($widget === null || $widget->getType() !== CModule::TYPE_WIDGET) {
+ if ($widget_data['name'] !== '') {
+ $widget_name = $widget_data['name'];
}
else {
- $widget_name = $widget['name'];
+ $widget_name = 'pages['.$dashboard_page_index.'][widgets]['.$widget_index.']';
}
+ $errors[] = _s('Cannot save widget "%1$s".', $widget_name).' '._('Inaccessible widget type.');
+
+ continue;
+ }
+
+ $widget_name = $widget_data['name'] !== '' ? $widget_data['name'] : $widget->getDefaultName();
+
+ if ($templateid !== null && !$widget->hasTemplateSupport()) {
+ $errors[] = _s('Cannot save widget "%1$s".', $widget_name).' '._('Inaccessible widget type.');
+
+ continue;
+ }
+
+ $widget_data['form'] = $widget->getForm($widget_fields, $templateid);
+
+ if ($widget_errors = $widget_data['form']->validate()) {
foreach ($widget_errors as $error) {
$errors[] = _s('Cannot save widget "%1$s".', $widget_name).' '.$error;
}
}
}
- unset($widget);
+ unset($widget_data);
}
unset($dashboard_page);
@@ -568,4 +572,52 @@ class CDashboardHelper {
return $dashboards;
}
+
+ public static function getWidgetLastType(bool $for_template_dashboard_only = false): ?string {
+ $known_widgets = APP::ModuleManager()->getWidgets($for_template_dashboard_only);
+
+ $widget_last_type = CProfile::get('web.dashboard.last_widget_type');
+
+ if (!array_key_exists($widget_last_type, $known_widgets)) {
+ $current_types = [];
+ $deprecated_types = [];
+
+ /** @var CWidget $widget */
+ foreach ($known_widgets as $widget) {
+ if (!$widget->isDeprecated()) {
+ $current_types[$widget->getId()] = $widget->getDefaultName();
+ }
+ else {
+ $deprecated_types[$widget->getId()] = $widget->getDefaultName();
+ }
+ }
+
+ natcasesort($current_types);
+ natcasesort($deprecated_types);
+
+ if ($current_types) {
+ $widget_last_type = array_key_first($current_types);
+ }
+ elseif ($deprecated_types) {
+ $widget_last_type = array_key_first($deprecated_types);
+ }
+ else {
+ $widget_last_type = null;
+ }
+ }
+
+ return $widget_last_type;
+ }
+
+ /**
+ * @throws JsonException
+ */
+ public static function getConfigurationHash(array $dashboard, array $widget_defaults): string {
+ ksort($widget_defaults);
+
+ return md5(json_encode([
+ array_intersect_key($dashboard, array_flip(['name', 'display_period', 'auto_start', 'pages'])),
+ $widget_defaults
+ ], JSON_THROW_ON_ERROR));
+ }
}
diff --git a/ui/include/classes/helpers/CDocHelper.php b/ui/include/classes/helpers/CDocHelper.php
index 03287ed8936..a1f2b3095b2 100644
--- a/ui/include/classes/helpers/CDocHelper.php
+++ b/ui/include/classes/helpers/CDocHelper.php
@@ -153,15 +153,15 @@ class CDocHelper {
const USERS_USERROLE_EDIT = 'web_interface/frontend_sections/users/user_roles#default-user-roles';
const USERS_USERROLE_LIST = 'web_interface/frontend_sections/users/user_roles';
- public static function getUrl($path): ?string {
+ public static function getUrl($path): string {
if (CBrandHelper::isRebranded()) {
- return null;
+ return '';
}
if (preg_match('/^\d+\.\d+/', ZABBIX_VERSION, $version)) {
return ZBX_DOCUMENTATION_URL.'/'.$version[0].'/en/manual/'.$path;
}
- return null;
+ return '';
}
}
diff --git a/ui/include/classes/helpers/CMessageHelper.php b/ui/include/classes/helpers/CMessageHelper.php
index 1ae461866cb..68560c27c84 100644
--- a/ui/include/classes/helpers/CMessageHelper.php
+++ b/ui/include/classes/helpers/CMessageHelper.php
@@ -161,10 +161,9 @@ class CMessageHelper {
/**
* Clear messages.
*/
- public static function clear(bool $clear_title = true): void {
- if ($clear_title) {
- self::$title = null;
- }
+ public static function clear(): void {
+ self::$type = null;
+ self::$title = null;
self::$messages = [];
}
diff --git a/ui/include/classes/helpers/CSvgGraphHelper.php b/ui/include/classes/helpers/CSvgGraphHelper.php
index a9cb6c78046..85ca3cc6925 100644
--- a/ui/include/classes/helpers/CSvgGraphHelper.php
+++ b/ui/include/classes/helpers/CSvgGraphHelper.php
@@ -19,6 +19,8 @@
**/
+use Zabbix\Widgets\Fields\CWidgetFieldGraphDataSet;
+
/**
* Class calculates graph data and makes SVG graph.
*/
@@ -109,7 +111,7 @@ class CSvgGraphHelper {
$max_metrics = SVG_GRAPH_MAX_NUMBER_OF_METRICS;
foreach ($data_sets as $index => $data_set) {
- if ($data_set['dataset_type'] == CWidgetHelper::DATASET_TYPE_SINGLE_ITEM) {
+ if ($data_set['dataset_type'] == CWidgetFieldGraphDataSet::DATASET_TYPE_SINGLE_ITEM) {
continue;
}
@@ -179,7 +181,7 @@ class CSvgGraphHelper {
$max_metrics = SVG_GRAPH_MAX_NUMBER_OF_METRICS;
foreach ($data_sets as $index => $data_set) {
- if ($data_set['dataset_type'] == CWidgetHelper::DATASET_TYPE_PATTERN_ITEM) {
+ if ($data_set['dataset_type'] == CWidgetFieldGraphDataSet::DATASET_TYPE_PATTERN_ITEM) {
continue;
}
@@ -750,7 +752,7 @@ class CSvgGraphHelper {
* Find problems at given time period that matches specified problem options.
*/
private static function getProblems(array $metrics, array $problem_options, array $time_period): array {
- if ($problem_options['show_problems'] != SVG_GRAPH_PROBLEMS_SHOW) {
+ if ($problem_options['show_problems'] == SVG_GRAPH_PROBLEMS_OFF) {
return [];
}
diff --git a/ui/include/classes/html/CBarGauge.php b/ui/include/classes/html/CBarGauge.php
index 2afa30bcea2..5b5941eea97 100644
--- a/ui/include/classes/html/CBarGauge.php
+++ b/ui/include/classes/html/CBarGauge.php
@@ -20,7 +20,8 @@
class CBarGauge extends CTag {
- private $thresholds = [];
+
+ private array $thresholds = [];
public function __construct() {
parent::__construct('z-bar-gauge', true);
diff --git a/ui/include/classes/html/CCollapsibleUiWidget.php b/ui/include/classes/html/CCollapsibleUiWidget.php
deleted file mode 100644
index 58fb46c8fd4..00000000000
--- a/ui/include/classes/html/CCollapsibleUiWidget.php
+++ /dev/null
@@ -1,103 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * A class for rendering a widget that can be collapsed or expanded.
- */
-class CCollapsibleUiWidget extends CUiWidget {
-
- /**
- * Expand/collapse widget.
- *
- * Supported values:
- * - true - expanded;
- * - false - collapsed.
- *
- * @var bool
- */
- private $expanded = true;
-
- /**
- * Sets the header and adds a default expand-collapse icon.
- *
- * @param string $caption Header caption.
- * @param array $controls (optional)
- * @param string $idx (optional)
- *
- * @return $this
- */
- public function setHeader($caption, array $controls = [], $idx = '') {
- $icon = (new CRedirectButton(null, null))
- ->setId($this->id.'_icon')
- ->onClick('changeWidgetState(this, "'.$this->id.'", "'.$idx.'");');
-
- if ($this->expanded) {
- $icon
- ->addClass(ZBX_STYLE_BTN_WIDGET_COLLAPSE)
- ->setTitle(_('Collapse'));
- }
- else {
- $icon
- ->addClass(ZBX_STYLE_BTN_WIDGET_EXPAND)
- ->setTitle(_('Expand'));
- }
-
- $controls[] = $icon;
-
- parent::setHeader($caption, $controls);
-
- return $this;
- }
-
- /**
- * Display the widget in expanded or collapsed state.
- */
- protected function build() {
- $body = (new CDiv($this->body))
- ->addClass('body')
- ->setId($this->id);
-
- if (!$this->expanded) {
- $body->setAttribute('style', 'display: none;');
-
- if ($this->footer) {
- $this->footer->setAttribute('style', 'display: none;');
- }
- }
-
- $this->cleanItems();
- $this->addItem($this->header);
- $this->addItem($body);
- $this->addItem($this->footer);
-
- return $this;
- }
-
- /**
- * Sets expanded or collapsed state of the widget.
- *
- * @param bool
- */
- public function setExpanded($expanded) {
- $this->expanded = $expanded;
- return $this;
- }
-}
diff --git a/ui/include/classes/html/CColor.php b/ui/include/classes/html/CColor.php
index 178454953a7..f991288ffe7 100644
--- a/ui/include/classes/html/CColor.php
+++ b/ui/include/classes/html/CColor.php
@@ -64,11 +64,9 @@ class CColor extends CDiv {
/**
* Enable default color button.
-
- * @return CColor
*/
- public function enableUseDefault(): self {
- $this->use_default = true;
+ public function enableUseDefault($use_default = true): self {
+ $this->use_default = $use_default;
return $this;
}
diff --git a/ui/include/classes/html/widget/CWidget.php b/ui/include/classes/html/CHtmlPage.php
index 70dbac9f539..4fc21fe8b9a 100644
--- a/ui/include/classes/html/widget/CWidget.php
+++ b/ui/include/classes/html/CHtmlPage.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,7 +19,9 @@
**/
-class CWidget {
+class CHtmlPage {
+
+ public const PAGE_TITLE_ID = 'page-title-general';
private const ZBX_STYLE_HEADER_TITLE = 'header-title';
private const ZBX_STYLE_HEADER_DOC_LINK = 'header-doc-link';
@@ -27,104 +29,83 @@ class CWidget {
private const ZBX_STYLE_HEADER_CONTROLS = 'header-controls';
private const ZBX_STYLE_HEADER_KIOSKMODE_CONTROLS = 'header-kioskmode-controls';
- private $title;
- private $title_submenu;
- private $doc_url;
- private $controls;
- private $kiosk_mode_controls;
+ private string $title = '';
+ private array $title_submenu = [];
- /**
- * Navigation, displayed exclusively in ZBX_LAYOUT_NORMAL mode.
- *
- * @var mixed
- */
- private $navigation;
+ private ?CTag $controls = null;
+ private ?CList $kiosk_mode_controls = null;
+
+ private string $doc_url = '';
+
+ private array $items = [];
/**
- * The contents of the body of the widget.
- *
- * @var array
+ * Navigation, displayed exclusively in ZBX_LAYOUT_NORMAL mode.
*/
- protected $body = [];
+ private ?CList $navigation = null;
/**
* Layout mode (ZBX_LAYOUT_NORMAL|ZBX_LAYOUT_KIOSKMODE).
- *
- * @var integer
*/
- protected $web_layout_mode = ZBX_LAYOUT_NORMAL;
+ private int $web_layout_mode = ZBX_LAYOUT_NORMAL;
- public function setTitle($title) {
+ public function setTitle(string $title): self {
$this->title = $title;
return $this;
}
- public function setTitleSubmenu($title_submenu) {
+ public function setTitleSubmenu(array $title_submenu): self {
$this->title_submenu = $title_submenu;
return $this;
}
- public function setDocUrl($doc_url) {
+ public function setDocUrl(string $doc_url): self {
$this->doc_url = $doc_url;
return $this;
}
- public function setControls($controls) {
+ public function setControls(?CTag $controls): self {
$this->controls = $controls;
return $this;
}
- public function setKioskModeControls($kiosk_mode_controls) {
+ public function setKioskModeControls(?CList $kiosk_mode_controls): self {
$this->kiosk_mode_controls = $kiosk_mode_controls;
return $this;
}
- /**
- * Set layout mode.
- *
- * @param integer $web_layout_mode
- *
- * @return CWidget
- */
- public function setWebLayoutMode($web_layout_mode) {
+ public function setWebLayoutMode(int $web_layout_mode): self {
$this->web_layout_mode = $web_layout_mode;
return $this;
}
- /**
- * Set navigation for displaying exclusively in ZBX_LAYOUT_NORMAL mode.
- *
- * @param mixed $navigation
- *
- * @return CWidget
- */
- public function setNavigation($navigation) {
+ public function setNavigation(?CList $navigation): self {
$this->navigation = $navigation;
return $this;
}
- public function addItem($items = null) {
- if (!is_null($items)) {
- $this->body[] = $items;
+ public function addItem($value): self {
+ if ($value !== null) {
+ $this->items[] = $value;
}
return $this;
}
- public function show() {
+ public function show(): self {
echo $this->toString();
return $this;
}
- public function toString() {
+ private function toString() {
$items = [];
if ($this->web_layout_mode == ZBX_LAYOUT_KIOSKMODE) {
@@ -138,7 +119,7 @@ class CWidget {
)
);
}
- elseif ($this->title !== null || $this->controls !== null || $this->doc_url !== null) {
+ elseif ($this->title !== '' || $this->doc_url !== '' || $this->controls !== null) {
$items[] = $this->createTopHeader();
}
@@ -152,27 +133,28 @@ class CWidget {
? (new CDiv($this->navigation))->addClass(self::ZBX_STYLE_HEADER_NAVIGATION)
: null;
- $items[] = new CTag('main', true, [$navigation, $this->body]);
+ $items[] = new CTag('main', true, [$navigation, $this->items]);
return unpack_object($items);
}
private function createTopHeader(): CTag {
$divs = [
- (new CTag('nav', true, (new CButton(null, _('Show sidebar')))
- ->setId('sidebar-button-toggle')
- ->addClass('button-toggle')
- ->setAttribute('title', _('Show sidebar'))
+ (new CTag('nav', true,
+ (new CButton(null, _('Show sidebar')))
+ ->setId('sidebar-button-toggle')
+ ->addClass('button-toggle')
+ ->setAttribute('title', _('Show sidebar'))
))
->addClass('sidebar-nav-toggle')
->setAttribute('role', 'navigation')
->setAttribute('aria-label', _('Sidebar control'))
];
- if ($this->title !== null) {
- $title_tag = (new CTag('h1', true, $this->title))->setId(ZBX_STYLE_PAGE_TITLE);
+ if ($this->title !== '') {
+ $title_tag = (new CTag('h1', true, $this->title))->setId(self::PAGE_TITLE_ID);
- if ($this->title_submenu) {
+ if ($this->title_submenu !== []) {
$title_tag = (new CLinkAction($title_tag))
->setMenuPopup([
'type' => 'submenu',
@@ -189,7 +171,7 @@ class CWidget {
$divs[] = new CDiv($title_tag);
}
- if ($this->doc_url !== null) {
+ if ($this->doc_url !== '') {
$divs[] = (new CDiv(
(new CLink(null, $this->doc_url))
->setTitle(_('Help'))
diff --git a/ui/include/classes/html/CHtmlPageHeader.php b/ui/include/classes/html/CHtmlPageHeader.php
new file mode 100644
index 00000000000..c0944d6e244
--- /dev/null
+++ b/ui/include/classes/html/CHtmlPageHeader.php
@@ -0,0 +1,181 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+/**
+ * Class for rendering html page head part.
+ */
+class CHtmlPageHeader {
+
+ /**
+ * Page title.
+ */
+ protected string $title;
+
+ /**
+ * Language attribute.
+ */
+ protected string $lang;
+
+ /**
+ * Theme attribute.
+ */
+ protected string $theme = ZBX_DEFAULT_THEME;
+
+ /**
+ * CSS files list.
+ */
+ protected array $css_files = [];
+
+ /**
+ * Inline CSS styles.
+ */
+ protected array $styles = [];
+
+ /**
+ * JavaScripts to render before JS files.
+ */
+ protected array $js = [];
+
+ /**
+ * JS files list.
+ */
+ protected array $js_files = [];
+
+ protected string $sid;
+
+ public function __construct(string $title, string $lang) {
+ $this->title = CHtml::encode($title);
+ $this->lang = $lang;
+ $this->sid = substr(CSessionHelper::getId(), 16, 16);
+ }
+
+ public function setTheme(string $theme): self {
+ $this->theme = CHtml::encode($theme);
+
+ return $this;
+ }
+
+ public function getTheme(): string {
+ return $this->theme;
+ }
+
+ /**
+ * Add path to css file to render in page head.
+ */
+ public function addCssFile(string $css_file): self {
+ $this->css_files[$css_file] = $css_file;
+
+ return $this;
+ }
+
+ /**
+ * Add css style to render in page head.
+ */
+ public function addStyle(string $style): self {
+ $this->styles[] = $style;
+
+ return $this;
+ }
+
+ /**
+ * Add JavaScript to render in page head before js file includes are rendered.
+ */
+ public function addJavaScript(string $js): self {
+ $this->js[] = $js;
+
+ return $this;
+ }
+
+ /**
+ * Add path to js file to render in page head.
+ */
+ public function addJsFile(string $js_file): self {
+ $this->js_files[$js_file] = $js_file;
+
+ return $this;
+ }
+
+ public function addJsTranslationStrings(array $translations_strings): self {
+ foreach ($translations_strings as $orig_string => $string) {
+ $this->addJavaScript('locale[\''.$orig_string.'\'] = '.json_encode($string, JSON_THROW_ON_ERROR).';');
+ }
+
+ return $this;
+ }
+
+ /**
+ * Show page head html.
+ */
+ public function show(): CHtmlPageHeader {
+ echo '<!DOCTYPE html>';
+ echo '<html lang="'.$this->lang.'" theme="'.$this->theme.'">';
+ echo <<<HTML
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <meta name="Author" content="Zabbix SIA" />
+ <title>$this->title</title>
+ <link rel="icon" href="favicon.ico">
+ <link rel="apple-touch-icon-precomposed" sizes="76x76" href="assets/img/apple-touch-icon-76x76-precomposed.png">
+ <link rel="apple-touch-icon-precomposed" sizes="120x120" href="assets/img/apple-touch-icon-120x120-precomposed.png">
+ <link rel="apple-touch-icon-precomposed" sizes="152x152" href="assets/img/apple-touch-icon-152x152-precomposed.png">
+ <link rel="apple-touch-icon-precomposed" sizes="180x180" href="assets/img/apple-touch-icon-180x180-precomposed.png">
+ <link rel="icon" sizes="192x192" href="assets/img/touch-icon-192x192.png">
+ <meta name="csrf-token" content="$this->sid"/>
+ <meta name="msapplication-TileImage" content="assets/img/ms-tile-144x144.png">
+ <meta name="msapplication-TileColor" content="#d40000">
+ <meta name="msapplication-config" content="none"/>
+ HTML;
+
+ foreach ($this->css_files as $path) {
+ if (parse_url($path, PHP_URL_QUERY) === null) {
+ $path .= '?'.(int) filemtime($path);
+ }
+
+ echo '<link rel="stylesheet" type="text/css" href="'.htmlspecialchars($path).'" />'."\n";
+ }
+
+ if ($this->styles) {
+ echo '<style>';
+ echo implode("\n", $this->styles);
+ echo '</style>';
+ }
+
+ if ($this->js) {
+ echo '<script>';
+ echo implode("\n", $this->js);
+ echo '</script>';
+ }
+
+ foreach ($this->js_files as $path) {
+ if (parse_url($path, PHP_URL_QUERY) === null) {
+ $path .= '?'.(int) filemtime($path);
+ }
+
+ echo '<script src="'.htmlspecialchars($path).'"></script>'."\n";
+ }
+
+ echo '</head>'."\n";
+
+ return $this;
+ }
+}
diff --git a/ui/include/classes/html/CLabel.php b/ui/include/classes/html/CLabel.php
index 513dfe94eb0..ab41f1493fc 100644
--- a/ui/include/classes/html/CLabel.php
+++ b/ui/include/classes/html/CLabel.php
@@ -21,12 +21,18 @@
class CLabel extends CTag {
- public function __construct($label, $for = null) {
+ public function __construct($label, $id = null) {
parent::__construct('label', true, $label);
- if ($for !== null) {
- $this->setAttribute('for', zbx_formatDomId($for));
+ $this->setFor($id);
+ }
+
+ public function setFor($id): self {
+ if ($id !== null) {
+ $this->setAttribute('for', zbx_formatDomId($id));
}
+
+ return $this;
}
/**
diff --git a/ui/include/classes/html/CRadioButtonList.php b/ui/include/classes/html/CRadioButtonList.php
index 8ff7c4c8138..69f195c1982 100644
--- a/ui/include/classes/html/CRadioButtonList.php
+++ b/ui/include/classes/html/CRadioButtonList.php
@@ -100,7 +100,7 @@ class CRadioButtonList extends CList {
return $this;
}
- public function setModern($modern) {
+ public function setModern($modern = true) {
$this->modern = $modern;
return $this;
diff --git a/ui/include/classes/html/CSection.php b/ui/include/classes/html/CSection.php
new file mode 100644
index 00000000000..18c77db3930
--- /dev/null
+++ b/ui/include/classes/html/CSection.php
@@ -0,0 +1,68 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+class CSection extends CTag {
+
+ private const ZBX_STYLE_HEAD = 'section-head';
+ private const ZBX_STYLE_BODY = 'section-body';
+ private const ZBX_STYLE_FOOT = 'section-foot';
+
+ protected ?CDiv $header = null;
+ protected ?CDiv $footer = null;
+
+ public function __construct($items = null) {
+ parent::__construct('section', true, $items);
+ }
+
+ public function addItem($value): self {
+ if ($value !== null) {
+ $this->items[] = $value;
+ }
+
+ return $this;
+ }
+
+ public function setHeader($header_items): self {
+ if ($header_items !== null) {
+ $this->header = (new CDiv($header_items))->addClass(self::ZBX_STYLE_HEAD);
+ }
+
+ return $this;
+ }
+
+ public function setFooter($footer_items): self {
+ if ($footer_items !== null) {
+ $this->footer = (new CDiv($footer_items))->addClass(self::ZBX_STYLE_FOOT);
+ }
+
+ return $this;
+ }
+
+ public function toString($destroy = true): string {
+ $body = (new CDiv($this->items))->addClass(self::ZBX_STYLE_BODY);
+
+ $this->cleanItems();
+
+ parent::addItem([$this->header, $body, $this->footer]);
+
+ return parent::toString($destroy);
+ }
+}
diff --git a/ui/include/classes/html/CSectionCollapsible.php b/ui/include/classes/html/CSectionCollapsible.php
new file mode 100755
index 00000000000..55d3ebf1171
--- /dev/null
+++ b/ui/include/classes/html/CSectionCollapsible.php
@@ -0,0 +1,59 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+class CSectionCollapsible extends CSection {
+
+ private const ZBX_STYLE_COLLAPSED = 'section-collapsed';
+ private const ZBX_STYLE_TOGGLE = 'section-toggle';
+
+ private bool $is_expanded = true;
+ private string $profile_key = '';
+
+ public function setExpanded(bool $is_expanded): self {
+ $this->is_expanded = $is_expanded;
+
+ return $this;
+ }
+
+ public function setProfileIdx(string $profile_key): self {
+ $this->profile_key = $profile_key;
+
+ return $this;
+ }
+
+ public function toString($destroy = true): string {
+ $this->addClass($this->is_expanded ? null : self::ZBX_STYLE_COLLAPSED);
+
+ $toggle = (new CSimpleButton())
+ ->addClass(self::ZBX_STYLE_TOGGLE)
+ ->setTitle($this->is_expanded ? _('Collapse') : _('Expand'))
+ ->onClick('toggleSection("'.$this->getId().'", "'.$this->profile_key.'");');
+
+ if ($this->header === null) {
+ $this->setHeader($toggle);
+ }
+ else {
+ $this->header->addItem($toggle);
+ }
+
+ return parent::toString($destroy);
+ }
+}
diff --git a/ui/include/classes/html/CTemplateTag.php b/ui/include/classes/html/CTemplateTag.php
new file mode 100644
index 00000000000..79a60f26648
--- /dev/null
+++ b/ui/include/classes/html/CTemplateTag.php
@@ -0,0 +1,34 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+/**
+ * Class to embed HTML template.
+ */
+class CTemplateTag extends CTag {
+
+ public function __construct($id, $value = null) {
+ parent::__construct('template', true);
+
+ $this
+ ->setId($id)
+ ->addItem($value);
+ }
+}
diff --git a/ui/include/classes/html/CUiWidget.php b/ui/include/classes/html/CUiWidget.php
deleted file mode 100644
index 0823642534b..00000000000
--- a/ui/include/classes/html/CUiWidget.php
+++ /dev/null
@@ -1,136 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-class CUiWidget extends CDiv {
-
- /**
- * Widget id.
- *
- * @var string
- */
- public $id;
-
- /**
- * Expand/collapse widget.
- *
- * Supported values:
- * - true - expanded;
- * - false - collapsed.
- *
- * @var bool
- */
- public $open;
-
- /**
- * Header div.
- *
- * @var CDiv
- */
- protected $header;
-
- /**
- * Body div.
- *
- * @var array
- */
- protected $body;
-
- /**
- * Footer div.
- *
- * @var CDiv
- */
- protected $footer;
-
- /**
- * Construct widget.
- *
- * @param string $id
- * @param string|array|CTag $body
- */
- public function __construct($id, $body = null) {
- $this->id = $id;
- $this->body = $body ? [$body] : [];
-
- parent::__construct();
-
- $this->addClass(ZBX_STYLE_DASHBOARD_WIDGET);
- $this->setId($this->id.'_widget');
- }
-
- /**
- * Set widget header.
- *
- * @param string $caption
- * @param array $controls
- *
- * @return $this
- */
- public function setHeader($caption, array $controls = []) {
- $this->header = (new CDiv())
- ->addClass(ZBX_STYLE_DASHBOARD_WIDGET_HEAD)
- ->addItem(
- (new CTag('h4', true, $caption))->setId($this->id.'_header')
- );
-
- if ($controls) {
- $this->header->addItem(new CList($controls));
- }
-
- return $this;
- }
-
- /**
- * Set widget footer.
- *
- * @param string|array|CTag $footer
- * @param bool $right
- */
- public function setFooter($list) {
- $this->footer = $list;
- $this->footer->addClass(ZBX_STYLE_DASHBOARD_WIDGET_FOOT);
- return $this;
- }
-
- /**
- * Build widget header, body and footer.
- */
- protected function build() {
- $body = (new CDiv($this->body))
- ->setId($this->id);
-
- $this->cleanItems();
-
- $this->addItem($this->header);
- $this->addItem($body);
- $this->addItem($this->footer);
- return $this;
- }
-
- /**
- * Get widget html.
- */
- public function toString($destroy = true) {
- $this->build();
-
- return parent::toString($destroy);
- }
-}
diff --git a/ui/include/classes/html/pageheader/CPageHeader.php b/ui/include/classes/html/pageheader/CPageHeader.php
deleted file mode 100644
index e272f094998..00000000000
--- a/ui/include/classes/html/pageheader/CPageHeader.php
+++ /dev/null
@@ -1,190 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Class for rendering html page head part.
- */
-class CPageHeader {
-
- /**
- * @var string page title
- */
- protected $title;
-
- /**
- * @var string Language attribute.
- */
- protected $lang;
-
- /**
- * @var array of css file paths
- */
- protected $cssFiles = [];
-
- /**
- * @var array of css styles
- */
- protected $styles = [];
-
- /**
- * @var array of js file paths
- */
- protected $jsFiles = [];
-
- /**
- * @var array of js scripts to render before js files
- */
- protected $jsBefore = [];
-
- /**
- * @var array of js scripts to render after js files
- */
- protected $js = [];
-
- /**
- * @var {string} sid
- */
- protected $sid;
-
- /**
- * @param string $title
- * @param string $lang
- */
- public function __construct(string $title, string $lang) {
- $this->title = CHtml::encode($title);
- $this->lang = $lang;
- $this->sid = substr(CSessionHelper::getId(), 16, 16);
- }
-
- /**
- * Add path to css file to render in page head.
- *
- * @param string $path
- */
- public function addCssFile($path) {
- $this->cssFiles[$path] = $path;
- return $this;
- }
-
- /**
- * Add css style to render in page head.
- *
- * @param string $style
- */
- public function addStyle($style) {
- $this->styles[] = $style;
- return $this;
- }
-
- /**
- * Add path to js file to render in page head.
- *
- * @param string $path
- */
- public function addJsFile($path) {
- $this->jsFiles[$path] = $path;
- return $this;
- }
-
- /**
- * Add js script to render in page head after js file includes are rendered.
- *
- * @param string $js
- */
- public function addJs($js) {
- $this->js[] = $js;
- return $this;
- }
-
- /**
- * Add js script to render in page head before js file includes are rendered.
- *
- * @param string $js
- */
- public function addJsBeforeScripts($js) {
- $this->jsBefore[] = $js;
- return $this;
- }
-
- /**
- * Display page head html.
- */
- public function display() {
- echo '<!DOCTYPE html>'."\n";
- echo '<html lang="'.$this->lang.'">'."\n";
- echo <<<HTML
- <head>
- <meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <meta name="Author" content="Zabbix SIA" />
- <title>$this->title</title>
- <link rel="icon" href="favicon.ico">
- <link rel="apple-touch-icon-precomposed" sizes="76x76" href="assets/img/apple-touch-icon-76x76-precomposed.png">
- <link rel="apple-touch-icon-precomposed" sizes="120x120" href="assets/img/apple-touch-icon-120x120-precomposed.png">
- <link rel="apple-touch-icon-precomposed" sizes="152x152" href="assets/img/apple-touch-icon-152x152-precomposed.png">
- <link rel="apple-touch-icon-precomposed" sizes="180x180" href="assets/img/apple-touch-icon-180x180-precomposed.png">
- <link rel="icon" sizes="192x192" href="assets/img/touch-icon-192x192.png">
- <meta name="csrf-token" content="$this->sid"/>
- <meta name="msapplication-TileImage" content="assets/img/ms-tile-144x144.png">
- <meta name="msapplication-TileColor" content="#d40000">
- <meta name="msapplication-config" content="none"/>
-
-HTML;
-
- foreach ($this->cssFiles as $path) {
- if (parse_url($path, PHP_URL_QUERY) === null) {
- $path .= '?'.(int) filemtime($path);
- }
-
- echo '<link rel="stylesheet" type="text/css" href="'.htmlspecialchars($path).'" />'."\n";
- }
-
- if ($this->styles) {
- echo '<style type="text/css">';
- echo implode("\n", $this->styles);
- echo '</style>';
- }
-
- if ($this->jsBefore) {
- echo '<script>';
- echo implode("\n", $this->jsBefore);
- echo '</script>';
- }
-
- foreach ($this->jsFiles as $path) {
- if (parse_url($path, PHP_URL_QUERY) === null) {
- $path .= '?'.(int) filemtime($path);
- }
-
- echo '<script src="'.htmlspecialchars($path).'"></script>'."\n";
- }
-
- if ($this->js) {
- echo '<script>';
- echo implode("\n", $this->js);
- echo '</script>';
- }
-
- echo '</head>'."\n";
- return $this;
- }
-}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldCheckBoxListView.php b/ui/include/classes/html/widgets/CWidgetFieldCheckBoxListView.php
new file mode 100755
index 00000000000..2fe19e51d1d
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldCheckBoxListView.php
@@ -0,0 +1,59 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldCheckBoxList;
+
+class CWidgetFieldCheckBoxListView extends CWidgetFieldView {
+
+ private array $classes = [];
+
+ public function __construct(CWidgetFieldCheckBoxList $field) {
+ $this->field = $field;
+ }
+
+ public function getView(): CList {
+ $checkbox_list = (new CList())->addClass(ZBX_STYLE_LIST_CHECK_RADIO);
+
+ foreach ($this->classes as $class) {
+ $checkbox_list->addClass($class);
+ }
+
+ foreach ($this->field->getValues() as $key => $label) {
+ $checkbox_list->addItem(
+ (new CCheckBox($this->field->getName().'[]', $key))
+ ->setLabel($label)
+ ->setId($this->field->getName().'_'.$key)
+ ->setChecked(in_array($key, $this->field->getValue()))
+ ->setEnabled(!$this->isDisabled())
+ );
+ }
+
+ return $checkbox_list;
+ }
+
+ public function addClass(?string $class): self {
+ if ($class !== null) {
+ $this->classes[] = $class;
+ }
+
+ return $this;
+ }
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldCheckBoxView.php b/ui/include/classes/html/widgets/CWidgetFieldCheckBoxView.php
new file mode 100755
index 00000000000..f2a3dbfa274
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldCheckBoxView.php
@@ -0,0 +1,40 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldCheckBox;
+
+class CWidgetFieldCheckBoxView extends CWidgetFieldView {
+
+ public function __construct(CWidgetFieldCheckBox $field) {
+ $this->field = $field;
+ }
+
+ public function getView(): array {
+ return [
+ (new CVar($this->field->getName(), '0'))->removeId(),
+ (new CCheckBox($this->field->getName()))
+ ->setChecked((bool) $this->field->getValue())
+ ->setEnabled(!$this->isDisabled())
+ ->setLabel($this->field->getCaption())
+ ->onChange($this->field->getAction())
+ ];
+ }
+}
diff --git a/ui/include/classes/html/CScriptTemplate.php b/ui/include/classes/html/widgets/CWidgetFieldColorView.php
index 5d3f4212036..0c7ee880f64 100644..100755
--- a/ui/include/classes/html/CScriptTemplate.php
+++ b/ui/include/classes/html/widgets/CWidgetFieldColorView.php
@@ -19,34 +19,27 @@
**/
-/**
- * Class to embed script HTML template.
- */
-class CScriptTemplate extends CTag {
-
- /**
- * Create a <script type="text/x-jquery-tmpl" id="{$id}"> HTML template.
- *
- * @param string $id Template id
- */
- public function __construct($id) {
- parent::__construct('script', true);
- $this->setAttribute('type', 'text/x-jquery-tmpl');
- $this->setId($id);
+use Zabbix\Widgets\Fields\CWidgetFieldColor;
+
+class CWidgetFieldColorView extends CWidgetFieldView {
+
+ public function __construct(CWidgetFieldColor $field) {
+ $this->field = $field;
}
- public function addItem($value) {
- if (is_array($value)) {
- array_map([$this, 'addItem'], $value);
- }
- else {
- $this->items[] = $value;
+ public function getLabel(): ?CLabel {
+ $label = parent::getLabel();
+
+ if ($label !== null) {
+ $label->setFor('lbl_'.$this->field->getName());
}
- return $this;
+ return $label;
}
- protected function bodyToString(): string {
- return implode("\n", $this->items);
+ public function getView(): CColor {
+ return (new CColor($this->field->getName(), $this->field->getValue()))
+ ->appendColorPickerJs(false)
+ ->enableUseDefault(!$this->field->hasAllowInherited());
}
}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldColumnsListView.php b/ui/include/classes/html/widgets/CWidgetFieldColumnsListView.php
new file mode 100755
index 00000000000..ffdd353366b
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldColumnsListView.php
@@ -0,0 +1,91 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldColumnsList;
+
+class CWidgetFieldColumnsListView extends CWidgetFieldView {
+
+ public function __construct(CWidgetFieldColumnsList $field) {
+ $this->field = $field;
+ }
+
+ public function getView(): CTag {
+ $columns = $this->field->getValue();
+
+ $header = [
+ '',
+ (new CColHeader(_('Name')))->addStyle('width: 39%'),
+ (new CColHeader(_('Data')))->addStyle('width: 59%'),
+ _('Action')
+ ];
+
+ $row_actions = [
+ (new CButton('edit', _('Edit')))
+ ->addClass(ZBX_STYLE_BTN_LINK)
+ ->removeId(),
+ (new CButton('remove', _('Remove')))
+ ->addClass(ZBX_STYLE_BTN_LINK)
+ ->removeId()
+ ];
+
+ $table = (new CTable())
+ ->setId('list_'.$this->field->getName())
+ ->setHeader($header);
+
+ foreach ($columns as $column_index => $column) {
+ $column_data = [new CVar('sortorder['.$this->field->getName().'][]', $column_index)];
+
+ foreach ($column as $key => $value) {
+ $column_data[] = new CVar($this->field->getName().'['.$column_index.']['.$key.']', $value);
+ }
+
+ if ($column['data'] == CWidgetFieldColumnsList::DATA_HOST_NAME) {
+ $label = new CTag('em', true, _('Host name'));
+ }
+ else if ($column['data'] == CWidgetFieldColumnsList::DATA_TEXT) {
+ $label = new CTag('em', true, $column['text']);
+ }
+ elseif (array_key_exists('item', $column)) {
+ $label = $column['item'];
+ }
+ else {
+ $label = '';
+ }
+
+ $table->addRow((new CRow([
+ (new CCol((new CDiv)->addClass(ZBX_STYLE_DRAG_ICON)))->addClass(ZBX_STYLE_TD_DRAG_ICON),
+ (new CDiv($column['name']))->addClass('text'),
+ (new CDiv($label))->addClass('text'),
+ (new CList(array_merge($row_actions, [$column_data])))->addClass(ZBX_STYLE_HOR_LIST)
+ ]))->addClass('sortable'));
+ }
+
+ $table->addRow(
+ (new CCol(
+ (new CButton('add', _('Add')))
+ ->addClass(ZBX_STYLE_BTN_LINK)
+ ->setEnabled(!$this->isDisabled())
+ ))->setColSpan(count($header))
+ );
+
+ return $table;
+ }
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldDatePickerView.php b/ui/include/classes/html/widgets/CWidgetFieldDatePickerView.php
new file mode 100755
index 00000000000..d6b2fce25ba
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldDatePickerView.php
@@ -0,0 +1,62 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldDatePicker;
+
+class CWidgetFieldDatePickerView extends CWidgetFieldView {
+
+ private string $date_format = '';
+
+ private string $placeholder = '';
+
+ public function __construct(CWidgetFieldDatePicker $field) {
+ $this->field = $field;
+ }
+
+ public function getView(): CDateSelector {
+ $date_selector = (new CDateSelector($this->field->getName(), $this->field->getValue()))
+ ->setMaxLength(DB::getFieldLength('widget_field', 'value_str'))
+ ->setAriaRequired($this->isRequired())
+ ->setEnabled(!$this->isDisabled());
+
+ if ($this->date_format !== '') {
+ $date_selector->setDateFormat($this->date_format);
+ }
+
+ if ($this->placeholder !== '') {
+ $date_selector->setPlaceholder($this->placeholder);
+ }
+
+ return $date_selector;
+ }
+
+ public function setDateFormat(string $date_format): self {
+ $this->date_format = $date_format;
+
+ return $this;
+ }
+
+ public function setPlaceholder(string $placeholder): self {
+ $this->placeholder = $placeholder;
+
+ return $this;
+ }
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldGraphDataSetView.php b/ui/include/classes/html/widgets/CWidgetFieldGraphDataSetView.php
new file mode 100755
index 00000000000..e57baa95751
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldGraphDataSetView.php
@@ -0,0 +1,440 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldGraphDataSet;
+
+class CWidgetFieldGraphDataSetView extends CWidgetFieldView {
+
+ public function __construct(CWidgetFieldGraphDataSet $field) {
+ $this->field = $field;
+ }
+
+ public function getView(): CList {
+ $list = (new CList())
+ ->setId('data_sets')
+ ->addClass(ZBX_STYLE_SORTABLE_LIST);
+
+ $values = $this->field->getValue();
+
+ if (!$values) {
+ $values[] = CWidgetFieldGraphDataSet::getDefaults();
+ }
+
+ // Get item names for single item datasets.
+ $itemids = array_merge(...array_column($values, 'itemids'));
+ $item_names = [];
+ if ($itemids) {
+ $item_names = CWidgetFieldGraphDataSet::getItemNames($itemids);
+ }
+
+ foreach ($values as $i => $value) {
+ if ($value['dataset_type'] == CWidgetFieldGraphDataSet::DATASET_TYPE_SINGLE_ITEM) {
+ $value['item_names'] = $item_names;
+ }
+
+ $list->addItem(
+ $this->getGraphDataSetLayout($value, $value['dataset_type'], $i == 0, $i)
+ );
+ }
+
+ return $list;
+ }
+
+ public function getFooterView(): CList {
+ return (new CList())
+ ->addClass(ZBX_STYLE_BTN_SPLIT)
+ ->addItem([
+ (new CButton(null, [
+ (new CSpan())->addClass(ZBX_STYLE_PLUS_ICON),
+ _('Add new data set')
+ ]))
+ ->setId('dataset-add')
+ ->addClass(ZBX_STYLE_BTN_ALT),
+ (new CButton(null, '&#8203;'))
+ ->setId('dataset-menu')
+ ->addClass(ZBX_STYLE_BTN_ALT)
+ ->addClass(ZBX_STYLE_BTN_TOGGLE_CHEVRON)
+ ]);
+ }
+
+ public function getTemplates(): array {
+ $value = ['color' => '#{color}'] + CWidgetFieldGraphDataSet::getDefaults();
+
+ return [
+ new CTemplateTag('dataset-pattern-item-tmpl',
+ $this->getGraphDataSetLayout($value, CWidgetFieldGraphDataSet::DATASET_TYPE_PATTERN_ITEM, true)
+ ),
+ new CTemplateTag('dataset-single-item-tmpl',
+ $this->getGraphDataSetLayout($value, CWidgetFieldGraphDataSet::DATASET_TYPE_SINGLE_ITEM, true)
+ ),
+ new CTemplateTag('dataset-item-row-tmpl', $this->getItemRowTemplate()),
+ ];
+ }
+
+ private function getGraphDataSetLayout(array $value, int $dataset_type, bool $is_opened,
+ $row_num = '#{rowNum}'): CListItem {
+ $field_name = $this->field->getName();
+
+ $dataset_head = [
+ new CDiv((new CSimpleButton('&nbsp;'))->addClass(ZBX_STYLE_LIST_ACCORDION_ITEM_TOGGLE)),
+ new CVar($field_name.'['.$row_num.'][dataset_type]', $dataset_type, '')
+ ];
+
+ if ($dataset_type == CWidgetFieldGraphDataSet::DATASET_TYPE_PATTERN_ITEM) {
+ $host_pattern_field = (new CPatternSelect([
+ 'name' => $field_name.'['.$row_num.'][hosts][]',
+ 'object_name' => 'hosts',
+ 'data' => $value['hosts'],
+ 'placeholder' => _('host pattern'),
+ 'wildcard_allowed' => 1,
+ 'popup' => [
+ 'parameters' => [
+ 'srctbl' => 'hosts',
+ 'srcfld1' => 'host',
+ 'dstfrm' => $this->form_name,
+ 'dstfld1' => zbx_formatDomId($field_name.'['.$row_num.'][hosts][]')
+ ]
+ ],
+ 'add_post_js' => false
+ ]))->addClass('js-hosts-multiselect');
+
+ $dataset_head = array_merge($dataset_head, [
+ (new CColor($field_name.'['.$row_num.'][color]', $value['color']))
+ ->appendColorPickerJs(false),
+ $host_pattern_field,
+ (new CPatternSelect([
+ 'name' => $field_name.'['.$row_num.'][items][]',
+ 'object_name' => 'items',
+ 'data' => $value['items'],
+ 'placeholder' => _('item pattern'),
+ 'wildcard_allowed' => 1,
+ 'popup' => [
+ 'parameters' => [
+ 'srctbl' => 'items',
+ 'srcfld1' => 'name',
+ 'real_hosts' => 1,
+ 'numeric' => 1,
+ 'dstfrm' => $this->form_name,
+ 'dstfld1' => zbx_formatDomId($field_name.'['.$row_num.'][items][]')
+ ],
+ 'filter_preselect' => [
+ 'id' => $host_pattern_field->getId(),
+ 'submit_as' => 'host_pattern',
+ 'submit_parameters' => [
+ 'host_pattern_wildcard_allowed' => 1,
+ 'host_pattern_multiple' => 1
+ ],
+ 'multiple' => true
+ ]
+ ],
+ 'autosuggest' => [
+ 'filter_preselect' => [
+ 'id' => $host_pattern_field->getId(),
+ 'submit_as' => 'host_pattern',
+ 'submit_parameters' => [
+ 'host_pattern_wildcard_allowed' => 1,
+ 'host_pattern_multiple' => 1
+ ],
+ 'multiple' => true
+ ]
+ ],
+ 'add_post_js' => false
+ ]))->addClass('js-items-multiselect')
+ ]);
+ }
+ else {
+ $item_rows = [];
+ foreach($value['itemids'] as $i => $itemid) {
+ $item_name = array_key_exists($itemid, $value['item_names'])
+ ? $value['item_names'][$itemid]
+ : '';
+
+ $item_rows[] = $this->getItemRowTemplate($row_num, ($i + 1), $itemid, $item_name, $value['color'][$i]);
+ }
+
+ $empty_msg_block = (new CDiv(_('No item selected.')))->addClass('no-items-message');
+
+ $items_list = (new CTable())
+ ->addClass('single-item-table')
+ ->setAttribute('data-set', $row_num)
+ ->setColumns([
+ (new CTableColumn())->addClass('table-col-handle'),
+ (new CTableColumn())->addClass('table-col-color'),
+ (new CTableColumn())->addClass('table-col-no'),
+ (new CTableColumn(_('Name')))->addClass('table-col-name'),
+ (new CTableColumn(_('Action')))->addClass('table-col-action')
+ ])
+ ->addItem([
+ $item_rows,
+ (new CTag('tfoot', true))
+ ->addItem(
+ (new CCol(
+ (new CList())
+ ->addClass(ZBX_STYLE_INLINE_FILTER_FOOTER)
+ ->addItem(
+ (new CSimpleButton(_('Add')))
+ ->addClass(ZBX_STYLE_BTN_LINK)
+ ->addClass('js-add-item')
+ )
+ ))->setColSpan(5)
+ )
+ ]);
+
+ $dataset_head = array_merge($dataset_head, [
+ (new CDiv([$empty_msg_block, $items_list]))->addClass('items-list table-forms-separator')
+ ]);
+ }
+
+ $dataset_head[] = (new CDiv(
+ (new CButton())
+ ->setAttribute('title', _('Delete'))
+ ->addClass(ZBX_STYLE_BTN_REMOVE)
+ ->removeId()
+ ))->addClass('dataset-actions');
+
+ return (new CListItem([
+ (new CDiv())
+ ->addClass(ZBX_STYLE_DRAG_ICON)
+ ->addClass(ZBX_STYLE_SORTABLE_DRAG_HANDLE)
+ ->addClass('js-main-drag-icon'),
+ (new CDiv())
+ ->addClass(ZBX_STYLE_LIST_ACCORDION_ITEM_HEAD)
+ ->addClass('dataset-head')
+ ->addItem($dataset_head),
+ (new CDiv())
+ ->addClass(ZBX_STYLE_LIST_ACCORDION_ITEM_BODY)
+ ->addClass('dataset-body')
+ ->addItem([
+ (new CFormGrid())
+ ->addItem([
+ new CLabel(_('Draw')),
+ new CFormField(
+ (new CRadioButtonList($field_name.'['.$row_num.'][type]', (int) $value['type']))
+ ->addClass('js-type')
+ ->addValue(_('Line'), SVG_GRAPH_TYPE_LINE)
+ ->addValue(_('Points'), SVG_GRAPH_TYPE_POINTS)
+ ->addValue(_('Staircase'), SVG_GRAPH_TYPE_STAIRCASE)
+ ->addValue(_('Bar'), SVG_GRAPH_TYPE_BAR)
+ ->setModern()
+ )
+ ])
+ ->addItem([
+ new CLabel(_('Stacked'), $field_name.'['.$row_num.'][stacked]'),
+ new CFormField([
+ (new CVar($field_name.'['.$row_num.'][stacked]', '0'))->removeId(),
+ (new CCheckBox($field_name.'['.$row_num.'][stacked]'))
+ ->addClass('js-stacked')
+ ->setChecked((bool) $value['stacked'])
+ ->setEnabled($value['type'] != SVG_GRAPH_TYPE_POINTS)
+ ])
+ ])
+ ->addItem([
+ new CLabel(_('Width')),
+ new CFormField(
+ (new CRangeControl($field_name.'['.$row_num.'][width]', (int) $value['width']))
+ ->setEnabled(!in_array($value['type'], [SVG_GRAPH_TYPE_POINTS, SVG_GRAPH_TYPE_BAR]))
+ ->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
+ ->setStep(1)
+ ->setMin(0)
+ ->setMax(10)
+ )
+ ])
+ ->addItem([
+ new CLabel(_('Point size')),
+ new CFormField(
+ (new CRangeControl($field_name.'['.$row_num.'][pointsize]', (int) $value['pointsize']))
+ ->setEnabled($value['type'] == SVG_GRAPH_TYPE_POINTS)
+ ->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
+ ->setStep(1)
+ ->setMin(1)
+ ->setMax(10)
+ )
+ ])
+ ->addItem([
+ new CLabel(_('Transparency')),
+ new CFormField(
+ (new CRangeControl($field_name.'['.$row_num.'][transparency]',
+ (int) $value['transparency'])
+ )
+ ->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
+ ->setStep(1)
+ ->setMin(0)
+ ->setMax(10)
+ )
+ ])
+ ->addItem([
+ new CLabel(_('Fill')),
+ new CFormField(
+ (new CRangeControl($field_name.'['.$row_num.'][fill]', (int) $value['fill']))
+ ->setEnabled(!in_array($value['type'], [SVG_GRAPH_TYPE_POINTS, SVG_GRAPH_TYPE_BAR]))
+ ->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
+ ->setStep(1)
+ ->setMin(0)
+ ->setMax(10)
+ )
+ ]),
+ (new CFormGrid())
+ ->addItem([
+ new CLabel(_('Missing data')),
+ new CFormField(
+ (new CRadioButtonList($field_name.'['.$row_num.'][missingdatafunc]',
+ (int) $value['missingdatafunc'])
+ )
+ ->addValue(_('None'), SVG_GRAPH_MISSING_DATA_NONE)
+ ->addValue(_x('Connected', 'missing data function'),
+ SVG_GRAPH_MISSING_DATA_CONNECTED
+ )
+ ->addValue(_x('Treat as 0', 'missing data function'),
+ SVG_GRAPH_MISSING_DATA_TREAT_AS_ZERO
+ )
+ ->addValue(_x('Last known', 'missing data function'),
+ SVG_GRAPH_MISSING_DATA_LAST_KNOWN
+ )
+ ->setEnabled(!in_array($value['type'], [SVG_GRAPH_TYPE_POINTS, SVG_GRAPH_TYPE_BAR]))
+ ->setModern()
+ )
+ ])
+ ->addItem([
+ new CLabel(_('Y-axis')),
+ new CFormField(
+ (new CRadioButtonList($field_name.'['.$row_num.'][axisy]', (int) $value['axisy']))
+ ->addValue(_('Left'), GRAPH_YAXIS_SIDE_LEFT)
+ ->addValue(_('Right'), GRAPH_YAXIS_SIDE_RIGHT)
+ ->setModern()
+ )
+ ])
+ ->addItem([
+ new CLabel(_('Time shift'), $field_name.'['.$row_num.'][timeshift]'),
+ new CFormField(
+ (new CTextBox($field_name.'['.$row_num.'][timeshift]', $value['timeshift']))
+ ->setWidth(ZBX_TEXTAREA_TINY_WIDTH)
+ ->setAttribute('placeholder', _('none'))
+ )
+ ])
+ ->addItem([
+ new CLabel(_('Aggregation function'),
+ 'label-'.$field_name.'_'.$row_num.'_aggregate_function'
+ ),
+ new CFormField(
+ (new CSelect($field_name.'['.$row_num.'][aggregate_function]'))
+ ->setId($field_name.'_'.$row_num.'_aggregate_function')
+ ->setFocusableElementId('label-'.$field_name.'_'.$row_num.'_aggregate_function')
+ ->setValue((int) $value['aggregate_function'])
+ ->addOptions(CSelect::createOptionsFromArray([
+ AGGREGATE_NONE => graph_item_aggr_fnc2str(AGGREGATE_NONE),
+ AGGREGATE_MIN => graph_item_aggr_fnc2str(AGGREGATE_MIN),
+ AGGREGATE_MAX => graph_item_aggr_fnc2str(AGGREGATE_MAX),
+ AGGREGATE_AVG => graph_item_aggr_fnc2str(AGGREGATE_AVG),
+ AGGREGATE_COUNT => graph_item_aggr_fnc2str(AGGREGATE_COUNT),
+ AGGREGATE_SUM => graph_item_aggr_fnc2str(AGGREGATE_SUM),
+ AGGREGATE_FIRST => graph_item_aggr_fnc2str(AGGREGATE_FIRST),
+ AGGREGATE_LAST => graph_item_aggr_fnc2str(AGGREGATE_LAST)
+ ]))
+ ->setWidth(ZBX_TEXTAREA_TINY_WIDTH)
+ )
+ ])
+ ->addItem([
+ new CLabel(_('Aggregation interval'), $field_name.'['.$row_num.'][aggregate_interval]'),
+ new CFormField(
+ (new CTextBox($field_name.'['.$row_num.'][aggregate_interval]',
+ $value['aggregate_interval']
+ ))
+ ->setEnabled($value['aggregate_function'] != AGGREGATE_NONE)
+ ->setWidth(ZBX_TEXTAREA_TINY_WIDTH)
+ ->setAttribute('placeholder', GRAPH_AGGREGATE_DEFAULT_INTERVAL)
+ )
+ ])
+ ->addItem([
+ new CLabel(_('Aggregate')),
+ new CFormField(
+ (new CRadioButtonList($field_name.'['.$row_num.'][aggregate_grouping]',
+ (int) $value['aggregate_grouping'])
+ )
+ ->addValue(_('Each item'), GRAPH_AGGREGATE_BY_ITEM)
+ ->addValue(_('Data set'), GRAPH_AGGREGATE_BY_DATASET)
+ ->setEnabled($value['aggregate_function'] != AGGREGATE_NONE)
+ ->setModern()
+ )
+ ])
+ ->addItem([
+ new CLabel(_('Approximation'),
+ 'label-'.$field_name.'_'.$row_num.'_approximation'
+ ),
+ new CFormField(
+ (new CSelect($field_name.'['.$row_num.'][approximation]'))
+ ->setId($field_name.'_'.$row_num.'_approximation')
+ ->setFocusableElementId('label-'.$field_name.'_'.$row_num.'_approximation')
+ ->setValue((int) $value['approximation'])
+ ->addOptions(CSelect::createOptionsFromArray([
+ APPROXIMATION_ALL => [
+ 'label' => _('all'),
+ 'disabled' => $value['type'] != SVG_GRAPH_TYPE_LINE || $value['stacked']
+ ],
+ APPROXIMATION_MIN => _('min'),
+ APPROXIMATION_AVG => _('avg'),
+ APPROXIMATION_MAX => _('max')
+ ]))
+ ->setWidth(ZBX_TEXTAREA_TINY_WIDTH)
+ )
+ ])
+ ])
+ ]))
+ ->addClass(ZBX_STYLE_LIST_ACCORDION_ITEM)
+ ->addClass(ZBX_STYLE_SORTABLE_ITEM)
+ ->addClass($is_opened ? ZBX_STYLE_LIST_ACCORDION_ITEM_OPENED : ZBX_STYLE_LIST_ACCORDION_ITEM_CLOSED)
+ ->setAttribute('data-set', $row_num)
+ ->setAttribute('data-type', $dataset_type);
+ }
+
+ private function getItemRowTemplate($ds_num = '#{dsNum}', $row_num = '#{rowNum}', $itemid = '#{itemid}',
+ $name = '#{name}', $color = '#{color}'): CRow {
+ return (new CRow([
+ (new CCol(
+ (new CDiv())->addClass(ZBX_STYLE_DRAG_ICON)
+ ))
+ ->addClass('table-col-handle')
+ ->addClass(ZBX_STYLE_TD_DRAG_ICON),
+ (new CCol(
+ (new CColor($this->field->getName().'['.$ds_num.'][color][]', $color,
+ 'items_'.$ds_num.'_'.$row_num.'_color'
+ ))->appendColorPickerJs(false)
+ ))->addClass('table-col-color'),
+ (new CCol(new CSpan($row_num.':')))->addClass('table-col-no'),
+ (new CCol(
+ (new CLink($name))
+ ->setId('items_'.$ds_num.'_'.$row_num.'_name')
+ ->addClass('js-click-expend')
+ ))->addClass('table-col-name'),
+ (new CCol([
+ (new CButton('button', _('Remove')))
+ ->addClass(ZBX_STYLE_BTN_LINK)
+ ->addClass('element-table-remove'),
+ new CVar($this->field->getName().'['.$ds_num.'][itemids][]', $itemid,
+ 'items_'.$ds_num.'_'.$row_num.'_input'
+ )
+ ]))
+ ->addClass('table-col-action')
+ ->addClass(ZBX_STYLE_NOWRAP)
+ ]))
+ ->addClass(ZBX_STYLE_SORTABLE)
+ ->addClass('single-item-table-row');
+ }
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldGraphOverrideView.php b/ui/include/classes/html/widgets/CWidgetFieldGraphOverrideView.php
new file mode 100755
index 00000000000..a15914f30d1
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldGraphOverrideView.php
@@ -0,0 +1,348 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldGraphOverride;
+
+class CWidgetFieldGraphOverrideView extends CWidgetFieldView {
+
+ public function __construct(CWidgetFieldGraphOverride $field) {
+ $this->field = $field;
+ }
+
+ public function getView(): CList {
+ $list = (new CList())->addClass(ZBX_STYLE_OVERRIDES_LIST);
+
+ $i = 0;
+ foreach ($this->field->getValue() as $override) {
+ $list->addItem($this->getItemTemplate($override, $i));
+
+ $i++;
+ }
+
+ $list->addItem(
+ (new CDiv(
+ (new CButton('override_add', [(new CSpan())->addClass(ZBX_STYLE_PLUS_ICON), _('Add new override')]))
+ ->addClass(ZBX_STYLE_BTN_ALT)
+ ->setId('override-add')
+ )),
+ 'overrides-foot'
+ );
+
+ return $list;
+ }
+
+ public function getJavaScript(): string {
+ return '
+ // Define it as function to avoid redundancy.
+ function initializeOverrides() {
+ jQuery("#overrides .'.ZBX_STYLE_OVERRIDES_OPTIONS_LIST.'").overrides({
+ add: ".'.ZBX_STYLE_BTN_ALT.'",
+ options: "input[type=hidden]",
+ captions: '.json_encode($this->getGraphOverrideOptionNames()).',
+ makeName: function(option, row_id) {
+ return "'.$this->field->getName().'[" + row_id + "][" + option + "]";
+ },
+ makeOption: function(name) {
+ return name.match(
+ /.*\[('.implode('|', $this->field->getOverrideOptions()).')\]/
+ )[1];
+ },
+ override: ".'.ZBX_STYLE_OVERRIDES_LIST_ITEM.'",
+ overridesList: ".'.ZBX_STYLE_OVERRIDES_LIST.'",
+ onUpdate: () => widget_svggraph_form.onGraphConfigChange(),
+ menu: '.json_encode($this->getGraphOverrideMenu()).'
+ });
+ }
+
+ // Initialize dynamicRows.
+ jQuery("#overrides")
+ .dynamicRows({
+ template: "#overrides-row",
+ beforeRow: ".overrides-foot",
+ remove: ".'.ZBX_STYLE_BTN_REMOVE.'",
+ add: "#override-add",
+ row: ".'.ZBX_STYLE_OVERRIDES_LIST_ITEM.'"
+ })
+ .bind("afteradd.dynamicRows", function(event, options) {
+ const container = jQuery(".overlay-dialogue-body");
+
+ container.scrollTop(Math.max(container.scrollTop(),
+ jQuery("#widget-dialogue-form")[0].scrollHeight - container.height()
+ ));
+
+ jQuery(".multiselect", jQuery("#overrides")).each(function() {
+ jQuery(this).multiSelect(jQuery(this).data("params"));
+ });
+
+ widget_svggraph_form.updateVariableOrder(jQuery("#overrides"), ".'.ZBX_STYLE_OVERRIDES_LIST_ITEM.'", "or");
+ widget_svggraph_form.onGraphConfigChange();
+ })
+ .bind("afterremove.dynamicRows", function(event, options) {
+ widget_svggraph_form.updateVariableOrder(jQuery("#overrides"), ".'.ZBX_STYLE_OVERRIDES_LIST_ITEM.'", "or");
+ widget_svggraph_form.onGraphConfigChange();
+ })
+ .bind("tableupdate.dynamicRows", function(event, options) {
+ widget_svggraph_form.updateVariableOrder(jQuery("#overrides"), ".'.ZBX_STYLE_OVERRIDES_LIST_ITEM.'", "or");
+ initializeOverrides();
+ if (jQuery("#overrides .'.ZBX_STYLE_OVERRIDES_LIST_ITEM.'").length > 1) {
+ jQuery("#overrides .drag-icon").removeClass("disabled");
+ jQuery("#overrides").sortable("enable");
+ }
+ else {
+ jQuery("#overrides .drag-icon").addClass("disabled");
+ jQuery("#overrides").sortable("disable");
+ }
+ });
+
+ // Initialize overrides UI control.
+ initializeOverrides();
+
+ // Initialize override pattern-selectors.
+ jQuery(".multiselect", jQuery("#overrides")).each(function() {
+ jQuery(this).multiSelect(jQuery(this).data("params"));
+ });
+
+ // Make overrides sortable.
+ if (jQuery("#overrides .'.ZBX_STYLE_OVERRIDES_LIST_ITEM.'").length < 2) {
+ jQuery("#overrides .drag-icon").addClass("disabled");
+ }
+
+ jQuery("#overrides").sortable({
+ items: ".'.ZBX_STYLE_OVERRIDES_LIST_ITEM.'",
+ containment: "parent",
+ handle: ".drag-icon",
+ tolerance: "pointer",
+ scroll: false,
+ cursor: "grabbing",
+ opacity: 0.6,
+ axis: "y",
+ disabled: function() {
+ return jQuery("#overrides .'.ZBX_STYLE_OVERRIDES_LIST_ITEM.'").length < 2;
+ }(),
+ start: function() { // Workaround to fix wrong scrolling at initial sort.
+ jQuery(this).sortable("refreshPositions");
+ },
+ stop: () => widget_svggraph_form.onGraphConfigChange(),
+ update: function() {
+ widget_svggraph_form.updateVariableOrder(jQuery("#overrides"), ".'.ZBX_STYLE_OVERRIDES_LIST_ITEM.'", "or");
+ }
+ });
+ ';
+ }
+
+ public function getTemplates(): array {
+ return [
+ new CTemplateTag('overrides-row', $this->getItemTemplate(CWidgetFieldGraphOverride::getDefaults()))
+ ];
+ }
+
+ /**
+ * Function returns array containing string values used as titles for override options.
+ */
+ private function getGraphOverrideOptionNames(): array {
+ return [
+ 'width' => _('Width'),
+ 'type' => _('Draw'),
+ 'type'.SVG_GRAPH_TYPE_LINE => _('Line'),
+ 'type'.SVG_GRAPH_TYPE_POINTS => _('Points'),
+ 'type'.SVG_GRAPH_TYPE_STAIRCASE => _('Staircase'),
+ 'type'.SVG_GRAPH_TYPE_BAR => _('Bar'),
+ 'transparency' => _('Transparency'),
+ 'fill' => _('Fill'),
+ 'pointsize' => _('Point size'),
+ 'missingdatafunc' => _('Missing data'),
+ 'missingdatafunc'.SVG_GRAPH_MISSING_DATA_NONE => _('None'),
+ 'missingdatafunc'.SVG_GRAPH_MISSING_DATA_CONNECTED => _x('Connected', 'missing data function'),
+ 'missingdatafunc'.SVG_GRAPH_MISSING_DATA_TREAT_AS_ZERO => _x('Treat as 0', 'missing data function'),
+ 'missingdatafunc'.SVG_GRAPH_MISSING_DATA_LAST_KNOWN => _x('Last known', 'missing data function'),
+ 'axisy' => _('Y-axis'),
+ 'axisy'.GRAPH_YAXIS_SIDE_LEFT => _('Left'),
+ 'axisy'.GRAPH_YAXIS_SIDE_RIGHT => _('Right'),
+ 'timeshift' => _('Time shift')
+ ];
+ }
+
+ /**
+ * Function returns array used to construct override field menu of available override options.
+ */
+ private function getGraphOverrideMenu(): array {
+ return [
+ 'sections' => [
+ [
+ 'name' => _('ADD OVERRIDE'),
+ 'options' => [
+ ['name' => _('Base color'), 'callback' => 'addOverride', 'args' => ['color', '']],
+
+ ['name' => _('Width').'/0', 'callback' => 'addOverride', 'args' => ['width', 0]],
+ ['name' => _('Width').'/1', 'callback' => 'addOverride', 'args' => ['width', 1]],
+ ['name' => _('Width').'/2', 'callback' => 'addOverride', 'args' => ['width', 2]],
+ ['name' => _('Width').'/3', 'callback' => 'addOverride', 'args' => ['width', 3]],
+ ['name' => _('Width').'/4', 'callback' => 'addOverride', 'args' => ['width', 4]],
+ ['name' => _('Width').'/5', 'callback' => 'addOverride', 'args' => ['width', 5]],
+ ['name' => _('Width').'/6', 'callback' => 'addOverride', 'args' => ['width', 6]],
+ ['name' => _('Width').'/7', 'callback' => 'addOverride', 'args' => ['width', 7]],
+ ['name' => _('Width').'/8', 'callback' => 'addOverride', 'args' => ['width', 8]],
+ ['name' => _('Width').'/9', 'callback' => 'addOverride', 'args' => ['width', 9]],
+ ['name' => _('Width').'/10', 'callback' => 'addOverride', 'args' => ['width', 10]],
+
+ ['name' => _('Draw').'/'._('Line'), 'callback' => 'addOverride', 'args' => ['type', SVG_GRAPH_TYPE_LINE]],
+ ['name' => _('Draw').'/'._('Points'), 'callback' => 'addOverride', 'args' => ['type', SVG_GRAPH_TYPE_POINTS]],
+ ['name' => _('Draw').'/'._('Staircase'), 'callback' => 'addOverride', 'args' => ['type', SVG_GRAPH_TYPE_STAIRCASE]],
+ ['name' => _('Draw').'/'._('Bar'), 'callback' => 'addOverride', 'args' => ['type', SVG_GRAPH_TYPE_BAR]],
+
+ ['name' => _('Transparency').'/0', 'callback' => 'addOverride', 'args' => ['transparency', 0]],
+ ['name' => _('Transparency').'/1', 'callback' => 'addOverride', 'args' => ['transparency', 1]],
+ ['name' => _('Transparency').'/2', 'callback' => 'addOverride', 'args' => ['transparency', 2]],
+ ['name' => _('Transparency').'/3', 'callback' => 'addOverride', 'args' => ['transparency', 3]],
+ ['name' => _('Transparency').'/4', 'callback' => 'addOverride', 'args' => ['transparency', 4]],
+ ['name' => _('Transparency').'/5', 'callback' => 'addOverride', 'args' => ['transparency', 5]],
+ ['name' => _('Transparency').'/6', 'callback' => 'addOverride', 'args' => ['transparency', 6]],
+ ['name' => _('Transparency').'/7', 'callback' => 'addOverride', 'args' => ['transparency', 7]],
+ ['name' => _('Transparency').'/8', 'callback' => 'addOverride', 'args' => ['transparency', 8]],
+ ['name' => _('Transparency').'/9', 'callback' => 'addOverride', 'args' => ['transparency', 9]],
+ ['name' => _('Transparency').'/10', 'callback' => 'addOverride', 'args' => ['transparency', 10]],
+
+ ['name' => _('Fill').'/0', 'callback' => 'addOverride', 'args' => ['fill', 0]],
+ ['name' => _('Fill').'/1', 'callback' => 'addOverride', 'args' => ['fill', 1]],
+ ['name' => _('Fill').'/2', 'callback' => 'addOverride', 'args' => ['fill', 2]],
+ ['name' => _('Fill').'/3', 'callback' => 'addOverride', 'args' => ['fill', 3]],
+ ['name' => _('Fill').'/4', 'callback' => 'addOverride', 'args' => ['fill', 4]],
+ ['name' => _('Fill').'/5', 'callback' => 'addOverride', 'args' => ['fill', 5]],
+ ['name' => _('Fill').'/6', 'callback' => 'addOverride', 'args' => ['fill', 6]],
+ ['name' => _('Fill').'/7', 'callback' => 'addOverride', 'args' => ['fill', 7]],
+ ['name' => _('Fill').'/8', 'callback' => 'addOverride', 'args' => ['fill', 8]],
+ ['name' => _('Fill').'/9', 'callback' => 'addOverride', 'args' => ['fill', 9]],
+ ['name' => _('Fill').'/10', 'callback' => 'addOverride', 'args' => ['fill', 10]],
+
+ ['name' => _('Point size').'/1', 'callback' => 'addOverride', 'args' => ['pointsize', 1]],
+ ['name' => _('Point size').'/2', 'callback' => 'addOverride', 'args' => ['pointsize', 2]],
+ ['name' => _('Point size').'/3', 'callback' => 'addOverride', 'args' => ['pointsize', 3]],
+ ['name' => _('Point size').'/4', 'callback' => 'addOverride', 'args' => ['pointsize', 4]],
+ ['name' => _('Point size').'/5', 'callback' => 'addOverride', 'args' => ['pointsize', 5]],
+ ['name' => _('Point size').'/6', 'callback' => 'addOverride', 'args' => ['pointsize', 6]],
+ ['name' => _('Point size').'/7', 'callback' => 'addOverride', 'args' => ['pointsize', 7]],
+ ['name' => _('Point size').'/8', 'callback' => 'addOverride', 'args' => ['pointsize', 8]],
+ ['name' => _('Point size').'/9', 'callback' => 'addOverride', 'args' => ['pointsize', 9]],
+ ['name' => _('Point size').'/10', 'callback' => 'addOverride', 'args' => ['pointsize', 10]],
+
+ ['name' => _('Missing data').'/'._('None'), 'callback' => 'addOverride', 'args' => ['missingdatafunc', SVG_GRAPH_MISSING_DATA_NONE]],
+ ['name' => _('Missing data').'/'._x('Connected', 'missing data function'), 'callback' => 'addOverride', 'args' => ['missingdatafunc', SVG_GRAPH_MISSING_DATA_CONNECTED]],
+ ['name' => _('Missing data').'/'._x('Treat as 0', 'missing data function'), 'callback' => 'addOverride', 'args' => ['missingdatafunc', SVG_GRAPH_MISSING_DATA_TREAT_AS_ZERO]],
+ ['name' => _('Missing data').'/'._x('Last known', 'missing data function'), 'callback' => 'addOverride', 'args' => ['missingdatafunc', SVG_GRAPH_MISSING_DATA_LAST_KNOWN]],
+
+ ['name' => _('Y-axis').'/'._('Left'), 'callback' => 'addOverride', 'args' => ['axisy', GRAPH_YAXIS_SIDE_LEFT]],
+ ['name' => _('Y-axis').'/'._('Right'), 'callback' => 'addOverride', 'args' => ['axisy', GRAPH_YAXIS_SIDE_RIGHT]],
+
+ ['name' => _('Time shift'), 'callback' => 'addOverride', 'args' => ['timeshift']]
+ ]
+ ]
+ ]
+ ];
+ }
+
+ private function getItemTemplate(array $value, $row_num = '#{rowNum}'): CListItem {
+ $inputs = [];
+
+ // Create override options list.
+ foreach ($this->field->getOverrideOptions() as $option) {
+ if (array_key_exists($option, $value)) {
+ $inputs[] = (new CVar($this->field->getName().'['.$row_num.']['.$option.']', $value[$option]));
+ }
+ }
+
+ $host_pattern_field = (new CPatternSelect([
+ 'name' => $this->field->getName().'['.$row_num.'][hosts][]',
+ 'object_name' => 'hosts',
+ 'data' => $value['hosts'],
+ 'placeholder' => _('host pattern'),
+ 'wildcard_allowed' => 1,
+ 'popup' => [
+ 'parameters' => [
+ 'srctbl' => 'hosts',
+ 'srcfld1' => 'hostid',
+ 'dstfrm' => $this->form_name,
+ 'dstfld1' => zbx_formatDomId($this->field->getName().'['.$row_num.'][hosts][]')
+ ]
+ ],
+ 'add_post_js' => false
+ ]))
+ ->setEnabled(!$this->isDisabled())
+ ->setAriaRequired($this->isRequired());
+
+ return (new CListItem([
+ (new CDiv())->addClass(ZBX_STYLE_DRAG_ICON),
+ $host_pattern_field,
+ (new CPatternSelect([
+ 'name' => $this->field->getName().'['.$row_num.'][items][]',
+ 'object_name' => 'items',
+ 'data' => $value['items'],
+ 'placeholder' => _('item pattern'),
+ 'wildcard_allowed' => 1,
+ 'popup' => [
+ 'parameters' => [
+ 'srctbl' => 'items',
+ 'srcfld1' => 'itemid',
+ 'real_hosts' => 1,
+ 'numeric' => 1,
+ 'dstfrm' => $this->form_name,
+ 'dstfld1' => zbx_formatDomId($this->field->getName().'['.$row_num.'][items][]')
+ ],
+ 'filter_preselect' => [
+ 'id' => $host_pattern_field->getId(),
+ 'submit_as' => 'host_pattern',
+ 'submit_parameters' => [
+ 'host_pattern_wildcard_allowed' => 1,
+ 'host_pattern_multiple' => 1
+ ],
+ 'multiple' => true
+ ]
+ ],
+ 'autosuggest' => [
+ 'filter_preselect' => [
+ 'id' => $host_pattern_field->getId(),
+ 'submit_as' => 'host_pattern',
+ 'submit_parameters' => [
+ 'host_pattern_wildcard_allowed' => 1,
+ 'host_pattern_multiple' => 1
+ ],
+ 'multiple' => true
+ ]
+ ],
+ 'add_post_js' => false
+ ]))
+ ->setEnabled(!$this->isDisabled())
+ ->setAriaRequired($this->isRequired()),
+ (new CDiv(
+ (new CButton())
+ ->setAttribute('title', _('Delete'))
+ ->addClass(ZBX_STYLE_BTN_REMOVE)
+ ->removeId()
+ ))->addClass('dataset-actions'),
+ (new CList($inputs))
+ ->addClass(ZBX_STYLE_OVERRIDES_OPTIONS_LIST)
+ ->addItem(
+ (new CButton(null, (new CSpan())->addClass(ZBX_STYLE_PLUS_ICON)))
+ ->setAttribute('data-row', $row_num)
+ ->addClass(ZBX_STYLE_BTN_ALT)
+ )
+ ]))->addClass(ZBX_STYLE_OVERRIDES_LIST_ITEM);
+ }
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldHostPatternSelectView.php b/ui/include/classes/html/widgets/CWidgetFieldHostPatternSelectView.php
new file mode 100755
index 00000000000..2f16643f678
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldHostPatternSelectView.php
@@ -0,0 +1,65 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldHostPatternSelect;
+
+class CWidgetFieldHostPatternSelectView extends CWidgetFieldView {
+
+ private string $placeholder = '';
+
+ public function __construct(CWidgetFieldHostPatternSelect $field) {
+ $this->field = $field;
+ }
+
+ public function setPlaceholder(string $placeholder): self {
+ $this->placeholder = $placeholder;
+
+ return $this;
+ }
+
+ public function getView(): CPatternSelect {
+ return (new CPatternSelect([
+ 'name' => $this->field->getName().'[]',
+ 'object_name' => 'hosts',
+ 'data' => $this->field->getValue(),
+ 'placeholder' => $this->placeholder,
+ 'wildcard_allowed' => 1,
+ 'popup' => [
+ 'parameters' => [
+ 'srctbl' => 'hosts',
+ 'srcfld1' => 'hostid',
+ 'dstfrm' => $this->form_name,
+ 'dstfld1' => zbx_formatDomId($this->field->getName().'[]')
+ ]
+ ],
+ 'add_post_js' => false
+ ]))
+ ->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
+ ->setEnabled(!$this->isDisabled())
+ ->setAriaRequired($this->isRequired());
+ }
+
+ public function getJavaScript(): string {
+ $field_id = zbx_formatDomId($this->field->getName().'[]');
+
+ return 'jQuery("#'.$field_id.'").multiSelect(jQuery("#'.$field_id.'").data("params"));';
+ }
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldIntegerBoxView.php b/ui/include/classes/html/widgets/CWidgetFieldIntegerBoxView.php
new file mode 100755
index 00000000000..f1e36ee5e6a
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldIntegerBoxView.php
@@ -0,0 +1,37 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldIntegerBox;
+
+class CWidgetFieldIntegerBoxView extends CWidgetFieldView {
+
+ public function __construct(CWidgetFieldIntegerBox $field) {
+ $this->field = $field;
+ }
+
+ public function getView(): CNumericBox {
+ return (new CNumericBox($this->field->getName(), $this->field->getValue(), $this->field->getMaxLength(), false,
+ !$this->isNotEmpty()
+ ))
+ ->setWidth(ZBX_TEXTAREA_NUMERIC_STANDARD_WIDTH)
+ ->setAriaRequired($this->isRequired());
+ }
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldLatLngView.php b/ui/include/classes/html/widgets/CWidgetFieldLatLngView.php
new file mode 100755
index 00000000000..d06e5c4e1fc
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldLatLngView.php
@@ -0,0 +1,72 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldLatLng;
+
+class CWidgetFieldLatLngView extends CWidgetFieldView {
+
+ private string $placeholder = '';
+
+ private int $width = ZBX_TEXTAREA_MEDIUM_WIDTH;
+
+ public function __construct(CWidgetFieldLatLng $field) {
+ $this->field = $field;
+
+ $this->setHelpHint([
+ _('Comma separated center coordinates and zoom level to display when the widget is initially loaded.'),
+ BR(),
+ _('Supported formats:'),
+ (new CList([
+ new CListItem((new CSpan('<lat>,<lng>,<zoom>'))->addClass(ZBX_STYLE_MONOSPACE_FONT)),
+ new CListItem((new CSpan('<lat>,<lng>'))->addClass(ZBX_STYLE_MONOSPACE_FONT))
+ ]))->addClass(ZBX_STYLE_LIST_DASHED),
+ BR(),
+ _s('The maximum zoom level is "%1$s".', CSettingsHelper::get(CSettingsHelper::GEOMAPS_MAX_ZOOM)),
+ BR(),
+ _('Initial view is ignored if the default view is set.')
+ ]);
+ }
+
+ public function setPlaceholder(string $placeholder): self {
+ $this->placeholder = $placeholder;
+
+ return $this;
+ }
+
+ public function setWidth(int $width): self {
+ $this->width = $width;
+
+ return $this;
+ }
+
+ public function getView(): CTextBox {
+ $textbox = (new CTextBox($this->field->getName(), $this->field->getValue()))
+ ->setWidth($this->width)
+ ->setEnabled(!$this->isDisabled())
+ ->setAriaRequired($this->isRequired());
+
+ if ($this->placeholder !== '') {
+ $textbox = $textbox->setAttribute('placeholder', $this->placeholder);
+ }
+
+ return $textbox;
+ }
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldMultiSelectGraphPrototypeView.php b/ui/include/classes/html/widgets/CWidgetFieldMultiSelectGraphPrototypeView.php
new file mode 100755
index 00000000000..eb4169a0faa
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldMultiSelectGraphPrototypeView.php
@@ -0,0 +1,42 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldMultiSelectGraphPrototype;
+
+class CWidgetFieldMultiSelectGraphPrototypeView extends CWidgetFieldMultiSelectView {
+
+ public function __construct(CWidgetFieldMultiSelectGraphPrototype $field, array $data) {
+ parent::__construct($field, $data);
+ }
+
+ protected function getObjectName(): string {
+ return 'graph_prototypes';
+ }
+
+ protected function getPopupParameters(): array {
+ return [
+ 'srctbl' => 'graph_prototypes',
+ 'srcfld1' => 'graphid',
+ 'srcfld2' => 'name',
+ 'with_graph_prototypes' => true
+ ];
+ }
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldMultiSelectGraphView.php b/ui/include/classes/html/widgets/CWidgetFieldMultiSelectGraphView.php
new file mode 100755
index 00000000000..a67260b30ac
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldMultiSelectGraphView.php
@@ -0,0 +1,42 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldMultiSelectGraph;
+
+class CWidgetFieldMultiSelectGraphView extends CWidgetFieldMultiSelectView {
+
+ public function __construct(CWidgetFieldMultiSelectGraph $field, array $data) {
+ parent::__construct($field, $data);
+ }
+
+ protected function getObjectName(): string {
+ return 'graphs';
+ }
+
+ protected function getPopupParameters(): array {
+ return [
+ 'srctbl' => 'graphs',
+ 'srcfld1' => 'graphid',
+ 'srcfld2' => 'name',
+ 'with_graphs' => true
+ ];
+ }
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldMultiSelectGroupView.php b/ui/include/classes/html/widgets/CWidgetFieldMultiSelectGroupView.php
new file mode 100755
index 00000000000..42ac95d0721
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldMultiSelectGroupView.php
@@ -0,0 +1,42 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldMultiSelectGroup;
+
+class CWidgetFieldMultiSelectGroupView extends CWidgetFieldMultiSelectView {
+
+ public function __construct(CWidgetFieldMultiSelectGroup $field, array $data) {
+ parent::__construct($field, $data);
+ }
+
+ protected function getObjectName(): string {
+ return 'hostGroup';
+ }
+
+ protected function getPopupParameters(): array {
+ return [
+ 'srctbl' => 'host_groups',
+ 'srcfld1' => 'groupid',
+ 'real_hosts' => true,
+ 'enrich_parent_groups' => true
+ ];
+ }
+}
diff --git a/ui/app/views/js/monitoring.dashboard.widget.edit.js.php b/ui/include/classes/html/widgets/CWidgetFieldMultiSelectHostView.php
index b0f46f671e7..23d727818e5 100644..100755
--- a/ui/app/views/js/monitoring.dashboard.widget.edit.js.php
+++ b/ui/include/classes/html/widgets/CWidgetFieldMultiSelectHostView.php
@@ -17,21 +17,24 @@
** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
-?>
-window.widget_form = new class {
- init() {
- document.getElementById('type').addEventListener('change', () => ZABBIX.Dashboard.reloadWidgetProperties());
+use Zabbix\Widgets\Fields\CWidgetFieldMultiSelectHost;
- document.getElementById('widget-dialogue-form').addEventListener('change', (e) => {
- const is_trimmable = e.target.matches(
- 'input[type="text"]:not([data-no-trim="1"]), textarea:not([data-no-trim="1"])'
- );
+class CWidgetFieldMultiSelectHostView extends CWidgetFieldMultiSelectView {
- if (is_trimmable) {
- e.target.value = e.target.value.trim();
- }
- }, {capture: true});
+ public function __construct(CWidgetFieldMultiSelectHost $field, array $data) {
+ parent::__construct($field, $data);
}
-};
+
+ protected function getObjectName(): string {
+ return 'hosts';
+ }
+
+ protected function getPopupParameters(): array {
+ return [
+ 'srctbl' => 'hosts',
+ 'srcfld1' => 'hostid'
+ ];
+ }
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldMultiSelectItemPrototypeView.php b/ui/include/classes/html/widgets/CWidgetFieldMultiSelectItemPrototypeView.php
new file mode 100755
index 00000000000..8de80be206f
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldMultiSelectItemPrototypeView.php
@@ -0,0 +1,40 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldMultiSelectItemPrototype;
+
+class CWidgetFieldMultiSelectItemPrototypeView extends CWidgetFieldMultiSelectView {
+
+ public function __construct(CWidgetFieldMultiSelectItemPrototype $field, array $data) {
+ parent::__construct($field, $data);
+ }
+
+ protected function getObjectName(): string {
+ return 'item_prototypes';
+ }
+
+ protected function getPopupParameters(): array {
+ return [
+ 'srctbl' => 'item_prototypes',
+ 'srcfld1' => 'itemid'
+ ];
+ }
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldMultiSelectItemView.php b/ui/include/classes/html/widgets/CWidgetFieldMultiSelectItemView.php
new file mode 100755
index 00000000000..74c7816ef41
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldMultiSelectItemView.php
@@ -0,0 +1,40 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldMultiSelectItem;
+
+class CWidgetFieldMultiSelectItemView extends CWidgetFieldMultiSelectView {
+
+ public function __construct(CWidgetFieldMultiSelectItem $field, array $data) {
+ parent::__construct($field, $data);
+ }
+
+ protected function getObjectName(): string {
+ return 'items';
+ }
+
+ protected function getPopupParameters(): array {
+ return [
+ 'srctbl' => 'items',
+ 'srcfld1' => 'itemid'
+ ];
+ }
+}
diff --git a/ui/include/classes/widgets/views/js/widget.problems.form.view.js.php b/ui/include/classes/html/widgets/CWidgetFieldMultiSelectServiceView.php
index 64206926d0c..4b68ec939b4 100644..100755
--- a/ui/include/classes/widgets/views/js/widget.problems.form.view.js.php
+++ b/ui/include/classes/html/widgets/CWidgetFieldMultiSelectServiceView.php
@@ -17,17 +17,19 @@
** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
-?>
-window.widget_problems_form = new class {
+use Zabbix\Widgets\Fields\CWidgetFieldMultiSelectService;
- init({sort_with_enabled_show_timeline}) {
- document.getElementById('sort_triggers').addEventListener('change', (e) => {
- const show_timeline = document.getElementById('show_timeline');
+class CWidgetFieldMultiSelectServiceView extends CWidgetFieldMultiSelectView {
- show_timeline.disabled = !sort_with_enabled_show_timeline[e.target.value];
- show_timeline.checked = !show_timeline.disabled;
- });
+ public function __construct(CWidgetFieldMultiSelectService $field, array $data) {
+ parent::__construct($field, $data);
+
+ $this->custom_select = true;
+ }
+
+ protected function getObjectName(): string {
+ return 'services';
}
-};
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldMultiSelectSlaView.php b/ui/include/classes/html/widgets/CWidgetFieldMultiSelectSlaView.php
new file mode 100755
index 00000000000..6b3b87ede1a
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldMultiSelectSlaView.php
@@ -0,0 +1,40 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldMultiSelectSla;
+
+class CWidgetFieldMultiSelectSlaView extends CWidgetFieldMultiSelectView {
+
+ public function __construct(CWidgetFieldMultiSelectSla $field, array $data) {
+ parent::__construct($field, $data);
+ }
+
+ protected function getObjectName(): string {
+ return 'sla';
+ }
+
+ protected function getPopupParameters(): array {
+ return [
+ 'srctbl' => 'sla',
+ 'srcfld1' => 'slaid'
+ ];
+ }
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldMultiSelectView.php b/ui/include/classes/html/widgets/CWidgetFieldMultiSelectView.php
new file mode 100755
index 00000000000..17e148e670c
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldMultiSelectView.php
@@ -0,0 +1,106 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldMultiSelect;
+
+abstract class CWidgetFieldMultiSelectView extends CWidgetFieldView {
+
+ protected const OBJECT_NAME = '';
+
+ protected ?CMultiSelect $multiselect = null;
+
+ protected array $data;
+
+ protected bool $custom_select = false;
+
+ protected array $filter_preselect = [];
+
+ public function __construct(CWidgetFieldMultiSelect $field, array $data) {
+ $this->field = $field;
+ $this->data = $data;
+ }
+
+ public function getId(): string {
+ return $this->multiselect->getId();
+ }
+
+ public function getLabel(): ?CLabel {
+ $label = parent::getLabel();
+
+ return $label !== null
+ ? $label->setFor($this->getId().'_ms')
+ : null;
+ }
+
+ public function getView(): CMultiSelect {
+ if ($this->multiselect === null) {
+ $multiselect_name = $this->field->getName().($this->field->isMultiple() ? '[]' : '');
+
+ $options = [
+ 'name' => $multiselect_name,
+ 'object_name' => $this->getObjectName(),
+ 'multiple' => $this->field->isMultiple(),
+ 'data' => $this->data,
+ 'add_post_js' => false
+ ];
+
+ if ($this->custom_select) {
+ $options['custom_select'] = true;
+ }
+ else {
+ $options['popup'] = [
+ 'parameters' => [
+ 'dstfrm' => $this->form_name,
+ 'dstfld1' => zbx_formatDomId($multiselect_name)
+ ] + $this->getPopupParameters() + $this->field->getFilterParameters()
+ ];
+
+ if ($this->filter_preselect) {
+ $options['popup']['filter_preselect'] = $this->filter_preselect;
+ }
+ }
+
+ $this->multiselect = (new CMultiSelect($options))
+ ->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
+ ->setAriaRequired($this->isRequired());
+ }
+
+ return $this->multiselect;
+ }
+
+ public function getJavaScript(): string {
+ return $this->getView()->getPostJS();
+ }
+
+ public function setFilterPreselect(array $filter_preselect): self {
+ $this->filter_preselect = $filter_preselect;
+
+ return $this;
+ }
+
+ protected function getObjectName(): string {
+ return '';
+ }
+
+ protected function getPopupParameters(): array {
+ return [];
+ }
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldNumericBoxView.php b/ui/include/classes/html/widgets/CWidgetFieldNumericBoxView.php
new file mode 100755
index 00000000000..4f2957c0b42
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldNumericBoxView.php
@@ -0,0 +1,58 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldNumericBox;
+
+class CWidgetFieldNumericBoxView extends CWidgetFieldView {
+
+ private string $placeholder = '';
+
+ private int $width = ZBX_TEXTAREA_NUMERIC_BIG_WIDTH;
+
+ public function __construct(CWidgetFieldNumericBox $field) {
+ $this->field = $field;
+ }
+
+ public function setPlaceholder(string $placeholder): self {
+ $this->placeholder = $placeholder;
+
+ return $this;
+ }
+
+ public function setWidth(int $width): self {
+ $this->width = $width;
+
+ return $this;
+ }
+
+ public function getView(): CTextBox {
+ $textbox = (new CTextBox($this->field->getName(), $this->field->getValue()))
+ ->setWidth($this->width)
+ ->setAriaRequired($this->isRequired())
+ ->setEnabled(!$this->isDisabled());
+
+ if ($this->placeholder !== '') {
+ $textbox = $textbox->setAttribute('placeholder', $this->placeholder);
+ }
+
+ return $textbox;
+ }
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldRadioButtonListView.php b/ui/include/classes/html/widgets/CWidgetFieldRadioButtonListView.php
new file mode 100755
index 00000000000..158026e7bc7
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldRadioButtonListView.php
@@ -0,0 +1,43 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldRadioButtonList;
+
+class CWidgetFieldRadioButtonListView extends CWidgetFieldView {
+
+ public function __construct(CWidgetFieldRadioButtonList $field) {
+ $this->field = $field;
+ }
+
+ public function getView(): CRadioButtonList {
+ $radio_button_list = (new CRadioButtonList($this->field->getName(), $this->field->getValue()))
+ ->setModern()
+ ->setAriaRequired($this->isRequired());
+
+ foreach ($this->field->getValues() as $key => $value) {
+ $radio_button_list
+ ->addValue($value, $key, null, $this->field->getAction())
+ ->setEnabled(!$this->isDisabled());
+ }
+
+ return $radio_button_list;
+ }
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldRangeControlView.php b/ui/include/classes/html/widgets/CWidgetFieldRangeControlView.php
new file mode 100755
index 00000000000..f736024fc7b
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldRangeControlView.php
@@ -0,0 +1,52 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldRangeControl;
+
+class CWidgetFieldRangeControlView extends CWidgetFieldView {
+
+ protected ?CRangeControl $range_control = null;
+
+ public function __construct(CWidgetFieldRangeControl $field) {
+ $this->field = $field;
+ }
+
+ public function getView(): CRangeControl {
+ return $this->getRangeControl();
+ }
+
+ public function getJavaScript(): string {
+ return $this->getRangeControl()->getPostJS();
+ }
+
+ private function getRangeControl(): CRangeControl {
+ if ($this->range_control === null) {
+ $this->range_control = (new CRangeControl($this->field->getName(), (int) $this->field->getValue()))
+ ->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
+ ->setStep($this->field->getStep())
+ ->setMin($this->field->getMin())
+ ->setMax($this->field->getMax())
+ ->setEnabled(!$this->isDisabled());
+ }
+
+ return $this->range_control;
+ }
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldSelectResourceView.php b/ui/include/classes/html/widgets/CWidgetFieldSelectResourceView.php
new file mode 100755
index 00000000000..df6b80cf05f
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldSelectResourceView.php
@@ -0,0 +1,54 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldSelectResource;
+
+class CWidgetFieldSelectResourceView extends CWidgetFieldView {
+
+ private array $data;
+
+ public function __construct(CWidgetFieldSelectResource $field, array $data) {
+ $this->field = $field;
+ $this->data = $data;
+ }
+
+ public function getView(): array {
+ $caption = $this->field->getValue() != 0
+ ? $this->data[$this->field->getResourceType()][$this->field->getValue()]
+ : '';
+
+ return [
+ (new CTextBox($this->field->getName().'_caption', $caption, true))
+ ->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
+ ->setAriaRequired($this->isRequired()),
+ (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
+ (new CButton('select', _('Select')))
+ ->addClass(ZBX_STYLE_BTN_GREY)
+ ->onClick('return PopUp("popup.generic",
+ '.json_encode($this->field->getPopupOptions($this->form_name)).',
+ {dialogue_class: "modal-popup-generic"}
+ );'),
+ new CVar($this->field->getName(), $this->field->getValue())
+ ];
+ }
+
+
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldSelectView.php b/ui/include/classes/html/widgets/CWidgetFieldSelectView.php
new file mode 100755
index 00000000000..94475f64ced
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldSelectView.php
@@ -0,0 +1,55 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldSelect;
+
+class CWidgetFieldSelectView extends CWidgetFieldView {
+
+ protected ?CSelect $select = null;
+
+ public function __construct(CWidgetFieldSelect $field) {
+ $this->field = $field;
+ }
+
+ public function getLabel(): ?CLabel {
+ $label = parent::getLabel();
+
+ if ($label !== null) {
+ $label->setFor($this->getView()->getFocusableElementId());
+ }
+
+ return $label;
+ }
+
+ public function getView(): CSelect {
+ if ($this->select === null) {
+ $this->select = (new CSelect($this->field->getName()))
+ ->setId($this->field->getName())
+ ->setFocusableElementId('label-'.$this->field->getName())
+ ->setValue($this->field->getValue())
+ ->addOptions(CSelect::createOptionsFromArray($this->field->getValues()))
+ ->setDisabled($this->isDisabled())
+ ->setAriaRequired($this->isRequired());
+ }
+
+ return $this->select;
+ }
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldSeveritiesView.php b/ui/include/classes/html/widgets/CWidgetFieldSeveritiesView.php
new file mode 100755
index 00000000000..3831e8db139
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldSeveritiesView.php
@@ -0,0 +1,36 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldSeverities;
+
+class CWidgetFieldSeveritiesView extends CWidgetFieldView {
+
+ public function __construct(CWidgetFieldSeverities $field) {
+ $this->field = $field;
+ }
+
+ public function getView(): CSeverityCheckBoxList {
+ return (new CSeverityCheckBoxList($this->field->getName()))
+ ->setChecked($this->field->getValue())
+ ->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
+ ->setEnabled(!$this->isDisabled());
+ }
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldTagsView.php b/ui/include/classes/html/widgets/CWidgetFieldTagsView.php
new file mode 100755
index 00000000000..a7d08e29fdb
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldTagsView.php
@@ -0,0 +1,118 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldTags;
+
+class CWidgetFieldTagsView extends CWidgetFieldView {
+
+ public function __construct(CWidgetFieldTags $field) {
+ $this->field = $field;
+ }
+
+ public function getView(): CTable {
+ $tags = $this->field->getValue();
+
+ if (!$tags) {
+ $tags = [CWidgetFieldTags::DEFAULT_TAG];
+ }
+
+ $tags_table = (new CTable())
+ ->setId('tags_table_'.$this->field->getName())
+ ->addClass('table-tags')
+ ->addClass('table-initial-width');
+
+ $i = 0;
+
+ foreach ($tags as $tag) {
+ $tags_table->addItem($this->getRowTemplate($tag, $i));
+
+ $i++;
+ }
+
+ $tags_table->addRow(
+ (new CCol(
+ (new CButton('tags_add', _('Add')))
+ ->addClass(ZBX_STYLE_BTN_LINK)
+ ->addClass('element-table-add')
+ ->setEnabled(!$this->isDisabled())
+ ))->setColSpan(3)
+ );
+
+ return $tags_table;
+ }
+
+ public function getJavaScript(): string {
+ return '
+ jQuery("#tags_table_'.$this->field->getName().'")
+ .dynamicRows({template: "#'.$this->field->getName().'-row-tmpl"})
+ .on("afteradd.dynamicRows", function() {
+ const rows = this.querySelectorAll(".form_row");
+ new CTagFilterItem(rows[rows.length - 1]);
+ });
+
+ // Init existing fields once loaded.
+ document.querySelectorAll("#tags_table_'.$this->field->getName().' .form_row").forEach(row => {
+ new CTagFilterItem(row);
+ });
+ ';
+ }
+
+ public function getTemplates(): array {
+ return [
+ new CTemplateTag($this->field->getName().'-row-tmpl', $this->getRowTemplate(CWidgetFieldTags::DEFAULT_TAG))
+ ];
+ }
+
+ private function getRowTemplate(array $tag, $row_num = '#{rowNum}'): CRow {
+ return (new CRow([
+ (new CTextBox($this->field->getName().'['.$row_num.'][tag]', $tag['tag']))
+ ->setWidth(ZBX_TEXTAREA_FILTER_SMALL_WIDTH)
+ ->setAriaRequired($this->isRequired())
+ ->setEnabled(!$this->isDisabled() || $row_num === '#{rowNum}')
+ ->setAttribute('placeholder', _('tag')),
+ (new CSelect($this->field->getName().'['.$row_num.'][operator]'))
+ ->addOptions(CSelect::createOptionsFromArray([
+ TAG_OPERATOR_EXISTS => _('Exists'),
+ TAG_OPERATOR_EQUAL => _('Equals'),
+ TAG_OPERATOR_LIKE => _('Contains'),
+ TAG_OPERATOR_NOT_EXISTS => _('Does not exist'),
+ TAG_OPERATOR_NOT_EQUAL => _('Does not equal'),
+ TAG_OPERATOR_NOT_LIKE => _('Does not contain')
+ ]))
+ ->setValue($tag['operator'])
+ ->setFocusableElementId($this->field->getName().'-'.$row_num.'-operator-select')
+ ->setId($this->field->getName().'_'.$row_num.'_operator')
+ ->setDisabled($this->isDisabled() && $row_num !== '#{rowNum}'),
+ (new CTextBox($this->field->getName().'['.$row_num.'][value]', $tag['value']))
+ ->setWidth(ZBX_TEXTAREA_FILTER_SMALL_WIDTH)
+ ->setAriaRequired($this->isRequired())
+ ->setId($this->field->getName().'_'.$row_num.'_value')
+ ->setEnabled(!$this->isDisabled() || $row_num === '#{rowNum}')
+ ->setAttribute('placeholder', _('value')),
+ (new CCol(
+ (new CButton($this->field->getName().'['.$row_num.'][remove]', _('Remove')))
+ ->addClass(ZBX_STYLE_BTN_LINK)
+ ->addClass('element-table-remove')
+ ->setEnabled(!$this->isDisabled() || $row_num === '#{rowNum}')
+ ))->addClass(ZBX_STYLE_NOWRAP)
+ ]))->addClass('form_row');
+ }
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldTextAreaView.php b/ui/include/classes/html/widgets/CWidgetFieldTextAreaView.php
new file mode 100755
index 00000000000..1c7a6bfb7a6
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldTextAreaView.php
@@ -0,0 +1,59 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldTextArea;
+
+class CWidgetFieldTextAreaView extends CWidgetFieldView {
+
+ private int $width = ZBX_TEXTAREA_STANDARD_WIDTH;
+ private ?int $adaptive_width = null;
+
+ public function __construct(CWidgetFieldTextArea $field) {
+ $this->field = $field;
+ }
+
+ public function setWidth(int $width): self {
+ $this->width = $width;
+
+ return $this;
+ }
+
+ public function setAdaptiveWidth(int $adaptive_width): self {
+ $this->adaptive_width = $adaptive_width;
+
+ return $this;
+ }
+
+ public function getView(): CTextArea {
+ $textarea = (new CTextArea($this->field->getName(), $this->field->getValue()))
+ ->setEnabled(!$this->isDisabled())
+ ->setAriaRequired($this->isRequired());
+
+ if ($this->adaptive_width !== null) {
+ $textarea->setAdaptiveWidth($this->adaptive_width);
+ }
+ else {
+ $textarea->setWidth($this->width);
+ }
+
+ return $textarea;
+ }
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldTextBoxView.php b/ui/include/classes/html/widgets/CWidgetFieldTextBoxView.php
new file mode 100755
index 00000000000..8a8a666d9b8
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldTextBoxView.php
@@ -0,0 +1,71 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldTextBox;
+
+class CWidgetFieldTextBoxView extends CWidgetFieldView {
+
+ private string $placeholder = '';
+
+ private int $width = ZBX_TEXTAREA_STANDARD_WIDTH;
+ private ?int $adaptive_width = null;
+
+ public function __construct(CWidgetFieldTextBox $field) {
+ $this->field = $field;
+ }
+
+ public function setPlaceholder(string $placeholder): self {
+ $this->placeholder = $placeholder;
+
+ return $this;
+ }
+
+ public function setWidth(int $width): self {
+ $this->width = $width;
+
+ return $this;
+ }
+
+ public function setAdaptiveWidth(int $adaptive_width): self {
+ $this->adaptive_width = $adaptive_width;
+
+ return $this;
+ }
+
+ public function getView(): CTextBox {
+ $textbox = (new CTextBox($this->field->getName(), $this->field->getValue()))
+ ->setEnabled(!$this->isDisabled())
+ ->setAriaRequired($this->isRequired());
+
+ if ($this->placeholder !== '') {
+ $textbox = $textbox->setAttribute('placeholder', $this->placeholder);
+ }
+
+ if ($this->adaptive_width !== null) {
+ $textbox->setAdaptiveWidth($this->adaptive_width);
+ }
+ else {
+ $textbox->setWidth($this->width);
+ }
+
+ return $textbox;
+ }
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldThresholdsView.php b/ui/include/classes/html/widgets/CWidgetFieldThresholdsView.php
new file mode 100755
index 00000000000..331efe4e145
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldThresholdsView.php
@@ -0,0 +1,100 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldThresholds;
+
+class CWidgetFieldThresholdsView extends CWidgetFieldView {
+
+ public function __construct(CWidgetFieldThresholds $field) {
+ $this->field = $field;
+ }
+
+ public function getView(): CDiv {
+ $thresholds_table = (new CTable())
+ ->setId($this->field->getName().'-table')
+ ->addClass(ZBX_STYLE_TABLE_FORMS)
+ ->setHeader([
+ '',
+ (new CColHeader(_('Threshold')))->setWidth('100%'),
+ _('Action')
+ ])
+ ->setFooter(new CRow(
+ new CCol(
+ (new CSimpleButton(_('Add')))
+ ->addClass(ZBX_STYLE_BTN_LINK)
+ ->addClass('element-table-add')
+ )
+ ));
+
+ foreach ($this->field->getValue() as $i => $threshold) {
+ $thresholds_table->addRow(
+ $this->getRowTemplate($i, $threshold['color'], $threshold['threshold'])
+ );
+ }
+
+ return (new CDiv($thresholds_table))
+ ->addClass('table-forms-separator')
+ ->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH);
+ }
+
+ public function getJavaScript(): string {
+ return '
+ var $thresholds_table = jQuery("#'.$this->field->getName().'-table");
+
+ $thresholds_table
+ .dynamicRows({template: "#'.$this->field->getName().'-row-tmpl"})
+ .on("afteradd.dynamicRows", function(opt) {
+ const rows = this.querySelectorAll(".form_row");
+ const colors = jQuery("#widget-dialogue-form")[0]
+ .querySelectorAll(".'.ZBX_STYLE_COLOR_PICKER.' input");
+ const used_colors = [];
+ for (const color of colors) {
+ if (color.value !== "" && color.name.includes("thresholds")) {
+ used_colors.push(color.value);
+ }
+ }
+ jQuery(".color-picker input", rows[rows.length - 1])
+ .val(colorPalette.getNextColor(used_colors))
+ .colorpicker({
+ appendTo: ".overlay-dialogue-body"
+ });
+ });
+ ';
+ }
+
+ public function getTemplates(): array {
+ return [
+ new CTemplateTag($this->field->getName().'-row-tmpl', $this->getRowTemplate())
+ ];
+ }
+
+ public function getRowTemplate($row_num = '#{rowNum}', $color = '#{color}', $threshold = '#{threshold}'): CRow {
+ return (new CRow([
+ (new CColor($this->field->getName().'['.$row_num.'][color]', $color))->appendColorPickerJs(false),
+ (new CTextBox($this->field->getName().'['.$row_num.'][threshold]', $threshold, false))
+ ->setWidth(ZBX_TEXTAREA_TINY_WIDTH)
+ ->setAriaRequired(),
+ (new CButton($this->field->getName().'['.$row_num.'][remove]', _('Remove')))
+ ->addClass(ZBX_STYLE_BTN_LINK)
+ ->addClass('element-table-remove')
+ ]))->addClass('form_row');
+ }
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldTimeZoneView.php b/ui/include/classes/html/widgets/CWidgetFieldTimeZoneView.php
new file mode 100755
index 00000000000..d7fc2fb65bc
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldTimeZoneView.php
@@ -0,0 +1,47 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldTimeZone;
+
+class CWidgetFieldTimeZoneView extends CWidgetFieldSelectView {
+
+ public function __construct(CWidgetFieldTimeZone $field) {
+ parent::__construct($field);
+ }
+
+ public function getJavaScript(): string {
+ return '
+ var timezone_select = document.getElementById("'.$this->field->getName().'");
+ var timezone_from_list = timezone_select.getOptionByValue(Intl.DateTimeFormat().resolvedOptions().timeZone);
+ var local_list_item = timezone_select.getOptionByValue("'.TIMEZONE_DEFAULT_LOCAL.'");
+
+ if (timezone_from_list && local_list_item) {
+ const title = `${local_list_item.label}: ${timezone_from_list.label}`;
+ local_list_item.label = title;
+ local_list_item._node.innerText = title;
+
+ if (timezone_select.selectedIndex === local_list_item._index) {
+ timezone_select._preselect(timezone_select.selectedIndex);
+ }
+ }
+ ';
+ }
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldUrlView.php b/ui/include/classes/html/widgets/CWidgetFieldUrlView.php
new file mode 100755
index 00000000000..3b4158bef5a
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldUrlView.php
@@ -0,0 +1,35 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldUrl;
+
+class CWidgetFieldUrlView extends CWidgetFieldView {
+
+ public function __construct(CWidgetFieldUrl $field) {
+ $this->field = $field;
+ }
+
+ public function getView(): CTextBox {
+ return (new CTextBox($this->field->getName(), $this->field->getValue()))
+ ->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
+ ->setAriaRequired($this->isRequired());
+ }
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldView.php b/ui/include/classes/html/widgets/CWidgetFieldView.php
new file mode 100755
index 00000000000..7d3e3b01cb6
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldView.php
@@ -0,0 +1,91 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\CWidgetField;
+
+abstract class CWidgetFieldView {
+
+ protected CWidgetField $field;
+
+ protected string $form_name = '';
+
+ protected ?CTag $hint = null;
+ protected $help_hint;
+
+ public function setFormName($form_name): self {
+ $this->form_name = $form_name;
+
+ return $this;
+ }
+
+ public function setHint(CTag $hint): self {
+ $this->hint = $hint;
+
+ return $this;
+ }
+
+ public function setHelpHint($help_hint): self {
+ $this->help_hint = $help_hint;
+
+ return $this;
+ }
+
+ public function getLabel(): ?CLabel {
+ $label = $this->field->getLabel();
+
+ if ($label === null) {
+ return null;
+ }
+
+ return new CLabel([
+ $label,
+ $this->hint,
+ $this->help_hint !== null ? makeHelpIcon($this->help_hint) : null
+ ], zbx_formatDomId($this->field->getName()));
+ }
+
+ /**
+ * @return null|array|CTag
+ */
+ public function getView() {
+ return null;
+ }
+
+ public function getJavaScript(): string {
+ return '';
+ }
+
+ public function getTemplates(): array {
+ return [];
+ }
+
+ public function isNotEmpty(): bool {
+ return ($this->field->getFlags() & CWidgetField::FLAG_NOT_EMPTY) !== 0;
+ }
+
+ public function isRequired(): bool {
+ return ($this->field->getFlags() & CWidgetField::FLAG_LABEL_ASTERISK) !== 0;
+ }
+
+ public function isDisabled(): bool {
+ return ($this->field->getFlags() & CWidgetField::FLAG_DISABLED) !== 0;
+ }
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFieldWidgetSelectView.php b/ui/include/classes/html/widgets/CWidgetFieldWidgetSelectView.php
new file mode 100755
index 00000000000..0a643d27810
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFieldWidgetSelectView.php
@@ -0,0 +1,72 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\Fields\CWidgetFieldWidgetSelect;
+
+class CWidgetFieldWidgetSelectView extends CWidgetFieldView {
+
+ protected ?CSelect $select = null;
+
+ public function __construct(CWidgetFieldWidgetSelect $field) {
+ $this->field = $field;
+ }
+
+ public function getLabel(): ?CLabel {
+ $label = parent::getLabel();
+
+ if ($label !== null) {
+ $label->setFor($this->getView()->getFocusableElementId());
+ }
+
+ return $label;
+ }
+
+ public function getView(): CSelect {
+ if ($this->select === null) {
+ $this->select = (new CSelect($this->field->getName()))
+ ->setId($this->field->getName())
+ ->setFocusableElementId('label-'.$this->field->getName())
+ ->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
+ ->setAriaRequired($this->isRequired());
+ }
+
+ return $this->select;
+ }
+
+ public function getJavaScript(): string {
+ return '
+ var filter_select = document.getElementById("'.$this->field->getName().'");
+
+ filter_select.addOption('.json_encode(['label' => _('Select widget'), 'value' => '-1']).');
+ filter_select.selectedIndex = 0;
+
+ ZABBIX.Dashboard.getSelectedDashboardPage().getWidgets().forEach((widget) => {
+ if (widget.getType() === "'.$this->field->getSearchByValue().'") {
+ const widget_reference = widget.getFields().reference;
+ filter_select.addOption({label: widget.getHeaderName(), value: widget_reference});
+ if (widget_reference === "'.$this->field->getValue().'") {
+ filter_select.value = "'.$this->field->getValue().'";
+ }
+ }
+ });
+ ';
+ }
+}
diff --git a/ui/include/classes/html/widgets/CWidgetFormView.php b/ui/include/classes/html/widgets/CWidgetFormView.php
new file mode 100755
index 00000000000..d85d6c74f80
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetFormView.php
@@ -0,0 +1,281 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Zabbix\Widgets\CWidgetField;
+
+class CWidgetFormView {
+
+ private array $data;
+ private string $name;
+
+ private array $vars = [];
+ private array $javascript = [];
+ private array $templates = [];
+
+ private CFormGrid $form_grid;
+
+ public function __construct($data, $name = 'widget_dialogue_form') {
+ $this->data = $data;
+ $this->name = $name;
+
+ $this->makeFormGrid();
+ }
+
+ /**
+ * Add configuration row with single label and multiple CWidgetFieldView-s as content.
+ *
+ * @param array|string|null $label
+ * @param array $items
+ * @param string|null $row_class
+ *
+ * @return $this
+ */
+ public function addFieldsGroup($label, array $items, string $row_class = null): self {
+ foreach ($items as &$item) {
+ if ($item instanceof CWidgetFieldView) {
+ $item = $this->makeField($item);
+ }
+ }
+ unset($item);
+
+ $this->form_grid->addItem([
+ $label !== null
+ ? (new CLabel($label))
+ ->addClass(CFormGrid::ZBX_STYLE_FIELDS_GROUP_LABEL)
+ ->addClass($row_class)
+ : null,
+ (new CDiv($items))
+ ->addClass(CFormGrid::ZBX_STYLE_FIELDS_GROUP)
+ ->addClass($row_class)
+ ]);
+
+ return $this;
+ }
+
+ /**
+ * Add configuration row based on single CWidgetFieldView.
+ *
+ * @param CWidgetFieldView|null $field_view
+ * @param string|null $row_class
+ * @param bool $show_label
+ *
+ * @return $this
+ */
+ public function addField(?CWidgetFieldView $field_view, string $row_class = null, bool $show_label = true): self {
+ if ($field_view !== null) {
+ $this->registerFieldView($field_view);
+
+ $this->form_grid->addItem($this->makeField($field_view, $row_class, $show_label));
+ }
+
+ return $this;
+ }
+
+ /**
+ * Prepare CWidgetFieldView for addFieldGroup() items array in default view or by custom CHTML.
+ *
+ * @param CWidgetFieldView $field_view
+ * @param array $items
+ * @param string|null $row_class
+ *
+ * @return array Label and field views taken from field object or $items array if not empty.
+ */
+ public function makeCustomField(CWidgetFieldView $field_view, array $items = [], string $row_class = null): array {
+ $this->registerFieldView($field_view);
+
+ return $items ?: $this->makeField($field_view, $row_class);
+ }
+
+ public function addItem($value): self {
+ $this->form_grid->addItem($value);
+
+ return $this;
+ }
+
+ public function addVar(string $name, string $value): self {
+ $this->vars[] = (new CVar($name, $value))->removeId();
+
+ return $this;
+ }
+
+ public function addFieldVar(?CWidgetField $field): self {
+ if ($field !== null) {
+ $this->vars[] = new CVar($field->getName(), $field->getValue());
+ }
+
+ return $this;
+ }
+
+ public function addJavaScript(string $javascript): self {
+ $this->javascript[] = $javascript;
+
+ return $this;
+ }
+
+ public function includeJsFile(string $file_path): self {
+ $view = APP::View();
+
+ if ($view !== null) {
+ ob_start();
+
+ if ((include $view->getDirectory().'/'.$file_path) === false) {
+ ob_end_clean();
+
+ throw new RuntimeException(sprintf('Cannot read file: "%s".', $file_path));
+ }
+
+ $this->javascript[] = ob_get_clean();
+ }
+
+
+ return $this;
+ }
+
+ /**
+ * @throws JsonException
+ */
+ public function show(): void {
+ $output = [
+ 'header' => $this->data['unique_id'] !== null ? _('Edit widget') : _('Add widget'),
+ 'body' => implode('', [
+ (new CForm())
+ ->cleanItems()
+ ->setId('widget-dialogue-form')
+ ->setName($this->name)
+ ->addClass(ZBX_STYLE_DASHBOARD_WIDGET_FORM)
+ ->addClass('dashboard-widget-'.$this->data['type'])
+ ->addItem($this->vars)
+ ->addItem($this->form_grid)
+ // Submit button is needed to enable submit event on Enter on inputs.
+ ->addItem((new CInput('submit', 'dashboard_widget_config_submit'))->addStyle('display: none;')),
+ implode('', $this->templates),
+ $this->javascript ? new CScriptTag($this->javascript) : ''
+ ]),
+ 'buttons' => [
+ [
+ 'title' => $this->data['unique_id'] !== null ? _('Apply') : _('Add'),
+ 'class' => 'dialogue-widget-save',
+ 'keepOpen' => true,
+ 'isSubmit' => true,
+ 'action' => 'ZABBIX.Dashboard.applyWidgetProperties();'
+ ]
+ ],
+ 'doc_url' => CDocHelper::getUrl(CDocHelper::DASHBOARDS_WIDGET_EDIT),
+ 'data' => [
+ 'original_properties' => [
+ 'type' => $this->data['type'],
+ 'unique_id' => $this->data['unique_id'],
+ 'dashboard_page_unique_id' => $this->data['dashboard_page_unique_id']
+ ]
+ ]
+ ];
+
+ if ($error = get_and_clear_messages()) {
+ $output['error'] = [
+ 'messages' => array_column($error, 'message')
+ ];
+ }
+
+ if ($this->data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
+ CProfiler::getInstance()->stop();
+ $output['debug'] = CProfiler::getInstance()->make()->toString();
+ }
+
+ echo json_encode($output, JSON_THROW_ON_ERROR);
+ }
+
+ private function addTemplate(?CTemplateTag $template): void {
+ if ($template !== null) {
+ $this->templates[$template->getId()] = $template;
+ }
+ }
+
+ private function registerFieldView(CWidgetFieldView $field_view): void {
+ $field_view->setFormName($this->name);
+
+ $this->addJavaScript($field_view->getJavaScript());
+
+ foreach ($field_view->getTemplates() as $template) {
+ $this->addTemplate($template);
+ }
+ }
+
+ private function makeFormGrid(): void {
+ $types_select = (new CSelect('type'))
+ ->setFocusableElementId('label-type')
+ ->setId('type')
+ ->setValue($this->data['type'])
+ ->setAttribute('autofocus', 'autofocus')
+ ->addOptions(CSelect::createOptionsFromArray($this->data['known_types']))
+ ->addStyle('max-width: '.ZBX_TEXTAREA_MEDIUM_WIDTH.'px');
+
+ if ($this->data['deprecated_types']) {
+ $types_select->addOptionGroup(
+ (new CSelectOptionGroup(_('Deprecated')))
+ ->addOptions(CSelect::createOptionsFromArray($this->data['deprecated_types']))
+ );
+ }
+
+ $this->form_grid = (new CFormGrid())
+ ->addItem([
+ new CLabel(_('Type'), 'label-type'),
+ new CFormField(array_key_exists($this->data['type'], $this->data['deprecated_types'])
+ ? [$types_select, ' ', makeWarningIcon(_('Widget is deprecated.'))]
+ : $types_select
+ )
+ ])
+ ->addItem(
+ (new CFormField(
+ (new CCheckBox('show_header'))
+ ->setLabel(_('Show header'))
+ ->setLabelPosition(CCheckBox::LABEL_POSITION_LEFT)
+ ->setId('show_header')
+ ->setChecked($this->data['view_mode'] == ZBX_WIDGET_VIEW_MODE_NORMAL)
+ ))->addClass('form-field-show-header')
+ )
+ ->addItem([
+ new CLabel(_('Name'), 'name'),
+ new CFormField(
+ (new CTextBox('name', $this->data['name']))
+ ->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
+ ->setAttribute('placeholder', _('default'))
+ )
+ ]);
+
+ if (array_key_exists('rf_rate', $this->data['fields'])) {
+ $this->addField(new CWidgetFieldSelectView($this->data['fields']['rf_rate']));
+ }
+ }
+
+ private function makeField(CWidgetFieldView $field_view, string $row_class = null, bool $show_label = true): array {
+ $label = $show_label ? $field_view->getLabel() : null;
+
+ return [
+ $label !== null
+ ? $label
+ ->addClass($row_class)
+ ->setAsteriskMark($field_view->isRequired())
+ : null,
+ (new CFormField($field_view->getView()))
+ ->addClass($row_class)
+ ];
+ }
+}
diff --git a/ui/include/classes/html/widgets/CWidgetView.php b/ui/include/classes/html/widgets/CWidgetView.php
new file mode 100755
index 00000000000..33f09802990
--- /dev/null
+++ b/ui/include/classes/html/widgets/CWidgetView.php
@@ -0,0 +1,69 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+class CWidgetView extends CObject {
+
+ private array $data;
+
+ private array $vars = [];
+
+ public function __construct($data) {
+ parent::__construct();
+
+ $this->data = $data;
+ }
+
+ public function setVar(string $name, $value): self {
+ $this->vars[$name] = $value;
+
+ return $this;
+ }
+
+ /**
+ * @throws JsonException
+ */
+ public function show($destroy = true): void {
+ $output = [];
+
+ if (array_key_exists('name', $this->data)) {
+ $output['name'] = $this->data['name'];
+ }
+
+ if ($this->items) {
+ $output['body'] = implode('', $this->items);
+ }
+
+ foreach ($this->vars as $name => $value) {
+ $output[$name] = $value;
+ }
+
+ if ($messages = get_and_clear_messages()) {
+ $output['messages'] = array_column($messages, 'message');
+ }
+
+ if (array_key_exists('user', $this->data) && $this->data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
+ CProfiler::getInstance()->stop();
+ $output['debug'] = CProfiler::getInstance()->make()->toString();
+ }
+
+ echo json_encode($output, JSON_THROW_ON_ERROR);
+ }
+}
diff --git a/ui/include/classes/import/converters/C62ImportConverter.php b/ui/include/classes/import/converters/C62ImportConverter.php
index 1a79ace08ff..19bb2ccf11d 100644
--- a/ui/include/classes/import/converters/C62ImportConverter.php
+++ b/ui/include/classes/import/converters/C62ImportConverter.php
@@ -24,6 +24,15 @@
*/
class C62ImportConverter extends CConverter {
+ private const DASHBOARD_WIDGET_TYPE = [
+ CXmlConstantName::DASHBOARD_WIDGET_TYPE_CLOCK => CXmlConstantValue::DASHBOARD_WIDGET_TYPE_CLOCK,
+ CXmlConstantName::DASHBOARD_WIDGET_TYPE_GRAPH_CLASSIC => CXmlConstantValue::DASHBOARD_WIDGET_TYPE_GRAPH_CLASSIC,
+ CXmlConstantName::DASHBOARD_WIDGET_TYPE_GRAPH_PROTOTYPE => CXmlConstantValue::DASHBOARD_WIDGET_TYPE_GRAPH_PROTOTYPE,
+ CXmlConstantName::DASHBOARD_WIDGET_TYPE_ITEM => CXmlConstantValue::DASHBOARD_WIDGET_TYPE_ITEM,
+ CXmlConstantName::DASHBOARD_WIDGET_TYPE_PLAIN_TEXT => CXmlConstantValue::DASHBOARD_WIDGET_TYPE_PLAIN_TEXT,
+ CXmlConstantName::DASHBOARD_WIDGET_TYPE_URL => CXmlConstantValue::DASHBOARD_WIDGET_TYPE_URL
+ ];
+
/**
* Convert import data from 6.2 to 6.4 version.
*
@@ -75,6 +84,10 @@ class C62ImportConverter extends CConverter {
if (array_key_exists('discovery_rules', $template)) {
$template['discovery_rules'] = self::convertDiscoveryRules($template['discovery_rules']);
}
+
+ if (array_key_exists('dashboards', $template)) {
+ $template['dashboards'] = self::convertDashboards($template['dashboards']);
+ }
}
unset($template);
@@ -116,4 +129,34 @@ class C62ImportConverter extends CConverter {
return $item_prototypes;
}
+
+ /**
+ * Convert dashboards.
+ *
+ * @param array $dashboards
+ *
+ * @return array
+ */
+ private static function convertDashboards(array $dashboards): array {
+ foreach ($dashboards as &$dashboard) {
+ if (!array_key_exists('pages', $dashboard)) {
+ continue;
+ }
+
+ foreach ($dashboard['pages'] as &$dashboard_page) {
+ if (!array_key_exists('widgets', $dashboard_page)) {
+ continue;
+ }
+
+ foreach ($dashboard_page['widgets'] as &$widget) {
+ $widget['type'] = self::DASHBOARD_WIDGET_TYPE[$widget['type']];
+ }
+ unset($widget);
+ }
+ unset($dashboard_page);
+ }
+ unset($dashboard);
+
+ return $dashboards;
+ }
}
diff --git a/ui/include/classes/import/converters/CImportConverterFactory.php b/ui/include/classes/import/converters/CImportConverterFactory.php
index 97e693ff11c..a4a88562064 100644
--- a/ui/include/classes/import/converters/CImportConverterFactory.php
+++ b/ui/include/classes/import/converters/CImportConverterFactory.php
@@ -22,23 +22,29 @@
/**
* Factory for creating import conversions.
*/
-class CImportConverterFactory extends CRegistryFactory {
+final class CImportConverterFactory extends CRegistryFactory {
+
+ private const SEQUENTIAL_CONVERTERS = [
+ '1.0' => 'C10ImportConverter',
+ '2.0' => 'C20ImportConverter',
+ '3.0' => 'C30ImportConverter',
+ '3.2' => 'C32ImportConverter',
+ '3.4' => 'C34ImportConverter',
+ '4.0' => 'C40ImportConverter',
+ '4.2' => 'C42ImportConverter',
+ '4.4' => 'C44ImportConverter',
+ '5.0' => 'C50ImportConverter',
+ '5.2' => 'C52ImportConverter',
+ '5.4' => 'C54ImportConverter',
+ '6.0' => 'C60ImportConverter',
+ '6.2' => 'C62ImportConverter'
+ ];
public function __construct() {
- parent::__construct([
- '1.0' => 'C10ImportConverter',
- '2.0' => 'C20ImportConverter',
- '3.0' => 'C30ImportConverter',
- '3.2' => 'C32ImportConverter',
- '3.4' => 'C34ImportConverter',
- '4.0' => 'C40ImportConverter',
- '4.2' => 'C42ImportConverter',
- '4.4' => 'C44ImportConverter',
- '5.0' => 'C50ImportConverter',
- '5.2' => 'C52ImportConverter',
- '5.4' => 'C54ImportConverter',
- '6.0' => 'C60ImportConverter',
- '6.2' => 'C62ImportConverter'
- ]);
+ parent::__construct(self::SEQUENTIAL_CONVERTERS);
+ }
+
+ public static function getSequentialVersions() {
+ return array_keys(self::SEQUENTIAL_CONVERTERS);
}
}
diff --git a/ui/include/classes/import/validators/C64XmlValidator.php b/ui/include/classes/import/validators/C64XmlValidator.php
index 4b385810d3e..625fe8cb1e1 100644
--- a/ui/include/classes/import/validators/C64XmlValidator.php
+++ b/ui/include/classes/import/validators/C64XmlValidator.php
@@ -374,15 +374,6 @@ class C64XmlValidator extends CXmlValidatorGeneral {
CXmlConstantValue::CUSTOM_INTERFACES_YES => CXmlConstantName::YES
];
- private $DASHBOARD_WIDGET_TYPE = [
- CXmlConstantValue::DASHBOARD_WIDGET_TYPE_CLOCK => CXmlConstantName::DASHBOARD_WIDGET_TYPE_CLOCK,
- CXmlConstantValue::DASHBOARD_WIDGET_TYPE_GRAPH_CLASSIC => CXmlConstantName::DASHBOARD_WIDGET_TYPE_GRAPH_CLASSIC,
- CXmlConstantValue::DASHBOARD_WIDGET_TYPE_GRAPH_PROTOTYPE => CXmlConstantName::DASHBOARD_WIDGET_TYPE_GRAPH_PROTOTYPE,
- CXmlConstantValue::DASHBOARD_WIDGET_TYPE_ITEM => CXmlConstantName::DASHBOARD_WIDGET_TYPE_ITEM,
- CXmlConstantValue::DASHBOARD_WIDGET_TYPE_PLAIN_TEXT => CXmlConstantName::DASHBOARD_WIDGET_TYPE_PLAIN_TEXT,
- CXmlConstantValue::DASHBOARD_WIDGET_TYPE_URL => CXmlConstantName::DASHBOARD_WIDGET_TYPE_URL
- ];
-
private $DASHBOARD_WIDGET_FIELD_TYPE = [
CXmlConstantValue::DASHBOARD_WIDGET_FIELD_TYPE_INTEGER => CXmlConstantName::DASHBOARD_WIDGET_FIELD_TYPE_INTEGER,
CXmlConstantValue::DASHBOARD_WIDGET_FIELD_TYPE_STRING => CXmlConstantName::DASHBOARD_WIDGET_FIELD_TYPE_STRING,
@@ -1745,7 +1736,7 @@ class C64XmlValidator extends CXmlValidatorGeneral {
'display_period' => ['type' => XML_STRING, 'default' => '0'],
'widgets' => ['type' => XML_INDEXED_ARRAY, 'prefix' => 'widget', 'rules' => [
'widget' => ['type' => XML_ARRAY, 'rules' => [
- 'type' => ['type' => XML_STRING | XML_REQUIRED, 'in' => $this->DASHBOARD_WIDGET_TYPE],
+ 'type' => ['type' => XML_STRING | XML_REQUIRED],
'name' => ['type' => XML_STRING, 'default' => ''],
'x' => ['type' => XML_STRING, 'default' => '0'],
'y' => ['type' => XML_STRING, 'default' => '0'],
diff --git a/ui/include/classes/mvc/CControllerResponse.php b/ui/include/classes/mvc/CControllerResponse.php
index ddb418c6327..90559fed541 100644
--- a/ui/include/classes/mvc/CControllerResponse.php
+++ b/ui/include/classes/mvc/CControllerResponse.php
@@ -39,7 +39,7 @@ abstract class CControllerResponse {
CMessageHelper::restoreScheduleMessages();
}
- (new CPageHeader(_('Loading...'), CWebUser::getLang()))->display();
+ (new CHtmlPageHeader(_('Loading...'), CWebUser::getLang()))->show();
echo '<body>';
diff --git a/ui/include/classes/mvc/CRouter.php b/ui/include/classes/mvc/CRouter.php
index 4f444971dbe..c9a5f96d0bb 100644
--- a/ui/include/classes/mvc/CRouter.php
+++ b/ui/include/classes/mvc/CRouter.php
@@ -22,38 +22,28 @@
class CRouter {
/**
* Layout used for view rendering.
- *
- * @var string
*/
- private $layout = null;
+ private ?string $layout = null;
/**
* Controller class for action handling.
- *
- * @var string
*/
- private $controller = null;
+ private ?string $controller = null;
/**
* View used to generate HTML, CSV, JSON and other content.
- *
- * @var string
*/
- private $view = null;
+ private ?string $view = null;
/**
* Unique action (request) identifier.
- *
- * @var string
*/
- private $action = null;
+ private ?string $action = null;
/**
* Mapping between action and corresponding controller, layout and view.
- *
- * @var array
*/
- private $routes = [
+ private array $routes = [
// action controller layout view
'action.operation.get' => ['CControllerActionOperationGet', 'layout.json', null],
'action.operation.validate' => ['CControllerActionOperationValidate', 'layout.json', null],
@@ -74,6 +64,7 @@ class CRouter {
'correlation.enable' => ['CControllerCorrelationEnable', null, null],
'correlation.list' => ['CControllerCorrelationList', 'layout.htmlpage', 'configuration.correlation.list'],
'correlation.update' => ['CControllerCorrelationUpdate', null, null],
+ 'dashboard.configuration.hash.get' => ['CControllerDashboardConfigurationHashGet', 'layout.json', null],
'dashboard.delete' => ['CControllerDashboardDelete', null, null],
'dashboard.list' => ['CControllerDashboardList', 'layout.htmlpage', 'monitoring.dashboard.list'],
'dashboard.page.properties.check' => ['CControllerDashboardPagePropertiesCheck', 'layout.json', null],
@@ -85,8 +76,6 @@ class CRouter {
'dashboard.update' => ['CControllerDashboardUpdate', 'layout.json', null],
'dashboard.view' => ['CControllerDashboardView', 'layout.htmlpage', 'monitoring.dashboard.view'],
'dashboard.widget.check' => ['CControllerDashboardWidgetCheck', 'layout.json', null],
- 'dashboard.widget.configure' => ['CControllerDashboardWidgetConfigure', 'layout.json', null],
- 'dashboard.widget.edit' => ['CControllerDashboardWidgetEdit', 'layout.json', 'monitoring.dashboard.widget.edit'],
'dashboard.widget.rfrate' => ['CControllerDashboardWidgetRfRate', 'layout.json', null],
'dashboard.widgets.sanitize' => ['CControllerDashboardWidgetsSanitize', 'layout.json', null],
'discovery.create' => ['CControllerDiscoveryCreate', null, null],
@@ -102,8 +91,8 @@ class CRouter {
'export.sysmaps' => ['CControllerExport', 'layout.export', null],
'export.templates' => ['CControllerExport', 'layout.export', null],
'export.valuemaps' => ['CControllerExport', 'layout.export', null],
- 'favourite.create' => ['CControllerFavouriteCreate', 'layout.javascript', null],
- 'favourite.delete' => ['CControllerFavouriteDelete', 'layout.javascript', null],
+ 'favorite.create' => ['CControllerFavoriteCreate', 'layout.javascript', null],
+ 'favorite.delete' => ['CControllerFavoriteDelete', 'layout.javascript', null],
'geomaps.edit' => ['CControllerGeomapsEdit', 'layout.htmlpage', 'administration.geomaps.edit'],
'geomaps.update' => ['CControllerGeomapsUpdate', null, null],
'gui.edit' => ['CControllerGuiEdit', 'layout.htmlpage', 'administration.gui.edit'],
@@ -217,7 +206,6 @@ class CRouter {
'popup.testtriggerexpr' => ['CControllerPopupTestTriggerExpr', 'layout.json', 'popup.testtriggerexpr'],
'popup.token.edit' => ['CControllerPopupTokenEdit', 'layout.json', 'popup.token.edit'],
'popup.token.view' => ['CControllerPopupTokenView', 'layout.json', 'popup.token.view'],
- 'popup.tophosts.column.edit' => ['CControllerPopupTopHostsColumnEdit', 'layout.json', 'popup.tophosts.column.edit'],
'popup.triggerexpr' => ['CControllerPopupTriggerExpr', 'layout.json', 'popup.triggerexpr'],
'popup.valuemap.edit' => ['CControllerPopupValueMapEdit', 'layout.json', 'popup.valuemap.edit'],
'popup.valuemap.update' => ['CControllerPopupValueMapUpdate', 'layout.json', null],
@@ -315,32 +303,6 @@ class CRouter {
'userrole.list' => ['CControllerUserroleList', 'layout.htmlpage', 'administration.userrole.list'],
'userrole.update' => ['CControllerUserroleUpdate', null, null],
'web.view' => ['CControllerWebView', 'layout.htmlpage', 'monitoring.web.view'],
- 'widget.actionlog.view' => ['CControllerWidgetActionLogView', 'layout.widget', 'monitoring.widget.actionlog.view'],
- 'widget.clock.view' => ['CControllerWidgetClockView', 'layout.widget', 'monitoring.widget.clock.view'],
- 'widget.dataover.view' => ['CControllerWidgetDataOverView', 'layout.widget', 'monitoring.widget.dataover.view'],
- 'widget.discovery.view' => ['CControllerWidgetDiscoveryView', 'layout.widget', 'monitoring.widget.discovery.view'],
- 'widget.favgraphs.view' => ['CControllerWidgetFavGraphsView', 'layout.widget', 'monitoring.widget.favgraphs.view'],
- 'widget.favmaps.view' => ['CControllerWidgetFavMapsView', 'layout.widget', 'monitoring.widget.favmaps.view'],
- 'widget.geomap.view' => ['CControllerWidgetGeoMapView', 'layout.widget', 'monitoring.widget.geomap.view'],
- 'widget.graph.view' => ['CControllerWidgetGraphView', 'layout.widget', 'monitoring.widget.graph.view'],
- 'widget.graphprototype.view' => ['CControllerWidgetIteratorGraphPrototypeView', 'layout.json', null],
- 'widget.hostavail.view' => ['CControllerWidgetHostAvailView', 'layout.widget', 'monitoring.widget.hostavail.view'],
- 'widget.item.view' => ['CControllerWidgetItemView', 'layout.widget', 'monitoring.widget.item.view'],
- 'widget.map.view' => ['CControllerWidgetMapView', 'layout.widget', 'monitoring.widget.map.view'],
- 'widget.navtree.item.edit' => ['CControllerWidgetNavTreeItemEdit', 'layout.json', 'monitoring.widget.navtreeitem.edit'],
- 'widget.navtree.item.update' => ['CControllerWidgetNavTreeItemUpdate', 'layout.json', null],
- 'widget.navtree.view' => ['CControllerWidgetNavTreeView', 'layout.widget', 'monitoring.widget.navtree.view'],
- 'widget.plaintext.view' => ['CControllerWidgetPlainTextView', 'layout.widget', 'monitoring.widget.plaintext.view'],
- 'widget.problemhosts.view' => ['CControllerWidgetProblemHostsView', 'layout.widget', 'monitoring.widget.problemhosts.view'],
- 'widget.problems.view' => ['CControllerWidgetProblemsView', 'layout.widget', 'monitoring.widget.problems.view'],
- 'widget.problemsbysv.view' => ['CControllerWidgetProblemsBySvView', 'layout.widget', 'monitoring.widget.problemsbysv.view'],
- 'widget.slareport.view' => ['CControllerWidgetSlaReportView', 'layout.widget', 'monitoring.widget.slareport.view'],
- 'widget.svggraph.view' => ['CControllerWidgetSvgGraphView', 'layout.widget', 'monitoring.widget.svggraph.view'],
- 'widget.systeminfo.view' => ['CControllerWidgetSystemInfoView', 'layout.widget', 'monitoring.widget.systeminfo.view'],
- 'widget.tophosts.view' => ['CControllerWidgetTopHostsView', 'layout.widget', 'monitoring.widget.tophosts.view'],
- 'widget.trigover.view' => ['CControllerWidgetTrigOverView', 'layout.widget', 'monitoring.widget.trigover.view'],
- 'widget.url.view' => ['CControllerWidgetUrlView', 'layout.widget', 'monitoring.widget.url.view'],
- 'widget.web.view' => ['CControllerWidgetWebView', 'layout.widget', 'monitoring.widget.web.view'],
// legacy actions
'actionconf.php' => ['CLegacyAction', null, null],
@@ -381,6 +343,13 @@ class CRouter {
'triggers.php' => ['CLegacyAction', null, null]
];
+ private const DASHBOARD_ACTIONS = [
+ 'dashboard.print',
+ 'dashboard.view',
+ 'host.dashboard.view',
+ 'template.dashboard.edit'
+ ];
+
/**
* Add new actions (potentially overwriting the existing ones).
*
@@ -420,39 +389,23 @@ class CRouter {
}
}
- /**
- * Returns layout name.
- *
- * @return string|null
- */
public function getLayout(): ?string {
return $this->layout;
}
- /**
- * Returns controller name.
- *
- * @return string|null
- */
public function getController(): ?string {
return $this->controller;
}
- /**
- * Returns view name.
- *
- * @return string|null
- */
public function getView(): ?string {
return $this->view;
}
- /**
- * Returns action name.
- *
- * @return string|null
- */
public function getAction(): ?string {
return $this->action;
}
+
+ public static function isDashboardAction(string $action): bool {
+ return in_array($action, self::DASHBOARD_ACTIONS, true);
+ }
}
diff --git a/ui/include/classes/mvc/CView.php b/ui/include/classes/mvc/CView.php
index 92f0a769c16..89dfaef5093 100644
--- a/ui/include/classes/mvc/CView.php
+++ b/ui/include/classes/mvc/CView.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -26,61 +26,45 @@ class CView {
/**
* Directory list of MVC views ordered by search priority.
- *
- * @static
- *
- * @var array
*/
- private static $directories = ['local/app/views', 'app/views', 'include/views'];
+ private static array $directories = ['local/app/views', 'app/views', 'include/views'];
/**
* Indicates support of web layout modes.
- *
- * @var boolean
*/
- private $layout_modes_enabled = false;
+ private bool $layout_modes_enabled = false;
/**
* Explicitly set layout mode.
- *
- * @var int
*/
- private $layout_mode;
+ private ?int $layout_mode = null;
/**
- * View name.
- *
- * @var string
+ * Directory where the view file was found.
*/
- private $name;
+ private ?string $directory = null;
+
+ private string $assets_path = 'assets';
/**
- * Data provided for view.
- *
- * @var array
+ * View name.
*/
- private $data;
+ private string $name;
/**
- * Directory where the view file was found.
- *
- * @var string
+ * List of JavaScript files for inclusion into HTML page using <script src="...">.
*/
- private $directory;
+ private array $js_files = [];
/**
- * List of JavaScript files for inclusion into a HTML page using <script src="...">.
- *
- * @var array
+ * List of CSS files for inclusion into HTML page using <link rel="stylesheet" type="text/css" src="...">.
*/
- private $js_files = [];
+ private array $css_files = [];
/**
- * List of CSS files for inclusion into a HTML page using <link rel="stylesheet" type="text/css" src="...">.
- *
- * @var array
+ * Data provided for view.
*/
- private $css_files = [];
+ private array $data;
/**
* Create a view based on view name and data.
@@ -91,7 +75,7 @@ class CView {
* @throws InvalidArgumentException if view name not valid.
* @throws RuntimeException if view not found or not readable.
*/
- public function __construct($name, array $data = []) {
+ public function __construct(string $name, array $data = []) {
if (!preg_match('/^[a-z]+(\/[a-z]+)*(\.[a-z]+)*$/', $name)) {
throw new InvalidArgumentException(sprintf('Invalid view name: "%s".', $name));
}
@@ -100,6 +84,7 @@ class CView {
foreach (self::$directories as $directory) {
$file_path = $directory.'/'.$name.'.php';
+
if (is_file($file_path)) {
$this->directory = $directory;
break;
@@ -118,15 +103,27 @@ class CView {
$this->data = $data;
}
+ public function getDirectory(): string {
+ return $this->directory;
+ }
+
+ public function setAssetsPath(string $asset_path): self {
+ $this->assets_path = $asset_path;
+
+ return $this;
+ }
+
+ public function getAssetsPath(): string {
+ RETURN $this->assets_path;
+ }
+
/**
* Render view and return the output.
* Note: view should only output textual content like HTML, JSON, scripts or similar.
*
* @throws RuntimeException if view not found, not readable or returned false.
- *
- * @return string
*/
- public function getOutput() {
+ public function getOutput(): string {
$data = $this->data;
$file_path = $this->directory.'/'.$this->name.'.php';
@@ -148,17 +145,15 @@ class CView {
* - JavaScript file will be searched in the "js" subdirectory of the view file.
* - A copy of $data variable will be available for using within the file.
*
- * @param string $file_name
- * @param array $data
- *
- * @throws RuntimeException if the file not found, not readable or returned false.
+ * @param string $file_name
+ * @param array|null $data
*
* @return string
*/
- public function readJsFile(string $file_name, ?array $data = null): string {
- $data = ($data === null) ? $this->data : $data;
+ public function readJsFile(string $file_name, array $data = null, $relative_dir = '/js'): string {
+ $data = $data ?? $this->data;
- $file_path = $this->directory.'/js/'.$file_name;
+ $file_path = $this->directory.$relative_dir.'/'.$file_name;
ob_start();
@@ -177,40 +172,37 @@ class CView {
* - JavaScript file will be searched in the "js" subdirectory of the view file.
* - A copy of $data variable will be available for using within the file.
*
- * @param string $file_name
- * @param array $data
- *
* @throws RuntimeException if the file not found, not readable or returned false.
*/
- public function includeJsFile(string $file_name, array $data = null) {
+ public function includeJsFile(string $file_name, array $data = null): self {
echo $this->readJsFile($file_name, $data);
+
+ return $this;
}
/**
* Add a native JavaScript file to this view.
- *
- * @param string $src
*/
- public function addJsFile($src) {
- $this->js_files[] = $src;
+ public function addJsFile(string $js): self {
+ $this->js_files[] = $js;
+
+ return $this;
}
/**
* Get list of native JavaScript files added to this view.
- *
- * @return array
*/
- public function getJsFiles() {
+ public function getJsFiles(): array {
return $this->js_files;
}
/**
* Add a CSS file to this view.
- *
- * @param string $src
*/
- public function addCssFile($src) {
- $this->css_files[] = $src;
+ public function addCssFile($css): self {
+ $this->css_files[] = $css;
+
+ return $this;
}
/**
@@ -218,15 +210,17 @@ class CView {
*
* @return array
*/
- public function getCssFiles() {
+ public function getCssFiles(): array {
return $this->css_files;
}
/**
* Enable support of web layout modes.
*/
- public function enableLayoutModes() {
+ public function enableLayoutModes(): self {
$this->layout_modes_enabled = true;
+
+ return $this;
}
/**
@@ -234,8 +228,10 @@ class CView {
*
* @param int $layout_mode ZBX_LAYOUT_NORMAL | ZBX_LAYOUT_KIOSKMODE
*/
- public function setLayoutMode(int $layout_mode): void {
+ public function setLayoutMode(int $layout_mode): self {
$this->layout_mode = $layout_mode;
+
+ return $this;
}
/**
@@ -243,9 +239,9 @@ class CView {
*
* @return int ZBX_LAYOUT_NORMAL | ZBX_LAYOUT_KIOSKMODE
*/
- public function getLayoutMode() {
+ public function getLayoutMode(): int {
if ($this->layout_modes_enabled) {
- return ($this->layout_mode !== null) ? $this->layout_mode : CViewHelper::loadLayoutMode();
+ return $this->layout_mode ?? CViewHelper::loadLayoutMode();
}
return ZBX_LAYOUT_NORMAL;
@@ -253,11 +249,9 @@ class CView {
/**
* Register custom directory of MVC views. The last registered will have the first priority.
- *
- * @param string $directory
*/
- public static function registerDirectory($directory) {
- if (!in_array($directory, self::$directories)) {
+ public static function registerDirectory(string $directory): void {
+ if (!in_array($directory, self::$directories, true)) {
array_unshift(self::$directories, $directory);
}
}
diff --git a/ui/include/classes/setup/CSetupWizard.php b/ui/include/classes/setup/CSetupWizard.php
index 97fb1b9eb19..6216713e257 100644
--- a/ui/include/classes/setup/CSetupWizard.php
+++ b/ui/include/classes/setup/CSetupWizard.php
@@ -320,7 +320,7 @@ class CSetupWizard extends CForm {
// make zabbix.conf.php downloadable
header('Content-Type: application/x-httpd-php');
header('Content-Disposition: attachment; filename="'.basename(CConfigFile::CONFIG_FILE_PATH).'"');
- $config = new CConfigFile(APP::getInstance()->getRootDir().CConfigFile::CONFIG_FILE_PATH);
+ $config = new CConfigFile(APP::getRootDir().CConfigFile::CONFIG_FILE_PATH);
$config->config = [
'DB' => [
'TYPE' => $this->getConfig('DB_TYPE'),
@@ -973,7 +973,7 @@ class CSetupWizard extends CForm {
$this->setConfig('ZBX_CONFIG_FILE_CORRECT', true);
- $config_file_name = APP::getInstance()->getRootDir().CConfigFile::CONFIG_FILE_PATH;
+ $config_file_name = APP::getRootDir().CConfigFile::CONFIG_FILE_PATH;
$config = new CConfigFile($config_file_name);
$config->config = [
'DB' => [
diff --git a/ui/include/classes/widgets/CWidgetConfig.php b/ui/include/classes/widgets/CWidgetConfig.php
deleted file mode 100644
index 1d37c52e602..00000000000
--- a/ui/include/classes/widgets/CWidgetConfig.php
+++ /dev/null
@@ -1,501 +0,0 @@
-<?php declare(strict_types = 0);
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-class CWidgetConfig {
-
- /**
- * Array of deprecated widgets constants.
- */
- public const DEPRECATED_WIDGETS = [
- WIDGET_DATA_OVER
- ];
-
- /**
- * Classifier for non-template dashboards.
- */
- public const CONTEXT_DASHBOARD = 'dashboard';
-
- /**
- * Classifier for template and host dashboards.
- */
- public const CONTEXT_TEMPLATE_DASHBOARD = 'template_dashboard';
-
- /**
- * Get default names for all widget types.
- *
- * @static
- *
- * @param string $context CWidgetConfig::CONTEXT_DASHBOARD | CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD
- *
- * @return array
- */
- public static function getKnownWidgetTypes(string $context): array {
- $types = [
- WIDGET_ACTION_LOG => _('Action log'),
- WIDGET_CLOCK => _('Clock'),
- WIDGET_DATA_OVER => _('Data overview'),
- WIDGET_DISCOVERY => _('Discovery status'),
- WIDGET_FAV_GRAPHS => _('Favorite graphs'),
- WIDGET_FAV_MAPS => _('Favorite maps'),
- WIDGET_GEOMAP => _('Geomap'),
- WIDGET_ITEM => _('Item value'),
- WIDGET_GRAPH => _('Graph (classic)'),
- WIDGET_GRAPH_PROTOTYPE => _('Graph prototype'),
- WIDGET_HOST_AVAIL => _('Host availability'),
- WIDGET_MAP => _('Map'),
- WIDGET_NAV_TREE => _('Map navigation tree'),
- WIDGET_PLAIN_TEXT => _('Plain text'),
- WIDGET_PROBLEM_HOSTS => _('Problem hosts'),
- WIDGET_PROBLEMS => _('Problems'),
- WIDGET_PROBLEMS_BY_SV => _('Problems by severity'),
- WIDGET_SLA_REPORT => _('SLA report'),
- WIDGET_SVG_GRAPH => _('Graph'),
- WIDGET_SYSTEM_INFO => _('System information'),
- WIDGET_TRIG_OVER => _('Trigger overview'),
- WIDGET_URL => _('URL'),
- WIDGET_WEB => _('Web monitoring'),
- WIDGET_TOP_HOSTS => _('Top hosts')
- ];
-
- $types = array_filter($types,
- function(string $type) use ($context): bool {
- return self::isWidgetTypeSupportedInContext($type, $context);
- },
- ARRAY_FILTER_USE_KEY
- );
-
- return $types;
- }
-
- /**
- * Get JavaScript classes for all widget types.
- *
- * @static
- *
- * @return array
- */
- public static function getJSClasses(): array {
- return [
- WIDGET_ACTION_LOG => 'CWidget',
- WIDGET_CLOCK => 'CWidgetClock',
- WIDGET_DATA_OVER => 'CWidget',
- WIDGET_DISCOVERY => 'CWidget',
- WIDGET_FAV_GRAPHS => 'CWidget',
- WIDGET_FAV_MAPS => 'CWidget',
- WIDGET_GEOMAP => 'CWidgetGeoMap',
- WIDGET_ITEM => 'CWidgetItem',
- WIDGET_GRAPH => 'CWidgetGraph',
- WIDGET_GRAPH_PROTOTYPE => 'CWidgetGraphPrototype',
- WIDGET_HOST_AVAIL => 'CWidget',
- WIDGET_MAP => 'CWidgetMap',
- WIDGET_NAV_TREE => 'CWidgetNavTree',
- WIDGET_PLAIN_TEXT => 'CWidget',
- WIDGET_PROBLEM_HOSTS => 'CWidget',
- WIDGET_PROBLEMS => 'CWidgetProblems',
- WIDGET_PROBLEMS_BY_SV => 'CWidgetProblemsBySv',
- WIDGET_SLA_REPORT => 'CWidget',
- WIDGET_SVG_GRAPH => 'CWidgetSvgGraph',
- WIDGET_SYSTEM_INFO => 'CWidget',
- WIDGET_TRIG_OVER => 'CWidgetTrigerOver',
- WIDGET_URL => 'CWidget',
- WIDGET_WEB => 'CWidget',
- WIDGET_TOP_HOSTS => 'CWidget'
- ];
- }
-
- /**
- * Get reference field name for widgets of the given type.
- *
- * @static
- *
- * @return string|null
- */
- public static function getReferenceField(string $type): ?string {
- switch ($type) {
- case WIDGET_MAP:
- case WIDGET_NAV_TREE:
- return 'reference';
-
- default:
- return null;
- }
- }
-
- /**
- * Get foreign reference field names for widgets of the given type.
- *
- * @static
- *
- * @return array
- */
- public static function getForeignReferenceFields(string $type): array {
- switch ($type) {
- case WIDGET_MAP:
- return ['filter_widget_reference'];
-
- default:
- return [];
- }
- }
-
- /**
- * Get default widget dimensions.
- *
- * @static
- *
- * @return array
- */
- private static function getDefaultDimensions(): array {
- return [
- WIDGET_ACTION_LOG => ['width' => 12, 'height' => 5],
- WIDGET_CLOCK => ['width' => 4, 'height' => 3],
- WIDGET_DATA_OVER => ['width' => 12, 'height' => 5],
- WIDGET_DISCOVERY => ['width' => 6, 'height' => 3],
- WIDGET_FAV_GRAPHS => ['width' => 4, 'height' => 3],
- WIDGET_FAV_MAPS => ['width' => 4, 'height' => 3],
- WIDGET_GEOMAP => ['width' => 12, 'height' => 5],
- WIDGET_ITEM => ['width' => 4, 'height' => 3],
- WIDGET_GRAPH => ['width' => 12, 'height' => 5],
- WIDGET_GRAPH_PROTOTYPE => ['width' => 16, 'height' => 5],
- WIDGET_HOST_AVAIL => ['width' => 6, 'height' => 3],
- WIDGET_MAP => ['width' => 18, 'height' => 5],
- WIDGET_NAV_TREE => ['width' => 6, 'height' => 5],
- WIDGET_PLAIN_TEXT => ['width' => 6, 'height' => 3],
- WIDGET_PROBLEM_HOSTS => ['width' => 12, 'height' => 5],
- WIDGET_PROBLEMS => ['width' => 12, 'height' => 5],
- WIDGET_PROBLEMS_BY_SV => ['width' => 12, 'height' => 5],
- WIDGET_SLA_REPORT => ['width' => 12, 'height' => 5],
- WIDGET_SVG_GRAPH => ['width' => 12, 'height' => 5],
- WIDGET_SYSTEM_INFO => ['width' => 12, 'height' => 5],
- WIDGET_TRIG_OVER => ['width' => 12, 'height' => 5],
- WIDGET_URL => ['width' => 12, 'height' => 5],
- WIDGET_WEB => ['width' => 6, 'height' => 3],
- WIDGET_TOP_HOSTS => ['width' => 12, 'height' => 5]
- ];
- }
-
- /**
- * Get default values for widgets.
- *
- * @static
- *
- * @param string $context CWidgetConfig::CONTEXT_DASHBOARD | CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD
- *
- * @return array
- */
- public static function getDefaults(string $context): array {
- $ret = [];
-
- $dimensions = self::getDefaultDimensions();
- $js_clases = self::getJSClasses();
-
- foreach (self::getKnownWidgetTypes($context) as $type => $name) {
- $ret[$type] = [
- 'name' => $name,
- 'size' => $dimensions[$type],
- 'js_class' => $js_clases[$type],
- 'iterator' => self::isIterator($type),
- 'reference_field' => self::getReferenceField($type),
- 'foreign_reference_fields' => self::getForeignReferenceFields($type)
- ];
- }
-
- return $ret;
- }
-
- /**
- * Check if widget type is supported in a given context.
- *
- * @static
- *
- * @param string $type Widget type - 'WIDGET_*' constant.
- * @param string $context CWidgetConfig::CONTEXT_DASHBOARD | CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD
- *
- * @return bool
- */
- public static function isWidgetTypeSupportedInContext(string $type, string $context): bool {
- switch ($context) {
- case self::CONTEXT_DASHBOARD:
- return true;
-
- case self::CONTEXT_TEMPLATE_DASHBOARD:
- switch ($type) {
- case WIDGET_CLOCK:
- case WIDGET_GRAPH:
- case WIDGET_GRAPH_PROTOTYPE:
- case WIDGET_ITEM:
- case WIDGET_PLAIN_TEXT:
- case WIDGET_URL:
- return true;
-
- default:
- return false;
- }
- }
- }
-
- /**
- * Get default refresh rate for widget type.
- *
- * @static
- *
- * @param string $type Widget type - 'WIDGET_*' constant.
- *
- * @return int default refresh rate, 0 for no refresh
- */
- public static function getDefaultRfRate(string $type): int {
- switch ($type) {
- case WIDGET_ACTION_LOG:
- case WIDGET_DATA_OVER:
- case WIDGET_TOP_HOSTS:
- case WIDGET_DISCOVERY:
- case WIDGET_GEOMAP:
- case WIDGET_GRAPH:
- case WIDGET_GRAPH_PROTOTYPE:
- case WIDGET_PLAIN_TEXT:
- case WIDGET_ITEM:
- case WIDGET_PROBLEM_HOSTS:
- case WIDGET_PROBLEMS:
- case WIDGET_PROBLEMS_BY_SV:
- case WIDGET_SVG_GRAPH:
- case WIDGET_TRIG_OVER:
- case WIDGET_WEB:
- return SEC_PER_MIN;
-
- case WIDGET_CLOCK:
- case WIDGET_FAV_GRAPHS:
- case WIDGET_FAV_MAPS:
- case WIDGET_HOST_AVAIL:
- case WIDGET_MAP:
- case WIDGET_NAV_TREE:
- case WIDGET_SYSTEM_INFO:
- return 15 * SEC_PER_MIN;
-
- case WIDGET_SLA_REPORT:
- case WIDGET_URL:
- return 0;
- }
- }
-
- /**
- * Get all possible widget refresh intervals.
- *
- * @return array
- */
- public static function getRfRates() {
- return [
- 0 => _('No refresh'),
- SEC_PER_MIN / 6 => _n('%1$s second', '%1$s seconds', 10),
- SEC_PER_MIN / 2 => _n('%1$s second', '%1$s seconds', 30),
- SEC_PER_MIN => _n('%1$s minute', '%1$s minutes', 1),
- SEC_PER_MIN * 2 => _n('%1$s minute', '%1$s minutes', 2),
- SEC_PER_MIN * 10 => _n('%1$s minute', '%1$s minutes', 10),
- SEC_PER_MIN * 15 => _n('%1$s minute', '%1$s minutes', 15)
- ];
- }
-
- /**
- * Check if time selector is necessary for widget having specified type and fields.
- *
- * @static
- *
- * @param string $type Widget type - 'WIDGET_*' constant.
- * @param array $fields
- *
- * @return bool
- */
- public static function usesTimeSelector(string $type, array $fields): bool {
- switch ($type) {
- case WIDGET_GRAPH:
- case WIDGET_GRAPH_PROTOTYPE:
- return true;
-
- case WIDGET_SVG_GRAPH:
- return !CWidgetFormSvgGraph::hasOverrideTime($fields);
-
- default:
- return false;
- }
- }
-
- /**
- * Check if widget type belongs to iterators.
- *
- * @static
- *
- * @param string $type Widget type - 'WIDGET_*' constant.
- *
- * @return bool
- */
- public static function isIterator(string $type): bool {
- switch ($type) {
- case WIDGET_GRAPH_PROTOTYPE:
- return true;
-
- default:
- return false;
- }
- }
-
- /**
- * Check if widget has padding or not.
- *
- * @static
- *
- * @param string $type Widget type - 'WIDGET_*' constant.
- * @param array $fields Widget form fields
- * @param int $view_mode Widget view mode. ZBX_WIDGET_VIEW_MODE_NORMAL by default
- *
- * @return bool
- */
- private static function hasPadding(string $type, array $fields, int $view_mode): bool {
- if ($view_mode == ZBX_WIDGET_VIEW_MODE_HIDDEN_HEADER) {
- switch ($type) {
- case WIDGET_CLOCK:
- return $fields['clock_type'] === WIDGET_CLOCK_TYPE_ANALOG;
-
- case WIDGET_GRAPH:
- case WIDGET_MAP:
- case WIDGET_SVG_GRAPH:
- return true;
-
- default:
- return false;
- }
- }
- else {
- switch ($type) {
- case WIDGET_CLOCK:
- return $fields['clock_type'] === WIDGET_CLOCK_TYPE_ANALOG;
-
- case WIDGET_HOST_AVAIL:
- return (count($fields['interface_type']) != 1);
-
- case WIDGET_PROBLEMS_BY_SV:
- return $fields['show_type'] != WIDGET_PROBLEMS_BY_SV_SHOW_TOTALS;
-
- case WIDGET_GRAPH_PROTOTYPE:
- case WIDGET_ITEM:
- case WIDGET_URL:
- return false;
-
- default:
- return true;
- }
- }
- }
-
- /**
- * Get widget configuration based on widget type, fields and current view mode.
- *
- * @param string $type Widget type - 'WIDGET_*' constant.
- * @param array $fields Widget form fields
- * @param int $view_mode Widget view mode
- *
- * @return array
- */
- public static function getConfiguration(string $type, array $fields, int $view_mode): array {
- return [
- 'padding' => self::hasPadding($type, $fields, $view_mode)
- ];
- }
-
- /**
- * Get Form object for widget with provided data.
- *
- * @static
- *
- * @param string $type Widget type - 'WIDGET_*' constant.
- * @param string $data JSON string with widget fields.
- * @param string|null $templateid Template ID for template dashboards or null for non-template dashboards.
- *
- * @return CWidgetForm
- */
- public static function getForm(string $type, string $data, ?string $templateid): CWidgetForm {
- switch ($type) {
- case WIDGET_ACTION_LOG:
- return new CWidgetFormActionLog($data, $templateid);
-
- case WIDGET_CLOCK:
- return new CWidgetFormClock($data, $templateid);
-
- case WIDGET_DATA_OVER:
- return new CWidgetFormDataOver($data, $templateid);
-
- case WIDGET_GEOMAP:
- return new CWidgetFormGeoMap($data, $templateid);
-
- case WIDGET_GRAPH:
- return new CWidgetFormGraph($data, $templateid);
-
- case WIDGET_GRAPH_PROTOTYPE:
- return new CWidgetFormGraphPrototype($data, $templateid);
-
- case WIDGET_HOST_AVAIL:
- return new CWidgetFormHostAvail($data, $templateid);
-
- case WIDGET_MAP:
- return new CWidgetFormMap($data, $templateid);
-
- case WIDGET_NAV_TREE:
- return new CWidgetFormNavTree($data, $templateid);
-
- case WIDGET_PLAIN_TEXT:
- return new CWidgetFormPlainText($data, $templateid);
-
- case WIDGET_PROBLEM_HOSTS:
- return new CWidgetFormProblemHosts($data, $templateid);
-
- case WIDGET_PROBLEMS:
- return new CWidgetFormProblems($data, $templateid);
-
- case WIDGET_PROBLEMS_BY_SV:
- return new CWidgetFormProblemsBySv($data, $templateid);
-
- case WIDGET_SLA_REPORT:
- return new CWidgetFormSlaReport($data, $templateid);
-
- case WIDGET_SVG_GRAPH:
- return new CWidgetFormSvgGraph($data, $templateid);
-
- case WIDGET_SYSTEM_INFO:
- return new CWidgetFormSystemInfo($data, $templateid);
-
- case WIDGET_TRIG_OVER:
- return new CWidgetFormTrigOver($data, $templateid);
-
- case WIDGET_URL:
- return new CWidgetFormUrl($data, $templateid);
-
- case WIDGET_WEB:
- return new CWidgetFormWeb($data, $templateid);
-
- case WIDGET_ITEM:
- return new CWidgetFormItem($data, $templateid);
-
- case WIDGET_TOP_HOSTS:
- return new CWidgetFormTopHosts($data, $templateid);
-
- default:
- return new CWidgetForm($data, $templateid, $type);
- }
- }
-}
diff --git a/ui/include/classes/widgets/fields/CWidgetField.php b/ui/include/classes/widgets/CWidgetField.php
index 8eda42f3da7..76a0444288b 100644
--- a/ui/include/classes/widgets/fields/CWidgetField.php
+++ b/ui/include/classes/widgets/CWidgetField.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -18,197 +18,115 @@
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
-class CWidgetField {
- const FLAG_ACKNOWLEDGES = 0x01;
- const FLAG_NOT_EMPTY = 0x02;
- const FLAG_LABEL_ASTERISK = 0x04;
- const FLAG_DISABLED = 0x08;
+namespace Zabbix\Widgets;
+
+use CApiInputValidator;
+
+abstract class CWidgetField {
+
+ public const FLAG_ACKNOWLEDGES = 0x01;
+ public const FLAG_NOT_EMPTY = 0x02;
+ public const FLAG_LABEL_ASTERISK = 0x04;
+ public const FLAG_DISABLED = 0x08;
+
+ protected string $name;
+ protected ?string $label;
+ protected ?string $full_name = null;
+
+ protected ?int $save_type = null;
- protected $name;
- protected $full_name;
- protected $label;
protected $value;
protected $default;
- protected $save_type;
- protected $action;
- protected $validation_rules = [];
- protected $strict_validation_rules = null;
- protected $ex_validation_rules = [];
- protected $flags;
+
+ protected ?string $action = null;
+
+ protected int $flags = 0x00;
+
+ protected array $validation_rules = [];
+ protected ?array $strict_validation_rules = null;
+ protected array $ex_validation_rules = [];
/**
- * Create widget field (general)
- *
- * @param string $name Field name in form.
- * @param string $label Label for the field in form.
+ * @param string $name Field name in form.
+ * @param string|null $label Label for the field in form.
*/
- public function __construct($name, $label = null) {
+ public function __construct(string $name, string $label = null) {
$this->name = $name;
$this->label = $label;
$this->value = null;
$this->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR);
- $this->flags = 0x00;
}
- public function setValue($value) {
- $this->value = $value;
-
- return $this;
+ public function getName(): string {
+ return $this->name;
}
- public function setDefault($value) {
- $this->default = $value;
-
- return $this;
+ public function getLabel(): ?string {
+ return $this->label;
}
/**
- * Set JS code that will be called on field change.
- *
- * @param string $action JS function to call on field change.
- *
- * @return $this
+ * Set field full name which will appear in case of error messages. For example:
+ * Invalid parameter "<FULL NAME>": too many decimal places.
*/
- public function setAction($action) {
- $this->action = $action;
-
- return $this;
- }
-
- protected function setSaveType($save_type) {
- switch ($save_type) {
- case ZBX_WIDGET_FIELD_TYPE_INT32:
- $this->validation_rules = ['type' => API_INT32];
- break;
-
- case ZBX_WIDGET_FIELD_TYPE_STR:
- $this->validation_rules = ['type' => API_STRING_UTF8, 'length' => 255];
- break;
-
- case ZBX_WIDGET_FIELD_TYPE_GROUP:
- case ZBX_WIDGET_FIELD_TYPE_HOST:
- case ZBX_WIDGET_FIELD_TYPE_ITEM:
- case ZBX_WIDGET_FIELD_TYPE_ITEM_PROTOTYPE:
- case ZBX_WIDGET_FIELD_TYPE_GRAPH:
- case ZBX_WIDGET_FIELD_TYPE_GRAPH_PROTOTYPE:
- case ZBX_WIDGET_FIELD_TYPE_SERVICE:
- case ZBX_WIDGET_FIELD_TYPE_SLA:
- $this->validation_rules = ['type' => API_IDS];
- break;
-
- case ZBX_WIDGET_FIELD_TYPE_MAP:
- $this->validation_rules = ['type' => API_ID];
- break;
-
- default:
- exit(_('Internal error.'));
- }
-
- $this->save_type = $save_type;
+ public function setFullName(string $name): self {
+ $this->full_name = $name;
return $this;
}
- protected function setValidationRules(array $validation_rules) {
- $this->validation_rules = $validation_rules;
- }
-
- protected function getValidationRules() {
- return $this->validation_rules;
- }
-
- /**
- * Set validation rules for "strict" mode.
- *
- * @param array|null $strict_validation_rules
- */
- protected function setStrictValidationRules(array $strict_validation_rules = null) {
- $this->strict_validation_rules = $strict_validation_rules;
- }
-
- protected function setExValidationRules(array $ex_validation_rules) {
- $this->ex_validation_rules = $ex_validation_rules;
- }
-
/**
* Get field value. If no value is set, will return default value.
- *
- * @return mixed
*/
public function getValue() {
- return ($this->value === null) ? $this->default : $this->value;
+ return $this->value ?? $this->default;
}
- public function getLabel() {
- return $this->label;
- }
+ public function setValue($value): self {
+ $this->value = $value;
- public function getName() {
- return $this->name;
+ return $this;
}
- /**
- * Set field full name which will appear in case of error messages. For example:
- * Invalid parameter "<FULL NAME>": too many decimal places.
- *
- * @param string $name
- *
- * @return CWidgetField
- */
- public function setFullName($name) {
- $this->full_name = $name;
+ public function setDefault($value): self {
+ $this->default = $value;
return $this;
}
- public function getAction() {
+ public function getAction(): ?string {
return $this->action;
}
- public function getSaveType() {
- return $this->save_type;
+ /**
+ * Set JS code that will be called on field change.
+ *
+ * @param string $action JS function to call on field change.
+ */
+ public function setAction(string $action): self {
+ $this->action = $action;
+
+ return $this;
}
/**
- * Set additional flags for validation rule array.
- *
- * @param array $validation_rule
- * @param int $flag
- *
+ * Get additional flags, which can be used in configuration form.
*/
- protected static function setValidationRuleFlag(array &$validation_rule, $flag) {
- if (array_key_exists('flags', $validation_rule)) {
- $validation_rule['flags'] |= $flag;
- }
- else {
- $validation_rule['flags'] = $flag;
- }
+ public function getFlags(): int {
+ return $this->flags;
}
/**
* Set additional flags, which can be used in configuration form.
- *
- * @param int $flags
- *
- * @return $this
*/
- public function setFlags($flags) {
+ public function setFlags(int $flags): self {
$this->flags = $flags;
return $this;
}
/**
- * Get additional flags, which can be used in configuration form.
- *
- * @return int
- */
- public function getFlags() {
- return $this->flags;
- }
-
- /**
* @param bool $strict Widget form submit validation?
*
* @return array Errors.
@@ -220,13 +138,14 @@ class CWidgetField {
? $this->strict_validation_rules
: $this->validation_rules;
$validation_rules += $this->ex_validation_rules;
- $value = ($this->value === null) ? $this->default : $this->value;
+
+ $value = $this->value ?? $this->default;
if ($this->full_name !== null) {
$label = $this->full_name;
}
else {
- $label = ($this->label === null) ? $this->name : $this->label;
+ $label = $this->label ?? $this->name;
}
if (CApiInputValidator::validate($validation_rules, $value, $label, $error)) {
@@ -245,9 +164,9 @@ class CWidgetField {
* Reference is needed here to avoid array merging in CWidgetForm::fieldsToApi method. With large number of widget
* fields it causes significant performance decrease.
*
- * @param array $widget_fields reference to Array of widget fields.
+ * @param array $widget_fields reference to Array of widget fields.
*/
- public function toApi(array &$widget_fields = []) {
+ public function toApi(array &$widget_fields = []): void {
$value = $this->getValue();
if ($value !== null && $value !== $this->default) {
@@ -268,4 +187,75 @@ class CWidgetField {
}
}
}
+
+ protected function setSaveType($save_type): self {
+ switch ($save_type) {
+ case ZBX_WIDGET_FIELD_TYPE_INT32:
+ $this->validation_rules = ['type' => API_INT32];
+ break;
+
+ case ZBX_WIDGET_FIELD_TYPE_STR:
+ $this->validation_rules = ['type' => API_STRING_UTF8, 'length' => 255];
+ break;
+
+ case ZBX_WIDGET_FIELD_TYPE_GROUP:
+ case ZBX_WIDGET_FIELD_TYPE_HOST:
+ case ZBX_WIDGET_FIELD_TYPE_ITEM:
+ case ZBX_WIDGET_FIELD_TYPE_ITEM_PROTOTYPE:
+ case ZBX_WIDGET_FIELD_TYPE_GRAPH:
+ case ZBX_WIDGET_FIELD_TYPE_GRAPH_PROTOTYPE:
+ case ZBX_WIDGET_FIELD_TYPE_SERVICE:
+ case ZBX_WIDGET_FIELD_TYPE_SLA:
+ $this->validation_rules = ['type' => API_IDS];
+ break;
+
+ case ZBX_WIDGET_FIELD_TYPE_MAP:
+ $this->validation_rules = ['type' => API_ID];
+ break;
+
+ default:
+ exit(_('Internal error.'));
+ }
+
+ $this->save_type = $save_type;
+
+ return $this;
+ }
+
+ protected function getValidationRules(): array {
+ return $this->validation_rules;
+ }
+
+ protected function setValidationRules(array $validation_rules): self {
+ $this->validation_rules = $validation_rules;
+
+ return $this;
+ }
+
+ /**
+ * Set validation rules for "strict" mode.
+ */
+ protected function setStrictValidationRules(array $strict_validation_rules = null): self {
+ $this->strict_validation_rules = $strict_validation_rules;
+
+ return $this;
+ }
+
+ protected function setExValidationRules(array $ex_validation_rules): self {
+ $this->ex_validation_rules = $ex_validation_rules;
+
+ return $this;
+ }
+
+ /**
+ * Set additional flags for validation rule array.
+ */
+ protected static function setValidationRuleFlag(array &$validation_rule, int $flag): void {
+ if (array_key_exists('flags', $validation_rule)) {
+ $validation_rule['flags'] |= $flag;
+ }
+ else {
+ $validation_rule['flags'] = $flag;
+ }
+ }
}
diff --git a/ui/include/classes/widgets/forms/CWidgetForm.php b/ui/include/classes/widgets/CWidgetForm.php
index a48a5c86d27..308a0a72645 100644
--- a/ui/include/classes/widgets/forms/CWidgetForm.php
+++ b/ui/include/classes/widgets/CWidgetForm.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,76 +19,95 @@
**/
-class CWidgetForm {
-
- protected $fields;
+namespace Zabbix\Widgets;
- /**
- * Widget fields array that came from AJAX request.
- *
- * @var array
- */
- protected $data;
+class CWidgetForm {
- protected $templateid;
+ protected array $fields = [];
- public function __construct($data, $templateid, $type) {
- $this->data = json_decode($data, true);
+ protected array $values;
+ protected ?string $templateid;
+ public function __construct(array $values, ?string $templateid) {
+ $this->values = $this->normalizeValues($values);
$this->templateid = $templateid;
+ }
- $this->fields = [];
+ public function addFields(): self {
+ return $this;
+ }
- if ($templateid === null) {
- // Refresh interval field.
- $default_rf_rate = '';
+ public function addField(?CWidgetField $field): self {
+ if ($field !== null) {
+ $this->fields[$field->getName()] = $field;
+ }
- foreach (CWidgetConfig::getRfRates() as $rf_rate => $label) {
- if ($rf_rate == CWidgetConfig::getDefaultRfRate($type)) {
- $default_rf_rate = $label;
- break;
- }
- }
+ return $this;
+ }
- $rf_rates = [
- -1 => _('Default').' ('.$default_rf_rate.')'
- ];
- $rf_rates += CWidgetConfig::getRfRates();
+ public function getFields(): array {
+ return $this->fields;
+ }
- $rf_rate_field = (new CWidgetFieldSelect('rf_rate', _('Refresh interval'), $rf_rates))
- ->setDefault(-1);
+ public function getFieldValue(string $field_name) {
+ return $this->fields[$field_name]->getValue();
+ }
- if (array_key_exists('rf_rate', $this->data)) {
- $rf_rate_field->setValue($this->data['rf_rate']);
- }
+ public function getFieldsValues(): array {
+ $values = [];
- $this->fields[$rf_rate_field->getName()] = $rf_rate_field;
+ foreach ($this->fields as $field) {
+ $values[$field->getName()] = $field->getValue();
}
- // Add Columns and Rows fields for Iterator widgets.
-
- if (CWidgetConfig::isIterator($type)) {
- $field_columns = (new CWidgetFieldIntegerBox('columns', _('Columns'), 1, DASHBOARD_MAX_COLUMNS))
- ->setFlags(CWidgetField::FLAG_LABEL_ASTERISK)
- ->setDefault(2);
+ return $values;
+ }
- if (array_key_exists('columns', $this->data)) {
- $field_columns->setValue($this->data['columns']);
+ public function setFieldsValues(): self {
+ foreach ($this->fields as $field) {
+ if (array_key_exists($field->getName(), $this->values)) {
+ $field->setValue($this->values[$field->getName()]);
}
+ }
- $this->fields[$field_columns->getName()] = $field_columns;
+ return $this;
+ }
- $field_rows = (new CWidgetFieldIntegerBox('rows', _('Rows'), 1,
- floor(DASHBOARD_WIDGET_MAX_ROWS / DASHBOARD_WIDGET_MIN_ROWS)))
- ->setFlags(CWidgetField::FLAG_LABEL_ASTERISK)
- ->setDefault(1);
+ /**
+ * Validate form fields.
+ *
+ * @param bool $strict Enables more strict validation of the form fields.
+ * Must be enabled for validation of input parameters in the widget configuration form.
+ *
+ * @return array
+ */
+ public function validate(bool $strict = false): array {
+ $errors = [];
- if (array_key_exists('rows', $this->data)) {
- $field_rows->setValue($this->data['rows']);
- }
+ foreach ($this->fields as $field) {
+ $errors = array_merge($errors, $field->validate($strict));
+ }
+
+ return $errors;
+ }
+
+ /**
+ * Prepares array, ready to be passed to CDashboard API functions.
+ *
+ * @return array Array of widget fields ready for saving in API.
+ */
+ public function fieldsToApi(): array {
+ $api_fields = [];
- $this->fields[$field_rows->getName()] = $field_rows;
+ foreach ($this->fields as $field) {
+ $field->toApi($api_fields);
}
+
+ return $api_fields;
+ }
+
+ protected function normalizeValues(array $values): array {
+ return self::convertDottedKeys($values);
}
/**
@@ -119,9 +138,9 @@ class CWidgetForm {
*
* @return array
*/
- protected static function convertDottedKeys(array $data) {
+ protected static function convertDottedKeys(array $data): array {
// API doesn't guarantee fields to be retrieved in same order as stored. Sorting by key...
- uksort($data, function ($key1, $key2) {
+ uksort($data, static function ($key1, $key2) {
foreach (['key1', 'key2'] as $var) {
if (preg_match('/^([a-z]+)\.([a-z_]+)\.(\d+)\.(\d+)$/', (string) $$var, $matches) === 1) {
$$var = $matches[1].'.'.$matches[3].'.'.$matches[2].'.'.$matches[4];
@@ -152,62 +171,4 @@ class CWidgetForm {
return $data;
}
-
- /**
- * Return fields for this form.
- *
- * @return array An array of CWidgetField.
- */
- public function getFields() {
- return $this->fields;
- }
-
- /**
- * Returns widget fields data as array.
- *
- * @return array Key/value pairs where key is field name and value is it's data.
- */
- public function getFieldsData() {
- $data = [];
-
- foreach ($this->fields as $field) {
- /* @var $field CWidgetField */
- $data[$field->getName()] = $field->getValue();
- }
-
- return $data;
- }
-
- /**
- * Validate form fields.
- *
- * @param bool $strict Enables more strict validation of the form fields.
- * Must be enabled for validation of input parameters in the widget configuration form.
- *
- * @return array
- */
- public function validate($strict = false) {
- $errors = [];
-
- foreach ($this->fields as $field) {
- $errors = array_merge($errors, $field->validate($strict));
- }
-
- return $errors;
- }
-
- /**
- * Prepares array, ready to be passed to CDashboard API functions.
- *
- * @return array Array of widget fields ready for saving in API.
- */
- public function fieldsToApi() {
- $api_fields = [];
-
- foreach ($this->fields as $field) {
- $field->toApi($api_fields);
- }
-
- return $api_fields;
- }
}
diff --git a/ui/include/classes/widgets/CWidgetHelper.php b/ui/include/classes/widgets/CWidgetHelper.php
deleted file mode 100644
index 4336c73ac7c..00000000000
--- a/ui/include/classes/widgets/CWidgetHelper.php
+++ /dev/null
@@ -1,1611 +0,0 @@
-<?php declare(strict_types = 0);
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-class CWidgetHelper {
-
- public const DATASET_TYPE_SINGLE_ITEM = 0;
- public const DATASET_TYPE_PATTERN_ITEM = 1;
-
- /**
- * Create CForm for widget configuration form.
- *
- * @return CForm
- */
- public static function createForm(): CForm {
- return (new CForm('post'))
- ->cleanItems()
- ->setId('widget-dialogue-form')
- ->setName('widget_dialogue_form')
- ->addClass(ZBX_STYLE_DASHBOARD_WIDGET_FORM);
- }
-
- /**
- * Create CFormGrid for widget configuration form with default fields in it.
- *
- * @param string $name
- * @param string $type
- * @param int $view_mode ZBX_WIDGET_VIEW_MODE_NORMAL | ZBX_WIDGET_VIEW_MODE_HIDDEN_HEADER
- * @param array $known_widget_types
- * @param CWidgetFieldSelect|null $field_rf_rate
- *
- * @return CFormGrid
- */
- public static function createFormGrid(string $name, string $type, int $view_mode, array $known_widget_types,
- ?CWidgetFieldSelect $field_rf_rate): CFormGrid {
-
- $deprecated_widget_types = array_intersect_key($known_widget_types,
- array_flip(CWidgetConfig::DEPRECATED_WIDGETS)
- );
-
- $widget_types_select = (new CSelect('type'))
- ->setFocusableElementId('label-type')
- ->setId('type')
- ->setValue($type)
- ->setAttribute('autofocus', 'autofocus')
- ->addOptions(CSelect::createOptionsFromArray(
- array_diff_key($known_widget_types, $deprecated_widget_types))
- );
-
- if ($deprecated_widget_types) {
- $widget_types_select->addOptionGroup(
- (new CSelectOptionGroup(_('Deprecated')))
- ->addOptions(CSelect::createOptionsFromArray($deprecated_widget_types))
- );
- }
-
- return (new CFormGrid())
- ->addItem([
- new CLabel(_('Type'), 'label-type'),
- new CFormField(array_key_exists($type, $deprecated_widget_types)
- ? [$widget_types_select, ' ', makeWarningIcon(_('Widget is deprecated.'))]
- : $widget_types_select
- )
- ])
- ->addItem(
- (new CFormField(
- (new CCheckBox('show_header'))
- ->setLabel(_('Show header'))
- ->setLabelPosition(CCheckBox::LABEL_POSITION_LEFT)
- ->setId('show_header')
- ->setChecked($view_mode == ZBX_WIDGET_VIEW_MODE_NORMAL)
- ))->addClass('form-field-show-header')
- )
- ->addItem([
- new CLabel(_('Name'), 'name'),
- new CFormField(
- (new CTextBox('name', $name))
- ->setAttribute('placeholder', _('default'))
- ->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
- )
- ])
- ->addItem($field_rf_rate !== null
- ? [
- self::getLabel($field_rf_rate),
- new CFormField(self::getSelect($field_rf_rate))
- ]
- : null
- );
- }
-
- /**
- * Creates label linked to the field.
- *
- * @param CWidgetField $field
- * @param string $class Custom CSS class for label.
- * @param mixed $hint Hint box text.
- *
- * @return CLabel
- */
- public static function getLabel($field, $class = null, $hint = null) {
- $help_icon = ($hint !== null)
- ? makeHelpIcon($hint)
- : null;
-
- if ($field instanceof CWidgetFieldSelect) {
- return (new CLabel([$field->getLabel(), $help_icon], 'label-'.$field->getName()))
- ->setAsteriskMark(self::isAriaRequired($field))
- ->addClass($class);
- }
-
- return (new CLabel([$field->getLabel(), $help_icon], $field->getName()))
- ->setAsteriskMark(self::isAriaRequired($field))
- ->addClass($class);
- }
-
- /**
- * @param CWidgetFieldSelect $field
- *
- * @return CSelect
- */
- public static function getSelect($field) {
- return (new CSelect($field->getName()))
- ->setId($field->getName())
- ->setFocusableElementId('label-'.$field->getName())
- ->setValue($field->getValue())
- ->addOptions(CSelect::createOptionsFromArray($field->getValues()))
- ->setDisabled($field->getFlags() & CWidgetField::FLAG_DISABLED)
- ->setAriaRequired(self::isAriaRequired($field));
- }
-
- /**
- * @param CWidgetFieldTextArea $field
- *
- * @return CTextArea
- */
- public static function getTextArea($field) {
- return (new CTextArea($field->getName(), $field->getValue()))
- ->setAriaRequired(self::isAriaRequired($field))
- ->setEnabled(!($field->getFlags() & CWidgetField::FLAG_DISABLED))
- ->setAdaptiveWidth($field->getWidth());
- }
-
- /**
- * @param CWidgetFieldTextBox $field
- *
- * @return CTextBox
- */
- public static function getTextBox($field) {
- return (new CTextBox($field->getName(), $field->getValue()))
- ->setAriaRequired(self::isAriaRequired($field))
- ->setEnabled(!($field->getFlags() & CWidgetField::FLAG_DISABLED))
- ->setAttribute('placeholder', $field->getPlaceholder())
- ->setWidth($field->getWidth());
- }
-
- /**
- * @param CWidgetFieldLatLng $field
- *
- * @return CTextBox
- */
- public static function getLatLngZoomBox($field) {
- return (new CTextBox($field->getName(), $field->getValue()))
- ->setAttribute('placeholder', $field->getPlaceholder())
- ->setWidth($field->getWidth());
- }
-
- /**
- * @param CWidgetFieldUrl $field
- *
- * @return CTextBox
- */
- public static function getUrlBox($field) {
- return (new CTextBox($field->getName(), $field->getValue()))
- ->setAriaRequired(self::isAriaRequired($field))
- ->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH);
- }
-
- /**
- * @param CWidgetFieldRangeControl $field
- *
- * @return CRangeControl
- */
- public static function getRangeControl($field) {
- return (new CRangeControl($field->getName(), (int) $field->getValue()))
- ->setEnabled(!($field->getFlags() & CWidgetField::FLAG_DISABLED))
- ->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
- ->setStep($field->getStep())
- ->setMin($field->getMin())
- ->setMax($field->getMax());
- }
-
- /**
- * @param CWidgetFieldHostPatternSelect $field Widget field object.
- * @param string $form_name HTML form element name.
- *
- * @return CPatternSelect
- */
- public static function getHostPatternSelect($field, $form_name) {
- return (new CPatternSelect([
- 'name' => $field->getName().'[]',
- 'object_name' => 'hosts',
- 'data' => $field->getValue(),
- 'placeholder' => $field->getPlaceholder(),
- 'wildcard_allowed' => 1,
- 'popup' => [
- 'parameters' => [
- 'srctbl' => 'hosts',
- 'srcfld1' => 'hostid',
- 'dstfrm' => $form_name,
- 'dstfld1' => zbx_formatDomId($field->getName().'[]')
- ]
- ],
- 'add_post_js' => false
- ]))
- ->setEnabled(!($field->getFlags() & CWidgetField::FLAG_DISABLED))
- ->setAriaRequired(self::isAriaRequired($field))
- ->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH);
- }
-
- /**
- * @param CWidgetFieldCheckBox $field
- *
- * @return array
- */
- public static function getCheckBox($field) {
- return [(new CVar($field->getName(), '0'))->removeId(), (new CCheckBox($field->getName()))
- ->setChecked((bool) $field->getValue())
- ->setEnabled(!($field->getFlags() & CWidgetField::FLAG_DISABLED))
- ->setLabel($field->getCaption())
- ->onChange($field->getAction())
- ];
- }
-
- /**
- * @param CWidgetFieldColor $field
- * @param bool $use_default Tell the Color picker whether to use Default color feature or not.
- *
- * @return CColor
- */
- public static function getColor($field, $use_default = false) {
- // appendColorPickerJs(false), because the script responsible for it is in widget.item.form.view.
- $color_picker = (new CColor($field->getName(), $field->getValue()))->appendColorPickerJs(false);
- if ($use_default) {
- $color_picker->enableUseDefault();
- }
- return $color_picker;
- }
-
- /**
- * Creates label linked to the multiselect field.
- *
- * @param CWidgetFieldMs $field
- *
- * @return CLabel
- */
- public static function getMultiselectLabel($field) {
- $field_name = $field->getName();
-
- if ($field instanceof CWidgetFieldMs) {
- $field_name .= ($field->isMultiple() ? '[]' : '');
- }
- else {
- $field_name .= '[]';
- }
-
- return (new CLabel($field->getLabel(), $field_name.'_ms'))
- ->setAsteriskMark(self::isAriaRequired($field));
- }
-
- /**
- * @param CWidgetFieldMs $field
- * @param array $captions
- * @param string $form_name
- *
- * @return CMultiSelect
- */
- private static function getMultiselectField($field, $captions, $form_name, $object_name, $popup_options) {
- $field_name = $field->getName().($field->isMultiple() ? '[]' : '');
- $options = [
- 'name' => $field_name,
- 'object_name' => $object_name,
- 'multiple' => $field->isMultiple(),
- 'data' => $captions,
- 'popup' => [
- 'parameters' => [
- 'dstfrm' => $form_name,
- 'dstfld1' => zbx_formatDomId($field_name)
- ] + $popup_options
- ],
- 'add_post_js' => false
- ];
-
- if ($field instanceof CWidgetFieldMsHost && $field->getFilterPreselect()) {
- $options['popup']['filter_preselect']['id'] = $field->getFilterPreselect();
- $options['popup']['filter_preselect']['submit_as'] = 'groupid';
- }
-
- return (new CMultiSelect($options))
- ->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
- ->setAriaRequired(self::isAriaRequired($field));
- }
-
- /**
- * @param CWidgetFieldMsGroup $field
- * @param array $captions
- * @param string $form_name
- *
- * @return CMultiSelect
- */
- public static function getGroup($field, $captions, $form_name) {
- return self::getMultiselectField($field, $captions, $form_name, 'hostGroup', [
- 'srctbl' => 'host_groups',
- 'srcfld1' => 'groupid',
- 'real_hosts' => true,
- 'enrich_parent_groups' => true
- ] + $field->getFilterParameters());
- }
-
- /**
- * @param CWidgetFieldMsHost $field
- * @param array $captions
- * @param string $form_name
- *
- * @return CMultiSelect
- */
- public static function getHost($field, $captions, $form_name) {
- return self::getMultiselectField($field, $captions, $form_name, 'hosts', [
- 'srctbl' => 'hosts',
- 'srcfld1' => 'hostid'
- ] + $field->getFilterParameters());
- }
-
- /**
- * @param CWidgetFieldMsItem $field
- * @param array $captions
- * @param string $form_name
- *
- * @return CMultiSelect
- */
- public static function getItem($field, $captions, $form_name) {
- return self::getMultiselectField($field, $captions, $form_name, 'items', [
- 'srctbl' => 'items',
- 'srcfld1' => 'itemid'
- ] + $field->getFilterParameters());
- }
-
- /**
- * @param CWidgetFieldMsGraph $field
- * @param array $captions
- * @param string $form_name
- *
- * @return CMultiSelect
- */
- public static function getGraph($field, $captions, $form_name) {
- return self::getMultiselectField($field, $captions, $form_name, 'graphs', [
- 'srctbl' => 'graphs',
- 'srcfld1' => 'graphid',
- 'srcfld2' => 'name',
- 'with_graphs' => true
- ] + $field->getFilterParameters());
- }
-
- /**
- * @param CWidgetFieldMsItemPrototype $field
- * @param array $captions
- * @param string $form_name
- *
- * @return CMultiSelect
- */
- public static function getItemPrototype($field, $captions, $form_name) {
- return self::getMultiselectField($field, $captions, $form_name, 'item_prototypes', [
- 'srctbl' => 'item_prototypes',
- 'srcfld1' => 'itemid'
- ] + $field->getFilterParameters());
- }
-
- /**
- * @param CWidgetFieldMsGraphPrototype $field
- * @param array $captions
- * @param string $form_name
- *
- * @return CMultiSelect
- */
- public static function getGraphPrototype($field, $captions, $form_name) {
- return self::getMultiselectField($field, $captions, $form_name, 'graph_prototypes', [
- 'srctbl' => 'graph_prototypes',
- 'srcfld1' => 'graphid',
- 'srcfld2' => 'name',
- 'with_graph_prototypes' => true
- ] + $field->getFilterParameters());
- }
-
- /**
- * @param CWidgetFieldMsService $field
- * @param array $captions
- * @param string $form_name
- *
- * @return CMultiSelect
- */
- public static function getService($field, $captions, $form_name) {
- return (new CMultiSelect([
- 'name' => $field->getName().($field->isMultiple() ? '[]' : ''),
- 'object_name' => 'services',
- 'multiple' => $field->isMultiple(),
- 'data' => $captions,
- 'custom_select' => true,
- 'add_post_js' => false
- ]))
- ->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
- ->setAriaRequired(self::isAriaRequired($field));
- }
-
- /**
- * @param CWidgetFieldMsSla $field
- * @param array $captions
- * @param string $form_name
- *
- * @return CMultiSelect
- */
- public static function getSla($field, $captions, $form_name) {
- return self::getMultiselectField($field, $captions, $form_name, 'sla', [
- 'srctbl' => 'sla',
- 'srcfld1' => 'slaid'
- ] + $field->getFilterParameters());
- }
-
- public static function getSelectResource($field, $caption, $form_name) {
- return [
- (new CTextBox($field->getName().'_caption', $caption, true))
- ->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
- ->setAriaRequired(self::isAriaRequired($field)),
- (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
- (new CButton('select', _('Select')))
- ->addClass(ZBX_STYLE_BTN_GREY)
- ->onClick('return PopUp("popup.generic", '.json_encode($field->getPopupOptions($form_name)).',
- {dialogue_class: "modal-popup-generic"}
- );')
- ];
- }
-
- /**
- * Creates select field without values, to later fill it by JS script.
- *
- * @param CWidgetFieldWidgetSelect $field
- *
- * @return CSelect
- */
- public static function getEmptySelect($field) {
- return (new CSelect($field->getName()))
- ->setFocusableElementId('label-'.$field->getName())
- ->setId($field->getName())
- ->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
- ->setAriaRequired(self::isAriaRequired($field));
- }
-
- /**
- * @param CWidgetFieldIntegerBox $field
- *
- * @return CNumericBox
- */
- public static function getIntegerBox(CWidgetFieldIntegerBox $field): CNumericBox {
- return (new CNumericBox($field->getName(), $field->getValue(), $field->getMaxLength(), false,
- ($field->getFlags() & CWidgetField::FLAG_NOT_EMPTY) == 0
- ))
- ->setWidth(ZBX_TEXTAREA_NUMERIC_STANDARD_WIDTH)
- ->setAriaRequired(self::isAriaRequired($field));
- }
-
- /**
- * @param CWidgetFieldNumericBox $field
- *
- * @return CTextBox
- */
- public static function getNumericBox($field) {
- return (new CTextBox($field->getName(), $field->getValue()))
- ->setAriaRequired(self::isAriaRequired($field))
- ->setEnabled(!($field->getFlags() & CWidgetField::FLAG_DISABLED))
- ->setAttribute('placeholder', $field->getPlaceholder())
- ->setWidth($field->getWidth());
- }
-
- /**
- * @param CWidgetFieldRadioButtonList $field
- *
- * @return CRadioButtonList
- */
- public static function getRadioButtonList($field) {
- $radio_button_list = (new CRadioButtonList($field->getName(), $field->getValue()))
- ->setModern($field->getModern())
- ->setAriaRequired(self::isAriaRequired($field));
-
- foreach ($field->getValues() as $key => $value) {
- $radio_button_list
- ->addValue($value, $key, null, $field->getAction())
- ->setEnabled(!($field->getFlags() & CWidgetField::FLAG_DISABLED));
- }
-
- return $radio_button_list;
- }
-
- /**
- * @param CWidgetFieldSeverities $field
- *
- * @return CSeverityCheckBoxList
- */
- public static function getSeverities($field) {
- return (new CSeverityCheckBoxList($field->getName()))
- ->setChecked($field->getValue())
- ->setEnabled(!($field->getFlags() & CWidgetField::FLAG_DISABLED))
- ->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH);
- }
-
- /**
- * @param CWidgetFieldCheckBoxList $field
- * @param array $list Option list array.
- * @param array $class_list List of additional CSS classes.
- *
- * @return CList
- */
- public static function getCheckBoxList($field, array $list, array $class_list = []) {
- $checkbox_list = (new CList())->addClass(ZBX_STYLE_LIST_CHECK_RADIO);
- if ($class_list) {
- foreach ($class_list as $class) {
- $checkbox_list->addClass($class);
- }
- }
-
- foreach ($list as $key => $label) {
- $checkbox_list->addItem(
- (new CCheckBox($field->getName().'[]', $key))
- ->setLabel($label)
- ->setId($field->getName().'_'.$key)
- ->setChecked(in_array($key, $field->getValue()))
- ->setEnabled(!($field->getFlags() & CWidgetField::FLAG_DISABLED))
- );
- }
-
- return $checkbox_list;
- }
-
- /**
- * @param CWidgetFieldColumnsList $field Widget columns field.
- *
- * @return CDiv
- */
- public static function getWidgetColumns(CWidgetFieldColumnsList $field) {
- $columns = $field->getValue();
- $header = [
- '',
- (new CColHeader(_('Name')))->addStyle('width: 39%'),
- (new CColHeader(_('Data')))->addStyle('width: 59%'),
- _('Action')
- ];
- $row_actions = [
- (new CButton('edit', _('Edit')))
- ->addClass(ZBX_STYLE_BTN_LINK)
- ->removeId(),
- (new CButton('remove', _('Remove')))
- ->addClass(ZBX_STYLE_BTN_LINK)
- ->removeId()
- ];
- $table = (new CTable())
- ->setId('list_'.$field->getName())
- ->setHeader($header);
- $enabled = !($field->getFlags() & CWidgetField::FLAG_DISABLED);
-
- foreach ($columns as $column_index => $column) {
- $column_data = [new CVar('sortorder['.$field->getName().'][]', $column_index)];
-
- foreach ($column as $key => $value) {
- $column_data[] = new CVar($field->getName().'['.$column_index.']['.$key.']', $value);
- }
-
- $label = array_key_exists('item', $column) ? $column['item'] : '';
-
- if ($column['data'] == CWidgetFieldColumnsList::DATA_HOST_NAME) {
- $label = new CTag('em', true, _('Host name'));
- }
- else if ($column['data'] == CWidgetFieldColumnsList::DATA_TEXT) {
- $label = new CTag('em', true, $column['text']);
- }
-
- $table->addRow((new CRow([
- (new CCol((new CDiv)->addClass(ZBX_STYLE_DRAG_ICON)))->addClass(ZBX_STYLE_TD_DRAG_ICON),
- (new CDiv($column['name']))->addClass('text'),
- (new CDiv($label))->addClass('text'),
- (new CList(array_merge($row_actions, [$column_data])))->addClass(ZBX_STYLE_HOR_LIST)
- ]))->addClass('sortable'));
- }
-
- $table->addRow(
- (new CCol(
- (new CButton('add', _('Add')))
- ->addClass(ZBX_STYLE_BTN_LINK)
- ->setEnabled($enabled)
- ))->setColSpan(count($header))
- );
-
- return $table;
- }
-
- /**
- * @param CWidgetFieldTags $field
- *
- * @return CTable
- */
- public static function getTags($field) {
- $tags = $field->getValue();
-
- if (!$tags) {
- $tags = [['tag' => '', 'operator' => TAG_OPERATOR_LIKE, 'value' => '']];
- }
-
- $tags_table = (new CTable())
- ->setId('tags_table_'.$field->getName())
- ->addClass('table-tags')
- ->addClass('table-initial-width');
-
- $enabled = !($field->getFlags() & CWidgetField::FLAG_DISABLED);
- $i = 0;
-
- foreach ($tags as $tag) {
- $zselect_operator = (new CSelect($field->getName().'['.$i.'][operator]'))
- ->addOptions(CSelect::createOptionsFromArray([
- TAG_OPERATOR_EXISTS => _('Exists'),
- TAG_OPERATOR_EQUAL => _('Equals'),
- TAG_OPERATOR_LIKE => _('Contains'),
- TAG_OPERATOR_NOT_EXISTS => _('Does not exist'),
- TAG_OPERATOR_NOT_EQUAL => _('Does not equal'),
- TAG_OPERATOR_NOT_LIKE => _('Does not contain')
- ]))
- ->setValue($tag['operator'])
- ->setFocusableElementId($field->getName().'-'.$i.'-operator-select')
- ->setId($field->getName().'_'.$i.'_operator');
-
- if (!$enabled) {
- $zselect_operator->setDisabled();
- }
-
- $tags_table->addRow([
- (new CTextBox($field->getName().'['.$i.'][tag]', $tag['tag']))
- ->setAttribute('placeholder', _('tag'))
- ->setWidth(ZBX_TEXTAREA_FILTER_SMALL_WIDTH)
- ->setAriaRequired(self::isAriaRequired($field))
- ->setEnabled($enabled),
- $zselect_operator,
- (new CTextBox($field->getName().'['.$i.'][value]', $tag['value']))
- ->setAttribute('placeholder', _('value'))
- ->setWidth(ZBX_TEXTAREA_FILTER_SMALL_WIDTH)
- ->setAriaRequired(self::isAriaRequired($field))
- ->setId($field->getName().'_'.$i.'_value')
- ->setEnabled($enabled),
- (new CCol(
- (new CButton($field->getName().'['.$i.'][remove]', _('Remove')))
- ->addClass(ZBX_STYLE_BTN_LINK)
- ->addClass('element-table-remove')
- ->setEnabled($enabled)
- ))->addClass(ZBX_STYLE_NOWRAP)
- ], 'form_row');
-
- $i++;
- }
-
- $tags_table->addRow(
- (new CCol(
- (new CButton('tags_add', _('Add')))
- ->addClass(ZBX_STYLE_BTN_LINK)
- ->addClass('element-table-add')
- ->setEnabled($enabled)
- ))->setColSpan(3)
- );
-
- return $tags_table;
- }
-
- /**
- * JS Template for one tag line for Tags field
- *
- * @param CWidgetFieldTags $field
- *
- * @return string
- */
- public static function getTagsTemplate($field) {
- return (new CRow([
- (new CTextBox($field->getName().'[#{rowNum}][tag]'))
- ->setAttribute('placeholder', _('tag'))
- ->setWidth(ZBX_TEXTAREA_FILTER_SMALL_WIDTH)
- ->setAriaRequired(self::isAriaRequired($field)),
- (new CSelect($field->getName().'[#{rowNum}][operator]'))
- ->addOptions(CSelect::createOptionsFromArray([
- TAG_OPERATOR_EXISTS => _('Exists'),
- TAG_OPERATOR_EQUAL => _('Equals'),
- TAG_OPERATOR_LIKE => _('Contains'),
- TAG_OPERATOR_NOT_EXISTS => _('Does not exist'),
- TAG_OPERATOR_NOT_EQUAL => _('Does not equal'),
- TAG_OPERATOR_NOT_LIKE => _('Does not contain')
- ]))
- ->setValue(TAG_OPERATOR_LIKE)
- ->setFocusableElementId($field->getName().'-#{rowNum}-operator-select')
- ->setId($field->getName().'_#{rowNum}_operator'),
- (new CTextBox($field->getName().'[#{rowNum}][value]'))
- ->setAttribute('placeholder', _('value'))
- ->setWidth(ZBX_TEXTAREA_FILTER_SMALL_WIDTH)
- ->setAriaRequired(self::isAriaRequired($field))
- ->setId($field->getName().'_#{rowNum}_value'),
- (new CCol(
- (new CButton($field->getName().'[#{rowNum}][remove]', _('Remove')))
- ->addClass(ZBX_STYLE_BTN_LINK)
- ->addClass('element-table-remove')
- ))->addClass(ZBX_STYLE_NOWRAP)
- ]))
- ->addClass('form_row')
- ->toString();
- }
-
- /**
- * @param CWidgetFieldDatePicker $field
- *
- * @return CDateSelector
- */
- public static function getDatePicker(CWidgetFieldDatePicker $field): CDateSelector {
- return (new CDateSelector($field->getName(), $field->getValue()))
- ->setAriaRequired(self::isAriaRequired($field))
- ->setMaxLength(DB::getFieldLength('widget_field', 'value_str'))
- ->setEnabled(($field->getFlags() & CWidgetField::FLAG_DISABLED) == 0);
- }
-
- /**
- * Function returns array containing HTML objects filled with given values. Used to generate HTML in widget
- * overrides field.
- *
- * @param CWidgetFieldGraphOverride $field
- * @param array $value Values to fill in particular data set row. See self::setValue() for
- * detailed description.
- * @param string $form_name Name of form in which data set fields resides.
- * @param int|string $row_num Unique data set numeric identifier. Used to make unique field names.
- *
- * @return CListItem
- */
- public static function getGraphOverrideLayout($field, array $value, $form_name, $row_num) {
- $inputs = [];
-
- // Create override options list.
- foreach (CWidgetFieldGraphOverride::getOverrideOptions() as $option) {
- if (array_key_exists($option, $value)) {
- $inputs[] = (new CVar($field->getName().'['.$row_num.']['.$option.']', $value[$option]));
- }
- }
-
- return (new CListItem([
- /**
- * First line: host pattern field, item pattern field.
- * Contains also drag and drop button and delete button.
- */
- (new CDiv([
- (new CDiv())
- ->addClass(ZBX_STYLE_DRAG_ICON)
- ->addStyle('position: absolute; margin-left: -25px;'),
- (new CDiv([
- (new CDiv(
- (new CPatternSelect([
- 'name' => $field->getName().'['.$row_num.'][hosts][]',
- 'object_name' => 'hosts',
- 'data' => $value['hosts'],
- 'placeholder' => _('host pattern'),
- 'wildcard_allowed' => 1,
- 'popup' => [
- 'parameters' => [
- 'srctbl' => 'hosts',
- 'srcfld1' => 'hostid',
- 'dstfrm' => $form_name,
- 'dstfld1' => zbx_formatDomId($field->getName().'['.$row_num.'][hosts][]')
- ]
- ],
- 'add_post_js' => false
- ]))
- ->setEnabled(!($field->getFlags() & CWidgetField::FLAG_DISABLED))
- ->setAriaRequired(self::isAriaRequired($field))
- ->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
- ))->addClass(ZBX_STYLE_COLUMN_50),
- (new CDiv(
- (new CPatternSelect([
- 'name' => $field->getName().'['.$row_num.'][items][]',
- 'object_name' => 'items',
- 'data' => $value['items'],
- 'placeholder' => _('item pattern'),
- 'multiple' => true,
- 'wildcard_allowed' => 1,
- 'popup' => [
- 'parameters' => [
- 'srctbl' => 'items',
- 'srcfld1' => 'itemid',
- 'real_hosts' => 1,
- 'numeric' => 1,
- 'dstfrm' => $form_name,
- 'dstfld1' => zbx_formatDomId($field->getName().'['.$row_num.'][items][]')
- ]
- ],
- 'add_post_js' => false
- ]))
- ->setEnabled(!($field->getFlags() & CWidgetField::FLAG_DISABLED))
- ->setAriaRequired(self::isAriaRequired($field))
- ->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
- ))->addClass(ZBX_STYLE_COLUMN_50)
- ]))
- ->addClass(ZBX_STYLE_COLUMNS)
- ->addClass(ZBX_STYLE_COLUMNS_NOWRAP)
- ->addClass(ZBX_STYLE_COLUMN_95),
-
- (new CDiv(
- (new CButton())
- ->setAttribute('title', _('Delete'))
- ->addClass(ZBX_STYLE_BTN_REMOVE)
- ->removeId()
- ))
- ->addClass(ZBX_STYLE_COLUMN_5)
- ]))
- ->addClass(ZBX_STYLE_COLUMNS),
-
- // Selected override options.
- (new CList($inputs))
- ->addClass(ZBX_STYLE_OVERRIDES_OPTIONS_LIST)
- ->addItem((new CButton(null, (new CSpan())
- ->addClass(ZBX_STYLE_PLUS_ICON)
- ->addStyle('margin-right: 0px;')
- ))
- ->setAttribute('data-row', $row_num)
- ->addClass(ZBX_STYLE_BTN_ALT)
- )
- ]))
- ->addClass(ZBX_STYLE_OVERRIDES_LIST_ITEM);
- }
-
- /**
- * Return template used by dynamic rows in CWidgetFieldGraphOverride field.
- *
- * @param CWidgetFieldGraphOverride $field
- * @param string $form_name Form name in which override field is located.
- *
- * @return string
- */
- public static function getGraphOverrideTemplate($field, $form_name) {
- $value = CWidgetFieldGraphOverride::getDefaults();
-
- return self::getGraphOverrideLayout($field, $value, $form_name, '#{rowNum}')->toString();
- }
-
- /**
- * @param CWidgetFieldGraphOverride $field
- *
- * @return CList
- */
- public static function getGraphOverride($field, $form_name) {
- $list = (new CList())->addClass(ZBX_STYLE_OVERRIDES_LIST);
-
- $values = $field->getValue();
-
- if (!$values) {
- $values = [];
- }
-
- $i = 0;
-
- foreach ($values as $override) {
- $list->addItem(self::getGraphOverrideLayout($field, $override, $form_name, $i));
-
- $i++;
- }
-
- // Add 'Add' button under the list.
- $list->addItem(
- (new CDiv(
- (new CButton('override_add', [(new CSpan())->addClass(ZBX_STYLE_PLUS_ICON), _('Add new override')]))
- ->addClass(ZBX_STYLE_BTN_ALT)
- ->setId('override-add')
- )),
- 'overrides-foot'
- );
-
- return $list;
- }
-
- /**
- * Function returns array containing string values used as titles for override options.
- *
- * @return array
- */
- private static function getGraphOverrideOptionNames() {
- return [
- 'width' => _('Width'),
- 'type' => _('Draw'),
- 'type'.SVG_GRAPH_TYPE_LINE => _('Line'),
- 'type'.SVG_GRAPH_TYPE_POINTS => _('Points'),
- 'type'.SVG_GRAPH_TYPE_STAIRCASE => _('Staircase'),
- 'type'.SVG_GRAPH_TYPE_BAR => _('Bar'),
- 'transparency' => _('Transparency'),
- 'fill' => _('Fill'),
- 'pointsize' => _('Point size'),
- 'missingdatafunc' => _('Missing data'),
- 'missingdatafunc'.SVG_GRAPH_MISSING_DATA_NONE => _('None'),
- 'missingdatafunc'.SVG_GRAPH_MISSING_DATA_CONNECTED => _x('Connected', 'missing data function'),
- 'missingdatafunc'.SVG_GRAPH_MISSING_DATA_TREAT_AS_ZERO => _x('Treat as 0', 'missing data function'),
- 'missingdatafunc'.SVG_GRAPH_MISSING_DATA_LAST_KNOWN => _x('Last known', 'missing data function'),
- 'axisy' => _('Y-axis'),
- 'axisy'.GRAPH_YAXIS_SIDE_LEFT => _('Left'),
- 'axisy'.GRAPH_YAXIS_SIDE_RIGHT => _('Right'),
- 'timeshift' => _('Time shift')
- ];
- }
-
- /**
- * Function returns array used to construct override field menu of available override options.
- *
- * @return array
- */
- private static function getGraphOverrideMenu() {
- return [
- 'sections' => [
- [
- 'name' => _('ADD OVERRIDE'),
- 'options' => [
- ['name' => _('Base color'), 'callback' => 'addOverride', 'args' => ['color', '']],
-
- ['name' => _('Width').'/0', 'callback' => 'addOverride', 'args' => ['width', 0]],
- ['name' => _('Width').'/1', 'callback' => 'addOverride', 'args' => ['width', 1]],
- ['name' => _('Width').'/2', 'callback' => 'addOverride', 'args' => ['width', 2]],
- ['name' => _('Width').'/3', 'callback' => 'addOverride', 'args' => ['width', 3]],
- ['name' => _('Width').'/4', 'callback' => 'addOverride', 'args' => ['width', 4]],
- ['name' => _('Width').'/5', 'callback' => 'addOverride', 'args' => ['width', 5]],
- ['name' => _('Width').'/6', 'callback' => 'addOverride', 'args' => ['width', 6]],
- ['name' => _('Width').'/7', 'callback' => 'addOverride', 'args' => ['width', 7]],
- ['name' => _('Width').'/8', 'callback' => 'addOverride', 'args' => ['width', 8]],
- ['name' => _('Width').'/9', 'callback' => 'addOverride', 'args' => ['width', 9]],
- ['name' => _('Width').'/10', 'callback' => 'addOverride', 'args' => ['width', 10]],
-
- ['name' => _('Draw').'/'._('Line'), 'callback' => 'addOverride', 'args' => ['type', SVG_GRAPH_TYPE_LINE]],
- ['name' => _('Draw').'/'._('Points'), 'callback' => 'addOverride', 'args' => ['type', SVG_GRAPH_TYPE_POINTS]],
- ['name' => _('Draw').'/'._('Staircase'), 'callback' => 'addOverride', 'args' => ['type', SVG_GRAPH_TYPE_STAIRCASE]],
- ['name' => _('Draw').'/'._('Bar'), 'callback' => 'addOverride', 'args' => ['type', SVG_GRAPH_TYPE_BAR]],
-
- ['name' => _('Transparency').'/0', 'callback' => 'addOverride', 'args' => ['transparency', 0]],
- ['name' => _('Transparency').'/1', 'callback' => 'addOverride', 'args' => ['transparency', 1]],
- ['name' => _('Transparency').'/2', 'callback' => 'addOverride', 'args' => ['transparency', 2]],
- ['name' => _('Transparency').'/3', 'callback' => 'addOverride', 'args' => ['transparency', 3]],
- ['name' => _('Transparency').'/4', 'callback' => 'addOverride', 'args' => ['transparency', 4]],
- ['name' => _('Transparency').'/5', 'callback' => 'addOverride', 'args' => ['transparency', 5]],
- ['name' => _('Transparency').'/6', 'callback' => 'addOverride', 'args' => ['transparency', 6]],
- ['name' => _('Transparency').'/7', 'callback' => 'addOverride', 'args' => ['transparency', 7]],
- ['name' => _('Transparency').'/8', 'callback' => 'addOverride', 'args' => ['transparency', 8]],
- ['name' => _('Transparency').'/9', 'callback' => 'addOverride', 'args' => ['transparency', 9]],
- ['name' => _('Transparency').'/10', 'callback' => 'addOverride', 'args' => ['transparency', 10]],
-
- ['name' => _('Fill').'/0', 'callback' => 'addOverride', 'args' => ['fill', 0]],
- ['name' => _('Fill').'/1', 'callback' => 'addOverride', 'args' => ['fill', 1]],
- ['name' => _('Fill').'/2', 'callback' => 'addOverride', 'args' => ['fill', 2]],
- ['name' => _('Fill').'/3', 'callback' => 'addOverride', 'args' => ['fill', 3]],
- ['name' => _('Fill').'/4', 'callback' => 'addOverride', 'args' => ['fill', 4]],
- ['name' => _('Fill').'/5', 'callback' => 'addOverride', 'args' => ['fill', 5]],
- ['name' => _('Fill').'/6', 'callback' => 'addOverride', 'args' => ['fill', 6]],
- ['name' => _('Fill').'/7', 'callback' => 'addOverride', 'args' => ['fill', 7]],
- ['name' => _('Fill').'/8', 'callback' => 'addOverride', 'args' => ['fill', 8]],
- ['name' => _('Fill').'/9', 'callback' => 'addOverride', 'args' => ['fill', 9]],
- ['name' => _('Fill').'/10', 'callback' => 'addOverride', 'args' => ['fill', 10]],
-
- ['name' => _('Point size').'/1', 'callback' => 'addOverride', 'args' => ['pointsize', 1]],
- ['name' => _('Point size').'/2', 'callback' => 'addOverride', 'args' => ['pointsize', 2]],
- ['name' => _('Point size').'/3', 'callback' => 'addOverride', 'args' => ['pointsize', 3]],
- ['name' => _('Point size').'/4', 'callback' => 'addOverride', 'args' => ['pointsize', 4]],
- ['name' => _('Point size').'/5', 'callback' => 'addOverride', 'args' => ['pointsize', 5]],
- ['name' => _('Point size').'/6', 'callback' => 'addOverride', 'args' => ['pointsize', 6]],
- ['name' => _('Point size').'/7', 'callback' => 'addOverride', 'args' => ['pointsize', 7]],
- ['name' => _('Point size').'/8', 'callback' => 'addOverride', 'args' => ['pointsize', 8]],
- ['name' => _('Point size').'/9', 'callback' => 'addOverride', 'args' => ['pointsize', 9]],
- ['name' => _('Point size').'/10', 'callback' => 'addOverride', 'args' => ['pointsize', 10]],
-
- ['name' => _('Missing data').'/'._('None'), 'callback' => 'addOverride', 'args' => ['missingdatafunc', SVG_GRAPH_MISSING_DATA_NONE]],
- ['name' => _('Missing data').'/'._x('Connected', 'missing data function'), 'callback' => 'addOverride', 'args' => ['missingdatafunc', SVG_GRAPH_MISSING_DATA_CONNECTED]],
- ['name' => _('Missing data').'/'._x('Treat as 0', 'missing data function'), 'callback' => 'addOverride', 'args' => ['missingdatafunc', SVG_GRAPH_MISSING_DATA_TREAT_AS_ZERO]],
- ['name' => _('Missing data').'/'._x('Last known', 'missing data function'), 'callback' => 'addOverride', 'args' => ['missingdatafunc', SVG_GRAPH_MISSING_DATA_LAST_KNOWN]],
-
- ['name' => _('Y-axis').'/'._('Left'), 'callback' => 'addOverride', 'args' => ['axisy', GRAPH_YAXIS_SIDE_LEFT]],
- ['name' => _('Y-axis').'/'._('Right'), 'callback' => 'addOverride', 'args' => ['axisy', GRAPH_YAXIS_SIDE_RIGHT]],
-
- ['name' => _('Time shift'), 'callback' => 'addOverride', 'args' => ['timeshift']]
- ]
- ]
- ]
- ];
- }
-
- /**
- * Return javascript necessary to initialize CWidgetFieldGraphOverride field.
- *
- * @param CWidgetFieldGraphOverride $field
- *
- * @return string
- */
- public static function getGraphOverrideJavascript($field) {
- return '
- // Define it as function to avoid redundancy.
- function initializeOverrides() {
- jQuery("#overrides .'.ZBX_STYLE_OVERRIDES_OPTIONS_LIST.'").overrides({
- add: ".'.ZBX_STYLE_BTN_ALT.'",
- options: "input[type=hidden]",
- captions: '.json_encode(self::getGraphOverrideOptionNames()).',
- makeName: function(option, row_id) {
- return "'.$field->getName().'[" + row_id + "][" + option + "]";
- },
- makeOption: function(name) {
- return name.match(
- /.*\[('.implode('|', CWidgetFieldGraphOverride::getOverrideOptions()).')\]/
- )[1];
- },
- override: ".'.ZBX_STYLE_OVERRIDES_LIST_ITEM.'",
- overridesList: ".'.ZBX_STYLE_OVERRIDES_LIST.'",
- onUpdate: () => widget_svggraph_form.onGraphConfigChange(),
- menu: '.json_encode(self::getGraphOverrideMenu()).'
- });
- }
-
- // Initialize dynamicRows.
- jQuery("#overrides")
- .dynamicRows({
- template: "#overrides-row",
- beforeRow: ".overrides-foot",
- remove: ".'.ZBX_STYLE_BTN_REMOVE.'",
- add: "#override-add",
- row: ".'.ZBX_STYLE_OVERRIDES_LIST_ITEM.'"
- })
- .bind("afteradd.dynamicRows", function(event, options) {
- const container = jQuery(".overlay-dialogue-body");
-
- container.scrollTop(Math.max(container.scrollTop(),
- jQuery("#widget-dialogue-form")[0].scrollHeight - container.height()
- ));
-
- jQuery(".multiselect", jQuery("#overrides")).each(function() {
- jQuery(this).multiSelect(jQuery(this).data("params"));
- });
-
- widget_svggraph_form.updateVariableOrder(jQuery("#overrides"), ".'.ZBX_STYLE_OVERRIDES_LIST_ITEM.'", "or");
- widget_svggraph_form.onGraphConfigChange();
- })
- .bind("afterremove.dynamicRows", function(event, options) {
- widget_svggraph_form.updateVariableOrder(jQuery("#overrides"), ".'.ZBX_STYLE_OVERRIDES_LIST_ITEM.'", "or");
- widget_svggraph_form.onGraphConfigChange();
- })
- .bind("tableupdate.dynamicRows", function(event, options) {
- widget_svggraph_form.updateVariableOrder(jQuery("#overrides"), ".'.ZBX_STYLE_OVERRIDES_LIST_ITEM.'", "or");
- initializeOverrides();
- if (jQuery("#overrides .'.ZBX_STYLE_OVERRIDES_LIST_ITEM.'").length > 1) {
- jQuery("#overrides .drag-icon").removeClass("disabled");
- jQuery("#overrides").sortable("enable");
- }
- else {
- jQuery("#overrides .drag-icon").addClass("disabled");
- jQuery("#overrides").sortable("disable");
- }
- });
-
- // Initialize overrides UI control.
- initializeOverrides();
-
- // Initialize override pattern-selectors.
- jQuery(".multiselect", jQuery("#overrides")).each(function() {
- jQuery(this).multiSelect(jQuery(this).data("params"));
- });
-
- // Make overrides sortable.
- if (jQuery("#overrides .'.ZBX_STYLE_OVERRIDES_LIST_ITEM.'").length < 2) {
- jQuery("#overrides .drag-icon").addClass("disabled");
- }
-
- jQuery("#overrides").sortable({
- items: ".'.ZBX_STYLE_OVERRIDES_LIST_ITEM.'",
- containment: "parent",
- handle: ".drag-icon",
- tolerance: "pointer",
- scroll: false,
- cursor: "grabbing",
- opacity: 0.6,
- axis: "y",
- disabled: function() {
- return jQuery("#overrides .'.ZBX_STYLE_OVERRIDES_LIST_ITEM.'").length < 2;
- }(),
- start: function() { // Workaround to fix wrong scrolling at initial sort.
- jQuery(this).sortable("refreshPositions");
- },
- stop: () => widget_svggraph_form.onGraphConfigChange(),
- update: function() {
- widget_svggraph_form.updateVariableOrder(jQuery("#overrides"), ".'.ZBX_STYLE_OVERRIDES_LIST_ITEM.'", "or");
- }
- });
- ';
- }
-
- /**
- * Function returns array containing HTML objects filled with given values. Used to generate HTML row in widget
- * data set field.
- *
- * @param string $field_name
- * @param array $value Values to fill in particular data set row. See self::setValue() for detailed
- * description.
- * @param string $form_name Name of form in which data set fields resides.
- * @param int|string $row_num Unique data set numeric identifier. Used to make unique field names.
- * @param bool $is_opened Either accordion row is made opened or closed.
- *
- * @return CListItem
- */
- private static function getGraphDataSetLayout($field_name, array $value, $form_name, $row_num, $is_opened,
- int $dataset_type = CWidgetHelper::DATASET_TYPE_PATTERN_ITEM) {
- $dataset_head = [
- new CDiv((new CSimpleButton('&nbsp;'))->addClass(ZBX_STYLE_LIST_ACCORDION_ITEM_TOGGLE)),
- new CVar($field_name.'['.$row_num.'][dataset_type]', $dataset_type, '')
- ];
-
- if ($dataset_type == self::DATASET_TYPE_PATTERN_ITEM) {
- $host_pattern_field = (new CPatternSelect([
- 'name' => $field_name.'['.$row_num.'][hosts][]',
- 'object_name' => 'hosts',
- 'data' => $value['hosts'],
- 'placeholder' => _('host pattern'),
- 'wildcard_allowed' => 1,
- 'popup' => [
- 'parameters' => [
- 'srctbl' => 'hosts',
- 'srcfld1' => 'host',
- 'dstfrm' => $form_name,
- 'dstfld1' => zbx_formatDomId($field_name.'['.$row_num.'][hosts][]')
- ]
- ],
- 'add_post_js' => false
- ]))
- ->addClass('js-hosts-multiselect')
- ->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH);
-
- $dataset_head = array_merge($dataset_head, [
- (new CColor($field_name.'['.$row_num.'][color]', $value['color']))->appendColorPickerJs(false),
- $host_pattern_field,
- (new CPatternSelect([
- 'name' => $field_name.'['.$row_num.'][items][]',
- 'object_name' => 'items',
- 'data' => $value['items'],
- 'placeholder' => _('item pattern'),
- 'wildcard_allowed' => 1,
- 'popup' => [
- 'parameters' => [
- 'srctbl' => 'items',
- 'srcfld1' => 'name',
- 'real_hosts' => 1,
- 'numeric' => 1,
- 'dstfrm' => $form_name,
- 'dstfld1' => zbx_formatDomId($field_name.'['.$row_num.'][items][]')
- ],
- 'filter_preselect' => [
- 'id' => $host_pattern_field->getId(),
- 'submit_as' => 'host_pattern',
- 'submit_parameters' => [
- 'host_pattern_wildcard_allowed' => 1,
- 'host_pattern_multiple' => 1
- ],
- 'multiple' => true
- ]
- ],
- 'autosuggest' => [
- 'filter_preselect' => [
- 'id' => $host_pattern_field->getId(),
- 'submit_as' => 'host_pattern',
- 'submit_parameters' => [
- 'host_pattern_wildcard_allowed' => 1,
- 'host_pattern_multiple' => 1
- ],
- 'multiple' => true
- ]
- ],
- 'add_post_js' => false
- ]))
- ->addClass('js-items-multiselect')
- ->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
- ]);
- }
- else {
- $item_rows = [];
- foreach($value['itemids'] as $i => $itemid) {
- $item_name = array_key_exists($itemid, $value['item_names'])
- ? $value['item_names'][$itemid]
- : '';
-
- $item_rows[] = (new CRow([
- (new CCol(
- (new CDiv())->addClass(ZBX_STYLE_DRAG_ICON)
- ))
- ->addClass('table-col-handle')
- ->addClass(ZBX_STYLE_TD_DRAG_ICON),
- (new CCol(
- (new CColor($field_name.'['.$row_num.'][color][]', $value['color'][$i],
- 'items_'.$row_num.'_'.($i + 1).'_color'
- ))->appendColorPickerJs(false)
- ))->addClass('table-col-color'),
- (new CCol(new CSpan(($i + 1).':')))->addClass('table-col-no'),
- (new CCol(
- (new CLink($item_name))
- ->setId('items_'.$row_num.'_'.($i + 1).'_name')
- ->addClass('js-click-expend')
- ))->addClass('table-col-name'),
- (new CCol([
- (new CButton('button', _('Remove')))
- ->addClass(ZBX_STYLE_BTN_LINK)
- ->addClass('element-table-remove'),
- new CVar($field_name.'['.$row_num.'][itemids][]', $itemid,
- 'items_'.$row_num.'_'.($i + 1).'_input'
- )
- ]))
- ->addClass('table-col-action')
- ->addClass(ZBX_STYLE_NOWRAP)
- ]))
- ->addClass(ZBX_STYLE_SORTABLE)
- ->addClass('single-item-table-row');
- }
-
- $empty_msg_block = (new CDiv(_('No item selected.')))->addClass('no-items-message');
-
- $items_list = (new CTable())
- ->addClass('single-item-table')
- ->setAttribute('data-set', $row_num)
- ->setColumns([
- (new CTableColumn())->addClass('table-col-handle'),
- (new CTableColumn())->addClass('table-col-color'),
- (new CTableColumn())->addClass('table-col-no'),
- (new CTableColumn(_('Name')))->addClass('table-col-name'),
- (new CTableColumn(_('Action')))->addClass('table-col-action')
- ])
- ->addItem([
- $item_rows,
- (new CTag('tfoot', true))
- ->addItem(
- (new CCol(
- (new CList())
- ->addClass(ZBX_STYLE_INLINE_FILTER_FOOTER)
- ->addItem(
- (new CSimpleButton(_('Add')))
- ->addClass(ZBX_STYLE_BTN_LINK)
- ->addClass('js-add-item')
- )
- ))->setColSpan(5)
- )
- ]);
-
- $dataset_head = array_merge($dataset_head, [
- (new CDiv([$empty_msg_block, $items_list]))->addClass('items-list table-forms-separator')
- ]);
- }
-
- $dataset_head[] = (new CDiv(
- (new CButton())
- ->setAttribute('title', _('Delete'))
- ->addClass(ZBX_STYLE_BTN_REMOVE)
- ->removeId()
- ))->addClass('dataset-actions');
-
- return (new CListItem([
- (new CDiv())
- ->addClass(ZBX_STYLE_DRAG_ICON)
- ->addClass(ZBX_STYLE_SORTABLE_DRAG_HANDLE)
- ->addClass('js-main-drag-icon'),
- (new CDiv())
- ->addClass(ZBX_STYLE_LIST_ACCORDION_ITEM_HEAD)
- ->addClass('dataset-head')
- ->addItem($dataset_head),
- (new CDiv())
- ->addClass(ZBX_STYLE_LIST_ACCORDION_ITEM_BODY)
- ->addClass('dataset-body')
- ->addItem([
- (new CFormGrid())
- ->addItem([
- new CLabel(_('Draw')),
- new CFormField(
- (new CRadioButtonList($field_name.'['.$row_num.'][type]', (int) $value['type']))
- ->addClass('js-type')
- ->addValue(_('Line'), SVG_GRAPH_TYPE_LINE)
- ->addValue(_('Points'), SVG_GRAPH_TYPE_POINTS)
- ->addValue(_('Staircase'), SVG_GRAPH_TYPE_STAIRCASE)
- ->addValue(_('Bar'), SVG_GRAPH_TYPE_BAR)
- ->setModern(true)
- )
- ])
- ->addItem([
- new CLabel(_('Stacked'), $field_name.'['.$row_num.'][stacked]'),
- new CFormField([
- (new CVar($field_name.'['.$row_num.'][stacked]', '0'))->removeId(),
- (new CCheckBox($field_name.'['.$row_num.'][stacked]'))
- ->addClass('js-stacked')
- ->setChecked((bool) $value['stacked'])
- ->setEnabled($value['type'] != SVG_GRAPH_TYPE_POINTS)
- ])
- ])
- ->addItem([
- new CLabel(_('Width')),
- new CFormField(
- (new CRangeControl($field_name.'['.$row_num.'][width]', (int) $value['width']))
- ->setEnabled(!in_array($value['type'], [SVG_GRAPH_TYPE_POINTS, SVG_GRAPH_TYPE_BAR]))
- ->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
- ->setStep(1)
- ->setMin(0)
- ->setMax(10)
- )
- ])
- ->addItem([
- new CLabel(_('Point size')),
- new CFormField(
- (new CRangeControl($field_name.'['.$row_num.'][pointsize]', (int) $value['pointsize']))
- ->setEnabled($value['type'] == SVG_GRAPH_TYPE_POINTS)
- ->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
- ->setStep(1)
- ->setMin(1)
- ->setMax(10)
- )
- ])
- ->addItem([
- new CLabel(_('Transparency')),
- new CFormField(
- (new CRangeControl($field_name.'['.$row_num.'][transparency]',
- (int) $value['transparency'])
- )
- ->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
- ->setStep(1)
- ->setMin(0)
- ->setMax(10)
- )
- ])
- ->addItem([
- new CLabel(_('Fill')),
- new CFormField(
- (new CRangeControl($field_name.'['.$row_num.'][fill]', (int) $value['fill']))
- ->setEnabled(!in_array($value['type'], [SVG_GRAPH_TYPE_POINTS, SVG_GRAPH_TYPE_BAR]))
- ->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
- ->setStep(1)
- ->setMin(0)
- ->setMax(10)
- )
- ]),
- (new CFormGrid())
- ->addItem([
- new CLabel(_('Missing data')),
- new CFormField(
- (new CRadioButtonList($field_name.'['.$row_num.'][missingdatafunc]',
- (int) $value['missingdatafunc'])
- )
- ->addValue(_('None'), SVG_GRAPH_MISSING_DATA_NONE)
- ->addValue(_x('Connected', 'missing data function'),
- SVG_GRAPH_MISSING_DATA_CONNECTED
- )
- ->addValue(_x('Treat as 0', 'missing data function'),
- SVG_GRAPH_MISSING_DATA_TREAT_AS_ZERO
- )
- ->addValue(_x('Last known', 'missing data function'),
- SVG_GRAPH_MISSING_DATA_LAST_KNOWN
- )
- ->setEnabled(!in_array($value['type'], [SVG_GRAPH_TYPE_POINTS, SVG_GRAPH_TYPE_BAR]))
- ->setModern(true)
- )
- ])
- ->addItem([
- new CLabel(_('Y-axis')),
- new CFormField(
- (new CRadioButtonList($field_name.'['.$row_num.'][axisy]', (int) $value['axisy']))
- ->addValue(_('Left'), GRAPH_YAXIS_SIDE_LEFT)
- ->addValue(_('Right'), GRAPH_YAXIS_SIDE_RIGHT)
- ->setModern(true)
- )
- ])
- ->addItem([
- new CLabel(_('Time shift'), $field_name.'['.$row_num.'][timeshift]'),
- new CFormField(
- (new CTextBox($field_name.'['.$row_num.'][timeshift]', $value['timeshift']))
- ->setAttribute('placeholder', _('none'))
- ->setWidth(ZBX_TEXTAREA_TINY_WIDTH)
- )
- ])
- ->addItem([
- new CLabel(_('Aggregation function'),
- 'label-'.$field_name.'_'.$row_num.'_aggregate_function'
- ),
- new CFormField(
- (new CSelect($field_name.'['.$row_num.'][aggregate_function]'))
- ->setId($field_name.'_'.$row_num.'_aggregate_function')
- ->setFocusableElementId('label-'.$field_name.'_'.$row_num.'_aggregate_function')
- ->setValue((int) $value['aggregate_function'])
- ->addOptions(CSelect::createOptionsFromArray([
- AGGREGATE_NONE => graph_item_aggr_fnc2str(AGGREGATE_NONE),
- AGGREGATE_MIN => graph_item_aggr_fnc2str(AGGREGATE_MIN),
- AGGREGATE_MAX => graph_item_aggr_fnc2str(AGGREGATE_MAX),
- AGGREGATE_AVG => graph_item_aggr_fnc2str(AGGREGATE_AVG),
- AGGREGATE_COUNT => graph_item_aggr_fnc2str(AGGREGATE_COUNT),
- AGGREGATE_SUM => graph_item_aggr_fnc2str(AGGREGATE_SUM),
- AGGREGATE_FIRST => graph_item_aggr_fnc2str(AGGREGATE_FIRST),
- AGGREGATE_LAST => graph_item_aggr_fnc2str(AGGREGATE_LAST)
- ]))
- ->setWidth(ZBX_TEXTAREA_TINY_WIDTH)
- )
- ])
- ->addItem([
- new CLabel(_('Aggregation interval'), $field_name.'['.$row_num.'][aggregate_interval]'),
- new CFormField(
- (new CTextBox($field_name.'['.$row_num.'][aggregate_interval]',
- $value['aggregate_interval']
- ))
- ->setEnabled($value['aggregate_function'] != AGGREGATE_NONE)
- ->setAttribute('placeholder', GRAPH_AGGREGATE_DEFAULT_INTERVAL)
- ->setWidth(ZBX_TEXTAREA_TINY_WIDTH)
- )
- ])
- ->addItem([
- new CLabel(_('Aggregate')),
- new CFormField(
- (new CRadioButtonList($field_name.'['.$row_num.'][aggregate_grouping]',
- (int) $value['aggregate_grouping'])
- )
- ->addValue(_('Each item'), GRAPH_AGGREGATE_BY_ITEM)
- ->addValue(_('Data set'), GRAPH_AGGREGATE_BY_DATASET)
- ->setEnabled($value['aggregate_function'] != AGGREGATE_NONE)
- ->setModern(true)
- )
- ])
- ->addItem([
- new CLabel(_('Approximation'),
- 'label-'.$field_name.'_'.$row_num.'_approximation'
- ),
- new CFormField(
- (new CSelect($field_name.'['.$row_num.'][approximation]'))
- ->setId($field_name.'_'.$row_num.'_approximation')
- ->setFocusableElementId('label-'.$field_name.'_'.$row_num.'_approximation')
- ->setValue((int) $value['approximation'])
- ->addOptions(CSelect::createOptionsFromArray([
- APPROXIMATION_ALL => [
- 'label' => _('all'),
- 'disabled' => ($value['type'] != SVG_GRAPH_TYPE_LINE || (bool) $value['stacked'])
- ],
- APPROXIMATION_MIN => _('min'),
- APPROXIMATION_AVG => _('avg'),
- APPROXIMATION_MAX => _('max')
- ]))
- ->setWidth(ZBX_TEXTAREA_TINY_WIDTH)
- )
- ])
- ])
- ]))
- ->addClass(ZBX_STYLE_LIST_ACCORDION_ITEM)
- ->addClass(ZBX_STYLE_SORTABLE_ITEM)
- ->addClass($is_opened ? ZBX_STYLE_LIST_ACCORDION_ITEM_OPENED : ZBX_STYLE_LIST_ACCORDION_ITEM_CLOSED)
- ->setAttribute('data-set', $row_num)
- ->setAttribute('data-type', $dataset_type);
- }
-
- /**
- * Return template used by dynamic rows in CWidgetFieldGraphDataSet field.
- *
- * @param CWidgetFieldGraphDataSet $field
- * @param string $form_name Form name in which data set field resides.
- * @param int $dataset_type
- *
- * @return string
- */
- public static function getGraphDataSetTemplate($field, $form_name, int $dataset_type) {
- $value = ['color' => '#{color}'] + CWidgetFieldGraphDataSet::getDefaults();
-
- return self::getGraphDataSetLayout($field->getName(), $value, $form_name, '#{rowNum}', true, $dataset_type)->toString();
- }
-
- /**
- * @param CWidgetFieldGraphDataSet $field
- *
- * @return CList
- */
- public static function getGraphDataSet($field, $form_name) {
- $list = (new CList())
- ->setId('data_sets')
- ->addClass(ZBX_STYLE_SORTABLE_LIST);
-
- $values = $field->getValue();
-
- if (!$values) {
- $values[] = CWidgetFieldGraphDataSet::getDefaults();
- }
-
- // Get item names for single item datasets.
- $itemids = array_merge(...array_column($values, 'itemids'));
- if ($itemids) {
- $names = self::getItemNames($itemids);
- }
-
- foreach ($values as $i => $value) {
- if ($value['dataset_type'] == self::DATASET_TYPE_SINGLE_ITEM) {
- $value['item_names'] = $names;
- }
-
- $list->addItem(
- self::getGraphDataSetLayout($field->getName(), $value, $form_name, $i, $i == 0, $value['dataset_type'])
- );
- }
-
- return $list;
- }
-
- public static function getGraphDataSetFooter() {
- return (new CList())
- ->addClass(ZBX_STYLE_BTN_SPLIT)
- ->addItem([
- (new CButton(null, [
- (new CSpan())->addClass(ZBX_STYLE_PLUS_ICON),
- _('Add new data set')
- ]))
- ->setId('dataset-add')
- ->addClass(ZBX_STYLE_BTN_ALT),
- (new CButton(null, '&#8203;'))
- ->setId('dataset-menu')
- ->addClass(ZBX_STYLE_BTN_ALT)
- ->addClass(ZBX_STYLE_BTN_TOGGLE_CHEVRON)
- ]);
- }
-
- private static function getItemNames(array $itemids): array {
- $names = [];
-
- $items = API::Item()->get([
- 'output' => ['itemid', 'hostid', 'name'],
- 'selectHosts' => ['hostid', 'name'],
- 'webitems' => true,
- 'itemids' => $itemids,
- 'preservekeys' => true
- ]);
-
- if (!$items) {
- return $names;
- }
-
- foreach ($items as $item) {
- $hosts = array_column($item['hosts'], 'name', 'hostid');
- $names[$item['itemid']] = $hosts[$item['hostid']].NAME_DELIMITER.$item['name'];
- }
-
- return $names;
- }
-
- public static function getThresholds(CWidgetFieldThresholds $field): CDiv {
- $thresholds_table = (new CTable())
- ->setId(sprintf(CWidgetFieldThresholds::THRESHOLDS_TABLE_ID, $field->getName()))
- ->addClass(ZBX_STYLE_TABLE_FORMS)
- ->setHeader([
- '',
- (new CColHeader(_('Threshold')))->setWidth('100%'),
- _('Action')
- ])
- ->setFooter(new CRow(
- new CCol(
- (new CSimpleButton(_('Add')))
- ->addClass(ZBX_STYLE_BTN_LINK)
- ->addClass('element-table-add')
- )
- ));
-
- foreach ($field->getValue() as $i => $threshold) {
- $thresholds_table->addRow(
- self::getThresholdsTemplate($field->getName(), $i, $threshold['color'], $threshold['threshold'])
- );
- }
-
- return (new CDiv($thresholds_table))
- ->addClass('table-forms-separator')
- ->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH);
- }
-
- public static function getThresholdsTemplate($name, $index = '#{rowNum}', $color = '#{color}',
- $threshold = '#{threshold}'): CRow {
- return (new CRow([
- (new CColor($name.'['.$index.'][color]', $color))->appendColorPickerJs(false),
- (new CTextBox($name.'['.$index.'][threshold]', $threshold, false))
- ->setWidth(ZBX_TEXTAREA_TINY_WIDTH)
- ->setAriaRequired(),
- (new CButton($name.'['.$index.'][remove]', _('Remove')))
- ->addClass(ZBX_STYLE_BTN_LINK)
- ->addClass('element-table-remove')
- ]))->addClass('form_row');
- }
-
- /**
- * @param CWidgetField $field
- *
- * @return int
- */
- public static function isAriaRequired($field) {
- return ($field->getFlags() & CWidgetField::FLAG_LABEL_ASTERISK);
- }
-}
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldCheckBox.php b/ui/include/classes/widgets/fields/CWidgetFieldCheckBox.php
index a12565c4d96..716a030382c 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldCheckBox.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldCheckBox.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -18,30 +18,35 @@
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
+
+namespace Zabbix\Widgets\Fields;
+
+use Zabbix\Widgets\CWidgetField;
+
class CWidgetFieldCheckBox extends CWidgetField {
- private $caption;
+ public const DEFAULT_VALUE = 0;
+
+ private ?string $caption;
/**
- * Check box widget field.
- *
- * @param string $name Field name in form.
- * @param string $label Label for the field in form.
- * @param string $caption Text after checkbox.
+ * @param string|null $caption Text after checkbox.
*/
- public function __construct($name, $label, $caption = null) {
+ public function __construct(string $name, string $label = null, string $caption = null) {
parent::__construct($name, $label);
- $this->setSaveType(ZBX_WIDGET_FIELD_TYPE_INT32);
- $this->setDefault(0);
$this->caption = $caption;
+
+ $this
+ ->setDefault(self::DEFAULT_VALUE)
+ ->setSaveType(ZBX_WIDGET_FIELD_TYPE_INT32);
}
- public function setValue($value) {
+ public function setValue($value): self {
return parent::setValue((int) $value);
}
- public function getCaption() {
+ public function getCaption(): ?string {
return $this->caption;
}
}
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldCheckBoxList.php b/ui/include/classes/widgets/fields/CWidgetFieldCheckBoxList.php
index 5fc1f3f0762..9127e262ac9 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldCheckBoxList.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldCheckBoxList.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,24 +19,39 @@
**/
+namespace Zabbix\Widgets\Fields;
+
+use Zabbix\Widgets\CWidgetField;
+
class CWidgetFieldCheckBoxList extends CWidgetField {
- public function __construct($name, $label) {
+ public const DEFAULT_VALUE = [];
+
+ private array $values;
+
+ public function __construct(string $name, string $label = null, array $values = []) {
parent::__construct($name, $label);
- $this->setSaveType(ZBX_WIDGET_FIELD_TYPE_INT32);
- $this->setDefault([]);
- $this->setValidationRules(['type' => API_INTS32]);
+ $this->values = $values;
+
+ $this
+ ->setDefault(self::DEFAULT_VALUE)
+ ->setSaveType(ZBX_WIDGET_FIELD_TYPE_INT32)
+ ->setValidationRules(['type' => API_INTS32]);
+ }
+
+ public function getValues(): array {
+ return $this->values;
}
- public function setValue($value) {
+ public function setValue($value): self {
$this->value = (array) $value;
return $this;
}
- public function setDefault($values) {
- $this->default = (array) $values;
+ public function setDefault($value): self {
+ $this->default = (array) $value;
return $this;
}
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldColor.php b/ui/include/classes/widgets/fields/CWidgetFieldColor.php
index b70d550631a..a0082e1c484 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldColor.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldColor.php
@@ -19,21 +19,37 @@
**/
-/**
- * Class for widget field color.
- */
+namespace Zabbix\Widgets\Fields;
+
+use Zabbix\Widgets\CWidgetField;
+
class CWidgetFieldColor extends CWidgetField {
+ public const DEFAULT_VALUE = '';
+
+ private bool $allow_inherited = false;
+
+ public function __construct(string $name, string $label = null) {
+ parent::__construct($name, $label);
+
+ $this
+ ->setDefault(self::DEFAULT_VALUE)
+ ->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR)
+ ->setValidationRules(['type' => API_COLOR, 'flags' => API_ALLOW_NULL]);
+ }
+
+ public function hasAllowInherited(): bool {
+ return $this->allow_inherited;
+ }
+
/**
- * Create color widget field.
- *
- * @param string $name Field name in form.
- * @param string $label Label for the field in form.
+ * Tell the Color picker whether to use Default (inherited) color feature or not.
*/
- public function __construct($name, $label) {
- parent::__construct($name, $label);
+ public function allowInherited($allow_inherited = true): self {
+ $this->allow_inherited = $allow_inherited;
- $this->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR);
- $this->setValidationRules(['type' => API_COLOR, 'flags' => API_ALLOW_NULL]);
+ return $this;
}
+
+
}
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldColumnsList.php b/ui/include/classes/widgets/fields/CWidgetFieldColumnsList.php
index f74c303dd67..dc6e43d5108 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldColumnsList.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldColumnsList.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2021 Zabbix SIA
@@ -19,92 +19,90 @@
**/
+namespace Zabbix\Widgets\Fields;
+
+use Zabbix\Widgets\CWidgetField;
+
class CWidgetFieldColumnsList extends CWidgetField {
// Source of value to display in column.
- const DATA_ITEM_VALUE = 1;
- const DATA_HOST_NAME = 2;
- const DATA_TEXT = 3;
+ public const DATA_ITEM_VALUE = 1;
+ public const DATA_HOST_NAME = 2;
+ public const DATA_TEXT = 3;
// Column value display type.
- const DISPLAY_AS_IS = 1;
- const DISPLAY_BAR = 2;
- const DISPLAY_INDICATORS = 3;
+ public const DISPLAY_AS_IS = 1;
+ public const DISPLAY_BAR = 2;
+ public const DISPLAY_INDICATORS = 3;
// Where to select data for aggregation function.
- const HISTORY_DATA_AUTO = 1;
- const HISTORY_DATA_HISTORY = 2;
- const HISTORY_DATA_TRENDS = 3;
+ public const HISTORY_DATA_AUTO = 1;
+ public const HISTORY_DATA_HISTORY = 2;
+ public const HISTORY_DATA_TRENDS = 3;
// Predefined colors for thresholds. Each next threshold takes next sequential value from palette.
- const THRESHOLDS_DEFAULT_COLOR_PALETTE = [
- 'FF465C','B0AF07','0EC9AC','524BBC','ED1248','D1E754','2AB5FF','385CC7','EC1594','BAE37D',
- '6AC8FF','EE2B29','3CA20D','6F4BBC','00A1FF','F3601B','1CAE59','45CFDB','894BBC','6D6D6D'
+ public const THRESHOLDS_DEFAULT_COLOR_PALETTE = [
+ 'FF465C', 'B0AF07', '0EC9AC', '524BBC', 'ED1248', 'D1E754', '2AB5FF', '385CC7', 'EC1594', 'BAE37D',
+ '6AC8FF', 'EE2B29', '3CA20D', '6F4BBC', '00A1FF', 'F3601B', '1CAE59', '45CFDB', '894BBC', '6D6D6D'
];
- public function __construct($name, $label) {
+ public function __construct(string $name, string $label = null) {
parent::__construct($name, $label);
- $this->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR);
- $this->setValidationRules(['type' => API_OBJECTS, 'fields' => [
- 'name' => ['type' => API_STRING_UTF8, 'default' => '', 'length' => 255],
- 'data' => ['type' => API_INT32, 'flags' => API_REQUIRED, 'in' => implode(',', [self::DATA_ITEM_VALUE, self::DATA_HOST_NAME, self::DATA_TEXT])],
- 'item' => ['type' => API_MULTIPLE, 'rules' => [
- ['if' => ['field' => 'data', 'in' => self::DATA_ITEM_VALUE],
- 'type' => API_STRING_UTF8, 'flags' => API_REQUIRED, 'length' => 255],
- ['else' => true,
- 'type' => API_STRING_UTF8]
- ]],
- 'timeshift' => ['type' => API_TIME_UNIT, 'in' => implode(':', [ZBX_MIN_TIMESHIFT, ZBX_MAX_TIMESHIFT])],
- 'aggregate_function' => ['type' => API_INT32, 'in' => implode(',', [AGGREGATE_NONE, AGGREGATE_MIN, AGGREGATE_MAX, AGGREGATE_AVG, AGGREGATE_COUNT, AGGREGATE_SUM, AGGREGATE_FIRST, AGGREGATE_LAST]), 'default' => AGGREGATE_NONE],
- 'aggregate_interval' => ['type' => API_MULTIPLE, 'rules' => [
- ['if' => ['field' => 'aggregate_function', 'in' => implode(',', [AGGREGATE_MIN, AGGREGATE_MAX, AGGREGATE_AVG, AGGREGATE_COUNT, AGGREGATE_SUM, AGGREGATE_FIRST, AGGREGATE_LAST])],
- 'type' => API_TIME_UNIT, 'flags' => API_REQUIRED | API_NOT_EMPTY | API_TIME_UNIT_WITH_YEAR, 'in' => implode(':', [1, ZBX_MAX_TIMESHIFT])],
- ['else' => true,
- 'type' => API_STRING_UTF8]
- ]],
- 'display' => ['type' => API_MULTIPLE, 'rules' => [
- ['if' => ['field' => 'data', 'in' => self::DATA_ITEM_VALUE],
- 'type' => API_INT32, 'default' => self::DISPLAY_AS_IS, 'in' => implode(',', [self::DISPLAY_AS_IS, self::DISPLAY_BAR, self::DISPLAY_INDICATORS])],
- ['else' => true,
- 'type' => API_INT32]
- ]],
- 'history' => ['type' => API_MULTIPLE, 'rules' => [
- ['if' => ['field' => 'data', 'in' => self::DATA_ITEM_VALUE],
- 'type' => API_INT32, 'default' => self::HISTORY_DATA_AUTO, 'in' => implode(',', [self::HISTORY_DATA_AUTO, self::HISTORY_DATA_HISTORY, self::HISTORY_DATA_TRENDS])],
- ['else' => true,
- 'type' => API_INT32]
- ]],
- 'base_color' => ['type' => API_COLOR],
- 'min' => ['type' => API_NUMERIC],
- 'max' => ['type' => API_NUMERIC],
- 'thresholds' => ['type' => API_OBJECTS, 'uniq' => [['threshold']], 'fields' => [
- 'color' => ['type' => API_COLOR],
- 'threshold' => ['type' => API_NUMERIC]
- ]],
- 'text' => ['type' => API_MULTIPLE, 'rules' => [
- ['if' => ['field' => 'data', 'in' => self::DATA_TEXT],
- 'type' => API_STRING_UTF8, 'flags' => API_REQUIRED | API_NOT_EMPTY, 'length' => 255],
- ['else' => true,
- 'type' => API_STRING_UTF8]
- ]]
- ]]);
+ $this
+ ->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR)
+ ->setValidationRules(['type' => API_OBJECTS, 'fields' => [
+ 'name' => ['type' => API_STRING_UTF8, 'default' => '', 'length' => 255],
+ 'data' => ['type' => API_INT32, 'flags' => API_REQUIRED, 'in' => implode(',', [self::DATA_ITEM_VALUE, self::DATA_HOST_NAME, self::DATA_TEXT])],
+ 'item' => ['type' => API_MULTIPLE, 'rules' => [
+ ['if' => ['field' => 'data', 'in' => self::DATA_ITEM_VALUE],
+ 'type' => API_STRING_UTF8, 'flags' => API_REQUIRED, 'length' => 255],
+ ['else' => true,
+ 'type' => API_STRING_UTF8]
+ ]],
+ 'timeshift' => ['type' => API_TIME_UNIT, 'in' => implode(':', [ZBX_MIN_TIMESHIFT, ZBX_MAX_TIMESHIFT])],
+ 'aggregate_function' => ['type' => API_INT32, 'in' => implode(',', [AGGREGATE_NONE, AGGREGATE_MIN, AGGREGATE_MAX, AGGREGATE_AVG, AGGREGATE_COUNT, AGGREGATE_SUM, AGGREGATE_FIRST, AGGREGATE_LAST]), 'default' => AGGREGATE_NONE],
+ 'aggregate_interval' => ['type' => API_MULTIPLE, 'rules' => [
+ ['if' => ['field' => 'aggregate_function', 'in' => implode(',', [AGGREGATE_MIN, AGGREGATE_MAX, AGGREGATE_AVG, AGGREGATE_COUNT, AGGREGATE_SUM, AGGREGATE_FIRST, AGGREGATE_LAST])],
+ 'type' => API_TIME_UNIT, 'flags' => API_REQUIRED | API_NOT_EMPTY | API_TIME_UNIT_WITH_YEAR, 'in' => implode(':', [1, ZBX_MAX_TIMESHIFT])],
+ ['else' => true,
+ 'type' => API_STRING_UTF8]
+ ]],
+ 'display' => ['type' => API_MULTIPLE, 'rules' => [
+ ['if' => ['field' => 'data', 'in' => self::DATA_ITEM_VALUE],
+ 'type' => API_INT32, 'default' => self::DISPLAY_AS_IS, 'in' => implode(',', [self::DISPLAY_AS_IS, self::DISPLAY_BAR, self::DISPLAY_INDICATORS])],
+ ['else' => true,
+ 'type' => API_INT32]
+ ]],
+ 'history' => ['type' => API_MULTIPLE, 'rules' => [
+ ['if' => ['field' => 'data', 'in' => self::DATA_ITEM_VALUE],
+ 'type' => API_INT32, 'default' => self::HISTORY_DATA_AUTO, 'in' => implode(',', [self::HISTORY_DATA_AUTO, self::HISTORY_DATA_HISTORY, self::HISTORY_DATA_TRENDS])],
+ ['else' => true,
+ 'type' => API_INT32]
+ ]],
+ 'base_color' => ['type' => API_COLOR],
+ 'min' => ['type' => API_NUMERIC],
+ 'max' => ['type' => API_NUMERIC],
+ 'thresholds' => ['type' => API_OBJECTS, 'uniq' => [['threshold']], 'fields' => [
+ 'color' => ['type' => API_COLOR],
+ 'threshold' => ['type' => API_NUMERIC]
+ ]],
+ 'text' => ['type' => API_MULTIPLE, 'rules' => [
+ ['if' => ['field' => 'data', 'in' => self::DATA_TEXT],
+ 'type' => API_STRING_UTF8, 'flags' => API_REQUIRED | API_NOT_EMPTY, 'length' => 255],
+ ['else' => true,
+ 'type' => API_STRING_UTF8]
+ ]]
+ ]]);
}
- public function setValue($value) {
+ public function setValue($value): self {
$this->value = (array) $value;
return $this;
}
- /**
- * Prepares array entry for widget field, ready to be passed to CDashboard API functions.
- * Reference is needed here to avoid array merging in CWidgetForm::fieldsToApi method. With large number of widget
- * fields it causes significant performance decrease.
- *
- * @param array $widget_fields reference to Array of widget fields.
- */
- public function toApi(array &$widget_fields = []) {
+ public function toApi(array &$widget_fields = []): void {
$fields = [
'name' => ZBX_WIDGET_FIELD_TYPE_STR,
'data' => ZBX_WIDGET_FIELD_TYPE_INT32,
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldDatePicker.php b/ui/include/classes/widgets/fields/CWidgetFieldDatePicker.php
index 881b9f22785..faf3f03bd60 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldDatePicker.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldDatePicker.php
@@ -19,43 +19,42 @@
**/
+namespace Zabbix\Widgets\Fields;
+
+use CAbsoluteTimeParser,
+ CParser,
+ CRelativeTimeParser,
+ DB;
+
+use Zabbix\Widgets\CWidgetField;
+
class CWidgetFieldDatePicker extends CWidgetField {
- /**
- * @var bool
- */
- private $is_date_only;
-
- /**
- * @param string $name
- * @param string $label
- * @param bool $is_date_only
- */
- public function __construct(string $name, string $label, bool $is_date_only) {
+ public const DEFAULT_VALUE = '';
+
+ private bool $is_date_only;
+
+ public function __construct(string $name, string $label = null, bool $is_date_only = false) {
parent::__construct($name, $label);
$this->is_date_only = $is_date_only;
- $this->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR);
- $this->setValidationRules([
- 'type' => API_STRING_UTF8,
- 'length' => DB::getFieldLength('widget_field', 'value_str')
- ]);
- $this->setDefault('');
+ $this
+ ->setDefault(self::DEFAULT_VALUE)
+ ->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR)
+ ->setValidationRules([
+ 'type' => API_STRING_UTF8,
+ 'length' => DB::getFieldLength('widget_field', 'value_str')
+ ]);
}
- /**
- * @param $flags
- *
- * @return CWidgetFieldDatePicker
- */
- public function setFlags($flags): self {
+ public function setFlags(int $flags): self {
parent::setFlags($flags);
$validation_rules = $this->getValidationRules();
$validation_rules['flags'] = $validation_rules['flags'] ?? 0x00;
- if (($flags & self::FLAG_NOT_EMPTY) != 0) {
+ if (($flags & self::FLAG_NOT_EMPTY) !== 0) {
$validation_rules['flags'] |= API_NOT_EMPTY;
}
else {
@@ -67,11 +66,6 @@ class CWidgetFieldDatePicker extends CWidgetField {
return $this;
}
- /**
- * @param bool $strict
- *
- * @return array
- */
public function validate(bool $strict = false): array {
if ($errors = parent::validate($strict)) {
return $errors;
@@ -80,7 +74,7 @@ class CWidgetFieldDatePicker extends CWidgetField {
$label = $this->full_name ?? $this->label ?? $this->name;
$value = $this->value ?? $this->default;
- if ($value === '' && ($this->getFlags() & self::FLAG_NOT_EMPTY) == 0) {
+ if ($value === '' && ($this->getFlags() & self::FLAG_NOT_EMPTY) === 0) {
$this->setValue('');
return [];
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldGraphDataSet.php b/ui/include/classes/widgets/fields/CWidgetFieldGraphDataSet.php
index b65418b16f5..1ff879942f8 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldGraphDataSet.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldGraphDataSet.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,61 +19,65 @@
**/
+namespace Zabbix\Widgets\Fields;
+
+use API,
+ CApiInputValidator;
+
+use Zabbix\Widgets\CWidgetField;
+
/**
* Class for data set widget field used in Graph widget configuration Data set tab.
*/
class CWidgetFieldGraphDataSet extends CWidgetField {
+ public const DEFAULT_VALUE = [];
+
+ public const DATASET_TYPE_SINGLE_ITEM = 0;
+ public const DATASET_TYPE_PATTERN_ITEM = 1;
+
// Predefined colors for data-sets in JSON format. Each next data set takes next sequential value from palette.
- const DEFAULT_COLOR_PALETTE = ["FF465C","B0AF07","0EC9AC","524BBC","ED1248","D1E754","2AB5FF","385CC7","EC1594","BAE37D","6AC8FF","EE2B29","3CA20D","6F4BBC","00A1FF","F3601B","1CAE59","45CFDB","894BBC","6D6D6D"];
+ public const DEFAULT_COLOR_PALETTE = [
+ 'FF465C', 'B0AF07', '0EC9AC', '524BBC', 'ED1248', 'D1E754', '2AB5FF', '385CC7', 'EC1594', 'BAE37D',
+ '6AC8FF', 'EE2B29', '3CA20D', '6F4BBC', '00A1FF', 'F3601B', '1CAE59', '45CFDB', '894BBC', '6D6D6D'
+ ];
// First color from the default color palette.
- const DEFAULT_COLOR = 'FF465C';
-
- /**
- * Create widget field for Data set selection.
- *
- * @param string $name Field name in form.
- * @param string $label Label for the field in form.
- */
- public function __construct($name, $label) {
+ private const DEFAULT_COLOR = 'FF465C';
+
+ public function __construct(string $name, string $label = null) {
parent::__construct($name, $label);
- $this->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR);
- $this->setValidationRules(['type' => API_OBJECTS, 'fields' => [
- 'dataset_type' => ['type' => API_INT32, 'in' => implode(',', [CWidgetHelper::DATASET_TYPE_SINGLE_ITEM, CWidgetHelper::DATASET_TYPE_PATTERN_ITEM])],
- 'hosts' => ['type' => API_STRINGS_UTF8, 'flags' => null],
- 'items' => ['type' => API_STRINGS_UTF8, 'flags' => null],
- 'itemids' => ['type' => API_IDS, 'flags' => null],
- 'color' => ['type' => API_COLOR, 'flags' => API_REQUIRED | API_NOT_EMPTY],
- 'type' => ['type' => API_INT32, 'flags' => API_REQUIRED, 'in' => implode(',', [SVG_GRAPH_TYPE_LINE, SVG_GRAPH_TYPE_POINTS, SVG_GRAPH_TYPE_STAIRCASE, SVG_GRAPH_TYPE_BAR])],
- 'stacked' => ['type' => API_INT32, 'flags' => API_REQUIRED, 'in' => implode(',', [SVG_GRAPH_STACKED_OFF, SVG_GRAPH_STACKED_ON])],
- 'width' => ['type' => API_INT32, 'in' => implode(',', range(0, 10))],
- 'pointsize' => ['type' => API_INT32, 'in' => implode(',', range(1, 10))],
- 'transparency' => ['type' => API_INT32, 'flags' => API_REQUIRED, 'in' => implode(',', range(0, 10))],
- 'fill' => ['type' => API_INT32, 'in' => implode(',', range(0, 10))],
- 'missingdatafunc' => ['type' => API_INT32, 'in' => implode(',', [SVG_GRAPH_MISSING_DATA_NONE, SVG_GRAPH_MISSING_DATA_CONNECTED, SVG_GRAPH_MISSING_DATA_TREAT_AS_ZERO, SVG_GRAPH_MISSING_DATA_LAST_KNOWN])],
- 'axisy' => ['type' => API_INT32, 'flags' => API_REQUIRED, 'in' => implode(',', [GRAPH_YAXIS_SIDE_LEFT, GRAPH_YAXIS_SIDE_RIGHT])],
- 'timeshift' => ['type' => API_TIME_UNIT, 'flags' => API_REQUIRED, 'in' => implode(':', [ZBX_MIN_TIMESHIFT, ZBX_MAX_TIMESHIFT])],
- 'aggregate_function' => ['type' => API_INT32, 'flags' => API_REQUIRED, 'in' => implode(',', [AGGREGATE_NONE, AGGREGATE_MIN, AGGREGATE_MAX, AGGREGATE_AVG, AGGREGATE_COUNT, AGGREGATE_SUM, AGGREGATE_FIRST, AGGREGATE_LAST])],
- 'aggregate_interval' => ['type' => API_MULTIPLE, 'rules' => [
- ['if' => ['field' => 'aggregate_function', 'in' => implode(',', [AGGREGATE_MIN, AGGREGATE_MAX, AGGREGATE_AVG, AGGREGATE_COUNT, AGGREGATE_SUM, AGGREGATE_FIRST, AGGREGATE_LAST])],
- 'type' => API_TIME_UNIT, 'flags' => API_REQUIRED | API_NOT_EMPTY | API_TIME_UNIT_WITH_YEAR, 'in' => implode(':', [1, ZBX_MAX_TIMESHIFT])],
- ['else' => true, 'type' => API_STRING_UTF8, 'in' => GRAPH_AGGREGATE_DEFAULT_INTERVAL]
- ]],
- 'aggregate_grouping' => ['type' => API_INT32, 'in' => implode(',', [GRAPH_AGGREGATE_BY_ITEM, GRAPH_AGGREGATE_BY_DATASET])],
- 'approximation' => ['type' => API_INT32, 'in' => implode(',', [APPROXIMATION_MIN, APPROXIMATION_AVG, APPROXIMATION_MAX, APPROXIMATION_ALL])]
- ]]);
-
- $this->setDefault([]);
+ $this
+ ->setDefault(self::DEFAULT_VALUE)
+ ->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR)
+ ->setValidationRules(['type' => API_OBJECTS, 'fields' => [
+ 'dataset_type' => ['type' => API_INT32, 'in' => implode(',', [self::DATASET_TYPE_SINGLE_ITEM, self::DATASET_TYPE_PATTERN_ITEM])],
+ 'hosts' => ['type' => API_STRINGS_UTF8, 'flags' => null],
+ 'items' => ['type' => API_STRINGS_UTF8, 'flags' => null],
+ 'itemids' => ['type' => API_IDS, 'flags' => null],
+ 'color' => ['type' => API_COLOR, 'flags' => API_REQUIRED | API_NOT_EMPTY],
+ 'type' => ['type' => API_INT32, 'flags' => API_REQUIRED, 'in' => implode(',', [SVG_GRAPH_TYPE_LINE, SVG_GRAPH_TYPE_POINTS, SVG_GRAPH_TYPE_STAIRCASE, SVG_GRAPH_TYPE_BAR])],
+ 'stacked' => ['type' => API_INT32, 'flags' => API_REQUIRED, 'in' => implode(',', [SVG_GRAPH_STACKED_OFF, SVG_GRAPH_STACKED_ON])],
+ 'width' => ['type' => API_INT32, 'in' => implode(',', range(0, 10))],
+ 'pointsize' => ['type' => API_INT32, 'in' => implode(',', range(1, 10))],
+ 'transparency' => ['type' => API_INT32, 'flags' => API_REQUIRED, 'in' => implode(',', range(0, 10))],
+ 'fill' => ['type' => API_INT32, 'in' => implode(',', range(0, 10))],
+ 'missingdatafunc' => ['type' => API_INT32, 'in' => implode(',', [SVG_GRAPH_MISSING_DATA_NONE, SVG_GRAPH_MISSING_DATA_CONNECTED, SVG_GRAPH_MISSING_DATA_TREAT_AS_ZERO, SVG_GRAPH_MISSING_DATA_LAST_KNOWN])],
+ 'axisy' => ['type' => API_INT32, 'flags' => API_REQUIRED, 'in' => implode(',', [GRAPH_YAXIS_SIDE_LEFT, GRAPH_YAXIS_SIDE_RIGHT])],
+ 'timeshift' => ['type' => API_TIME_UNIT, 'flags' => API_REQUIRED, 'in' => implode(':', [ZBX_MIN_TIMESHIFT, ZBX_MAX_TIMESHIFT])],
+ 'aggregate_function' => ['type' => API_INT32, 'flags' => API_REQUIRED, 'in' => implode(',', [AGGREGATE_NONE, AGGREGATE_MIN, AGGREGATE_MAX, AGGREGATE_AVG, AGGREGATE_COUNT, AGGREGATE_SUM, AGGREGATE_FIRST, AGGREGATE_LAST])],
+ 'aggregate_interval' => ['type' => API_MULTIPLE, 'rules' => [
+ ['if' => ['field' => 'aggregate_function', 'in' => implode(',', [AGGREGATE_MIN, AGGREGATE_MAX, AGGREGATE_AVG, AGGREGATE_COUNT, AGGREGATE_SUM, AGGREGATE_FIRST, AGGREGATE_LAST])],
+ 'type' => API_TIME_UNIT, 'flags' => API_REQUIRED | API_NOT_EMPTY | API_TIME_UNIT_WITH_YEAR, 'in' => implode(':', [1, ZBX_MAX_TIMESHIFT])],
+ ['else' => true, 'type' => API_STRING_UTF8, 'in' => GRAPH_AGGREGATE_DEFAULT_INTERVAL]
+ ]],
+ 'aggregate_grouping' => ['type' => API_INT32, 'in' => implode(',', [GRAPH_AGGREGATE_BY_ITEM, GRAPH_AGGREGATE_BY_DATASET])],
+ 'approximation' => ['type' => API_INT32, 'in' => implode(',', [APPROXIMATION_MIN, APPROXIMATION_AVG, APPROXIMATION_MAX, APPROXIMATION_ALL])]
+ ]]);
}
- /**
- * Set field values for the datasets.
- *
- * @return $this
- */
- public function setValue($value) {
+ public function setValue($value): self {
$data_sets = [];
foreach ((array) $value as $data_set) {
@@ -83,14 +87,7 @@ class CWidgetFieldGraphDataSet extends CWidgetField {
return parent::setValue($data_sets);
}
- /**
- * Set additional flags, which can be used in configuration form.
- *
- * @param int $flags
- *
- * @return $this
- */
- public function setFlags($flags) {
+ public function setFlags($flags): self {
parent::setFlags($flags);
if ($flags & self::FLAG_NOT_EMPTY) {
@@ -102,20 +99,15 @@ class CWidgetFieldGraphDataSet extends CWidgetField {
$this->setStrictValidationRules($strict_validation_rules);
}
else {
- $this->setStrictValidationRules(null);
+ $this->setStrictValidationRules();
}
return $this;
}
- /**
- * Default values filled in newly created data set or used as unspecified values.
- *
- * @return array
- */
- public static function getDefaults() {
+ public static function getDefaults(): array {
return [
- 'dataset_type' => CWidgetHelper::DATASET_TYPE_PATTERN_ITEM,
+ 'dataset_type' => self::DATASET_TYPE_PATTERN_ITEM,
'hosts' => [],
'items' => [],
'itemids' => [],
@@ -136,11 +128,29 @@ class CWidgetFieldGraphDataSet extends CWidgetField {
];
}
- /**
- * @param bool $strict Widget form submit validation?
- *
- * @return array Errors.
- */
+ public static function getItemNames(array $itemids): array {
+ $names = [];
+
+ $items = API::Item()->get([
+ 'output' => ['itemid', 'hostid', 'name'],
+ 'selectHosts' => ['hostid', 'name'],
+ 'webitems' => true,
+ 'itemids' => $itemids,
+ 'preservekeys' => true
+ ]);
+
+ if (!$items) {
+ return $names;
+ }
+
+ foreach ($items as $item) {
+ $hosts = array_column($item['hosts'], 'name', 'hostid');
+ $names[$item['itemid']] = $hosts[$item['hostid']].NAME_DELIMITER.$item['name'];
+ }
+
+ return $names;
+ }
+
public function validate(bool $strict = false): array {
$errors = [];
@@ -148,13 +158,14 @@ class CWidgetFieldGraphDataSet extends CWidgetField {
? $this->strict_validation_rules
: $this->validation_rules;
$validation_rules += $this->ex_validation_rules;
- $value = ($this->value === null) ? $this->default : $this->value;
+
+ $value = $this->value ?? $this->default;
if ($this->full_name !== null) {
$label = $this->full_name;
}
else {
- $label = ($this->label === null) ? $this->name : $this->label;
+ $label = $this->label ?? $this->name;
}
if ($strict) {
@@ -170,7 +181,7 @@ class CWidgetFieldGraphDataSet extends CWidgetField {
foreach ($value as $i => $data) {
$validation_rules_by_type = $validation_rules;
- if ($data['dataset_type'] == CWidgetHelper::DATASET_TYPE_SINGLE_ITEM) {
+ if ($data['dataset_type'] == self::DATASET_TYPE_SINGLE_ITEM) {
$validation_rules_by_type['fields']['itemids']['flags'] |= API_REQUIRED;
$validation_rules_by_type['fields']['color']['type'] = API_COLORS;
@@ -200,14 +211,7 @@ class CWidgetFieldGraphDataSet extends CWidgetField {
return $errors;
}
- /**
- * Prepares array entry for widget field, ready to be passed to CDashboard API functions.
- * Reference is needed here to avoid array merging in CWidgetForm::fieldsToApi method. With large number of widget
- * fields it causes significant performance decrease.
- *
- * @param array $widget_fields Reference to array of widget fields.
- */
- public function toApi(array &$widget_fields = []) {
+ public function toApi(array &$widget_fields = []): void {
$value = $this->getValue();
$dataset_fields = [
@@ -251,8 +255,8 @@ class CWidgetFieldGraphDataSet extends CWidgetField {
'value' => $itemid
];
}
- // Field "color" stored as array for dataset type CWidgetHelper::DATASET_TYPE_SINGLE_ITEM (0)
- if ($val['dataset_type'] == CWidgetHelper::DATASET_TYPE_SINGLE_ITEM) {
+ // Field "color" stored as array for dataset type DATASET_TYPE_SINGLE_ITEM (0)
+ if ($val['dataset_type'] == self::DATASET_TYPE_SINGLE_ITEM) {
foreach ($val['color'] as $num => $color) {
$widget_fields[] = [
'type' => ZBX_WIDGET_FIELD_TYPE_STR,
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldGraphOverride.php b/ui/include/classes/widgets/fields/CWidgetFieldGraphOverride.php
index f9a6a6ba166..ef9558b47bf 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldGraphOverride.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldGraphOverride.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,43 +19,43 @@
**/
+namespace Zabbix\Widgets\Fields;
+
+use Zabbix\Widgets\CWidgetField;
+
/**
* Class for override widget field used in Graph widget configuration overrides tab.
*/
class CWidgetFieldGraphOverride extends CWidgetField {
- /**
- * Create widget field for Graph Override selection.
- *
- * @param string $name Field name in form.
- * @param string $label Label for the field in form.
- */
- public function __construct($name, $label) {
+ public const DEFAULT_VALUE = [];
+
+ public function __construct(string $name, string $label = null) {
parent::__construct($name, $label);
- $this->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR);
- $this->setValidationRules(['type' => API_OBJECTS, 'fields' => [
- 'hosts' => ['type' => API_STRINGS_UTF8, 'flags' => API_REQUIRED],
- 'items' => ['type' => API_STRINGS_UTF8, 'flags' => API_REQUIRED],
- 'color' => ['type' => API_COLOR],
- 'type' => ['type' => API_INT32, 'in' => implode(',', [SVG_GRAPH_TYPE_LINE, SVG_GRAPH_TYPE_POINTS, SVG_GRAPH_TYPE_STAIRCASE, SVG_GRAPH_TYPE_BAR])],
- 'width' => ['type' => API_INT32, 'in' => implode(',', range(0, 10))],
- 'pointsize' => ['type' => API_INT32, 'in' => implode(',', range(1, 10))],
- 'transparency' => ['type' => API_INT32, 'in' => implode(',', range(0, 10))],
- 'fill' => ['type' => API_INT32, 'in' => implode(',', range(0, 10))],
- 'missingdatafunc' => ['type' => API_INT32, 'in' => implode(',', [SVG_GRAPH_MISSING_DATA_NONE, SVG_GRAPH_MISSING_DATA_CONNECTED, SVG_GRAPH_MISSING_DATA_TREAT_AS_ZERO])],
- 'axisy' => ['type' => API_INT32, 'in' => implode(',', [GRAPH_YAXIS_SIDE_LEFT, GRAPH_YAXIS_SIDE_RIGHT])],
- 'timeshift' => ['type' => API_TIME_UNIT, 'in' => implode(':', [ZBX_MIN_TIMESHIFT, ZBX_MAX_TIMESHIFT])]
- ]]);
- $this->setDefault([]);
+ $this
+ ->setDefault(self::DEFAULT_VALUE)
+ ->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR)
+ ->setValidationRules(['type' => API_OBJECTS, 'fields' => [
+ 'hosts' => ['type' => API_STRINGS_UTF8, 'flags' => API_REQUIRED],
+ 'items' => ['type' => API_STRINGS_UTF8, 'flags' => API_REQUIRED],
+ 'color' => ['type' => API_COLOR],
+ 'type' => ['type' => API_INT32, 'in' => implode(',', [SVG_GRAPH_TYPE_LINE, SVG_GRAPH_TYPE_POINTS, SVG_GRAPH_TYPE_STAIRCASE, SVG_GRAPH_TYPE_BAR])],
+ 'width' => ['type' => API_INT32, 'in' => implode(',', range(0, 10))],
+ 'pointsize' => ['type' => API_INT32, 'in' => implode(',', range(1, 10))],
+ 'transparency' => ['type' => API_INT32, 'in' => implode(',', range(0, 10))],
+ 'fill' => ['type' => API_INT32, 'in' => implode(',', range(0, 10))],
+ 'missingdatafunc' => ['type' => API_INT32, 'in' => implode(',', [SVG_GRAPH_MISSING_DATA_NONE, SVG_GRAPH_MISSING_DATA_CONNECTED, SVG_GRAPH_MISSING_DATA_TREAT_AS_ZERO])],
+ 'axisy' => ['type' => API_INT32, 'in' => implode(',', [GRAPH_YAXIS_SIDE_LEFT, GRAPH_YAXIS_SIDE_RIGHT])],
+ 'timeshift' => ['type' => API_TIME_UNIT, 'in' => implode(':', [ZBX_MIN_TIMESHIFT, ZBX_MAX_TIMESHIFT])]
+ ]]);
+ }
+
+ public function getOverrideOptions(): array {
+ return ['color', 'width', 'type', 'transparency', 'fill', 'pointsize', 'missingdatafunc', 'axisy', 'timeshift'];
}
- /**
- * Set field values for the overrides.
- *
- * @return $this
- */
- public function setValue($value) {
+ public function setValue($value): self {
$overrides = [];
foreach ((array) $value as $override) {
@@ -65,17 +65,17 @@ class CWidgetFieldGraphOverride extends CWidgetField {
return parent::setValue($overrides);
}
- /**
- * Set additional flags, which can be used in configuration form.
- *
- * @param int $flags
- *
- * @return $this
- */
- public function setFlags($flags) {
+ public static function getDefaults(): array {
+ return [
+ 'hosts' => [],
+ 'items' => []
+ ];
+ }
+
+ public function setFlags(int $flags): self {
parent::setFlags($flags);
- if ($flags & self::FLAG_NOT_EMPTY) {
+ if (($flags & self::FLAG_NOT_EMPTY) !== 0) {
$strict_validation_rules = $this->getValidationRules();
self::setValidationRuleFlag($strict_validation_rules['fields']['hosts'], API_NOT_EMPTY);
self::setValidationRuleFlag($strict_validation_rules['fields']['items'], API_NOT_EMPTY);
@@ -84,47 +84,21 @@ class CWidgetFieldGraphOverride extends CWidgetField {
$this->setStrictValidationRules($strict_validation_rules);
}
else {
- $this->setStrictValidationRules(null);
+ $this->setStrictValidationRules();
}
return $this;
}
- /**
- * Default values filled in newly created data set or used as unspecified values.
- *
- * @return array
- */
- public static function getDefaults() {
- return [
- 'hosts' => [],
- 'items' => []
- ];
- }
-
- /**
- * Returns array of supported override options.
- *
- * @return array
- */
- public static function getOverrideOptions() {
- return ['color', 'width', 'type', 'transparency', 'fill', 'pointsize', 'missingdatafunc', 'axisy', 'timeshift'];
- }
-
- /**
- * @param bool $strict
- *
- * @return array
- */
public function validate(bool $strict = false): array {
$errors = parent::validate($strict);
$value = $this->getValue();
- $label = ($this->label === null) ? $this->name : $this->label;
+ $label = $this->label ?? $this->name;
// Validate options.
if (!$errors && $strict) {
foreach ($value as $index => $overrides) {
- if (!array_intersect(self::getOverrideOptions(), array_keys($overrides))) {
+ if (!array_intersect($this->getOverrideOptions(), array_keys($overrides))) {
$errors[] = _s('Invalid parameter "%1$s": %2$s.', $label.'/'.($index + 1),
_('at least one override option must be specified')
);
@@ -136,14 +110,7 @@ class CWidgetFieldGraphOverride extends CWidgetField {
return $errors;
}
- /**
- * Prepares array entry for widget field, ready to be passed to CDashboard API functions.
- * Reference is needed here to avoid array merging in CWidgetForm::fieldsToApi method. With large number of widget
- * fields it causes significant performance decrease.
- *
- * @param array $widget_fields reference to Array of widget fields.
- */
- public function toApi(array &$widget_fields = []) {
+ public function toApi(array &$widget_fields = []): void {
$value = $this->getValue();
foreach ($value as $index => $val) {
@@ -163,7 +130,7 @@ class CWidgetFieldGraphOverride extends CWidgetField {
];
}
- foreach (self::getOverrideOptions() as $opt) {
+ foreach ($this->getOverrideOptions() as $opt) {
if (array_key_exists($opt, $val)) {
$widget_fields[] = [
'type' => ($opt === 'color' || $opt === 'timeshift')
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldHidden.php b/ui/include/classes/widgets/fields/CWidgetFieldHidden.php
deleted file mode 100644
index d1d8bf21b54..00000000000
--- a/ui/include/classes/widgets/fields/CWidgetFieldHidden.php
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-class CWidgetFieldHidden extends CWidgetField {
-
- /**
- * Hidden widget field. Will not be displayed for user. Can contain string, int or id type value.
- *
- * @param string $name field name in form
- * @param int $save_type ZBX_WIDGET_FIELD_TYPE_ constant. Defines how field will be saved in database.
- */
- public function __construct($name, $save_type) {
- parent::__construct($name, null);
-
- $this->setSaveType($save_type);
- }
-}
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldHostPatternSelect.php b/ui/include/classes/widgets/fields/CWidgetFieldHostPatternSelect.php
index d988491be0d..165cdcc2d20 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldHostPatternSelect.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldHostPatternSelect.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,36 +19,23 @@
**/
+namespace Zabbix\Widgets\Fields;
+
+use Zabbix\Widgets\CWidgetField;
+
class CWidgetFieldHostPatternSelect extends CWidgetField {
- private $placeholder;
+ public const DEFAULT_VALUE = [];
- /**
- * Textarea widget field.
- *
- * @param string $name field name in form
- * @param string $label label for the field in form
- */
- public function __construct($name, $label) {
+ public function __construct(string $name, string $label = null) {
parent::__construct($name, $label);
- $this->setDefault([]);
-
- /*
- * Set validation rules bypassing a parent::setSaveType to skip validation of length.
- * Save type is set in self::toApi method for each string field separately.
- */
- $this->setValidationRules(['type' => API_STRINGS_UTF8]);
+ $this
+ ->setDefault(self::DEFAULT_VALUE)
+ ->setValidationRules(['type' => API_STRINGS_UTF8]);
}
- /**
- * Prepares array entry for widget field, ready to be passed to CDashboard API functions.
- * Reference is needed here to avoid array merging in CWidgetForm::fieldsToApi method. With large number of widget
- * fields it causes significant performance decrease.
- *
- * @param array $widget_fields reference to array of widget fields.
- */
- public function toApi(array &$widget_fields = []) {
+ public function toApi(array &$widget_fields = []): void {
$value = $this->getValue();
if ($value !== $this->default) {
@@ -61,20 +48,4 @@ class CWidgetFieldHostPatternSelect extends CWidgetField {
}
}
}
-
- public function setPlaceholder($placeholder) {
- $this->placeholder = $placeholder;
-
- return $this;
- }
-
- public function getPlaceholder() {
- return $this->placeholder;
- }
-
- public function getJavascript() {
- $fieldid = zbx_formatDomId($this->getName().'[]');
-
- return 'jQuery("#'.$fieldid.'").multiSelect(jQuery("#'.$fieldid.'").data("params"));';
- }
}
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldIntegerBox.php b/ui/include/classes/widgets/fields/CWidgetFieldIntegerBox.php
index a246dfda320..32c12e43393 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldIntegerBox.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldIntegerBox.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,47 +19,33 @@
**/
-/**
- * Widget Field for integer values.
- */
-class CWidgetFieldIntegerBox extends CWidgetField {
+namespace Zabbix\Widgets\Fields;
- /**
- * Allowed min value
- *
- * @var int
- */
- private $min;
+use Zabbix\Widgets\CWidgetField;
- /**
- * Allowed max value
- *
- * @var int
- */
- private $max;
+class CWidgetFieldIntegerBox extends CWidgetField {
+
+ private int $max;
/**
- * A numeric box widget field.
- *
- * @param string $name field name in form
- * @param string $label label for the field in form
- * @param int $min minimal allowed value (this included)
- * @param int $max maximal allowed value (this included)
+ * @param int $min Minimal allowed value.
+ * @param int $max Maximal allowed value.
*/
- public function __construct($name, $label, $min = 0, $max = ZBX_MAX_INT32) {
+ public function __construct(string $name, string $label = null, int $min = 0, int $max = ZBX_MAX_INT32) {
parent::__construct($name, $label);
- $this->setSaveType(ZBX_WIDGET_FIELD_TYPE_INT32);
- $this->min = $min;
$this->max = $max;
- $this->setExValidationRules(['in' => $this->min.':'.$this->max]);
- }
- public function getMaxLength() {
- return strlen((string) $this->max);
+ $this
+ ->setSaveType(ZBX_WIDGET_FIELD_TYPE_INT32)
+ ->setExValidationRules(['in' => $min.':'.$this->max]);
}
- public function setValue($value) {
+ public function setValue($value): self {
return parent::setValue((int) $value);
}
+
+ public function getMaxLength(): int {
+ return strlen((string) $this->max);
+ }
}
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldLatLng.php b/ui/include/classes/widgets/fields/CWidgetFieldLatLng.php
index 798a8a21d92..60494f70cf4 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldLatLng.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldLatLng.php
@@ -19,39 +19,23 @@
**/
-class CWidgetFieldLatLng extends CWidgetField {
+namespace Zabbix\Widgets\Fields;
- /**
- * @var string
- */
- private $placeholder;
+use Zabbix\Widgets\CWidgetField;
- /**
- * @var int
- */
- private $width;
+class CWidgetFieldLatLng extends CWidgetField {
+
+ public const DEFAULT_VALUE = '';
/**
* Latitude, longitude and zoom level input text box widget field.
- *
- * @param string $name field name in form
- * @param string $label label for the field in form
*/
- public function __construct($name, $label) {
+ public function __construct(string $name, string $label = null) {
parent::__construct($name, $label);
- $this->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR);
- $this->setValidationRules(['type' => API_LAT_LNG_ZOOM, 'length' => 255]);
- $this->placeholder = '40.6892494,-74.0466891';
- $this->width = ZBX_TEXTAREA_MEDIUM_WIDTH;
- $this->setDefault('');
- }
-
- public function getPlaceholder() {
- return $this->placeholder;
- }
-
- public function getWidth() {
- return $this->width;
+ $this
+ ->setDefault(self::DEFAULT_VALUE)
+ ->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR)
+ ->setValidationRules(['type' => API_LAT_LNG_ZOOM, 'length' => 255]);
}
}
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldMsHost.php b/ui/include/classes/widgets/fields/CWidgetFieldMsHost.php
deleted file mode 100644
index d168170ee68..00000000000
--- a/ui/include/classes/widgets/fields/CWidgetFieldMsHost.php
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-class CWidgetFieldMsHost extends CWidgetFieldMs {
-
- /**
- * ID for Host group Multiselect element used to prefill Application PoPup Host group filter.
- * Analog for multiselect filter_preselect_fields['hostgroups'] property.
- *
- * @var string (nullable) ID for Multiselect element.
- */
- protected $filter_preselect;
-
- /**
- * Create widget field for Host selection
- *
- * @param string $name field name in form
- * @param string $label label for the field in form
- */
- public function __construct(string $name, string $label) {
- parent::__construct($name, $label);
-
- $this->setSaveType(ZBX_WIDGET_FIELD_TYPE_HOST);
- }
-
- public function setFilterPreselect(string $id) {
- $this->filter_preselect = $id;
- return $this;
- }
-
- public function getFilterPreselect() {
- return $this->filter_preselect;
- }
-}
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldMs.php b/ui/include/classes/widgets/fields/CWidgetFieldMultiSelect.php
index 5dc9946c683..45984fa57e4 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldMs.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldMultiSelect.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,106 +19,72 @@
**/
-class CWidgetFieldMs extends CWidgetField {
+namespace Zabbix\Widgets\Fields;
- /**
- * Is selecting multiple objects or a single one?
- *
- * @var bool
- */
- protected $multiple = true;
+use Zabbix\Widgets\CWidgetField;
- /**
- * Additional filter parameters used for data selection.
- *
- * @var array
- */
- protected $filter_parameters = [];
+abstract class CWidgetFieldMultiSelect extends CWidgetField {
- /**
- * Multiselect widget field.
- * Will create text box field with select button, that will allow to select specified resource.
- *
- * @param string $name Field name in form.
- * @param string $label Label for the field in form.
- */
- public function __construct($name, $label) {
+ // Is selecting multiple objects or a single one?
+ private bool $is_multiple = true;
+
+ // Additional filter parameters used for data selection.
+ protected array $filter_parameters = [];
+
+ public function __construct(string $name, string $label = null) {
parent::__construct($name, $label);
$this->setDefault([]);
}
- /**
- * Set additional validation flags.
- *
- * @param int $flags
- *
- * @return CWidgetFieldMs
- */
- public function setFlags($flags) {
+ public function setValue($value): self {
+ $this->value = (array) $value;
+
+ return $this;
+ }
+
+ public function setFlags(int $flags): self {
parent::setFlags($flags);
- if ($flags & self::FLAG_NOT_EMPTY) {
+ if (($flags & self::FLAG_NOT_EMPTY) !== 0) {
$strict_validation_rules = $this->getValidationRules();
self::setValidationRuleFlag($strict_validation_rules, API_NOT_EMPTY);
$this->setStrictValidationRules($strict_validation_rules);
}
else {
- $this->setStrictValidationRules(null);
+ $this->setStrictValidationRules();
}
return $this;
}
/**
- * @return CWidgetFieldMs
- */
- public function setValue($value) {
- $this->value = (array) $value;
-
- return $this;
- }
-
- /**
* Is selecting multiple values or a single value?
- *
- * @return bool
*/
- public function isMultiple() {
- return $this->multiple;
+ public function isMultiple(): bool {
+ return $this->is_multiple;
}
/**
* Set field to multiple objects mode.
- *
- * @param bool $multiple
- *
- * @return CWidgetFieldMs
*/
- public function setMultiple($multiple) {
- $this->multiple = $multiple;
+ public function setMultiple(bool $is_multiple = true): self {
+ $this->is_multiple = $is_multiple;
return $this;
}
/**
* Get additional filter parameters.
- *
- * @return array
*/
- public function getFilterParameters() {
+ public function getFilterParameters(): array {
return $this->filter_parameters;
}
/**
* Set an additional filter parameter for data selection.
- *
- * @param string $name
- * @param mixed $value
- *
- * @return CWidgetFieldMs
*/
- public function setFilterParameter($name, $value) {
+ public function setFilterParameter(string $name, $value): self {
$this->filter_parameters[$name] = $value;
return $this;
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldMsGraph.php b/ui/include/classes/widgets/fields/CWidgetFieldMultiSelectGraph.php
index 2904ebe8c77..756ed0be4e2 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldMsGraph.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldMultiSelectGraph.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,22 +19,20 @@
**/
-class CWidgetFieldMsGraph extends CWidgetFieldMs {
+namespace Zabbix\Widgets\Fields;
- public function __construct($name, $label, $hostid = null) {
+class CWidgetFieldMultiSelectGraph extends CWidgetFieldMultiSelect {
+
+ public function __construct(string $name, string $label = null, $hostid = null) {
parent::__construct($name, $label);
$this->setSaveType(ZBX_WIDGET_FIELD_TYPE_GRAPH);
if ($hostid === null) {
- $this->filter_parameters += [
- 'real_hosts' => true
- ];
+ $this->setFilterParameter('real_hosts', true);
}
else {
- $this->filter_parameters += [
- 'hostid' => $hostid
- ];
+ $this->setFilterParameter('hostid', $hostid);
}
}
}
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldMsGraphPrototype.php b/ui/include/classes/widgets/fields/CWidgetFieldMultiSelectGraphPrototype.php
index 10e63026729..1d5736c8e12 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldMsGraphPrototype.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldMultiSelectGraphPrototype.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,22 +19,20 @@
**/
-class CWidgetFieldMsGraphPrototype extends CWidgetFieldMs {
+namespace Zabbix\Widgets\Fields;
- public function __construct($name, $label, $hostid = null) {
+class CWidgetFieldMultiSelectGraphPrototype extends CWidgetFieldMultiSelect {
+
+ public function __construct(string $name, string $label = null, $hostid = null) {
parent::__construct($name, $label);
$this->setSaveType(ZBX_WIDGET_FIELD_TYPE_GRAPH_PROTOTYPE);
if ($hostid === null) {
- $this->filter_parameters += [
- 'real_hosts' => true
- ];
+ $this->setFilterParameter('real_hosts', true);
}
else {
- $this->filter_parameters += [
- 'hostid' => $hostid
- ];
+ $this->setFilterParameter('hostid', $hostid);
}
}
}
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldMsGroup.php b/ui/include/classes/widgets/fields/CWidgetFieldMultiSelectGroup.php
index dae91733aac..9c9e7743d34 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldMsGroup.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldMultiSelectGroup.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,9 +19,11 @@
**/
-class CWidgetFieldMsGroup extends CWidgetFieldMs {
+namespace Zabbix\Widgets\Fields;
- public function __construct($name, $label) {
+class CWidgetFieldMultiSelectGroup extends CWidgetFieldMultiSelect {
+
+ public function __construct(string $name, string $label = null) {
parent::__construct($name, $label);
$this->setSaveType(ZBX_WIDGET_FIELD_TYPE_GROUP);
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldMultiSelectHost.php b/ui/include/classes/widgets/fields/CWidgetFieldMultiSelectHost.php
new file mode 100644
index 00000000000..65987d9253a
--- /dev/null
+++ b/ui/include/classes/widgets/fields/CWidgetFieldMultiSelectHost.php
@@ -0,0 +1,31 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Zabbix\Widgets\Fields;
+
+class CWidgetFieldMultiSelectHost extends CWidgetFieldMultiSelect {
+
+ public function __construct(string $name, string $label = null) {
+ parent::__construct($name, $label);
+
+ $this->setSaveType(ZBX_WIDGET_FIELD_TYPE_HOST);
+ }
+}
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldMsItem.php b/ui/include/classes/widgets/fields/CWidgetFieldMultiSelectItem.php
index 9ba02f81d27..ad25de8d77f 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldMsItem.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldMultiSelectItem.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,22 +19,20 @@
**/
-class CWidgetFieldMsItem extends CWidgetFieldMs {
+namespace Zabbix\Widgets\Fields;
- public function __construct($name, $label, $hostid = null) {
+class CWidgetFieldMultiSelectItem extends CWidgetFieldMultiSelect {
+
+ public function __construct(string $name, string $label = null, $hostid = null) {
parent::__construct($name, $label);
$this->setSaveType(ZBX_WIDGET_FIELD_TYPE_ITEM);
if ($hostid === null) {
- $this->filter_parameters += [
- 'real_hosts' => true
- ];
+ $this->setFilterParameter('real_hosts', true);
}
else {
- $this->filter_parameters += [
- 'hostid' => $hostid
- ];
+ $this->setFilterParameter('hostid', $hostid);
}
}
}
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldMsItemPrototype.php b/ui/include/classes/widgets/fields/CWidgetFieldMultiSelectItemPrototype.php
index c380af8124a..d29b5435020 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldMsItemPrototype.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldMultiSelectItemPrototype.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,22 +19,20 @@
**/
-class CWidgetFieldMsItemPrototype extends CWidgetFieldMs {
+namespace Zabbix\Widgets\Fields;
- public function __construct($name, $label, $hostid = null) {
+class CWidgetFieldMultiSelectItemPrototype extends CWidgetFieldMultiSelect {
+
+ public function __construct(string $name, string $label = null, $hostid = null) {
parent::__construct($name, $label);
$this->setSaveType(ZBX_WIDGET_FIELD_TYPE_ITEM_PROTOTYPE);
if ($hostid === null) {
- $this->filter_parameters += [
- 'real_hosts' => true
- ];
+ $this->setFilterParameter('real_hosts', true);
}
else {
- $this->filter_parameters += [
- 'hostid' => $hostid
- ];
+ $this->setFilterParameter('hostid', $hostid);
}
}
}
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldMsService.php b/ui/include/classes/widgets/fields/CWidgetFieldMultiSelectService.php
index ab88ce01186..7d7ed555588 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldMsService.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldMultiSelectService.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,15 +19,11 @@
**/
-class CWidgetFieldMsService extends CWidgetFieldMs {
+namespace Zabbix\Widgets\Fields;
- /**
- * Create widget field for Service selection
- *
- * @param string $name field name in form
- * @param string $label label for the field in form
- */
- public function __construct($name, $label) {
+class CWidgetFieldMultiSelectService extends CWidgetFieldMultiSelect {
+
+ public function __construct(string $name, string $label = null) {
parent::__construct($name, $label);
$this->setSaveType(ZBX_WIDGET_FIELD_TYPE_SERVICE);
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldMsSla.php b/ui/include/classes/widgets/fields/CWidgetFieldMultiSelectSla.php
index 0e77590975a..55cc0dd2667 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldMsSla.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldMultiSelectSla.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,15 +19,11 @@
**/
-class CWidgetFieldMsSla extends CWidgetFieldMs {
+namespace Zabbix\Widgets\Fields;
- /**
- * Create widget field for SLA selection
- *
- * @param string $name field name in form
- * @param string $label label for the field in form
- */
- public function __construct($name, $label) {
+class CWidgetFieldMultiSelectSla extends CWidgetFieldMultiSelect {
+
+ public function __construct(string $name, string $label = null) {
parent::__construct($name, $label);
$this->setSaveType(ZBX_WIDGET_FIELD_TYPE_SLA);
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldNavTree.php b/ui/include/classes/widgets/fields/CWidgetFieldNavTree.php
index 1fc163f4b9a..6ff384232e3 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldNavTree.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldNavTree.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,41 +19,45 @@
**/
+namespace Zabbix\Widgets\Fields;
+
+use Zabbix\Widgets\CWidgetField;
+
class CWidgetFieldNavTree extends CWidgetField {
- /**
- * Create widget field for Tags selection.
- *
- * @param string $name Field name in form.
- * @param string $label Label for the field in form.
- */
- public function __construct($name, $label) {
+ public const DEFAULT_VALUE = [];
+
+ public function __construct(string $name, string $label = null) {
parent::__construct($name, $label);
- $this->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR);
- $this->setValidationRules(['type' => API_OBJECTS, 'flags' => API_PRESERVE_KEYS, 'fields' => [
- 'name' => ['type' => API_STRING_UTF8, 'flags' => API_REQUIRED | API_NOT_EMPTY, 'length' => 255],
- 'order' => ['type' => API_INT32, 'in' => '1:'.ZBX_MAX_INT32, 'default' => 1],
- 'parent' => ['type' => API_INT32, 'in' => '0:'.ZBX_MAX_INT32, 'default' => 0],
- 'sysmapid' => ['type' => API_ID, 'default' => '0']
- ]]);
- $this->setDefault([]);
+ $this
+ ->setDefault(self::DEFAULT_VALUE)
+ ->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR)
+ ->setValidationRules(['type' => API_OBJECTS, 'flags' => API_PRESERVE_KEYS, 'fields' => [
+ 'name' => ['type' => API_STRING_UTF8, 'flags' => API_REQUIRED | API_NOT_EMPTY, 'length' => 255],
+ 'order' => ['type' => API_INT32, 'in' => '1:'.ZBX_MAX_INT32, 'default' => 1],
+ 'parent' => ['type' => API_INT32, 'in' => '0:'.ZBX_MAX_INT32, 'default' => 0],
+ 'sysmapid' => ['type' => API_ID, 'default' => '0']
+ ]]);
}
- public function setValue($value) {
+ public function setValue($value): self {
$this->value = (array) $value;
return $this;
}
- /**
- * Prepares array entry for widget field, ready to be passed to CDashboard API functions.
- * Reference is needed here to avoid array merging in CWidgetForm::fieldsToApi method. With large number of widget
- * fields it causes significant performance decrease.
- *
- * @param array $widget_fields reference to Array of widget fields.
- */
- public function toApi(array &$widget_fields = []) {
+ public function validate(bool $strict = false): array {
+ $errors = parent::validate($strict);
+
+ if (!$errors) {
+ $this->setValue(self::validateNavTree($this->getValue(), $errors));
+ }
+
+ return $errors;
+ }
+
+ public function toApi(array &$widget_fields = []): void {
$value = $this->getValue();
foreach ($value as $index => $val) {
@@ -96,13 +100,8 @@ class CWidgetFieldNavTree extends CWidgetField {
/**
* Check and fix the tree of the maps.
- *
- * @param array $navtree_items
- * @param string $navtree_items[<id>]['parent']
- *
- * @return array
*/
- static private function validateNavTree(array $navtree_items, array &$errors) {
+ private static function validateNavTree(array $navtree_items, array &$errors): array {
// Check for incorrect parent IDs.
foreach ($navtree_items as $fieldid => &$navtree_item) {
if ($navtree_item['parent'] != 0 && !array_key_exists($navtree_item['parent'], $navtree_items)) {
@@ -115,7 +114,7 @@ class CWidgetFieldNavTree extends CWidgetField {
unset($navtree_item);
// Find and fix circular dependencies.
- foreach ($navtree_items as $fieldid => $navtree_item) {
+ foreach ($navtree_items as $navtree_item) {
$parentid = $navtree_item['parent'];
$parentids = [$parentid => true];
@@ -133,19 +132,4 @@ class CWidgetFieldNavTree extends CWidgetField {
return $navtree_items;
}
-
- /**
- * @param bool $strict
- *
- * @return array
- */
- public function validate(bool $strict = false): array {
- $errors = parent::validate($strict);
-
- if (!$errors) {
- $this->setValue(self::validateNavTree($this->getValue(), $errors));
- }
-
- return $errors;
- }
}
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldNumericBox.php b/ui/include/classes/widgets/fields/CWidgetFieldNumericBox.php
index 4981289b46f..9aa6e68dcf6 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldNumericBox.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldNumericBox.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,50 +19,24 @@
**/
-/**
- * Widget Field for numeric data.
- */
+namespace Zabbix\Widgets\Fields;
+
+use Zabbix\Widgets\CWidgetField;
+
class CWidgetFieldNumericBox extends CWidgetField {
- private $placeholder;
- private $width;
+ public const DEFAULT_VALUE = '';
/**
* A numeric box widget field.
* Supported signed decimal values with suffix (KMGTsmhdw).
- *
- * @param string $name field name in form
- * @param string $label label for the field in form
*/
- public function __construct($name, $label) {
+ public function __construct(string $name, string $label = null) {
parent::__construct($name, $label);
- $this->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR);
- $this->setValidationRules(['type' => API_NUMERIC, 'length' => 255]);
- $this->setDefault('');
- }
-
- public function getMaxLength() {
- return strlen((string) $this->max);
- }
-
- public function setPlaceholder($placeholder) {
- $this->placeholder = $placeholder;
-
- return $this;
- }
-
- public function getPlaceholder() {
- return $this->placeholder;
- }
-
- public function setWidth($width) {
- $this->width = $width;
-
- return $this;
- }
-
- public function getWidth() {
- return $this->width;
+ $this
+ ->setDefault(self::DEFAULT_VALUE)
+ ->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR)
+ ->setValidationRules(['type' => API_NUMERIC, 'length' => 255]);
}
}
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldRadioButtonList.php b/ui/include/classes/widgets/fields/CWidgetFieldRadioButtonList.php
index 4764301cf9b..6da247c53e7 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldRadioButtonList.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldRadioButtonList.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,41 +19,34 @@
**/
+namespace Zabbix\Widgets\Fields;
+
+use Zabbix\Widgets\CWidgetField;
+
class CWidgetFieldRadioButtonList extends CWidgetField {
- private $values;
- private $modern = false;
+ private array $values;
/**
* Radio button widget field. Can use both, string and integer type keys.
*
- * @param string $name field name in form
- * @param string $label label for the field in form
- * @param array $values key/value pairs of radio button values. Key - saved in DB. Value - visible to user.
+ * @param array $values key/value pairs of radio button values. Key - saved in DB. Value - visible to user.
*/
- public function __construct($name, $label, $values) {
+ public function __construct(string $name, string $label = null, array $values = []) {
parent::__construct($name, $label);
- $this->setSaveType(ZBX_WIDGET_FIELD_TYPE_INT32);
$this->values = $values;
- $this->setExValidationRules(['in' => implode(',', array_keys($this->values))]);
- }
-
- public function setValue($value) {
- return parent::setValue((int) $value);
- }
-
- public function setModern($modern) {
- $this->modern = $modern;
- return $this;
+ $this
+ ->setSaveType(ZBX_WIDGET_FIELD_TYPE_INT32)
+ ->setExValidationRules(['in' => implode(',', array_keys($this->values))]);
}
- public function getModern() {
- return $this->modern;
+ public function getValues(): array {
+ return $this->values;
}
- public function getValues() {
- return $this->values;
+ public function setValue($value): self {
+ return parent::setValue((int) $value);
}
}
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldRangeControl.php b/ui/include/classes/widgets/fields/CWidgetFieldRangeControl.php
index 43246743f36..8e92698fac2 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldRangeControl.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldRangeControl.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,65 +19,48 @@
**/
-/**
- * Widget Field for numeric box
- */
-class CWidgetFieldRangeControl extends CWidgetField {
+namespace Zabbix\Widgets\Fields;
- /**
- * Allowed min value
- *
- * @var int
- */
- private $min;
+use Zabbix\Widgets\CWidgetField;
- /**
- * Allowed max value
- *
- * @var int
- */
- private $max;
+class CWidgetFieldRangeControl extends CWidgetField {
- /**
- * Step value
- *
- * @var int
- */
- private $step;
+ private int $min;
+ private int $max;
+ private int $step;
/**
- * A numeric box widget field.
- *
- * @param string $name field name in form
- * @param string $label label for the field in form
- * @param int $min minimal allowed value (this included)
- * @param int $max maximal allowed value (this included)
- * @param int $step step value
+ * @param int $min Minimal allowed value.
+ * @param int $max Maximal allowed value.
*/
- public function __construct($name, $label, $min = 0, $max = ZBX_MAX_INT32, $step = 1) {
+ public function __construct(string $name, string $label = null, int $min = 0, int $max = ZBX_MAX_INT32,
+ int $step = 1) {
parent::__construct($name, $label);
- $this->setSaveType(ZBX_WIDGET_FIELD_TYPE_INT32);
$this->min = $min;
$this->max = $max;
$this->step = $step;
- $this->setExValidationRules(['in' => $this->min.':'.$this->max]);
+
+ $this
+ ->setSaveType(ZBX_WIDGET_FIELD_TYPE_INT32)
+ ->setExValidationRules(['in' => $this->min.':'.$this->max]);
}
- public function setValue($value) {
+ public function setValue($value): self {
$this->value = (int) $value;
+
return $this;
}
- public function getMin() {
+ public function getMin(): int {
return $this->min;
}
- public function getMax() {
+ public function getMax(): int {
return $this->max;
}
- public function getStep() {
+ public function getStep(): int {
return $this->step;
}
}
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldReference.php b/ui/include/classes/widgets/fields/CWidgetFieldReference.php
index 0505d00e490..a4445c68857 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldReference.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldReference.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,10 +19,16 @@
**/
+namespace Zabbix\Widgets\Fields;
+
+use Zabbix\Widgets\CWidgetField;
+
class CWidgetFieldReference extends CWidgetField {
+ public const DEFAULT_VALUE = '';
+
// This field name is reserved by Zabbix for this particular use case. See comments below.
- const FIELD_NAME = 'reference';
+ public const FIELD_NAME = 'reference';
/**
* Reference widget field. If added to widget, will generate unique value across the dashboard
@@ -33,19 +39,17 @@ class CWidgetFieldReference extends CWidgetField {
* All reference fields for all widgets on dashboard should share the same name.
* It is needed to make possible search if value is not taken by some other widget in same dashboard.
*/
- parent::__construct(self::FIELD_NAME, null);
+ parent::__construct(self::FIELD_NAME);
- $this->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR);
+ $this
+ ->setDefault(self::DEFAULT_VALUE)
+ ->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR);
}
/**
- * Set field value.
- *
* @param string $value Reference value. Only numeric characters allowed.
- *
- * @return CWidgetFieldReference
*/
- public function setValue($value) {
+ public function setValue($value): self {
if ($value === '' || ctype_alnum($value)) {
$this->value = $value;
}
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldSelect.php b/ui/include/classes/widgets/fields/CWidgetFieldSelect.php
index c9380869366..055a64ad840 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldSelect.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldSelect.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,38 +19,37 @@
**/
+namespace Zabbix\Widgets\Fields;
+
+use Zabbix\Widgets\CWidgetField;
+
class CWidgetFieldSelect extends CWidgetField {
- private $values;
+ public const DEFAULT_VALUE = null;
+
+ private array $values;
/**
* CSelect widget field. Can use both, string and integer type keys.
*
- * @param string $name Field name in form
- * @param string $label Label for the field in form
* @param array $values Key/value pairs of select option values. Key - saved in DB. Value - visible to user.
*/
- public function __construct($name, $label, $values) {
+ public function __construct(string $name, string $label, array $values) {
parent::__construct($name, $label);
- $this->setSaveType(ZBX_WIDGET_FIELD_TYPE_INT32);
$this->values = $values;
- $this->setExValidationRules(['in' => implode(',', array_keys($this->values))]);
+
+ $this
+ ->setDefault(self::DEFAULT_VALUE)
+ ->setSaveType(ZBX_WIDGET_FIELD_TYPE_INT32)
+ ->setExValidationRules(['in' => implode(',', array_keys($this->values))]);
}
- public function setValue($value) {
+ public function setValue($value): self {
return parent::setValue((int) $value);
}
- public function getValues() {
+ public function getValues(): array {
return $this->values;
}
-
- public function setAction($action) {
- throw new RuntimeException(sprintf('Method is not implemented: "%s".', __METHOD__));
- }
-
- public function getAction() {
- throw new RuntimeException(sprintf('Method is not implemented: "%s".', __METHOD__));
- }
}
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldSelectResource.php b/ui/include/classes/widgets/fields/CWidgetFieldSelectResource.php
index 06c7bec9ad6..1cc86819715 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldSelectResource.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldSelectResource.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,78 +19,80 @@
**/
+namespace Zabbix\Widgets\Fields;
+
+use Zabbix\Widgets\CWidgetField;
+
class CWidgetFieldSelectResource extends CWidgetField {
- protected $srctbl;
- protected $srcfld1;
- protected $srcfld2;
- protected $dstfld1;
- protected $dstfld2;
- protected $resource_type;
+ public const RESOURCE_TYPE_SYSMAP = 1;
+
+ public const DEFAULT_VALUE = '0';
+
+ private string $resource_type;
+
+ private array $popup_options = [
+ 'srctbl' => null,
+ 'srcfld1' => null,
+ 'srcfld2' => null,
+ 'dstfld1' => null,
+ 'dstfld2' => null,
+ 'dstfrm' => null
+ ];
/**
* Select resource type widget field. Will create text box field with select button,
- * that will allow to select specified resource.
- *
- * @param string $name field name in form
- * @param string $label label for the field in form
- * @param int $resource_type WIDGET_FIELD_SELECT_RES_ constant.
+ * that will allow selecting specified resource.
*/
- public function __construct($name, $label, $resource_type) {
+ public function __construct(string $name, string $label = null) {
parent::__construct($name, $label);
+ $this->popup_options = array_merge($this->popup_options, [
+ 'dstfld1' => $this->name,
+ 'dstfld2' => $this->name.'_caption'
+ ]);
+
+ $this->setDefault(self::DEFAULT_VALUE);
+ }
+
+ public function getResourceType(): int {
+ return $this->resource_type;
+ }
+
+ public function setResourceType(int $resource_type): self {
$this->resource_type = $resource_type;
- switch ($resource_type) {
- case WIDGET_FIELD_SELECT_RES_SYSMAP:
- $this->setSaveType(ZBX_WIDGET_FIELD_TYPE_MAP);
- $this->srctbl = 'sysmaps';
- $this->srcfld1 = 'sysmapid';
- $this->srcfld2 = 'name';
- break;
+ if ($this->resource_type == self::RESOURCE_TYPE_SYSMAP) {
+ $this->setSaveType(ZBX_WIDGET_FIELD_TYPE_MAP);
+
+ $this->popup_options = array_merge($this->popup_options, [
+ 'srctbl' => 'sysmaps',
+ 'srcfld1' => 'sysmapid',
+ 'srcfld2' => 'name'
+ ]);
}
- $this->dstfld1 = $name;
- $this->dstfld2 = $this->name.'_caption';
- $this->setDefault('0');
+ return $this;
}
- /**
- * Set additional flags, which can be used in configuration form.
- *
- * @param int $flags
- *
- * @return $this
- */
- public function setFlags($flags) {
+ public function setFlags(int $flags): self {
parent::setFlags($flags);
- if ($flags & self::FLAG_NOT_EMPTY) {
+ if (($flags & self::FLAG_NOT_EMPTY) !== 0) {
$strict_validation_rules = $this->getValidationRules();
self::setValidationRuleFlag($strict_validation_rules, API_NOT_EMPTY);
$this->setStrictValidationRules($strict_validation_rules);
}
else {
- $this->setStrictValidationRules(null);
+ $this->setStrictValidationRules();
}
return $this;
}
- public function getResourceType() {
- return $this->resource_type;
- }
-
- public function getPopupOptions($dstfrm) {
- $popup_options = [
- 'srctbl' => $this->srctbl,
- 'srcfld1' => $this->srcfld1,
- 'srcfld2' => $this->srcfld2,
- 'dstfld1' => $this->dstfld1,
- 'dstfld2' => $this->dstfld2,
- 'dstfrm' => $dstfrm
- ];
-
- return $popup_options;
+ public function getPopupOptions(string $form_name): array {
+ return array_merge($this->popup_options, [
+ 'dstfrm' => $form_name
+ ]);
}
}
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldSeverities.php b/ui/include/classes/widgets/fields/CWidgetFieldSeverities.php
index 5c661cd673a..7e72d150d16 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldSeverities.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldSeverities.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,9 +19,11 @@
**/
+namespace Zabbix\Widgets\Fields;
+
class CWidgetFieldSeverities extends CWidgetFieldCheckBoxList {
- public function __construct($name, $label) {
+ public function __construct(string $name, string $label = null) {
parent::__construct($name, $label);
$this->setExValidationRules(
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldTags.php b/ui/include/classes/widgets/fields/CWidgetFieldTags.php
index 528af29a696..febcc6c862f 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldTags.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldTags.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,36 +19,30 @@
**/
-class CWidgetFieldTags extends CWidgetField {
+namespace Zabbix\Widgets\Fields;
- /**
- * Create widget field for Tags selection.
- *
- * @param string $name Field name in form.
- * @param string $label Label for the field in form.
- */
- public function __construct($name, $label) {
- parent::__construct($name, $label);
+use Zabbix\Widgets\CWidgetField;
- $this->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR);
- $this->setValidationRules(['type' => API_OBJECTS, 'fields' => [
- 'tag' => ['type' => API_STRING_UTF8, 'flags' => API_REQUIRED, 'length' => 255],
- 'operator' => ['type' => API_INT32, 'flags' => API_REQUIRED, 'in' => implode(',', [TAG_OPERATOR_LIKE, TAG_OPERATOR_EQUAL, TAG_OPERATOR_NOT_LIKE, TAG_OPERATOR_NOT_EQUAL, TAG_OPERATOR_EXISTS, TAG_OPERATOR_NOT_EXISTS])],
- 'value' => ['type' => API_STRING_UTF8, 'flags' => API_REQUIRED, 'length' => 255]
- ]]);
- $this->setDefault([]);
- }
+class CWidgetFieldTags extends CWidgetField {
- public function setValue($value) {
- $this->value = (array) $value;
+ public const DEFAULT_VALUE = [];
+ public const DEFAULT_TAG = ['tag' => '', 'operator' => TAG_OPERATOR_LIKE, 'value' => ''];
- return $this;
+ public function __construct(string $name, string $label = null) {
+ parent::__construct($name, $label);
+
+ $this
+ ->setDefault(self::DEFAULT_VALUE)
+ ->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR)
+ ->setValidationRules(['type' => API_OBJECTS, 'fields' => [
+ 'tag' => ['type' => API_STRING_UTF8, 'flags' => API_REQUIRED, 'length' => 255],
+ 'operator' => ['type' => API_INT32, 'flags' => API_REQUIRED, 'in' => implode(',', [TAG_OPERATOR_LIKE, TAG_OPERATOR_EQUAL, TAG_OPERATOR_NOT_LIKE, TAG_OPERATOR_NOT_EQUAL, TAG_OPERATOR_EXISTS, TAG_OPERATOR_NOT_EXISTS])],
+ 'value' => ['type' => API_STRING_UTF8, 'flags' => API_REQUIRED, 'length' => 255]
+ ]]);
}
/**
* Get field value. If no value is set, will return default value.
- *
- * @return mixed
*/
public function getValue() {
$value = parent::getValue();
@@ -62,35 +56,13 @@ class CWidgetFieldTags extends CWidgetField {
return $value;
}
- /**
- * Add dynamic row script and fix the distance between AND/OR buttons and tag inputs below them.
- *
- * @return string
- */
- public function getJavascript() {
- return 'var tags_table = jQuery("#tags_table_'.$this->getName().'");'.
-
- 'tags_table'.
- '.dynamicRows({template: "#tag-row-tmpl"})'.
- '.on("afteradd.dynamicRows", function() {'.
- 'var rows = this.querySelectorAll(".form_row");'.
- 'new CTagFilterItem(rows[rows.length - 1]);'.
- '});'.
+ public function setValue($value): self {
+ $this->value = (array) $value;
- // Init existing fields once loaded.
- 'document.querySelectorAll("#tags_table_'.$this->getName().' .form_row").forEach(row => {'.
- 'new CTagFilterItem(row);'.
- '});';
+ return $this;
}
- /**
- * Prepares array entry for widget field, ready to be passed to CDashboard API functions.
- * Reference is needed here to avoid array merging in CWidgetForm::fieldsToApi method. With large number of widget
- * fields it causes significant performance decrease.
- *
- * @param array $widget_fields reference to Array of widget fields.
- */
- public function toApi(array &$widget_fields = []) {
+ public function toApi(array &$widget_fields = []): void {
$value = $this->getValue();
foreach ($value as $index => $val) {
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldTextArea.php b/ui/include/classes/widgets/fields/CWidgetFieldTextArea.php
index 6d3edfec74a..5d9b8633e58 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldTextArea.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldTextArea.php
@@ -19,53 +19,34 @@
**/
+namespace Zabbix\Widgets\Fields;
+
+use Zabbix\Widgets\CWidgetField;
+
class CWidgetFieldTextArea extends CWidgetField {
- private $width;
+ public const DEFAULT_VALUE = '';
- /**
- * Textarea widget field.
- *
- * @param string $name Field name in form.
- * @param string $label Label for the field in form.
- */
- public function __construct($name, $label) {
+ public function __construct(string $name, string $label = null) {
parent::__construct($name, $label);
- $this->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR);
- $this->setDefault('');
- $this->width = ZBX_TEXTAREA_STANDARD_WIDTH;
+ $this
+ ->setDefault(self::DEFAULT_VALUE)
+ ->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR);
}
- /**
- * Set additional flags, which can be used in configuration form.
- *
- * @param int $flags
- *
- * @return $this
- */
- public function setFlags($flags) {
+ public function setFlags(int $flags): self {
parent::setFlags($flags);
- if ($flags & self::FLAG_NOT_EMPTY) {
+ if (($flags & self::FLAG_NOT_EMPTY) !== 0) {
$strict_validation_rules = $this->getValidationRules();
self::setValidationRuleFlag($strict_validation_rules, API_NOT_EMPTY);
$this->setStrictValidationRules($strict_validation_rules);
}
else {
- $this->setStrictValidationRules(null);
+ $this->setStrictValidationRules();
}
return $this;
}
-
- public function setWidth($width) {
- $this->width = $width;
-
- return $this;
- }
-
- public function getWidth() {
- return $this->width;
- }
}
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldTextBox.php b/ui/include/classes/widgets/fields/CWidgetFieldTextBox.php
index 1dbeaddb245..6932d86f9b1 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldTextBox.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldTextBox.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,64 +19,40 @@
**/
+namespace Zabbix\Widgets\Fields;
+
+use Zabbix\Widgets\CWidgetField;
+
class CWidgetFieldTextBox extends CWidgetField {
- private $placeholder;
- private $width;
+ public const DEFAULT_VALUE = '';
/**
* Text box widget field.
- *
- * @param string $name field name in form
- * @param string $label label for the field in form
*/
- public function __construct($name, $label) {
+ public function __construct(string $name, string $label = null) {
parent::__construct($name, $label);
- $this->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR);
- $this->setDefault('');
- $this->width = ZBX_TEXTAREA_STANDARD_WIDTH;
+ $this
+ ->setDefault(self::DEFAULT_VALUE)
+ ->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR);
}
/**
* Set additional flags, which can be used in configuration form.
- *
- * @param int $flags
- *
- * @return $this
*/
- public function setFlags($flags) {
+ public function setFlags(int $flags): self {
parent::setFlags($flags);
- if ($flags & self::FLAG_NOT_EMPTY) {
+ if (($flags & self::FLAG_NOT_EMPTY) !== 0) {
$strict_validation_rules = $this->getValidationRules();
self::setValidationRuleFlag($strict_validation_rules, API_NOT_EMPTY);
$this->setStrictValidationRules($strict_validation_rules);
}
else {
- $this->setStrictValidationRules(null);
+ $this->setStrictValidationRules();
}
return $this;
}
-
- public function setPlaceholder($placeholder) {
- $this->placeholder = $placeholder;
-
- return $this;
- }
-
- public function getPlaceholder() {
- return $this->placeholder;
- }
-
- public function setWidth($width) {
- $this->width = $width;
-
- return $this;
- }
-
- public function getWidth() {
- return $this->width;
- }
}
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldThresholds.php b/ui/include/classes/widgets/fields/CWidgetFieldThresholds.php
index dac9b93f543..0988fb29143 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldThresholds.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldThresholds.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,29 +19,34 @@
**/
+namespace Zabbix\Widgets\Fields;
+
+use CArrayHelper,
+ CNumberParser,
+ CParser;
+
+use Zabbix\Widgets\CWidgetField;
+
class CWidgetFieldThresholds extends CWidgetField {
- public const THRESHOLDS_TABLE_ID = '%s-table';
- public const THRESHOLDS_ROW_TMPL_ID = '%s-row-tmpl';
+ public const DEFAULT_VALUE = [];
/**
* Create widget field for Thresholds selection.
- *
- * @param string $name Field name in form.
- * @param string $label Label for the field in form.
*/
- public function __construct($name, $label) {
+ public function __construct(string $name, string $label = null) {
parent::__construct($name, $label);
- $this->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR);
- $this->setValidationRules(['type' => API_OBJECTS, 'uniq' => [['threshold']], 'fields' => [
- 'color' => ['type' => API_COLOR, 'flags' => API_REQUIRED | API_NOT_EMPTY],
- 'threshold' => ['type' => API_NUMERIC, 'flags' => API_REQUIRED]
- ]]);
- $this->setDefault([]);
+ $this
+ ->setDefault(self::DEFAULT_VALUE)
+ ->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR)
+ ->setValidationRules(['type' => API_OBJECTS, 'uniq' => [['threshold']], 'fields' => [
+ 'color' => ['type' => API_COLOR, 'flags' => API_REQUIRED | API_NOT_EMPTY],
+ 'threshold' => ['type' => API_NUMERIC, 'flags' => API_REQUIRED]
+ ]]);
}
- public function setValue($value) {
+ public function setValue($value): self {
$thresholds = [];
foreach ($value as $threshold) {
@@ -81,29 +86,7 @@ class CWidgetFieldThresholds extends CWidgetField {
return [];
}
- public function getJavascript() {
- return 'var thresholds_table = jQuery("#'.sprintf(self::THRESHOLDS_TABLE_ID, $this->getName()).'");'.
- 'thresholds_table'.
- '.dynamicRows({template: "#'.sprintf(self::THRESHOLDS_ROW_TMPL_ID, $this->getName()).'"})'.
- '.on("afteradd.dynamicRows", function(opt) {'.
- 'const rows = this.querySelectorAll(".form_row");'.
- 'const colors = jQuery("#widget-dialogue-form")[0]'.
- '.querySelectorAll(".'.ZBX_STYLE_COLOR_PICKER.' input");'.
- 'const used_colors = [];'.
- 'for (const color of colors) {'.
- 'if (color.value !== "" && color.name.includes("thresholds")) {'.
- 'used_colors.push(color.value);'.
- '}'.
- '}'.
- 'jQuery(".color-picker input", rows[rows.length - 1])'.
- '.val(colorPalette.getNextColor(used_colors))'.
- '.colorpicker({'.
- 'appendTo: ".overlay-dialogue-body"'.
- '});'.
- '});';
- }
-
- public function toApi(array &$widget_fields = []) {
+ public function toApi(array &$widget_fields = []): void {
$value = $this->getValue();
foreach ($value as $index => $val) {
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldTimeZone.php b/ui/include/classes/widgets/fields/CWidgetFieldTimeZone.php
index 202283188f3..32806e9885a 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldTimeZone.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldTimeZone.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,62 +19,33 @@
**/
-class CWidgetFieldTimeZone extends CWidgetField {
+namespace Zabbix\Widgets\Fields;
- private $values;
+use CTimezoneHelper;
- /**
- * CSelect widget field.
- *
- * @param string $name Field name in form
- * @param string $label Label for the field in form
- * @param array $values Key/value pairs of select option values. Key - saved in DB. Value - visible to user.
- */
- public function __construct($name, $label, $values = null) {
- parent::__construct($name, $label);
+class CWidgetFieldTimeZone extends CWidgetFieldSelect {
- $this->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR);
+ public const DEFAULT_VALUE = '';
- if ($values === null) {
- $this->values = $this->generateValues();
- }
+ public function __construct(string $name, string $label = null, array $values = null) {
+ parent::__construct($name, $label, $values === null
+ ? [
+ ZBX_DEFAULT_TIMEZONE => CTimezoneHelper::getTitle(CTimezoneHelper::getSystemTimezone(),
+ _('System default')
+ ),
+ TIMEZONE_DEFAULT_LOCAL => _('Local default')
+ ] + CTimezoneHelper::getList()
+ : null
+ );
- $this->setExValidationRules(['in' => implode(',', array_keys($this->values))]);
+ $this
+ ->setDefault(self::DEFAULT_VALUE)
+ ->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR);
}
- public function setValue($value) {
- return parent::setValue($value);
- }
-
- public function getValues() {
- return $this->values;
- }
-
- private function generateValues() {
- return [
- ZBX_DEFAULT_TIMEZONE => CTimezoneHelper::getTitle(CTimezoneHelper::getSystemTimezone(),
- _('System default')
- ),
- TIMEZONE_DEFAULT_LOCAL => _('Local default')
- ] + CTimezoneHelper::getList();
- }
-
- public function getJavascript() {
- return '
- var timezone_select = document.getElementById("'.$this->getName().'");
- var local_time_zone = Intl.DateTimeFormat().resolvedOptions().timeZone;
- var timezone_from_list = timezone_select.getOptionByValue(local_time_zone);
- var local_list_item = timezone_select.getOptionByValue("'.TIMEZONE_DEFAULT_LOCAL.'");
-
- if (timezone_from_list && local_list_item) {
- const title = local_list_item.label + ": " + timezone_from_list.label;
- local_list_item.label = title;
- local_list_item._node.innerText = title;
+ public function setValue($value): self {
+ $this->value = $value;
- if (timezone_select.selectedIndex === local_list_item._index) {
- timezone_select._preselect(timezone_select.selectedIndex);
- }
- }
- ';
+ return $this;
}
}
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldUrl.php b/ui/include/classes/widgets/fields/CWidgetFieldUrl.php
index 31c760be381..7d8706deb1a 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldUrl.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldUrl.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,39 +19,33 @@
**/
+namespace Zabbix\Widgets\Fields;
+
+use Zabbix\Widgets\CWidgetField;
+
class CWidgetFieldUrl extends CWidgetField {
- /**
- * URL widget field.
- *
- * @param string $name field name in form
- * @param string $label label for the field in form
- */
- public function __construct($name, $label) {
+ public const DEFAULT_VALUE = '';
+
+ public function __construct(string $name, string $label = null) {
parent::__construct($name, $label);
- $this->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR);
- $this->setValidationRules(['type' => API_URL, 'flags' => API_ALLOW_USER_MACRO]);
- $this->setDefault('');
+ $this
+ ->setDefault(self::DEFAULT_VALUE)
+ ->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR)
+ ->setValidationRules(['type' => API_URL, 'flags' => API_ALLOW_USER_MACRO]);
}
- /**
- * Set additional flags, which can be used in configuration form.
- *
- * @param int $flags
- *
- * @return $this
- */
- public function setFlags($flags) {
+ public function setFlags(int $flags): self {
parent::setFlags($flags);
- if ($flags & self::FLAG_NOT_EMPTY) {
+ if (($flags & self::FLAG_NOT_EMPTY) !== 0) {
$strict_validation_rules = $this->getValidationRules();
self::setValidationRuleFlag($strict_validation_rules, API_NOT_EMPTY);
$this->setStrictValidationRules($strict_validation_rules);
}
else {
- $this->setStrictValidationRules(null);
+ $this->setStrictValidationRules();
}
return $this;
diff --git a/ui/include/classes/widgets/fields/CWidgetFieldWidgetSelect.php b/ui/include/classes/widgets/fields/CWidgetFieldWidgetSelect.php
index b9dd08205fd..39b131a0d10 100644
--- a/ui/include/classes/widgets/fields/CWidgetFieldWidgetSelect.php
+++ b/ui/include/classes/widgets/fields/CWidgetFieldWidgetSelect.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,82 +19,55 @@
**/
+namespace Zabbix\Widgets\Fields;
+
+use Zabbix\Widgets\CWidgetField;
+
class CWidgetFieldWidgetSelect extends CWidgetField {
- private $search_by_value;
+ public const DEFAULT_VALUE = -1;
+
+ private string $search_by_value;
/**
* Field that creates a selection of widgets in current dashboard, filtered by given key of widget array.
*
- * @param string $name Name of field in config form and widget['fields'] array.
- * @param string $label Field label in config form.
- * @param mixed $search_type Value that will be searched in widgets.
+ * @param string $search_by_value Value that will be searched in widgets.
*/
- public function __construct($name, $label, $search_by_value) {
+ public function __construct(string $name, string $label = null, string $search_by_value = '') {
parent::__construct($name, $label);
- $this->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR);
$this->search_by_value = $search_by_value;
+
+ $this
+ ->setDefault(self::DEFAULT_VALUE)
+ ->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR);
}
- /**
- * Set additional flags, which can be used in configuration form.
- *
- * @param int $flags
- *
- * @return $this
- */
- public function setFlags($flags) {
+ public function getSearchByValue(): string {
+ return $this->search_by_value;
+ }
+
+ public function setFlags(int $flags): self {
parent::setFlags($flags);
- if ($flags & self::FLAG_NOT_EMPTY) {
+ if (($flags & self::FLAG_NOT_EMPTY) !== 0) {
$strict_validation_rules = $this->getValidationRules();
self::setValidationRuleFlag($strict_validation_rules, API_NOT_EMPTY);
$this->setStrictValidationRules($strict_validation_rules);
}
else {
- $this->setStrictValidationRules(null);
+ $this->setStrictValidationRules();
}
return $this;
}
- /**
- * JS code, that should be executed, to fill the select element with values and select current one.
- *
- * @return string
- */
- public function getJavascript() {
- return '
- var filter_select = document.getElementById("'.$this->getName().'");
-
- filter_select.addOption('.json_encode(['label' => _('Select widget'), 'value' => '-1']).');
- filter_select.selectedIndex = 0;
-
- ZABBIX.Dashboard.getSelectedDashboardPage().getWidgets().forEach((widget) => {
- if (widget.getType() === "'.$this->search_by_value.'") {
- filter_select.addOption({label: widget.getHeaderName(), value: widget.getFields().reference});
- if (widget.getFields().reference === "'.$this->getValue().'") {
- filter_select.value = "'.$this->getValue().'";
- }
- }
- });
- ';
- }
-
- public function setValue($value) {
+ public function setValue($value): self {
if ($value === '' || ctype_alnum($value)) {
$this->value = $value;
}
return $this;
}
-
- public function setAction($action) {
- throw new RuntimeException(sprintf('Method is not implemented: "%s".', __METHOD__));
- }
-
- public function getAction() {
- throw new RuntimeException(sprintf('Method is not implemented: "%s".', __METHOD__));
- }
}
diff --git a/ui/include/classes/widgets/forms/CWidgetFormActionLog.php b/ui/include/classes/widgets/forms/CWidgetFormActionLog.php
deleted file mode 100644
index 2603dfddd90..00000000000
--- a/ui/include/classes/widgets/forms/CWidgetFormActionLog.php
+++ /dev/null
@@ -1,60 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Action log widget form.
- */
-class CWidgetFormActionLog extends CWidgetForm {
-
- public function __construct($data, $templateid) {
- parent::__construct($data, $templateid, WIDGET_ACTION_LOG);
-
- $field_sort = (new CWidgetFieldSelect('sort_triggers', _('Sort entries by'), [
- SCREEN_SORT_TRIGGERS_TIME_DESC => _('Time').' ('._('descending').')',
- SCREEN_SORT_TRIGGERS_TIME_ASC => _('Time').' ('._('ascending').')',
- SCREEN_SORT_TRIGGERS_TYPE_DESC => _('Type').' ('._('descending').')',
- SCREEN_SORT_TRIGGERS_TYPE_ASC => _('Type').' ('._('ascending').')',
- SCREEN_SORT_TRIGGERS_STATUS_DESC => _('Status').' ('._('descending').')',
- SCREEN_SORT_TRIGGERS_STATUS_ASC => _('Status').' ('._('ascending').')',
- SCREEN_SORT_TRIGGERS_RECIPIENT_DESC => _('Recipient').' ('._('descending').')',
- SCREEN_SORT_TRIGGERS_RECIPIENT_ASC => _('Recipient').' ('._('ascending').')'
- ]))
- ->setDefault(SCREEN_SORT_TRIGGERS_TIME_DESC);
-
- if (array_key_exists('sort_triggers', $this->data)) {
- $field_sort->setValue($this->data['sort_triggers']);
- }
-
- $this->fields[$field_sort->getName()] = $field_sort;
-
- $field_lines = (new CWidgetFieldIntegerBox('show_lines', _('Show lines'), ZBX_MIN_WIDGET_LINES,
- ZBX_MAX_WIDGET_LINES
- ))
- ->setFlags(CWidgetField::FLAG_LABEL_ASTERISK)
- ->setDefault(25);
-
- if (array_key_exists('show_lines', $this->data)) {
- $field_lines->setValue($this->data['show_lines']);
- }
-
- $this->fields[$field_lines->getName()] = $field_lines;
- }
-}
diff --git a/ui/include/classes/widgets/forms/CWidgetFormClock.php b/ui/include/classes/widgets/forms/CWidgetFormClock.php
deleted file mode 100644
index 6e619dcc6bf..00000000000
--- a/ui/include/classes/widgets/forms/CWidgetFormClock.php
+++ /dev/null
@@ -1,255 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Clock widget form.
- */
-class CWidgetFormClock extends CWidgetForm {
-
- /**
- * Minimum value of percentage.
- *
- * @var int
- */
- private const WIDGET_CLOCK_PERCENT_MIN = 1;
-
- /**
- * Maximum value of percentage.
- *
- * @var int
- */
- private const WIDGET_CLOCK_PERCENT_MAX = 100;
-
- public function __construct($data, $templateid) {
- parent::__construct($data, $templateid, WIDGET_CLOCK);
-
- // Time type field.
- $field_time_type = (new CWidgetFieldSelect('time_type', _('Time type'), [
- TIME_TYPE_LOCAL => _('Local time'),
- TIME_TYPE_SERVER => _('Server time'),
- TIME_TYPE_HOST => _('Host time')
- ]))->setDefault(TIME_TYPE_LOCAL);
-
- if (array_key_exists('time_type', $this->data)) {
- $field_time_type->setValue($this->data['time_type']);
- }
-
- $this->fields[$field_time_type->getName()] = $field_time_type;
-
- // Item field.
- if ($field_time_type->getValue() === TIME_TYPE_HOST) {
- // Item multiselector with single value.
- $field_item = (new CWidgetFieldMsItem('itemid', _('Item'), $templateid))
- ->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
- ->setMultiple(false);
-
- if (array_key_exists('itemid', $this->data)) {
- $field_item->setValue($this->data['itemid']);
- }
-
- $this->fields[$field_item->getName()] = $field_item;
- }
-
- // clock type
- $field_clock_type = (new CWidgetFieldRadioButtonList('clock_type', _('Clock type'), [
- WIDGET_CLOCK_TYPE_ANALOG => _('Analog'),
- WIDGET_CLOCK_TYPE_DIGITAL => _('Digital')
- ]))
- ->setDefault(WIDGET_CLOCK_TYPE_ANALOG)
- ->setModern(true);
-
- if (array_key_exists('clock_type', $this->data)) {
- $field_clock_type->setValue($this->data['clock_type']);
- }
-
- $this->fields[$field_clock_type->getName()] = $field_clock_type;
-
- // field show
- $field_show =(new CWidgetFieldCheckBoxList('show', _('Show')))
- ->setDefault([WIDGET_CLOCK_SHOW_TIME])
- ->setFlags(CWidgetField::FLAG_LABEL_ASTERISK);
-
- if (array_key_exists('show', $this->data)) {
- $field_show->setValue($this->data['show']);
- }
-
- $this->fields[$field_show->getName()] = $field_show;
-
- // advanced configuration
- $field_adv_conf = (new CWidgetFieldCheckBox('adv_conf', _('Advanced configuration')))->setDefault(0);
-
- if (array_key_exists('adv_conf', $this->data)) {
- $field_adv_conf->setValue($this->data['adv_conf']);
- }
-
- $this->fields[$field_adv_conf->getName()] = $field_adv_conf;
-
- // background color
- $field_bg_color = (new CWidgetFieldColor('bg_color', _('Background color')))->setDefault('');
-
- if (array_key_exists('bg_color', $this->data)) {
- $field_bg_color->setValue($this->data['bg_color']);
- }
-
- $this->fields[$field_bg_color->getName()] = $field_bg_color;
-
- // date size
- $field_date_size = (new CWidgetFieldIntegerBox('date_size', _('Size'), self::WIDGET_CLOCK_PERCENT_MIN,
- self::WIDGET_CLOCK_PERCENT_MAX
- ))->setDefault(20);
-
- if (array_key_exists('date_size', $this->data)) {
- $field_date_size->setValue($this->data['date_size']);
- }
-
- $this->fields[$field_date_size->getName()] = $field_date_size;
-
- // date bold
- $field_date_bold = (new CWidgetFieldCheckBox('date_bold', _('Bold')))->setDefault(0);
-
- if (array_key_exists('date_bold', $this->data)) {
- $field_date_bold->setValue($this->data['date_bold']);
- }
-
- $this->fields[$field_date_bold->getName()] = $field_date_bold;
-
- // date color
- $field_date_color = (new CWidgetFieldColor('date_color', _('Color')))->setDefault('');
-
- if (array_key_exists('date_color', $this->data)) {
- $field_date_color->setValue($this->data['date_color']);
- }
-
- $this->fields[$field_date_color->getName()] = $field_date_color;
-
- // time size
- $field_time_size = (new CWidgetFieldIntegerBox('time_size', _('Size'), self::WIDGET_CLOCK_PERCENT_MIN,
- self::WIDGET_CLOCK_PERCENT_MAX
- ))->setDefault(30);
-
- if (array_key_exists('time_size', $this->data)) {
- $field_time_size->setValue($this->data['time_size']);
- }
-
- $this->fields[$field_time_size->getName()] = $field_time_size;
-
- // time bold
- $field_time_bold = (new CWidgetFieldCheckBox('time_bold', _('Bold')))->setDefault(0);
-
- if (array_key_exists('time_bold', $this->data)) {
- $field_time_bold->setValue($this->data['time_bold']);
- }
-
- $this->fields[$field_time_bold->getName()] = $field_time_bold;
-
- // time color
- $field_time_color = (new CWidgetFieldColor('time_color', _('Color')))->setDefault('');
-
- if (array_key_exists('time_color', $this->data)) {
- $field_time_color->setValue($this->data['time_color']);
- }
-
- $this->fields[$field_time_color->getName()] = $field_time_color;
-
- // time seconds
- $field_time_sec = (new CWidgetFieldCheckBox('time_sec', _('Seconds')))->setDefault(1);
-
- if (array_key_exists('time_sec', $this->data)) {
- $field_time_sec->setValue($this->data['time_sec']);
- }
-
- $this->fields[$field_time_sec->getName()] = $field_time_sec;
-
- // time format
- $field_time_format = (new CWidgetFieldRadioButtonList('time_format', _('Format'), [
- WIDGET_CLOCK_HOUR_TWENTY_FOUR => _('24-hour'),
- WIDGET_CLOCK_HOUR_TWELVE => _('12-hour')
- ]))
- ->setDefault(WIDGET_CLOCK_HOUR_TWENTY_FOUR)
- ->setModern(true);
-
- if (array_key_exists('time_format', $this->data)) {
- $field_time_format->setValue($this->data['time_format']);
- }
-
- $this->fields[$field_time_format->getName()] = $field_time_format;
-
- // time zone size
- $field_tzone_size = (new CWidgetFieldIntegerBox('tzone_size', _('Size'), self::WIDGET_CLOCK_PERCENT_MIN,
- self::WIDGET_CLOCK_PERCENT_MAX
- ))->setDefault(20);
-
- if (array_key_exists('tzone_size', $this->data)) {
- $field_tzone_size->setValue($this->data['tzone_size']);
- }
-
- $this->fields[$field_tzone_size->getName()] = $field_tzone_size;
-
- // time zone bold
- $field_tzone_bold = (new CWidgetFieldCheckBox('tzone_bold', _('Bold')))->setDefault(0);
-
- if (array_key_exists('tzone_bold', $this->data)) {
- $field_tzone_bold->setValue($this->data['tzone_bold']);
- }
-
- $this->fields[$field_tzone_bold->getName()] = $field_tzone_bold;
-
- // time zone color
- $field_tzone_color = (new CWidgetFieldColor('tzone_color', _('Color')))->setDefault('');
-
- if (array_key_exists('tzone_color', $this->data)) {
- $field_tzone_color->setValue($this->data['tzone_color']);
- }
-
- $this->fields[$field_tzone_color->getName()] = $field_tzone_color;
-
- // time zone time zone
- $field_tzone_timezone = (new CWidgetFieldTimeZone('tzone_timezone', _('Time zone')))
- ->setDefault(ZBX_DEFAULT_TIMEZONE);
-
- if ($field_time_type->getValue() === TIME_TYPE_LOCAL) {
- $field_tzone_timezone->setDefault(TIMEZONE_DEFAULT_LOCAL);
- }
-
- if (array_key_exists('tzone_timezone', $this->data)) {
- $field_tzone_timezone->setValue($this->data['tzone_timezone']);
- }
- elseif ($field_time_type->getValue() === TIME_TYPE_LOCAL) {
- $field_tzone_timezone->setValue(TIMEZONE_DEFAULT_LOCAL);
- }
-
- $this->fields[$field_tzone_timezone->getName()] = $field_tzone_timezone;
-
- // time zone format
- $field_tzone_format = (new CWidgetFieldRadioButtonList('tzone_format', _('Format'), [
- WIDGET_CLOCK_TIMEZONE_SHORT => _('Short'),
- WIDGET_CLOCK_TIMEZONE_FULL => _('Full')
- ]))
- ->setDefault(WIDGET_CLOCK_TIMEZONE_SHORT)
- ->setModern(true);
-
- if (array_key_exists('tzone_format', $this->data)) {
- $field_tzone_format->setValue($this->data['tzone_format']);
- }
-
- $this->fields[$field_tzone_format->getName()] = $field_tzone_format;
- }
-}
diff --git a/ui/include/classes/widgets/forms/CWidgetFormDataOver.php b/ui/include/classes/widgets/forms/CWidgetFormDataOver.php
deleted file mode 100644
index d6b5a4a6380..00000000000
--- a/ui/include/classes/widgets/forms/CWidgetFormDataOver.php
+++ /dev/null
@@ -1,97 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Data overview widget form.
- */
-class CWidgetFormDataOver extends CWidgetForm {
-
- public function __construct($data, $templateid) {
- parent::__construct($data, $templateid, WIDGET_DATA_OVER);
-
- $this->data = self::convertDottedKeys($this->data);
-
- // Host groups.
- $field_groups = new CWidgetFieldMsGroup('groupids', _('Host groups'));
-
- if (array_key_exists('groupids', $this->data)) {
- $field_groups->setValue($this->data['groupids']);
- }
- $this->fields[$field_groups->getName()] = $field_groups;
-
- // Hosts.
- $field_hosts = new CWidgetFieldMsHost('hostids', _('Hosts'));
- $field_hosts->setFilterPreselect('groupids_');
-
- if (array_key_exists('hostids', $this->data)) {
- $field_hosts->setValue($this->data['hostids']);
- }
-
- $this->fields[$field_hosts->getName()] = $field_hosts;
-
- // Tag evaltype (And/Or).
- $field_evaltype = (new CWidgetFieldRadioButtonList('evaltype', _('Tags'), [
- TAG_EVAL_TYPE_AND_OR => _('And/Or'),
- TAG_EVAL_TYPE_OR => _('Or')
- ]))
- ->setDefault(TAG_EVAL_TYPE_AND_OR)
- ->setModern(true);
-
- if (array_key_exists('evaltype', $this->data)) {
- $field_evaltype->setValue($this->data['evaltype']);
- }
-
- $this->fields[$field_evaltype->getName()] = $field_evaltype;
-
- // Tags array: tag, operator and value. No label, because it belongs to previous group.
- $field_tags = new CWidgetFieldTags('tags', '');
-
- if (array_key_exists('tags', $this->data)) {
- $field_tags->setValue($this->data['tags']);
- }
-
- $this->fields[$field_tags->getName()] = $field_tags;
-
- // Show suppressed problems.
- $field_show_suppressed = (new CWidgetFieldCheckBox('show_suppressed', _('Show suppressed problems')))
- ->setDefault(ZBX_PROBLEM_SUPPRESSED_FALSE);
-
- if (array_key_exists('show_suppressed', $this->data)) {
- $field_show_suppressed->setValue($this->data['show_suppressed']);
- }
-
- $this->fields[$field_show_suppressed->getName()] = $field_show_suppressed;
-
- // Hosts names location.
- $field_style = (new CWidgetFieldRadioButtonList('style', _('Hosts location'), [
- STYLE_LEFT => _('Left'),
- STYLE_TOP => _('Top')
- ]))
- ->setDefault(STYLE_LEFT)
- ->setModern(true);
-
- if (array_key_exists('style', $this->data)) {
- $field_style->setValue($this->data['style']);
- }
-
- $this->fields[$field_style->getName()] = $field_style;
- }
-}
diff --git a/ui/include/classes/widgets/forms/CWidgetFormGeoMap.php b/ui/include/classes/widgets/forms/CWidgetFormGeoMap.php
deleted file mode 100644
index be0a49f437c..00000000000
--- a/ui/include/classes/widgets/forms/CWidgetFormGeoMap.php
+++ /dev/null
@@ -1,83 +0,0 @@
-<?php declare(strict_types = 0);
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Geomap widget form.
- */
-class CWidgetFormGeoMap extends CWidgetForm {
-
- public function __construct($data, $templateid) {
- parent::__construct($data, $templateid, WIDGET_GEOMAP);
-
- $this->data = self::convertDottedKeys($this->data);
-
- // Host groups.
- $field_groups = new CWidgetFieldMsGroup('groupids', _('Host groups'));
-
- if (array_key_exists('groupids', $this->data)) {
- $field_groups->setValue($this->data['groupids']);
- }
-
- $this->fields[$field_groups->getName()] = $field_groups;
-
- // Hosts field.
- $field_hosts = new CWidgetFieldMsHost('hostids', _('Hosts'));
- $field_hosts->setFilterPreselect('groupids_');
-
- if (array_key_exists('hostids', $this->data)) {
- $field_hosts->setValue($this->data['hostids']);
- }
-
- $this->fields[$field_hosts->getName()] = $field_hosts;
-
- // Tag evaltype (And/Or).
- $field_evaltype = (new CWidgetFieldRadioButtonList('evaltype', _('Tags'), [
- TAG_EVAL_TYPE_AND_OR => _('And/Or'),
- TAG_EVAL_TYPE_OR => _('Or')
- ]))
- ->setDefault(TAG_EVAL_TYPE_AND_OR)
- ->setModern(true);
-
- if (array_key_exists('evaltype', $this->data)) {
- $field_evaltype->setValue($this->data['evaltype']);
- }
-
- $this->fields[$field_evaltype->getName()] = $field_evaltype;
-
- // Tags array: tag, operator and value. No label, because it belongs to previous group.
- $field_tags = new CWidgetFieldTags('tags', '');
-
- if (array_key_exists('tags', $this->data)) {
- $field_tags->setValue($this->data['tags']);
- }
-
- $this->fields[$field_tags->getName()] = $field_tags;
-
- // Default view.
- $field_default_view = new CWidgetFieldLatLng('default_view', _('Initial view'));
-
- if (array_key_exists('default_view', $this->data)) {
- $field_default_view->setValue($this->data['default_view']);
- }
-
- $this->fields[$field_default_view->getName()] = $field_default_view;
- }
-}
diff --git a/ui/include/classes/widgets/forms/CWidgetFormGraph.php b/ui/include/classes/widgets/forms/CWidgetFormGraph.php
deleted file mode 100644
index 034923647ef..00000000000
--- a/ui/include/classes/widgets/forms/CWidgetFormGraph.php
+++ /dev/null
@@ -1,95 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Graph widget form.
- */
-class CWidgetFormGraph extends CWidgetForm {
-
- public function __construct($data, $templateid) {
- parent::__construct($data, $templateid, WIDGET_GRAPH);
-
- // Select graph type field.
- $field_source = (new CWidgetFieldRadioButtonList('source_type', _('Source'), [
- ZBX_WIDGET_FIELD_RESOURCE_GRAPH => _('Graph'),
- ZBX_WIDGET_FIELD_RESOURCE_SIMPLE_GRAPH => _('Simple graph')
- ]))
- ->setDefault(ZBX_WIDGET_FIELD_RESOURCE_GRAPH)
- ->setAction('ZABBIX.Dashboard.reloadWidgetProperties()')
- ->setModern(true);
-
- if (array_key_exists('source_type', $this->data)) {
- $field_source->setValue($this->data['source_type']);
- }
-
- $this->fields[$field_source->getName()] = $field_source;
-
- if (array_key_exists('source_type', $this->data)
- && $this->data['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_SIMPLE_GRAPH) {
- // Select simple graph field.
- $field_item = (new CWidgetFieldMsItem('itemid', _('Item'), $templateid))
- ->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
- ->setMultiple(false)
- ->setFilterParameter('numeric', true);
-
- if ($templateid === null) {
- // For groups and hosts selection.
- $field_item->setFilterParameter('with_simple_graph_items', true);
- }
-
- if (array_key_exists('itemid', $this->data)) {
- $field_item->setValue($this->data['itemid']);
- }
-
- $this->fields[$field_item->getName()] = $field_item;
- }
- else {
- // Select graph field.
- $field_graph = (new CWidgetFieldMsGraph('graphid', _('Graph'), $templateid))
- ->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
- ->setMultiple(false);
-
- if (array_key_exists('graphid', $this->data)) {
- $field_graph->setValue($this->data['graphid']);
- }
-
- $this->fields[$field_graph->getName()] = $field_graph;
- }
-
- // Show legend checkbox.
- $field_legend = (new CWidgetFieldCheckBox('show_legend', _('Show legend')))->setDefault(1);
-
- if (array_key_exists('show_legend', $this->data)) {
- $field_legend->setValue($this->data['show_legend']);
- }
-
- $this->fields[$field_legend->getName()] = $field_legend;
-
- // Dynamic item.
- if ($templateid === null) {
- $field_dynamic = (new CWidgetFieldCheckBox('dynamic', _('Enable host selection')))->setDefault(WIDGET_SIMPLE_ITEM);
-
- $field_dynamic->setValue(array_key_exists('dynamic', $this->data) ? $this->data['dynamic'] : false);
-
- $this->fields[$field_dynamic->getName()] = $field_dynamic;
- }
- }
-}
diff --git a/ui/include/classes/widgets/forms/CWidgetFormGraphPrototype.php b/ui/include/classes/widgets/forms/CWidgetFormGraphPrototype.php
deleted file mode 100644
index fb940335cc4..00000000000
--- a/ui/include/classes/widgets/forms/CWidgetFormGraphPrototype.php
+++ /dev/null
@@ -1,95 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Graph prototype widget form.
- */
-class CWidgetFormGraphPrototype extends CWidgetForm {
-
- public function __construct($data, $templateid) {
- parent::__construct($data, $templateid, WIDGET_GRAPH_PROTOTYPE);
-
- // Select graph type field.
- $field_source = (new CWidgetFieldRadioButtonList('source_type', _('Source'), [
- ZBX_WIDGET_FIELD_RESOURCE_GRAPH_PROTOTYPE => _('Graph prototype'),
- ZBX_WIDGET_FIELD_RESOURCE_SIMPLE_GRAPH_PROTOTYPE => _('Simple graph prototype')
- ]))
- ->setDefault(ZBX_WIDGET_FIELD_RESOURCE_GRAPH_PROTOTYPE)
- ->setAction('ZABBIX.Dashboard.reloadWidgetProperties()')
- ->setModern(true);
-
- if (array_key_exists('source_type', $this->data)) {
- $field_source->setValue($this->data['source_type']);
- }
-
- $this->fields[$field_source->getName()] = $field_source;
-
- if (array_key_exists('source_type', $this->data)
- && $this->data['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_SIMPLE_GRAPH_PROTOTYPE) {
- // Select simple graph prototype field.
- $field_item_prototype = (new CWidgetFieldMsItemPrototype('itemid', _('Item prototype'), $templateid))
- ->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
- ->setMultiple(false)
- ->setFilterParameter('numeric', true);
-
- if ($templateid === null) {
- // For groups and hosts selection.
- $field_item_prototype->setFilterParameter('with_simple_graph_item_prototypes', true);
- }
-
- if (array_key_exists('itemid', $this->data)) {
- $field_item_prototype->setValue($this->data['itemid']);
- }
-
- $this->fields[$field_item_prototype->getName()] = $field_item_prototype;
- }
- else {
- // Select graph prototype field.
- $field_graph_prototype = (new CWidgetFieldMsGraphPrototype('graphid', _('Graph prototype'), $templateid))
- ->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
- ->setMultiple(false);
-
- if (array_key_exists('graphid', $this->data)) {
- $field_graph_prototype->setValue($this->data['graphid']);
- }
-
- $this->fields[$field_graph_prototype->getName()] = $field_graph_prototype;
- }
-
- // Show legend checkbox.
- $field_legend = (new CWidgetFieldCheckBox('show_legend', _('Show legend')))->setDefault(1);
-
- if (array_key_exists('show_legend', $this->data)) {
- $field_legend->setValue($this->data['show_legend']);
- }
-
- $this->fields[$field_legend->getName()] = $field_legend;
-
- // Dynamic item.
- if ($templateid === null) {
- $field_dynamic = (new CWidgetFieldCheckBox('dynamic', _('Enable host selection')))->setDefault(WIDGET_SIMPLE_ITEM);
-
- $field_dynamic->setValue(array_key_exists('dynamic', $this->data) ? $this->data['dynamic'] : false);
-
- $this->fields[$field_dynamic->getName()] = $field_dynamic;
- }
- }
-}
diff --git a/ui/include/classes/widgets/forms/CWidgetFormHostAvail.php b/ui/include/classes/widgets/forms/CWidgetFormHostAvail.php
deleted file mode 100644
index e3aedaa5f5c..00000000000
--- a/ui/include/classes/widgets/forms/CWidgetFormHostAvail.php
+++ /dev/null
@@ -1,71 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Host availability widget form.
- */
-class CWidgetFormHostAvail extends CWidgetForm {
-
- public function __construct($data, $templateid) {
- parent::__construct($data, $templateid, WIDGET_HOST_AVAIL);
-
- // Host groups.
- $field_groups = new CWidgetFieldMsGroup('groupids', _('Host groups'));
-
- if (array_key_exists('groupids', $this->data)) {
- $field_groups->setValue($this->data['groupids']);
- }
- $this->fields[$field_groups->getName()] = $field_groups;
-
- // Interface type.
- $field_interface_type = new CWidgetFieldCheckBoxList('interface_type', _('Interface type'));
-
- if (array_key_exists('interface_type', $this->data)) {
- $field_interface_type->setValue($this->data['interface_type']);
- }
-
- $this->fields[$field_interface_type->getName()] = $field_interface_type;
-
- // Layout.
- $field_layout = (new CWidgetFieldRadioButtonList('layout', _('Layout'), [
- STYLE_HORIZONTAL => _('Horizontal'),
- STYLE_VERTICAL => _('Vertical')
- ]))
- ->setDefault(STYLE_HORIZONTAL)
- ->setModern(true);
-
- if (array_key_exists('layout', $this->data)) {
- $field_layout->setValue($this->data['layout']);
- }
-
- $this->fields[$field_layout->getName()] = $field_layout;
-
- // Show hosts in maintenance.
- $field_maintenance = (new CWidgetFieldCheckBox('maintenance', _('Show hosts in maintenance')))
- ->setDefault(HOST_MAINTENANCE_STATUS_OFF);
-
- if (array_key_exists('maintenance', $this->data)) {
- $field_maintenance->setValue($this->data['maintenance']);
- }
-
- $this->fields[$field_maintenance->getName()] = $field_maintenance;
- }
-}
diff --git a/ui/include/classes/widgets/forms/CWidgetFormItem.php b/ui/include/classes/widgets/forms/CWidgetFormItem.php
deleted file mode 100644
index 96272bd7d51..00000000000
--- a/ui/include/classes/widgets/forms/CWidgetFormItem.php
+++ /dev/null
@@ -1,461 +0,0 @@
-<?php declare(strict_types = 0);
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Single item widget form.
- */
-class CWidgetFormItem extends CWidgetForm {
-
- /**
- * Minimum value of percentage.
- *
- * @var int
- */
- private const WIDGET_ITEM_PERCENT_MIN = 1;
-
- /**
- * Maximum value of percentage.
- *
- * @var int
- */
- private const WIDGET_ITEM_PERCENT_MAX = 100;
-
- public function __construct($data, $templateid) {
- parent::__construct($data, $templateid, WIDGET_ITEM);
-
- $this->data = self::convertDottedKeys($this->data);
-
- // Item field.
- $field_item = (new CWidgetFieldMsItem('itemid', _('Item'), $templateid))
- ->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
- ->setMultiple(false);
-
- if (array_key_exists('itemid', $this->data)) {
- $field_item->setValue($this->data['itemid']);
- }
-
- $this->fields[$field_item->getName()] = $field_item;
-
- // Show checkboxes.
- $field_show = (new CWidgetFieldCheckBoxList('show', _('Show')))
- ->setDefault([WIDGET_ITEM_SHOW_DESCRIPTION, WIDGET_ITEM_SHOW_VALUE, WIDGET_ITEM_SHOW_TIME,
- WIDGET_ITEM_SHOW_CHANGE_INDICATOR
- ])
- ->setFlags(CWidgetField::FLAG_LABEL_ASTERISK);
-
- if (array_key_exists('show', $this->data)) {
- $field_show->setValue($this->data['show']);
- }
-
- $this->fields[$field_show->getName()] = $field_show;
-
- // Advanced configuration.
- $field_adv_conf = (new CWidgetFieldCheckBox('adv_conf', _('Advanced configuration')))->setDefault(0);
-
- if (array_key_exists('adv_conf', $this->data)) {
- $field_adv_conf->setValue($this->data['adv_conf']);
- }
-
- $this->fields[$field_adv_conf->getName()] = $field_adv_conf;
-
- // Description textarea field.
- $field_desc = (new CWidgetFieldTextArea('description', _('Description')))
- ->setDefault('{ITEM.NAME}')
- ->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
- ->setWidth(ZBX_TEXTAREA_BIG_WIDTH - 38);
-
- if (array_key_exists('description', $this->data)) {
- $field_desc->setValue($this->data['description']);
- }
-
- $this->fields[$field_desc->getName()] = $field_desc;
-
- // Description horizontal position.
- $field_desc_h_pos = (new CWidgetFieldRadioButtonList('desc_h_pos', _('Horizontal position'), [
- WIDGET_ITEM_POS_LEFT => _('Left'),
- WIDGET_ITEM_POS_CENTER => _('Center'),
- WIDGET_ITEM_POS_RIGHT => _('Right')
- ]))
- ->setDefault(WIDGET_ITEM_POS_CENTER)
- ->setModern(true);
-
- if (array_key_exists('desc_h_pos', $this->data)) {
- $field_desc_h_pos->setValue($this->data['desc_h_pos']);
- }
-
- $this->fields[$field_desc_h_pos->getName()] = $field_desc_h_pos;
-
- // Description vertical position.
- $field_desc_v_pos = (new CWidgetFieldRadioButtonList('desc_v_pos', _('Vertical position'), [
- WIDGET_ITEM_POS_TOP => _('Top'),
- WIDGET_ITEM_POS_MIDDLE => _('Middle'),
- WIDGET_ITEM_POS_BOTTOM => _('Bottom')
- ]))
- ->setDefault(WIDGET_ITEM_POS_BOTTOM)
- ->setModern(true);
-
- if (array_key_exists('desc_v_pos', $this->data)) {
- $field_desc_v_pos->setValue($this->data['desc_v_pos']);
- }
-
- $this->fields[$field_desc_v_pos->getName()] = $field_desc_v_pos;
-
- // Description size.
- $field_desc_size = (new CWidgetFieldIntegerBox('desc_size', _('Size'), self::WIDGET_ITEM_PERCENT_MIN,
- self::WIDGET_ITEM_PERCENT_MAX
- ))->setDefault(15);
-
- if (array_key_exists('desc_size', $this->data)) {
- $field_desc_size->setValue($this->data['desc_size']);
- }
-
- $this->fields[$field_desc_size->getName()] = $field_desc_size;
-
- // Description bold.
- $field_desc_bold = (new CWidgetFieldCheckBox('desc_bold', _('Bold')))->setDefault(0);
-
- if (array_key_exists('desc_bold', $this->data)) {
- $field_desc_bold->setValue($this->data['desc_bold']);
- }
-
- $this->fields[$field_desc_bold->getName()] = $field_desc_bold;
-
- // Description color.
- $field_desc_color = (new CWidgetFieldColor('desc_color', _('Color')))
- ->setDefault('');
-
- if (array_key_exists('desc_color', $this->data)) {
- $field_desc_color->setValue($this->data['desc_color']);
- }
-
- $this->fields[$field_desc_color->getName()] = $field_desc_color;
-
- // Value decimal places.
- $field_decimal_places = (new CWidgetFieldIntegerBox('decimal_places', _('Decimal places'), 0, 10))
- ->setDefault(2);
-
- if (array_key_exists('decimal_places', $this->data)) {
- $field_decimal_places->setValue($this->data['decimal_places']);
- }
-
- $this->fields[$field_decimal_places->getName()] = $field_decimal_places;
-
- // Value decimal size.
- $field_decimal_size = (new CWidgetFieldIntegerBox('decimal_size', _('Size'), self::WIDGET_ITEM_PERCENT_MIN,
- self::WIDGET_ITEM_PERCENT_MAX
- ))->setDefault(35);
-
- if (array_key_exists('decimal_size', $this->data)) {
- $field_decimal_size->setValue($this->data['decimal_size']);
- }
-
- $this->fields[$field_decimal_size->getName()] = $field_decimal_size;
-
- // Value horizontal position.
- $field_value_h_pos = (new CWidgetFieldRadioButtonList('value_h_pos', _('Horizontal position'), [
- WIDGET_ITEM_POS_LEFT => _('Left'),
- WIDGET_ITEM_POS_CENTER => _('Center'),
- WIDGET_ITEM_POS_RIGHT => _('Right')
- ]))
- ->setDefault(WIDGET_ITEM_POS_CENTER)
- ->setModern(true);
-
- if (array_key_exists('value_h_pos', $this->data)) {
- $field_value_h_pos->setValue($this->data['value_h_pos']);
- }
-
- $this->fields[$field_value_h_pos->getName()] = $field_value_h_pos;
-
- // Value vertical position.
- $field_value_v_pos = (new CWidgetFieldRadioButtonList('value_v_pos', _('Vertical position'), [
- WIDGET_ITEM_POS_TOP => _('Top'),
- WIDGET_ITEM_POS_MIDDLE => _('Middle'),
- WIDGET_ITEM_POS_BOTTOM => _('Bottom')
- ]))
- ->setDefault(WIDGET_ITEM_POS_MIDDLE)
- ->setModern(true);
-
- if (array_key_exists('value_v_pos', $this->data)) {
- $field_value_v_pos->setValue($this->data['value_v_pos']);
- }
-
- $this->fields[$field_value_v_pos->getName()] = $field_value_v_pos;
-
- // Value size.
- $field_value_size = (new CWidgetFieldIntegerBox('value_size', _('Size'), self::WIDGET_ITEM_PERCENT_MIN,
- self::WIDGET_ITEM_PERCENT_MAX
- ))->setDefault(45);
-
- if (array_key_exists('value_size', $this->data)) {
- $field_value_size->setValue($this->data['value_size']);
- }
-
- $this->fields[$field_value_size->getName()] = $field_value_size;
-
- // Value bold.
- $field_value_bold = (new CWidgetFieldCheckBox('value_bold', _('Bold')))->setDefault(1);
-
- if (array_key_exists('value_bold', $this->data)) {
- $field_value_bold->setValue($this->data['value_bold']);
- }
-
- $this->fields[$field_value_bold->getName()] = $field_value_bold;
-
- // Value color.
- $field_value_color = (new CWidgetFieldColor('value_color', _('Color')))
- ->setDefault('');
-
- if (array_key_exists('value_color', $this->data)) {
- $field_value_color->setValue($this->data['value_color']);
- }
-
- $this->fields[$field_value_color->getName()] = $field_value_color;
-
- // Units show.
- $field_units_show = (new CWidgetFieldCheckBox('units_show', _('Units')))->setDefault(1);
-
- if (array_key_exists('units_show', $this->data)) {
- $field_units_show->setValue($this->data['units_show']);
- }
-
- $this->fields[$field_units_show->getName()] = $field_units_show;
-
- // Units input field.
- $field_units = new CWidgetFieldTextBox('units', _('Units'));
-
- if (array_key_exists('units', $this->data)) {
- $field_units->setValue($this->data['units']);
- }
-
- $this->fields[$field_units->getName()] = $field_units;
-
- // Units position.
- $field_units_pos = (new CWidgetFieldSelect('units_pos', _('Position'), [
- WIDGET_ITEM_POS_BEFORE => _('Before value'),
- WIDGET_ITEM_POS_ABOVE => _('Above value'),
- WIDGET_ITEM_POS_AFTER => _('After value'),
- WIDGET_ITEM_POS_BELOW => _('Below value')
- ]))
- ->setDefault(WIDGET_ITEM_POS_AFTER);
-
- if (array_key_exists('units_pos', $this->data)) {
- $field_units_pos->setValue($this->data['units_pos']);
- }
-
- $this->fields[$field_units_pos->getName()] = $field_units_pos;
-
- // Units size.
- $field_units_size = (new CWidgetFieldIntegerBox('units_size', _('Size'), self::WIDGET_ITEM_PERCENT_MIN,
- self::WIDGET_ITEM_PERCENT_MAX
- ))->setDefault(35);
-
- if (array_key_exists('units_size', $this->data)) {
- $field_units_size->setValue($this->data['units_size']);
- }
-
- $this->fields[$field_units_size->getName()] = $field_units_size;
-
- // Units bold.
- $field_units_bold = (new CWidgetFieldCheckBox('units_bold', _('Bold')))->setDefault(1);
-
- if (array_key_exists('units_bold', $this->data)) {
- $field_units_bold->setValue($this->data['units_bold']);
- }
-
- $this->fields[$field_units_bold->getName()] = $field_units_bold;
-
- // Units color.
- $field_units_color = (new CWidgetFieldColor('units_color', _('Color')))
- ->setDefault('');
-
- if (array_key_exists('units_color', $this->data)) {
- $field_units_color->setValue($this->data['units_color']);
- }
-
- $this->fields[$field_units_color->getName()] = $field_units_color;
-
- // Time horizontal position.
- $field_time_h_pos = (new CWidgetFieldRadioButtonList('time_h_pos', _('Horizontal position'), [
- WIDGET_ITEM_POS_LEFT => _('Left'),
- WIDGET_ITEM_POS_CENTER => _('Center'),
- WIDGET_ITEM_POS_RIGHT => _('Right')
- ]))
- ->setDefault(WIDGET_ITEM_POS_CENTER)
- ->setModern(true);
-
- if (array_key_exists('time_h_pos', $this->data)) {
- $field_time_h_pos->setValue($this->data['time_h_pos']);
- }
-
- $this->fields[$field_time_h_pos->getName()] = $field_time_h_pos;
-
- // Time vertical position.
- $field_time_v_pos = (new CWidgetFieldRadioButtonList('time_v_pos', _('Vertical position'), [
- WIDGET_ITEM_POS_TOP => _('Top'),
- WIDGET_ITEM_POS_MIDDLE => _('Middle'),
- WIDGET_ITEM_POS_BOTTOM => _('Bottom')
- ]))
- ->setDefault(WIDGET_ITEM_POS_TOP)
- ->setModern(true);
-
- if (array_key_exists('time_v_pos', $this->data)) {
- $field_time_v_pos->setValue($this->data['time_v_pos']);
- }
-
- $this->fields[$field_time_v_pos->getName()] = $field_time_v_pos;
-
- // Time size.
- $field_time_size = (new CWidgetFieldIntegerBox('time_size', _('Size'), self::WIDGET_ITEM_PERCENT_MIN,
- self::WIDGET_ITEM_PERCENT_MAX
- ))->setDefault(15);
-
- if (array_key_exists('time_size', $this->data)) {
- $field_time_size->setValue($this->data['time_size']);
- }
-
- $this->fields[$field_time_size->getName()] = $field_time_size;
-
- // Time bold.
- $field_time_bold = (new CWidgetFieldCheckBox('time_bold', _('Bold')))->setDefault(0);
-
- if (array_key_exists('time_bold', $this->data)) {
- $field_time_bold->setValue($this->data['time_bold']);
- }
-
- $this->fields[$field_time_bold->getName()] = $field_time_bold;
-
- // Time color.
- $field_time_color = (new CWidgetFieldColor('time_color', _('Color')))
- ->setDefault('');
-
- if (array_key_exists('time_color', $this->data)) {
- $field_time_color->setValue($this->data['time_color']);
- }
-
- $this->fields[$field_time_color->getName()] = $field_time_color;
-
- // Change indicator up arrow color.
- $field_up_color = (new CWidgetFieldColor('up_color', _('Change indicator')))
- ->setDefault('');
-
- if (array_key_exists('up_color', $this->data)) {
- $field_up_color->setValue($this->data['up_color']);
- }
-
- $this->fields[$field_up_color->getName()] = $field_up_color;
-
- // Change indicator down arrow color.
- $field_down_color = (new CWidgetFieldColor('down_color', _('Change indicator')))
- ->setDefault('');
-
- if (array_key_exists('down_color', $this->data)) {
- $field_down_color->setValue($this->data['down_color']);
- }
-
- $this->fields[$field_down_color->getName()] = $field_down_color;
-
- // Change indicator up/down arrow color.
- $field_updown_color = (new CWidgetFieldColor('updown_color', _('Change indicator')))
- ->setDefault('');
-
- if (array_key_exists('updown_color', $this->data)) {
- $field_updown_color->setValue($this->data['updown_color']);
- }
-
- $this->fields[$field_updown_color->getName()] = $field_updown_color;
-
- // Background color.
- $field_bg_color = (new CWidgetFieldColor('bg_color', _('Background color')))
- ->setDefault('');
-
- if (array_key_exists('bg_color', $this->data)) {
- $field_bg_color->setValue($this->data['bg_color']);
- }
-
- $this->fields[$field_bg_color->getName()] = $field_bg_color;
-
- // Thresholds.
- $field_thresholds = (new CWidgetFieldThresholds('thresholds', _('Thresholds')));
-
- if (array_key_exists('thresholds', $this->data)) {
- $field_thresholds->setValue($this->data['thresholds']);
- }
-
- $this->fields[$field_thresholds->getName()] = $field_thresholds;
-
- // Dynamic item.
- if ($templateid === null) {
- $dynamic_item = (new CWidgetFieldCheckBox('dynamic', _('Enable host selection')))->setDefault(WIDGET_SIMPLE_ITEM);
-
- if (array_key_exists('dynamic', $this->data)) {
- $dynamic_item->setValue($this->data['dynamic']);
- }
-
- $this->fields[$dynamic_item->getName()] = $dynamic_item;
- }
- }
-
- /**
- * Validate form fields.
- *
- * @param bool $strict Enables more strict validation of the form fields.
- * Must be enabled for validation of input parameters in the widget configuration form.
- *
- * @return array
- */
- public function validate($strict = false) {
- $errors = parent::validate($strict);
-
- // Check if one of the objects (description, value or time) occupies same space.
- $fields = [
- ['show' => WIDGET_ITEM_SHOW_DESCRIPTION, 'h_pos' => 'desc_h_pos', 'v_pos' => 'desc_v_pos'],
- ['show' => WIDGET_ITEM_SHOW_VALUE, 'h_pos' => 'value_h_pos', 'v_pos' => 'value_v_pos'],
- ['show' => WIDGET_ITEM_SHOW_TIME, 'h_pos' => 'time_h_pos', 'v_pos' => 'time_v_pos']
- ];
- $fields_count = count($fields);
- $show = $this->fields['show']->getValue();
-
- for ($i = 0; $i < $fields_count - 1; $i++) {
- if (!in_array($fields[$i]['show'], $show)) {
- continue;
- }
-
- $i_h_pos = $this->fields[$fields[$i]['h_pos']]->getValue();
- $i_v_pos = $this->fields[$fields[$i]['v_pos']]->getValue();
-
- for ($j = $i + 1; $j < $fields_count; $j++) {
- if (!in_array($fields[$j]['show'], $show)) {
- continue;
- }
-
- $j_h_pos = $this->fields[$fields[$j]['h_pos']]->getValue();
- $j_v_pos = $this->fields[$fields[$j]['v_pos']]->getValue();
-
- if ($i_h_pos == $j_h_pos && $i_v_pos == $j_v_pos) {
- $errors[] = _('Two or more fields cannot occupy same space.');
- break 2;
- }
- }
- }
-
- return $errors;
- }
-}
diff --git a/ui/include/classes/widgets/forms/CWidgetFormMap.php b/ui/include/classes/widgets/forms/CWidgetFormMap.php
deleted file mode 100644
index 4f1230e95be..00000000000
--- a/ui/include/classes/widgets/forms/CWidgetFormMap.php
+++ /dev/null
@@ -1,80 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Map widget form.
- */
-class CWidgetFormMap extends CWidgetForm {
-
- public function __construct($data, $templateid) {
- parent::__construct($data, $templateid, WIDGET_MAP);
-
- // Widget reference field.
- $field_reference = (new CWidgetFieldReference())->setDefault('');
-
- if (array_key_exists($field_reference->getName(), $this->data)) {
- $field_reference->setValue($this->data[$field_reference->getName()]);
- }
-
- $this->fields[$field_reference->getName()] = $field_reference;
-
- // Select source type field.
- $field_source_type = (new CWidgetFieldRadioButtonList('source_type', _('Source type'), [
- WIDGET_SYSMAP_SOURCETYPE_MAP => _('Map'),
- WIDGET_SYSMAP_SOURCETYPE_FILTER => _('Map navigation tree')
- ]))
- ->setDefault(WIDGET_SYSMAP_SOURCETYPE_MAP)
- ->setAction('ZABBIX.Dashboard.reloadWidgetProperties()')
- ->setModern(true);
-
- if (array_key_exists('source_type', $this->data)) {
- $field_source_type->setValue($this->data['source_type']);
- }
-
- $this->fields[$field_source_type->getName()] = $field_source_type;
-
- if ($field_source_type->getValue() === WIDGET_SYSMAP_SOURCETYPE_FILTER) {
- // Select filter widget field.
- $field_filter_widget = (new CWidgetFieldWidgetSelect('filter_widget_reference', _('Filter'),
- WIDGET_NAV_TREE
- ))
- ->setDefault('')
- ->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK);
-
- if (array_key_exists('filter_widget_reference', $this->data)) {
- $field_filter_widget->setValue($this->data['filter_widget_reference']);
- }
-
- $this->fields[$field_filter_widget->getName()] = $field_filter_widget;
- }
- else {
- // Select sysmap field.
- $field_map = (new CWidgetFieldSelectResource('sysmapid', _('Map'), WIDGET_FIELD_SELECT_RES_SYSMAP))
- ->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK);
-
- if (array_key_exists('sysmapid', $this->data)) {
- $field_map->setValue($this->data['sysmapid']);
- }
-
- $this->fields[$field_map->getName()] = $field_map;
- }
- }
-}
diff --git a/ui/include/classes/widgets/forms/CWidgetFormNavTree.php b/ui/include/classes/widgets/forms/CWidgetFormNavTree.php
deleted file mode 100644
index fa5e68a87a2..00000000000
--- a/ui/include/classes/widgets/forms/CWidgetFormNavTree.php
+++ /dev/null
@@ -1,60 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Map navigation widget form.
- */
-class CWidgetFormNavTree extends CWidgetForm {
-
- public function __construct($data, $templateid) {
- parent::__construct($data, $templateid, WIDGET_NAV_TREE);
-
- $this->data = self::convertDottedKeys($this->data);
-
- // Widget reference field.
- $field_reference = (new CWidgetFieldReference())->setDefault('');
-
- if (array_key_exists($field_reference->getName(), $this->data)) {
- $field_reference->setValue($this->data[$field_reference->getName()]);
- }
-
- $this->fields[$field_reference->getName()] = $field_reference;
-
- // Elements of the tree.
- $field_navtree = new CWidgetFieldNavTree('navtree', '');
-
- if (array_key_exists('navtree', $this->data)) {
- $field_navtree->setValue($this->data['navtree']);
- }
-
- $this->fields[$field_navtree->getName()] = $field_navtree;
-
- // Show unavailable maps.
- $show_unavailable_maps = (new CWidgetFieldCheckBox('show_unavailable', _('Show unavailable maps')))
- ->setDefault(0);
-
- if (array_key_exists('show_unavailable', $this->data)) {
- $show_unavailable_maps->setValue($this->data['show_unavailable']);
- }
-
- $this->fields[$show_unavailable_maps->getName()] = $show_unavailable_maps;
- }
-}
diff --git a/ui/include/classes/widgets/forms/CWidgetFormPlainText.php b/ui/include/classes/widgets/forms/CWidgetFormPlainText.php
deleted file mode 100644
index fd5ed730fb4..00000000000
--- a/ui/include/classes/widgets/forms/CWidgetFormPlainText.php
+++ /dev/null
@@ -1,87 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Plain text widget form.
- */
-class CWidgetFormPlainText extends CWidgetForm {
-
- public function __construct($data, $templateid) {
- parent::__construct($data, $templateid, WIDGET_PLAIN_TEXT);
-
- // Items selector.
- $field_items = (new CWidgetFieldMsItem('itemids', _('Items'), $templateid))
- ->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK);
-
- if (array_key_exists('itemids', $this->data)) {
- $field_items->setValue($this->data['itemids']);
- }
-
- $this->fields[$field_items->getName()] = $field_items;
-
- // Location of the item names.
- $field_style = (new CWidgetFieldRadioButtonList('style', _('Items location'), [
- STYLE_LEFT => _('Left'),
- STYLE_TOP => _('Top')
- ]))
- ->setDefault(STYLE_LEFT)
- ->setModern(true);
-
- if (array_key_exists('style', $this->data)) {
- $field_style->setValue($this->data['style']);
- }
-
- $this->fields[$field_style->getName()] = $field_style;
-
- // Number of records to display.
- $field_lines = (new CWidgetFieldIntegerBox('show_lines', _('Show lines'), ZBX_MIN_WIDGET_LINES,
- ZBX_MAX_WIDGET_LINES
- ))
- ->setFlags(CWidgetField::FLAG_LABEL_ASTERISK)
- ->setDefault(ZBX_DEFAULT_WIDGET_LINES);
-
- if (array_key_exists('show_lines', $this->data)) {
- $field_lines->setValue($this->data['show_lines']);
- }
-
- $this->fields[$field_lines->getName()] = $field_lines;
-
- // Show text as HTML.
- $field_show_as_html = (new CWidgetFieldCheckBox('show_as_html', _('Show text as HTML')))->setDefault(0);
-
- if (array_key_exists('show_as_html', $this->data)) {
- $field_show_as_html->setValue($this->data['show_as_html']);
- }
-
- $this->fields[$field_show_as_html->getName()] = $field_show_as_html;
-
- // Dynamic item.
- if ($templateid === null) {
- $dynamic_item = (new CWidgetFieldCheckBox('dynamic', _('Enable host selection')))->setDefault(WIDGET_SIMPLE_ITEM);
-
- if (array_key_exists('dynamic', $this->data)) {
- $dynamic_item->setValue($this->data['dynamic']);
- }
-
- $this->fields[$dynamic_item->getName()] = $dynamic_item;
- }
- }
-}
diff --git a/ui/include/classes/widgets/forms/CWidgetFormProblemHosts.php b/ui/include/classes/widgets/forms/CWidgetFormProblemHosts.php
deleted file mode 100644
index 9db26f80e32..00000000000
--- a/ui/include/classes/widgets/forms/CWidgetFormProblemHosts.php
+++ /dev/null
@@ -1,136 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Problem hosts widget form.
- */
-class CWidgetFormProblemHosts extends CWidgetForm {
-
- public function __construct($data, $templateid) {
- parent::__construct($data, $templateid, WIDGET_PROBLEM_HOSTS);
-
- $this->data = self::convertDottedKeys($this->data);
-
- // Host groups.
- $field_groups = new CWidgetFieldMsGroup('groupids', _('Host groups'));
-
- if (array_key_exists('groupids', $this->data)) {
- $field_groups->setValue($this->data['groupids']);
- }
-
- $this->fields[$field_groups->getName()] = $field_groups;
-
- // Exclude host groups.
- $field_exclude_groups = new CWidgetFieldMsGroup('exclude_groupids', _('Exclude host groups'));
-
- if (array_key_exists('exclude_groupids', $this->data)) {
- $field_exclude_groups->setValue($this->data['exclude_groupids']);
- }
-
- $this->fields[$field_exclude_groups->getName()] = $field_exclude_groups;
-
- // Hosts field.
- $field_hosts = new CWidgetFieldMsHost('hostids', _('Hosts'));
- $field_hosts->setFilterPreselect('groupids_');
-
- if (array_key_exists('hostids', $this->data)) {
- $field_hosts->setValue($this->data['hostids']);
- }
-
- $this->fields[$field_hosts->getName()] = $field_hosts;
-
- // Problem field.
- $field_problem = new CWidgetFieldTextBox('problem', _('Problem'));
-
- if (array_key_exists('problem', $this->data)) {
- $field_problem->setValue($this->data['problem']);
- }
-
- $this->fields[$field_problem->getName()] = $field_problem;
-
- // Severity field.
- $field_severities = new CWidgetFieldSeverities('severities', _('Severity'));
-
- if (array_key_exists('severities', $this->data)) {
- $field_severities->setValue($this->data['severities']);
- }
-
- $this->fields[$field_severities->getName()] = $field_severities;
-
- // Tag evaltype (And/Or).
- $field_evaltype = (new CWidgetFieldRadioButtonList('evaltype', _('Tags'), [
- TAG_EVAL_TYPE_AND_OR => _('And/Or'),
- TAG_EVAL_TYPE_OR => _('Or')
- ]))
- ->setDefault(TAG_EVAL_TYPE_AND_OR)
- ->setModern(true);
-
- if (array_key_exists('evaltype', $this->data)) {
- $field_evaltype->setValue($this->data['evaltype']);
- }
-
- $this->fields[$field_evaltype->getName()] = $field_evaltype;
-
- // Tags array: tag, operator and value. No label, because it belongs to previous group.
- $field_tags = new CWidgetFieldTags('tags', '');
-
- if (array_key_exists('tags', $this->data)) {
- $field_tags->setValue($this->data['tags']);
- }
-
- $this->fields[$field_tags->getName()] = $field_tags;
-
- // Show suppressed problems.
- $field_show_suppressed = (new CWidgetFieldCheckBox('show_suppressed', _('Show suppressed problems')))
- ->setDefault(ZBX_PROBLEM_SUPPRESSED_FALSE);
-
- if (array_key_exists('show_suppressed', $this->data)) {
- $field_show_suppressed->setValue($this->data['show_suppressed']);
- }
-
- $this->fields[$field_show_suppressed->getName()] = $field_show_suppressed;
-
- // Hide groups without problems.
- $field_hide_empty_groups = new CWidgetFieldCheckBox('hide_empty_groups', _('Hide groups without problems'));
-
- if (array_key_exists('hide_empty_groups', $this->data)) {
- $field_hide_empty_groups->setValue($this->data['hide_empty_groups']);
- }
-
- $this->fields[$field_hide_empty_groups->getName()] = $field_hide_empty_groups;
-
- // Problem display.
- $field_ext_ack = (new CWidgetFieldRadioButtonList('ext_ack', _('Problem display'), [
- EXTACK_OPTION_ALL => _('All'),
- EXTACK_OPTION_BOTH => _('Separated'),
- EXTACK_OPTION_UNACK => _('Unacknowledged only')
- ]))
- ->setDefault(EXTACK_OPTION_ALL)
- ->setFlags(CWidgetField::FLAG_ACKNOWLEDGES)
- ->setModern(true);
-
- if (array_key_exists('ext_ack', $this->data)) {
- $field_ext_ack->setValue($this->data['ext_ack']);
- }
-
- $this->fields[$field_ext_ack->getName()] = $field_ext_ack;
- }
-}
diff --git a/ui/include/classes/widgets/forms/CWidgetFormProblems.php b/ui/include/classes/widgets/forms/CWidgetFormProblems.php
deleted file mode 100644
index 5236da642de..00000000000
--- a/ui/include/classes/widgets/forms/CWidgetFormProblems.php
+++ /dev/null
@@ -1,243 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Problems widget form.
- */
-class CWidgetFormProblems extends CWidgetForm {
-
- public function __construct($data, $templateid) {
- parent::__construct($data, $templateid, WIDGET_PROBLEMS);
-
- $this->data = self::convertDottedKeys($this->data);
-
- // Output information option.
- $field_show = (new CWidgetFieldRadioButtonList('show', _('Show'), [
- TRIGGERS_OPTION_RECENT_PROBLEM => _('Recent problems'),
- TRIGGERS_OPTION_IN_PROBLEM => _('Problems'),
- TRIGGERS_OPTION_ALL => _('History')
- ]))
- ->setDefault(TRIGGERS_OPTION_RECENT_PROBLEM)
- ->setModern(true);
-
- if (array_key_exists('show', $this->data)) {
- $field_show->setValue($this->data['show']);
- }
-
- $this->fields[$field_show->getName()] = $field_show;
-
- // Host groups.
- $field_groups = new CWidgetFieldMsGroup('groupids', _('Host groups'));
-
- if (array_key_exists('groupids', $this->data)) {
- $field_groups->setValue($this->data['groupids']);
- }
-
- $this->fields[$field_groups->getName()] = $field_groups;
-
- // Exclude host groups.
- $field_exclude_groups = new CWidgetFieldMsGroup('exclude_groupids', _('Exclude host groups'));
-
- if (array_key_exists('exclude_groupids', $this->data)) {
- $field_exclude_groups->setValue($this->data['exclude_groupids']);
- }
-
- $this->fields[$field_exclude_groups->getName()] = $field_exclude_groups;
-
- // Hosts field.
- $field_hosts = new CWidgetFieldMsHost('hostids', _('Hosts'));
- $field_hosts->setFilterPreselect('groupids_');
-
- if (array_key_exists('hostids', $this->data)) {
- $field_hosts->setValue($this->data['hostids']);
- }
-
- $this->fields[$field_hosts->getName()] = $field_hosts;
-
- // Problem field.
- $field_problem = new CWidgetFieldTextBox('problem', _('Problem'));
-
- if (array_key_exists('problem', $this->data)) {
- $field_problem->setValue($this->data['problem']);
- }
-
- $this->fields[$field_problem->getName()] = $field_problem;
-
- // Severity field.
- $field_severities = new CWidgetFieldSeverities('severities', _('Severity'));
-
- if (array_key_exists('severities', $this->data)) {
- $field_severities->setValue($this->data['severities']);
- }
-
- $this->fields[$field_severities->getName()] = $field_severities;
-
- // Tag evaltype (And/Or).
- $field_evaltype = (new CWidgetFieldRadioButtonList('evaltype', _('Tags'), [
- TAG_EVAL_TYPE_AND_OR => _('And/Or'),
- TAG_EVAL_TYPE_OR => _('Or')
- ]))
- ->setDefault(TAG_EVAL_TYPE_AND_OR)
- ->setModern(true);
-
- if (array_key_exists('evaltype', $this->data)) {
- $field_evaltype->setValue($this->data['evaltype']);
- }
-
- $this->fields[$field_evaltype->getName()] = $field_evaltype;
-
- // Tags array: tag, operator and value. No label, because it belongs to previous group.
- $field_tags = new CWidgetFieldTags('tags', '');
-
- if (array_key_exists('tags', $this->data)) {
- $field_tags->setValue($this->data['tags']);
- }
-
- $this->fields[$field_tags->getName()] = $field_tags;
-
- // Show tags.
- $field_show_tags = (new CWidgetFieldRadioButtonList('show_tags', _('Show tags'), [
- SHOW_TAGS_NONE => _('None'),
- SHOW_TAGS_1 => SHOW_TAGS_1,
- SHOW_TAGS_2 => SHOW_TAGS_2,
- SHOW_TAGS_3 => SHOW_TAGS_3
- ]))
- ->setDefault(SHOW_TAGS_NONE)
- ->setModern(true)
- ->setAction('var disabled = jQuery(this).filter("[value=\''.SHOW_TAGS_NONE.'\']").is(":checked");'.
- 'jQuery("#tag_priority").prop("disabled", disabled);'.
- 'jQuery("#tag_name_format input").prop("disabled", disabled)'
- );
-
- if (array_key_exists('show_tags', $this->data)) {
- $field_show_tags->setValue($this->data['show_tags']);
- }
-
- $this->fields[$field_show_tags->getName()] = $field_show_tags;
-
- // Tag name.
- $tag_format_line = (new CWidgetFieldRadioButtonList('tag_name_format', _('Tag name'), [
- TAG_NAME_FULL => _('Full'),
- TAG_NAME_SHORTENED => _('Shortened'),
- TAG_NAME_NONE => _('None')
- ]))
- ->setDefault(TAG_NAME_FULL)
- ->setModern(true);
-
- if (array_key_exists('tag_name_format', $this->data)) {
- $tag_format_line->setValue($this->data['tag_name_format']);
- }
- $this->fields[$tag_format_line->getName()] = $tag_format_line;
-
- // Tag display priority.
- $tag_priority = (new CWidgetFieldTextBox('tag_priority', _('Tag display priority')));
-
- if (array_key_exists('tag_priority', $this->data)) {
- $tag_priority->setValue($this->data['tag_priority']);
- }
- $this->fields[$tag_priority->getName()] = $tag_priority;
-
- // Show operational data.
- $field_show_opdata = (new CWidgetFieldRadioButtonList('show_opdata', _('Show operational data'), [
- OPERATIONAL_DATA_SHOW_NONE => _('None'),
- OPERATIONAL_DATA_SHOW_SEPARATELY => _('Separately'),
- OPERATIONAL_DATA_SHOW_WITH_PROBLEM => _('With problem name')
- ]))
- ->setDefault(OPERATIONAL_DATA_SHOW_NONE)
- ->setModern(true);
-
- if (array_key_exists('show_opdata', $this->data)) {
- $field_show_opdata->setValue($this->data['show_opdata']);
- }
-
- $this->fields[$field_show_opdata->getName()] = $field_show_opdata;
-
- // Show suppressed problems.
- $field_show_suppressed = (new CWidgetFieldCheckBox('show_suppressed', _('Show suppressed problems')))
- ->setDefault(ZBX_PROBLEM_SUPPRESSED_FALSE);
-
- if (array_key_exists('show_suppressed', $this->data)) {
- $field_show_suppressed->setValue($this->data['show_suppressed']);
- }
-
- $this->fields[$field_show_suppressed->getName()] = $field_show_suppressed;
-
- // Show unacknowledged only.
- $field_unacknowledged = (new CWidgetFieldCheckBox('unacknowledged', _('Show unacknowledged only')))
- ->setFlags(CWidgetField::FLAG_ACKNOWLEDGES);
-
- if (array_key_exists('unacknowledged', $this->data)) {
- $field_unacknowledged->setValue($this->data['unacknowledged']);
- }
-
- $this->fields[$field_unacknowledged->getName()] = $field_unacknowledged;
-
- $sort_with_enabled_show_timeline = [
- SCREEN_SORT_TRIGGERS_TIME_DESC => true,
- SCREEN_SORT_TRIGGERS_TIME_ASC => true
- ];
-
- // Sort entries by.
- $field_sort = (new CWidgetFieldSelect('sort_triggers', _('Sort entries by'), [
- SCREEN_SORT_TRIGGERS_TIME_DESC => _('Time').' ('._('descending').')',
- SCREEN_SORT_TRIGGERS_TIME_ASC => _('Time').' ('._('ascending').')',
- SCREEN_SORT_TRIGGERS_SEVERITY_DESC => _('Severity').' ('._('descending').')',
- SCREEN_SORT_TRIGGERS_SEVERITY_ASC => _('Severity').' ('._('ascending').')',
- SCREEN_SORT_TRIGGERS_NAME_DESC => _('Problem').' ('._('descending').')',
- SCREEN_SORT_TRIGGERS_NAME_ASC => _('Problem').' ('._('ascending').')',
- SCREEN_SORT_TRIGGERS_HOST_NAME_DESC => _('Host').' ('._('descending').')',
- SCREEN_SORT_TRIGGERS_HOST_NAME_ASC => _('Host').' ('._('ascending').')'
- ]))
- ->setDefault(SCREEN_SORT_TRIGGERS_TIME_DESC);
-
- if (array_key_exists('sort_triggers', $this->data)) {
- $field_sort->setValue($this->data['sort_triggers']);
- }
-
- $this->fields[$field_sort->getName()] = $field_sort;
-
- // Show timeline.
- $field_show_timeline = (new CWidgetFieldCheckBox('show_timeline', _('Show timeline')))->setDefault(1);
-
- if (array_key_exists('show_timeline', $this->data)) {
- $field_show_timeline->setValue($this->data['show_timeline']);
- }
-
- if (!array_key_exists($field_sort->getValue(), $sort_with_enabled_show_timeline)) {
- $field_show_timeline->setFlags(CWidgetField::FLAG_DISABLED);
- }
-
- $this->fields[$field_show_timeline->getName()] = $field_show_timeline;
-
- // Show lines.
- $field_lines = (new CWidgetFieldIntegerBox('show_lines', _('Show lines'), ZBX_MIN_WIDGET_LINES,
- ZBX_MAX_WIDGET_LINES
- ))
- ->setFlags(CWidgetField::FLAG_LABEL_ASTERISK)
- ->setDefault(ZBX_DEFAULT_WIDGET_LINES);
-
- if (array_key_exists('show_lines', $this->data)) {
- $field_lines->setValue($this->data['show_lines']);
- }
-
- $this->fields[$field_lines->getName()] = $field_lines;
- }
-}
diff --git a/ui/include/classes/widgets/forms/CWidgetFormProblemsBySv.php b/ui/include/classes/widgets/forms/CWidgetFormProblemsBySv.php
deleted file mode 100644
index c76820d6624..00000000000
--- a/ui/include/classes/widgets/forms/CWidgetFormProblemsBySv.php
+++ /dev/null
@@ -1,202 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Problems by severity widget form.
- */
-class CWidgetFormProblemsBySv extends CWidgetForm {
-
- public function __construct($data, $templateid) {
- parent::__construct($data, $templateid, WIDGET_PROBLEMS_BY_SV);
-
- $this->data = self::convertDottedKeys($this->data);
-
- // Host groups.
- $field_groups = new CWidgetFieldMsGroup('groupids', _('Host groups'));
-
- if (array_key_exists('groupids', $this->data)) {
- $field_groups->setValue($this->data['groupids']);
- }
-
- $this->fields[$field_groups->getName()] = $field_groups;
-
- // Exclude host groups.
- $field_exclude_groups = new CWidgetFieldMsGroup('exclude_groupids', _('Exclude host groups'));
-
- if (array_key_exists('exclude_groupids', $this->data)) {
- $field_exclude_groups->setValue($this->data['exclude_groupids']);
- }
-
- $this->fields[$field_exclude_groups->getName()] = $field_exclude_groups;
-
- // Hosts field.
- $field_hosts = new CWidgetFieldMsHost('hostids', _('Hosts'));
- $field_hosts->setFilterPreselect('groupids_');
-
- if (array_key_exists('hostids', $this->data)) {
- $field_hosts->setValue($this->data['hostids']);
- }
-
- $this->fields[$field_hosts->getName()] = $field_hosts;
-
- // Problem field.
- $field_problem = new CWidgetFieldTextBox('problem', _('Problem'));
-
- if (array_key_exists('problem', $this->data)) {
- $field_problem->setValue($this->data['problem']);
- }
-
- $this->fields[$field_problem->getName()] = $field_problem;
-
- // Severity field.
- $field_severities = new CWidgetFieldSeverities('severities', _('Severity'));
-
- if (array_key_exists('severities', $this->data)) {
- $field_severities->setValue($this->data['severities']);
- }
-
- $this->fields[$field_severities->getName()] = $field_severities;
-
- // Tag evaltype (And/Or).
- $field_evaltype = (new CWidgetFieldRadioButtonList('evaltype', _('Tags'), [
- TAG_EVAL_TYPE_AND_OR => _('And/Or'),
- TAG_EVAL_TYPE_OR => _('Or')
- ]))
- ->setDefault(TAG_EVAL_TYPE_AND_OR)
- ->setModern(true);
-
- if (array_key_exists('evaltype', $this->data)) {
- $field_evaltype->setValue($this->data['evaltype']);
- }
-
- $this->fields[$field_evaltype->getName()] = $field_evaltype;
-
- // Tags array: tag, operator and value. No label, because it belongs to previous group.
- $field_tags = new CWidgetFieldTags('tags', '');
-
- if (array_key_exists('tags', $this->data)) {
- $field_tags->setValue($this->data['tags']);
- }
-
- $this->fields[$field_tags->getName()] = $field_tags;
-
- // Show type.
- $field_show_type = (new CWidgetFieldRadioButtonList('show_type', _('Show'), [
- WIDGET_PROBLEMS_BY_SV_SHOW_GROUPS => _('Host groups'),
- WIDGET_PROBLEMS_BY_SV_SHOW_TOTALS => _('Totals')
- ]))
- ->setDefault(WIDGET_PROBLEMS_BY_SV_SHOW_GROUPS)
- ->setModern(true)
- ->setAction('var disabled = jQuery(this).filter("[value=\''.WIDGET_PROBLEMS_BY_SV_SHOW_GROUPS.'\']")'.
- '.is(":checked");'.
- 'jQuery("#hide_empty_groups").prop("disabled", !disabled);'.
- 'jQuery("#layout input").prop("disabled", disabled)'
- );
-
- if (array_key_exists('show_type', $this->data)) {
- $field_show_type->setValue($this->data['show_type']);
- }
-
- $this->fields[$field_show_type->getName()] = $field_show_type;
-
- // Layout.
- $field_layout = (new CWidgetFieldRadioButtonList('layout', _('Layout'), [
- STYLE_HORIZONTAL => _('Horizontal'),
- STYLE_VERTICAL => _('Vertical')
- ]))
- ->setDefault(STYLE_HORIZONTAL)
- ->setModern(true);
-
- if (array_key_exists('layout', $this->data)) {
- $field_layout->setValue($this->data['layout']);
- }
-
- if ($field_show_type->getValue() == WIDGET_PROBLEMS_BY_SV_SHOW_GROUPS) {
- $field_layout->setFlags(CWidgetField::FLAG_DISABLED);
- }
-
- $this->fields[$field_layout->getName()] = $field_layout;
-
- // Show operational data.
- $field_show_opdata = (new CWidgetFieldRadioButtonList('show_opdata', _('Show operational data'), [
- OPERATIONAL_DATA_SHOW_NONE => _('None'),
- OPERATIONAL_DATA_SHOW_SEPARATELY => _('Separately'),
- OPERATIONAL_DATA_SHOW_WITH_PROBLEM => _('With problem name')
- ]))
- ->setDefault(OPERATIONAL_DATA_SHOW_NONE)
- ->setModern(true);
-
- if (array_key_exists('show_opdata', $this->data)) {
- $field_show_opdata->setValue($this->data['show_opdata']);
- }
-
- $this->fields[$field_show_opdata->getName()] = $field_show_opdata;
-
- // Show suppressed problems.
- $field_show_suppressed = (new CWidgetFieldCheckBox('show_suppressed', _('Show suppressed problems')))
- ->setDefault(ZBX_PROBLEM_SUPPRESSED_FALSE);
-
- if (array_key_exists('show_suppressed', $this->data)) {
- $field_show_suppressed->setValue($this->data['show_suppressed']);
- }
-
- $this->fields[$field_show_suppressed->getName()] = $field_show_suppressed;
-
- // Hide groups without problems.
- $field_hide_empty_groups = new CWidgetFieldCheckBox('hide_empty_groups', _('Hide groups without problems'));
-
- if (array_key_exists('hide_empty_groups', $this->data)) {
- $field_hide_empty_groups->setValue($this->data['hide_empty_groups']);
- }
-
- if ($field_show_type->getValue() == WIDGET_PROBLEMS_BY_SV_SHOW_TOTALS) {
- $field_hide_empty_groups->setFlags(CWidgetField::FLAG_DISABLED);
- }
-
- $this->fields[$field_hide_empty_groups->getName()] = $field_hide_empty_groups;
-
- // Problem display.
- $field_ext_ack = (new CWidgetFieldRadioButtonList('ext_ack', _('Problem display'), [
- EXTACK_OPTION_ALL => _('All'),
- EXTACK_OPTION_BOTH => _('Separated'),
- EXTACK_OPTION_UNACK => _('Unacknowledged only')
- ]))
- ->setDefault(EXTACK_OPTION_ALL)
- ->setFlags(CWidgetField::FLAG_ACKNOWLEDGES)
- ->setModern(true);
-
- if (array_key_exists('ext_ack', $this->data)) {
- $field_ext_ack->setValue($this->data['ext_ack']);
- }
-
- $this->fields[$field_ext_ack->getName()] = $field_ext_ack;
-
- // Show timeline.
- $field_show_timeline = (new CWidgetFieldCheckBox('show_timeline', _('Show timeline')))
- ->setDefault(1);
-
- if (array_key_exists('show_timeline', $this->data)) {
- $field_show_timeline->setValue($this->data['show_timeline']);
- }
-
- $this->fields[$field_show_timeline->getName()] = $field_show_timeline;
- }
-}
diff --git a/ui/include/classes/widgets/forms/CWidgetFormSlaReport.php b/ui/include/classes/widgets/forms/CWidgetFormSlaReport.php
deleted file mode 100644
index e1a2f2705b0..00000000000
--- a/ui/include/classes/widgets/forms/CWidgetFormSlaReport.php
+++ /dev/null
@@ -1,145 +0,0 @@
-<?php declare(strict_types = 0);
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-class CWidgetFormSlaReport extends CWidgetForm
-{
- public function __construct($data, $templateid) {
- parent::__construct($data, $templateid, WIDGET_SLA_REPORT);
-
- // SLA.
- $field_sla = (new CWidgetFieldMsSla('slaid', _('SLA')))
- ->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
- ->setMultiple(false);
-
- if (array_key_exists('slaid', $this->data)) {
- $field_sla->setValue($this->data['slaid']);
- }
-
- $this->fields[$field_sla->getName()] = $field_sla;
-
- // Service.
- $field_service = (new CWidgetFieldMsService('serviceid', _('Service')))
- ->setMultiple(false);
-
- if (array_key_exists('serviceid', $this->data)) {
- $field_service->setValue($this->data['serviceid']);
- }
-
- $this->fields[$field_service->getName()] = $field_service;
-
- // Show periods.
- $field_show_periods = (new CWidgetFieldIntegerBox('show_periods', _('Show periods'), 1,
- ZBX_SLA_MAX_REPORTING_PERIODS
- ))->setDefault(ZBX_SLA_DEFAULT_REPORTING_PERIODS);
-
- if (array_key_exists('show_periods', $this->data)) {
- $field_show_periods->setValue($this->data['show_periods']);
- }
-
- $this->fields[$field_show_periods->getName()] = $field_show_periods;
-
- // Date from.
- $field_date_from = new CWidgetFieldDatePicker('date_from', _('From'), true);
-
- if (array_key_exists('date_from', $this->data)) {
- $field_date_from->setValue($this->data['date_from']);
- }
-
- $this->fields[$field_date_from->getName()] = $field_date_from;
-
- // Date to.
- $field_date_to = new CWidgetFieldDatePicker('date_to', _('To'), true);
-
- if (array_key_exists('date_to', $this->data)) {
- $field_date_to->setValue($this->data['date_to']);
- }
-
- $this->fields[$field_date_to->getName()] = $field_date_to;
- }
-
- /**
- * @param bool $strict
- *
- * @return array
- */
- public function validate($strict = false): array {
- if ($errors = parent::validate($strict)) {
- return $errors;
- }
-
- $errors = [];
-
- $slaids = $this->fields['slaid']->getValue();
-
- $slas = $slaids
- ? API::Sla()->get([
- 'output' => ['timezone'],
- 'slaids' => $slaids,
- 'filter' => [
- 'status' => ZBX_SLA_STATUS_ENABLED
- ]
- ])
- : [];
-
- $sla = $slas ? $slas[0] : null;
-
- $timezone = new DateTimeZone($sla !== null && $sla['timezone'] !== ZBX_DEFAULT_TIMEZONE
- ? $sla['timezone']
- : CTimezoneHelper::getSystemTimezone()
- );
-
- $absolute_time_parser = new CAbsoluteTimeParser();
-
- $period_from = null;
-
- if ($absolute_time_parser->parse($this->fields['date_from']->getValue()) == CParser::PARSE_SUCCESS) {
- $period_from = $absolute_time_parser
- ->getDateTime(true, $timezone)
- ->getTimestamp();
-
- if ($period_from < 0 || $period_from > ZBX_MAX_DATE) {
- $period_from = null;
-
- $errors[] = _s('Incorrect value for field "%1$s": %2$s.', _s('From'), _('a date is expected'));
- }
- }
-
- $period_to = null;
-
- if ($absolute_time_parser->parse($this->fields['date_to']->getValue()) == CParser::PARSE_SUCCESS) {
- $period_to = $absolute_time_parser
- ->getDateTime(false, $timezone)
- ->getTimestamp();
-
- if ($period_to < 0 || $period_to > ZBX_MAX_DATE) {
- $period_to = null;
-
- $errors[] = _s('Incorrect value for field "%1$s": %2$s.', _s('To'), _('a date is expected'));
- }
- }
-
- if ($period_from !== null && $period_to !== null && $period_to <= $period_from) {
- $errors[] = _s('"%1$s" date must be less than "%2$s" date.', _('From'), _('To'));
- }
-
- return $errors;
- }
-}
diff --git a/ui/include/classes/widgets/forms/CWidgetFormSvgGraph.php b/ui/include/classes/widgets/forms/CWidgetFormSvgGraph.php
deleted file mode 100644
index ca4f60adc92..00000000000
--- a/ui/include/classes/widgets/forms/CWidgetFormSvgGraph.php
+++ /dev/null
@@ -1,635 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-class CWidgetFormSvgGraph extends CWidgetForm {
-
- private const WIDGET_ITEM_PERCENTILE_MIN = 1;
- private const WIDGET_ITEM_PERCENTILE_MAX = 100;
-
- public function __construct($data, $templateid) {
- parent::__construct($data, $templateid, WIDGET_SVG_GRAPH);
-
- $this->data = self::convertDottedKeys($this->data);
-
- $this->initDataSetFields();
- $this->initDisplayingOptionsFields();
- $this->initTimePeriodFields();
- $this->initAxesFields();
- $this->initLegendFields();
- $this->initProblemsFields();
- $this->initOverridesFields();
- }
-
- /**
- * Validate form fields.
- *
- * @param bool $strict Enables more strict validation of the form fields.
- * Must be enabled for validation of input parameters in the widget configuration form.
- *
- * @throws Exception
- *
- * @return array
- */
- public function validate($strict = false): array {
- $errors = parent::validate($strict);
-
- $number_parser_w_suffix = new CNumberParser(['with_size_suffix' => true, 'with_time_suffix' => true]);
- $number_parser_wo_suffix = new CNumberParser();
-
- // Percentiles
- if ($this->fields['percentile_left']->getValue() == SVG_GRAPH_PERCENTILE_LEFT_ON) {
- $percentile_left_value = $this->fields['percentile_left_value']->getValue();
-
- if ($percentile_left_value !== '') {
- $percentile_left_value_calculated =
- $number_parser_wo_suffix->parse($percentile_left_value) == CParser::PARSE_SUCCESS
- ? $number_parser_wo_suffix->calcValue()
- : null;
-
- if ($percentile_left_value_calculated === null
- || $percentile_left_value_calculated < self::WIDGET_ITEM_PERCENTILE_MIN
- || $percentile_left_value_calculated > self::WIDGET_ITEM_PERCENTILE_MAX) {
- $errors[] = _s('Invalid parameter "%1$s": %2$s.', _('Percentile line (left)'),
- _s('value must be between "%1$s" and "%2$s"', self::WIDGET_ITEM_PERCENTILE_MIN,
- self::WIDGET_ITEM_PERCENTILE_MAX
- )
- );
- }
- }
- }
-
- if ($this->fields['percentile_right']->getValue() == SVG_GRAPH_PERCENTILE_RIGHT_ON) {
- $percentile_right_value = $this->fields['percentile_right_value']->getValue();
-
- if ($percentile_right_value !== '') {
- $percentile_right_value_calculated =
- $number_parser_wo_suffix->parse($percentile_right_value) == CParser::PARSE_SUCCESS
- ? $number_parser_wo_suffix->calcValue()
- : null;
-
- if ($percentile_right_value_calculated === null
- || $percentile_right_value_calculated < self::WIDGET_ITEM_PERCENTILE_MIN
- || $percentile_right_value_calculated > self::WIDGET_ITEM_PERCENTILE_MAX) {
- $errors[] = _s('Invalid parameter "%1$s": %2$s.', _('Percentile line (right)'),
- _s('value must be between "%1$s" and "%2$s"', self::WIDGET_ITEM_PERCENTILE_MIN,
- self::WIDGET_ITEM_PERCENTILE_MAX
- )
- );
- }
- }
- }
-
- // Test graph custom time period.
- if ($this->fields['graph_time']->getValue() == SVG_GRAPH_CUSTOM_TIME) {
- $errors = array_merge($errors, self::validateTimeSelectorPeriod($this->fields['time_from']->getValue(),
- $this->fields['time_to']->getValue()
- ));
- }
-
- // Validate Min/Max values in Axes tab.
- if ($this->fields['lefty']->getValue() == SVG_GRAPH_AXIS_SHOW) {
- $lefty_min =
- $number_parser_w_suffix->parse($this->fields['lefty_min']->getValue()) == CParser::PARSE_SUCCESS
- ? $number_parser_w_suffix->calcValue()
- : '';
-
- $lefty_max =
- $number_parser_w_suffix->parse($this->fields['lefty_max']->getValue()) == CParser::PARSE_SUCCESS
- ? $number_parser_w_suffix->calcValue()
- : '';
-
- if ($lefty_min !== '' && $lefty_max !== '' && $lefty_min >= $lefty_max) {
- $errors[] = _s('Invalid parameter "%1$s": %2$s.', _('Left Y').'/'._('Max'),
- _('Y axis MAX value must be greater than Y axis MIN value')
- );
- }
- }
-
- if ($this->fields['righty']->getValue() == SVG_GRAPH_AXIS_SHOW) {
- $righty_min =
- $number_parser_w_suffix->parse($this->fields['righty_min']->getValue()) == CParser::PARSE_SUCCESS
- ? $number_parser_w_suffix->calcValue()
- : '';
-
- $righty_max =
- $number_parser_w_suffix->parse($this->fields['righty_max']->getValue()) == CParser::PARSE_SUCCESS
- ? $number_parser_w_suffix->calcValue()
- : '';
-
- if ($righty_min !== '' && $righty_max !== '' && $righty_min >= $righty_max) {
- $errors[] = _s('Invalid parameter "%1$s": %2$s.', _('Right Y').'/'._('Max'),
- _('Y axis MAX value must be greater than Y axis MIN value')
- );
- }
- }
-
- return $errors;
- }
-
- /**
- * Check if widget configuration is set to use overridden time.
- *
- * @param array $fields Widget configuration fields.
- *
- * @return bool
- */
- public static function hasOverrideTime(array $fields): bool {
- return array_key_exists('graph_time', $fields) && $fields['graph_time'] == SVG_GRAPH_CUSTOM_TIME;
- }
-
- private function initDataSetFields(): void {
- $field_ds = (new CWidgetFieldGraphDataSet('ds', _('Data set')))->setFlags(CWidgetField::FLAG_NOT_EMPTY);
-
- if (array_key_exists('ds', $this->data)) {
- $field_ds->setValue($this->data['ds']);
- }
-
- $this->fields[$field_ds->getName()] = $field_ds;
- }
-
- private function initDisplayingOptionsFields(): void {
- // History data selection.
- $field_data_source = (new CWidgetFieldRadioButtonList('source', _('History data selection'), [
- SVG_GRAPH_DATA_SOURCE_AUTO => _x('Auto', 'history source selection method'),
- SVG_GRAPH_DATA_SOURCE_HISTORY => _('History'),
- SVG_GRAPH_DATA_SOURCE_TRENDS => _('Trends')
- ]))
- ->setDefault(SVG_GRAPH_DATA_SOURCE_AUTO)
- ->setModern(true);
-
- if (array_key_exists('source', $this->data)) {
- $field_data_source->setValue($this->data['source']);
- }
-
- $this->fields[$field_data_source->getName()] = $field_data_source;
-
- // Simple triggers.
- $field_simple_triggers = new CWidgetFieldCheckBox('simple_triggers', _('Simple triggers'));
-
- if (array_key_exists('simple_triggers', $this->data)) {
- $field_simple_triggers->setValue($this->data['simple_triggers']);
- }
-
- $this->fields[$field_simple_triggers->getName()] = $field_simple_triggers;
-
- // Working time.
- $field_working_time = new CWidgetFieldCheckBox('working_time', _('Working time'));
-
- if (array_key_exists('working_time', $this->data)) {
- $field_working_time->setValue($this->data['working_time']);
- }
-
- $this->fields[$field_working_time->getName()] = $field_working_time;
-
- // Percentile line left.
- $field_percentile_left = new CWidgetFieldCheckBox('percentile_left', _('Percentile line (left)'));
-
- if (array_key_exists('percentile_left', $this->data)) {
- $field_percentile_left->setValue($this->data['percentile_left']);
- }
-
- $this->fields[$field_percentile_left->getName()] = $field_percentile_left;
-
- // Percentile line left value.
- $field_percentile_left_value = (new CWidgetFieldTextBox('percentile_left_value', null))
- ->setPlaceholder(_('value'))
- ->setWidth(ZBX_TEXTAREA_TINY_WIDTH);
-
- if ($field_percentile_left->getValue() != SVG_GRAPH_PERCENTILE_LEFT_ON) {
- $field_percentile_left_value->setFlags(CWidgetField::FLAG_DISABLED);
- }
- elseif (array_key_exists('percentile_left_value', $this->data)) {
- $field_percentile_left_value->setValue($this->data['percentile_left_value']);
- }
-
- $this->fields[$field_percentile_left_value->getName()] = $field_percentile_left_value;
-
- // Percentile line right.
- $field_percentile_right = new CWidgetFieldCheckBox('percentile_right', _('Percentile line (right)'));
-
- if (array_key_exists('percentile_right', $this->data)) {
- $field_percentile_right->setValue($this->data['percentile_right']);
- }
-
- $this->fields[$field_percentile_right->getName()] = $field_percentile_right;
-
- // Percentile line right value.
- $field_percentile_right_value = (new CWidgetFieldTextBox('percentile_right_value', null))
- ->setPlaceholder(_('value'))
- ->setWidth(ZBX_TEXTAREA_TINY_WIDTH);
-
- if ($field_percentile_right->getValue() != SVG_GRAPH_PERCENTILE_RIGHT_ON) {
- $field_percentile_right_value->setFlags(CWidgetField::FLAG_DISABLED);
- }
- elseif (array_key_exists('percentile_right_value', $this->data)) {
- $field_percentile_right_value->setValue($this->data['percentile_right_value']);
- }
-
- $this->fields[$field_percentile_right_value->getName()] = $field_percentile_right_value;
- }
-
- private function initTimePeriodFields(): void {
- // Checkbox to specify either relative dashboard time or widget's own time.
- $field_graph_time = new CWidgetFieldCheckBox('graph_time', _('Set custom time period'));
-
- if (array_key_exists('graph_time', $this->data)) {
- $field_graph_time->setValue($this->data['graph_time']);
- }
-
- $this->fields[$field_graph_time->getName()] = $field_graph_time;
-
- // Date from.
- $field_time_from = (new CWidgetFieldDatePicker('time_from', _('From'), false))
- ->setDefault('now-1h')
- ->setFlags(CWidgetField::FLAG_NOT_EMPTY);
-
- if ($field_graph_time->getValue() != SVG_GRAPH_CUSTOM_TIME) {
- $field_time_from->setFlags(CWidgetField::FLAG_DISABLED);
- }
- elseif (array_key_exists('time_from', $this->data)) {
- $field_time_from->setValue($this->data['time_from']);
- }
-
- $this->fields[$field_time_from->getName()] = $field_time_from;
-
- // Time to.
- $field_time_to = (new CWidgetFieldDatePicker('time_to', _('To'), false))
- ->setDefault('now')
- ->setFlags(CWidgetField::FLAG_NOT_EMPTY);
-
- if ($field_graph_time->getValue() != SVG_GRAPH_CUSTOM_TIME) {
- $field_time_to->setFlags(CWidgetField::FLAG_DISABLED);
- }
- elseif (array_key_exists('time_to', $this->data)) {
- $field_time_to->setValue($this->data['time_to']);
- }
-
- $this->fields[$field_time_to->getName()] = $field_time_to;
- }
-
- private function initAxesFields(): void {
- // Show left Y axis.
- $field_lefty = (new CWidgetFieldCheckBox('lefty', _('Left Y'), _('Show')))->setDefault(SVG_GRAPH_AXIS_SHOW);
-
- if (array_key_exists('lefty', $this->data)) {
- $field_lefty->setValue($this->data['lefty']);
- }
-
- $this->fields[$field_lefty->getName()] = $field_lefty;
-
- // Min value on left Y axis.
- $field_lefty_min = (new CWidgetFieldNumericBox('lefty_min', _('Min')))
- ->setPlaceholder(_('calculated'))
- ->setFullName(_('Left Y').'/'._('Min'))
- ->setWidth(ZBX_TEXTAREA_SMALL_WIDTH);
-
- if ($field_lefty->getValue() != SVG_GRAPH_AXIS_SHOW) {
- $field_lefty_min->setFlags(CWidgetField::FLAG_DISABLED);
- }
- elseif (array_key_exists('lefty_min', $this->data)) {
- $field_lefty_min->setValue($this->data['lefty_min']);
- }
-
- $this->fields[$field_lefty_min->getName()] = $field_lefty_min;
-
- // Max value on left Y axis.
- $field_lefty_max = (new CWidgetFieldNumericBox('lefty_max', _('Max')))
- ->setPlaceholder(_('calculated'))
- ->setFullName(_('Left Y').'/'._('Max'))
- ->setWidth(ZBX_TEXTAREA_SMALL_WIDTH);
-
- if ($field_lefty->getValue() != SVG_GRAPH_AXIS_SHOW) {
- $field_lefty_max->setFlags(CWidgetField::FLAG_DISABLED);
- }
- elseif (array_key_exists('lefty_max', $this->data)) {
- $field_lefty_max->setValue($this->data['lefty_max']);
- }
-
- $this->fields[$field_lefty_max->getName()] = $field_lefty_max;
-
- // Specify the type of units on left Y axis.
- $field_lefty_units = (new CWidgetFieldSelect('lefty_units', _('Units'), [
- SVG_GRAPH_AXIS_UNITS_AUTO => _x('Auto', 'history source selection method'),
- SVG_GRAPH_AXIS_UNITS_STATIC => _x('Static', 'history source selection method')
- ]))->setDefault(SVG_GRAPH_AXIS_UNITS_AUTO);
-
- if ($field_lefty->getValue() != SVG_GRAPH_AXIS_SHOW) {
- $field_lefty_units->setFlags(CWidgetField::FLAG_DISABLED);
- }
- elseif (array_key_exists('lefty_units', $this->data)) {
- $field_lefty_units->setValue($this->data['lefty_units']);
- }
-
- $this->fields[$field_lefty_units->getName()] = $field_lefty_units;
-
- // Static units on left Y axis.
- $field_lefty_static_units = (new CWidgetFieldTextBox('lefty_static_units', null))
- ->setPlaceholder(_('value'))
- ->setWidth(ZBX_TEXTAREA_TINY_WIDTH);
-
- if ($field_lefty->getValue() != SVG_GRAPH_AXIS_SHOW
- || $field_lefty_units->getValue() != SVG_GRAPH_AXIS_UNITS_STATIC) {
- $field_lefty_static_units->setFlags(CWidgetField::FLAG_DISABLED);
- }
- elseif (array_key_exists('lefty_static_units', $this->data)) {
- $field_lefty_static_units->setValue($this->data['lefty_static_units']);
- }
-
- $this->fields[$field_lefty_static_units->getName()] = $field_lefty_static_units;
-
- // Show right Y axis.
- $field_righty = (new CWidgetFieldCheckBox('righty', _('Right Y'), _('Show')))->setDefault(SVG_GRAPH_AXIS_SHOW);
-
- if (array_key_exists('righty', $this->data)) {
- $field_righty->setValue($this->data['righty']);
- }
-
- $this->fields[$field_righty->getName()] = $field_righty;
-
- // Min value on right Y axis.
- $field_righty_min = (new CWidgetFieldNumericBox('righty_min', _('Min')))
- ->setPlaceholder(_('calculated'))
- ->setFullName(_('Right Y').'/'._('Min'))
- ->setWidth(ZBX_TEXTAREA_SMALL_WIDTH);
-
- if ($field_righty->getValue() != SVG_GRAPH_AXIS_SHOW) {
- $field_righty_min->setFlags(CWidgetField::FLAG_DISABLED);
- }
- elseif (array_key_exists('righty_min', $this->data)) {
- $field_righty_min->setValue($this->data['righty_min']);
- }
-
- $this->fields[$field_righty_min->getName()] = $field_righty_min;
-
- // Max value on right Y axis.
- $field_righty_max = (new CWidgetFieldNumericBox('righty_max', _('Max')))
- ->setPlaceholder(_('calculated'))
- ->setFullName(_('Right Y').'/'._('Max'))
- ->setWidth(ZBX_TEXTAREA_SMALL_WIDTH);
-
- if ($field_righty->getValue() != SVG_GRAPH_AXIS_SHOW) {
- $field_righty_max->setFlags(CWidgetField::FLAG_DISABLED);
- }
- elseif (array_key_exists('righty_max', $this->data)) {
- $field_righty_max->setValue($this->data['righty_max']);
- }
-
- $this->fields[$field_righty_max->getName()] = $field_righty_max;
-
- // Specify the type of units on right Y axis.
- $field_righty_units = (new CWidgetFieldSelect('righty_units', _('Units'), [
- SVG_GRAPH_AXIS_UNITS_AUTO => _x('Auto', 'history source selection method'),
- SVG_GRAPH_AXIS_UNITS_STATIC => _x('Static', 'history source selection method')
- ]))->setDefault(SVG_GRAPH_AXIS_UNITS_AUTO);
-
- if ($field_righty->getValue() != SVG_GRAPH_AXIS_SHOW) {
- $field_righty_units->setFlags(CWidgetField::FLAG_DISABLED);
- }
- elseif (array_key_exists('righty_units', $this->data)) {
- $field_righty_units->setValue($this->data['righty_units']);
- }
-
- $this->fields[$field_righty_units->getName()] = $field_righty_units;
-
- // Static units on right Y axis.
- $field_righty_static_units = (new CWidgetFieldTextBox('righty_static_units', null))
- ->setPlaceholder(_('value'))
- ->setWidth(ZBX_TEXTAREA_TINY_WIDTH);
-
- if ($field_righty->getValue() != SVG_GRAPH_AXIS_SHOW
- || $field_righty_units->getValue() != SVG_GRAPH_AXIS_UNITS_STATIC) {
- $field_righty_static_units->setFlags(CWidgetField::FLAG_DISABLED);
- }
- elseif (array_key_exists('righty_static_units', $this->data)) {
- $field_righty_static_units->setValue($this->data['righty_static_units']);
- }
-
- $this->fields[$field_righty_static_units->getName()] = $field_righty_static_units;
-
- // Show X axis.
- $field_axisx = (new CWidgetFieldCheckBox('axisx', _('X-Axis'), _('Show')))->setDefault(SVG_GRAPH_AXIS_SHOW);
-
- if (array_key_exists('axisx', $this->data)) {
- $field_axisx->setValue($this->data['axisx']);
- }
-
- $this->fields[$field_axisx->getName()] = $field_axisx;
- }
-
- private function initLegendFields(): void {
- /**
- * Legend tab.
- *
- * Contains check-box field to show/hide legend and field to specify number of lines in which legend is shown.
- */
-
- $field_legend = (new CWidgetFieldCheckBox('legend', _('Show legend')))->setDefault(SVG_GRAPH_LEGEND_ON);
-
- if (array_key_exists('legend', $this->data)) {
- $field_legend->setValue($this->data['legend']);
- }
-
- $this->fields[$field_legend->getName()] = $field_legend;
-
- // Show legend statistic.
- $field_legend_statistic = (new CWidgetFieldCheckBox('legend_statistic', _('Display min/max/avg')))
- ->setDefault(SVG_GRAPH_LEGEND_STATISTIC_OFF);
-
- if ($field_legend->getValue() == SVG_GRAPH_LEGEND_OFF) {
- $field_legend_statistic->setFlags(CWidgetField::FLAG_DISABLED);
- }
- if (array_key_exists('legend_statistic', $this->data)) {
- $field_legend_statistic->setValue($this->data['legend_statistic']);
- }
-
- $this->fields[$field_legend_statistic->getName()] = $field_legend_statistic;
-
- // Number of lines.
- $field_legend_lines = (new CWidgetFieldRangeControl('legend_lines', _('Number of rows'),
- SVG_GRAPH_LEGEND_LINES_MIN, SVG_GRAPH_LEGEND_LINES_MAX
- ))->setDefault(SVG_GRAPH_LEGEND_LINES_MIN);
-
- if ($field_legend->getValue() == SVG_GRAPH_LEGEND_OFF) {
- $field_legend_lines->setFlags(CWidgetField::FLAG_DISABLED);
- }
- if (array_key_exists('legend_lines', $this->data)) {
- $field_legend_lines->setValue($this->data['legend_lines']);
- }
-
- $this->fields[$field_legend_lines->getName()] = $field_legend_lines;
-
- // Number of columns.
- $field_legend_columns = (new CWidgetFieldRangeControl('legend_columns', _('Number of columns'),
- SVG_GRAPH_LEGEND_COLUMNS_MIN, SVG_GRAPH_LEGEND_COLUMNS_MAX
- ))->setDefault(SVG_GRAPH_LEGEND_COLUMNS_MAX);
-
- if ($field_legend_statistic->getValue() == SVG_GRAPH_LEGEND_STATISTIC_ON) {
- $field_legend_columns->setFlags(CWidgetField::FLAG_DISABLED);
- }
- if (array_key_exists('legend_columns', $this->data)) {
- $field_legend_columns->setValue($this->data['legend_columns']);
- }
-
- $this->fields[$field_legend_columns->getName()] = $field_legend_columns;
- }
-
- private function initProblemsFields(): void {
- // Checkbox: Selected items only.
- $field_show_problems = new CWidgetFieldCheckBox('show_problems', _('Show problems'));
-
- if (array_key_exists('show_problems', $this->data)) {
- $field_show_problems->setValue($this->data['show_problems']);
- }
-
- $this->fields[$field_show_problems->getName()] = $field_show_problems;
-
- // Checkbox: Selected items only.
- $field_problems = (new CWidgetFieldCheckBox('graph_item_problems', _('Selected items only')))
- ->setDefault(SVG_GRAPH_SELECTED_ITEM_PROBLEMS);
-
- if ($field_show_problems->getValue() != SVG_GRAPH_PROBLEMS_SHOW) {
- $field_problems->setFlags(CWidgetField::FLAG_DISABLED);
- }
- elseif (array_key_exists('graph_item_problems', $this->data)) {
- $field_problems->setValue($this->data['graph_item_problems']);
- }
-
- $this->fields[$field_problems->getName()] = $field_problems;
-
- // Problem hosts.
- $field_problemhosts = (new CWidgetFieldHostPatternSelect('problemhosts', _('Problem hosts')))
- ->setPlaceholder(_('host pattern'));
-
- if ($field_show_problems->getValue() != SVG_GRAPH_PROBLEMS_SHOW) {
- $field_problemhosts->setFlags(CWidgetField::FLAG_DISABLED);
- }
- elseif (array_key_exists('problemhosts', $this->data)) {
- $field_problemhosts->setValue($this->data['problemhosts']);
- }
-
- $this->fields[$field_problemhosts->getName()] = $field_problemhosts;
-
- // Severity checkboxes list.
- $field_severities = new CWidgetFieldSeverities('severities', _('Severity'));
-
- if ($field_show_problems->getValue() != SVG_GRAPH_PROBLEMS_SHOW) {
- $field_severities->setFlags(CWidgetField::FLAG_DISABLED);
- }
- elseif (array_key_exists('severities', $this->data)) {
- $field_severities->setValue($this->data['severities']);
- }
-
- $this->fields[$field_severities->getName()] = $field_severities;
-
- // Problem name input-text field.
- $field_problem_name = (new CWidgetFieldTextBox('problem_name', _('Problem')))
- ->setPlaceholder(_('problem pattern'));
-
- if ($field_show_problems->getValue() != SVG_GRAPH_PROBLEMS_SHOW) {
- $field_problem_name->setFlags(CWidgetField::FLAG_DISABLED);
- }
- elseif (array_key_exists('problem_name', $this->data)) {
- $field_problem_name->setValue($this->data['problem_name']);
- }
-
- $this->fields[$field_problem_name->getName()] = $field_problem_name;
-
- // Problem tag evaltype (And/Or).
- $field_evaltype = (new CWidgetFieldRadioButtonList('evaltype', _('Tags'), [
- TAG_EVAL_TYPE_AND_OR => _('And/Or'),
- TAG_EVAL_TYPE_OR => _('Or')
- ]))
- ->setDefault(TAG_EVAL_TYPE_AND_OR)
- ->setModern(true);
-
- if ($field_show_problems->getValue() != SVG_GRAPH_PROBLEMS_SHOW) {
- $field_evaltype->setFlags(CWidgetField::FLAG_DISABLED);
- }
- elseif (array_key_exists('evaltype', $this->data)) {
- $field_evaltype->setValue($this->data['evaltype']);
- }
-
- $this->fields[$field_evaltype->getName()] = $field_evaltype;
-
- // Problem tags field.
- $field_tags = new CWidgetFieldTags('tags', '');
-
- if ($field_show_problems->getValue() != SVG_GRAPH_PROBLEMS_SHOW) {
- $field_tags->setFlags(CWidgetField::FLAG_DISABLED);
- }
- elseif (array_key_exists('tags', $this->data)) {
- $field_tags->setValue($this->data['tags']);
- }
-
- $this->fields[$field_tags->getName()] = $field_tags;
- }
-
- private function initOverridesFields(): void {
- $field_or = (new CWidgetFieldGraphOverride('or', _('Overrides')))->setFlags(CWidgetField::FLAG_NOT_EMPTY);
-
- if (array_key_exists('or', $this->data)) {
- $field_or->setValue($this->data['or']);
- }
-
- $this->fields[$field_or->getName()] = $field_or;
- }
-
- /**
- * Validate "from" and "to" parameters for allowed period.
- *
- * @param string $from
- * @param string $to
- *
- * @return array
- */
- private static function validateTimeSelectorPeriod(string $from, string $to): array {
- $errors = [];
- $ts = [];
- $ts['now'] = time();
- $range_time_parser = new CRangeTimeParser();
-
- foreach (['from' => $from, 'to' => $to] as $field => $value) {
- $range_time_parser->parse($value);
- $ts[$field] = $range_time_parser
- ->getDateTime($field === 'from')
- ->getTimestamp();
- }
-
- $period = $ts['to'] - $ts['from'] + 1;
- $range_time_parser->parse('now-'.CSettingsHelper::get(CSettingsHelper::MAX_PERIOD));
- $max_period = 1 + $ts['now'] - $range_time_parser
- ->getDateTime(true)
- ->getTimestamp();
-
- if ($period < ZBX_MIN_PERIOD) {
- $errors[] = _n('Minimum time period to display is %1$s minute.',
- 'Minimum time period to display is %1$s minutes.', (int) (ZBX_MIN_PERIOD / SEC_PER_MIN)
- );
- }
- elseif ($period > $max_period) {
- $errors[] = _n('Maximum time period to display is %1$s day.',
- 'Maximum time period to display is %1$s days.', (int) round($max_period / SEC_PER_DAY)
- );
- }
-
- return $errors;
- }
-}
diff --git a/ui/include/classes/widgets/forms/CWidgetFormSystemInfo.php b/ui/include/classes/widgets/forms/CWidgetFormSystemInfo.php
deleted file mode 100644
index 7a2f318bdcc..00000000000
--- a/ui/include/classes/widgets/forms/CWidgetFormSystemInfo.php
+++ /dev/null
@@ -1,43 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * System information widget form.
- */
-class CWidgetFormSystemInfo extends CWidgetForm {
-
- public function __construct($data, $templateid) {
- parent::__construct($data, $templateid, WIDGET_SYSTEM_INFO);
-
- $field_info_type = (new CWidgetFieldRadioButtonList('info_type', _('Show'), [
- ZBX_SYSTEM_INFO_SERVER_STATS => _('System stats'),
- ZBX_SYSTEM_INFO_HAC_STATUS => _('High availability nodes')
- ]))
- ->setDefault(ZBX_SYSTEM_INFO_SERVER_STATS)
- ->setModern(true);
-
- if (array_key_exists('info_type', $this->data)) {
- $field_info_type->setValue($this->data['info_type']);
- }
-
- $this->fields[$field_info_type->getName()] = $field_info_type;
- }
-}
diff --git a/ui/include/classes/widgets/forms/CWidgetFormTopHosts.php b/ui/include/classes/widgets/forms/CWidgetFormTopHosts.php
deleted file mode 100644
index a594b86e201..00000000000
--- a/ui/include/classes/widgets/forms/CWidgetFormTopHosts.php
+++ /dev/null
@@ -1,171 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2021 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Top hosts data widget form.
- */
-class CWidgetFormTopHosts extends CWidgetForm {
-
- const ORDER_TOPN = 2;
- const ORDER_BOTTOMN = 3;
-
- const DEFAULT_HOSTS_COUNT = 10;
-
- public function __construct($data, $templateid) {
- parent::__construct($data, $templateid, WIDGET_TOP_HOSTS);
-
- $this->data = self::convertDottedKeys($this->data);
-
- if (array_key_exists('columnsthresholds', $this->data)) {
- foreach ($this->data['columnsthresholds'] as $column_index => $fields) {
- $this->data['columns'][$column_index]['thresholds'] = [];
-
- foreach ($fields as $field_key => $field_values) {
- foreach ($field_values as $value_index => $value) {
- $this->data['columns'][$column_index]['thresholds'][$value_index][$field_key] = $value;
- }
- }
- }
- }
-
- // Apply sortable changes to data.
- if (array_key_exists('sortorder', $this->data)) {
- if (array_key_exists('column', $this->data) && array_key_exists('columns', $this->data['sortorder'])) {
- // Fix selected column index when columns were sorted.
- $this->data['column'] = array_search($this->data['column'], $this->data['sortorder']['columns']);
- }
-
- foreach ($this->data['sortorder'] as $key => $sortorder) {
- if (!array_key_exists($key, $this->data)) {
- continue;
- }
-
- $sorted = [];
-
- foreach ($sortorder as $index) {
- $sorted[] = $this->data[$key][$index];
- }
-
- $this->data[$key] = $sorted;
- }
- }
-
- // Host groups.
- $field_groups = new CWidgetFieldMsGroup('groupids', _('Host groups'));
-
- if (array_key_exists('groupids', $this->data)) {
- $field_groups->setValue($this->data['groupids']);
- }
-
- $this->fields[$field_groups->getName()] = $field_groups;
-
- // Hosts.
- $field_hosts = new CWidgetFieldMsHost('hostids', _('Hosts'));
- $field_hosts->setFilterPreselect('groupids_');
-
- if (array_key_exists('hostids', $this->data)) {
- $field_hosts->setValue($this->data['hostids']);
- }
-
- $this->fields[$field_hosts->getName()] = $field_hosts;
-
- // Tag evaltype (And/Or).
- $field_evaltype = (new CWidgetFieldRadioButtonList('evaltype', _('Host tags'), [
- TAG_EVAL_TYPE_AND_OR => _('And/Or'),
- TAG_EVAL_TYPE_OR => _('Or')
- ]))
- ->setDefault(TAG_EVAL_TYPE_AND_OR)
- ->setModern(true);
-
- if (array_key_exists('evaltype', $this->data)) {
- $field_evaltype->setValue($this->data['evaltype']);
- }
-
- $this->fields[$field_evaltype->getName()] = $field_evaltype;
-
- // Tags array: tag, operator and value. No label, because it belongs to previous group.
- $field_tags = new CWidgetFieldTags('tags', '');
-
- if (array_key_exists('tags', $this->data)) {
- $field_tags->setValue($this->data['tags']);
- }
-
- $this->fields[$field_tags->getName()] = $field_tags;
-
- // Columns definition table.
- $field_columns = (new CWidgetFieldColumnsList('columns', _('Columns')))
- ->setFlags(CWidgetField::FLAG_LABEL_ASTERISK);
- $field_column_values = [];
-
- if (array_key_exists('columns', $this->data)) {
- $field_columns->setValue($this->data['columns']);
-
- foreach ($this->data['columns'] as $key => $value) {
- if ($value['data'] == CWidgetFieldColumnsList::DATA_ITEM_VALUE) {
- $field_column_values[$key] = ($value['name'] === '') ? $value['item'] : $value['name'];
- }
- }
- }
-
- $this->fields[$field_columns->getName()] = $field_columns;
-
- // Order.
- $field_order = (new CWidgetFieldRadioButtonList('order', _('Order'), [
- self::ORDER_TOPN => _('Top N'),
- self::ORDER_BOTTOMN => _('Bottom N')
- ]))
- ->setDefault(self::ORDER_TOPN)
- ->setModern(true);
-
- if (array_key_exists('order', $this->data)) {
- $field_order->setValue($this->data['order']);
- }
-
- $this->fields[$field_order->getName()] = $field_order;
-
- // Field column.
- $field_column = (new CWidgetFieldSelect('column', _('Order column'), $field_column_values))
- ->setFlags(CWidgetField::FLAG_LABEL_ASTERISK);
-
- if (array_key_exists('column', $this->data)) {
- $field_column->setValue($this->data['column']);
- }
- else if ($field_column_values) {
- reset($field_column_values);
- $field_column->setValue((int) key($field_column_values));
- }
-
- $this->fields[$field_column->getName()] = $field_column;
-
- // Host count.
- $field_count = (new CWidgetFieldIntegerBox('count', _('Host count'), ZBX_MIN_WIDGET_LINES,
- ZBX_MAX_WIDGET_LINES
- ))
- ->setFlags(CWidgetField::FLAG_LABEL_ASTERISK)
- ->setDefault(self::DEFAULT_HOSTS_COUNT);
-
- if (array_key_exists('count', $this->data)) {
- $field_count->setValue((int) $this->data['count']);
- }
-
- $this->fields[$field_count->getName()] = $field_count;
- }
-}
diff --git a/ui/include/classes/widgets/forms/CWidgetFormTrigOver.php b/ui/include/classes/widgets/forms/CWidgetFormTrigOver.php
deleted file mode 100644
index e4a1e76ca0c..00000000000
--- a/ui/include/classes/widgets/forms/CWidgetFormTrigOver.php
+++ /dev/null
@@ -1,113 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Trigger overview widget form.
- */
-class CWidgetFormTrigOver extends CWidgetForm {
-
- public function __construct($data, $templateid) {
- parent::__construct($data, $templateid, WIDGET_TRIG_OVER);
-
- $this->data = self::convertDottedKeys($this->data);
-
- // Output information option.
- $field_show = (new CWidgetFieldRadioButtonList('show', _('Show'), [
- TRIGGERS_OPTION_RECENT_PROBLEM => _('Recent problems'),
- TRIGGERS_OPTION_IN_PROBLEM => _('Problems'),
- TRIGGERS_OPTION_ALL => _('Any')
- ]))
- ->setDefault(TRIGGERS_OPTION_RECENT_PROBLEM)
- ->setModern(true);
-
- if (array_key_exists('show', $this->data)) {
- $field_show->setValue($this->data['show']);
- }
-
- $this->fields[$field_show->getName()] = $field_show;
-
- // Host groups.
- $field_groups = new CWidgetFieldMsGroup('groupids', _('Host groups'));
-
- if (array_key_exists('groupids', $this->data)) {
- $field_groups->setValue($this->data['groupids']);
- }
-
- $this->fields[$field_groups->getName()] = $field_groups;
-
- // Hosts.
- $field_hosts = new CWidgetFieldMsHost('hostids', _('Hosts'));
- $field_hosts->setFilterPreselect('groupids_');
-
- if (array_key_exists('hostids', $this->data)) {
- $field_hosts->setValue($this->data['hostids']);
- }
-
- $this->fields[$field_hosts->getName()] = $field_hosts;
-
- // Tag evaltype (And/Or).
- $field_evaltype = (new CWidgetFieldRadioButtonList('evaltype', _('Tags'), [
- TAG_EVAL_TYPE_AND_OR => _('And/Or'),
- TAG_EVAL_TYPE_OR => _('Or')
- ]))
- ->setDefault(TAG_EVAL_TYPE_AND_OR)
- ->setModern(true);
-
- if (array_key_exists('evaltype', $this->data)) {
- $field_evaltype->setValue($this->data['evaltype']);
- }
-
- $this->fields[$field_evaltype->getName()] = $field_evaltype;
-
- // Tags array: tag, operator and value. No label, because it belongs to previous group.
- $field_tags = new CWidgetFieldTags('tags', '');
-
- if (array_key_exists('tags', $this->data)) {
- $field_tags->setValue($this->data['tags']);
- }
-
- $this->fields[$field_tags->getName()] = $field_tags;
-
- // Show suppressed problems.
- $field_show_suppressed = (new CWidgetFieldCheckBox('show_suppressed', _('Show suppressed problems')))
- ->setDefault(ZBX_PROBLEM_SUPPRESSED_FALSE);
-
- if (array_key_exists('show_suppressed', $this->data)) {
- $field_show_suppressed->setValue($this->data['show_suppressed']);
- }
-
- $this->fields[$field_show_suppressed->getName()] = $field_show_suppressed;
-
- // Hosts names location.
- $field_style = (new CWidgetFieldRadioButtonList('style', _('Hosts location'), [
- STYLE_LEFT => _('Left'),
- STYLE_TOP => _('Top')
- ]))
- ->setDefault(STYLE_LEFT)
- ->setModern(true);
-
- if (array_key_exists('style', $this->data)) {
- $field_style->setValue($this->data['style']);
- }
-
- $this->fields[$field_style->getName()] = $field_style;
- }
-}
diff --git a/ui/include/classes/widgets/forms/CWidgetFormUrl.php b/ui/include/classes/widgets/forms/CWidgetFormUrl.php
deleted file mode 100644
index 2be6bd78530..00000000000
--- a/ui/include/classes/widgets/forms/CWidgetFormUrl.php
+++ /dev/null
@@ -1,51 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * URL widget form.
- */
-class CWidgetFormUrl extends CWidgetForm {
-
- public function __construct($data, $templateid) {
- parent::__construct($data, $templateid, WIDGET_URL);
-
- // URL field.
- $field_url = (new CWidgetFieldUrl('url', _('URL')))
- ->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK);
-
- if (array_key_exists('url', $this->data)) {
- $field_url->setValue($this->data['url']);
- }
-
- $this->fields[$field_url->getName()] = $field_url;
-
- // Dynamic item.
- if ($templateid === null) {
- $field_dynamic = (new CWidgetFieldCheckBox('dynamic', _('Enable host selection')))->setDefault(WIDGET_SIMPLE_ITEM);
-
- if (array_key_exists('dynamic', $this->data)) {
- $field_dynamic->setValue($this->data['dynamic']);
- }
-
- $this->fields[$field_dynamic->getName()] = $field_dynamic;
- }
- }
-}
diff --git a/ui/include/classes/widgets/forms/CWidgetFormWeb.php b/ui/include/classes/widgets/forms/CWidgetFormWeb.php
deleted file mode 100644
index 00b33dc89e7..00000000000
--- a/ui/include/classes/widgets/forms/CWidgetFormWeb.php
+++ /dev/null
@@ -1,93 +0,0 @@
-<?php
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Web widget form.
- */
-class CWidgetFormWeb extends CWidgetForm {
-
- public function __construct($data, $templateid) {
- parent::__construct($data, $templateid, WIDGET_WEB);
-
- $this->data = self::convertDottedKeys($this->data);
-
- // Host groups.
- $field_groups = new CWidgetFieldMsGroup('groupids', _('Host groups'));
-
- if (array_key_exists('groupids', $this->data)) {
- $field_groups->setValue($this->data['groupids']);
- }
-
- $this->fields[$field_groups->getName()] = $field_groups;
-
- // Exclude host groups.
- $field_exclude_groups = new CWidgetFieldMsGroup('exclude_groupids', _('Exclude host groups'));
-
- if (array_key_exists('exclude_groupids', $this->data)) {
- $field_exclude_groups->setValue($this->data['exclude_groupids']);
- }
-
- $this->fields[$field_exclude_groups->getName()] = $field_exclude_groups;
-
- // Hosts field.
- $field_hosts = new CWidgetFieldMsHost('hostids', _('Hosts'));
- $field_hosts->setFilterPreselect('groupids_');
-
- if (array_key_exists('hostids', $this->data)) {
- $field_hosts->setValue($this->data['hostids']);
- }
-
- $this->fields[$field_hosts->getName()] = $field_hosts;
-
- // Tag evaltype (And/Or).
- $field_evaltype = (new CWidgetFieldRadioButtonList('evaltype', _('Tags'), [
- TAG_EVAL_TYPE_AND_OR => _('And/Or'),
- TAG_EVAL_TYPE_OR => _('Or')
- ]))
- ->setDefault(TAG_EVAL_TYPE_AND_OR)
- ->setModern(true);
-
- if (array_key_exists('evaltype', $this->data)) {
- $field_evaltype->setValue($this->data['evaltype']);
- }
-
- $this->fields[$field_evaltype->getName()] = $field_evaltype;
-
- // Tags array: tag, operator and value. No label, because it belongs to previous group.
- $field_tags = new CWidgetFieldTags('tags', '');
-
- if (array_key_exists('tags', $this->data)) {
- $field_tags->setValue($this->data['tags']);
- }
-
- $this->fields[$field_tags->getName()] = $field_tags;
-
- // Show hosts in maintenance.
- $field_maintenance = (new CWidgetFieldCheckBox('maintenance', _('Show hosts in maintenance')))
- ->setDefault(1);
-
- if (array_key_exists('maintenance', $this->data)) {
- $field_maintenance->setValue($this->data['maintenance']);
- }
-
- $this->fields[$field_maintenance->getName()] = $field_maintenance;
- }
-}
diff --git a/ui/include/classes/widgets/views/js/widget.clock.form.view.js.php b/ui/include/classes/widgets/views/js/widget.clock.form.view.js.php
deleted file mode 100644
index c7469b37ab3..00000000000
--- a/ui/include/classes/widgets/views/js/widget.clock.form.view.js.php
+++ /dev/null
@@ -1,102 +0,0 @@
-<?php declare(strict_types = 0);
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-?>
-
-
-window.widget_clock_form = new class {
-
- init() {
- this.form = document.getElementById('widget-dialogue-form');
- this.time_type = document.getElementById('time_type');
- this.clock_type = document.getElementById('clock_type');
-
- this.show_date = document.getElementById('show_1');
- this.show_time = document.getElementById('show_2');
- this.show_tzone = document.getElementById('show_3');
-
- this.advanced_configuration = document.getElementById('adv_conf');
-
- for (const colorpicker of this.form.querySelectorAll('.<?= ZBX_STYLE_COLOR_PICKER ?> input')) {
- $(colorpicker).colorpicker({
- appendTo: '.overlay-dialogue-body',
- use_default: true,
- onUpdate: window.setIndicatorColor
- });
- }
-
- this.time_type.addEventListener('change', () => {
- ZABBIX.Dashboard.reloadWidgetProperties();
- this.updateForm();
- });
-
- for (const checkbox of this.clock_type.querySelectorAll('input')) {
- checkbox.addEventListener('change', () => this.updateForm());
- }
-
- const show = [this.show_date, this.show_time, this.show_tzone];
-
- for (const checkbox of show) {
- checkbox.addEventListener('change', (e) => {
- if (show.filter((checkbox) => checkbox.checked).length > 0) {
- this.updateForm();
- }
- else {
- e.target.checked = true;
- }
- });
- }
-
- this.advanced_configuration.addEventListener('change', () => this.updateForm());
-
- this.updateForm();
- }
-
- updateForm() {
- const is_digital = this.clock_type.querySelector('input:checked').value == <?= WIDGET_CLOCK_TYPE_DIGITAL ?>;
-
- const show_date_row = is_digital && this.advanced_configuration.checked && this.show_date.checked;
- const show_time_row = is_digital && this.advanced_configuration.checked && this.show_time.checked;
- const show_tzone_row = is_digital && this.advanced_configuration.checked && this.show_tzone.checked;
-
- for (const element of this.form.querySelectorAll('.js-row-show, .js-row-adv-conf')) {
- element.style.display = is_digital ? '' : 'none';
- }
-
- for (const element of this.form.querySelectorAll('.js-row-bg-color')) {
- element.style.display = is_digital && this.advanced_configuration.checked ? '' : 'none';
- }
-
- for (const element of this.form.querySelectorAll('.js-row-date')) {
- element.style.display = show_date_row ? '' : 'none';
- }
-
- for (const element of this.form.querySelectorAll('.js-row-time')) {
- element.style.display = show_time_row ? '' : 'none';
- }
-
- for (const element of this.form.querySelectorAll('.js-row-tzone')) {
- element.style.display = show_tzone_row ? '' : 'none';
- }
-
- for (const element of this.form.querySelectorAll('.js-row-tzone-timezone, .js-row-tzone-format')) {
- element.style.display = this.time_type.value != <?= TIME_TYPE_HOST ?> ? '' : 'none';
- }
- }
-};
diff --git a/ui/include/classes/widgets/views/widget.clock.form.view.php b/ui/include/classes/widgets/views/widget.clock.form.view.php
deleted file mode 100644
index 23232749fb1..00000000000
--- a/ui/include/classes/widgets/views/widget.clock.form.view.php
+++ /dev/null
@@ -1,179 +0,0 @@
-<?php declare(strict_types = 0);
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Clock widget form view.
- *
- * @var CView $this
- * @var array $data
- */
-
-$fields = $data['dialogue']['fields'];
-
-$form = CWidgetHelper::createForm();
-
-$scripts = [$this->readJsFile('../../../include/classes/widgets/views/js/widget.clock.form.view.js.php')];
-
-$form_grid = CWidgetHelper::createFormGrid($data['dialogue']['name'], $data['dialogue']['type'],
- $data['dialogue']['view_mode'], $data['known_widget_types'],
- $data['templateid'] === null ? $fields['rf_rate'] : null
-);
-
-// Time type.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['time_type']),
- new CFormField(CWidgetHelper::getSelect($fields['time_type']))
-]);
-
-// Item.
-if (array_key_exists('itemid', $fields)) {
- $field_itemid = CWidgetHelper::getItem($fields['itemid'], $data['captions']['ms']['items']['itemid'],
- $form->getName()
- );
- $form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['itemid']),
- new CFormField($field_itemid)
- ]);
- $scripts[] = $field_itemid->getPostJS();
-}
-
-// Clock type.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['clock_type']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['clock_type']))
-]);
-
-// Show.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['show'])->addClass('js-row-show'),
- (new CFormField(
- CWidgetHelper::getCheckBoxList($fields['show'], [
- WIDGET_CLOCK_SHOW_DATE => _('Date'),
- WIDGET_CLOCK_SHOW_TIME => _('Time'),
- WIDGET_CLOCK_SHOW_TIMEZONE => _('Time zone')
- ])
- ))->addClass('js-row-show')
-]);
-
-// Advanced configuration.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['adv_conf'])->addClass('js-row-adv-conf'),
- (new CFormField(
- CWidgetHelper::getCheckBox($fields['adv_conf'])
- ))->addClass('js-row-adv-conf')
-]);
-
-// Background color.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['bg_color'])->addClass('js-row-bg-color'),
- (new CFormField(
- CWidgetHelper::getColor($fields['bg_color'], true)
- ))->addClass('js-row-bg-color')
-]);
-
-// Date.
-$form_grid->addItem([
- (new CLabel(_('Date')))
- ->addClass(CFormGrid::ZBX_STYLE_FIELDS_GROUP_LABEL)
- ->addClass('js-row-date'),
- (new CDiv([
- CWidgetHelper::getLabel($fields['date_size']),
- (new CFormField([CWidgetHelper::getIntegerBox($fields['date_size']), '%']))->addClass('field-size'),
-
- CWidgetHelper::getLabel($fields['date_bold']),
- new CFormField(CWidgetHelper::getCheckBox($fields['date_bold'])),
-
- CWidgetHelper::getLabel($fields['date_color'])->addClass('offset-3'),
- new CFormField(CWidgetHelper::getColor($fields['date_color'], true))
- ]))
- ->addClass(CFormGrid::ZBX_STYLE_FIELDS_GROUP)
- ->addClass('fields-group-date')
- ->addClass('js-row-date')
-]);
-
-// Time.
-$form_grid->addItem([
- (new CLabel(_('Time')))
- ->addClass(CFormGrid::ZBX_STYLE_FIELDS_GROUP_LABEL)
- ->addClass('js-row-time'),
- (new CDiv([
- CWidgetHelper::getLabel($fields['time_size']),
- (new CFormField([CWidgetHelper::getIntegerBox($fields['time_size']), '%']))->addClass('field-size'),
-
- CWidgetHelper::getLabel($fields['time_bold']),
- new CFormField(CWidgetHelper::getCheckBox($fields['time_bold'])),
-
- CWidgetHelper::getLabel($fields['time_color'])->addClass('offset-3'),
- new CFormField(CWidgetHelper::getColor($fields['time_color'], true)),
-
- CWidgetHelper::getLabel($fields['time_sec']),
- new CFormField(CWidgetHelper::getCheckBox($fields['time_sec'])),
-
- CWidgetHelper::getLabel($fields['time_format']),
- (new CFormField(CWidgetHelper::getRadioButtonList($fields['time_format'])))->addClass('field-format')
- ]))
- ->addClass(CFormGrid::ZBX_STYLE_FIELDS_GROUP)
- ->addClass('fields-group-time')
- ->addClass('js-row-time')
-]);
-
-// Time zone.
-$form_grid->addItem([
- (new CLabel(_('Time zone')))
- ->addClass(CFormGrid::ZBX_STYLE_FIELDS_GROUP_LABEL)
- ->addClass('js-row-tzone'),
- (new CDiv([
- CWidgetHelper::getLabel($fields['tzone_size']),
- (new CFormField([CWidgetHelper::getIntegerBox($fields['tzone_size']), '%']))->addClass('field-size'),
-
- CWidgetHelper::getLabel($fields['tzone_bold']),
- new CFormField(CWidgetHelper::getCheckBox($fields['tzone_bold'])),
-
- CWidgetHelper::getLabel($fields['tzone_color'])->addClass('offset-3'),
- new CFormField(CWidgetHelper::getColor($fields['tzone_color'], true)),
-
- (CWidgetHelper::getLabel($fields['tzone_timezone']))->addClass('js-row-tzone-timezone'),
- (new CFormField(CWidgetHelper::getSelect($fields['tzone_timezone'])))
- ->addClass('field-timezone')
- ->addClass('js-row-tzone-timezone'),
-
- (CWidgetHelper::getLabel($fields['tzone_format']))->addClass('js-row-tzone-format'),
- (new CFormField(CWidgetHelper::getRadioButtonList($fields['tzone_format'])))
- ->addClass('field-format')
- ->addClass('js-row-tzone-format')
- ]))
- ->addClass(CFormGrid::ZBX_STYLE_FIELDS_GROUP)
- ->addClass('fields-group-tzone')
- ->addClass('js-row-tzone')
-]);
-
-$scripts[] = $fields['tzone_timezone']->getJavascript();
-
-$form->addItem($form_grid);
-
-$scripts[] = '
- widget_clock_form.init();
-';
-
-return [
- 'form' => $form,
- 'scripts' => $scripts
-];
diff --git a/ui/include/classes/widgets/views/widget.dataover.form.view.php b/ui/include/classes/widgets/views/widget.dataover.form.view.php
deleted file mode 100644
index 4823ba334fe..00000000000
--- a/ui/include/classes/widgets/views/widget.dataover.form.view.php
+++ /dev/null
@@ -1,90 +0,0 @@
-<?php declare(strict_types = 0);
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Data overview widget form view.
- *
- * @var CView $this
- * @var array $data
- */
-
-$fields = $data['dialogue']['fields'];
-
-$form = CWidgetHelper::createForm();
-
-$scripts = [];
-
-$form_grid = CWidgetHelper::createFormGrid($data['dialogue']['name'], $data['dialogue']['type'],
- $data['dialogue']['view_mode'], $data['known_widget_types'],
- $data['templateid'] === null ? $fields['rf_rate'] : null
-);
-
-// Host groups.
-$field_groupids = CWidgetHelper::getGroup($fields['groupids'], $data['captions']['ms']['groups']['groupids'],
- $form->getName()
-);
-$form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['groupids']),
- new CFormField($field_groupids)
-]);
-$scripts[] = $field_groupids->getPostJS();
-
-// Hosts.
-$field_hostids = CWidgetHelper::getHost($fields['hostids'], $data['captions']['ms']['hosts']['hostids'],
- $form->getName()
-);
-$form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['hostids']),
- new CFormField($field_hostids)
-]);
-$scripts[] = $field_hostids->getPostJS();
-
-// Tags.
-$form_grid
- ->addItem([
- CWidgetHelper::getLabel($fields['evaltype']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['evaltype']))
- ])
- ->addItem(
- new CFormField(CWidgetHelper::getTags($fields['tags']))
- );
-$scripts[] = $fields['tags']->getJavascript();
-$jq_templates['tag-row-tmpl'] = CWidgetHelper::getTagsTemplate($fields['tags']);
-
-// Show suppressed problems.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['show_suppressed']),
- new CFormField(CWidgetHelper::getCheckBox($fields['show_suppressed']))
-]);
-
-// Hosts location.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['style']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['style']))
-]);
-
-$form->addItem($form_grid);
-
-return [
- 'form' => $form,
- 'scripts' => $scripts,
- 'jq_templates' => $jq_templates
-];
diff --git a/ui/include/classes/widgets/views/widget.geomap.form.view.php b/ui/include/classes/widgets/views/widget.geomap.form.view.php
deleted file mode 100644
index 0a61d3d2cb3..00000000000
--- a/ui/include/classes/widgets/views/widget.geomap.form.view.php
+++ /dev/null
@@ -1,96 +0,0 @@
-<?php declare(strict_types = 0);
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Map widget form view.
- *
- * @var CView $this
- * @var array $data
- */
-
-$fields = $data['dialogue']['fields'];
-
-$form = CWidgetHelper::createForm();
-
-$scripts = [];
-
-$form_grid = CWidgetHelper::createFormGrid($data['dialogue']['name'], $data['dialogue']['type'],
- $data['dialogue']['view_mode'], $data['known_widget_types'],
- $data['templateid'] === null ? $fields['rf_rate'] : null
-);
-
-// Host groups.
-$field_groupids = CWidgetHelper::getGroup($fields['groupids'], $data['captions']['ms']['groups']['groupids'],
- $form->getName()
-);
-$form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['groupids']),
- new CFormField($field_groupids)
-]);
-$scripts[] = $field_groupids->getPostJS();
-
-// Hosts.
-$field_hostids = CWidgetHelper::getHost($fields['hostids'], $data['captions']['ms']['hosts']['hostids'],
- $form->getName()
-);
-$form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['hostids']),
- new CFormField($field_hostids)
-]);
-$scripts[] = $field_hostids->getPostJS();
-
-// Tags.
-$form_grid
- ->addItem([
- CWidgetHelper::getLabel($fields['evaltype']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['evaltype']))
- ])
- ->addItem(
- new CFormField(CWidgetHelper::getTags($fields['tags']))
- );
-$scripts[] = $fields['tags']->getJavascript();
-$jq_templates['tag-row-tmpl'] = CWidgetHelper::getTagsTemplate($fields['tags']);
-
-// Initial view.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['default_view'], null, [
- _('Comma separated center coordinates and zoom level to display when the widget is initially loaded.'),
- BR(),
- _('Supported formats:'),
- (new CList([
- new CListItem((new CSpan('<lat>,<lng>,<zoom>'))->addClass(ZBX_STYLE_MONOSPACE_FONT)),
- new CListItem((new CSpan('<lat>,<lng>'))->addClass(ZBX_STYLE_MONOSPACE_FONT))
- ]))->addClass(ZBX_STYLE_LIST_DASHED),
- BR(),
- _s('The maximum zoom level is "%1$s".', CSettingsHelper::get(CSettingsHelper::GEOMAPS_MAX_ZOOM)),
- BR(),
- _('Initial view is ignored if the default view is set.')
- ]),
- new CFormField(CWidgetHelper::getLatLngZoomBox($fields['default_view']))
-]);
-
-$form->addItem($form_grid);
-
-return [
- 'form' => $form,
- 'scripts' => $scripts,
- 'jq_templates' => $jq_templates
-];
diff --git a/ui/include/classes/widgets/views/widget.graph.form.view.php b/ui/include/classes/widgets/views/widget.graph.form.view.php
deleted file mode 100644
index 31dea04b1dc..00000000000
--- a/ui/include/classes/widgets/views/widget.graph.form.view.php
+++ /dev/null
@@ -1,89 +0,0 @@
-<?php declare(strict_types = 0);
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Graph widget form view.
- *
- * @var CView $this
- * @var array $data
- */
-
-$fields = $data['dialogue']['fields'];
-
-$form = CWidgetHelper::createForm();
-
-$scripts = [];
-
-$form_grid = CWidgetHelper::createFormGrid($data['dialogue']['name'], $data['dialogue']['type'],
- $data['dialogue']['view_mode'], $data['known_widget_types'],
- $data['templateid'] === null ? $fields['rf_rate'] : null
-);
-
-// Source.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['source_type']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['source_type']))
-]);
-
-// Graph.
-if (array_key_exists('graphid', $fields)) {
- $field_graphid = CWidgetHelper::getGraph($fields['graphid'], $data['captions']['ms']['graphs']['graphid'],
- $form->getName()
- );
- $form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['graphid']),
- new CFormField($field_graphid)
- ]);
- $scripts[] = $field_graphid->getPostJS();
-}
-
-// Item.
-if (array_key_exists('itemid', $fields)) {
- $field_itemid = CWidgetHelper::getItem($fields['itemid'], $data['captions']['ms']['items']['itemid'],
- $form->getName()
- );
- $form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['itemid']),
- new CFormField($field_itemid)
- ]);
- $scripts[] = $field_itemid->getPostJS();
-}
-
-// Show legend.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['show_legend']),
- new CFormField(CWidgetHelper::getCheckBox($fields['show_legend']))
-]);
-
-// Dynamic item.
-if ($data['templateid'] === null) {
- $form_grid->addItem([
- CWidgetHelper::getLabel($fields['dynamic']),
- new CFormField(CWidgetHelper::getCheckBox($fields['dynamic']))
- ]);
-}
-
-$form->addItem($form_grid);
-
-return [
- 'form' => $form,
- 'scripts' => $scripts
-];
diff --git a/ui/include/classes/widgets/views/widget.graphprototype.form.view.php b/ui/include/classes/widgets/views/widget.graphprototype.form.view.php
deleted file mode 100644
index 400b4c9ef87..00000000000
--- a/ui/include/classes/widgets/views/widget.graphprototype.form.view.php
+++ /dev/null
@@ -1,101 +0,0 @@
-<?php declare(strict_types = 0);
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Graph prototype widget form view.
- *
- * @var CView $this
- * @var array $data
- */
-
-$fields = $data['dialogue']['fields'];
-
-$form = CWidgetHelper::createForm();
-
-$scripts = [];
-
-$form_grid = CWidgetHelper::createFormGrid($data['dialogue']['name'], $data['dialogue']['type'],
- $data['dialogue']['view_mode'], $data['known_widget_types'],
- $data['templateid'] === null ? $fields['rf_rate'] : null
-);
-
-// Source.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['source_type']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['source_type']))
-]);
-
-// Graph prototype.
-if (array_key_exists('graphid', $fields)) {
- $field_graphid = CWidgetHelper::getGraphPrototype($fields['graphid'],
- $data['captions']['ms']['graph_prototypes']['graphid'], $form->getName()
- );
- $form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['graphid']),
- new CFormField($field_graphid)
- ]);
- $scripts[] = $field_graphid->getPostJS();
-}
-
-// Item prototype.
-if (array_key_exists('itemid', $fields)) {
- $field_itemid = CWidgetHelper::getItemPrototype($fields['itemid'],
- $data['captions']['ms']['item_prototypes']['itemid'], $form->getName()
- );
- $form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['itemid']),
- new CFormField($field_itemid)
- ]);
- $scripts[] = $field_itemid->getPostJS();
-}
-
-// Show legend.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['show_legend']),
- new CFormField(CWidgetHelper::getCheckBox($fields['show_legend']))
-]);
-
-// Dynamic item.
-if ($data['templateid'] === null) {
- $form_grid->addItem([
- CWidgetHelper::getLabel($fields['dynamic']),
- new CFormField(CWidgetHelper::getCheckBox($fields['dynamic']))
- ]);
-}
-
-// Columns.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['columns']),
- new CFormField(CWidgetHelper::getIntegerBox($fields['columns']))
-]);
-
-// Rows.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['rows']),
- new CFormField(CWidgetHelper::getIntegerBox($fields['rows']))
-]);
-
-$form->addItem($form_grid);
-
-return [
- 'form' => $form,
- 'scripts' => $scripts
-];
diff --git a/ui/include/classes/widgets/views/widget.hostavail.form.view.php b/ui/include/classes/widgets/views/widget.hostavail.form.view.php
deleted file mode 100644
index a691fc0cafc..00000000000
--- a/ui/include/classes/widgets/views/widget.hostavail.form.view.php
+++ /dev/null
@@ -1,80 +0,0 @@
-<?php declare(strict_types = 0);
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Host availability widget form view.
- *
- * @var CView $this
- * @var array $data
- */
-
-$fields = $data['dialogue']['fields'];
-
-$form = CWidgetHelper::createForm();
-
-$scripts = [];
-
-$form_grid = CWidgetHelper::createFormGrid($data['dialogue']['name'], $data['dialogue']['type'],
- $data['dialogue']['view_mode'], $data['known_widget_types'],
- $data['templateid'] === null ? $fields['rf_rate'] : null
-);
-
-// Host groups.
-$field_groupids = CWidgetHelper::getGroup($fields['groupids'], $data['captions']['ms']['groups']['groupids'],
- $form->getName()
-);
-$form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['groupids']),
- new CFormField($field_groupids)
-]);
-$scripts[] = $field_groupids->getPostJS();
-
-// Interface type.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['interface_type']),
- new CFormField(
- CWidgetHelper::getCheckBoxList($fields['interface_type'], [
- INTERFACE_TYPE_AGENT => _('Zabbix agent'),
- INTERFACE_TYPE_SNMP => _('SNMP'),
- INTERFACE_TYPE_JMX => _('JMX'),
- INTERFACE_TYPE_IPMI => _('IPMI')
- ])
- )
-]);
-
-// Layout.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['layout']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['layout']))
-]);
-
-// Show hosts in maintenance.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['maintenance']),
- new CFormField(CWidgetHelper::getCheckBox($fields['maintenance']))
-]);
-
-$form->addItem($form_grid);
-
-return [
- 'form' => $form,
- 'scripts' => $scripts
-];
diff --git a/ui/include/classes/widgets/views/widget.item.form.view.php b/ui/include/classes/widgets/views/widget.item.form.view.php
deleted file mode 100644
index cad8ddd6962..00000000000
--- a/ui/include/classes/widgets/views/widget.item.form.view.php
+++ /dev/null
@@ -1,262 +0,0 @@
-<?php declare(strict_types = 0);
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Item value widget.
- *
- * @var CView $this
- * @var array $data
- */
-
-$fields = $data['dialogue']['fields'];
-
-$form = CWidgetHelper::createForm();
-
-$scripts = [$this->readJsFile('../../../include/classes/widgets/views/js/widget.item.form.view.js.php')];
-
-$form_grid = CWidgetHelper::createFormGrid($data['dialogue']['name'], $data['dialogue']['type'],
- $data['dialogue']['view_mode'], $data['known_widget_types'],
- $data['templateid'] === null ? $fields['rf_rate'] : null
-);
-
-// Item.
-$field_itemid = CWidgetHelper::getItem($fields['itemid'], $data['captions']['ms']['items']['itemid'],
- $form->getName()
-);
-$form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['itemid']),
- new CFormField($field_itemid)
-]);
-$scripts[] = $field_itemid->getPostJS();
-
-// Show.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['show']),
- new CFormField(
- CWidgetHelper::getCheckBoxList($fields['show'], [
- WIDGET_ITEM_SHOW_DESCRIPTION => _('Description'),
- WIDGET_ITEM_SHOW_VALUE => _('Value'),
- WIDGET_ITEM_SHOW_TIME => _('Time'),
- WIDGET_ITEM_SHOW_CHANGE_INDICATOR => _('Change indicator')
- ], [ZBX_STYLE_COLUMNS, ZBX_STYLE_COLUMNS_2])
- )
-]);
-
-// Advanced configuration.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['adv_conf']),
- new CFormField(CWidgetHelper::getCheckBox($fields['adv_conf']))
-]);
-
-// Description.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['description'], CFormGrid::ZBX_STYLE_FIELDS_GROUP_LABEL, [
- _('Supported macros:'),
- (new CList([
- '{HOST.*}',
- '{ITEM.*}',
- '{INVENTORY.*}',
- _('User macros')
- ]))->addClass(ZBX_STYLE_LIST_DASHED)
- ])->addClass('js-row-description'),
- (new CDiv([
- new CFormField(
- CWidgetHelper::getTextArea($fields['description'])
- ->setAttribute('maxlength', DB::getFieldLength('widget_field', 'value_str'))
- ),
-
- CWidgetHelper::getLabel($fields['desc_h_pos']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['desc_h_pos'])),
-
- CWidgetHelper::getLabel($fields['desc_size']),
- (new CFormField([CWidgetHelper::getIntegerBox($fields['desc_size']), '%']))->addClass('field-size'),
-
- CWidgetHelper::getLabel($fields['desc_v_pos']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['desc_v_pos'])),
-
- CWidgetHelper::getLabel($fields['desc_bold']),
- new CFormField(CWidgetHelper::getCheckBox($fields['desc_bold'])),
-
- CWidgetHelper::getLabel($fields['desc_color'])->addClass('offset-3'),
- new CFormField(CWidgetHelper::getColor($fields['desc_color'], true))
- ]))
- ->addClass(CFormGrid::ZBX_STYLE_FIELDS_GROUP)
- ->addClass('fields-group-description')
- ->addClass('js-row-description')
-]);
-
-// Value.
-$form_grid->addItem([
- (new CLabel(_('Value')))
- ->addClass(CFormGrid::ZBX_STYLE_FIELDS_GROUP_LABEL)
- ->addClass('js-row-value'),
- (new CDiv([
- CWidgetHelper::getLabel($fields['decimal_places']),
- new CFormField(CWidgetHelper::getIntegerBox($fields['decimal_places'])),
-
- CWidgetHelper::getLabel($fields['decimal_size']),
- (new CFormField([CWidgetHelper::getIntegerBox($fields['decimal_size']), '%']))->addClass('field-size'),
-
- new CTag('hr'),
-
- CWidgetHelper::getLabel($fields['value_h_pos']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['value_h_pos'])),
-
- CWidgetHelper::getLabel($fields['value_size']),
- (new CFormField([CWidgetHelper::getIntegerBox($fields['value_size']), '%']))->addClass('field-size'),
-
- CWidgetHelper::getLabel($fields['value_v_pos']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['value_v_pos'])),
-
- CWidgetHelper::getLabel($fields['value_bold']),
- new CFormField(CWidgetHelper::getCheckBox($fields['value_bold'])),
-
- CWidgetHelper::getLabel($fields['value_color'])->addClass('offset-3'),
- new CFormField(CWidgetHelper::getColor($fields['value_color'], true)),
-
- new CTag('hr'),
-
- (new CDiv([
- CWidgetHelper::getCheckBox($fields['units_show']),
- CWidgetHelper::getLabel($fields['units'])
- ]))->addClass('units-show'),
-
- (new CFormField(
- CWidgetHelper::getTextBox($fields['units'])
- ->setAttribute('style', '')
- ->setAdaptiveWidth(ZBX_TEXTAREA_BIG_WIDTH)
- ))->addClass(CFormField::ZBX_STYLE_FORM_FIELD_FLUID),
-
- CWidgetHelper::getLabel($fields['units_pos'], null,
- _('Position is ignored for s, uptime and unixtime units.')
- ),
- new CFormField(CWidgetHelper::getSelect($fields['units_pos'])),
-
- CWidgetHelper::getLabel($fields['units_size']),
- (new CFormField([CWidgetHelper::getIntegerBox($fields['units_size']), '%']))->addClass('field-size'),
-
- CWidgetHelper::getLabel($fields['units_bold'])->addClass('offset-3'),
- new CFormField(CWidgetHelper::getCheckBox($fields['units_bold'])),
-
- CWidgetHelper::getLabel($fields['units_color'])->addClass('offset-3'),
- new CFormField(CWidgetHelper::getColor($fields['units_color'], true))
- ]))
- ->addClass(CFormGrid::ZBX_STYLE_FIELDS_GROUP)
- ->addClass('fields-group-value')
- ->addClass('js-row-value')
-]);
-
-// Time.
-$form_grid->addItem([
- (new CLabel(_('Time')))
- ->addCLass(CFormGrid::ZBX_STYLE_FIELDS_GROUP_LABEL)
- ->addClass('js-row-time'),
- (new CDiv([
- CWidgetHelper::getLabel($fields['time_h_pos']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['time_h_pos'])),
-
- CWidgetHelper::getLabel($fields['time_size']),
- (new CFormField([CWidgetHelper::getIntegerBox($fields['time_size']), '%']))->addClass('field-size'),
-
- CWidgetHelper::getLabel($fields['time_v_pos']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['time_v_pos'])),
-
- CWidgetHelper::getLabel($fields['time_bold']),
- new CFormField(CWidgetHelper::getCheckBox($fields['time_bold'])),
-
- CWidgetHelper::getLabel($fields['time_color'])->addClass('offset-3'),
- new CFormField(CWidgetHelper::getColor($fields['time_color'], true))
- ]))
- ->addClass(CFormGrid::ZBX_STYLE_FIELDS_GROUP)
- ->addClass('fields-group-time')
- ->addClass('js-row-time')
-]);
-
-// Change indicator.
-$form_grid->addItem([
- (new CLabel(_('Change indicator')))
- ->addClass(CFormGrid::ZBX_STYLE_FIELDS_GROUP_LABEL)
- ->addClass('js-row-change-indicator'),
- (new CDiv([
- (new CSvgArrow(['up' => true, 'fill_color' => $fields['up_color']->getValue()]))
- ->setId('change-indicator-up')
- ->setSize(14, 20),
- new CFormField(CWidgetHelper::getColor($fields['up_color'], true)),
-
- (new CSvgArrow(['down' => true, 'fill_color' => $fields['down_color']->getValue()]))
- ->setId('change-indicator-down')
- ->setSize(14, 20),
- new CFormField(CWidgetHelper::getColor($fields['down_color'], true)),
-
- (new CSvgArrow(['up' => true, 'down' => true, 'fill_color' => $fields['updown_color']->getValue()]))
- ->setId('change-indicator-updown')
- ->setSize(14, 20),
- new CFormField(CWidgetHelper::getColor($fields['updown_color'], true))
- ]))
- ->addClass(CFormGrid::ZBX_STYLE_FIELDS_GROUP)
- ->addClass('fields-group-change-indicator')
- ->addClass('js-row-change-indicator')
-]);
-
-// Background color.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['bg_color'])->addClass('js-row-bg-color'),
- (new CFormField(CWidgetHelper::getColor($fields['bg_color'], true)))->addClass('js-row-bg-color')
-]);
-
-// Thresholds.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['thresholds'])
- ->addItem(
- (new CSpan([
- '&nbsp;',
- makeWarningIcon(_('This setting applies only to numeric data.'))
- ]))->setId('item-value-thresholds-warning'))
- ->addClass('js-row-thresholds'),
- (new CFormField(CWidgetHelper::getThresholds($fields['thresholds'])))->addClass('js-row-thresholds')
-]);
-$scripts[] = $fields['thresholds']->getJavascript();
-
-$thresholds_tmpl_id = sprintf(CWidgetFieldThresholds::THRESHOLDS_ROW_TMPL_ID, $fields['thresholds']->getName());
-$jq_templates[$thresholds_tmpl_id] = CWidgetHelper::getThresholdsTemplate($fields['thresholds']->getName())
- ->toString();
-
-// Dynamic item.
-if ($data['templateid'] === null) {
- $form_grid->addItem([
- CWidgetHelper::getLabel($fields['dynamic']),
- new CFormField(CWidgetHelper::getCheckBox($fields['dynamic']))
- ]);
-}
-
-$form->addItem($form_grid);
-
-$scripts[] = '
- widget_item_form.init('.json_encode([
- 'thresholds_colors' => CWidgetFieldColumnsList::THRESHOLDS_DEFAULT_COLOR_PALETTE
- ]).');
-';
-
-return [
- 'form' => $form,
- 'scripts' => $scripts,
- 'jq_templates' => $jq_templates
-];
diff --git a/ui/include/classes/widgets/views/widget.map.form.view.php b/ui/include/classes/widgets/views/widget.map.form.view.php
deleted file mode 100644
index c2de3627efc..00000000000
--- a/ui/include/classes/widgets/views/widget.map.form.view.php
+++ /dev/null
@@ -1,85 +0,0 @@
-<?php declare(strict_types = 0);
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Map widget form view.
- *
- * @var CView $this
- * @var array $data
- */
-
-$fields = $data['dialogue']['fields'];
-
-$form = CWidgetHelper::createForm();
-
-$scripts = [];
-
-$form_grid = CWidgetHelper::createFormGrid($data['dialogue']['name'], $data['dialogue']['type'],
- $data['dialogue']['view_mode'], $data['known_widget_types'],
- $data['templateid'] === null ? $fields['rf_rate'] : null
-);
-
-// Map widget reference.
-$form->addVar($fields[CWidgetFieldReference::FIELD_NAME]->getName(),
- $fields[CWidgetFieldReference::FIELD_NAME]->getValue()
-);
-
-// Source type.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['source_type']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['source_type']))
-]);
-
-// Map.
-if (array_key_exists('sysmapid', $fields)) {
- $field = $fields['sysmapid'];
-
- $form->addVar($field->getName(), $field->getValue());
-
- $form_grid->addItem([
- CWidgetHelper::getLabel($field),
- new CFormField(
- CWidgetHelper::getSelectResource(
- $field,
- $field->getValue() != 0
- ? $data['captions']['simple'][$field->getResourceType()][$field->getValue()]
- : '',
- $form->getName()
- )
- )
- ]);
-}
-
-// Filter.
-if (array_key_exists('filter_widget_reference', $fields)) {
- $form_grid->addItem([
- CWidgetHelper::getLabel($fields['filter_widget_reference']),
- new CFormField(CWidgetHelper::getEmptySelect($fields['filter_widget_reference']))
- ]);
- $scripts[] = $fields['filter_widget_reference']->getJavascript();
-}
-
-$form->addItem($form_grid);
-
-return [
- 'form' => $form,
- 'scripts' => $scripts
-];
diff --git a/ui/include/classes/widgets/views/widget.navtree.form.view.php b/ui/include/classes/widgets/views/widget.navtree.form.view.php
deleted file mode 100644
index 96601e3f47d..00000000000
--- a/ui/include/classes/widgets/views/widget.navtree.form.view.php
+++ /dev/null
@@ -1,72 +0,0 @@
-<?php declare(strict_types = 0);
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Map navigation tree widget form view.
- *
- * @var CView $this
- * @var array $data
- */
-
-$fields = $data['dialogue']['fields'];
-
-$form = CWidgetHelper::createForm();
-
-$form_grid = CWidgetHelper::createFormGrid($data['dialogue']['name'], $data['dialogue']['type'],
- $data['dialogue']['view_mode'], $data['known_widget_types'],
- $data['templateid'] === null ? $fields['rf_rate'] : null
-);
-
-// Map widget reference.
-$form->addItem(
- (new CVar($fields[CWidgetFieldReference::FIELD_NAME]->getName(),
- $fields[CWidgetFieldReference::FIELD_NAME]->getValue()
- ))->removeId()
-);
-
-// Add dynamically created fields navtree.name.<N>, navtree.parent.<N>, navtree.order.<N> and navtree.sysmapid.<N>.
-foreach ($fields['navtree']->getValue() as $i => $navtree_item) {
- $form->addItem((new CVar($fields['navtree']->getName().'.name.'.$i, $navtree_item['name']))->removeId());
-
- if ($navtree_item['order'] != 1) {
- $form->addItem((new CVar($fields['navtree']->getName().'.order.'.$i, $navtree_item['order']))->removeId());
- }
- if ($navtree_item['parent'] != 0) {
- $form->addItem((new CVar($fields['navtree']->getName().'.parent.'.$i, $navtree_item['parent']))->removeId());
- }
- if (array_key_exists('sysmapid', $navtree_item)) {
- $form->addItem(
- (new CVar($fields['navtree']->getName().'.sysmapid.'.$i, $navtree_item['sysmapid']))->removeId()
- );
- }
-}
-
-// Show unavailable maps.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['show_unavailable']),
- new CFormField(CWidgetHelper::getCheckBox($fields['show_unavailable']))
-]);
-
-$form->addItem($form_grid);
-
-return [
- 'form' => $form
-];
diff --git a/ui/include/classes/widgets/views/widget.plaintext.form.view.php b/ui/include/classes/widgets/views/widget.plaintext.form.view.php
deleted file mode 100644
index 649a4d0941b..00000000000
--- a/ui/include/classes/widgets/views/widget.plaintext.form.view.php
+++ /dev/null
@@ -1,81 +0,0 @@
-<?php declare(strict_types = 0);
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Plain text widget form view.
- *
- * @var CView $this
- * @var array $data
- */
-
-$fields = $data['dialogue']['fields'];
-
-$form = CWidgetHelper::createForm();
-
-$scripts = [];
-
-$form_grid = CWidgetHelper::createFormGrid($data['dialogue']['name'], $data['dialogue']['type'],
- $data['dialogue']['view_mode'], $data['known_widget_types'],
- $data['templateid'] === null ? $fields['rf_rate'] : null
-);
-
-// Items.
-$field_itemids = CWidgetHelper::getItem($fields['itemids'], $data['captions']['ms']['items']['itemids'],
- $form->getName()
-);
-$form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['itemids']),
- new CFormField($field_itemids)
-]);
-$scripts[] = $field_itemids->getPostJS();
-
-// Items location.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['style']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['style']))
-]);
-
-// Show lines.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['show_lines']),
- new CFormField(CWidgetHelper::getIntegerBox($fields['show_lines']))
-]);
-
-// Show text as HTML.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['show_as_html']),
- new CFormField(CWidgetHelper::getCheckBox($fields['show_as_html']))
-]);
-
-// Dynamic item.
-if ($data['templateid'] === null) {
- $form_grid->addItem([
- CWidgetHelper::getLabel($fields['dynamic']),
- new CFormField(CWidgetHelper::getCheckBox($fields['dynamic']))
- ]);
-}
-
-$form->addItem($form_grid);
-
-return [
- 'form' => $form,
- 'scripts' => $scripts
-];
diff --git a/ui/include/classes/widgets/views/widget.problemhosts.form.view.php b/ui/include/classes/widgets/views/widget.problemhosts.form.view.php
deleted file mode 100644
index c748d2119dd..00000000000
--- a/ui/include/classes/widgets/views/widget.problemhosts.form.view.php
+++ /dev/null
@@ -1,118 +0,0 @@
-<?php declare(strict_types = 0);
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Problem hosts widget form view.
- *
- * @var CView $this
- * @var array $data
- */
-
-$fields = $data['dialogue']['fields'];
-
-$form = CWidgetHelper::createForm();
-
-$scripts = [];
-
-$form_grid = CWidgetHelper::createFormGrid($data['dialogue']['name'], $data['dialogue']['type'],
- $data['dialogue']['view_mode'], $data['known_widget_types'],
- $data['templateid'] === null ? $fields['rf_rate'] : null
-);
-
-// Host groups.
-$field_groupids = CWidgetHelper::getGroup($fields['groupids'], $data['captions']['ms']['groups']['groupids'],
- $form->getName()
-);
-$form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['groupids']),
- new CFormField($field_groupids)
-]);
-$scripts[] = $field_groupids->getPostJS();
-
-// Exclude host groups.
-$field_exclude_groupids = CWidgetHelper::getGroup($fields['exclude_groupids'],
- $data['captions']['ms']['groups']['exclude_groupids'], $form->getName()
-);
-$form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['exclude_groupids']),
- new CFormField($field_exclude_groupids)
-]);
-$scripts[] = $field_exclude_groupids->getPostJS();
-
-// Hosts.
-$field_hostids = CWidgetHelper::getHost($fields['hostids'], $data['captions']['ms']['hosts']['hostids'],
- $form->getName()
-);
-$form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['hostids']),
- new CFormField($field_hostids)
-]);
-$scripts[] = $field_hostids->getPostJS();
-
-// Problem.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['problem']),
- new CFormField(CWidgetHelper::getTextBox($fields['problem']))
-]);
-
-// Severity.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['severities']),
- new CFormField(CWidgetHelper::getSeverities($fields['severities']))
-]);
-
-// Tags.
-$form_grid
- ->addItem([
- CWidgetHelper::getLabel($fields['evaltype']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['evaltype']))
- ])
- ->addItem(
- new CFormField(CWidgetHelper::getTags($fields['tags']))
- );
-$scripts[] = $fields['tags']->getJavascript();
-$jq_templates['tag-row-tmpl'] = CWidgetHelper::getTagsTemplate($fields['tags']);
-
-// Show suppressed problems.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['show_suppressed']),
- new CFormField(CWidgetHelper::getCheckBox($fields['show_suppressed']))
-]);
-
-// Hide groups without problems.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['hide_empty_groups']),
- new CFormField(CWidgetHelper::getCheckBox($fields['hide_empty_groups']))
-]);
-
-// Problem display.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['ext_ack']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['ext_ack']))
-]);
-
-$form->addItem($form_grid);
-
-return [
- 'form' => $form,
- 'scripts' => $scripts,
- 'jq_templates' => $jq_templates
-];
diff --git a/ui/include/classes/widgets/views/widget.problems.form.view.php b/ui/include/classes/widgets/views/widget.problems.form.view.php
deleted file mode 100644
index a806e7464a4..00000000000
--- a/ui/include/classes/widgets/views/widget.problems.form.view.php
+++ /dev/null
@@ -1,178 +0,0 @@
-<?php declare(strict_types = 0);
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Problems widget form view.
- *
- * @var CView $this
- * @var array $data
- */
-
-$fields = $data['dialogue']['fields'];
-
-$form = CWidgetHelper::createForm();
-
-$scripts = [$this->readJsFile('../../../include/classes/widgets/views/js/widget.problems.form.view.js.php')];
-
-$form_grid = CWidgetHelper::createFormGrid($data['dialogue']['name'], $data['dialogue']['type'],
- $data['dialogue']['view_mode'], $data['known_widget_types'],
- $data['templateid'] === null ? $fields['rf_rate'] : null
-);
-
-// Show.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['show']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['show']))
-]);
-
-// Host groups.
-$field_groupids = CWidgetHelper::getGroup($fields['groupids'], $data['captions']['ms']['groups']['groupids'],
- $form->getName()
-);
-$form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['groupids']),
- new CFormField($field_groupids)
-]);
-$scripts[] = $field_groupids->getPostJS();
-
-// Exclude host groups.
-$field_exclude_groupids = CWidgetHelper::getGroup($fields['exclude_groupids'],
- $data['captions']['ms']['groups']['exclude_groupids'], $form->getName()
-);
-$form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['exclude_groupids']),
- new CFormField($field_exclude_groupids)
-]);
-$scripts[] = $field_exclude_groupids->getPostJS();
-
-// Hosts.
-$field_hostids = CWidgetHelper::getHost($fields['hostids'], $data['captions']['ms']['hosts']['hostids'],
- $form->getName()
-);
-$form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['hostids']),
- new CFormField($field_hostids)
-]);
-$scripts[] = $field_hostids->getPostJS();
-
-// Problem.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['problem']),
- new CFormField(CWidgetHelper::getTextBox($fields['problem']))
-]);
-
-// Severity.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['severities']),
- new CFormField(CWidgetHelper::getSeverities($fields['severities']))
-]);
-
-// Tags.
-$form_grid
- ->addItem([
- CWidgetHelper::getLabel($fields['evaltype']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['evaltype']))
- ])
- ->addItem(
- new CFormField(CWidgetHelper::getTags($fields['tags']))
- );
-$scripts[] = $fields['tags']->getJavascript();
-$jq_templates['tag-row-tmpl'] = CWidgetHelper::getTagsTemplate($fields['tags']);
-
-// Show tags.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['show_tags']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['show_tags']))
-]);
-
-// Tag name.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['tag_name_format']),
- new CFormField(
- CWidgetHelper::getRadioButtonList($fields['tag_name_format'])
- ->setEnabled($fields['show_tags']->getValue() !== SHOW_TAGS_NONE)
- )
-]);
-
-// Tag display priority.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['tag_priority']),
- new CFormField(
- CWidgetHelper::getTextBox($fields['tag_priority'])
- ->setAttribute('placeholder', _('comma-separated list'))
- ->setEnabled($fields['show_tags']->getValue() !== SHOW_TAGS_NONE)
- )
-]);
-
-// Show operational data.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['show_opdata']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['show_opdata']))
-]);
-
-// Show suppressed problems.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['show_suppressed']),
- new CFormField(CWidgetHelper::getCheckBox($fields['show_suppressed']))
-]);
-
-// Show unacknowledged only.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['unacknowledged']),
- new CFormField(CWidgetHelper::getCheckBox($fields['unacknowledged']))
-]);
-
-// Sort entries by.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['sort_triggers']),
- new CFormField(CWidgetHelper::getSelect($fields['sort_triggers']))
-]);
-
-// Show timeline.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['show_timeline']),
- new CFormField(CWidgetHelper::getCheckBox($fields['show_timeline']))
-]);
-
-// Show lines.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['show_lines']),
- new CFormField(CWidgetHelper::getIntegerBox($fields['show_lines']))
-]);
-
-$form
- ->addItem($form_grid)
- ->addItem(
- (new CScriptTag('
- widget_problems_form.init('.json_encode([
- 'sort_with_enabled_show_timeline' => [
- SCREEN_SORT_TRIGGERS_TIME_DESC => true,
- SCREEN_SORT_TRIGGERS_TIME_ASC => true
- ]
- ]).');
- '))->setOnDocumentReady()
- );
-
-return [
- 'form' => $form,
- 'scripts' => $scripts,
- 'jq_templates' => $jq_templates
-];
diff --git a/ui/include/classes/widgets/views/widget.problemsbysv.form.view.php b/ui/include/classes/widgets/views/widget.problemsbysv.form.view.php
deleted file mode 100644
index f1e48a701ce..00000000000
--- a/ui/include/classes/widgets/views/widget.problemsbysv.form.view.php
+++ /dev/null
@@ -1,142 +0,0 @@
-<?php declare(strict_types = 0);
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Problems by severity widget form view.
- *
- * @var CView $this
- * @var array $data
- */
-
-$fields = $data['dialogue']['fields'];
-
-$form = CWidgetHelper::createForm();
-
-$scripts = [];
-
-$form_grid = CWidgetHelper::createFormGrid($data['dialogue']['name'], $data['dialogue']['type'],
- $data['dialogue']['view_mode'], $data['known_widget_types'],
- $data['templateid'] === null ? $fields['rf_rate'] : null
-);
-
-// Host groups.
-$field_groupids = CWidgetHelper::getGroup($fields['groupids'], $data['captions']['ms']['groups']['groupids'],
- $form->getName()
-);
-$form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['groupids']),
- new CFormField($field_groupids)
-]);
-$scripts[] = $field_groupids->getPostJS();
-
-// Exclude host groups.
-$field_exclude_groupids = CWidgetHelper::getGroup($fields['exclude_groupids'],
- $data['captions']['ms']['groups']['exclude_groupids'], $form->getName()
-);
-$form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['exclude_groupids']),
- new CFormField($field_exclude_groupids)
-]);
-$scripts[] = $field_exclude_groupids->getPostJS();
-
-// Hosts.
-$field_hostids = CWidgetHelper::getHost($fields['hostids'], $data['captions']['ms']['hosts']['hostids'],
- $form->getName()
-);
-$form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['hostids']),
- new CFormField($field_hostids)
-]);
-$scripts[] = $field_hostids->getPostJS();
-
-// Problem.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['problem']),
- new CFormField(CWidgetHelper::getTextBox($fields['problem']))
-]);
-
-// Severity.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['severities']),
- new CFormField(CWidgetHelper::getSeverities($fields['severities']))
-]);
-
-// Tags.
-$form_grid
- ->addItem([
- CWidgetHelper::getLabel($fields['evaltype']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['evaltype']))
- ])
- ->addItem(
- new CFormField(CWidgetHelper::getTags($fields['tags']))
- );
-$scripts[] = $fields['tags']->getJavascript();
-$jq_templates['tag-row-tmpl'] = CWidgetHelper::getTagsTemplate($fields['tags']);
-
-// Show.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['show_type']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['show_type']))
-]);
-
-// Layout.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['layout']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['layout']))
-]);
-
-// Show operational data.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['show_opdata']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['show_opdata']))
-]);
-
-// Show suppressed problems.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['show_suppressed']),
- new CFormField(CWidgetHelper::getCheckBox($fields['show_suppressed']))
-]);
-
-// Hide groups without problems.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['hide_empty_groups']),
- new CFormField(CWidgetHelper::getCheckBox($fields['hide_empty_groups']))
-]);
-
-// Problem display.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['ext_ack']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['ext_ack']))
-]);
-
-// Show timeline.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['show_timeline']),
- new CFormField(CWidgetHelper::getCheckBox($fields['show_timeline']))
-]);
-
-$form->addItem($form_grid);
-
-return [
- 'form' => $form,
- 'scripts' => $scripts,
- 'jq_templates' => $jq_templates
-];
diff --git a/ui/include/classes/widgets/views/widget.slareport.form.view.php b/ui/include/classes/widgets/views/widget.slareport.form.view.php
deleted file mode 100644
index 9a470ac3cfe..00000000000
--- a/ui/include/classes/widgets/views/widget.slareport.form.view.php
+++ /dev/null
@@ -1,98 +0,0 @@
-<?php declare(strict_types = 0);
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * SLA report widget form view.
- *
- * @var CView $this
- * @var array $data
- */
-
-$fields = $data['dialogue']['fields'];
-
-$form = CWidgetHelper::createForm();
-
-$scripts = [$this->readJsFile('../../../include/classes/widgets/views/js/widget.slareport.form.view.js.php')];
-
-$form_grid = CWidgetHelper::createFormGrid($data['dialogue']['name'], $data['dialogue']['type'],
- $data['dialogue']['view_mode'], $data['known_widget_types'],
- $data['templateid'] === null ? $fields['rf_rate'] : null
-);
-
-// SLA.
-$field_slaid = CWidgetHelper::getSla($fields['slaid'], $data['captions']['ms']['slas']['slaid'],
- $form->getName()
-);
-$form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['slaid']),
- new CFormField($field_slaid)
-]);
-$scripts[] = $field_slaid->getPostJS();
-
-// Service.
-$field_serviceid = CWidgetHelper::getService($fields['serviceid'], $data['captions']['ms']['services']['serviceid'],
- $form->getName()
-);
-$form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['serviceid']),
- new CFormField($field_serviceid)
-]);
-$scripts[] = $field_serviceid->getPostJS();
-
-// Show periods.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['show_periods']),
- new CFormField(CWidgetHelper::getIntegerBox($fields['show_periods']))
-]);
-
-// From.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['date_from']),
- new CFormField(
- CWidgetHelper::getDatePicker($fields['date_from'])
- ->setDateFormat(ZBX_DATE)
- ->setPlaceholder(_('YYYY-MM-DD'))
- )
-]);
-
-// To.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['date_to']),
- new CFormField(
- CWidgetHelper::getDatePicker($fields['date_to'])
- ->setDateFormat(ZBX_DATE)
- ->setPlaceholder(_('YYYY-MM-DD'))
- )
-]);
-
-$form->addItem($form_grid);
-
-$scripts[] = '
- widget_slareport_form.init('.json_encode([
- 'serviceid_field_id' => $fields['serviceid']->getName(),
- 'serviceid_multiple' => $fields['serviceid']->isMultiple()
- ]).');
-';
-
-return [
- 'form' => $form,
- 'scripts' => $scripts
-];
diff --git a/ui/include/classes/widgets/views/widget.svggraph.form.view.php b/ui/include/classes/widgets/views/widget.svggraph.form.view.php
deleted file mode 100644
index 4c42861e105..00000000000
--- a/ui/include/classes/widgets/views/widget.svggraph.form.view.php
+++ /dev/null
@@ -1,328 +0,0 @@
-<?php declare(strict_types = 0);
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * SVG graph widget form view.
- *
- * @var CView $this
- * @var array $data
- */
-
-$fields = $data['dialogue']['fields'];
-
-$form = CWidgetHelper::createForm();
-
-$scripts = [$this->readJsFile('../../../include/classes/widgets/views/js/widget.svggraph.form.view.js.php')];
-$jq_templates = [];
-
-$form_grid = CWidgetHelper::createFormGrid($data['dialogue']['name'], $data['dialogue']['type'],
- $data['dialogue']['view_mode'], $data['known_widget_types'],
- $data['templateid'] === null ? $fields['rf_rate'] : null
-);
-
-$graph_preview = (new CDiv())
- ->addClass(ZBX_STYLE_SVG_GRAPH_PREVIEW)
- ->addItem((new CDiv())->setId('svg-graph-preview'));
-
-$form_tabs = (new CTabView())
- ->addTab('data_set', _('Data set'), getDatasetTab($fields, $jq_templates, $form->getName()),
- TAB_INDICATOR_GRAPH_DATASET
- )
- ->addTab('displaying_options', _('Displaying options'), getDisplayOptionsTab($fields),
- TAB_INDICATOR_GRAPH_DISPLAY_OPTIONS
- )
- ->addTab('time_period', _('Time period'), getTimePeriodTab($fields), TAB_INDICATOR_GRAPH_TIME)
- ->addTab('axes', _('Axes'), getAxesTab($fields), TAB_INDICATOR_GRAPH_AXES)
- ->addTab('legend_tab', _('Legend'), getLegendTab($fields, $scripts), TAB_INDICATOR_GRAPH_LEGEND)
- ->addTab('problems', _('Problems'), getProblemsTab($fields, $scripts, $jq_templates, $form->getName()),
- TAB_INDICATOR_GRAPH_PROBLEMS
- )
- ->addTab('overrides', _('Overrides'), getOverridesTab($fields, $scripts, $jq_templates, $form->getName()),
- TAB_INDICATOR_GRAPH_OVERRIDES
- )
- ->addClass('graph-widget-config-tabs')
- ->setSelected(0);
-$scripts[] = $form_tabs->makeJavascript();
-
-$form
- ->addItem($form_grid)
- ->addItem($graph_preview)
- ->addItem($form_tabs);
-
-$scripts[] = '
- widget_svggraph_form.init('.json_encode([
- 'form_id' => $form->getId(),
- 'form_tabs_id' => $form_tabs->getId(),
- 'color_palette' => CWidgetFieldGraphDataSet::DEFAULT_COLOR_PALETTE
- ]).');
-';
-
-return [
- 'form' => $form,
- 'scripts' => $scripts,
- 'jq_templates' => $jq_templates
-];
-
-function getGraphDataSetItemRow(): string {
- return (new CRow([
- (new CCol(
- (new CDiv())->addClass(ZBX_STYLE_DRAG_ICON)
- ))
- ->addClass('table-col-handle')
- ->addClass(ZBX_STYLE_TD_DRAG_ICON),
- (new CCol(
- (new CColor('ds[#{dsNum}][color][]', '#{color}', 'items_#{dsNum}_#{rowNum}_color'))
- ->appendColorPickerJs(false)
- ))->addClass('table-col-color'),
- (new CCol(new CSpan('#{rowNum}:')))->addClass('table-col-no'),
- (new CCol(
- (new CLink('#{name}'))
- ->setId('items_#{dsNum}_#{rowNum}_name')
- ->addClass('js-click-expend')
- ))->addClass('table-col-name'),
- (new CCol([
- (new CButton('button', _('Remove')))
- ->addClass(ZBX_STYLE_BTN_LINK)
- ->addClass('element-table-remove'),
- (new CVar('ds[#{dsNum}][itemids][]', '#{itemid}', 'items_#{dsNum}_#{rowNum}_input'))
- ]))
- ->addClass('table-col-action')
- ->addClass(ZBX_STYLE_NOWRAP)
- ]))
- ->addClass('sortable')
- ->addClass('single-item-table-row')
- ->toString();
-}
-
-function getDatasetTab(array $fields, array &$jq_templates, string $form_name): CFormGrid {
- $jq_templates['dataset-single-item-tmpl'] = CWidgetHelper::getGraphDataSetTemplate($fields['ds'], $form_name,
- CWidgetHelper::DATASET_TYPE_SINGLE_ITEM
- );
- $jq_templates['dataset-pattern-item-tmpl'] = CWidgetHelper::getGraphDataSetTemplate($fields['ds'], $form_name,
- CWidgetHelper::DATASET_TYPE_PATTERN_ITEM
- );
- $jq_templates['dataset-item-row-tmpl'] = getGraphDataSetItemRow();
-
- return (new CFormGrid())
- ->addItem([
- CWidgetHelper::getLabel($fields['ds']),
- (new CFormField(CWidgetHelper::getGraphDataSet($fields['ds'], $form_name)))
- ->addClass(ZBX_STYLE_LIST_VERTICAL_ACCORDION),
- (new CFormField(CWidgetHelper::getGraphDataSetFooter()))->addClass(ZBX_STYLE_LIST_ACCORDION_FOOT)
- ]);
-}
-
-function getDisplayOptionsTab(array $fields): CDiv {
- return (new CDiv())
- ->addClass(ZBX_STYLE_GRID_COLUMNS)
- ->addClass(ZBX_STYLE_GRID_COLUMNS_2)
- ->addItem(
- (new CFormGrid())
- ->addItem([
- CWidgetHelper::getLabel($fields['source']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['source']))
- ])
- ->addItem([
- CWidgetHelper::getLabel($fields['simple_triggers']),
- new CFormField(CWidgetHelper::getCheckBox($fields['simple_triggers']))
- ])
- ->addItem([
- CWidgetHelper::getLabel($fields['working_time']),
- new CFormField(CWidgetHelper::getCheckBox($fields['working_time']))
- ])
- )
- ->addItem(
- (new CFormGrid())
- ->addItem([
- CWidgetHelper::getLabel($fields['percentile_left']),
- new CFormField([
- CWidgetHelper::getCheckBox($fields['percentile_left']),
- CWidgetHelper::getTextBox($fields['percentile_left_value'])
- ])
- ])
- ->addItem([
- CWidgetHelper::getLabel($fields['percentile_right']),
- new CFormField([
- CWidgetHelper::getCheckBox($fields['percentile_right']),
- CWidgetHelper::getTextBox($fields['percentile_right_value'])
- ])
- ])
- );
-}
-
-function getTimePeriodTab(array $fields): CFormGrid {
- return (new CFormGrid())
- ->addItem([
- CWidgetHelper::getLabel($fields['graph_time']),
- new CFormField(CWidgetHelper::getCheckBox($fields['graph_time']))
- ])
- ->addItem([
- CWidgetHelper::getLabel($fields['time_from']),
- new CFormField(
- CWidgetHelper::getDatePicker($fields['time_from'])
- ->setDateFormat(ZBX_FULL_DATE_TIME)
- ->setPlaceholder(_('YYYY-MM-DD hh:mm:ss'))
- )
- ])
- ->addItem([
- CWidgetHelper::getLabel($fields['time_to']),
- new CFormField(
- CWidgetHelper::getDatePicker($fields['time_to'])
- ->setDateFormat(ZBX_FULL_DATE_TIME)
- ->setPlaceholder(_('YYYY-MM-DD hh:mm:ss'))
- )
- ]);
-}
-
-function getAxesTab(array $fields): CDiv {
- return (new CDiv())
- ->addClass(ZBX_STYLE_GRID_COLUMNS)
- ->addClass(ZBX_STYLE_GRID_COLUMNS_3)
- ->addItem(
- (new CFormGrid())
- ->addItem([
- CWidgetHelper::getLabel($fields['lefty']),
- new CFormField(CWidgetHelper::getCheckBox($fields['lefty']))
- ])
- ->addItem([
- CWidgetHelper::getLabel($fields['lefty_min']),
- new CFormField(CWidgetHelper::getNumericBox($fields['lefty_min']))
- ])
- ->addItem([
- CWidgetHelper::getLabel($fields['lefty_max']),
- new CFormField(CWidgetHelper::getNumericBox($fields['lefty_max']))
- ])
- ->addItem([
- CWidgetHelper::getLabel($fields['lefty_units']),
- new CFormField([
- CWidgetHelper::getSelect($fields['lefty_units'])->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
- CWidgetHelper::getTextBox($fields['lefty_static_units'])
- ])
- ])
- )
- ->addItem(
- (new CFormGrid())
- ->addItem([
- CWidgetHelper::getLabel($fields['righty']),
- new CFormField(CWidgetHelper::getCheckBox($fields['righty']))
- ])
- ->addItem([
- CWidgetHelper::getLabel($fields['righty_min']),
- new CFormField(CWidgetHelper::getNumericBox($fields['righty_min']))
- ])
- ->addItem([
- CWidgetHelper::getLabel($fields['righty_max']),
- new CFormField(CWidgetHelper::getNumericBox($fields['righty_max']))
- ])
- ->addItem([
- CWidgetHelper::getLabel($fields['righty_units']),
- new CFormField([
- CWidgetHelper::getSelect($fields['righty_units'])->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
- CWidgetHelper::getTextBox($fields['righty_static_units'])
- ])
- ])
- )
- ->addItem(
- (new CFormGrid())
- ->addItem([
- CWidgetHelper::getLabel($fields['axisx']),
- new CFormField(CWidgetHelper::getCheckBox($fields['axisx']))
- ])
- );
-}
-
-function getLegendTab(array $fields, array &$scripts): CDiv {
- $field_legend_lines = CWidgetHelper::getRangeControl($fields['legend_lines']);
- $field_legend_columns = CWidgetHelper::getRangeControl($fields['legend_columns']);
-
- $scripts[] = $field_legend_lines->getPostJS();
- $scripts[] = $field_legend_columns->getPostJS();
-
- return (new CDiv())
- ->addClass(ZBX_STYLE_GRID_COLUMNS)
- ->addClass(ZBX_STYLE_GRID_COLUMNS_2)
- ->addItem(
- (new CFormGrid())
- ->addItem([
- CWidgetHelper::getLabel($fields['legend']),
- new CFormField(CWidgetHelper::getCheckBox($fields['legend']))
- ])
- ->addItem([
- CWidgetHelper::getLabel($fields['legend_statistic']),
- new CFormField(CWidgetHelper::getCheckBox($fields['legend_statistic']))
- ])
- )
- ->addItem(
- (new CFormGrid())
- ->addItem([
- CWidgetHelper::getLabel($fields['legend_lines']),
- new CFormField($field_legend_lines)
- ])
- ->addItem([
- CWidgetHelper::getLabel($fields['legend_columns']),
- new CFormField($field_legend_columns)
- ])
- );
-}
-
-function getProblemsTab(array $fields, array &$scripts, array &$jq_templates, string $form_name): CFormGrid {
- $scripts[] = $fields['problemhosts']->getJavascript();
- $scripts[] = $fields['tags']->getJavascript();
- $jq_templates['tag-row-tmpl'] = CWidgetHelper::getTagsTemplate($fields['tags']);
-
- return (new CFormGrid())
- ->addItem([
- CWidgetHelper::getLabel($fields['show_problems']),
- new CFormField(CWidgetHelper::getCheckBox($fields['show_problems']))
- ])
- ->addItem([
- CWidgetHelper::getLabel($fields['graph_item_problems']),
- new CFormField(CWidgetHelper::getCheckBox($fields['graph_item_problems']))
- ])
- ->addItem([
- CWidgetHelper::getLabel($fields['problemhosts']),
- new CFormField(CWidgetHelper::getHostPatternSelect($fields['problemhosts'], $form_name))
- ])
- ->addItem([
- CWidgetHelper::getLabel($fields['severities']),
- new CFormField(CWidgetHelper::getSeverities($fields['severities']))
- ])
- ->addItem([
- CWidgetHelper::getLabel($fields['problem_name']),
- new CFormField(CWidgetHelper::getTextBox($fields['problem_name']))
- ])
- ->addItem([
- CWidgetHelper::getLabel($fields['evaltype']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['evaltype']))
- ])
- ->addItem(new CFormField(CWidgetHelper::getTags($fields['tags'])));
-}
-
-function getOverridesTab(array $fields, array &$scripts, array &$jq_templates, string $form_name): CFormGrid {
- $scripts[] = CWidgetHelper::getGraphOverrideJavascript($fields['or']);
- $jq_templates['overrides-row'] = CWidgetHelper::getGraphOverrideTemplate($fields['or'], $form_name);
-
- return (new CFormGrid())
- ->addItem([
- CWidgetHelper::getLabel($fields['or']),
- new CFormField(CWidgetHelper::getGraphOverride($fields['or'], $form_name))
- ]);
-}
diff --git a/ui/include/classes/widgets/views/widget.tophosts.form.view.php b/ui/include/classes/widgets/views/widget.tophosts.form.view.php
deleted file mode 100644
index b740f4f2ea5..00000000000
--- a/ui/include/classes/widgets/views/widget.tophosts.form.view.php
+++ /dev/null
@@ -1,118 +0,0 @@
-<?php declare(strict_types = 0);
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Data overview widget form view.
- *
- * @var CView $this
- * @var array $data
- */
-
-$fields = $data['dialogue']['fields'];
-
-$form = CWidgetHelper::createForm();
-
-$scripts = [$this->readJsFile('../../../include/classes/widgets/views/js/widget.tophosts.form.view.js.php')];
-
-$form_grid = CWidgetHelper::createFormGrid($data['dialogue']['name'], $data['dialogue']['type'],
- $data['dialogue']['view_mode'], $data['known_widget_types'],
- $data['templateid'] === null ? $fields['rf_rate'] : null
-);
-
-// Host groups.
-$field_groupids = CWidgetHelper::getGroup($fields['groupids'], $data['captions']['ms']['groups']['groupids'],
- $form->getName()
-);
-$form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['groupids']),
- new CFormField($field_groupids)
-]);
-$scripts[] = $field_groupids->getPostJS();
-
-// Hosts.
-$field_hostids = CWidgetHelper::getHost($fields['hostids'], $data['captions']['ms']['hosts']['hostids'],
- $form->getName()
-);
-$form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['hostids']),
- new CFormField($field_hostids)
-]);
-$scripts[] = $field_hostids->getPostJS();
-
-// Host tags.
-$form_grid
- ->addItem([
- CWidgetHelper::getLabel($fields['evaltype']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['evaltype']))
- ])
- ->addItem(
- new CFormField(CWidgetHelper::getTags($fields['tags']))
- );
-$scripts[] = $fields['tags']->getJavascript();
-$jq_templates['tag-row-tmpl'] = CWidgetHelper::getTagsTemplate($fields['tags']);
-
-// Columns.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['columns']),
- (new CFormField(
- CWidgetHelper::getWidgetColumns($fields['columns'])
- ))->addClass(ZBX_STYLE_TABLE_FORMS_SEPARATOR)
-]);
-
-// Order.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['order']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['order']))
-]);
-
-// Order column.
-$column = CWidgetHelper::getSelect($fields['column']);
-if (!$fields['column']->getValues()) {
- $column = (new CDiv(_('Add item column')))->addClass(
- ($fields['column']->getFlags() & CWidgetField::FLAG_DISABLED)
- ? ZBX_STYLE_DISABLED
- : null
- );
-}
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['column']),
- new CFormField($column)
-]);
-
-// Hosts count.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['count']),
- new CFormField(CWidgetHelper::getIntegerBox($fields['count']))
-]);
-
-$form->addItem($form_grid);
-
-$scripts[] = '
- widget_tophosts_form.init('.json_encode([
- 'form_id' => $form->getId()
- ]).');
-';
-
-return [
- 'form' => $form,
- 'scripts' => $scripts,
- 'jq_templates' => $jq_templates
-];
diff --git a/ui/include/classes/widgets/views/widget.trigover.form.view.php b/ui/include/classes/widgets/views/widget.trigover.form.view.php
deleted file mode 100644
index af3327ed14e..00000000000
--- a/ui/include/classes/widgets/views/widget.trigover.form.view.php
+++ /dev/null
@@ -1,96 +0,0 @@
-<?php declare(strict_types = 0);
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Trigger overview widget form view.
- *
- * @var CView $this
- * @var array $data
- */
-
-$fields = $data['dialogue']['fields'];
-
-$form = CWidgetHelper::createForm();
-
-$scripts = [];
-
-$form_grid = CWidgetHelper::createFormGrid($data['dialogue']['name'], $data['dialogue']['type'],
- $data['dialogue']['view_mode'], $data['known_widget_types'],
- $data['templateid'] === null ? $fields['rf_rate'] : null
-);
-
-// Show.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['show']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['show']))
-]);
-
-// Host groups.
-$field_groupids = CWidgetHelper::getGroup($fields['groupids'], $data['captions']['ms']['groups']['groupids'],
- $form->getName()
-);
-$form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['groupids']),
- new CFormField($field_groupids)
-]);
-$scripts[] = $field_groupids->getPostJS();
-
-// Hosts.
-$field_hostids = CWidgetHelper::getHost($fields['hostids'], $data['captions']['ms']['hosts']['hostids'],
- $form->getName()
-);
-$form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['hostids']),
- new CFormField($field_hostids)
-]);
-$scripts[] = $field_hostids->getPostJS();
-
-// Tags.
-$form_grid
- ->addItem([
- CWidgetHelper::getLabel($fields['evaltype']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['evaltype']))
- ])
- ->addItem(
- new CFormField(CWidgetHelper::getTags($fields['tags']))
- );
-$scripts[] = $fields['tags']->getJavascript();
-$jq_templates['tag-row-tmpl'] = CWidgetHelper::getTagsTemplate($fields['tags']);
-
-// Show suppressed problems.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['show_suppressed']),
- new CFormField(CWidgetHelper::getCheckBox($fields['show_suppressed']))
-]);
-
-// Hosts location.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['style']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['style']))
-]);
-
-$form->addItem($form_grid);
-
-return [
- 'form' => $form,
- 'scripts' => $scripts,
- 'jq_templates' => $jq_templates
-];
diff --git a/ui/include/classes/widgets/views/widget.url.form.view.php b/ui/include/classes/widgets/views/widget.url.form.view.php
deleted file mode 100644
index b055cbbd4a0..00000000000
--- a/ui/include/classes/widgets/views/widget.url.form.view.php
+++ /dev/null
@@ -1,56 +0,0 @@
-<?php declare(strict_types = 0);
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * URL widget form view.
- *
- * @var CView $this
- * @var array $data
- */
-
-$fields = $data['dialogue']['fields'];
-
-$form = CWidgetHelper::createForm();
-
-$form_grid = CWidgetHelper::createFormGrid($data['dialogue']['name'], $data['dialogue']['type'],
- $data['dialogue']['view_mode'], $data['known_widget_types'],
- $data['templateid'] === null ? $fields['rf_rate'] : null
-);
-
-// URL.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['url']),
- new CFormField(CWidgetHelper::getUrlBox($fields['url']))
-]);
-
-// Dynamic item.
-if ($data['templateid'] === null) {
- $form_grid->addItem([
- CWidgetHelper::getLabel($fields['dynamic']),
- new CFormField(CWidgetHelper::getCheckBox($fields['dynamic']))
- ]);
-}
-
-$form->addItem($form_grid);
-
-return [
- 'form' => $form
-];
diff --git a/ui/include/classes/widgets/views/widget.web.form.view.php b/ui/include/classes/widgets/views/widget.web.form.view.php
deleted file mode 100644
index 40b5364f77d..00000000000
--- a/ui/include/classes/widgets/views/widget.web.form.view.php
+++ /dev/null
@@ -1,94 +0,0 @@
-<?php declare(strict_types = 0);
-/*
-** Zabbix
-** Copyright (C) 2001-2022 Zabbix SIA
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**/
-
-
-/**
- * Web widget form view.
- *
- * @var CView $this
- * @var array $data
- */
-
-$fields = $data['dialogue']['fields'];
-
-$form = CWidgetHelper::createForm();
-
-$scripts = [];
-
-$form_grid = CWidgetHelper::createFormGrid($data['dialogue']['name'], $data['dialogue']['type'],
- $data['dialogue']['view_mode'], $data['known_widget_types'],
- $data['templateid'] === null ? $fields['rf_rate'] : null
-);
-
-// Host groups.
-$field_groupids = CWidgetHelper::getGroup($fields['groupids'], $data['captions']['ms']['groups']['groupids'],
- $form->getName()
-);
-$form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['groupids']),
- new CFormField($field_groupids)
-]);
-$scripts[] = $field_groupids->getPostJS();
-
-// Exclude host groups.
-$field_exclude_groupids = CWidgetHelper::getGroup($fields['exclude_groupids'],
- $data['captions']['ms']['groups']['exclude_groupids'], $form->getName()
-);
-$form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['exclude_groupids']),
- new CFormField($field_exclude_groupids)
-]);
-$scripts[] = $field_exclude_groupids->getPostJS();
-
-// Hosts.
-$field_hostids = CWidgetHelper::getHost($fields['hostids'], $data['captions']['ms']['hosts']['hostids'],
- $form->getName()
-);
-$form_grid->addItem([
- CWidgetHelper::getMultiselectLabel($fields['hostids']),
- new CFormField($field_hostids)
-]);
-$scripts[] = $field_hostids->getPostJS();
-
-// Tags.
-$form_grid
- ->addItem([
- CWidgetHelper::getLabel($fields['evaltype']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['evaltype']))
- ])
- ->addItem(
- new CFormField(CWidgetHelper::getTags($fields['tags']))
- );
-$scripts[] = $fields['tags']->getJavascript();
-$jq_templates['tag-row-tmpl'] = CWidgetHelper::getTagsTemplate($fields['tags']);
-
-// Show hosts in maintenance.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['maintenance']),
- new CFormField(CWidgetHelper::getCheckBox($fields['maintenance']))
-]);
-
-$form->addItem($form_grid);
-
-return [
- 'form' => $form,
- 'scripts' => $scripts,
- 'jq_templates' => $jq_templates
-];
diff --git a/ui/include/defines.inc.php b/ui/include/defines.inc.php
index 36200260754..f42c123840b 100644
--- a/ui/include/defines.inc.php
+++ b/ui/include/defines.inc.php
@@ -18,11 +18,11 @@
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
-define('ZABBIX_VERSION', '6.4.0beta3');
+define('ZABBIX_VERSION', '6.4.0beta2');
define('ZABBIX_API_VERSION', '6.4.0');
define('ZABBIX_EXPORT_VERSION', '6.4');
-define('ZABBIX_DB_VERSION', 6030061);
+define('ZABBIX_DB_VERSION', 6030063);
define('DB_VERSION_SUPPORTED', 0);
define('DB_VERSION_LOWER_THAN_MINIMUM', 1);
@@ -134,9 +134,6 @@ define('EXTACK_OPTION_ALL', 0);
define('EXTACK_OPTION_UNACK', 1);
define('EXTACK_OPTION_BOTH', 2);
-define('WIDGET_PROBLEMS_BY_SV_SHOW_GROUPS', 0);
-define('WIDGET_PROBLEMS_BY_SV_SHOW_TOTALS', 1);
-
define('TRIGGERS_OPTION_RECENT_PROBLEM', 1);
define('TRIGGERS_OPTION_ALL', 2);
define('TRIGGERS_OPTION_IN_PROBLEM', 3);
@@ -860,7 +857,7 @@ define('SCREEN_SORT_TRIGGERS_NAME_DESC', 16);
define('SCREEN_MODE_PREVIEW', 0);
define('SCREEN_MODE_EDIT', 1);
-define('SCREEN_MODE_SLIDESHOW', 2);
+define('SCREEN_MODE_SLIDESHOW', 2);
define('SCREEN_MODE_JS', 3);
define('SCREEN_REFRESH_RESPONSIVENESS', 10);
@@ -1177,7 +1174,8 @@ define('SVG_GRAPH_PERCENTILE_LEFT_ON', 1);
define('SVG_GRAPH_PERCENTILE_RIGHT_OFF', 0);
define('SVG_GRAPH_PERCENTILE_RIGHT_ON', 1);
-define('SVG_GRAPH_CUSTOM_TIME', 1);
+define('SVG_GRAPH_CUSTOM_TIME_OFF', 0);
+define('SVG_GRAPH_CUSTOM_TIME_ON', 1);
define('SVG_GRAPH_LEGEND_OFF', 0);
define('SVG_GRAPH_LEGEND_ON', 1);
@@ -1191,11 +1189,13 @@ define('SVG_GRAPH_LEGEND_LINES_MAX', 10);
define('SVG_GRAPH_LEGEND_COLUMNS_MIN', 1);
define('SVG_GRAPH_LEGEND_COLUMNS_MAX', 4);
-define('SVG_GRAPH_PROBLEMS_SHOW', 1);
+define('SVG_GRAPH_PROBLEMS_OFF', 0);
+define('SVG_GRAPH_PROBLEMS_ON', 1);
define('SVG_GRAPH_SELECTED_ITEM_PROBLEMS', 1);
-define('SVG_GRAPH_AXIS_SHOW', 1);
+define('SVG_GRAPH_AXIS_OFF', 0);
+define('SVG_GRAPH_AXIS_ON', 1);
define('SVG_GRAPH_AXIS_UNITS_AUTO', 0);
define('SVG_GRAPH_AXIS_UNITS_STATIC', 1);
@@ -1292,6 +1292,9 @@ define('ZBX_FUNCTION_TYPE_OPERATOR', 5);
define('ZBX_FUNCTION_TYPE_PREDICTION', 6);
define('ZBX_FUNCTION_TYPE_STRING', 7);
+define('ZBX_TIMELINE_OFF', 0);
+define('ZBX_TIMELINE_ON', 1);
+
/**
* @deprecated use either a literal space " " or a non-breakable space "&nbsp;" instead
*/
@@ -1609,94 +1612,28 @@ define('ZBX_ACTIONS_POPUP_MAX_WIDTH', 800);
define('ZBX_HINTBOX_CONTENT_LIMIT', 8192);
-// dashboard widgets
-define('WIDGET_ACTION_LOG', 'actionlog');
+// Dashboard widget types supported in templates (used only in import converters).
define('WIDGET_CLOCK', 'clock');
-define('WIDGET_DISCOVERY', 'discovery');
-define('WIDGET_FAV_GRAPHS', 'favgraphs');
-define('WIDGET_FAV_MAPS', 'favmaps');
-define('WIDGET_GEOMAP', 'geomap');
define('WIDGET_GRAPH', 'graph');
define('WIDGET_GRAPH_PROTOTYPE', 'graphprototype');
-define('WIDGET_HOST_AVAIL', 'hostavail');
-define('WIDGET_MAP', 'map');
-define('WIDGET_NAV_TREE', 'navtree');
+define('WIDGET_ITEM', 'item');
define('WIDGET_PLAIN_TEXT', 'plaintext');
-define('WIDGET_PROBLEM_HOSTS', 'problemhosts');
-define('WIDGET_PROBLEMS', 'problems');
-define('WIDGET_PROBLEMS_BY_SV', 'problemsbysv');
-define('WIDGET_SLA_REPORT', 'slareport');
-define('WIDGET_SVG_GRAPH', 'svggraph');
-define('WIDGET_SYSTEM_INFO', 'systeminfo');
-define('WIDGET_TOP_HOSTS', 'tophosts');
-define('WIDGET_TRIG_OVER', 'trigover');
define('WIDGET_URL', 'url');
-define('WIDGET_WEB', 'web');
-define('WIDGET_ITEM', 'item');
-// Deprecated widgets
-define('WIDGET_DATA_OVER', 'dataover');
-
-// Clock widget type
-define('WIDGET_CLOCK_TYPE_ANALOG', 0);
-define('WIDGET_CLOCK_TYPE_DIGITAL', 1);
-
-// Clock time zone format
-define('WIDGET_CLOCK_TIMEZONE_SHORT', 0);
-define('WIDGET_CLOCK_TIMEZONE_FULL', 1);
-
-// Clock widget time format
-define('WIDGET_CLOCK_HOUR_TWENTY_FOUR', 0);
-define('WIDGET_CLOCK_HOUR_TWELVE', 1);
-
-// Item widget object positions.
-define('WIDGET_ITEM_POS_LEFT', 0);
-define('WIDGET_ITEM_POS_CENTER', 1);
-define('WIDGET_ITEM_POS_RIGHT', 2);
-
-define('WIDGET_ITEM_POS_TOP', 0);
-define('WIDGET_ITEM_POS_MIDDLE', 1);
-define('WIDGET_ITEM_POS_BOTTOM', 2);
-
-define('WIDGET_ITEM_POS_BEFORE', 0);
-define('WIDGET_ITEM_POS_ABOVE', 1);
-define('WIDGET_ITEM_POS_AFTER', 2);
-define('WIDGET_ITEM_POS_BELOW', 3);
-
-// sysmap widget source types
-define('WIDGET_SYSMAP_SOURCETYPE_MAP', 1);
-define('WIDGET_SYSMAP_SOURCETYPE_FILTER', 2);
-
-// widget select resource field types
-define('WIDGET_FIELD_SELECT_RES_SYSMAP', 1);
-
-// max depth of navigation tree
-define('WIDGET_NAVIGATION_TREE_MAX_DEPTH', 10);
-
-// event details widgets
-define('WIDGET_HAT_TRIGGERDETAILS', 'hat_triggerdetails');
-define('WIDGET_HAT_EVENTDETAILS', 'hat_eventdetails');
-define('WIDGET_HAT_EVENTACTIONS', 'hat_eventactions');
-define('WIDGET_HAT_EVENTLIST', 'hat_eventlist');
-// search widget
-define('WIDGET_SEARCH_HOSTS', 'search_hosts');
-define('WIDGET_SEARCH_HOSTGROUP', 'search_hostgroup');
-define('WIDGET_SEARCH_TEMPLATES', 'search_templates');
-define('WIDGET_SEARCH_TEMPLATEGROUP', 'search_templategroup');
-
-// dashboard widget dynamic state
-define('WIDGET_SIMPLE_ITEM', 0);
-define('WIDGET_DYNAMIC_ITEM', 1);
-
-// clock widget blocks
-define('WIDGET_CLOCK_SHOW_DATE', 1);
-define('WIDGET_CLOCK_SHOW_TIME', 2);
-define('WIDGET_CLOCK_SHOW_TIMEZONE', 3);
-
-// item widget blocks
-define('WIDGET_ITEM_SHOW_DESCRIPTION', 1);
-define('WIDGET_ITEM_SHOW_VALUE', 2);
-define('WIDGET_ITEM_SHOW_TIME', 3);
-define('WIDGET_ITEM_SHOW_CHANGE_INDICATOR', 4);
+
+// Inaccessible widget type.
+define('ZBX_WIDGET_INACCESSIBLE', 'inaccessible');
+
+// event details sections
+define('SECTION_HAT_TRIGGERDETAILS', 'hat_triggerdetails');
+define('SECTION_HAT_EVENTDETAILS', 'hat_eventdetails');
+define('SECTION_HAT_EVENTACTIONS', 'hat_eventactions');
+define('SECTION_HAT_EVENTLIST', 'hat_eventlist');
+
+// search sections
+define('SECTION_SEARCH_HOSTS', 'search_hosts');
+define('SECTION_SEARCH_HOSTGROUP', 'search_hostgroup');
+define('SECTION_SEARCH_TEMPLATES', 'search_templates');
+define('SECTION_SEARCH_TEMPLATEGROUP', 'search_templategroup');
// widget defaults
define('ZBX_WIDGET_ROWS', 20);
@@ -1723,9 +1660,6 @@ define('ZBX_WIDGET_FIELD_RESOURCE_SIMPLE_GRAPH_PROTOTYPE', 3);
define('ZBX_WIDGET_VIEW_MODE_NORMAL', 0);
define('ZBX_WIDGET_VIEW_MODE_HIDDEN_HEADER', 1);
-// top hosts widget
-define('ZBX_WIDGET_TOP_HOSTS_DEFAULT_FILL', '#97AAB3');
-
// validation
define('DB_ID', "({}>=0&&bccomp({},\"9223372036854775807\")<=0)&&");
define('NOT_EMPTY', "({}!='')&&");
@@ -1921,7 +1855,6 @@ define('ZBX_STYLE_DASHBOARD_NEXT_PAGE', 'dashboard-next-page');
define('ZBX_STYLE_DASHBOARD_TOGGLE_SLIDESHOW', 'dashboard-toggle-slideshow');
define('ZBX_STYLE_DASHBOARD_WIDGET', 'dashboard-widget');
define('ZBX_STYLE_DASHBOARD_WIDGET_FORM', 'dashboard-widget-form');
-define('ZBX_STYLE_DASHBOARD_WIDGET_FLUID', 'dashboard-widget-fluid');
define('ZBX_STYLE_DASHBOARD_WIDGET_HEAD', 'dashboard-widget-head');
define('ZBX_STYLE_DASHBOARD_WIDGET_FOOT', 'dashboard-widget-foot');
define('ZBX_STYLE_DASHBOARD_EDIT', 'dashboard-edit');
@@ -2064,7 +1997,6 @@ define('ZBX_STYLE_OVERLAY_DESCR_URL', 'overlay-descr-url');
define('ZBX_STYLE_OVERFLOW_ELLIPSIS', 'overflow-ellipsis');
define('ZBX_STYLE_PAGING_BTN_CONTAINER', 'paging-btn-container');
define('ZBX_STYLE_PAGING_SELECTED', 'paging-selected');
-define('ZBX_STYLE_PAGE_TITLE', 'page-title-general');
define('ZBX_STYLE_PAGE_TITLE_SUBMENU', 'page-title-submenu');
define('ZBX_STYLE_RED', 'red');
define('ZBX_STYLE_RED_BG', 'red-bg');
diff --git a/ui/include/func.inc.php b/ui/include/func.inc.php
index d34d9b36b0a..55600959ffc 100644
--- a/ui/include/func.inc.php
+++ b/ui/include/func.inc.php
@@ -1625,7 +1625,7 @@ function access_deny($mode = ACCESS_DENY_OBJECT) {
show_error_message(_('No permissions to referred object or it does not exist!'));
require_once dirname(__FILE__).'/page_header.php';
- (new CWidget())->show();
+ (new CHtmlPage())->show();
require_once dirname(__FILE__).'/page_footer.php';
}
// deny access to a page
@@ -1806,8 +1806,20 @@ function makeMessageBox(string $class, array $messages, string $title = null, bo
function filter_messages(): array {
if (!CSettingsHelper::getGlobal(CSettingsHelper::SHOW_TECHNICAL_ERRORS)
&& CWebUser::getType() != USER_TYPE_SUPER_ADMIN && !CWebUser::getDebugMode()) {
+
+ $type = CMessageHelper::getType();
+ $title = CMessageHelper::getTitle();
$messages = CMessageHelper::getMessages();
- CMessageHelper::clear(false);
+ CMessageHelper::clear();
+
+ if ($title !== null) {
+ if ($type === CMessageHelper::MESSAGE_TYPE_SUCCESS) {
+ CMessageHelper::setSuccessTitle($title);
+ }
+ else {
+ CMessageHelper::setErrorTitle($title);
+ }
+ }
$generic_exists = false;
foreach ($messages as $message) {
diff --git a/ui/include/html.inc.php b/ui/include/html.inc.php
index 9c4b6e549bf..f808e6a092f 100644
--- a/ui/include/html.inc.php
+++ b/ui/include/html.inc.php
@@ -140,7 +140,7 @@ function BR() {
function get_icon($type, $params = []) {
switch ($type) {
- case 'favourite':
+ case 'favorite':
if (CFavorite::exists($params['fav'], $params['elid'], $params['elname'])) {
$icon = (new CRedirectButton(SPACE, null))
->addClass(ZBX_STYLE_BTN_REMOVE_FAV)
@@ -806,11 +806,11 @@ function makePageFooter($with_version = true) {
/**
* Get drop-down submenu item list for the User settings section.
*
- * @return array|null Menu definition for CWidget::setTitleSubmenu.
+ * @return array Menu definition for CHtmlPage::setTitleSubmenu.
*/
-function getUserSettingsSubmenu(): ?array {
+function getUserSettingsSubmenu(): array {
if (!CWebUser::checkAccess(CRoleHelper::ACTIONS_MANAGE_API_TOKENS)) {
- return null;
+ return [];
}
$profile_url = (new CUrl('zabbix.php'))
@@ -834,7 +834,7 @@ function getUserSettingsSubmenu(): ?array {
/**
* Get drop-down submenu item list for the Administration->General section.
*
- * @return array Menu definition for CWidget::setTitleSubmenu.
+ * @return array Menu definition for CHtmlPage::setTitleSubmenu.
*/
function getAdministrationGeneralSubmenu() {
$gui_url = (new CUrl('zabbix.php'))
diff --git a/ui/include/page_header.php b/ui/include/page_header.php
index 693c40e50f3..79c3fecef32 100644
--- a/ui/include/page_header.php
+++ b/ui/include/page_header.php
@@ -114,28 +114,27 @@ if ($page['type'] == PAGE_TYPE_HTML) {
global $ZBX_SERVER_NAME;
// page title
- $pageTitle = '';
+ $page_title = '';
if (isset($ZBX_SERVER_NAME) && $ZBX_SERVER_NAME !== '') {
- $pageTitle = $ZBX_SERVER_NAME.NAME_DELIMITER;
+ $page_title = $ZBX_SERVER_NAME.NAME_DELIMITER;
}
- $pageTitle .= isset($page['title']) ? $page['title'] : _('Zabbix');
+ $page_title .= isset($page['title']) ? $page['title'] : _('Zabbix');
if (defined('ZBX_PAGE_DO_JS_REFRESH') && CWebUser::getRefresh() != 0) {
- $pageTitle .= ' ['._s('refreshed every %1$s sec.', CWebUser::getRefresh()).']';
+ $page_title .= ' ['._s('refreshed every %1$s sec.', CWebUser::getRefresh()).']';
}
- $pageHeader = new CPageHeader($pageTitle, CWebUser::getLang());
+ $page_header = new CHtmlPageHeader($page_title, CWebUser::getLang());
$is_standard_page = (!defined('ZBX_PAGE_NO_MENU') || $page['web_layout_mode'] == ZBX_LAYOUT_KIOSKMODE);
- $theme = ZBX_DEFAULT_THEME;
if (!ZBX_PAGE_NO_THEME) {
global $DB;
if (!empty($DB['DB'])) {
- $theme = getUserTheme(CWebUser::$data);
-
- $pageHeader->addStyle(getTriggerSeverityCss());
- $pageHeader->addStyle(getTriggerStatusCss());
+ $page_header
+ ->setTheme(getUserTheme(CWebUser::$data))
+ ->addStyle(getTriggerSeverityCss())
+ ->addStyle(getTriggerStatusCss());
// perform Zabbix server check only for standard pages
if ($is_standard_page && CSettingsHelper::get(CSettingsHelper::SERVER_CHECK_INTERVAL)) {
@@ -143,39 +142,65 @@ if ($page['type'] == PAGE_TYPE_HTML) {
}
}
}
- $pageHeader->addCssFile('assets/styles/'.CHtml::encode($theme).'.css');
+
+ $page_header->addCssFile('assets/styles/'.$page_header->getTheme().'.css');
+
+ foreach (APP::ModuleManager()->getAssets() as $module_id => $assets) {
+ $module = APP::ModuleManager()->getModule($module_id);
+ $relative_path = $module->getRelativePath().'/assets/css';
+
+ foreach ($assets['css'] as $css_file) {
+ $page_header->addCssFile((new CUrl($relative_path.'/'.$css_file))->getUrl());
+ }
+ }
if ($page['file'] == 'sysmap.php') {
- $pageHeader->addCssFile('imgstore.php?css=1&output=css');
+ $page_header->addCssFile('imgstore.php?css=1&output=css');
}
- $pageHeader
- ->addJsFile((new CUrl('js/browsers.js'))->getUrl())
- ->addJsBeforeScripts(
- 'var PHP_TZ_OFFSET = '.date('Z').','.
- 'PHP_ZBX_FULL_DATE_TIME = "'.ZBX_FULL_DATE_TIME.'";'
- );
+ $page_header
+ ->addJavaScript('
+ const PHP_TZ_OFFSET = '.date('Z').';
+ const PHP_ZBX_FULL_DATE_TIME = "'.ZBX_FULL_DATE_TIME.'";
+ ')
+ ->addJsFile((new CUrl('js/browsers.js'))->getUrl());
// Show GUI messages in pages with menus and in fullscreen mode.
if (!defined('ZBX_PAGE_NO_JSLOADER')) {
- $pageHeader->addJsFile((new CUrl('jsLoader.php'))
- ->setArgument('ver', ZABBIX_VERSION)
- ->setArgument('lang', CWebUser::$data['lang'])
- ->setArgument('showGuiMessaging', ($is_standard_page && !CWebUser::isGuest()) ? 1 : null)
- ->getUrl()
- );
-
- if (array_key_exists('scripts', $page) && $page['scripts']) {
- $pageHeader->addJsFile((new CUrl('jsLoader.php'))
+ $page_header->addJsFile(
+ (new CUrl('jsLoader.php'))
->setArgument('ver', ZABBIX_VERSION)
->setArgument('lang', CWebUser::$data['lang'])
- ->setArgument('files', $page['scripts'])
+ ->setArgument('showGuiMessaging', ($is_standard_page && !CWebUser::isGuest()) ? 1 : null)
->getUrl()
+ );
+
+ if (array_key_exists('scripts', $page) && $page['scripts']) {
+ $page_header->addJsFile(
+ (new CUrl('jsLoader.php'))
+ ->setArgument('ver', ZABBIX_VERSION)
+ ->setArgument('lang', CWebUser::$data['lang'])
+ ->setArgument('files', $page['scripts'])
+ ->getUrl()
);
}
+
+ foreach (APP::ModuleManager()->getAssets() as $module_id => $assets) {
+ $module = APP::ModuleManager()->getModule($module_id);
+ $relative_path = $module->getRelativePath().'/assets/js';
+ $translation_strings = $module->getTranslationStrings();
+
+ foreach ($assets['js'] as $js_file) {
+ $page_header->addJsFile((new CUrl($relative_path.'/'.$js_file))->getUrl());
+
+ if (array_key_exists($js_file, $translation_strings)) {
+ $page_header->addJsTranslationStrings($translation_strings[$js_file]);
+ }
+ }
+ }
}
- $pageHeader->display();
+ $page_header->show();
echo '<body>';
}
diff --git a/ui/include/validate.inc.php b/ui/include/validate.inc.php
index af7fa11b066..f777d2aab02 100644
--- a/ui/include/validate.inc.php
+++ b/ui/include/validate.inc.php
@@ -378,7 +378,7 @@ function invalid_url($msg = null) {
unset_all();
show_error_message($msg);
- (new CWidget())->show();
+ (new CHtmlPage())->show();
require_once dirname(__FILE__).'/page_footer.php';
}
diff --git a/ui/include/views/administration.auditacts.list.php b/ui/include/views/administration.auditacts.list.php
index 241b33fa074..16527340b71 100644
--- a/ui/include/views/administration.auditacts.list.php
+++ b/ui/include/views/administration.auditacts.list.php
@@ -23,7 +23,7 @@
* @var CView $this
*/
-$auditWidget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Action log'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::ADMINISTRATION_AUDITACTS_LIST));
@@ -47,7 +47,7 @@ $filterColumn->addRow(new CLabel(_('Recipients'), 'filter_userids__ms'), [
]))->setWidth(ZBX_TEXTAREA_FILTER_STANDARD_WIDTH)
]);
-$auditWidget->addItem(
+$html_page->addItem(
(new CFilter())
->setResetUrl(new CUrl('auditacts.php'))
->setProfile($data['timeline']['profileIdx'])
@@ -141,7 +141,6 @@ $objData = [
zbx_add_post_js('timeControl.addObject("events", '.zbx_jsvalue($data['timeline']).', '.zbx_jsvalue($objData).');');
zbx_add_post_js('timeControl.processObjects();');
-// append form to widget
-$auditWidget->addItem($auditForm);
-
-$auditWidget->show();
+$html_page
+ ->addItem($auditForm)
+ ->show();
diff --git a/ui/include/views/configuration.action.edit.php b/ui/include/views/configuration.action.edit.php
index a4f3c51bcf0..25ebb5a2575 100644
--- a/ui/include/views/configuration.action.edit.php
+++ b/ui/include/views/configuration.action.edit.php
@@ -25,7 +25,7 @@
require_once dirname(__FILE__).'/js/configuration.action.edit.js.php';
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Actions'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::ALERTS_ACTION_EDIT));
@@ -37,7 +37,7 @@ $actionForm = (new CForm())
->setArgument('eventsource', $data['eventsource'])
->getUrl()
)
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE)
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID)
->addVar('form', $data['form']);
if ($data['actionid']) {
@@ -539,7 +539,6 @@ $action_tabs->setFooter([
]);
$actionForm->addItem($action_tabs);
-// Append form to widget.
-$widget->addItem($actionForm);
-
-$widget->show();
+$html_page
+ ->addItem($actionForm)
+ ->show();
diff --git a/ui/include/views/configuration.action.list.php b/ui/include/views/configuration.action.list.php
index cc0fd295d84..c7c229a04d6 100644
--- a/ui/include/views/configuration.action.list.php
+++ b/ui/include/views/configuration.action.list.php
@@ -59,7 +59,7 @@ foreach ($submenu_source as $value => $label) {
$current_url = (new CUrl('actionconf.php'))->setArgument('eventsource', $data['eventsource']);
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle($title)
->setTitleSubmenu(['main_section' => ['items' => $submenu]])
->setDocUrl(CDocHelper::getUrl(CDocHelper::ALERTS_ACTION_LIST))
@@ -180,7 +180,6 @@ $actionForm->addItem([
], $data['eventsource'])
]);
-// append form to widget
-$widget->addItem($actionForm);
-
-$widget->show();
+$html_page
+ ->addItem($actionForm)
+ ->show();
diff --git a/ui/include/views/configuration.copy.elements.php b/ui/include/views/configuration.copy.elements.php
index 82fd613109d..68110cac228 100644
--- a/ui/include/views/configuration.copy.elements.php
+++ b/ui/include/views/configuration.copy.elements.php
@@ -24,7 +24,7 @@
* @var array $data
*/
-$widget = (new CWidget())->setTitle($data['title']);
+$html_page = (new CHtmlPage())->setTitle($data['title']);
// append host summary to widget header
if ($data['hostid'] != 0) {
@@ -42,13 +42,13 @@ if ($data['hostid'] != 0) {
$host_table_element = '';
}
- $widget->setNavigation(getHostNavigation($host_table_element, $data['hostid']));
+ $html_page->setNavigation(getHostNavigation($host_table_element, $data['hostid']));
}
// create form
$form = (new CForm('post', (new CUrl())->getUrl()))
->setName('elements_form')
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE)
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID)
->addVar('action', $data['action'])
->addVar($data['elements_field'], $data['elements'])
->addVar('hostid', $data['hostid']);
@@ -81,11 +81,11 @@ $tab_view->setFooter(makeFormFooter(
));
$form->addItem($tab_view);
-$widget->addItem($form);
+$html_page->addItem($form);
require_once dirname(__FILE__).'/js/configuration.copy.elements.js.php';
-$widget->show();
+$html_page->show();
(new CScriptTag('
view.init('.json_encode([
diff --git a/ui/include/views/configuration.graph.edit.php b/ui/include/views/configuration.graph.edit.php
index c10c07c64d8..1d85b47b2d5 100644
--- a/ui/include/views/configuration.graph.edit.php
+++ b/ui/include/views/configuration.graph.edit.php
@@ -23,16 +23,16 @@
* @var CView $this
*/
-$widget = new CWidget();
+$html_page = new CHtmlPage();
if ($data['parent_discoveryid'] === null) {
- $widget
+ $html_page
->setTitle(_('Graphs'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::DATA_COLLECTION_GRAPH_EDIT))
->setNavigation(getHostNavigation('graphs', $data['hostid']));
}
else {
- $widget
+ $html_page
->setTitle(_('Graph prototypes'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::DATA_COLLECTION_PROTOTYPE_GRAPH_EDIT))
->setNavigation(getHostNavigation('graphs', $data['hostid'], $data['parent_discoveryid']));
@@ -46,7 +46,7 @@ $url = (new CUrl('graphs.php'))
// Create form.
$graphForm = (new CForm('post', $url))
->setName('graphForm')
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE)
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID)
->addVar('form', $data['form'])
->addVar('hostid', $data['hostid']);
@@ -533,10 +533,9 @@ require_once dirname(__FILE__).'/js/configuration.graph.edit.js.php';
$graphForm->addItem($graphTab);
-// Append form to widget.
-$widget->addItem($graphForm);
-
-$widget->show();
+$html_page
+ ->addItem($graphForm)
+ ->show();
(new CScriptTag('
view.init('.json_encode([
diff --git a/ui/include/views/configuration.graph.list.php b/ui/include/views/configuration.graph.list.php
index d999c4a345b..c30e18a1ded 100644
--- a/ui/include/views/configuration.graph.list.php
+++ b/ui/include/views/configuration.graph.list.php
@@ -26,7 +26,7 @@
$this->includeJsFile('configuration.graph.list.js.php');
if (!empty($this->data['parent_discoveryid'])) {
- $widget = (new CWidget())
+ $html_page = (new CHtmlPage())
->setTitle(_('Graph prototypes'))
->setDocUrl(CDocHelper::getUrl($data['context'] === 'host'
? CDocHelper::DATA_COLLECTION_HOST_GRAPH_PROTOTYPE_LIST
@@ -48,7 +48,7 @@ if (!empty($this->data['parent_discoveryid'])) {
->setNavigation(getHostNavigation('graphs', $this->data['hostid'], $this->data['parent_discoveryid']));
}
else {
- $widget = (new CWidget())
+ $html_page = (new CHtmlPage())
->setTitle(_('Graphs'))
->setDocUrl(CDocHelper::getUrl($data['context'] === 'host'
? CDocHelper::DATA_COLLECTION_HOST_GRAPH_LIST
@@ -75,13 +75,13 @@ else {
);
if (!empty($this->data['hostid'])) {
- $widget->setNavigation(getHostNavigation('graphs', $this->data['hostid']));
+ $html_page->setNavigation(getHostNavigation('graphs', $this->data['hostid']));
}
// Add filter tab.
$hg_ms_params = $data['context'] === 'host' ? ['with_hosts' => true] : ['with_templates' => true];
- $widget->addItem(
+ $html_page->addItem(
(new CFilter())
->setResetUrl((new CUrl('graphs.php'))->setArgument('context', $data['context']))
->setProfile($data['profileIdx'])
@@ -270,7 +270,6 @@ $graphForm->addItem([
)
]);
-// append form to widget
-$widget->addItem($graphForm);
-
-$widget->show();
+$html_page
+ ->addItem($graphForm)
+ ->show();
diff --git a/ui/include/views/configuration.host.discovery.edit.php b/ui/include/views/configuration.host.discovery.edit.php
index aa08f03049c..7d7fe2672b7 100644
--- a/ui/include/views/configuration.host.discovery.edit.php
+++ b/ui/include/views/configuration.host.discovery.edit.php
@@ -24,7 +24,7 @@
* @var array $data
*/
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Discovery rules'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::DATA_COLLECTION_HOST_DISCOVERY_EDIT))
->setNavigation(getHostNavigation('discoveries', $data['hostid'],
@@ -38,7 +38,7 @@ $url = (new CUrl('host_discovery.php'))
$form = (new CForm('post', $url))
->setId('host-discovery-form')
->setName('itemForm')
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE)
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID)
->addVar('form', $data['form'])
->addVar('hostid', $data['hostid'])
->addVar('backurl', $data['backurl']);
@@ -1021,11 +1021,11 @@ else {
$tab->setFooter(new CFormGrid($form_actions));
$form->addItem($tab);
-$widget->addItem($form);
+$html_page->addItem($form);
require_once __DIR__.'/js/configuration.host.discovery.edit.js.php';
-$widget->show();
+$html_page->show();
(new CScriptTag('
item_form.init('.json_encode([
diff --git a/ui/include/views/configuration.host.discovery.list.php b/ui/include/views/configuration.host.discovery.list.php
index c5a4f46d2d2..2dc1a73c8d5 100644
--- a/ui/include/views/configuration.host.discovery.list.php
+++ b/ui/include/views/configuration.host.discovery.list.php
@@ -25,7 +25,7 @@
require_once dirname(__FILE__).'/js/configuration.host.discovery.list.js.php';
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Discovery rules'))
->setDocUrl(CDocHelper::getUrl($data['context'] === 'host'
? CDocHelper::DATA_COLLECTION_HOST_DISCOVERY_LIST
@@ -52,7 +52,7 @@ $widget = (new CWidget())
);
if ($data['hostid'] != 0) {
- $widget->setNavigation(getHostNavigation('discoveries', $data['hostid']));
+ $html_page->setNavigation(getHostNavigation('discoveries', $data['hostid']));
}
// Add filter tab.
@@ -177,7 +177,7 @@ $filter_column3->addRow(_('Status'),
$filter->addFilterTab(_('Filter'), [$filter_column1, $filter_column2, $filter_column3]);
-$widget->addItem($filter);
+$html_page->addItem($filter);
$url = (new CUrl('host_discovery.php'))
->setArgument('context', $data['context'])
@@ -361,10 +361,9 @@ $discoveryForm->addItem([$discoveryTable, $data['paging'], new CActionButtonList
$button_list, $data['checkbox_hash']
)]);
-// Append form to widget.
-$widget->addItem($discoveryForm);
-
-$widget->show();
+$html_page
+ ->addItem($discoveryForm)
+ ->show();
(new CScriptTag('
view.init('.json_encode([
diff --git a/ui/include/views/configuration.host.prototype.edit.php b/ui/include/views/configuration.host.prototype.edit.php
index 2c5093777d0..d182b45711b 100644
--- a/ui/include/views/configuration.host.prototype.edit.php
+++ b/ui/include/views/configuration.host.prototype.edit.php
@@ -29,7 +29,7 @@ require_once __DIR__.'/js/common.template.edit.js.php';
$host_prototype = $data['host_prototype'];
$parent_host = $data['parent_host'];
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Host prototypes'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::DATA_COLLECTION_HOST_PROTOTYPE_EDIT))
->setNavigation(getHostNavigation('hosts', $data['discovery_rule']['hostid'], $data['discovery_rule']['itemid']));
@@ -48,7 +48,7 @@ $url = (new CUrl('host_prototypes.php'))
$form = (new CForm('post', $url))
->setId('host-prototype-form')
->setName('hostPrototypeForm')
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE)
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID)
->addVar('form', getRequest('form', 1))
->addVar('parent_discoveryid', $data['discovery_rule']['itemid'])
->addVar('tls_accept', $parent_host['tls_accept'])
@@ -449,6 +449,7 @@ else {
}
$form->addItem($tabs);
-$widget->addItem($form);
-$widget->show();
+$html_page
+ ->addItem($form)
+ ->show();
diff --git a/ui/include/views/configuration.host.prototype.list.php b/ui/include/views/configuration.host.prototype.list.php
index da4db4cdd5a..9db4adf4165 100644
--- a/ui/include/views/configuration.host.prototype.list.php
+++ b/ui/include/views/configuration.host.prototype.list.php
@@ -25,7 +25,7 @@
require_once dirname(__FILE__).'/js/configuration.host.prototype.list.js.php';
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Host prototypes'))
->setDocUrl(CDocHelper::getUrl($data['context'] === 'host'
? CDocHelper::DATA_COLLECTION_HOST_PROTOTYPE_LIST
@@ -206,7 +206,6 @@ $itemForm->addItem([
)
]);
-// append form to widget
-$widget->addItem($itemForm);
-
-$widget->show();
+$html_page
+ ->addItem($itemForm)
+ ->show();
diff --git a/ui/include/views/configuration.httpconf.edit.php b/ui/include/views/configuration.httpconf.edit.php
index 7da317aece8..33ca974d66c 100644
--- a/ui/include/views/configuration.httpconf.edit.php
+++ b/ui/include/views/configuration.httpconf.edit.php
@@ -23,13 +23,13 @@
* @var CView $this
*/
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Web monitoring'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::DATA_COLLECTION_HTTPCONF_EDIT));
// append host summary to widget header
if (!empty($this->data['hostid'])) {
- $widget->setNavigation(getHostNavigation('web', $this->data['hostid']));
+ $html_page->setNavigation(getHostNavigation('web', $this->data['hostid']));
}
$url = (new CUrl('httpconf.php'))
@@ -40,7 +40,7 @@ $url = (new CUrl('httpconf.php'))
$http_form = (new CForm('post', $url))
->setId('http-form')
->setName('httpForm')
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE)
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID)
->addVar('form', $this->data['form'])
->addVar('hostid', $this->data['hostid'])
->addVar('templated', $this->data['templated']);
@@ -281,7 +281,7 @@ else {
}
$http_form->addItem($http_tab);
-$widget->addItem($http_form);
+$html_page->addItem($http_form);
$this->data['scenario_tab_data'] = [
'agent_visibility' => [],
@@ -300,7 +300,7 @@ zbx_subarray_push($this->data['scenario_tab_data']['agent_visibility'], ZBX_AGEN
require_once dirname(__FILE__).'/js/configuration.httpconf.edit.js.php';
-$widget->show();
+$html_page->show();
(new CScriptTag('
view.init('.json_encode([
diff --git a/ui/include/views/configuration.httpconf.list.php b/ui/include/views/configuration.httpconf.list.php
index ba061589981..23c2538def5 100644
--- a/ui/include/views/configuration.httpconf.list.php
+++ b/ui/include/views/configuration.httpconf.list.php
@@ -88,7 +88,7 @@ $filter = (new CFilter())
->addvar('context', $data['context'])
->addFilterTab(_('Filter'), [$filter_column_left, $filter_column_right]);
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Web monitoring'))
->setDocUrl(CDocHelper::getUrl($data['context'] === 'host'
? CDocHelper::DATA_COLLECTION_HOST_HTTPCONF_LIST
@@ -115,10 +115,10 @@ $widget = (new CWidget())
);
if (!empty($this->data['hostid'])) {
- $widget->setNavigation(getHostNavigation('web', $this->data['hostid']));
+ $html_page->setNavigation(getHostNavigation('web', $this->data['hostid']));
}
-$widget->addItem($filter);
+$html_page->addItem($filter);
$url = (new CUrl('httpconf.php'))
->setArgument('context', $data['context'])
@@ -237,10 +237,9 @@ $httpForm->addItem([$httpTable, $data['paging'], new CActionButtonList('action',
$data['hostid']
)]);
-// Append form to widget.
-$widget->addItem($httpForm);
-
-$widget->show();
+$html_page
+ ->addItem($httpForm)
+ ->show();
(new CScriptTag('view.init();'))
->setOnDocumentReady()
diff --git a/ui/include/views/configuration.item.edit.php b/ui/include/views/configuration.item.edit.php
index aefee634f76..4e527061832 100644
--- a/ui/include/views/configuration.item.edit.php
+++ b/ui/include/views/configuration.item.edit.php
@@ -24,14 +24,14 @@
* @var array $data
*/
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Items'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::DATA_COLLECTION_ITEM_EDIT));
$host = $data['host'];
if (!empty($data['hostid'])) {
- $widget->setNavigation(getHostNavigation('items', $data['hostid']));
+ $html_page->setNavigation(getHostNavigation('items', $data['hostid']));
}
$url = (new CUrl('items.php'))
@@ -42,7 +42,7 @@ $url = (new CUrl('items.php'))
$form = (new CForm('post', $url))
->setId('item-form')
->setName('itemForm')
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE)
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID)
->addVar('form', $data['form'])
->addVar('hostid', $data['hostid']);
@@ -1103,11 +1103,11 @@ else {
}
$form->addItem($item_tabs);
-$widget->addItem($form);
+$html_page->addItem($form);
require_once __DIR__.'/js/configuration.item.edit.js.php';
-$widget->show();
+$html_page->show();
(new CScriptTag('
item_form.init('.json_encode([
diff --git a/ui/include/views/configuration.item.list.php b/ui/include/views/configuration.item.list.php
index c7c335c23ef..4eade5ab61c 100644
--- a/ui/include/views/configuration.item.list.php
+++ b/ui/include/views/configuration.item.list.php
@@ -25,7 +25,7 @@
require_once dirname(__FILE__).'/js/configuration.item.list.js.php';
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Items'))
->setDocUrl(CDocHelper::getUrl($data['context'] === 'host'
? CDocHelper::DATA_COLLECTION_HOST_ITEM_LIST
@@ -52,10 +52,10 @@ $widget = (new CWidget())
);
if ($data['hostid'] != 0) {
- $widget->setNavigation(getHostNavigation('items', $data['hostid']));
+ $html_page->setNavigation(getHostNavigation('items', $data['hostid']));
}
-$widget->addItem(new CPartial('configuration.filter.items', [
+$html_page->addItem(new CPartial('configuration.filter.items', [
'filter_data' => $data['filter_data'],
'subfilter' => $data['subfilter'],
'context' => $data['context']
@@ -343,10 +343,9 @@ $itemForm->addItem([$itemTable, $data['paging'], new CActionButtonList('action',
$data['checkbox_hash']
)]);
-// Append form to widget.
-$widget->addItem($itemForm);
-
-$widget->show();
+$html_page
+ ->addItem($itemForm)
+ ->show();
(new CScriptTag('
view.init('.json_encode([
diff --git a/ui/include/views/configuration.item.prototype.edit.php b/ui/include/views/configuration.item.prototype.edit.php
index 0f19cb6a33b..9ce17bf2fc2 100644
--- a/ui/include/views/configuration.item.prototype.edit.php
+++ b/ui/include/views/configuration.item.prototype.edit.php
@@ -24,12 +24,12 @@
* @var array $data
*/
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Item prototypes'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::DATA_COLLECTION_ITEM_PROTOTYPE_EDIT));
if (!empty($data['hostid'])) {
- $widget->setNavigation(getHostNavigation('items', $data['hostid'], $data['parent_discoveryid']));
+ $html_page->setNavigation(getHostNavigation('items', $data['hostid'], $data['parent_discoveryid']));
}
$url = (new CUrl('disc_prototypes.php'))
@@ -40,7 +40,7 @@ $url = (new CUrl('disc_prototypes.php'))
$form = (new CForm('post', $url))
->setId('item-prototype-form')
->setName('itemForm')
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE)
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID)
->addVar('form', $data['form'])
->addVar('parent_discoveryid', $data['parent_discoveryid']);
@@ -942,11 +942,11 @@ else {
}
$form->addItem($item_tabs);
-$widget->addItem($form);
+$html_page->addItem($form);
require_once __DIR__.'/js/configuration.item.prototype.edit.js.php';
-$widget->show();
+$html_page->show();
(new CScriptTag('
item_form.init('.json_encode([
diff --git a/ui/include/views/configuration.item.prototype.list.php b/ui/include/views/configuration.item.prototype.list.php
index d15cd8ef074..5de2fa06b49 100644
--- a/ui/include/views/configuration.item.prototype.list.php
+++ b/ui/include/views/configuration.item.prototype.list.php
@@ -25,7 +25,7 @@
require_once dirname(__FILE__).'/js/configuration.item.prototype.list.js.php';
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Item prototypes'))
->setDocUrl(CDocHelper::getUrl($data['context'] === 'host'
? CDocHelper::DATA_COLLECTION_HOST_ITEM_PROTOTYPE_LIST
@@ -226,7 +226,6 @@ $itemForm->addItem([
)
]);
-// append form to widget
-$widget->addItem($itemForm);
-
-$widget->show();
+$html_page
+ ->addItem($itemForm)
+ ->show();
diff --git a/ui/include/views/configuration.maintenance.edit.php b/ui/include/views/configuration.maintenance.edit.php
index 82fd38a3775..9184f0b60c6 100644
--- a/ui/include/views/configuration.maintenance.edit.php
+++ b/ui/include/views/configuration.maintenance.edit.php
@@ -25,14 +25,14 @@
require_once dirname(__FILE__).'/js/configuration.maintenance.edit.js.php';
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Maintenance periods'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::DATA_COLLECTION_MAINTENANCE_EDIT));
$maintenance_form = (new CForm())
->setId('maintenance-form')
->setName('maintenanceForm')
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE)
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID)
->addVar('form', $data['form']);
if (array_key_exists('maintenanceid', $data) && $data['maintenanceid']) {
@@ -281,6 +281,6 @@ else {
$maintenance_form->addItem($maintenance_tab);
-$widget->addItem($maintenance_form);
-
-$widget->show();
+$html_page
+ ->addItem($maintenance_form)
+ ->show();
diff --git a/ui/include/views/configuration.maintenance.list.php b/ui/include/views/configuration.maintenance.list.php
index 8a0fe745fe8..e096aa44b56 100644
--- a/ui/include/views/configuration.maintenance.list.php
+++ b/ui/include/views/configuration.maintenance.list.php
@@ -23,7 +23,7 @@
* @var CView $this
*/
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Maintenance periods'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::DATA_COLLECTION_MAINTENANCE_LIST))
->setControls(
@@ -129,7 +129,6 @@ $maintenanceForm->addItem([
])
]);
-// append form to widget
-$widget->addItem($maintenanceForm);
-
-$widget->show();
+$html_page
+ ->addItem($maintenanceForm)
+ ->show();
diff --git a/ui/include/views/configuration.template.edit.php b/ui/include/views/configuration.template.edit.php
index dc5239869c7..0a86265f25e 100644
--- a/ui/include/views/configuration.template.edit.php
+++ b/ui/include/views/configuration.template.edit.php
@@ -25,12 +25,12 @@
require_once __DIR__.'/js/common.template.edit.js.php';
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Templates'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::DATA_COLLECTION_TEMPLATES_EDIT));
if ($data['form'] !== 'clone' && $data['form'] !== 'full_clone') {
- $widget->setNavigation(getHostNavigation('', $data['templateid']));
+ $html_page->setNavigation(getHostNavigation('', $data['templateid']));
}
$tabs = new CTabView();
@@ -42,7 +42,7 @@ if (!hasRequest('form_refresh')) {
$form = (new CForm())
->setId('templates-form')
->setName('templatesForm')
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE)
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID)
->addVar('form', $data['form']);
if ($data['templateid'] != 0) {
@@ -236,6 +236,7 @@ else {
}
$form->addItem($tabs);
-$widget->addItem($form);
-$widget->show();
+$html_page
+ ->addItem($form)
+ ->show();
diff --git a/ui/include/views/configuration.template.list.php b/ui/include/views/configuration.template.list.php
index 4d7ead032c2..55839182cc0 100644
--- a/ui/include/views/configuration.template.list.php
+++ b/ui/include/views/configuration.template.list.php
@@ -83,7 +83,7 @@ $filter = (new CFilter())
(new CFormList())->addRow(_('Tags'), $filter_tags_table)
]);
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Templates'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::DATA_COLLECTION_TEMPLATES_LIST))
->setControls((new CTag('nav', true,
@@ -296,6 +296,6 @@ $form->addItem([
)
]);
-$widget->addItem($form);
-
-$widget->show();
+$html_page
+ ->addItem($form)
+ ->show();
diff --git a/ui/include/views/configuration.trigger.prototype.edit.php b/ui/include/views/configuration.trigger.prototype.edit.php
index 407e4f392d8..d77434b6065 100644
--- a/ui/include/views/configuration.trigger.prototype.edit.php
+++ b/ui/include/views/configuration.trigger.prototype.edit.php
@@ -25,7 +25,7 @@
require_once dirname(__FILE__).'/js/configuration.triggers.edit.js.php';
-$triggersWidget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Trigger prototypes'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::DATA_COLLECTION_TRIGGER_PROTOTYPE_EDIT))
->setNavigation(getHostNavigation('triggers', $data['hostid'], $data['parent_discoveryid']));
@@ -39,7 +39,7 @@ $url = (new CUrl('trigger_prototypes.php'))
$triggersForm = (new CForm('post', $url))
->setId('triggers-prototype-form')
->setName('triggersForm')
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE)
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID)
->addVar('form', $data['form'])
->addItem((new CVar('parent_discoveryid', $data['parent_discoveryid']))->removeId())
->addVar('expression_constructor', $data['expression_constructor'])
@@ -749,9 +749,9 @@ else {
// append tabs to form
$triggersForm->addItem($triggersTab);
-$triggersWidget->addItem($triggersForm);
-
-$triggersWidget->show();
+$html_page
+ ->addItem($triggersForm)
+ ->show();
(new CScriptTag('
view.init('.json_encode([
diff --git a/ui/include/views/configuration.trigger.prototype.list.php b/ui/include/views/configuration.trigger.prototype.list.php
index 82fef6e1bb5..ecc66d76ae2 100644
--- a/ui/include/views/configuration.trigger.prototype.list.php
+++ b/ui/include/views/configuration.trigger.prototype.list.php
@@ -25,7 +25,7 @@
require_once dirname(__FILE__).'/js/configuration.trigger.prototype.list.js.php';
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Trigger prototypes'))
->setDocUrl(CDocHelper::getUrl($data['context'] === 'host'
? CDocHelper::DATA_COLLECTION_HOST_TRIGGER_PROTOTYPE_LIST
@@ -226,7 +226,6 @@ $triggersForm->addItem([
)
]);
-// append form to widget
-$widget->addItem($triggersForm);
-
-$widget->show();
+$html_page
+ ->addItem($triggersForm)
+ ->show();
diff --git a/ui/include/views/configuration.triggers.edit.php b/ui/include/views/configuration.triggers.edit.php
index b2799572593..893d8c6bcf3 100644
--- a/ui/include/views/configuration.triggers.edit.php
+++ b/ui/include/views/configuration.triggers.edit.php
@@ -25,13 +25,13 @@
require_once dirname(__FILE__).'/js/configuration.triggers.edit.js.php';
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Triggers'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::DATA_COLLECTION_TRIGGERS_EDIT));
// Append host summary to widget header.
if ($data['hostid'] != 0) {
- $widget->setNavigation(getHostNavigation('triggers', $data['hostid']));
+ $html_page->setNavigation(getHostNavigation('triggers', $data['hostid']));
}
$url = (new CUrl('triggers.php'))
@@ -42,7 +42,7 @@ $url = (new CUrl('triggers.php'))
$triggersForm = (new CForm('post', $url))
->setid('triggers-form')
->setName('triggersForm')
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE)
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID)
->addVar('form', $data['form'])
->addVar('hostid', $data['hostid'])
->addVar('expression_constructor', $data['expression_constructor'])
@@ -730,9 +730,9 @@ else {
// Append tabs to form.
$triggersForm->addItem($triggersTab);
-$widget->addItem($triggersForm);
-
-$widget->show();
+$html_page
+ ->addItem($triggersForm)
+ ->show();
(new CScriptTag('
view.init('.json_encode([
diff --git a/ui/include/views/configuration.triggers.list.php b/ui/include/views/configuration.triggers.list.php
index 8cc3488ddfc..911f86b8dac 100644
--- a/ui/include/views/configuration.triggers.list.php
+++ b/ui/include/views/configuration.triggers.list.php
@@ -146,7 +146,7 @@ $filter = (new CFilter())
->addvar('context', $data['context'], 'filter_context')
->addFilterTab(_('Filter'), [$filter_column1, $filter_column2]);
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Triggers'))
->setDocUrl(CDocHelper::getUrl($data['context'] === 'host'
? CDocHelper::DATA_COLLECTION_HOST_TRIGGERS_LIST
@@ -173,10 +173,10 @@ $widget = (new CWidget())
);
if ($data['single_selected_hostid'] != 0) {
- $widget->setNavigation(getHostNavigation('triggers', $data['single_selected_hostid']));
+ $html_page->setNavigation(getHostNavigation('triggers', $data['single_selected_hostid']));
}
-$widget->addItem($filter);
+$html_page->addItem($filter);
$url = (new CUrl('triggers.php'))
->setArgument('context', $data['context'])
@@ -370,10 +370,9 @@ $triggers_form->addItem([
)
]);
-// append form to widget
-$widget->addItem($triggers_form);
-
-$widget->show();
+$html_page
+ ->addItem($triggers_form)
+ ->show();
(new CScriptTag('view.init();'))
->setOnDocumentReady()
diff --git a/ui/include/views/general.warning.php b/ui/include/views/general.warning.php
index b2f3f2ba3c9..90b3bd0bfba 100644
--- a/ui/include/views/general.warning.php
+++ b/ui/include/views/general.warning.php
@@ -21,11 +21,15 @@
/**
* @var CView $this
+ * @var array $data
*/
-$pageHeader = (new CPageHeader(_('Warning').' ['._s('refreshed every %1$s sec.', 30).']', CWebUser::getLang()))
- ->addCssFile('assets/styles/'.CHtml::encode($data['theme']).'.css')
- ->display();
+$page_header = (new CHtmlPageHeader(_('Warning').' ['._s('refreshed every %1$s sec.', 30).']', CWebUser::getLang()));
+
+$page_header
+ ->setTheme($data['theme'])
+ ->addCssFile('assets/styles/'.$page_header->getTheme().'.css')
+ ->show();
$buttons = array_key_exists('buttons', $data)
? $data['buttons']
diff --git a/ui/include/views/inventory.host.list.php b/ui/include/views/inventory.host.list.php
index 4809399d35b..9ddcfa202ba 100644
--- a/ui/include/views/inventory.host.list.php
+++ b/ui/include/views/inventory.host.list.php
@@ -23,7 +23,7 @@
* @var CView $this
*/
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Host inventory'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::INVENTORY_HOST_LIST));
@@ -37,7 +37,7 @@ foreach ($data['host_inventories'] as $inventoryField) {
}
// filter
-$widget->addItem(
+$html_page->addItem(
(new CFilter())
->setResetUrl(new CUrl('hostinventories.php'))
->setProfile($data['profileIdx'])
@@ -112,6 +112,6 @@ foreach ($this->data['hosts'] as $host) {
$table->addRow($row);
}
-$widget->addItem([$table, $this->data['paging']]);
-
-$widget->show();
+$html_page
+ ->addItem([$table, $this->data['paging']])
+ ->show();
diff --git a/ui/include/views/inventory.host.view.php b/ui/include/views/inventory.host.view.php
index 56052600dff..52c2b24132a 100644
--- a/ui/include/views/inventory.host.view.php
+++ b/ui/include/views/inventory.host.view.php
@@ -260,12 +260,13 @@ $hostInventoriesTab->setFooter(makeFormFooter(null, [new CButtonCancel()]));
$web_layout_mode = CViewHelper::loadLayoutMode();
-(new CWidget())
+(new CHtmlPage())
->setTitle(_('Host inventory'))
->setWebLayoutMode($web_layout_mode)
->setControls((new CList())->addItem(get_icon('kioskmode', ['mode' => $web_layout_mode])))
- ->addItem((new CForm())
- ->setAttribute('aria-labelledby', ZBX_STYLE_PAGE_TITLE)
- ->addItem($hostInventoriesTab)
+ ->addItem(
+ (new CForm())
+ ->setAttribute('aria-labelledby', CHtmlPage::PAGE_TITLE_ID)
+ ->addItem($hostInventoriesTab)
)
->show();
diff --git a/ui/include/views/monitoring.history.php b/ui/include/views/monitoring.history.php
index f20ef746389..23e3480b0a2 100644
--- a/ui/include/views/monitoring.history.php
+++ b/ui/include/views/monitoring.history.php
@@ -26,7 +26,7 @@ $this->includeJsFile('monitoring.history.js.php');
$web_layout_mode = CViewHelper::loadLayoutMode();
-$historyWidget = (new CWidget())->setWebLayoutMode($web_layout_mode);
+$html_page = (new CHtmlPage())->setWebLayoutMode($web_layout_mode);
$header = [
'left' => _n('%1$s item', '%1$s items', count($data['items'])),
@@ -52,12 +52,8 @@ if ($data['items']) {
}
if ((count($data['items']) == 1 || $same_host) && $data['itemids']) {
- $header['left'] = [
- $host_name,
- NAME_DELIMITER,
- count($data['items']) == 1 ? $item['name'] : $header['left']
- ];
- $header_row[] = implode('', $header['left']);
+ $header['left'] = $host_name.NAME_DELIMITER.(count($data['items']) == 1 ? $item['name'] : $header['left']);
+ $header_row[] = $header['left'];
}
else {
$header_row[] = $header['left'];
@@ -103,7 +99,7 @@ if ($data['action'] !== HISTORY_GRAPH && $data['action'] !== HISTORY_BATCH_GRAPH
}
if ($data['action'] == HISTORY_GRAPH && count($data['items']) == 1) {
- $action_list->addItem(get_icon('favourite', [
+ $action_list->addItem(get_icon('favorite', [
'fav' => 'web.favorite.graphids',
'elid' => $item['itemid'],
'elname' => 'itemid'
@@ -222,7 +218,7 @@ if ($data['itemids']) {
// append plaintext to widget
if ($data['plaintext']) {
foreach ($header_row as $text) {
- $historyWidget->addItem([new CSpan($text), BR()]);
+ $html_page->addItem([new CSpan($text), BR()]);
}
if ($data['itemids']) {
@@ -231,11 +227,11 @@ if ($data['plaintext']) {
foreach ($screen as $text) {
$pre->addItem([$text, BR()]);
}
- $historyWidget->addItem($pre);
+ $html_page->addItem($pre);
}
}
else {
- $historyWidget
+ $html_page
->setTitle($header['left'])
->setDocUrl(CDocHelper::getUrl(CDocHelper::MONITORING_HISTORY))
->setControls((new CTag('nav', true, $header['right']))->setAttribute('aria-label', _('Content controls')));
@@ -272,10 +268,10 @@ else {
if ($data['itemids']) {
if ($data['action'] !== HISTORY_LATEST) {
- $historyWidget->addItem($filter_form);
+ $html_page->addItem($filter_form);
}
- $historyWidget->addItem($screen->get());
+ $html_page->addItem($screen->get());
if ($data['action'] !== HISTORY_LATEST) {
CScreenBuilder::insertScreenStandardJs($screen->timeline);
@@ -283,10 +279,10 @@ else {
}
else {
if ($filter_tab) {
- $historyWidget->addItem($filter_form);
+ $html_page->addItem($filter_form);
}
- $historyWidget->addItem(
+ $html_page->addItem(
(new CTableInfo())
->setHeader([
(new CColHeader(_('Timestamp')))->addClass(ZBX_STYLE_CELL_WIDTH),
@@ -298,4 +294,4 @@ else {
}
}
-$historyWidget->show();
+$html_page->show();
diff --git a/ui/include/views/monitoring.sysmap.constructor.php b/ui/include/views/monitoring.sysmap.constructor.php
index cdc039c2f87..430eeb0b700 100644
--- a/ui/include/views/monitoring.sysmap.constructor.php
+++ b/ui/include/views/monitoring.sysmap.constructor.php
@@ -87,7 +87,7 @@ zbx_add_post_js('ZABBIX.apps.map.run("'.ZBX_STYLE_MAP_AREA.'", '.json_encode([
'defaultIconName' => $data['defaultIconName']
], JSON_FORCE_OBJECT).');');
-(new CWidget())
+(new CHtmlPage())
->setTitle(_('Network maps'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::MONITORING_SYSMAP_CONSTRUCTOR))
->setNavigation($menu)
diff --git a/ui/include/views/monitoring.sysmap.edit.php b/ui/include/views/monitoring.sysmap.edit.php
index 0d0883731c8..3ffc716d352 100644
--- a/ui/include/views/monitoring.sysmap.edit.php
+++ b/ui/include/views/monitoring.sysmap.edit.php
@@ -25,7 +25,7 @@
require_once dirname(__FILE__).'/js/monitoring.sysmap.edit.js.php';
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Network maps'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::MONITORING_SYSMAP_EDIT));
@@ -436,7 +436,6 @@ else {
$form->addItem($tabs);
-// Append form to widget.
-$widget->addItem($form);
-
-$widget->show();
+$html_page
+ ->addItem($form)
+ ->show();
diff --git a/ui/include/views/monitoring.sysmap.list.php b/ui/include/views/monitoring.sysmap.list.php
index 37c54a4d4e0..2401f0bd819 100644
--- a/ui/include/views/monitoring.sysmap.list.php
+++ b/ui/include/views/monitoring.sysmap.list.php
@@ -23,7 +23,7 @@
* @var CView $this
*/
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Maps'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::MONITORING_SYSMAP_LIST))
->setControls(
@@ -123,7 +123,6 @@ $sysmapForm->addItem([
])
]);
-// append form to widget
-$widget->addItem($sysmapForm);
-
-$widget->show();
+$html_page
+ ->addItem($sysmapForm)
+ ->show();
diff --git a/ui/include/views/reports.toptriggers.php b/ui/include/views/reports.toptriggers.php
index fc9ee507398..60e8e70dcff 100644
--- a/ui/include/views/reports.toptriggers.php
+++ b/ui/include/views/reports.toptriggers.php
@@ -115,7 +115,7 @@ $obj_data = [
zbx_add_post_js('timeControl.addObject("toptriggers", '.zbx_jsvalue($data['filter']).', '.zbx_jsvalue($obj_data).');');
zbx_add_post_js('timeControl.processObjects();');
-(new CWidget())
+(new CHtmlPage())
->setTitle(_('100 busiest triggers'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::REPORTS_TOPTRIGGERS))
->addItem($filterForm)
diff --git a/ui/js/class.dashboard.js b/ui/js/class.dashboard.js
index 2a5c3a09e4e..681b96062c7 100644
--- a/ui/js/class.dashboard.js
+++ b/ui/js/class.dashboard.js
@@ -33,6 +33,7 @@ const DASHBOARD_EVENT_BUSY = 'dashboard-busy';
const DASHBOARD_EVENT_IDLE = 'dashboard-idle';
const DASHBOARD_EVENT_EDIT = 'dashboard-edit';
const DASHBOARD_EVENT_APPLY_PROPERTIES = 'dashboard-apply-properties';
+const DASHBOARD_EVENT_CONFIGURATION_OUTDATED = 'dashboard-configuration-outdated';
class CDashboard extends CBaseComponent {
@@ -48,6 +49,8 @@ class CDashboard extends CBaseComponent {
widget_min_rows,
widget_max_rows,
widget_defaults,
+ widget_last_type = null,
+ configuration_hash = null,
is_editable,
is_edit_mode,
can_edit_dashboards,
@@ -85,7 +88,9 @@ class CDashboard extends CBaseComponent {
this._max_rows = max_rows;
this._widget_min_rows = widget_min_rows;
this._widget_max_rows = widget_max_rows;
- this._widget_defaults = widget_defaults;
+ this._widget_defaults = {...widget_defaults};
+ this._widget_last_type = widget_last_type;
+ this._configuration_hash = configuration_hash;
this._is_editable = is_editable;
this._is_edit_mode = is_edit_mode;
this._can_edit_dashboards = can_edit_dashboards;
@@ -132,6 +137,11 @@ class CDashboard extends CBaseComponent {
this._slideshow_switch_time = null;
this._slideshow_timeout_id = null;
+ this._configuration_check_period = 60000;
+ this._configuration_check_steady_period = 2000;
+ this._configuration_check_time = null;
+ this._configuration_check_timeout_id = null;
+
this._is_unsaved = false;
if (!this._is_kiosk_mode) {
@@ -173,8 +183,12 @@ class CDashboard extends CBaseComponent {
this._target.classList.add(ZBX_STYLE_DASHBOARD_IS_EDIT_MODE);
}
- if (!this._is_edit_mode && this._data.auto_start == 1 && this._dashboard_pages.size > 1) {
- this._startSlideshow();
+ if (!this._is_edit_mode) {
+ this._startConfigurationChecker();
+
+ if (this._data.auto_start == 1 && this._dashboard_pages.size > 1) {
+ this._startSlideshow();
+ }
}
}
@@ -197,6 +211,7 @@ class CDashboard extends CBaseComponent {
this._tabs.enableSorting();
}
+ this._stopConfigurationChecker();
this._stopSlideshow();
this._target.classList.add(ZBX_STYLE_DASHBOARD_IS_EDIT_MODE);
@@ -282,7 +297,7 @@ class CDashboard extends CBaseComponent {
}
this._slideshow_switch_time = Math.max(Date.now() + this._slideshow_steady_period,
- timeout_ms + this._slideshow_switch_time
+ this._slideshow_switch_time + timeout_ms
);
this._slideshow_timeout_id = setTimeout(() => this._switchSlideshow(),
@@ -310,6 +325,101 @@ class CDashboard extends CBaseComponent {
}
}
+ _startConfigurationChecker() {
+ if (this._configuration_check_timeout_id !== null) {
+ clearTimeout(this._configuration_check_timeout_id);
+ }
+
+ this._configuration_check_time = Date.now() + this._configuration_check_period;
+ this._configuration_check_timeout_id = setTimeout(() => this._checkConfiguration(),
+ this._configuration_check_period
+ );
+ }
+
+ _stopConfigurationChecker() {
+ if (this._configuration_check_timeout_id === null) {
+ return;
+ }
+
+ clearTimeout(this._configuration_check_timeout_id);
+
+ this._configuration_check_time = null;
+ this._configuration_check_timeout_id = null;
+ }
+
+ _checkConfiguration() {
+ this._configuration_check_timeout_id = null;
+
+ if (this._isUserInteracting()) {
+ this._configuration_check_time = Date.now() + this._configuration_check_steady_period;
+ this._configuration_check_timeout_id = setTimeout(() => this._checkConfiguration(),
+ this._configuration_check_steady_period
+ );
+
+ return;
+ }
+
+ const busy_condition = this._createBusyCondition();
+
+ Promise.resolve()
+ .then(() => this._promiseCheckConfiguration())
+ .catch((exception) => {
+ console.log('Could not check the dashboard configuration', exception);
+ })
+ .finally(() => {
+ this._configuration_check_time = Math.max(Date.now() + this._configuration_check_steady_period,
+ this._configuration_check_time + this._configuration_check_period
+ );
+
+ this._configuration_check_timeout_id = setTimeout(() => this._checkConfiguration(),
+ this._configuration_check_time - Date.now()
+ );
+
+ this._deleteBusyCondition(busy_condition);
+ });
+ }
+
+ _promiseCheckConfiguration() {
+ const curl = new Curl('zabbix.php');
+
+ curl.setArgument('action', 'dashboard.configuration.hash.get');
+
+ return fetch(curl.getUrl(), {
+ method: 'POST',
+ headers: {'Content-Type': 'application/json'},
+ body: JSON.stringify({
+ templateid: this._data.templateid ?? undefined,
+ dashboardid: this._data.dashboardid
+ })
+ })
+ .then((response) => response.json())
+ .then((response) => {
+ if ('error' in response) {
+ throw {error: response.error};
+ }
+
+ if (response.configuration_hash !== null && this._configuration_hash !== response.configuration_hash) {
+ this.fire(DASHBOARD_EVENT_CONFIGURATION_OUTDATED);
+ }
+ });
+ }
+
+ _keepSteadyConfigurationChecker() {
+ if (this._configuration_check_timeout_id === null) {
+ return;
+ }
+
+ if (this._configuration_check_time - Date.now() < this._configuration_check_steady_period) {
+ clearTimeout(this._configuration_check_timeout_id);
+
+ this._configuration_check_time = Date.now() + this._configuration_check_steady_period;
+
+ this._configuration_check_timeout_id = setTimeout(() => this._checkConfiguration(),
+ this._configuration_check_time - Date.now()
+ );
+ }
+ }
+
_announceWidgets() {
const dashboard_pages = Array.from(this._dashboard_pages.keys());
@@ -502,16 +612,26 @@ class CDashboard extends CBaseComponent {
}
pasteDashboardPage(new_dashboard_page_data) {
+ this._clearWarnings();
+
if (this._dashboard_pages.size >= this._max_dashboard_pages) {
this._warnDashboardExhausted();
return;
}
+ const widgets = [];
+
+ for (const widget of new_dashboard_page_data.widgets) {
+ if (widget.type in this._widget_defaults) {
+ widgets.push(widget);
+ }
+ }
+
const busy_condition = this._createBusyCondition();
return Promise.resolve()
- .then(() => this._promiseDashboardWidgetsSanitize(new_dashboard_page_data.widgets))
+ .then(() => this._promiseDashboardWidgetsSanitize(widgets))
.then((response) => {
if (this._dashboard_pages.size >= this._max_dashboard_pages) {
this._warnDashboardExhausted();
@@ -519,31 +639,42 @@ class CDashboard extends CBaseComponent {
return;
}
- const widgets = new_dashboard_page_data.widgets;
+ if (response.widgets.length < new_dashboard_page_data.widgets.length) {
+ this._warn(t('Inaccessible widgets were not pasted.'));
+ }
+
+ const sane_widgets = [];
for (let i = 0; i < response.widgets.length; i++) {
- widgets[i].fields = response.widgets[i].fields;
+ if (response.widgets[i] !== null) {
+ sane_widgets.push({
+ ...widgets[i],
+ fields: response.widgets[i].fields
+ });
+ }
}
const used_references = this._getUsedReferences();
const reference_substitution = new Map();
- for (const widget of widgets) {
- const reference_field = this._widget_defaults[widget.type].reference_field;
+ for (const widget of sane_widgets) {
+ const widget_class = eval(this._widget_defaults[widget.type].js_class);
- if (reference_field !== null) {
- const old_reference = widget.fields[reference_field];
+ if (widget_class.hasReferenceField()) {
+ const old_reference = widget.fields.reference;
const new_reference = this._createReference({used_references});
- widget.fields[reference_field] = new_reference;
+ widget.fields.reference = new_reference;
used_references.add(new_reference);
reference_substitution.set(old_reference, new_reference);
}
}
- for (const widget of widgets) {
- for (const reference_field of this._widget_defaults[widget.type].foreign_reference_fields) {
+ for (const widget of sane_widgets) {
+ const widget_class = eval(this._widget_defaults[widget.type].js_class);
+
+ for (const reference_field of widget_class.getForeignReferenceFields()) {
const old_reference = widget.fields[reference_field];
if (reference_substitution.has(old_reference)) {
@@ -556,7 +687,7 @@ class CDashboard extends CBaseComponent {
dashboard_pageid: null,
name: new_dashboard_page_data.name,
display_period: new_dashboard_page_data.display_period,
- widgets
+ widgets: sane_widgets
});
this._selectDashboardPage(dashboard_page, {is_async: true});
@@ -583,6 +714,14 @@ class CDashboard extends CBaseComponent {
}
pasteWidget(new_widget_data, {widget = null, new_widget_pos = null} = {}) {
+ this._clearWarnings();
+
+ if (!(new_widget_data.type in this._widget_defaults)) {
+ this._warn(t('Cannot paste inaccessible widget.'));
+
+ return;
+ }
+
const dashboard_page = this._selected_dashboard_page;
if (widget !== null) {
@@ -612,23 +751,21 @@ class CDashboard extends CBaseComponent {
dashboard_page.deleteWidget(widget, {is_batch_mode: true});
}
- const reference_field = this._widget_defaults[new_widget_data.type].reference_field;
+ const new_widget_class = eval(this._widget_defaults[new_widget_data.type].js_class);
- if (reference_field !== null) {
- new_widget_data.fields[reference_field] = this._createReference();
+ if (new_widget_class.hasReferenceField()) {
+ new_widget_data.fields.reference = this._createReference();
}
let references = [];
for (const widget of dashboard_page.getWidgets()) {
- const reference_field = this._widget_defaults[widget.getType()].reference_field;
-
- if (reference_field !== null) {
- references.push(widget.getFields()[reference_field]);
+ if (widget.constructor.hasReferenceField()) {
+ references.push(widget.getFields()['reference']);
}
}
- for (const reference_field of this._widget_defaults[new_widget_data.type].foreign_reference_fields) {
+ for (const reference_field of new_widget_class.getForeignReferenceFields()) {
if (reference_field in new_widget_data.fields
&& !references.includes(new_widget_data.fields[reference_field])) {
new_widget_data.fields[reference_field] = '';
@@ -654,6 +791,14 @@ class CDashboard extends CBaseComponent {
return;
}
+ if (response.widgets[0] === null) {
+ dashboard_page.deleteWidget(paste_placeholder_widget);
+
+ this._warn(t('Cannot paste inaccessible widget.'));
+
+ return;
+ }
+
dashboard_page.replaceWidget(paste_placeholder_widget, {
...new_widget_data,
fields: response.widgets[0].fields,
@@ -691,7 +836,7 @@ class CDashboard extends CBaseComponent {
for (const widget_data of widgets_data) {
request_widgets_data.push({
type: widget_data.type,
- fields: JSON.stringify(widget_data.fields)
+ fields: widget_data.fields
});
}
@@ -787,6 +932,8 @@ class CDashboard extends CBaseComponent {
if (!this._is_edit_mode) {
this._storeSelectedDashboardPage(dashboard_page);
+ this._keepSteadyConfigurationChecker();
+
if (this._isSlideshowRunning()) {
this._keepSteadySlideshow();
}
@@ -794,8 +941,12 @@ class CDashboard extends CBaseComponent {
this._promiseSelectDashboardPage(dashboard_page, {is_async})
.then(() => {
- if (this._isSlideshowRunning()) {
- this._startSlideshow();
+ if (!this._is_edit_mode) {
+ this._keepSteadyConfigurationChecker();
+
+ if (this._isSlideshowRunning()) {
+ this._startSlideshow();
+ }
}
});
}
@@ -1127,7 +1278,19 @@ class CDashboard extends CBaseComponent {
}
editWidgetProperties(properties = {}, {new_widget_pos = null} = {}) {
- const overlay = PopUp('dashboard.widget.edit', {
+ this._clearWarnings();
+
+ if (properties.type === undefined) {
+ properties.type = this._widget_last_type;
+
+ if (properties.type === null) {
+ this._warn(t('Cannot add widget: no widgets available.'));
+
+ return;
+ }
+ }
+
+ const overlay = PopUp(`widget.${properties.type}.edit`, {
templateid: this._data.templateid ?? undefined,
...properties
}, {
@@ -1184,6 +1347,18 @@ class CDashboard extends CBaseComponent {
}
}
+ document.getElementById('type').addEventListener('change', () => this.reloadWidgetProperties());
+
+ form.addEventListener('change', (e) => {
+ const do_trim = e.target.matches(
+ 'input[type="text"]:not([data-no-trim="1"]), textarea:not([data-no-trim="1"])'
+ );
+
+ if (do_trim) {
+ e.target.value = e.target.value.trim();
+ }
+ }, {capture: true});
+
try {
new TabIndicators();
}
@@ -1207,12 +1382,11 @@ class CDashboard extends CBaseComponent {
const properties = {
type: fields.type,
- prev_type: overlay.data.original_properties.type,
unique_id: overlay.data.original_properties.unique_id ?? undefined,
dashboard_page_unique_id: overlay.data.original_properties.dashboard_page_unique_id ?? undefined
};
- if (properties.type === properties.prev_type) {
+ if (properties.type === overlay.data.original_properties.type) {
properties.name = fields.name;
properties.view_mode = fields.show_header == 1
? ZBX_WIDGET_VIEW_MODE_NORMAL
@@ -1222,9 +1396,11 @@ class CDashboard extends CBaseComponent {
delete fields.name;
delete fields.show_header;
- properties.fields = JSON.stringify(fields);
+ properties.fields = fields;
}
+ overlay.$dialogue[0].dispatchEvent(new CustomEvent('overlay.reload'));
+
this.editWidgetProperties(properties, {new_widget_pos: this._new_widget_pos});
}
@@ -1256,18 +1432,24 @@ class CDashboard extends CBaseComponent {
return Promise.resolve()
.then(() => this._promiseDashboardWidgetCheck({templateid, type, name, view_mode, fields}))
- .then(() => this._promiseDashboardWidgetConfigure({templateid, type, view_mode, fields}))
- .then((configuration) => {
+ .then(() => {
overlayDialogueDestroy(overlay.dialogueid);
if (widget !== null && widget.getType() === type) {
- widget.updateProperties({name, view_mode, fields, configuration});
+ widget.updateProperties({name, view_mode, fields});
return;
}
- if (this._widget_defaults[type].reference_field !== null) {
- fields[this._widget_defaults[type].reference_field] = this._createReference();
+ if (type !== this._widget_last_type) {
+ this._widget_last_type = type;
+ updateUserProfile('web.dashboard.last_widget_type', type, [], PROFILE_TYPE_STR);
+ }
+
+ const widget_class = eval(this._widget_defaults[type].js_class);
+
+ if (widget_class.hasReferenceField()) {
+ fields.reference = this._createReference();
}
const widget_data = {
@@ -1275,7 +1457,6 @@ class CDashboard extends CBaseComponent {
name,
view_mode,
fields,
- configuration,
widgetid: null,
pos: widget === null ? this._new_widget_pos_reserved : widget.getPos(),
is_new: widget === null,
@@ -1332,45 +1513,25 @@ class CDashboard extends CBaseComponent {
});
}
- _promiseDashboardWidgetCheck({templateid, type, name, view_mode, fields}) {
- const fields_str = Object.keys(fields).length > 0 ? JSON.stringify(fields) : undefined;
-
- const curl = new Curl('zabbix.php');
-
- curl.setArgument('action', 'dashboard.widget.check');
-
- return fetch(curl.getUrl(), {
- method: 'POST',
- headers: {'Content-Type': 'application/json'},
- body: JSON.stringify({templateid, type, name, view_mode, fields: fields_str})
- })
- .then((response) => response.json())
- .then((response) => {
- if ('error' in response) {
- throw {error: response.error};
- }
- });
+ _isEditingWidgetProperties() {
+ return this._is_edit_widget_properties_cancel_subscribed;
}
- _promiseDashboardWidgetConfigure({templateid, type, view_mode, fields}) {
- const fields_str = Object.keys(fields).length > 0 ? JSON.stringify(fields) : undefined;
-
+ _promiseDashboardWidgetCheck({templateid, type, name, view_mode, fields}) {
const curl = new Curl('zabbix.php');
- curl.setArgument('action', 'dashboard.widget.configure');
+ curl.setArgument('action', 'dashboard.widget.check');
return fetch(curl.getUrl(), {
method: 'POST',
headers: {'Content-Type': 'application/json'},
- body: JSON.stringify({templateid, type, view_mode, fields: fields_str})
+ body: JSON.stringify({templateid, type, name, view_mode, fields})
})
.then((response) => response.json())
.then((response) => {
if ('error' in response) {
throw {error: response.error};
}
-
- return response.configuration;
});
}
@@ -1385,7 +1546,26 @@ class CDashboard extends CBaseComponent {
if (this._can_edit_dashboards) {
menu_actions.push({
label: t('Copy'),
- clickCallback: () => this._storeDashboardPageDataCopy(dashboard_page.getDataCopy())
+ clickCallback: () => {
+ this._clearWarnings();
+
+ const data_copy = dashboard_page.getDataCopy();
+ const data_copy_widgets = data_copy.widgets;
+
+ data_copy.widgets = [];
+
+ for (const widget of data_copy_widgets) {
+ if (widget.type in this._widget_defaults) {
+ data_copy.widgets.push(widget);
+ }
+ }
+
+ this._storeDashboardPageDataCopy(data_copy);
+
+ if (data_copy.widgets.length < data_copy_widgets.length) {
+ this._warn(t('Inaccessible widgets were not copied.'));
+ }
+ }
});
}
@@ -1430,25 +1610,23 @@ class CDashboard extends CBaseComponent {
// Dashboard view methods.
- _warnDashboardExhausted() {
+ _warn(warning) {
this._clearWarnings();
- this._warning_message_box = makeMessageBox('warning', [], sprintf(
+ this._warning_message_box = makeMessageBox('warning', [], warning);
+
+ addMessage(this._warning_message_box);
+ }
+
+ _warnDashboardExhausted() {
+ this._warn(sprintf(
t('Cannot add dashboard page: maximum number of %1$d dashboard pages has been added.'),
this._max_dashboard_pages
));
-
- addMessage(this._warning_message_box);
}
_warnDashboardPageExhausted() {
- this._clearWarnings();
-
- this._warning_message_box = makeMessageBox('warning', [],
- t('Cannot add widget: not enough free space on the dashboard.')
- );
-
- addMessage(this._warning_message_box);
+ this._warn(t('Cannot add widget: not enough free space on the dashboard.'));
}
_clearWarnings() {
@@ -1676,14 +1854,13 @@ class CDashboard extends CBaseComponent {
for (const dashboard_page of this._dashboard_pages.keys()) {
for (const widget of dashboard_page.getWidgets()) {
- const type = widget.getType();
const fields = widget.getFields();
- if (this._widget_defaults[type].reference_field !== null) {
- used_references.add(fields[this._widget_defaults[type].reference_field]);
+ if (widget.constructor.hasReferenceField()) {
+ used_references.add(fields.reference);
}
- for (const reference_field of this._widget_defaults[type].foreign_reference_fields) {
+ for (const reference_field of widget.constructor.getForeignReferenceFields()) {
used_references.add(fields[reference_field]);
}
}
@@ -1704,31 +1881,23 @@ class CDashboard extends CBaseComponent {
},
dashboardPageWidgetAdd: (e) => {
+ const dashboard_page = this._selected_dashboard_page;
+
const new_widget_data = this.getStoredWidgetDataCopy();
const new_widget_pos = e.detail.new_widget_pos;
if (new_widget_data !== null) {
- const dashboard_page = this._selected_dashboard_page;
-
- let menu_was_cancelled = true;
-
const menu = [
{
label: t('Actions'),
items: [
{
label: t('Add widget'),
- clickCallback: () => {
- this.editWidgetProperties({}, {new_widget_pos});
- menu_was_cancelled = false;
- }
+ clickCallback: () => this.editWidgetProperties({}, {new_widget_pos})
},
{
label: t('Paste widget'),
- clickCallback: () => {
- this.pasteWidget(new_widget_data, {new_widget_pos});
- menu_was_cancelled = false;
- }
+ clickCallback: () => this.pasteWidget(new_widget_data, {new_widget_pos})
}
]
}
@@ -1741,7 +1910,7 @@ class CDashboard extends CBaseComponent {
jQuery(placeholder).menuPopup(menu, placeholder_event, {
closeCallback: () => {
- if (menu_was_cancelled) {
+ if (!this._isEditingWidgetProperties()) {
dashboard_page.resetWidgetPlaceholder();
}
}
@@ -1749,6 +1918,10 @@ class CDashboard extends CBaseComponent {
}
else {
this.editWidgetProperties({}, {new_widget_pos});
+
+ if (!this._isEditingWidgetProperties()) {
+ dashboard_page.resetWidgetPlaceholder();
+ }
}
},
@@ -1780,7 +1953,7 @@ class CDashboard extends CBaseComponent {
type: widget.getType(),
name: widget.getName(),
view_mode: widget.getViewMode(),
- fields: JSON.stringify(widget.getFields()),
+ fields: widget.getFields(),
unique_id: widget.getUniqueId(),
dashboard_page_unique_id: dashboard_page.getUniqueId()
});
@@ -1907,6 +2080,8 @@ class CDashboard extends CBaseComponent {
}
if (!this._is_edit_mode) {
+ this._keepSteadyConfigurationChecker();
+
if (this._isSlideshowRunning()) {
this._keepSteadySlideshow();
}
diff --git a/ui/js/class.dashboard.page.js b/ui/js/class.dashboard.page.js
index bacb46c58ca..33a87f18a68 100644
--- a/ui/js/class.dashboard.page.js
+++ b/ui/js/class.dashboard.page.js
@@ -323,19 +323,26 @@ class CDashboardPage extends CBaseComponent {
return null;
}
- addWidget({type, name, view_mode, fields, configuration, widgetid, pos, is_new, rf_rate, unique_id}) {
- const widget = this._createWidget(this._widget_defaults[type].js_class, {
- type,
- name,
- view_mode,
- fields,
- configuration,
- widgetid,
- pos,
- is_new,
- rf_rate,
- unique_id
- });
+ addWidget({type, name, view_mode, fields, widgetid, pos, is_new, rf_rate, unique_id}) {
+ let widget;
+
+ if (type in this._widget_defaults) {
+ widget = this._createWidget(eval(this._widget_defaults[type].js_class), {
+ type,
+ name,
+ view_mode,
+ fields,
+ defaults: this._widget_defaults[type],
+ widgetid,
+ pos,
+ is_new,
+ rf_rate,
+ unique_id
+ });
+ }
+ else {
+ widget = this._createInaccessibleWidget({name, widgetid, pos, unique_id});
+ }
this._doAddWidget(widget);
@@ -406,14 +413,13 @@ class CDashboardPage extends CBaseComponent {
return this.addWidget(widget_data);
}
- _createWidget(js_class, {type, name, view_mode, fields, configuration, widgetid, pos, is_new, rf_rate, unique_id}) {
- return new (eval(js_class))({
+ _createWidget(widget_class, {type, name, view_mode, fields, defaults, widgetid, pos, is_new, rf_rate, unique_id}) {
+ return new widget_class({
type,
name,
view_mode,
fields,
- configuration,
- defaults: this._widget_defaults[type],
+ defaults,
widgetid,
pos,
is_new,
@@ -433,18 +439,34 @@ class CDashboardPage extends CBaseComponent {
can_edit_dashboards: this._can_edit_dashboards,
time_period: this._time_period,
dynamic_hostid: this._dynamic_hostid,
- scope_id: this._unique_id,
+ unique_id
+ });
+ }
+
+ _createInaccessibleWidget({name, widgetid, pos, unique_id}) {
+ return this._createWidget(CWidgetInaccessible, {
+ type: 'inaccessible',
+ name,
+ view_mode: ZBX_WIDGET_VIEW_MODE_HIDDEN_HEADER,
+ fields: {},
+ defaults: {
+ name: t('Inaccessible widget')
+ },
+ widgetid,
+ pos,
+ is_new: false,
+ rf_rate: 0,
unique_id
});
}
_createPastePlaceholderWidget({type, name, view_mode, pos, unique_id}) {
- return this._createWidget('CWidgetPastePlaceholder', {
- type,
+ return this._createWidget(CWidgetPastePlaceholder, {
+ type: 'paste-placeholder',
name,
view_mode,
fields: {},
- configuration: {},
+ defaults: this._widget_defaults[type],
widgetid: null,
pos,
is_new: false,
diff --git a/ui/js/class.sortable.js b/ui/js/class.sortable.js
index 6b8211c3085..e07755058b1 100644
--- a/ui/js/class.sortable.js
+++ b/ui/js/class.sortable.js
@@ -258,6 +258,8 @@ class CSortable extends CBaseComponent {
item.style.left = `${item_rect.x - list_rect.x}px`;
item.style.top = `${item_rect.y - list_rect.y}px`;
+ item.style.width = `${item_rect.width}px`;
+ item.style.height = `${item_rect.height}px`;
}
this._target.classList.add(ZBX_STYLE_SORTABLE_DRAGGING);
@@ -268,6 +270,9 @@ class CSortable extends CBaseComponent {
this._drag_item = drag_item;
this._drag_item.style.left = `${drag_item_rect.x - target_rect.x}px`;
this._drag_item.style.top = `${drag_item_rect.y - target_rect.y}px`;
+ this._drag_item.style.width = `${drag_item_rect.width}px`;
+ this._drag_item.style.height = `${drag_item_rect.height}px`;
+
this._target.appendChild(this._drag_item);
// Hide the actual dragging item.
@@ -355,6 +360,8 @@ class CSortable extends CBaseComponent {
drag_item.classList.remove(ZBX_STYLE_SORTABLE_DRAGGING);
drag_item.style.left = '';
drag_item.style.top = '';
+ drag_item.style.width = '';
+ drag_item.style.height = '';
this._target.classList.remove(ZBX_STYLE_SORTABLE_DRAGGING);
this._list.style.width = '';
@@ -363,6 +370,8 @@ class CSortable extends CBaseComponent {
for (const item of items) {
item.style.left = '';
item.style.top = '';
+ item.style.width = '';
+ item.style.height = '';
}
// Re-focus the dragged item.
diff --git a/ui/js/class.tabfilter.js b/ui/js/class.tabfilter.js
index a0faf3c281a..4ee58041b90 100644
--- a/ui/js/class.tabfilter.js
+++ b/ui/js/class.tabfilter.js
@@ -56,7 +56,7 @@ class CTabFilter extends CBaseComponent {
options.data[options.selected].expanded = true;
}
- for (const template of this._target.querySelectorAll('[type="text/x-jquery-tmpl"][data-template]')) {
+ for (const template of this._target.querySelectorAll('[data-template]')) {
this._templates[template.getAttribute('data-template')] = template;
}
diff --git a/ui/js/class.widget.inaccessible.js b/ui/js/class.widget.inaccessible.js
new file mode 100644
index 00000000000..411b19bba4e
--- /dev/null
+++ b/ui/js/class.widget.inaccessible.js
@@ -0,0 +1,74 @@
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+class CWidgetInaccessible extends CWidget {
+
+ _doStart() {
+ super._doStart();
+
+ this._updateButtons();
+
+ this._content_body.innerHTML = `<div>${t('No permissions to referred object or it does not exist!')}</div>`;
+ }
+
+ _updateButtons() {
+ for (const button of this._content_header.querySelectorAll('button')) {
+ button.hidden = !button.classList.contains('js-widget-action') || !this.isEditMode();
+ }
+ }
+
+ setEditMode() {
+ super.setEditMode();
+
+ this._updateButtons();
+ }
+
+ _promiseUpdate() {
+ return Promise.resolve();
+ }
+
+ getActionsContextMenu({can_paste_widget}) {
+ const menu = super.getActionsContextMenu({can_paste_widget});
+
+ for (const section of menu) {
+ switch (section.label) {
+ case t('Actions'):
+ for (const item of section.items) {
+ if (item.label === t('Copy')) {
+ item.disabled = true;
+ }
+ }
+ break;
+
+ case t('Refresh interval'):
+ for (const item of section.items) {
+ item.disabled = true;
+ }
+ break;
+ }
+ }
+
+ return menu;
+ }
+
+ _hasPadding() {
+ return true;
+ }
+}
diff --git a/ui/js/widgets/class.widget.iterator.js b/ui/js/class.widget.iterator.js
index 12080a2e6fb..d1c8db7131b 100644
--- a/ui/js/widgets/class.widget.iterator.js
+++ b/ui/js/class.widget.iterator.js
@@ -318,7 +318,6 @@ class CWidgetIterator extends CWidget {
name: data.name,
view_mode: this._view_mode,
fields: data.fields,
- configuration: data.configuration,
defaults: data.defaults,
widgetid: data.widgetid,
is_new: false,
diff --git a/ui/js/widgets/class.widget.js b/ui/js/class.widget.js
index 2b5456d2f41..2584a6c23cc 100644
--- a/ui/js/widgets/class.widget.js
+++ b/ui/js/class.widget.js
@@ -38,12 +38,19 @@ const WIDGET_EVENT_DELETE = 'widget-delete';
class CWidget extends CBaseComponent {
+ static hasReferenceField() {
+ return false;
+ }
+
+ static getForeignReferenceFields() {
+ return [];
+ }
+
constructor({
type,
name,
view_mode,
fields,
- configuration,
defaults,
widgetid = null,
pos = null,
@@ -59,7 +66,6 @@ class CWidget extends CBaseComponent {
can_edit_dashboards,
time_period,
dynamic_hostid,
- scope_id,
unique_id
}) {
super(document.createElement('div'));
@@ -68,7 +74,6 @@ class CWidget extends CBaseComponent {
this._name = name;
this._view_mode = view_mode;
this._fields = fields;
- this._configuration = configuration;
this._defaults = defaults;
this._widgetid = widgetid;
this._pos = pos;
@@ -92,7 +97,6 @@ class CWidget extends CBaseComponent {
this._can_edit_dashboards = can_edit_dashboards;
this._time_period = time_period;
this._dynamic_hostid = dynamic_hostid;
- this._scope_id = scope_id;
this._unique_id = unique_id;
this._init();
@@ -342,15 +346,17 @@ class CWidget extends CBaseComponent {
this._fields = fields;
}
- _setConfiguration(configuration) {
- this._configuration = configuration;
+ _hasPadding() {
+ return this._view_mode != ZBX_WIDGET_VIEW_MODE_HIDDEN_HEADER;
+ }
+ _updatePadding() {
if (this._state !== WIDGET_STATE_INITIAL) {
- this._content_body.classList.toggle('no-padding', !this._configuration.padding);
+ this._content_body.classList.toggle('no-padding', !this._hasPadding());
}
}
- updateProperties({name, view_mode, fields, configuration}) {
+ updateProperties({name, view_mode, fields}) {
if (name !== undefined) {
this._setName(name);
}
@@ -363,9 +369,7 @@ class CWidget extends CBaseComponent {
this._setFields(fields);
}
- if (configuration !== undefined) {
- this._setConfiguration(configuration);
- }
+ this._updatePadding();
this._show_preloader_asap = true;
@@ -409,7 +413,6 @@ class CWidget extends CBaseComponent {
name: this._name,
view_mode: this._view_mode,
fields: this._fields,
- configuration: this._configuration,
pos: is_single_copy
? {
width: this._pos.width,
@@ -435,7 +438,7 @@ class CWidget extends CBaseComponent {
type: this._type,
name: this._name,
view_mode: this._view_mode,
- fields: Object.keys(this._fields).length > 0 ? JSON.stringify(this._fields) : undefined
+ fields: Object.keys(this._fields).length > 0 ? this._fields : undefined
};
}
@@ -630,7 +633,7 @@ class CWidget extends CBaseComponent {
dashboardid: this._dashboard.dashboardid ?? undefined,
widgetid: this._widgetid ?? undefined,
name: this._name !== '' ? this._name : undefined,
- fields: Object.keys(this._fields).length > 0 ? JSON.stringify(this._fields) : undefined,
+ fields: Object.keys(this._fields).length > 0 ? this._fields : undefined,
view_mode: this._view_mode,
edit_mode: this._is_edit_mode ? 1 : 0,
dynamic_hostid: this._dashboard.templateid !== null || this.supportsDynamicHosts()
@@ -872,7 +875,7 @@ class CWidget extends CBaseComponent {
this._button_edit = document.createElement('button');
this._button_edit.type = 'button';
this._button_edit.title = t('Edit')
- this._button_edit.classList.add('btn-widget-edit');
+ this._button_edit.classList.add('btn-widget-edit', 'js-widget-edit');
const li = document.createElement('li');
@@ -885,7 +888,7 @@ class CWidget extends CBaseComponent {
this._button_actions.title = t('Actions');
this._button_actions.setAttribute('aria-expanded', 'false');
this._button_actions.setAttribute('aria-haspopup', 'true');
- this._button_actions.classList.add('btn-widget-action');
+ this._button_actions.classList.add('btn-widget-action', 'js-widget-action');
const li = document.createElement('li');
@@ -898,7 +901,8 @@ class CWidget extends CBaseComponent {
this._content_body = document.createElement('div');
this._content_body.classList.add(this._css_classes.content);
- this._content_body.classList.toggle('no-padding', !this._configuration.padding);
+ this._content_body.classList.add(`dashboard-widget-${this._type}`);
+ this._content_body.classList.toggle('no-padding', !this._hasPadding());
this._container.appendChild(this._content_body);
diff --git a/ui/js/widgets/class.widget.paste-placeholder.js b/ui/js/class.widget.paste-placeholder.js
index 88db8992684..88db8992684 100644
--- a/ui/js/widgets/class.widget.paste-placeholder.js
+++ b/ui/js/class.widget.paste-placeholder.js
diff --git a/ui/js/common.js b/ui/js/common.js
index cd696caa9e4..bad37ea49a6 100644
--- a/ui/js/common.js
+++ b/ui/js/common.js
@@ -361,7 +361,16 @@ function PopUp(action, parameters, {
.then(function(resp) {
if ('error' in resp) {
overlay.setProperties({
- content: makeMessageBox('bad', resp.error.messages, resp.error.title, false)
+ title: resp.header !== undefined ? resp.header : '',
+ content: makeMessageBox('bad', resp.error.messages, resp.error.title, false),
+ buttons: [
+ {
+ 'title': t('Cancel'),
+ 'class': 'btn-alt js-cancel',
+ 'cancel': true,
+ 'action': function() {}
+ }
+ ]
});
}
else {
@@ -401,6 +410,26 @@ function PopUp(action, parameters, {
overlay.recoverFocus();
overlay.containFocus();
+ })
+ .fail((resp) => {
+ const error = resp.responseJSON !== undefined && resp.responseJSON.error !== undefined
+ ? resp.responseJSON.error
+ : {title: t('Unexpected server error.')};
+
+ overlay.setProperties({
+ content: makeMessageBox('bad', error.messages, error.title, false),
+ buttons: [
+ {
+ 'title': t('Cancel'),
+ 'class': 'btn-alt js-cancel',
+ 'cancel': true,
+ 'action': function() {}
+ }
+ ]
+ });
+
+ overlay.recoverFocus();
+ overlay.containFocus();
});
addToOverlaysStack(overlay);
@@ -522,15 +551,18 @@ function closeDialogHandler(event) {
* @return {object|undefined|null} Overlay object, if found.
*/
function removeFromOverlaysStack(dialogueid, return_focus) {
- var overlay = null;
-
if (return_focus !== false) {
return_focus = true;
}
- overlay = overlays_stack.removeById(dialogueid);
+ const overlay = overlays_stack.removeById(dialogueid);
+
if (overlay && return_focus) {
- jQuery(overlay.element).focus();
+ if (overlay.element !== undefined) {
+ const element = overlay.element instanceof jQuery ? overlay.element[0] : overlay.element;
+
+ element.focus({preventScroll: true});
+ }
}
// Remove event listener.
diff --git a/ui/js/main.js b/ui/js/main.js
index 44ca0377e77..ec143333d4b 100644
--- a/ui/js/main.js
+++ b/ui/js/main.js
@@ -655,10 +655,10 @@ var hintBox = {
};
/**
- * Add object to the list of favourites.
+ * Add object to the list of favorites.
*/
function add2favorites(object, objectid) {
- sendAjaxData('zabbix.php?action=favourite.create', {
+ sendAjaxData('zabbix.php?action=favorite.create', {
data: {
object: object,
objectid: objectid
@@ -667,10 +667,10 @@ function add2favorites(object, objectid) {
}
/**
- * Remove object from the list of favourites. Remove all favourites if objectid==0.
+ * Remove object from the list of favorites. Remove all favorites if objectid==0.
*/
function rm4favorites(object, objectid) {
- sendAjaxData('zabbix.php?action=favourite.delete', {
+ sendAjaxData('zabbix.php?action=favorite.delete', {
data: {
object: object,
objectid: objectid
@@ -684,7 +684,7 @@ function rm4favorites(object, objectid) {
* @param {string} idx User profile index
* @param {string} value Value
* @param {object} idx2 An array of IDs
- * @param {integer} profile_type Profile type
+ * @param {int} profile_type Profile type
*/
function updateUserProfile(idx, value, idx2, profile_type = PROFILE_TYPE_INT) {
const value_fields = {
@@ -701,25 +701,23 @@ function updateUserProfile(idx, value, idx2, profile_type = PROFILE_TYPE_INT) {
});
}
-function changeWidgetState(obj, widgetId, idx) {
- var widgetObj = jQuery('#' + widgetId + '_widget'),
- css = switchElementClass(obj, 'btn-widget-collapse', 'btn-widget-expand'),
- state = 0;
+/**
+ * Section collapse toggle.
+ *
+ * @param {string} id
+ * @param {string|null} profile_idx If not null, stores state in profile.
+ */
+function toggleSection(id, profile_idx) {
+ const section = document.getElementById(id);
+ const toggle = section.querySelector('.section-toggle');
- if (css === 'btn-widget-expand') {
- jQuery('.body', widgetObj).slideUp(50);
- jQuery('.dashboard-widget-foot', widgetObj).slideUp(50);
- }
- else {
- jQuery('.body', widgetObj).slideDown(50);
- jQuery('.dashboard-widget-foot', widgetObj).slideDown(50);
+ let is_collapsed = section.classList.contains('section-collapsed');
- state = 1;
- }
+ section.classList.toggle('section-collapsed', !is_collapsed);
+ toggle.setAttribute('title', is_collapsed ? t('S_COLLAPSE') : t('S_EXPAND'));
- obj.title = (state == 1) ? t('S_COLLAPSE') : t('S_EXPAND');
- if (idx !== '' && typeof idx !== 'undefined') {
- updateUserProfile(idx, state, []);
+ if (profile_idx !== '') {
+ updateUserProfile(profile_idx, is_collapsed ? '1' : '0', []);
}
}
diff --git a/ui/js/menupopup.js b/ui/js/menupopup.js
index 6fd90b81f9a..50da50c3b7e 100644
--- a/ui/js/menupopup.js
+++ b/ui/js/menupopup.js
@@ -611,7 +611,8 @@ function getMenuPopupDashboard(options, trigger_element) {
const url_clone = new Curl('zabbix.php', false);
url_clone.setArgument('action', 'dashboard.view');
- url_clone.setArgument('source_dashboardid', options.dashboardid);
+ url_clone.setArgument('dashboardid', options.dashboardid);
+ url_clone.setArgument('clone', '1');
const url_delete = new Curl('zabbix.php', false);
url_delete.setArgument('action', 'dashboard.delete');
diff --git a/ui/jsLoader.php b/ui/jsLoader.php
index 2adaa6a783b..49d5c21e422 100644
--- a/ui/jsLoader.php
+++ b/ui/jsLoader.php
@@ -36,20 +36,10 @@ $available_js = [
'class.dashboard.js' => '',
'class.dashboard.page.js' => '',
'class.dashboard.widget.placeholder.js' => '',
- 'class.widget.js' => 'widgets/',
- 'class.widget.iterator.js' => 'widgets/',
- 'class.widget.clock.js' => 'widgets/',
- 'class.widget.geomap.js' => 'widgets/',
- 'class.widget.graph.js' => 'widgets/',
- 'class.widget.graph-prototype.js' => 'widgets/',
- 'class.widget.item.js' => 'widgets/',
- 'class.widget.map.js' => 'widgets/',
- 'class.widget.navtree.js' => 'widgets/',
- 'class.widget.paste-placeholder.js' => 'widgets/',
- 'class.widget.problems.js' => 'widgets/',
- 'class.widget.problemsbysv.js' => 'widgets/',
- 'class.widget.svggraph.js' => 'widgets/',
- 'class.widget.trigerover.js' => 'widgets/',
+ 'class.widget.js' => '',
+ 'class.widget.inaccessible.js' => '',
+ 'class.widget.iterator.js' => '',
+ 'class.widget.paste-placeholder.js' => '',
'hostinterfacemanager.js' => '',
'hostmacrosmanager.js' => '',
'menupopup.js' => '',
@@ -136,6 +126,8 @@ $translate_strings = [
'Actions' => _('Actions'),
'Cannot add dashboard page: maximum number of %1$d dashboard pages has been added.' => _('Cannot add dashboard page: maximum number of %1$d dashboard pages has been added.'),
'Cannot add widget: not enough free space on the dashboard.' => _('Cannot add widget: not enough free space on the dashboard.'),
+ 'Cannot add widget: no widgets available.' => _('Cannot add widget: no widgets available.'),
+ 'Cannot paste inaccessible widget.' => _('Cannot paste inaccessible widget.'),
'Copy' => _('Copy'),
'Delete' => _('Delete'),
'Failed to paste dashboard page.' => _('Failed to paste dashboard page.'),
@@ -143,12 +135,17 @@ $translate_strings = [
'Failed to update dashboard page properties.' => _('Failed to update dashboard page properties.'),
'Failed to update dashboard properties.' => _('Failed to update dashboard properties.'),
'Failed to update widget properties.' => _('Failed to update widget properties.'),
+ 'Inaccessible widgets were not copied.' => _('Inaccessible widgets were not copied.'),
+ 'Inaccessible widgets were not pasted.' => _('Inaccessible widgets were not pasted.'),
'Page %1$d' => _('Page %1$d'),
'Paste widget' => _('Paste widget'),
'Properties' => _('Properties'),
'Start slideshow' => _('Start slideshow'),
'Stop slideshow' => _('Stop slideshow')
],
+ 'class.dashboard.page.js' => [
+ 'Inaccessible widget' => _('Inaccessible widget')
+ ],
'class.dashboard.widget.placeholder.js' => [
'Add a new widget' => _('Add a new widget'),
'Click and drag to desired size.' => _('Click and drag to desired size.'),
@@ -172,26 +169,11 @@ $translate_strings = [
'Paste' => _s('Paste'),
'Refresh interval' => _s('Refresh interval')
],
- 'class.widget.geomap.js' => [
- 'Actions' => _('Actions'),
- 'Set this view as default' => _('Set this view as default'),
- 'Reset to initial view' => _('Reset to initial view'),
- 'No problems' => _('No problems'),
- 'Not classified' => _('Not classified'),
- 'Information' => _('Information'),
- 'Warning' => _('Warning'),
- 'Average' => _('Average'),
- 'High' => _('High'),
- 'Disaster' => _('Disaster'),
- 'Host' => _('Host'),
- 'D' => _x('D', 'abbreviation of severity level'),
- 'H' => _x('H', 'abbreviation of severity level'),
- 'A' => _x('A', 'abbreviation of severity level'),
- 'W' => _x('W', 'abbreviation of severity level'),
- 'I' => _x('I', 'abbreviation of severity level'),
- 'N' => _x('N', 'abbreviation of severity level'),
- 'Navigate to default view' => _('Navigate to default view'),
- 'Navigate to initial view' => _('Navigate to initial view')
+ 'class.widget.inaccessible.js' => [
+ 'Actions' => _s('Actions'),
+ 'Copy' => _s('Copy'),
+ 'Inaccessible widget' => _('Inaccessible widget'),
+ 'Refresh interval' => _s('Refresh interval')
],
'class.widget.iterator.js' => [
'Next page' => _s('Next page'),
@@ -199,24 +181,6 @@ $translate_strings = [
'Widget is too small for the specified number of columns and rows.' =>
_s('Widget is too small for the specified number of columns and rows.')
],
- 'class.widget.graph.js' => [
- 'Actions' => _s('Actions'),
- 'Download image' => _s('Download image')
- ],
- 'class.widget.navtree.js' => [
- 'Add' => _s('Add'),
- 'Add child element' => _s('Add child element'),
- 'Add multiple maps' => _s('Add multiple maps'),
- 'Apply' => _s('Apply'),
- 'Cancel' => _s('Cancel'),
- 'Edit' => _s('Edit'),
- 'Edit tree element' => _s('Edit tree element'),
- 'Remove' => _s('Remove')
- ],
- 'class.widget.svggraph.js' => [
- 'Actions' => _s('Actions'),
- 'Download image' => _s('Download image')
- ],
'functions.js' => [
'Cancel' => _('Cancel'),
'S_CLOSE' => _('Close'),
@@ -420,7 +384,8 @@ $translate_strings = [
],
'common.js' => [
'Cancel' => _('Cancel'),
- 'Ok' => _('Ok')
+ 'Ok' => _('Ok'),
+ 'Unexpected server error.' => _('Unexpected server error.')
],
'component.z-select.js' => [
'All' => _('All')
diff --git a/ui/report2.php b/ui/report2.php
index 808fae031df..032bc9c9cef 100644
--- a/ui/report2.php
+++ b/ui/report2.php
@@ -156,7 +156,7 @@ $triggerData = isset($_REQUEST['triggerid'])
])
: null;
-$reportWidget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Availability report'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::REPORT2));
@@ -167,7 +167,7 @@ if ($triggerData) {
$triggerData['hostid'] = $host['hostid'];
$triggerData['hostname'] = $host['name'];
- $reportWidget->setControls((new CTag('nav', true,
+ $html_page->setControls((new CTag('nav', true,
(new CList())
->addItem(new CLink($triggerData['hostname'], (new CUrl('report2.php'))
->setArgument('page', CPagerHelper::loadPage('report2.php', null))
@@ -180,7 +180,7 @@ if ($triggerData) {
$table = (new CTableInfo())
->addRow(new CImg('chart4.php?triggerid='.$_REQUEST['triggerid']));
- $reportWidget->addItem(BR())
+ $html_page->addItem(BR())
->addItem($table)
->show();
}
@@ -195,7 +195,7 @@ else {
->addOption(new CSelectOption(AVAILABILITY_REPORT_BY_HOST, _('By host')))
->addOption(new CSelectOption(AVAILABILITY_REPORT_BY_TEMPLATE, _('By trigger template')));
- $reportWidget->setControls((new CForm('get'))
+ $html_page->setControls((new CForm('get'))
->cleanItems()
->setAttribute('aria-label', _('Main filter'))
->addItem((new CList())
@@ -494,7 +494,7 @@ else {
}
unset($trigger);
- $reportWidget->addItem(
+ $html_page->addItem(
(new CFilter())
->setResetUrl(new CUrl('report2.php'))
->setProfile($data['filter']['timeline']['profileIdx'])
@@ -563,7 +563,7 @@ else {
);
zbx_add_post_js('timeControl.processObjects();');
- $reportWidget
+ $html_page
->addItem([$triggerTable, $paging])
->show();
}
diff --git a/ui/report4.php b/ui/report4.php
index 9fa0c9f2cd6..281cb753a75 100644
--- a/ui/report4.php
+++ b/ui/report4.php
@@ -61,7 +61,7 @@ CArrayHelper::sort($db_media_types, ['name']);
$media_types = array_column($db_media_types, 'name', 'mediatypeid');
-$widget = (new CWidget())
+$html_page = (new CHtmlPage())
->setTitle(_('Notifications'))
->setDocUrl(CDocHelper::getUrl(CDocHelper::REPORT4));
@@ -121,7 +121,7 @@ if ($media_types) {
]);
}
- $widget->setControls((new CForm('get'))
+ $html_page->setControls((new CForm('get'))
->cleanItems()
->setAttribute('aria-label', _('Main filter'))
->addItem($controls)
@@ -258,7 +258,7 @@ else {
$table = new CTableInfo();
}
-$widget
+$html_page
->addItem($table)
->show();
diff --git a/ui/setup.php b/ui/setup.php
index 2174a12a028..6a3dc3a8209 100644
--- a/ui/setup.php
+++ b/ui/setup.php
@@ -160,8 +160,11 @@ DBclose();
$setup_wizard = new CSetupWizard();
// page title
-(new CPageHeader(_('Installation'), substr($default_lang, 0, strpos($default_lang, '_'))))
- ->addCssFile('assets/styles/'.CHtml::encode($default_theme).'.css')
+$page_header = (new CHtmlPageHeader(_('Installation'), substr($default_lang, 0, strpos($default_lang, '_'))));
+
+$page_header
+ ->setTheme($default_theme)
+ ->addCssFile('assets/styles/'.$page_header->getTheme().'.css')
->addJsFile((new CUrl('js/browsers.js'))->getUrl())
->addJsFile((new CUrl('jsLoader.php'))
->setArgument('ver', ZABBIX_VERSION)
@@ -174,7 +177,7 @@ $setup_wizard = new CSetupWizard();
->setArgument('files', ['setup.js'])
->getUrl()
)
- ->display();
+ ->show();
/*
* Displaying
diff --git a/ui/tests/include/web/elements/CWidgetElement.php b/ui/tests/include/web/elements/CWidgetElement.php
index 5d4b1348377..beb333f7861 100644
--- a/ui/tests/include/web/elements/CWidgetElement.php
+++ b/ui/tests/include/web/elements/CWidgetElement.php
@@ -33,7 +33,7 @@ class CWidgetElement extends CElement {
* @return integer
*/
public function getRefreshInterval() {
- $this->query('xpath:.//button[@class="btn-widget-action"]')->waitUntilPresent()->one()->click(true);
+ $this->query('xpath:.//button[contains(@class, "btn-widget-action")]')->waitUntilPresent()->one()->click(true);
$selected = $this->query('xpath://ul[@role="menu"]//a[contains(@aria-label, "selected")]')->one();
$aria_label = explode(', ', $selected->getAttribute('aria-label'), 3);
@@ -66,7 +66,7 @@ class CWidgetElement extends CElement {
* @return boolean
*/
public function isEditable() {
- return $this->query('xpath:.//button[@class="btn-widget-edit"]')->one()->isPresent();
+ return $this->query('xpath:.//button[contains(@class, "btn-widget-edit")]')->one()->isPresent();
}
/**
@@ -77,7 +77,7 @@ class CWidgetElement extends CElement {
public function edit() {
// Edit can sometimes fail so we have to retry this operation.
for ($i = 0; $i < 4; $i++) {
- $this->query('xpath:.//button[@class="btn-widget-edit"]')->waitUntilPresent()->one()->click(true);
+ $this->query('xpath:.//button[contains(@class, "btn-widget-edit")]')->waitUntilPresent()->one()->click(true);
try {
return $this->query('xpath://div[@data-dialogueid="widget_properties"]//form')->waitUntilVisible()->asForm()->one();
diff --git a/ui/tests/selenium/dashboard/testDashboardItemValueWidget.php b/ui/tests/selenium/dashboard/testDashboardItemValueWidget.php
index 025c8314dcb..3a987bf1516 100644
--- a/ui/tests/selenium/dashboard/testDashboardItemValueWidget.php
+++ b/ui/tests/selenium/dashboard/testDashboardItemValueWidget.php
@@ -1350,8 +1350,9 @@ class testDashboardItemValueWidget extends CWebTest {
CDataHelper::addItemData(42244, $index, time() + $index);
$this->page->refresh()->waitUntilReady();
$rgb = implode(', ', sscanf($threshold['color'], "%02x%02x%02x"));
- $this->assertEquals('rgba('.$rgb.', 1)', $dashboard->getWidget($data['fields']['Name'])->getContent()
- ->query('class:dashboard-widget-item')->one()->getCSSValue('background-color')
+
+ $this->assertEquals('rgba('.$rgb.', 1)', $dashboard->getWidget($data['fields']['Name'])
+ ->query('xpath:.//div[contains(@class, "dashboard-widget-item")]/div')->one()->getCSSValue('background-color')
);
$index++;
}
diff --git a/ui/tests/selenium/dashboard/testPageDashboardWidgets.php b/ui/tests/selenium/dashboard/testPageDashboardWidgets.php
index 8e240aa1c7f..2862cc86117 100644
--- a/ui/tests/selenium/dashboard/testPageDashboardWidgets.php
+++ b/ui/tests/selenium/dashboard/testPageDashboardWidgets.php
@@ -105,21 +105,22 @@ class testPageDashboardWidgets extends CWebTest {
$default_form->fill(['Type' => 'Clock']);
$default_form->waitUntilReloaded();
$overlay->close();
- // Check that widget type is remembered as Clock.
- $this->checkLastSelectedWidgetType('Clock', 'clock');
+ // Check that widget type is not remembered without submitting the form.
+ $this->checkLastSelectedWidgetType();
// Save edit widget form without changing widget type.
$sys_info_form = $dashboard->getWidget('System information')->edit();
$this->assertEquals('System information', $sys_info_form->getField('Type')->getValue());
$sys_info_form->submit();
$this->page->waitUntilReady();
- // Check that widget type is still remembered as Clock.
- $this->checkLastSelectedWidgetType('Clock', 'clock');
+ // Check that widget type is still unchanged.
+ $this->checkLastSelectedWidgetType();
// Opening edit widget form and change widget type.
$change_form = $dashboard->getWidget('System information')->edit();
$change_form->fill(['Type' => 'Data overview']);
- $overlay->close();
+ $change_form->waitUntilReloaded();
+ $change_form->submit();
// Check that widget type inherited from previous widget.
$this->checkLastSelectedWidgetType('Data overview', 'dataover');
@@ -186,7 +187,7 @@ class testPageDashboardWidgets extends CWebTest {
// Change dashboard owner.
$owner = $configuration->getField('Owner');
$owner->clear();
- $owner->select('test-user');
+ $owner->fill('test-user');
// Change dashboard name.
$configuration->getField('Name')->clear()->type('Dashboard create test');
$configuration->submit();
diff --git a/ui/tests/selenium/data/sources/CopyWidgetsDashboards.php b/ui/tests/selenium/data/sources/CopyWidgetsDashboards.php
index 8d7d016f864..4aa259216e7 100644
--- a/ui/tests/selenium/data/sources/CopyWidgetsDashboards.php
+++ b/ui/tests/selenium/data/sources/CopyWidgetsDashboards.php
@@ -170,7 +170,7 @@ class CopyWidgetsDashboards {
]
],
[
- 'name' => 'Test copy Favourite graphs',
+ 'name' => 'Test copy Favorite graphs',
'type' => 'favgraphs',
'x' => 20,
'y' => 7,
@@ -186,7 +186,7 @@ class CopyWidgetsDashboards {
]
],
[
- 'name' => 'Test copy Favourite maps',
+ 'name' => 'Test copy Favorite maps',
'type' => 'favmaps',
'x' => 14,
'y' => 10,
diff --git a/ui/tests/selenium/data/sources/TopHostsWidget.php b/ui/tests/selenium/data/sources/TopHostsWidget.php
index 701ae100438..6d6fa221121 100644
--- a/ui/tests/selenium/data/sources/TopHostsWidget.php
+++ b/ui/tests/selenium/data/sources/TopHostsWidget.php
@@ -129,7 +129,7 @@ class TopHostsWidget {
[
'type' => 0,
'name' => 'column',
- 'value' => 0
+ 'value' => 1
],
[
'type' => 1,
diff --git a/ui/tests/selenium/modules/module_number_1/Module.php b/ui/tests/selenium/modules/module_number_1/Module.php
index 29ac7341018..7f2db59f59f 100644
--- a/ui/tests/selenium/modules/module_number_1/Module.php
+++ b/ui/tests/selenium/modules/module_number_1/Module.php
@@ -2,7 +2,7 @@
namespace Modules\Example_A;
-use Core\CModule,
+use Zabbix\Core\CModule,
APP,
CMenu;
diff --git a/ui/tests/selenium/modules/module_number_1/manifest.json b/ui/tests/selenium/modules/module_number_1/manifest.json
index a5a5d681f8a..24e4b4bd020 100644
--- a/ui/tests/selenium/modules/module_number_1/manifest.json
+++ b/ui/tests/selenium/modules/module_number_1/manifest.json
@@ -1,5 +1,5 @@
{
- "manifest_version": 1,
+ "manifest_version": 2,
"id": "1st module id",
"name": "1st Module name",
"author": "1st Module author",
diff --git a/ui/tests/selenium/modules/module_number_1/views/first.module.php b/ui/tests/selenium/modules/module_number_1/views/first.module.php
index 241c411bb00..253dfb54ba9 100644
--- a/ui/tests/selenium/modules/module_number_1/views/first.module.php
+++ b/ui/tests/selenium/modules/module_number_1/views/first.module.php
@@ -1,6 +1,6 @@
<?php
-(new CWidget())
+(new CHtmlPage())
->addItem(
(new CTag('h1', true, 'If You see this message - 1st module is working'))
)->show();
diff --git a/ui/tests/selenium/modules/module_number_2/Module.php b/ui/tests/selenium/modules/module_number_2/Module.php
index 749400799c7..4bf34ee290d 100644
--- a/ui/tests/selenium/modules/module_number_2/Module.php
+++ b/ui/tests/selenium/modules/module_number_2/Module.php
@@ -2,7 +2,7 @@
namespace Modules\Example_B;
-use Core\CModule,
+use Zabbix\Core\CModule,
APP,
CMenu;
diff --git a/ui/tests/selenium/modules/module_number_2/manifest.json b/ui/tests/selenium/modules/module_number_2/manifest.json
index 4039b0c3d18..fb444f702e0 100644
--- a/ui/tests/selenium/modules/module_number_2/manifest.json
+++ b/ui/tests/selenium/modules/module_number_2/manifest.json
@@ -1,5 +1,5 @@
{
- "manifest_version": 0.99,
+ "manifest_version": 2.0,
"id": "two",
"name": "2nd Module name !@#$%^&*()_+",
"author": "2nd Module author !@#$%^&*()_+",
diff --git a/ui/tests/selenium/modules/module_number_2/views/second.module.php b/ui/tests/selenium/modules/module_number_2/views/second.module.php
index 39b7f7acfb2..b16e7f3a6ef 100644
--- a/ui/tests/selenium/modules/module_number_2/views/second.module.php
+++ b/ui/tests/selenium/modules/module_number_2/views/second.module.php
@@ -1,6 +1,6 @@
<?php
-(new CWidget())
+(new CHtmlPage())
->addItem(
(new CTag('h1', true, '2nd module is also working'))
)->show();
diff --git a/ui/tests/selenium/modules/module_number_3/Module.php b/ui/tests/selenium/modules/module_number_3/Module.php
index ab32c67e4f5..62435cd5515 100644
--- a/ui/tests/selenium/modules/module_number_3/Module.php
+++ b/ui/tests/selenium/modules/module_number_3/Module.php
@@ -2,7 +2,7 @@
namespace Modules\Example_C;
-use Core\CModule,
+use Zabbix\Core\CModule,
APP,
CMenu;
diff --git a/ui/tests/selenium/modules/module_number_3/manifest.json b/ui/tests/selenium/modules/module_number_3/manifest.json
index 3266063c0b3..75117cee725 100644
--- a/ui/tests/selenium/modules/module_number_3/manifest.json
+++ b/ui/tests/selenium/modules/module_number_3/manifest.json
@@ -1,5 +1,5 @@
{
- "manifest_version": 1.01,
+ "manifest_version": 2.01,
"id": "3",
"name": "This module should not be loaded",
"author": "module author",
diff --git a/ui/tests/selenium/modules/module_number_3/views/third.module.php b/ui/tests/selenium/modules/module_number_3/views/third.module.php
index b3a60b195d0..085a1ee086e 100644
--- a/ui/tests/selenium/modules/module_number_3/views/third.module.php
+++ b/ui/tests/selenium/modules/module_number_3/views/third.module.php
@@ -1,6 +1,6 @@
<?php
-(new CWidget())
+(new CHtmlPage())
->addItem(
(new CTag('h1', true, 'You should not see this message'))
)->show();
diff --git a/ui/tests/selenium/modules/module_number_4/Module.php b/ui/tests/selenium/modules/module_number_4/Module.php
index dcd0bb13a90..52c472c3114 100644
--- a/ui/tests/selenium/modules/module_number_4/Module.php
+++ b/ui/tests/selenium/modules/module_number_4/Module.php
@@ -2,7 +2,7 @@
namespace Modules\Example_A;
-use Core\CModule,
+use Zabbix\Core\CModule,
APP,
CMenu;
diff --git a/ui/tests/selenium/modules/module_number_4/manifest.json b/ui/tests/selenium/modules/module_number_4/manifest.json
index e5a3450b197..249a5fb208b 100644
--- a/ui/tests/selenium/modules/module_number_4/manifest.json
+++ b/ui/tests/selenium/modules/module_number_4/manifest.json
@@ -1,5 +1,5 @@
{
- "manifest_version": 0.01,
+ "manifest_version": 2.00,
"id": "4",
"name": "4th Module",
"author": "",
diff --git a/ui/tests/selenium/modules/module_number_4/views/forth.module.php b/ui/tests/selenium/modules/module_number_4/views/forth.module.php
index bd1000cc1b6..f0ba934eaa8 100644
--- a/ui/tests/selenium/modules/module_number_4/views/forth.module.php
+++ b/ui/tests/selenium/modules/module_number_4/views/forth.module.php
@@ -1,6 +1,6 @@
<?php
-(new CWidget())
+(new CHtmlPage())
->addItem(
(new CTag('h1', true, '4th module - cannot be enabled together with 1st module'))
)->show();
diff --git a/ui/tests/selenium/modules/module_number_5/Module.php b/ui/tests/selenium/modules/module_number_5/Module.php
index 0f93a364c4e..f9120308bb5 100644
--- a/ui/tests/selenium/modules/module_number_5/Module.php
+++ b/ui/tests/selenium/modules/module_number_5/Module.php
@@ -2,7 +2,7 @@
namespace Modules\Example_E;
-use Core\CModule,
+use Zabbix\Core\CModule,
APP,
CMenu;
diff --git a/ui/tests/selenium/modules/module_number_5/manifest.json b/ui/tests/selenium/modules/module_number_5/manifest.json
index 7f1802f3548..442fbabae04 100644
--- a/ui/tests/selenium/modules/module_number_5/manifest.json
+++ b/ui/tests/selenium/modules/module_number_5/manifest.json
@@ -1,5 +1,5 @@
{
- "manifest_version": 0.01,
+ "manifest_version": 2,
"id": "5",
"name": "5th Module",
"author": "",
diff --git a/ui/tests/selenium/modules/module_number_5/views/fifth.module.php b/ui/tests/selenium/modules/module_number_5/views/fifth.module.php
index 5f702c5a5a5..5cd1eee6bea 100644
--- a/ui/tests/selenium/modules/module_number_5/views/fifth.module.php
+++ b/ui/tests/selenium/modules/module_number_5/views/fifth.module.php
@@ -1,6 +1,6 @@
<?php
-(new CWidget())
+(new CHtmlPage())
->addItem(
(new CTag('h1', true, 'Если ты это читаешь то 5ый модуль работает'))
)->show();
diff --git a/ui/tests/selenium/modules/module_number_6/Module.php b/ui/tests/selenium/modules/module_number_6/Module.php
index 4e19b0c8107..d5d5837f38e 100644
--- a/ui/tests/selenium/modules/module_number_6/Module.php
+++ b/ui/tests/selenium/modules/module_number_6/Module.php
@@ -2,7 +2,7 @@
namespace Modules\Example_F;
-use Core\CModule,
+use Zabbix\Core\CModule,
APP,
CMenu;
diff --git a/ui/tests/selenium/modules/module_number_6/manifest.json b/ui/tests/selenium/modules/module_number_6/manifest.json
index d0a79518577..474d69d8321 100644
--- a/ui/tests/selenium/modules/module_number_6/manifest.json
+++ b/ui/tests/selenium/modules/module_number_6/manifest.json
@@ -1,5 +1,5 @@
{
- "manifest_version": 0.01,
+ "manifest_version": 2.000,
"id": "6",
"name": "шестой модуль",
"author": "Работник Заббикса",
diff --git a/ui/tests/selenium/problems/testFormUpdateProblem.php b/ui/tests/selenium/problems/testFormUpdateProblem.php
index f7f283832e7..838536384ce 100644
--- a/ui/tests/selenium/problems/testFormUpdateProblem.php
+++ b/ui/tests/selenium/problems/testFormUpdateProblem.php
@@ -936,12 +936,12 @@ class testFormUpdateProblem extends CWebTest {
// Check Event details page.
$row->getColumn('Time')->query('tag:a')->waitUntilClickable()->one()->click();
$this->page->assertHeader('Event details');
- $this->checkHistoryTable($this->query("xpath://div[@id=\"hat_eventactions_widget\"]//table")->asTable()->one(),
+ $this->checkHistoryTable($this->query("xpath://section[@id=\"hat_eventactions\"]//table")->asTable()->one(),
'User/Recipient', 'Action'
);
// Check Actions hint in Event list.
- $event_list_table = $this->query('xpath://div[@id="hat_eventlist_widget"]//table')->asTable()->one();
+ $event_list_table = $this->query('xpath://section[@id="hat_eventlist"]//table')->asTable()->one();
$event_list_table->getRow(0)->getColumn('Actions')->query($unsuppress_button)->waitUntilClickable()->one()->click();
$hint->invalidate();
$this->checkHistoryTable($hint->query('class:list-table')->asTable()->one(), 'User', 'Action');
diff --git a/ui/tests/selenium/roles/testFormUserRoles.php b/ui/tests/selenium/roles/testFormUserRoles.php
index 3483986dfff..059407eaf8e 100644
--- a/ui/tests/selenium/roles/testFormUserRoles.php
+++ b/ui/tests/selenium/roles/testFormUserRoles.php
@@ -1345,12 +1345,19 @@ class testFormUserRoles extends CWebTest {
*/
public function testFormUserRoles_Modules() {
$this->page->login();
+
foreach ([true, false] as $enable_modules) {
$modules = ['4th Module', '5th Module'];
$this->page->open('zabbix.php?action=userrole.edit&roleid=2')->waitUntilReady();
$form = $this->query('id:userrole-form')->waitUntilPresent()->asForm()->one();
+
if ($enable_modules === true) {
- $this->assertTrue($form->query('xpath://label[text()="No enabled modules found."]')->one()->isDisplayed());
+ foreach ($modules as $module) {
+ $this->assertFalse($form->query("xpath:.//label[text()=".CXPathHelper::escapeQuotes($module)."]")
+ ->one(false)->isValid()
+ );
+ }
+
$this->page->open('zabbix.php?action=module.list')->waitUntilReady();
$this->query('button:Scan directory')->one()->click();
$table = $this->query('class:list-table')->asTable()->one();
@@ -1360,7 +1367,6 @@ class testFormUserRoles extends CWebTest {
$this->page->waitUntilReady();
}
else {
- $this->assertFalse($form->query('xpath://label[text()="No enabled modules found."]')->one($enable_modules)->isDisplayed());
foreach ($modules as $module) {
$form->getField($module)->isChecked();
}
diff --git a/ui/tests/selenium/testDocumentationLinks.php b/ui/tests/selenium/testDocumentationLinks.php
index 741b7e50228..603a9067489 100644
--- a/ui/tests/selenium/testDocumentationLinks.php
+++ b/ui/tests/selenium/testDocumentationLinks.php
@@ -117,7 +117,7 @@ class testDocumentationLinks extends CWebTest {
'actions' => [
[
'callback' => 'openFormWithLink',
- 'element' => 'xpath:(//button[@class="btn-widget-edit"])[1]'
+ 'element' => 'xpath:(//button[contains(@class, "btn-widget-edit")])[1]'
]
]
]
@@ -687,7 +687,7 @@ class testDocumentationLinks extends CWebTest {
'actions' => [
[
'callback' => 'openFormWithLink',
- 'element' => 'xpath:(//button[@class="btn-widget-edit"])[1]'
+ 'element' => 'xpath:(//button[contains(@class, "btn-widget-edit")])[1]'
]
],
'doc_link' => '/en/manual/web_interface/frontend_sections/dashboards/widgets'
diff --git a/ui/tests/selenium/testPageAdministrationGeneralModules.php b/ui/tests/selenium/testPageAdministrationGeneralModules.php
index fe488eecb37..4ea9799f49e 100644
--- a/ui/tests/selenium/testPageAdministrationGeneralModules.php
+++ b/ui/tests/selenium/testPageAdministrationGeneralModules.php
@@ -41,6 +41,12 @@ class testPageAdministrationGeneralModules extends CWebTest {
];
}
+ private static $widget_names = ['Action log', 'Clock', 'Data overview', 'Discovery status', 'Favorite graphs',
+ 'Favorite maps','Geomap', 'Graph', 'Graph (classic)', 'Graph prototype', 'Host availability', 'Item value',
+ 'Map', 'Map navigation tree', 'Plain text', 'Problem hosts', 'Problems', 'Problems by severity', 'SLA report',
+ 'System information', 'Top hosts', 'Trigger overview', 'URL', 'Web monitoring'
+ ];
+
public function testPageAdministrationGeneralModules_Layout() {
$modules = [
[
@@ -79,6 +85,21 @@ class testPageAdministrationGeneralModules extends CWebTest {
'Status' => 'Disabled'
]
];
+
+ // Create an array with widgt modules that should be present by default.
+ $widget_modules = [];
+ $i = 0;
+
+ foreach (self::$widget_names as $name) {
+ $widget_modules[$i]['Name'] = $name;
+ $widget_modules[$i]['Version'] = '1.0';
+ $widget_modules[$i]['Author'] = 'Zabbix SIA';
+ $widget_modules[$i]['Description'] = '';
+ $widget_modules[$i]['Status'] = 'Enabled';
+
+ $i++;
+ }
+
// Open modules page and check header.
$this->page->login()->open('zabbix.php?action=module.list');
$this->assertEquals('Modules', $this->query('tag:h1')->one()->getText());
@@ -87,12 +108,17 @@ class testPageAdministrationGeneralModules extends CWebTest {
foreach (['Scan directory' => true, 'Enable' => false, 'Disable' => false] as $button => $enabled) {
$this->assertTrue($this->query('button', $button)->one()->isEnabled($enabled));
}
- // Check that modules are not being loaded until the 'Scan directory' button is pressed.
- $this->assertEquals($this->query('class:nothing-to-show')->one()->getText(), 'No data found.');
- $this->assertEquals('Displaying 0 of 0 found', $this->query('class:table-stats')->one()->getText());
+
+ $table = $this->query('class:list-table')->asTable()->one();
+
+ // Check that only widget modules are present until the 'Scan directory' button is pressed.
+ $this->assertTableData($widget_modules);
+
+ $count = $table->getRows()->count();
+ $this->assertTableStats($count);
+
$this->assertEquals('0 selected', $this->query('id:selected_count')->one()->getText());
// Check modules table headers.
- $table = $this->query('class:list-table')->asTable()->one();
$headers = $table->getHeadersText();
// Remove empty element from headers array.
array_shift($headers);
@@ -101,8 +127,14 @@ class testPageAdministrationGeneralModules extends CWebTest {
// Load modules.
$this->loadModules();
+ $all_modules = array_merge($widget_modules, $modules);
+ // Sort column contents ascending.
+ usort($all_modules, function($a, $b) {
+ return strcmp($a['Name'], $b['Name']);
+ });
+
// Check parameters of modules in the modules table.
- $this->assertTableData($modules);
+ $this->assertTableData($all_modules);
$count = CDBHelper::getCount('SELECT moduleid FROM module');
$this->assertEquals('Displaying '.$count.' of '.$count.' found', $this->query('class:table-stats')->one()->getText());
@@ -121,8 +153,8 @@ class testPageAdministrationGeneralModules extends CWebTest {
'Version' => '1',
'Author' => '1st Module author',
'Description' => '1st Module description',
- 'Directory' => 'module_number_1',
- 'Namespace' => 'Example_A',
+ 'Directory' => 'modules/module_number_1',
+ 'Namespace' => 'Modules\Example_A',
'Homepage' => '1st module URL',
'Enabled' => false
]
@@ -134,8 +166,8 @@ class testPageAdministrationGeneralModules extends CWebTest {
'Version' => 'two !@#$%^&*()_+',
'Author' => '2nd Module author !@#$%^&*()_+',
'Description' => 'Module description !@#$%^&*()_+',
- 'Directory' => 'module_number_2',
- 'Namespace' => 'Example_B',
+ 'Directory' => 'modules/module_number_2',
+ 'Namespace' => 'Modules\Example_B',
'Homepage' => '!@#$%^&*()_+',
'Enabled' => false
]
@@ -147,8 +179,8 @@ class testPageAdministrationGeneralModules extends CWebTest {
'Version' => '',
'Author' => '-',
'Description' => '-',
- 'Directory' => 'module_number_4',
- 'Namespace' => 'Example_A',
+ 'Directory' => 'modules/module_number_4',
+ 'Namespace' => 'Modules\Example_A',
'Homepage' => '-',
'Enabled' => false
]
@@ -160,8 +192,8 @@ class testPageAdministrationGeneralModules extends CWebTest {
'Version' => '',
'Author' => '-',
'Description' => 'Adding top-level and sub-level menu',
- 'Directory' => 'module_number_5',
- 'Namespace' => 'Example_E',
+ 'Directory' => 'modules/module_number_5',
+ 'Namespace' => 'Modules\Example_E',
'Homepage' => '-',
'Enabled' => false
]
@@ -173,8 +205,8 @@ class testPageAdministrationGeneralModules extends CWebTest {
'Version' => 'бета 2',
'Author' => 'Работник Заббикса',
'Description' => 'Удалить "Reports" из меню верхнего уровня, а так же удалить "Maps" из секции "Monitoring".',
- 'Directory' => 'module_number_6',
- 'Namespace' => 'Example_F',
+ 'Directory' => 'modules/module_number_6',
+ 'Namespace' => 'Modules\Example_F',
'Homepage' => '-',
'Enabled' => false
]
@@ -277,9 +309,8 @@ class testPageAdministrationGeneralModules extends CWebTest {
'action' => 'forth.module'
]
],
-// 'error_title' => 'Cannot update module: 4th Module.',
- 'error_details' => 'Identical namespace (Example_A) is used by modules located at '.
- 'module_number_1, module_number_4.'
+ 'error_details' => 'Identical namespace (Modules\Example_A) is used by modules located at '.
+ 'modules/module_number_1, modules/module_number_4.'
]
]
],
@@ -409,9 +440,7 @@ class testPageAdministrationGeneralModules extends CWebTest {
'filter' => [
'Status' => 'Enabled'
],
- 'expected' => [
- '2nd Module name !@#$%^&*()_+'
- ]
+ 'expected' => array_merge(['2nd Module name !@#$%^&*()_+'], self::$widget_names)
]
],
// Retrieve only Disabled modules.
diff --git a/ui/tests/selenium/testSID.php b/ui/tests/selenium/testSID.php
index bc7f1c4a6ce..3669387d956 100644
--- a/ui/tests/selenium/testSID.php
+++ b/ui/tests/selenium/testSID.php
@@ -248,13 +248,6 @@ class testSID extends CWebTest {
'json_output' => true
]],
- // Dashboard widget configure.
- [[
- 'link' => 'zabbix.php?action=dashboard.widget.configure&type=actionlog&view_mode=0&fields=%7B%22rf_rate'.
- '%22%3A%22-1%22%2C%22sort_triggers%22%3A%224%22%2C%22show_lines%22%3A%2225%22%7D',
- 'json_output' => true
- ]],
-
// Dashboard widget refresh rate.
[[
'link' => 'zabbix.php?action=dashboard.widget.rfrate&widgetid=2002&rf_rate=120',
@@ -278,12 +271,6 @@ class testSID extends CWebTest {
'link' => 'zabbix.php?form_refresh=1&templateid=10076&dashboardids%5B146%5D=146&action=template.dashboard.delete'
]],
- // Template dashboard widget edit.
- [[
- 'link' => 'zabbix.php?action=dashboard.widget.edit&templateid=10076',
- 'json_output' => true
- ]],
-
// User token delete.
[[
'link' => 'zabbix.php?action=token.delete&action_src=user.token.list&tokenids%5B0%5D=1',
@@ -606,11 +593,11 @@ class testSID extends CWebTest {
// Export.
[['link' => 'zabbix.php?action=export.hosts&format=yaml&backurl=hosts.php&form_refresh=1&hosts%5B50011%5D=50011']],
- // Favourite create.
- [['link' => 'zabbix.php?action=favourite.create&object=screenid&objectid=200021']],
+ // Favorite create.
+ [['link' => 'zabbix.php?action=favorite.create&object=screenid&objectid=200021']],
- // Favourite delete.
- [['link' => 'zabbix.php?action=favourite.delete&object=screenid&objectid=200021']],
+ // Favorite delete.
+ [['link' => 'zabbix.php?action=favorite.delete&object=screenid&objectid=200021']],
// Host creation.
[[
diff --git a/ui/tests/selenium/users/testFormUserPermissions.php b/ui/tests/selenium/users/testFormUserPermissions.php
index 38b8e9ac8c7..85607986122 100644
--- a/ui/tests/selenium/users/testFormUserPermissions.php
+++ b/ui/tests/selenium/users/testFormUserPermissions.php
@@ -461,9 +461,23 @@ class testFormUserPermissions extends CWebTest {
* Check enabled/disabled module.
*/
public function testFormUserPermissions_Module() {
+ $widget_modules = ['Action log', 'Clock', 'Data overview', 'Discovery status', 'Favorite graphs', 'Favorite maps',
+ 'Geomap', 'Graph', 'Graph (classic)', 'Graph prototype', 'Host availability', 'Item value', 'Map',
+ 'Map navigation tree', 'Plain text', 'Problem hosts', 'Problems', 'Problems by severity', 'SLA report',
+ 'System information', 'Top hosts', 'Trigger overview', 'URL', 'Web monitoring'
+ ];
+
$this->page->login()->open('zabbix.php?action=user.edit&userid='.self::$admin_user)->waitUntilReady();
$this->query('xpath://form[@name="user_form"]')->waitUntilPresent()->one()->asForm()->selectTab('Permissions');
- $this->assertTrue($this->query('xpath://em[text()="No enabled modules found."]')->one()->isDisplayed());
+
+ // Check that the default modules are present in form.
+ $modules_selector = 'xpath://h4[text()="Access to modules"]/../../following::li[1]//span';
+ $modules = $this->query($modules_selector)->all()->asText();
+
+ foreach (array_values($modules) as $module_name) {
+ $this->assertTrue(in_array($module_name, $widget_modules));
+ }
+
$this->page->open('zabbix.php?action=module.list')->waitUntilReady();
$this->query('button:Scan directory')->one()->click();
$table = $this->query('class:list-table')->asTable()->one();
@@ -471,20 +485,24 @@ class testFormUserPermissions extends CWebTest {
$this->query('button:Enable')->one()->click();
$this->page->acceptAlert();
$this->page->waitUntilReady();
- $selector = 'xpath://h4[text()="Access to modules"]/../../following::li/div/div/span[text()=';
+
foreach ([true, false] as $enable_modules) {
$this->page->open('zabbix.php?action=user.edit&userid='.self::$admin_user)->waitUntilReady();
$this->query('xpath://form[@name="user_form"]')->waitUntilPresent()->one()->asForm()->selectTab('Permissions');
if ($enable_modules) {
- $this->assertEquals('status-green', $this->query($selector.'"4"]')->one()->getAttribute('class'));
+ $this->assertEquals('status-green', $this->query($modules_selector.'[text()="4th Module"]')->one()
+ ->getAttribute('class')
+ );
$this->page->open('zabbix.php?action=userrole.edit&roleid='.self::$admin_roleid);
$form = $this->query('id:userrole-form')->waitUntilPresent()->asForm()->one();
$form->getField('4th Module')->uncheck();
$form->submit();
}
else {
- $this->assertEquals('status-grey', $this->query($selector.'"4"]')->one()->getAttribute('class'));
+ $this->assertEquals('status-grey', $this->query($modules_selector.'[text()="4th Module"]')->one()
+ ->getAttribute('class')
+ );
}
}
}
diff --git a/ui/tests/unit/bootstrap.php b/ui/tests/unit/bootstrap.php
index 3fbbcae5f04..3ee9b0a4d60 100644
--- a/ui/tests/unit/bootstrap.php
+++ b/ui/tests/unit/bootstrap.php
@@ -73,5 +73,6 @@ $autoloader->addNamespace('', [
__DIR__.'/include/classes/import/converters',
__DIR__.'/include/classes/include/classes/vaults'
]);
-$autoloader->addNamespace('Core', [__DIR__.'/../../include/classes/core']);
+$autoloader->addNamespace('Zabbix\\Core', [__DIR__.'/../../include/classes/core']);
+$autoloader->addNamespace('Zabbix\\Widgets', [__DIR__.'/../../include/classes/widgets']);
$autoloader->register();
diff --git a/ui/tests/unit/include/classes/import/CImportDataAdapterTest.php b/ui/tests/unit/include/classes/import/CImportDataAdapterTest.php
index ae62d19d55e..1119ecabcb7 100644
--- a/ui/tests/unit/include/classes/import/CImportDataAdapterTest.php
+++ b/ui/tests/unit/include/classes/import/CImportDataAdapterTest.php
@@ -4279,9 +4279,7 @@ class CImportDataAdapterTest extends TestCase {
->setStrict(true)
->validate($source, '/');
- $versions = ['1.0', '2.0', '3.0', '3.2', '3.4', '4.0', '4.2', '4.4', '5.0', '5.2', '5.4', '6.0', '6.2'];
-
- foreach ($versions as $version) {
+ foreach ($import_converter_factory::getSequentialVersions() as $version) {
if ($source['zabbix_export']['version'] !== $version) {
continue;
}
diff --git a/ui/tr_events.php b/ui/tr_events.php
index d088c17f210..30c2a5c175e 100644
--- a/ui/tr_events.php
+++ b/ui/tr_events.php
@@ -37,20 +37,10 @@ require_once dirname(__FILE__).'/include/page_header.php';
// VAR TYPE OPTIONAL FLAGS VALIDATION EXCEPTION
$fields = [
'triggerid' => [T_ZBX_INT, O_OPT, P_SYS, DB_ID, PAGE_TYPE_HTML.'=='.$page['type']],
- 'eventid' => [T_ZBX_INT, O_OPT, P_SYS, DB_ID, PAGE_TYPE_HTML.'=='.$page['type']],
- // Ajax
- 'widget' => [T_ZBX_STR, O_OPT, P_ACT, IN('"'.WIDGET_HAT_EVENTACTIONS.'","'.WIDGET_HAT_EVENTLIST.'"'), null],
- 'state' => [T_ZBX_INT, O_OPT, P_ACT, IN('0,1'), null]
+ 'eventid' => [T_ZBX_INT, O_OPT, P_SYS, DB_ID, PAGE_TYPE_HTML.'=='.$page['type']]
];
check_fields($fields);
-/*
- * Ajax
- */
-if (hasRequest('widget') && hasRequest('state')) {
- CProfile::update('web.tr_events.hats.'.getRequest('widget').'.state', getRequest('state'), PROFILE_TYPE_INT);
-}
-
if ($page['type'] == PAGE_TYPE_JS || $page['type'] == PAGE_TYPE_HTML_BLOCK) {
require_once dirname(__FILE__).'/include/page_footer.php';
exit;
@@ -171,35 +161,36 @@ require_once dirname(__FILE__).'/include/views/js/tr_events.js.php';
$event_tab = (new CDiv([
new CDiv([
- (new CUiWidget(WIDGET_HAT_TRIGGERDETAILS, make_trigger_details($trigger, $event['eventid'])))
- ->setHeader(_('Trigger details')),
- (new CUiWidget(WIDGET_HAT_EVENTDETAILS, make_event_details($event, $allowed)))
- ->setHeader(_('Event details'))
+ (new CSection(make_trigger_details($trigger, $event['eventid'])))
+ ->setId(SECTION_HAT_TRIGGERDETAILS)
+ ->setHeader(new CTag('h4', true, _('Trigger details'))),
+ (new CSection(make_event_details($event, $allowed)))
+ ->setId(SECTION_HAT_EVENTDETAILS)
+ ->setHeader(new CTag('h4', true, _('Event details')))
]),
new CDiv([
- (new CCollapsibleUiWidget(WIDGET_HAT_EVENTACTIONS,
- makeEventDetailsActionsTable($actions, $users, $mediatypes)
- ))
- ->setExpanded((bool) CProfile::get('web.tr_events.hats.'.WIDGET_HAT_EVENTACTIONS.'.state', true))
- ->setHeader(_('Actions'), [], 'web.tr_events.hats.'.WIDGET_HAT_EVENTACTIONS.'.state')
- ->addClass(ZBX_STYLE_DASHBOARD_WIDGET_FLUID),
- (new CCollapsibleUiWidget(WIDGET_HAT_EVENTLIST, make_small_eventlist($event, $allowed)))
- ->setExpanded((bool) CProfile::get('web.tr_events.hats.'.WIDGET_HAT_EVENTLIST.'.state', true))
- ->setHeader(_('Event list [previous 20]'), [], 'web.tr_events.hats.'.WIDGET_HAT_EVENTLIST.'.state')
- ->addClass(ZBX_STYLE_DASHBOARD_WIDGET_FLUID)
+ (new CSectionCollapsible(makeEventDetailsActionsTable($actions, $users, $mediatypes)))
+ ->setId(SECTION_HAT_EVENTACTIONS)
+ ->setHeader(new CTag('h4', true, _('Actions')))
+ ->setProfileIdx('web.tr_events.hats.'.SECTION_HAT_EVENTACTIONS.'.state')
+ ->setExpanded((bool) CProfile::get('web.tr_events.hats.'.SECTION_HAT_EVENTACTIONS.'.state', true)),
+ (new CSectionCollapsible(make_small_eventlist($event, $allowed)))
+ ->setId(SECTION_HAT_EVENTLIST)
+ ->setHeader(new CTag('h4', true, _('Event list [previous 20]')))
+ ->setProfileIdx('web.tr_events.hats.'.SECTION_HAT_EVENTLIST.'.state')
+ ->setExpanded((bool) CProfile::get('web.tr_events.hats.'.SECTION_HAT_EVENTLIST.'.state', true)),
])
]))
->addClass(ZBX_STYLE_COLUMNS)
->addClass(ZBX_STYLE_COLUMNS_2);
-(new CWidget())
+(new CHtmlPage())
->setTitle(_('Event details'))
->setWebLayoutMode($page['web_layout_mode'])
->setDocUrl(CDocHelper::getUrl(CDocHelper::TR_EVENTS))
->setControls(
(new CTag('nav', true,
- (new CList())
- ->addItem(get_icon('kioskmode', ['mode' => $page['web_layout_mode']]))
+ (new CList())->addItem(get_icon('kioskmode', ['mode' => $page['web_layout_mode']]))
))->setAttribute('aria-label', _('Content controls'))
)
->addItem($event_tab)
diff --git a/ui/widgets/actionlog/Widget.php b/ui/widgets/actionlog/Widget.php
new file mode 100755
index 00000000000..e1609372bbb
--- /dev/null
+++ b/ui/widgets/actionlog/Widget.php
@@ -0,0 +1,31 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\ActionLog;
+
+use Zabbix\Core\CWidget;
+
+class Widget extends CWidget {
+
+ public function getDefaultName(): string {
+ return _('Action log');
+ }
+}
diff --git a/ui/app/controllers/CControllerWidgetActionLogView.php b/ui/widgets/actionlog/actions/WidgetView.php
index 9c17ba7e272..494dce08606 100644
--- a/ui/app/controllers/CControllerWidgetActionLogView.php
+++ b/ui/widgets/actionlog/actions/WidgetView.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,33 +19,27 @@
**/
-class CControllerWidgetActionLogView extends CControllerWidget {
+namespace Widgets\ActionLog\Actions;
- public function __construct() {
- parent::__construct();
+use API,
+ CControllerDashboardWidgetView,
+ CControllerResponseData;
- $this->setType(WIDGET_ACTION_LOG);
- $this->setValidationRules([
- 'name' => 'string',
- 'fields' => 'json'
- ]);
- }
+class WidgetView extends CControllerDashboardWidgetView {
- protected function doAction() {
- $fields = $this->getForm()->getFieldsData();
-
- list($sortfield, $sortorder) = self::getSorting($fields['sort_triggers']);
- $alerts = $this->getAlerts($sortfield, $sortorder, $fields['show_lines']);
+ protected function doAction(): void {
+ [$sortfield, $sortorder] = self::getSorting($this->fields_values['sort_triggers']);
+ $alerts = $this->getAlerts($sortfield, $sortorder, $this->fields_values['show_lines']);
$db_users = $this->getDbUsers($alerts);
$actions = API::Action()->get([
'output' => ['actionid', 'name'],
- 'actionids' => array_unique(zbx_objectValues($alerts, 'actionid')),
+ 'actionids' => array_unique(array_column($alerts, 'actionid')),
'preservekeys' => true
]);
$this->setResponse(new CControllerResponseData([
- 'name' => $this->getInput('name', $this->getDefaultName()),
+ 'name' => $this->getInput('name', $this->widget->getDefaultName()),
'actions' => $actions,
'alerts' => $alerts,
'db_users' => $db_users,
@@ -57,16 +51,7 @@ class CControllerWidgetActionLogView extends CControllerWidget {
]));
}
- /**
- * Get alerts.
- *
- * @param string $sortfield
- * @param string $sortorder
- * @param int $show_lines
- *
- * @return array
- */
- private function getAlerts($sortfield, $sortorder, $show_lines) {
+ private function getAlerts(string $sortfield, string $sortorder, $show_lines): array {
$alerts = API::Alert()->get([
'output' => ['clock', 'sendto', 'subject', 'message', 'status', 'retries', 'error', 'userid', 'actionid',
'mediatypeid', 'alerttype'
@@ -79,6 +64,7 @@ class CControllerWidgetActionLogView extends CControllerWidget {
foreach ($alerts as &$alert) {
$alert['description'] = '';
+
if ($alert['mediatypeid'] != 0 && array_key_exists(0, $alert['mediatypes'])) {
$alert['description'] = $alert['mediatypes'][0]['name'];
$alert['maxattempts'] = $alert['mediatypes'][0]['maxattempts'];
@@ -92,14 +78,7 @@ class CControllerWidgetActionLogView extends CControllerWidget {
return $alerts;
}
- /**
- * Get users.
- *
- * @param array $alerts
- *
- * @return array
- */
- private function getDbUsers(array $alerts) {
+ private function getDbUsers(array $alerts): array {
$userids = [];
foreach ($alerts as $alert) {
@@ -116,16 +95,7 @@ class CControllerWidgetActionLogView extends CControllerWidget {
: [];
}
- /**
- * Get sorting.
- *
- * @param int $sort_triggers
- *
- * @static
- *
- * @return array
- */
- private static function getSorting($sort_triggers) {
+ private static function getSorting(int $sort_triggers): array {
switch ($sort_triggers) {
case SCREEN_SORT_TRIGGERS_TIME_ASC:
return ['clock', ZBX_SORT_UP];
diff --git a/ui/widgets/actionlog/includes/WidgetForm.php b/ui/widgets/actionlog/includes/WidgetForm.php
new file mode 100644
index 00000000000..fa0d39fdfa8
--- /dev/null
+++ b/ui/widgets/actionlog/includes/WidgetForm.php
@@ -0,0 +1,59 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\ActionLog\Includes;
+
+use Zabbix\Widgets\{
+ CWidgetField,
+ CWidgetForm
+};
+
+use Zabbix\Widgets\Fields\{
+ CWidgetFieldIntegerBox,
+ CWidgetFieldSelect
+};
+
+/**
+ * Action log widget form.
+ */
+class WidgetForm extends CWidgetForm {
+
+ public function addFields(): self {
+ return $this
+ ->addField(
+ (new CWidgetFieldSelect('sort_triggers', _('Sort entries by'), [
+ SCREEN_SORT_TRIGGERS_TIME_DESC => _('Time').' ('._('descending').')',
+ SCREEN_SORT_TRIGGERS_TIME_ASC => _('Time').' ('._('ascending').')',
+ SCREEN_SORT_TRIGGERS_TYPE_DESC => _('Type').' ('._('descending').')',
+ SCREEN_SORT_TRIGGERS_TYPE_ASC => _('Type').' ('._('ascending').')',
+ SCREEN_SORT_TRIGGERS_STATUS_DESC => _('Status').' ('._('descending').')',
+ SCREEN_SORT_TRIGGERS_STATUS_ASC => _('Status').' ('._('ascending').')',
+ SCREEN_SORT_TRIGGERS_RECIPIENT_DESC => _('Recipient').' ('._('descending').')',
+ SCREEN_SORT_TRIGGERS_RECIPIENT_ASC => _('Recipient').' ('._('ascending').')'
+ ]))->setDefault(SCREEN_SORT_TRIGGERS_TIME_DESC)
+ )
+ ->addField(
+ (new CWidgetFieldIntegerBox('show_lines', _('Show lines'), ZBX_MIN_WIDGET_LINES, ZBX_MAX_WIDGET_LINES))
+ ->setDefault(ZBX_DEFAULT_WIDGET_LINES)
+ ->setFlags(CWidgetField::FLAG_LABEL_ASTERISK)
+ );
+ }
+}
diff --git a/ui/widgets/actionlog/manifest.json b/ui/widgets/actionlog/manifest.json
new file mode 100755
index 00000000000..d7c59e5f60a
--- /dev/null
+++ b/ui/widgets/actionlog/manifest.json
@@ -0,0 +1,9 @@
+{
+ "manifest_version": 2.0,
+ "id": "actionlog",
+ "type": "widget",
+ "name": "Action log",
+ "namespace": "ActionLog",
+ "version": "1.0",
+ "author": "Zabbix SIA"
+}
diff --git a/ui/widgets/actionlog/views/widget.edit.php b/ui/widgets/actionlog/views/widget.edit.php
new file mode 100755
index 00000000000..677ee2cc440
--- /dev/null
+++ b/ui/widgets/actionlog/views/widget.edit.php
@@ -0,0 +1,36 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+/**
+ * Action log widget form view.
+ *
+ * @var CView $this
+ * @var array $data
+ */
+
+(new CWidgetFormView($data))
+ ->addField(
+ new CWidgetFieldSelectView($data['fields']['sort_triggers'])
+ )
+ ->addField(
+ new CWidgetFieldIntegerBoxView($data['fields']['show_lines'])
+ )
+ ->show();
diff --git a/ui/app/views/monitoring.widget.actionlog.view.php b/ui/widgets/actionlog/views/widget.view.php
index f45fe68e66b..68b683319f9 100644
--- a/ui/app/views/monitoring.widget.actionlog.view.php
+++ b/ui/widgets/actionlog/views/widget.view.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -20,13 +20,14 @@
/**
+ * Action log widget view.
+ *
* @var CView $this
* @var array $data
*/
// indicator of sort field
-$sort_div = (new CSpan())
- ->addClass(($data['sortorder'] === ZBX_SORT_DOWN) ? ZBX_STYLE_ARROW_DOWN : ZBX_STYLE_ARROW_UP);
+$sort_div = (new CSpan())->addClass($data['sortorder'] === ZBX_SORT_DOWN ? ZBX_STYLE_ARROW_DOWN : ZBX_STYLE_ARROW_UP);
// create alert table
$table = (new CTableInfo())
@@ -59,7 +60,7 @@ foreach ($data['alerts'] as $alert) {
$info_icons = makeErrorIcon($alert['error']);
}
else {
- $info_icons = null;
+ $info_icons = [];
}
$message = ($alert['alerttype'] == ALERT_TYPE_MESSAGE)
@@ -84,18 +85,6 @@ foreach ($data['alerts'] as $alert) {
]);
}
-$output = [
- 'name' => $data['name'],
- 'body' => $table->toString()
-];
-
-if ($messages = get_and_clear_messages()) {
- $output['messages'] = array_column($messages, 'message');
-}
-
-if ($data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
- CProfiler::getInstance()->stop();
- $output['debug'] = CProfiler::getInstance()->make()->toString();
-}
-
-echo json_encode($output);
+(new CWidgetView($data))
+ ->addItem($table)
+ ->show();
diff --git a/ui/widgets/clock/Widget.php b/ui/widgets/clock/Widget.php
new file mode 100755
index 00000000000..c20635500d3
--- /dev/null
+++ b/ui/widgets/clock/Widget.php
@@ -0,0 +1,48 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\Clock;
+
+use Zabbix\Core\CWidget;
+
+class Widget extends CWidget {
+
+ // Clock type.
+ public const TYPE_ANALOG = 0;
+ public const TYPE_DIGITAL = 1;
+
+ // Clock time zone format.
+ public const TIMEZONE_SHORT = 0;
+ public const TIMEZONE_FULL = 1;
+
+ // Clock time format.
+ public const HOUR_24 = 0;
+ public const HOUR_12 = 1;
+
+ // Form blocks.
+ public const SHOW_DATE = 1;
+ public const SHOW_TIME = 2;
+ public const SHOW_TIMEZONE = 3;
+
+ public function getDefaultName(): string {
+ return _('Clock');
+ }
+}
diff --git a/ui/app/controllers/CControllerWidgetClockView.php b/ui/widgets/clock/actions/WidgetView.php
index f3fb20a7210..62ce9a2f435 100644..100755
--- a/ui/app/controllers/CControllerWidgetClockView.php
+++ b/ui/widgets/clock/actions/WidgetView.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,24 +19,33 @@
**/
-class CControllerWidgetClockView extends CControllerWidget {
+namespace Widgets\Clock\Actions;
- public function __construct() {
- parent::__construct();
+use API,
+ CControllerDashboardWidgetView,
+ CControllerResponseData,
+ CTimezoneHelper,
+ DateTime,
+ DateTimeZone,
+ Exception,
+ Manager;
- $this->setType(WIDGET_CLOCK);
- $this->setValidationRules([
- 'name' => 'string',
- 'fields' => 'json',
+use Widgets\Clock\Widget;
+
+class WidgetView extends CControllerDashboardWidgetView {
+
+ protected function init(): void {
+ parent::init();
+
+ $this->addValidationRules([
'dynamic_hostid' => 'db hosts.hostid'
]);
}
- protected function doAction() {
- $fields = $this->getForm()->getFieldsData();
+ protected function doAction(): void {
$config_defaults = [
- 'name' => $this->getDefaultName(),
- 'type' => $fields['clock_type'],
+ 'name' => $this->widget->getDefaultName(),
+ 'type' => $this->fields_values['clock_type'],
'time' => null,
'time_zone_offset' => null,
'date' => date(ZBX_DATE),
@@ -45,35 +54,35 @@ class CControllerWidgetClockView extends CControllerWidget {
'critical_error' => null
];
- switch ($fields['time_type']) {
+ switch ($this->fields_values['time_type']) {
case TIME_TYPE_HOST:
- $clock_data = $this->configureHostTime($fields) + $config_defaults;
+ $clock_data = $this->configureHostTime() + $config_defaults;
break;
case TIME_TYPE_SERVER:
- $clock_data = $this->configureFields($fields) + $config_defaults;
+ $clock_data = $this->configureFields() + $config_defaults;
$clock_data['name'] = _('Server');
break;
default:
- $clock_data = $this->configureFields($fields) + $config_defaults;
+ $clock_data = $this->configureFields() + $config_defaults;
$clock_data['name'] = _('Local');
break;
}
- // Pass clock configiguration to browser script.
- if ($fields['clock_type'] === WIDGET_CLOCK_TYPE_DIGITAL) {
- $clock_data['show'] = $fields['show'];
- $clock_data['bg_color'] = $fields['bg_color'];
- $clock_data['time_format'] = $fields['time_format'];
- $clock_data['seconds'] = ($fields['time_sec'] == 1);
- $clock_data['tzone_format'] = $fields['tzone_format'];
+ // Pass clock configuration to browser script.
+ if ($this->fields_values['clock_type'] === Widget::TYPE_DIGITAL) {
+ $clock_data['show'] = $this->fields_values['show'];
+ $clock_data['bg_color'] = $this->fields_values['bg_color'];
+ $clock_data['time_format'] = $this->fields_values['time_format'];
+ $clock_data['seconds'] = ($this->fields_values['time_sec'] == 1);
+ $clock_data['tzone_format'] = $this->fields_values['tzone_format'];
}
$this->setResponse(new CControllerResponseData([
'name' => $this->getInput('name', $clock_data['name']),
'clock_data' => $clock_data,
- 'styles' => self::getFieldStyles($fields),
+ 'styles' => $this->getFieldStyles(),
'user' => [
'debug_mode' => $this->getDebugMode()
]
@@ -88,18 +97,14 @@ class CControllerWidgetClockView extends CControllerWidget {
*
* @return string Return time zone name from list or 'local' if time zone must be set via browser.
*/
- protected function makeTimeZoneValue(string $time_zone, int $format = WIDGET_CLOCK_TIMEZONE_SHORT): string {
+ private function makeTimeZoneValue(string $time_zone, int $format = Widget::TIMEZONE_SHORT): string {
if ($time_zone === TIMEZONE_DEFAULT_LOCAL) {
return $time_zone;
}
- elseif ($time_zone === ZBX_DEFAULT_TIMEZONE) {
- $zone = CTimezoneHelper::getSystemTimezone();
- }
- else {
- $zone = $time_zone;
- }
- if ($format === WIDGET_CLOCK_TIMEZONE_SHORT) {
+ $zone = $time_zone === ZBX_DEFAULT_TIMEZONE ? CTimezoneHelper::getSystemTimezone() : $time_zone;
+
+ if ($format === Widget::TIMEZONE_SHORT) {
if (($pos = strrpos($zone, '/')) !== false) {
$zone = substr($zone, $pos + 1);
}
@@ -111,37 +116,19 @@ class CControllerWidgetClockView extends CControllerWidget {
return str_replace('_', ' ', $zone);
}
- /**
- * @param array $fields
- *
- * @return boolean
- */
- protected function showDate(array $fields): bool {
- return ($fields['clock_type'] === WIDGET_CLOCK_TYPE_DIGITAL
- && in_array(WIDGET_CLOCK_SHOW_DATE, $fields['show'])
- );
+ private function showDate(): bool {
+ return $this->fields_values['clock_type'] === Widget::TYPE_DIGITAL
+ && in_array(Widget::SHOW_DATE, $this->fields_values['show']);
}
- /**
- * @param array $fields
- *
- * @return boolean
- */
- protected function showTime(array $fields): bool {
- return ($fields['clock_type'] === WIDGET_CLOCK_TYPE_ANALOG
- || in_array(WIDGET_CLOCK_SHOW_TIMEZONE, $fields['show'])
- );
+ private function showTime(): bool {
+ return $this->fields_values['clock_type'] === Widget::TYPE_ANALOG
+ || in_array(Widget::SHOW_TIME, $this->fields_values['show']);
}
- /**
- * @param array $fields
- *
- * @return boolean
- */
- protected function showTimeZone(array $fields): bool {
- return ($fields['clock_type'] === WIDGET_CLOCK_TYPE_DIGITAL
- && in_array(WIDGET_CLOCK_SHOW_TIMEZONE, $fields['show'])
- );
+ private function showTimeZone(): bool {
+ return $this->fields_values['clock_type'] === Widget::TYPE_DIGITAL
+ && in_array(Widget::SHOW_TIMEZONE, $this->fields_values['show']);
}
/**
@@ -149,7 +136,7 @@ class CControllerWidgetClockView extends CControllerWidget {
*
* @return array
*/
- protected function makeTimeFromDateTime(DateTime $date): array {
+ private function makeTimeFromDateTime(DateTime $date): array {
$time = [];
$time['time'] = $date->getTimestamp();
@@ -165,7 +152,7 @@ class CControllerWidgetClockView extends CControllerWidget {
*
* @return DateTime|null Returns created DateTime object or null if time zone is set by browser.
*/
- protected function makeDateTimeFromTimeZone(string $time_zone): ?DateTime {
+ private function makeDateTimeFromTimeZone(string $time_zone): ?DateTime {
if ($time_zone === TIMEZONE_DEFAULT_LOCAL) {
return null;
}
@@ -179,46 +166,15 @@ class CControllerWidgetClockView extends CControllerWidget {
return $now;
}
- /**
- * Create required clock field values both for analog and digital clock.
- *
- * @param array $fields Saved clock configuration.
- *
- * @return array Return prepared clock configuration.
- */
- protected function configureFields(array $fields): array {
- $clock = [];
-
- $date = $this->makeDateTimeFromTimeZone($fields['tzone_timezone']);
-
- if ($this->showDate($fields) && $date !== null) {
- $clock['date'] = $date->format(ZBX_DATE);
- }
-
- if ($this->showTime($fields) && $date !== null) {
- $clock = array_merge($clock, $this->makeTimeFromDateTime($date));
- }
-
- if ($this->showTimeZone($fields)) {
- $clock['time_zone'] = $this->makeTimeZoneValue($fields['tzone_timezone'], $fields['tzone_format']);
- }
-
- return $clock;
- }
-
- /**
- * @param array $fields Saved clock configuration.
- *
- * @return array
- */
- protected function configureHostTime(array $fields): array {
+ private function configureHostTime(): array {
+ $items = [];
$clock = ['is_enabled' => true];
- if ($this->getContext() === CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD) {
+ if ($this->hasInput('templateid')) {
if ($this->hasInput('dynamic_hostid')) {
$template_items = API::Item()->get([
'output' => ['key_'],
- 'itemids' => $fields['itemid'],
+ 'itemids' => $this->fields_values['itemid'],
'webitems' => true
]);
@@ -233,9 +189,6 @@ class CControllerWidgetClockView extends CControllerWidget {
'webitems' => true
]);
}
- else {
- $items = [];
- }
}
// Editing template dashboard?
else {
@@ -246,7 +199,7 @@ class CControllerWidgetClockView extends CControllerWidget {
$items = API::Item()->get([
'output' => ['itemid', 'value_type'],
'selectHosts' => ['name'],
- 'itemids' => $fields['itemid'],
+ 'itemids' => $this->fields_values['itemid'],
'webitems' => true
]);
}
@@ -267,7 +220,7 @@ class CControllerWidgetClockView extends CControllerWidget {
try {
$now = new DateTime($last_value['value']);
- if ($this->showDate($fields)) {
+ if ($this->showDate()) {
$clock['date'] = $now->format(ZBX_DATE);
}
@@ -275,7 +228,7 @@ class CControllerWidgetClockView extends CControllerWidget {
$clock['time'] = time() - ($last_value['clock'] - $now->getTimestamp());
- if ($this->showTimeZone($fields)) {
+ if ($this->showTimeZone()) {
$clock['time_zone'] = 'UTC'.$now->format('P');
}
}
@@ -295,39 +248,62 @@ class CControllerWidgetClockView extends CControllerWidget {
}
/**
+ * Create required clock field values both for analog and digital clock.
+ */
+ private function configureFields(): array {
+ $clock = [];
+
+ $date = $this->makeDateTimeFromTimeZone($this->fields_values['tzone_timezone']);
+
+ if ($date !== null) {
+ if ($this->showDate()) {
+ $clock['date'] = $date->format(ZBX_DATE);
+ }
+
+ if ($this->showTime()) {
+ $clock = array_merge($clock, $this->makeTimeFromDateTime($date));
+ }
+ }
+
+ if ($this->showTimeZone()) {
+ $clock['time_zone'] = $this->makeTimeZoneValue($this->fields_values['tzone_timezone'],
+ $this->fields_values['tzone_format']
+ );
+ }
+
+ return $clock;
+ }
+
+ /**
* Groups enabled field styles by field name (Date, Time, Time zone).
- *
- * @param array $fields Saved clock configuration.
- *
- * @return array
*/
- protected static function getFieldStyles(array $fields): array {
+ private function getFieldStyles(): array {
$cells = [];
- if ($fields['clock_type'] === WIDGET_CLOCK_TYPE_DIGITAL) {
- $show = $fields['show'];
+ if ($this->fields_values['clock_type'] === Widget::TYPE_DIGITAL) {
+ $show = $this->fields_values['show'];
- if (in_array(WIDGET_CLOCK_SHOW_DATE, $show)) {
+ if (in_array(Widget::SHOW_DATE, $show)) {
$cells['date'] = [
- 'size' => $fields['date_size'],
- 'bold' => ($fields['date_bold'] == 1),
- 'color' => $fields['date_color']
+ 'size' => $this->fields_values['date_size'],
+ 'bold' => ($this->fields_values['date_bold'] == 1),
+ 'color' => $this->fields_values['date_color']
];
}
- if (in_array(WIDGET_CLOCK_SHOW_TIME, $show)) {
+ if (in_array(Widget::SHOW_TIME, $show)) {
$cells['time'] = [
- 'size' => $fields['time_size'],
- 'bold' => ($fields['time_bold'] == 1),
- 'color' => $fields['time_color']
+ 'size' => $this->fields_values['time_size'],
+ 'bold' => ($this->fields_values['time_bold'] == 1),
+ 'color' => $this->fields_values['time_color']
];
}
- if (in_array(WIDGET_CLOCK_SHOW_TIMEZONE, $show)) {
+ if (in_array(Widget::SHOW_TIMEZONE, $show)) {
$cells['timezone'] = [
- 'size' => $fields['tzone_size'],
- 'bold' => ($fields['tzone_bold'] == 1),
- 'color' => $fields['tzone_color']
+ 'size' => $this->fields_values['tzone_size'],
+ 'bold' => ($this->fields_values['tzone_bold'] == 1),
+ 'color' => $this->fields_values['tzone_color']
];
}
}
diff --git a/ui/js/widgets/class.widget.clock.js b/ui/widgets/clock/assets/js/class.widget.js
index 5c27ab4c20a..e93d59040ff 100644..100755
--- a/ui/js/widgets/class.widget.clock.js
+++ b/ui/widgets/clock/assets/js/class.widget.js
@@ -258,4 +258,8 @@ class CWidgetClock extends CWidget {
clock_time_zone.textContent = timezone_text;
}
+
+ _hasPadding() {
+ return this._fields.clock_type === undefined || this._fields.clock_type == CWidgetClock.TYPE_ANALOG;
+ }
}
diff --git a/ui/widgets/clock/includes/WidgetForm.php b/ui/widgets/clock/includes/WidgetForm.php
new file mode 100755
index 00000000000..ac94bea7d6b
--- /dev/null
+++ b/ui/widgets/clock/includes/WidgetForm.php
@@ -0,0 +1,142 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\Clock\Includes;
+
+use Zabbix\Widgets\{
+ CWidgetField,
+ CWidgetForm
+};
+
+use Zabbix\Widgets\Fields\{
+ CWidgetFieldCheckBox,
+ CWidgetFieldCheckBoxList,
+ CWidgetFieldColor,
+ CWidgetFieldIntegerBox,
+ CWidgetFieldMultiSelectItem,
+ CWidgetFieldRadioButtonList,
+ CWidgetFieldSelect,
+ CWidgetFieldTimeZone
+};
+
+use Widgets\Clock\Widget;
+
+/**
+ * Clock widget form.
+ */
+class WidgetForm extends CWidgetForm {
+
+ private const SIZE_PERCENT_MIN = 1;
+ private const SIZE_PERCENT_MAX = 100;
+
+ private const DEFAULT_DATE_SIZE = 20;
+ private const DEFAULT_TIME_SIZE = 30;
+ private const DEFAULT_TIMEZONE_SIZE = 20;
+
+ public function addFields(): self {
+ $time_type = array_key_exists('time_type', $this->values) ? $this->values['time_type'] : null;
+
+ return $this
+ ->addField(
+ (new CWidgetFieldSelect('time_type', _('Time type'), [
+ TIME_TYPE_LOCAL => _('Local time'),
+ TIME_TYPE_SERVER => _('Server time'),
+ TIME_TYPE_HOST => _('Host time')
+ ]))->setDefault(TIME_TYPE_LOCAL)
+ )
+ ->addField($time_type == TIME_TYPE_HOST
+ ? (new CWidgetFieldMultiSelectItem('itemid', _('Item'), $this->templateid))
+ ->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
+ ->setMultiple(false)
+ : null
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('clock_type', _('Clock type'), [
+ Widget::TYPE_ANALOG => _('Analog'),
+ Widget::TYPE_DIGITAL => _('Digital')
+ ]))->setDefault(Widget::TYPE_ANALOG)
+ )
+ ->addField(
+ (new CWidgetFieldCheckBoxList('show', _('Show'), [
+ Widget::SHOW_DATE => _('Date'),
+ Widget::SHOW_TIME => _('Time'),
+ Widget::SHOW_TIMEZONE => _('Time zone')
+ ]))
+ ->setDefault([Widget::SHOW_TIME])
+ ->setFlags(CWidgetField::FLAG_LABEL_ASTERISK)
+ )
+ ->addField(
+ new CWidgetFieldCheckBox('adv_conf', _('Advanced configuration'))
+ )
+ ->addField(
+ (new CWidgetFieldColor('bg_color', _('Background color')))->allowInherited()
+ )
+ ->addField(
+ (new CWidgetFieldIntegerBox('date_size', _('Size'), self::SIZE_PERCENT_MIN, self::SIZE_PERCENT_MAX))
+ ->setDefault(self::DEFAULT_DATE_SIZE)
+ )
+ ->addField(
+ new CWidgetFieldCheckBox('date_bold', _('Bold'))
+ )
+ ->addField(
+ (new CWidgetFieldColor('date_color', _('Color')))->allowInherited()
+ )
+ ->addField(
+ (new CWidgetFieldIntegerBox('time_size', _('Size'), self::SIZE_PERCENT_MIN, self::SIZE_PERCENT_MAX))
+ ->setDefault(self::DEFAULT_TIME_SIZE)
+ )
+ ->addField(
+ new CWidgetFieldCheckBox('time_bold', _('Bold'))
+ )
+ ->addField(
+ (new CWidgetFieldColor('time_color', _('Color')))->allowInherited()
+ )
+ ->addField(
+ (new CWidgetFieldCheckBox('time_sec', _('Seconds')))->setDefault(1)
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('time_format', _('Format'), [
+ Widget::HOUR_24 => _('24-hour'),
+ Widget::HOUR_12 => _('12-hour')
+ ]))->setDefault(Widget::HOUR_24)
+ )
+ ->addField(
+ (new CWidgetFieldIntegerBox('tzone_size', _('Size'), self::SIZE_PERCENT_MIN, self::SIZE_PERCENT_MAX))
+ ->setDefault(self::DEFAULT_TIMEZONE_SIZE)
+ )
+ ->addField(
+ new CWidgetFieldCheckBox('tzone_bold', _('Bold'))
+ )
+ ->addField(
+ (new CWidgetFieldColor('tzone_color', _('Color')))->allowInherited()
+ )
+ ->addField(
+ (new CWidgetFieldTimeZone('tzone_timezone', _('Time zone')))
+ ->setDefault($time_type == TIME_TYPE_LOCAL ? TIMEZONE_DEFAULT_LOCAL : ZBX_DEFAULT_TIMEZONE)
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('tzone_format', _('Format'), [
+ Widget::TIMEZONE_SHORT => _('Short'),
+ Widget::TIMEZONE_FULL => _('Full')
+ ]))->setDefault(Widget::TIMEZONE_SHORT)
+ );
+ }
+}
diff --git a/ui/widgets/clock/manifest.json b/ui/widgets/clock/manifest.json
new file mode 100755
index 00000000000..9bd304f5c83
--- /dev/null
+++ b/ui/widgets/clock/manifest.json
@@ -0,0 +1,21 @@
+{
+ "manifest_version": 2.0,
+ "id": "clock",
+ "type": "widget",
+ "name": "Clock",
+ "namespace": "Clock",
+ "version": "1.0",
+ "author": "Zabbix SIA",
+ "widget": {
+ "template_support": true,
+ "size": {
+ "width": 4,
+ "height": 3
+ },
+ "js_class": "CWidgetClock",
+ "refresh_rate": 900
+ },
+ "assets": {
+ "js": ["class.widget.js"]
+ }
+}
diff --git a/ui/widgets/clock/views/widget.edit.js.php b/ui/widgets/clock/views/widget.edit.js.php
new file mode 100755
index 00000000000..d6f548906b8
--- /dev/null
+++ b/ui/widgets/clock/views/widget.edit.js.php
@@ -0,0 +1,105 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Widgets\Clock\Widget;
+
+?>
+
+window.widget_clock_form = new class {
+
+ init() {
+ this._form = document.getElementById('widget-dialogue-form');
+ this._time_type = document.getElementById('time_type');
+ this._clock_type = document.getElementById('clock_type');
+
+ this._show_date = document.getElementById('show_1');
+ this._show_time = document.getElementById('show_2');
+ this._show_tzone = document.getElementById('show_3');
+
+ this._advanced_configuration = document.getElementById('adv_conf');
+
+ for (const colorpicker of this._form.querySelectorAll('.<?= ZBX_STYLE_COLOR_PICKER ?> input')) {
+ $(colorpicker).colorpicker({
+ appendTo: '.overlay-dialogue-body',
+ use_default: true,
+ onUpdate: window.setIndicatorColor
+ });
+ }
+
+ this._time_type.addEventListener('change', () => {
+ ZABBIX.Dashboard.reloadWidgetProperties();
+ this.updateForm();
+ });
+
+ for (const checkbox of this._clock_type.querySelectorAll('input')) {
+ checkbox.addEventListener('change', () => this.updateForm());
+ }
+
+ const show = [this._show_date, this._show_time, this._show_tzone];
+
+ for (const checkbox of show) {
+ checkbox.addEventListener('change', (e) => {
+ if (show.filter((checkbox) => checkbox.checked).length > 0) {
+ this.updateForm();
+ }
+ else {
+ e.target.checked = true;
+ }
+ });
+ }
+
+ this._advanced_configuration.addEventListener('change', () => this.updateForm());
+
+ this.updateForm();
+ }
+
+ updateForm() {
+ const is_digital = this._clock_type.querySelector('input:checked').value == <?= Widget::TYPE_DIGITAL ?>;
+
+ const show_date_row = is_digital && this._advanced_configuration.checked && this._show_date.checked;
+ const show_time_row = is_digital && this._advanced_configuration.checked && this._show_time.checked;
+ const show_tzone_row = is_digital && this._advanced_configuration.checked && this._show_tzone.checked;
+
+ for (const element of this._form.querySelectorAll('.js-row-show, .js-row-adv-conf')) {
+ element.style.display = is_digital ? '' : 'none';
+ }
+
+ for (const element of this._form.querySelectorAll('.js-row-bg-color')) {
+ element.style.display = is_digital && this._advanced_configuration.checked ? '' : 'none';
+ }
+
+ for (const element of this._form.querySelectorAll('.fields-group-date')) {
+ element.style.display = show_date_row ? '' : 'none';
+ }
+
+ for (const element of this._form.querySelectorAll('.fields-group-time')) {
+ element.style.display = show_time_row ? '' : 'none';
+ }
+
+ for (const element of this._form.querySelectorAll('.fields-group-tzone')) {
+ element.style.display = show_tzone_row ? '' : 'none';
+ }
+
+ for (const element of this._form.querySelectorAll('.field-tzone-timezone, .field-tzone-format')) {
+ element.style.display = this._time_type.value != <?= TIME_TYPE_HOST ?> ? '' : 'none';
+ }
+ }
+};
diff --git a/ui/widgets/clock/views/widget.edit.php b/ui/widgets/clock/views/widget.edit.php
new file mode 100755
index 00000000000..bc782d0cb08
--- /dev/null
+++ b/ui/widgets/clock/views/widget.edit.php
@@ -0,0 +1,130 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+/**
+ * Clock widget form view.
+ *
+ * @var CView $this
+ * @var array $data
+ */
+
+$form = (new CWidgetFormView($data));
+
+$form
+ ->addField(
+ new CWidgetFieldSelectView($data['fields']['time_type'])
+ )
+ ->addField(array_key_exists('itemid', $data['fields'])
+ ? new CWidgetFieldMultiSelectItemView($data['fields']['itemid'], $data['captions']['ms']['items']['itemid'])
+ : null
+ )
+ ->addField(
+ new CWidgetFieldRadioButtonListView($data['fields']['clock_type'])
+ )
+ ->addField(
+ new CWidgetFieldCheckBoxListView($data['fields']['show']),
+ 'js-row-show'
+ )
+ ->addField(
+ new CWidgetFieldCheckBoxView($data['fields']['adv_conf']),
+ 'js-row-adv-conf'
+ )
+ ->addField(
+ new CWidgetFieldColorView($data['fields']['bg_color']),
+ 'js-row-bg-color'
+ )
+ ->addFieldsGroup(_('Date'), getDateFieldsGroupViews($form, $data['fields']), 'fields-group-date')
+ ->addFieldsGroup(_('Time'), getTimeFieldsGroupViews($form, $data['fields']), 'fields-group-time')
+ ->addFieldsGroup(_('Time zone'), getTimeZoneFieldsGroupViews($form, $data['fields']), 'fields-group-tzone')
+ ->includeJsFile('widget.edit.js.php')
+ ->addJavaScript('widget_clock_form.init();')
+ ->show();
+
+function getDateFieldsGroupViews(CWidgetFormView $form, array $fields): array {
+ $date_size = new CWidgetFieldIntegerBoxView($fields['date_size']);
+ $date_color = new CWidgetFieldColorView($fields['date_color']);
+
+ return [
+ $form->makeCustomField($date_size, [
+ $date_size->getLabel(),
+ (new CFormField([$date_size->getView(), '%']))->addClass('field-size')
+ ]),
+
+ new CWidgetFieldCheckBoxView($fields['date_bold']),
+
+ $form->makeCustomField($date_color, [
+ $date_color->getLabel()->addClass('offset-3'),
+ new CFormField($date_color->getView())
+ ])
+ ];
+}
+
+function getTimeFieldsGroupViews(CWidgetFormView $form, array $fields): array {
+ $time_size = new CWidgetFieldIntegerBoxView($fields['time_size']);
+ $time_color = new CWidgetFieldColorView($fields['time_color']);
+ $time_format = new CWidgetFieldRadioButtonListView($fields['time_format']);
+
+ return [
+ $form->makeCustomField($time_size, [
+ $time_size->getLabel(),
+ (new CFormField([$time_size->getView(), '%']))->addClass('field-size')
+ ]),
+
+ new CWidgetFieldCheckBoxView($fields['time_bold']),
+
+ $form->makeCustomField($time_color, [
+ $time_color->getLabel()->addClass('offset-3'),
+ new CFormField($time_color->getView())
+ ]),
+
+ new CWidgetFieldCheckBoxView($fields['time_sec']),
+
+ $form->makeCustomField($time_format, [
+ $time_format->getLabel(),
+ (new CFormField($time_format->getView()))->addClass('field-format')
+ ])
+ ];
+}
+
+function getTimeZoneFieldsGroupViews(CWidgetFormView $form, array $fields): array {
+ $tzone_size = new CWidgetFieldIntegerBoxView($fields['tzone_size']);
+ $tzone_color = new CWidgetFieldColorView($fields['tzone_color']);
+ $tzone_timezone = new CWidgetFieldTimeZoneView($fields['tzone_timezone']);
+ $tzone_format = new CWidgetFieldRadioButtonListView($fields['tzone_format']);
+
+ return [
+ $form->makeCustomField($tzone_size, [
+ $tzone_size->getLabel(),
+ (new CFormField([$tzone_size->getView(), '%']))->addClass('field-size')
+ ]),
+
+ new CWidgetFieldCheckBoxView($fields['tzone_bold']),
+
+ $form->makeCustomField($tzone_color, [
+ $tzone_color->getLabel()->addClass('offset-3'),
+ new CFormField($tzone_color->getView())
+ ]),
+
+ $form->makeCustomField($tzone_timezone, [], 'field-tzone-timezone'),
+
+ $form->makeCustomField($tzone_format, [], 'field-tzone-format')
+ ];
+}
diff --git a/ui/app/views/monitoring.widget.clock.view.php b/ui/widgets/clock/views/widget.view.php
index 89b4ef1fe98..482208fa6f6 100644..100755
--- a/ui/app/views/monitoring.widget.clock.view.php
+++ b/ui/widgets/clock/views/widget.view.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -20,20 +20,21 @@
/**
+ * Clock widget view.
+ *
* @var CView $this
* @var array $data
*/
-if ($data['clock_data']['critical_error'] !== null) {
- $item = (new CTableInfo())->setNoDataMessage($data['clock_data']['critical_error']);
+use Widgets\Clock\Widget;
+
+$view = new CWidgetView($data);
- $output = [
- 'name' => $data['name'],
- 'body' => $item->toString()
- ];
+if ($data['clock_data']['critical_error'] !== null) {
+ $body = (new CTableInfo())->setNoDataMessage($data['clock_data']['critical_error']);
}
else {
- if ($data['clock_data']['type'] == WIDGET_CLOCK_TYPE_DIGITAL) {
+ if ($data['clock_data']['type'] == Widget::TYPE_DIGITAL) {
$clock_data = $data['clock_data'];
$rows = [];
@@ -43,17 +44,17 @@ else {
$div = new CDiv();
switch ($show) {
- case WIDGET_CLOCK_SHOW_DATE:
+ case Widget::SHOW_DATE:
$div->addClass('clock-date');
$styles = $data['styles']['date'];
break;
- case WIDGET_CLOCK_SHOW_TIME:
+ case Widget::SHOW_TIME:
$div->addClass('clock-time');
$styles = $data['styles']['time'];
break;
- case WIDGET_CLOCK_SHOW_TIMEZONE:
+ case Widget::SHOW_TIMEZONE:
$div->addClass('clock-time-zone');
$styles = $data['styles']['timezone'];
break;
@@ -83,9 +84,7 @@ else {
->addClass('clock-disabled');
}
- $body = (new CDiv($rows))
- ->addClass('dashboard-widget-clock')
- ->addClass('clock-digital');
+ $body = (new CDiv($rows))->addClass('clock-digital');
if ($clock_data['bg_color'] !== '') {
$body->addStyle('background-color: #'.$clock_data['bg_color']);
@@ -95,22 +94,9 @@ else {
$body = (new CClock())->setEnabled($data['clock_data']['is_enabled']);
}
- $output = [
- 'name' => $data['name'],
- 'body' => $body->toString(),
- 'clock_data' => $data['clock_data']
- ];
-}
-
-if ($messages = get_and_clear_messages()) {
- $output['messages'] = array_column($messages, 'message');
-}
-
-if ($data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
- CProfiler::getInstance()->stop();
- $output['debug'] = CProfiler::getInstance()
- ->make()
- ->toString();
+ $view->setVar('clock_data', $data['clock_data']);
}
-echo json_encode($output);
+$view
+ ->addItem($body)
+ ->show();
diff --git a/ui/widgets/dataover/Widget.php b/ui/widgets/dataover/Widget.php
new file mode 100755
index 00000000000..f0805d55f12
--- /dev/null
+++ b/ui/widgets/dataover/Widget.php
@@ -0,0 +1,35 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\DataOver;
+
+use Zabbix\Core\CWidget;
+
+class Widget extends CWidget {
+
+ public function getDefaultName(): string {
+ return _('Data overview');
+ }
+
+ public function isDeprecated(): bool {
+ return true;
+ }
+}
diff --git a/ui/app/controllers/CControllerWidgetDataOverView.php b/ui/widgets/dataover/actions/WidgetView.php
index abc140e7f1b..29f96642b5c 100644
--- a/ui/app/controllers/CControllerWidgetDataOverView.php
+++ b/ui/widgets/dataover/actions/WidgetView.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,31 +19,24 @@
**/
-class CControllerWidgetDataOverView extends CControllerWidget {
+namespace Widgets\DataOver\Actions;
- public function __construct() {
- parent::__construct();
+use CControllerDashboardWidgetView,
+ CControllerResponseData;
- $this->setType(WIDGET_DATA_OVER);
- $this->setValidationRules([
- 'name' => 'string',
- 'fields' => 'json'
- ]);
- }
-
- protected function doAction() {
- $fields = $this->getForm()->getFieldsData();
+class WidgetView extends CControllerDashboardWidgetView {
- $groupids = $fields['groupids'] ? getSubGroups($fields['groupids']) : null;
- $hostids = $fields['hostids'] ? $fields['hostids'] : null;
+ protected function doAction(): void {
+ $groupids = $this->fields_values['groupids'] ? getSubGroups($this->fields_values['groupids']) : null;
+ $hostids = $this->fields_values['hostids'] ?: null;
- [$items, $hosts, $has_hidden_data] = getDataOverview($groupids, $hostids, $fields);
+ [$items, $hosts, $has_hidden_data] = getDataOverview($groupids, $hostids, $this->fields_values);
$this->setResponse(new CControllerResponseData([
- 'name' => $this->getInput('name', $this->getDefaultName()),
- 'groupids' => getSubGroups($fields['groupids']),
- 'show_suppressed' => $fields['show_suppressed'],
- 'style' => $fields['style'],
+ 'name' => $this->getInput('name', $this->widget->getDefaultName()),
+ 'groupids' => getSubGroups($this->fields_values['groupids']),
+ 'show_suppressed' => $this->fields_values['show_suppressed'],
+ 'style' => $this->fields_values['style'],
'items' => $items,
'hosts' => $hosts,
'has_hidden_data' => $has_hidden_data,
diff --git a/ui/widgets/dataover/includes/WidgetForm.php b/ui/widgets/dataover/includes/WidgetForm.php
new file mode 100644
index 00000000000..a0b7556bd83
--- /dev/null
+++ b/ui/widgets/dataover/includes/WidgetForm.php
@@ -0,0 +1,66 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\DataOver\Includes;
+
+use Zabbix\Widgets\CWidgetForm;
+
+use Zabbix\Widgets\Fields\{
+ CWidgetFieldCheckBox,
+ CWidgetFieldMultiSelectGroup,
+ CWidgetFieldMultiSelectHost,
+ CWidgetFieldRadioButtonList,
+ CWidgetFieldTags
+};
+
+/**
+ * Data overview widget form.
+ */
+class WidgetForm extends CWidgetForm {
+
+ public function addFields(): self {
+ return $this
+ ->addField(
+ new CWidgetFieldMultiSelectGroup('groupids', _('Host groups'))
+ )
+ ->addField(
+ new CWidgetFieldMultiSelectHost('hostids', _('Hosts'))
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('evaltype', _('Tags'), [
+ TAG_EVAL_TYPE_AND_OR => _('And/Or'),
+ TAG_EVAL_TYPE_OR => _('Or')
+ ]))->setDefault(TAG_EVAL_TYPE_AND_OR)
+ )
+ ->addField(
+ new CWidgetFieldTags('tags')
+ )
+ ->addField(
+ new CWidgetFieldCheckBox('show_suppressed', _('Show suppressed problems'))
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('style', _('Hosts location'), [
+ STYLE_LEFT => _('Left'),
+ STYLE_TOP => _('Top')
+ ]))->setDefault(STYLE_LEFT)
+ );
+ }
+}
diff --git a/ui/widgets/dataover/manifest.json b/ui/widgets/dataover/manifest.json
new file mode 100755
index 00000000000..2d52fda7364
--- /dev/null
+++ b/ui/widgets/dataover/manifest.json
@@ -0,0 +1,9 @@
+{
+ "manifest_version": 2.0,
+ "id": "dataover",
+ "type": "widget",
+ "name": "Data overview",
+ "namespace": "DataOver",
+ "version": "1.0",
+ "author": "Zabbix SIA"
+}
diff --git a/ui/widgets/dataover/views/widget.edit.php b/ui/widgets/dataover/views/widget.edit.php
new file mode 100755
index 00000000000..0e7acc85ecc
--- /dev/null
+++ b/ui/widgets/dataover/views/widget.edit.php
@@ -0,0 +1,51 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+/**
+ * Data overview widget form view.
+ *
+ * @var CView $this
+ * @var array $data
+ */
+
+$groupids = new CWidgetFieldMultiSelectGroupView($data['fields']['groupids'],
+ $data['captions']['ms']['groups']['groupids']
+);
+
+(new CWidgetFormView($data))
+ ->addField($groupids)
+ ->addField(
+ (new CWidgetFieldMultiSelectHostView($data['fields']['hostids'], $data['captions']['ms']['hosts']['hostids']))
+ ->setFilterPreselect(['id' => $groupids->getId(), 'submit_as' => 'groupid'])
+ )
+ ->addField(
+ new CWidgetFieldRadioButtonListView($data['fields']['evaltype'])
+ )
+ ->addField(
+ new CWidgetFieldTagsView($data['fields']['tags'])
+ )
+ ->addField(
+ new CWidgetFieldCheckBoxView($data['fields']['show_suppressed'])
+ )
+ ->addField(
+ new CWidgetFieldRadioButtonListView($data['fields']['style'])
+ )
+ ->show();
diff --git a/ui/widgets/dataover/views/widget.view.php b/ui/widgets/dataover/views/widget.view.php
new file mode 100644
index 00000000000..c9c3cb60eab
--- /dev/null
+++ b/ui/widgets/dataover/views/widget.view.php
@@ -0,0 +1,34 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+/**
+ * Data overview widget view.
+ *
+ * @var CView $this
+ * @var array $data
+ */
+
+(new CWidgetView($data))
+ ->addItem($data['style'] == STYLE_TOP
+ ? (new CPartial('dataoverview.table.top', $data))->getOutput()
+ : (new CPartial('dataoverview.table.left', $data))->getOutput()
+ )
+ ->show();
diff --git a/ui/widgets/discovery/Widget.php b/ui/widgets/discovery/Widget.php
new file mode 100755
index 00000000000..e51d9b66a23
--- /dev/null
+++ b/ui/widgets/discovery/Widget.php
@@ -0,0 +1,31 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\Discovery;
+
+use Zabbix\Core\CWidget;
+
+class Widget extends CWidget {
+
+ public function getDefaultName(): string {
+ return _('Discovery status');
+ }
+}
diff --git a/ui/app/controllers/CControllerWidgetDiscoveryView.php b/ui/widgets/discovery/actions/WidgetView.php
index 92e30c38eb9..58dad250854 100644
--- a/ui/app/controllers/CControllerWidgetDiscoveryView.php
+++ b/ui/widgets/discovery/actions/WidgetView.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,21 +19,18 @@
**/
-require_once dirname(__FILE__).'/../../include/blocks.inc.php';
+namespace Widgets\Discovery\Actions;
-class CControllerWidgetDiscoveryView extends CControllerWidget {
+use API,
+ CArrayHelper,
+ CControllerDashboardWidgetView,
+ CControllerResponseData,
+ CRoleHelper,
+ CWebUser;
- public function __construct() {
- parent::__construct();
+class WidgetView extends CControllerDashboardWidgetView {
- $this->setType(WIDGET_DISCOVERY);
- $this->setValidationRules([
- 'name' => 'string',
- 'fields' => 'json'
- ]);
- }
-
- protected function doAction() {
+ protected function doAction(): void {
if ($this->getUserType() >= USER_TYPE_ZABBIX_ADMIN) {
$drules = API::DRule()->get([
'output' => ['druleid', 'name'],
@@ -65,7 +62,7 @@ class CControllerWidgetDiscoveryView extends CControllerWidget {
}
$this->setResponse(new CControllerResponseData([
- 'name' => $this->getInput('name', $this->getDefaultName()),
+ 'name' => $this->getInput('name', $this->widget->getDefaultName()),
'drules' => $drules,
'error' => $error,
'user' => [
diff --git a/ui/widgets/discovery/manifest.json b/ui/widgets/discovery/manifest.json
new file mode 100755
index 00000000000..ccd3eef7e4c
--- /dev/null
+++ b/ui/widgets/discovery/manifest.json
@@ -0,0 +1,15 @@
+{
+ "manifest_version": 2.0,
+ "id": "discovery",
+ "type": "widget",
+ "name": "Discovery status",
+ "namespace": "Discovery",
+ "version": "1.0",
+ "author": "Zabbix SIA",
+ "widget": {
+ "size": {
+ "width": 6,
+ "height": 3
+ }
+ }
+}
diff --git a/ui/app/views/monitoring.widget.discovery.view.php b/ui/widgets/discovery/views/widget.view.php
index 93946fb6e59..e6d825dce63 100644
--- a/ui/app/views/monitoring.widget.discovery.view.php
+++ b/ui/widgets/discovery/views/widget.view.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -20,6 +20,8 @@
/**
+ * Discovery status widget view.
+ *
* @var CView $this
* @var array $data
*/
@@ -45,24 +47,12 @@ else {
->setArgument('filter_druleids', [$drule['druleid']])
)
: $drule['name'],
- ($drule['up'] != 0) ? (new CSpan($drule['up']))->addClass(ZBX_STYLE_GREEN) : '',
- ($drule['down'] != 0) ? (new CSpan($drule['down']))->addClass(ZBX_STYLE_RED) : ''
+ $drule['up'] != 0 ? (new CSpan($drule['up']))->addClass(ZBX_STYLE_GREEN) : '',
+ $drule['down'] != 0 ? (new CSpan($drule['down']))->addClass(ZBX_STYLE_RED) : ''
]);
}
}
-$output = [
- 'name' => $data['name'],
- 'body' => $table->toString()
-];
-
-if ($messages = get_and_clear_messages()) {
- $output['messages'] = array_column($messages, 'message');
-}
-
-if ($data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
- CProfiler::getInstance()->stop();
- $output['debug'] = CProfiler::getInstance()->make()->toString();
-}
-
-echo json_encode($output);
+(new CWidgetView($data))
+ ->addItem($table)
+ ->show();
diff --git a/ui/widgets/favgraphs/Widget.php b/ui/widgets/favgraphs/Widget.php
new file mode 100755
index 00000000000..c27391cd799
--- /dev/null
+++ b/ui/widgets/favgraphs/Widget.php
@@ -0,0 +1,31 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\FavGraphs;
+
+use Zabbix\Core\CWidget;
+
+class Widget extends CWidget {
+
+ public function getDefaultName(): string {
+ return _('Favorite graphs');
+ }
+}
diff --git a/ui/app/controllers/CControllerWidgetFavGraphsView.php b/ui/widgets/favgraphs/actions/WidgetView.php
index aafc056e4a1..458729dbbb3 100644
--- a/ui/app/controllers/CControllerWidgetFavGraphsView.php
+++ b/ui/widgets/favgraphs/actions/WidgetView.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,26 +19,23 @@
**/
-require_once dirname(__FILE__).'/../../include/blocks.inc.php';
+namespace Widgets\FavGraphs\Actions;
-class CControllerWidgetFavGraphsView extends CControllerWidget {
+use API,
+ CArrayHelper,
+ CControllerDashboardWidgetView,
+ CControllerResponseData,
+ CFavorite,
+ CRoleHelper;
- public function __construct() {
- parent::__construct();
+class WidgetView extends CControllerDashboardWidgetView {
- $this->setType(WIDGET_FAV_GRAPHS);
- $this->setValidationRules([
- 'name' => 'string',
- 'fields' => 'json'
- ]);
- }
-
- protected function doAction() {
+ protected function doAction(): void {
$graphs = [];
$itemids = [];
- foreach (CFavorite::get('web.favorite.graphids') as $favourite) {
- $itemids[$favourite['value']] = true;
+ foreach (CFavorite::get('web.favorite.graphids') as $favorite) {
+ $itemids[$favorite['value']] = true;
}
if ($itemids) {
@@ -60,7 +57,7 @@ class CControllerWidgetFavGraphsView extends CControllerWidget {
CArrayHelper::sort($graphs, ['label']);
$this->setResponse(new CControllerResponseData([
- 'name' => $this->getInput('name', $this->getDefaultName()),
+ 'name' => $this->getInput('name', $this->widget->getDefaultName()),
'graphs' => $graphs,
'user' => [
'debug_mode' => $this->getDebugMode()
diff --git a/ui/widgets/favgraphs/manifest.json b/ui/widgets/favgraphs/manifest.json
new file mode 100755
index 00000000000..18e13ed26d3
--- /dev/null
+++ b/ui/widgets/favgraphs/manifest.json
@@ -0,0 +1,16 @@
+{
+ "manifest_version": 2.0,
+ "id": "favgraphs",
+ "type": "widget",
+ "name": "Favorite graphs",
+ "namespace": "FavGraphs",
+ "version": "1.0",
+ "author": "Zabbix SIA",
+ "widget": {
+ "size": {
+ "width": 4,
+ "height": 3
+ },
+ "refresh_rate": 900
+ }
+}
diff --git a/ui/app/views/monitoring.widget.favgraphs.view.php b/ui/widgets/favgraphs/views/widget.view.php
index c3e3b1b7e6b..a9db81a4202 100644
--- a/ui/app/views/monitoring.widget.favgraphs.view.php
+++ b/ui/widgets/favgraphs/views/widget.view.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -20,7 +20,10 @@
/**
+ * Favorite graphs widget view.
+ *
* @var CView $this
+ * @var array $data
*/
$table = (new CTableInfo())->setNoDataMessage(_('No graphs added.'));
@@ -43,18 +46,6 @@ foreach ($data['graphs'] as $graph) {
]);
}
-$output = [
- 'name' => $data['name'],
- 'body' => $table->toString()
-];
-
-if ($messages = get_and_clear_messages()) {
- $output['messages'] = array_column($messages, 'message');
-}
-
-if ($data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
- CProfiler::getInstance()->stop();
- $output['debug'] = CProfiler::getInstance()->make()->toString();
-}
-
-echo json_encode($output);
+(new CWidgetView($data))
+ ->addItem($table)
+ ->show();
diff --git a/ui/widgets/favmaps/Widget.php b/ui/widgets/favmaps/Widget.php
new file mode 100755
index 00000000000..b1ddd4f5d80
--- /dev/null
+++ b/ui/widgets/favmaps/Widget.php
@@ -0,0 +1,31 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\FavMaps;
+
+use Zabbix\Core\CWidget;
+
+class Widget extends CWidget {
+
+ public function getDefaultName(): string {
+ return _('Favorite maps');
+ }
+}
diff --git a/ui/app/controllers/CControllerWidgetFavMapsView.php b/ui/widgets/favmaps/actions/WidgetView.php
index ca139c25f7f..3921422e912 100644
--- a/ui/app/controllers/CControllerWidgetFavMapsView.php
+++ b/ui/widgets/favmaps/actions/WidgetView.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,26 +19,23 @@
**/
-require_once dirname(__FILE__).'/../../include/blocks.inc.php';
+namespace Widgets\FavMaps\Actions;
-class CControllerWidgetFavMapsView extends CControllerWidget {
+use API,
+ CArrayHelper,
+ CControllerDashboardWidgetView,
+ CControllerResponseData,
+ CFavorite,
+ CRoleHelper;
- public function __construct() {
- parent::__construct();
+class WidgetView extends CControllerDashboardWidgetView {
- $this->setType(WIDGET_FAV_MAPS);
- $this->setValidationRules([
- 'name' => 'string',
- 'fields' => 'json'
- ]);
- }
-
- protected function doAction() {
+ protected function doAction(): void {
$maps = [];
$mapids = [];
- foreach (CFavorite::get('web.favorite.sysmapids') as $favourite) {
- $mapids[$favourite['value']] = true;
+ foreach (CFavorite::get('web.favorite.sysmapids') as $favorite) {
+ $mapids[$favorite['value']] = true;
}
if ($mapids) {
@@ -58,7 +55,7 @@ class CControllerWidgetFavMapsView extends CControllerWidget {
CArrayHelper::sort($maps, ['label']);
$this->setResponse(new CControllerResponseData([
- 'name' => $this->getInput('name', CWidgetConfig::getKnownWidgetTypes($this->getContext())[WIDGET_FAV_MAPS]),
+ 'name' => $this->getInput('name', $this->widget !== null ? $this->widget->getDefaultName() : ''),
'maps' => $maps,
'user' => [
'debug_mode' => $this->getDebugMode()
diff --git a/ui/widgets/favmaps/manifest.json b/ui/widgets/favmaps/manifest.json
new file mode 100755
index 00000000000..3ea016df3de
--- /dev/null
+++ b/ui/widgets/favmaps/manifest.json
@@ -0,0 +1,16 @@
+{
+ "manifest_version": 2.0,
+ "id": "favmaps",
+ "type": "widget",
+ "name": "Favorite maps",
+ "namespace": "FavMaps",
+ "version": "1.0",
+ "author": "Zabbix SIA",
+ "widget": {
+ "size": {
+ "width": 4,
+ "height": 3
+ },
+ "refresh_rate": 900
+ }
+}
diff --git a/ui/app/views/monitoring.widget.favmaps.view.php b/ui/widgets/favmaps/views/widget.view.php
index c0ddad1e7f4..21e940cd8ff 100644
--- a/ui/app/views/monitoring.widget.favmaps.view.php
+++ b/ui/widgets/favmaps/views/widget.view.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -20,7 +20,10 @@
/**
+ * Favorite maps widget view.
+ *
* @var CView $this
+ * @var array $data
*/
$table = (new CTableInfo())->setNoDataMessage(_('No maps added.'));
@@ -42,18 +45,6 @@ foreach ($data['maps'] as $map) {
]);
}
-$output = [
- 'name' => $data['name'],
- 'body' => $table->toString()
-];
-
-if ($messages = get_and_clear_messages()) {
- $output['messages'] = array_column($messages, 'message');
-}
-
-if ($data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
- CProfiler::getInstance()->stop();
- $output['debug'] = CProfiler::getInstance()->make()->toString();
-}
-
-echo json_encode($output);
+(new CWidgetView($data))
+ ->addItem($table)
+ ->show();
diff --git a/ui/widgets/geomap/Widget.php b/ui/widgets/geomap/Widget.php
new file mode 100755
index 00000000000..5a3c82ae937
--- /dev/null
+++ b/ui/widgets/geomap/Widget.php
@@ -0,0 +1,57 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\Geomap;
+
+use Zabbix\Core\CWidget;
+
+class Widget extends CWidget {
+
+ public function getDefaultName(): string {
+ return _('Geomap');
+ }
+
+ public function getTranslationStrings(): array {
+ return [
+ 'class.widget.js' => [
+ 'Actions' => _('Actions'),
+ 'Set this view as default' => _('Set this view as default'),
+ 'Reset to initial view' => _('Reset to initial view'),
+ 'No problems' => _('No problems'),
+ 'Not classified' => _('Not classified'),
+ 'Information' => _('Information'),
+ 'Warning' => _('Warning'),
+ 'Average' => _('Average'),
+ 'High' => _('High'),
+ 'Disaster' => _('Disaster'),
+ 'Host' => _('Host'),
+ 'D' => _x('D', 'abbreviation of severity level'),
+ 'H' => _x('H', 'abbreviation of severity level'),
+ 'A' => _x('A', 'abbreviation of severity level'),
+ 'W' => _x('W', 'abbreviation of severity level'),
+ 'I' => _x('I', 'abbreviation of severity level'),
+ 'N' => _x('N', 'abbreviation of severity level'),
+ 'Navigate to default view' => _('Navigate to default view'),
+ 'Navigate to initial view' => _('Navigate to initial view')
+ ]
+ ];
+ }
+}
diff --git a/ui/app/controllers/CControllerWidgetGeoMapView.php b/ui/widgets/geomap/actions/WidgetView.php
index a0264e2e9ea..895bd55d149 100644
--- a/ui/app/controllers/CControllerWidgetGeoMapView.php
+++ b/ui/widgets/geomap/actions/WidgetView.php
@@ -19,50 +19,45 @@
**/
-class CControllerWidgetGeoMapView extends CControllerWidget {
+namespace Widgets\Geomap\Actions;
- const NO_PROBLEMS_MARKER_COLOR = '#009900';
+use API,
+ CControllerDashboardWidgetView,
+ CControllerResponseData,
+ CGeomapCoordinatesParser,
+ CParser,
+ CProfile,
+ CSettingsHelper,
+ CSeverityHelper;
- /**
- * Widget id.
- *
- * @param string
- */
- protected $widgetid;
+class WidgetView extends CControllerDashboardWidgetView {
- /**
- * Widget fields.
- *
- * @param array
- */
- protected $fields;
+ private const NO_PROBLEMS_MARKER_COLOR = '#009900';
+
+ protected string $widgetid;
/**
* Global geomap configuration.
*
* @param array
*/
- protected $geomap_config;
+ protected array $geomap_config;
- public function __construct() {
- parent::__construct();
+ protected function init(): void {
+ parent::init();
- $this->setType(WIDGET_GEOMAP);
- $this->setValidationRules([
- 'name' => 'string',
+ $this->addValidationRules([
'initial_load' => 'in 0,1',
'widgetid' => 'db widget.widgetid',
- 'unique_id' => 'required|string',
- 'fields' => 'json'
+ 'unique_id' => 'required|string'
]);
}
- protected function doAction() {
+ protected function doAction(): void {
$this->widgetid = $this->getInput('widgetid', 0);
- $this->fields = $this->getForm()->getFieldsData();
$data = [
- 'name' => $this->getInput('name', $this->getDefaultName()),
+ 'name' => $this->getInput('name', $this->widget->getDefaultName()),
'hosts' => self::convertToRFC7946($this->getHosts()),
'user' => [
'debug_mode' => $this->getDebugMode()
@@ -83,39 +78,18 @@ class CControllerWidgetGeoMapView extends CControllerWidget {
}
/**
- * Create an array of problem severity colors.
- *
- * @static
- *
- * @return array
- */
- protected static function getSeveritySettings(): array {
- $severity_config = [
- -1 => self::NO_PROBLEMS_MARKER_COLOR
- ];
-
- for ($severity = TRIGGER_SEVERITY_NOT_CLASSIFIED; $severity < TRIGGER_SEVERITY_COUNT; $severity++) {
- $severity_config[$severity] = '#'.CSeverityHelper::getColor($severity);
- }
-
- return $severity_config;
- }
-
- /**
* Get hosts and their properties to show on the map as markers.
- *
- * @return array
*/
- protected function getHosts(): array {
- $filter_groupids = $this->fields['groupids'] ? getSubGroups($this->fields['groupids']) : null;
+ private function getHosts(): array {
+ $filter_groupids = $this->fields_values['groupids'] ? getSubGroups($this->fields_values['groupids']) : null;
$hosts = API::Host()->get([
'output' => ['hostid', 'name'],
'selectInventory' => ['location_lat', 'location_lon'],
'groupids' => $filter_groupids,
- 'hostids' => $this->fields['hostids'] ? $this->fields['hostids'] : null,
- 'evaltype' => $this->fields['evaltype'],
- 'tags' => $this->fields['tags'],
+ 'hostids' => $this->fields_values['hostids'] ?: null,
+ 'evaltype' => $this->fields_values['evaltype'],
+ 'tags' => $this->fields_values['tags'],
'filter' => [
'inventory_mode' => [HOST_INVENTORY_MANUAL, HOST_INVENTORY_AUTOMATIC]
],
@@ -123,7 +97,7 @@ class CControllerWidgetGeoMapView extends CControllerWidget {
'preservekeys' => true
]);
- $hosts = array_filter($hosts, function ($host) {
+ $hosts = array_filter($hosts, static function ($host) {
$lat = $host['inventory']['location_lat'];
$lng = $host['inventory']['location_lon'];
@@ -174,7 +148,7 @@ class CControllerWidgetGeoMapView extends CControllerWidget {
$severity_filter = ($severity_filter !== '') ? array_flip(explode(',', $severity_filter)) : [];
if ($severity_filter && count($severity_filter) != 7) {
- $hosts = array_filter($hosts, function ($host) use ($severity_filter, $problems_by_host) {
+ $hosts = array_filter($hosts, static function ($host) use ($severity_filter, $problems_by_host) {
return array_key_exists($host['hostid'], $problems_by_host)
? (bool) array_intersect_key(array_filter($problems_by_host[$host['hostid']]), $severity_filter)
: array_key_exists(-1, $severity_filter);
@@ -202,10 +176,8 @@ class CControllerWidgetGeoMapView extends CControllerWidget {
/**
* Get initial map center point, zoom level and coordinates to center when clicking on navigate home button.
- *
- * @return array
*/
- protected function getMapCenter(): array {
+ private function getMapCenter(): array {
$geoloc_parser = new CGeomapCoordinatesParser();
$home_coords = [];
$center = [];
@@ -217,9 +189,9 @@ class CControllerWidgetGeoMapView extends CControllerWidget {
$center['zoom'] = min($this->geomap_config['max_zoom'], $center['zoom']);
}
- if (array_key_exists('default_view', $this->fields)
- && $this->fields['default_view'] !== ''
- && $geoloc_parser->parse($this->fields['default_view']) == CParser::PARSE_SUCCESS) {
+ if (array_key_exists('default_view', $this->fields_values)
+ && $this->fields_values['default_view'] !== ''
+ && $geoloc_parser->parse($this->fields_values['default_view']) == CParser::PARSE_SUCCESS) {
$initial_view = $geoloc_parser->result;
if (array_key_exists('zoom', $initial_view)) {
@@ -242,56 +214,59 @@ class CControllerWidgetGeoMapView extends CControllerWidget {
];
return [
- 'center' => $center ? $center : $defaults,
+ 'center' => $center ?: $defaults,
'home_coords' => $home_coords
];
}
+ private function getUserProfileFilter(): array {
+ return [
+ 'severity' => CProfile::get('web.dashboard.widget.geomap.severity_filter', [], $this->widgetid)
+ ];
+ }
+
/**
* Get global map configuration.
- *
- * @static
- *
- * @return array
*/
- protected static function getMapConfig(): array {
+ private static function getMapConfig(): array {
if (CSettingsHelper::get(CSettingsHelper::GEOMAPS_TILE_PROVIDER) === '') {
- $config = [
+ return [
'tile_url' => CSettingsHelper::get(CSettingsHelper::GEOMAPS_TILE_URL),
'max_zoom' => CSettingsHelper::get(CSettingsHelper::GEOMAPS_MAX_ZOOM),
'attribution' => CSettingsHelper::get(CSettingsHelper::GEOMAPS_ATTRIBUTION)
];
}
- else {
- $tile_provider = getTileProviders()[CSettingsHelper::get(CSettingsHelper::GEOMAPS_TILE_PROVIDER)];
- $config = [
- 'tile_url' => $tile_provider['geomaps_tile_url'],
- 'max_zoom' => $tile_provider['geomaps_max_zoom'],
- 'attribution' => $tile_provider['geomaps_attribution']
- ];
- }
+ $tile_provider = getTileProviders()[CSettingsHelper::get(CSettingsHelper::GEOMAPS_TILE_PROVIDER)];
- return $config;
+ return [
+ 'tile_url' => $tile_provider['geomaps_tile_url'],
+ 'max_zoom' => $tile_provider['geomaps_max_zoom'],
+ 'attribution' => $tile_provider['geomaps_attribution']
+ ];
}
- protected function getUserProfileFilter(): array {
- return [
- 'severity' => CProfile::get('web.dashboard.widget.geomap.severity_filter', [], $this->widgetid)
+ /**
+ * Create an array of problem severity colors.
+ */
+ private static function getSeveritySettings(): array {
+ $severity_config = [
+ -1 => self::NO_PROBLEMS_MARKER_COLOR
];
+
+ for ($severity = TRIGGER_SEVERITY_NOT_CLASSIFIED; $severity < TRIGGER_SEVERITY_COUNT; $severity++) {
+ $severity_config[$severity] = '#'.CSeverityHelper::getColor($severity);
+ }
+
+ return $severity_config;
}
/**
* Convert array of hosts to valid GeoJSON (RFC7946) object.
- *
- * @static
- *
- * @param array $hosts
- *
- * @return array
*/
- protected static function convertToRFC7946(array $hosts) : array {
+ private static function convertToRFC7946(array $hosts) : array {
$geo_json = [];
+
foreach ($hosts as $host) {
$problems = array_filter($host['problems']);
$severities = array_keys($problems);
diff --git a/ui/js/widgets/class.widget.geomap.js b/ui/widgets/geomap/assets/js/class.widget.js
index 600093bc471..1d115d87f5a 100644..100755
--- a/ui/js/widgets/class.widget.geomap.js
+++ b/ui/widgets/geomap/assets/js/class.widget.js
@@ -46,10 +46,23 @@ class CWidgetGeoMap extends CWidget {
}
_processUpdateResponse(response) {
- super._processUpdateResponse(response);
+ if (this._initial_load) {
+ super._processUpdateResponse(response);
+ }
+ else {
+ let message_box = this._content_body.querySelector('output');
+
+ if (message_box !== null) {
+ message_box.remove();
+ }
- if ('geomap' in response) {
- if ('config' in response.geomap) {
+ if (response.messages !== undefined) {
+ this._content_body.prepend(makeMessageBox('bad', response.messages)[0]);
+ }
+ }
+
+ if (response.geomap !== undefined) {
+ if (response.geomap.config !== undefined) {
this._initMap(response.geomap.config);
}
@@ -59,30 +72,10 @@ class CWidgetGeoMap extends CWidget {
this._initial_load = false;
}
- updateProperties({name, view_mode, fields, configuration}) {
+ updateProperties({name, view_mode, fields}) {
this._initial_load = true;
- super.updateProperties({name, view_mode, fields, configuration});
- }
-
- _setContents({name, body, messages, info, debug}) {
- this._setHeaderName(name);
-
- if (this._initial_load) {
- this._content_body.innerHTML = '';
- }
-
- if (messages !== undefined) {
- this._content_body.insertAdjacentHTML('beforeend', messages);
- }
-
- if (this._initial_load) {
- this._content_body.insertAdjacentHTML('beforeend', body);
- }
-
- if (debug !== undefined) {
- this._content_body.insertAdjacentHTML('beforeend', debug);
- }
+ super.updateProperties({name, view_mode, fields});
}
_addMarkers(hosts) {
diff --git a/ui/widgets/geomap/includes/WidgetForm.php b/ui/widgets/geomap/includes/WidgetForm.php
new file mode 100644
index 00000000000..83add4ae233
--- /dev/null
+++ b/ui/widgets/geomap/includes/WidgetForm.php
@@ -0,0 +1,60 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\Geomap\Includes;
+
+use Zabbix\Widgets\CWidgetForm;
+
+use Zabbix\Widgets\Fields\{
+ CWidgetFieldLatLng,
+ CWidgetFieldMultiSelectGroup,
+ CWidgetFieldMultiSelectHost,
+ CWidgetFieldRadioButtonList,
+ CWidgetFieldTags
+};
+
+/**
+ * Geomap widget form.
+ */
+class WidgetForm extends CWidgetForm {
+
+ public function addFields(): self {
+ return $this
+ ->addField(
+ new CWidgetFieldMultiSelectGroup('groupids', _('Host groups'))
+ )
+ ->addField(
+ new CWidgetFieldMultiSelectHost('hostids', _('Hosts'))
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('evaltype', _('Tags'), [
+ TAG_EVAL_TYPE_AND_OR => _('And/Or'),
+ TAG_EVAL_TYPE_OR => _('Or')
+ ]))->setDefault(TAG_EVAL_TYPE_AND_OR)
+ )
+ ->addField(
+ new CWidgetFieldTags('tags')
+ )
+ ->addField(
+ new CWidgetFieldLatLng('default_view', _('Initial view'))
+ );
+ }
+}
diff --git a/ui/widgets/geomap/manifest.json b/ui/widgets/geomap/manifest.json
new file mode 100755
index 00000000000..0de69c9350a
--- /dev/null
+++ b/ui/widgets/geomap/manifest.json
@@ -0,0 +1,15 @@
+{
+ "manifest_version": 2.0,
+ "id": "geomap",
+ "type": "widget",
+ "name": "Geomap",
+ "namespace": "Geomap",
+ "version": "1.0",
+ "author": "Zabbix SIA",
+ "widget": {
+ "js_class": "CWidgetGeoMap"
+ },
+ "assets": {
+ "js": ["class.widget.js"]
+ }
+}
diff --git a/ui/widgets/geomap/views/widget.edit.php b/ui/widgets/geomap/views/widget.edit.php
new file mode 100755
index 00000000000..90f9a562fef
--- /dev/null
+++ b/ui/widgets/geomap/views/widget.edit.php
@@ -0,0 +1,48 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+/**
+ * Geomap widget form view.
+ *
+ * @var CView $this
+ * @var array $data
+ */
+
+$groupids = new CWidgetFieldMultiSelectGroupView($data['fields']['groupids'],
+ $data['captions']['ms']['groups']['groupids']
+);
+
+(new CWidgetFormView($data))
+ ->addField($groupids)
+ ->addField(
+ (new CWidgetFieldMultiSelectHostView($data['fields']['hostids'], $data['captions']['ms']['hosts']['hostids']))
+ ->setFilterPreselect(['id' => $groupids->getId(), 'submit_as' => 'groupid'])
+ )
+ ->addField(
+ new CWidgetFieldRadioButtonListView($data['fields']['evaltype'])
+ )
+ ->addField(
+ new CWidgetFieldTagsView($data['fields']['tags'])
+ )
+ ->addField(
+ (new CWidgetFieldLatLngView($data['fields']['default_view']))->setPlaceholder('40.6892494,-74.0466891')
+ )
+ ->show();
diff --git a/ui/widgets/geomap/views/widget.view.php b/ui/widgets/geomap/views/widget.view.php
new file mode 100644
index 00000000000..5d8775d6b5c
--- /dev/null
+++ b/ui/widgets/geomap/views/widget.view.php
@@ -0,0 +1,34 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+/**
+ * Geomap widget view.
+ *
+ * @var CView $this
+ * @var array $data
+ */
+
+(new CWidgetView($data))
+ ->addItem(
+ (new CDiv())->setId($data['unique_id'])
+ )
+ ->setVar('geomap', array_intersect_key($data, array_flip(['config', 'hosts'])))
+ ->show();
diff --git a/ui/widgets/graph/Widget.php b/ui/widgets/graph/Widget.php
new file mode 100755
index 00000000000..a0bdfbe9c52
--- /dev/null
+++ b/ui/widgets/graph/Widget.php
@@ -0,0 +1,40 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\Graph;
+
+use Zabbix\Core\CWidget;
+
+class Widget extends CWidget {
+
+ public function getDefaultName(): string {
+ return _('Graph (classic)');
+ }
+
+ public function getTranslationStrings(): array {
+ return [
+ 'class.widget.js' => [
+ 'Actions' => _s('Actions'),
+ 'Download image' => _s('Download image')
+ ]
+ ];
+ }
+}
diff --git a/ui/app/controllers/CControllerWidgetGraphView.php b/ui/widgets/graph/actions/WidgetView.php
index ea69a05caa7..e42e320df37 100644
--- a/ui/app/controllers/CControllerWidgetGraphView.php
+++ b/ui/widgets/graph/actions/WidgetView.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,25 +19,34 @@
**/
-class CControllerWidgetGraphView extends CControllerWidget {
+namespace Widgets\Graph\Actions;
- public function __construct() {
- parent::__construct();
+use API,
+ CControllerDashboardWidgetView,
+ CControllerResponseData,
+ CGraphDraw,
+ CMacrosResolverHelper,
+ CRoleHelper,
+ CUrl,
+ CWebUser;
- $this->setType(WIDGET_GRAPH);
- $this->setValidationRules([
- 'name' => 'string',
+use Zabbix\Core\CWidget;
+
+class WidgetView extends CControllerDashboardWidgetView {
+
+ protected function init(): void {
+ parent::init();
+
+ $this->addValidationRules([
'edit_mode' => 'in 0,1',
'dashboardid' => 'db dashboard.dashboardid',
- 'fields' => 'json',
'dynamic_hostid' => 'db hosts.hostid',
'content_width' => 'int32',
'content_height' => 'int32'
]);
}
- protected function doAction() {
- $fields = $this->getForm()->getFieldsData();
+ protected function doAction(): void {
$edit_mode = (int) $this->getInput('edit_mode', 0);
$width = (int) $this->getInput('content_width', 100);
@@ -48,18 +57,20 @@ class CControllerWidgetGraphView extends CControllerWidget {
$profileIdx = 'web.dashboard.filter';
$profileIdx2 = $this->getInput('dashboardid', 0);
$is_resource_available = true;
- $header_name = $this->getDefaultName();
+ $header_name = $this->widget->getDefaultName();
- if ($fields['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_GRAPH && $fields['graphid']) {
+ if ($this->fields_values['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_GRAPH && $this->fields_values['graphid']) {
$resource_type = SCREEN_RESOURCE_GRAPH;
- $resourceid = reset($fields['graphid']);
+ $resourceid = reset($this->fields_values['graphid']);
$graph_dims = getGraphDims($resourceid);
$graph_dims['graphHeight'] = $height;
$graph_dims['width'] = $width;
}
- elseif ($fields['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_SIMPLE_GRAPH && $fields['itemid']) {
+ elseif ($this->fields_values['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_SIMPLE_GRAPH
+ && $this->fields_values['itemid']) {
+
$resource_type = SCREEN_RESOURCE_SIMPLE_GRAPH;
- $resourceid = $fields['itemid'][0];
+ $resourceid = $this->fields_values['itemid'][0];
$graph_dims = getGraphDims();
$graph_dims['graphHeight'] = $height;
$graph_dims['width'] = $width;
@@ -68,7 +79,7 @@ class CControllerWidgetGraphView extends CControllerWidget {
$resource_type = null;
$graph_dims = getGraphDims();
}
- $graph_dims['shiftYtop'] = CLineGraphDraw::DEFAULT_TOP_BOTTOM_PADDING;
+ $graph_dims['shiftYtop'] = CGraphDraw::DEFAULT_TOP_BOTTOM_PADDING;
$time_control_data = [
'id' => '',
@@ -88,13 +99,13 @@ class CControllerWidgetGraphView extends CControllerWidget {
'profileIdx2' => $profileIdx2
];
- $is_template_dashboard = ($this->getContext() === CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD);
- $is_dynamic_item = ($is_template_dashboard || $fields['dynamic'] == WIDGET_DYNAMIC_ITEM);
+ $is_template_dashboard = $this->hasInput('templateid');
+ $is_dynamic_item = ($is_template_dashboard || $this->fields_values['dynamic'] == CWidget::DYNAMIC_ITEM);
// Replace graph item by particular host item if dynamic items are used.
if ($is_dynamic_item && $dynamic_hostid != 0 && $resourceid) {
// Find same simple-graph item in selected $dynamic_hostid host.
- if ($fields['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_SIMPLE_GRAPH) {
+ if ($this->fields_values['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_SIMPLE_GRAPH) {
$src_items = API::Item()->get([
'output' => ['key_'],
'itemids' => $resourceid,
@@ -120,7 +131,7 @@ class CControllerWidgetGraphView extends CControllerWidget {
}
}
// Find requested host and change graph details.
- elseif ($fields['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_GRAPH) {
+ elseif ($this->fields_values['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_GRAPH) {
// get host
$hosts = API::Host()->get([
'output' => ['hostid', 'host', 'name'],
@@ -200,7 +211,7 @@ class CControllerWidgetGraphView extends CControllerWidget {
if (!$resourceid) {
$is_resource_available = false;
}
- elseif ($fields['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_SIMPLE_GRAPH) {
+ elseif ($this->fields_values['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_SIMPLE_GRAPH) {
$items = API::Item()->get([
'output' => ['name', 'key_', 'delay', 'hostid'],
'selectHosts' => ['name'],
@@ -214,7 +225,7 @@ class CControllerWidgetGraphView extends CControllerWidget {
$is_resource_available = false;
}
}
- elseif ($fields['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_GRAPH) {
+ elseif ($this->fields_values['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_GRAPH) {
// get graph, used below
$graph = API::Graph()->get([
'output' => API_OUTPUT_EXTEND,
@@ -232,7 +243,7 @@ class CControllerWidgetGraphView extends CControllerWidget {
if ($is_resource_available) {
// Build graph action and data source links.
- if ($fields['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_SIMPLE_GRAPH) {
+ if ($this->fields_values['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_SIMPLE_GRAPH) {
if (!$edit_mode) {
$time_control_data['loadSBox'] = 1;
}
@@ -242,26 +253,26 @@ class CControllerWidgetGraphView extends CControllerWidget {
->setArgument('itemids', [$resourceid])
->setArgument('width', $width)
->setArgument('height', $height)
- ->setArgument('legend', $fields['show_legend']);
+ ->setArgument('legend', $this->fields_values['show_legend']);
}
else {
$graph_src = new CUrl('chart3.php');
}
$graph_src
- ->setArgument('from', '')
- ->setArgument('to', '');
+ ->setArgument('from')
+ ->setArgument('to');
$header_name = $is_template_dashboard
? $item['name']
: $item['hosts'][0]['name'].NAME_DELIMITER.$item['name'];
}
- elseif ($fields['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_GRAPH) {
+ elseif ($this->fields_values['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_GRAPH) {
$graph_src = '';
$prepend_host_name = $is_template_dashboard
? false
- : (count($graph['hosts']) == 1 || $is_dynamic_item && $dynamic_hostid != 0);
+ : count($graph['hosts']) == 1 || ($is_dynamic_item && $dynamic_hostid != 0);
$header_name = $prepend_host_name
? $graph['hosts'][0]['name'].NAME_DELIMITER.$graph['name']
@@ -320,9 +331,9 @@ class CControllerWidgetGraphView extends CControllerWidget {
$graph_src
->setArgument('width', $width)
->setArgument('height', $height)
- ->setArgument('legend', ($fields['show_legend'] && $graph['show_legend']) ? 1 : 0)
- ->setArgument('from', '')
- ->setArgument('to', '');
+ ->setArgument('legend', $this->fields_values['show_legend'] && $graph['show_legend'] ? 1 : 0)
+ ->setArgument('from')
+ ->setArgument('to');
}
$graph_src
@@ -340,7 +351,7 @@ class CControllerWidgetGraphView extends CControllerWidget {
$graph_url = null;
}
else {
- if ($fields['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_GRAPH) {
+ if ($this->fields_values['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_GRAPH) {
$has_host_graph = $is_dynamic_item && $dynamic_hostid != 0
? (bool) API::Graph()->get([
'output' => [],
@@ -359,8 +370,8 @@ class CControllerWidgetGraphView extends CControllerWidget {
->setArgument('filter_name', $graph['name'])
->setArgument('filter_show', GRAPH_FILTER_HOST)
->setArgument('filter_set', '1')
- ->setArgument('from', '')
- ->setArgument('to', '')
+ ->setArgument('from')
+ ->setArgument('to')
: null;
}
else {
@@ -371,8 +382,8 @@ class CControllerWidgetGraphView extends CControllerWidget {
$graph_url = $this->checkAccess(CRoleHelper::UI_MONITORING_LATEST_DATA)
? (new CUrl('history.php'))
->setArgument('itemids', [$resourceid])
- ->setArgument('from', '')
- ->setArgument('to', '')
+ ->setArgument('from')
+ ->setArgument('to')
: null;
}
}
diff --git a/ui/js/widgets/class.widget.graph.js b/ui/widgets/graph/assets/js/class.widget.js
index 0222248600c..22f077b0979 100644..100755
--- a/ui/js/widgets/class.widget.graph.js
+++ b/ui/widgets/graph/assets/js/class.widget.js
@@ -72,14 +72,14 @@ class CWidgetGraph extends CWidget {
}
}
- updateProperties({name, view_mode, fields, configuration}) {
+ updateProperties({name, view_mode, fields}) {
if (this._state === WIDGET_STATE_ACTIVE) {
this._stopUpdating(true);
}
this._is_graph_mode = false;
- super.updateProperties({name, view_mode, fields, configuration});
+ super.updateProperties({name, view_mode, fields});
}
setEditMode() {
@@ -229,4 +229,8 @@ class CWidgetGraph extends CWidget {
return menu;
}
+
+ _hasPadding() {
+ return true;
+ }
}
diff --git a/ui/widgets/graph/includes/WidgetForm.php b/ui/widgets/graph/includes/WidgetForm.php
new file mode 100644
index 00000000000..5b57cf414aa
--- /dev/null
+++ b/ui/widgets/graph/includes/WidgetForm.php
@@ -0,0 +1,84 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\Graph\Includes;
+
+use Zabbix\Widgets\{
+ CWidgetField,
+ CWidgetForm
+};
+
+use Zabbix\Widgets\Fields\{
+ CWidgetFieldCheckBox,
+ CWidgetFieldMultiSelectGraph,
+ CWidgetFieldMultiSelectItem,
+ CWidgetFieldRadioButtonList
+};
+
+/**
+ * Graph (classic) widget form.
+ */
+class WidgetForm extends CWidgetForm {
+
+ public function addFields(): self {
+ $this->addField(
+ (new CWidgetFieldRadioButtonList('source_type', _('Source'), [
+ ZBX_WIDGET_FIELD_RESOURCE_GRAPH => _('Graph'),
+ ZBX_WIDGET_FIELD_RESOURCE_SIMPLE_GRAPH => _('Simple graph')
+ ]))
+ ->setDefault(ZBX_WIDGET_FIELD_RESOURCE_GRAPH)
+ ->setAction('ZABBIX.Dashboard.reloadWidgetProperties()')
+ );
+
+ if (array_key_exists('source_type', $this->values)
+ && $this->values['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_SIMPLE_GRAPH) {
+
+ $field_item = (new CWidgetFieldMultiSelectItem('itemid', _('Item'), $this->templateid))
+ ->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
+ ->setMultiple(false)
+ ->setFilterParameter('numeric', true);
+
+ if ($this->templateid === null) {
+ $field_item->setFilterParameter('with_simple_graph_items', true);
+ }
+
+ $this->addField($field_item);
+ }
+ else {
+ $this->addField(
+ (new CWidgetFieldMultiSelectGraph('graphid', _('Graph'), $this->templateid))
+ ->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
+ ->setMultiple(false)
+ );
+ }
+
+ $this
+ ->addField(
+ (new CWidgetFieldCheckBox('show_legend', _('Show legend')))->setDefault(1)
+ )
+ ->addField($this->templateid === null
+ ? new CWidgetFieldCheckBox('dynamic', _('Enable host selection'))
+ : null
+ );
+
+ return $this;
+ }
+}
diff --git a/ui/widgets/graph/manifest.json b/ui/widgets/graph/manifest.json
new file mode 100755
index 00000000000..678aa28c550
--- /dev/null
+++ b/ui/widgets/graph/manifest.json
@@ -0,0 +1,17 @@
+{
+ "manifest_version": 2.0,
+ "id": "graph",
+ "type": "widget",
+ "name": "Graph (classic)",
+ "namespace": "Graph",
+ "version": "1.0",
+ "author": "Zabbix SIA",
+ "widget": {
+ "template_support": true,
+ "js_class": "CWidgetGraph",
+ "use_time_selector": true
+ },
+ "assets": {
+ "js": ["class.widget.js"]
+ }
+}
diff --git a/ui/include/classes/widgets/views/widget.actionlog.form.view.php b/ui/widgets/graph/views/widget.edit.php
index 06591ee02d0..b88316c64df 100644..100755
--- a/ui/include/classes/widgets/views/widget.actionlog.form.view.php
+++ b/ui/widgets/graph/views/widget.edit.php
@@ -20,35 +20,29 @@
/**
- * Action log widget form view.
+ * Graph (classic) widget form view.
*
* @var CView $this
* @var array $data
*/
-$fields = $data['dialogue']['fields'];
-
-$form = CWidgetHelper::createForm();
-
-$form_grid = CWidgetHelper::createFormGrid($data['dialogue']['name'], $data['dialogue']['type'],
- $data['dialogue']['view_mode'], $data['known_widget_types'],
- $data['templateid'] === null ? $fields['rf_rate'] : null
-);
-
-// Sort entries by.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['sort_triggers']),
- new CFormField(CWidgetHelper::getSelect($fields['sort_triggers']))
-]);
-
-// Show lines.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['show_lines']),
- new CFormField(CWidgetHelper::getIntegerBox($fields['show_lines']))
-]);
-
-$form->addItem($form_grid);
-
-return [
- 'form' => $form
-];
+(new CWidgetFormView($data))
+ ->addField(
+ new CWidgetFieldRadioButtonListView($data['fields']['source_type'])
+ )
+ ->addField(array_key_exists('graphid', $data['fields'])
+ ? new CWidgetFieldMultiSelectGraphView($data['fields']['graphid'], $data['captions']['ms']['graphs']['graphid'])
+ : null
+ )
+ ->addField(array_key_exists('itemid', $data['fields'])
+ ? new CWidgetFieldMultiSelectItemView($data['fields']['itemid'], $data['captions']['ms']['items']['itemid'])
+ : null
+ )
+ ->addField(
+ new CWidgetFieldCheckBoxView($data['fields']['show_legend'])
+ )
+ ->addField(array_key_exists('dynamic', $data['fields'])
+ ? new CWidgetFieldCheckBoxView($data['fields']['dynamic'])
+ : null
+ )
+ ->show();
diff --git a/ui/widgets/graph/views/widget.view.php b/ui/widgets/graph/views/widget.view.php
new file mode 100644
index 00000000000..5b77fa37c54
--- /dev/null
+++ b/ui/widgets/graph/views/widget.view.php
@@ -0,0 +1,49 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+/**
+ * Graph (classic) widget view.
+ *
+ * @var CView $this
+ * @var array $data
+ */
+
+$view = new CWidgetView($data);
+
+if ($data['is_resource_available']) {
+ $view
+ ->addItem(
+ (new CDiv())
+ ->addClass('flickerfreescreen')
+ ->addItem(
+ (new CLink(null, $data['widget']['graph_url'] ?? 'javascript:void(0)'))
+ ->addClass(ZBX_STYLE_DASHBOARD_WIDGET_GRAPH_LINK)
+ )
+ )
+ ->setVar('async_data', $data['widget']);
+}
+else {
+ $view->addItem(
+ (new CTableInfo())->setNoDataMessage(_('No permissions to referred object or it does not exist!'))
+ );
+}
+
+$view->show();
diff --git a/ui/widgets/graphprototype/Widget.php b/ui/widgets/graphprototype/Widget.php
new file mode 100755
index 00000000000..4c21e63d00b
--- /dev/null
+++ b/ui/widgets/graphprototype/Widget.php
@@ -0,0 +1,31 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\GraphPrototype;
+
+use Zabbix\Core\CWidget;
+
+class Widget extends CWidget {
+
+ public function getDefaultName(): string {
+ return _('Graph prototype');
+ }
+}
diff --git a/ui/app/controllers/CControllerWidgetIteratorGraphPrototypeView.php b/ui/widgets/graphprototype/actions/WidgetView.php
index 367d8120a2a..556e573c0f2 100644
--- a/ui/app/controllers/CControllerWidgetIteratorGraphPrototypeView.php
+++ b/ui/widgets/graphprototype/actions/WidgetView.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,28 +19,35 @@
**/
-class CControllerWidgetIteratorGraphPrototypeView extends CControllerWidgetIterator {
+namespace Widgets\GraphPrototype\Actions;
- public function __construct() {
- parent::__construct();
+use API,
+ APP,
+ CControllerResponseData,
+ CControllerWidgetIterator,
+ CTableInfo;
- $this->setType(WIDGET_GRAPH_PROTOTYPE);
- $this->setValidationRules([
- 'name' => 'string',
- 'fields' => 'json',
+use Zabbix\Core\CWidget;
+
+class WidgetView extends CControllerWidgetIterator {
+
+ protected const GRAPH_WIDGET_ID = 'graph';
+
+ protected function init(): void {
+ parent::init();
+
+ $this->addValidationRules([
'view_mode' => 'in '.implode(',', [ZBX_WIDGET_VIEW_MODE_NORMAL, ZBX_WIDGET_VIEW_MODE_HIDDEN_HEADER]),
'dynamic_hostid' => 'db hosts.hostid'
]);
}
- protected function doAction() {
- $fields = $this->getForm()->getFieldsData();
-
- if ($fields['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_GRAPH_PROTOTYPE) {
- $data = $this->doGraphPrototype($fields);
+ protected function doAction(): void {
+ if ($this->fields_values['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_GRAPH_PROTOTYPE) {
+ $data = $this->doGraphPrototype();
}
- elseif ($fields['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_SIMPLE_GRAPH_PROTOTYPE) {
- $data = $this->doSimpleGraphPrototype($fields);
+ elseif ($this->fields_values['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_SIMPLE_GRAPH_PROTOTYPE) {
+ $data = $this->doSimpleGraphPrototype();
}
else {
error(_('Page received incorrect data'));
@@ -50,25 +57,23 @@ class CControllerWidgetIteratorGraphPrototypeView extends CControllerWidgetItera
$data['error']['messages'] = array_column($messages, 'message');
}
- $this->setResponse(new CControllerResponseData(['main_block' => json_encode($data)]));
+ $this->setResponse(new CControllerResponseData(['main_block' => json_encode($data, JSON_THROW_ON_ERROR)]));
}
/**
* Get graph prototype widget data for graph prototype source.
*
- * @param array $fields Widget form fields data
- *
* @return array Dashboard response data
*/
- protected function doGraphPrototype(array $fields) {
+ protected function doGraphPrototype(): array {
$options = [
'output' => ['graphid', 'name'],
'selectHosts' => ['hostid', 'name'],
'selectDiscoveryRule' => ['hostid']
];
- $is_template_dashboard = ($this->getContext() === CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD);
- $is_dynamic_item = ($is_template_dashboard || $fields['dynamic'] == WIDGET_DYNAMIC_ITEM);
+ $is_template_dashboard = $this->hasInput('templateid');
+ $is_dynamic_item = ($is_template_dashboard || $this->fields_values['dynamic'] == CWidget::DYNAMIC_ITEM);
$dynamic_hostid = $this->getInput('dynamic_hostid', 0);
@@ -76,7 +81,7 @@ class CControllerWidgetIteratorGraphPrototypeView extends CControllerWidgetItera
// The key of the actual graph prototype selected on widget's edit form.
$graph_prototype = API::GraphPrototype()->get([
'output' => ['name'],
- 'graphids' => reset($fields['graphid'])
+ 'graphids' => reset($this->fields_values['graphid'])
]);
if ($graph_prototype) {
$graph_prototype = reset($graph_prototype);
@@ -91,7 +96,7 @@ class CControllerWidgetIteratorGraphPrototypeView extends CControllerWidgetItera
}
else {
// Just fetch the item prototype selected on widget's edit form.
- $options['graphids'] = reset($fields['graphid']);
+ $options['graphids'] = reset($this->fields_values['graphid']);
}
// Use this graph prototype as base for collecting created graphs.
@@ -121,7 +126,7 @@ class CControllerWidgetIteratorGraphPrototypeView extends CControllerWidgetItera
if ($graph['graphDiscovery']['parent_graphid'] === $graph_prototype['graphid']) {
$prepend_host_name = $is_template_dashboard
? false
- : (count($graph['hosts']) == 1 || $is_dynamic_item && $dynamic_hostid != 0);
+ : count($graph['hosts']) == 1 || ($is_dynamic_item && $dynamic_hostid != 0);
$graphs_collected[$graph['graphid']] = $prepend_host_name
? $graph['hosts'][0]['name'].NAME_DELIMITER.$graph['name']
@@ -140,21 +145,24 @@ class CControllerWidgetIteratorGraphPrototypeView extends CControllerWidgetItera
$children = [];
- foreach ($graphs_collected as $graphid => $name) {
- $child_fields = [
- 'source_type' => ZBX_WIDGET_FIELD_RESOURCE_GRAPH,
- 'graphid' => $graphid,
- 'show_legend' => $fields['show_legend']
- ];
-
- $children[] = [
- 'widgetid' => (string) $graphid,
- 'type' => WIDGET_GRAPH,
- 'name' => $name,
- 'fields' => $child_fields,
- 'configuration' => CWidgetConfig::getConfiguration(WIDGET_GRAPH, $fields, $this->getInput('view_mode')),
- 'defaults' => CWidgetConfig::getDefaults($this->getContext())[WIDGET_GRAPH]
- ];
+ $widget = APP::ModuleManager()->getModule(self::GRAPH_WIDGET_ID);
+
+ if ($widget !== null) {
+ foreach ($graphs_collected as $graphid => $name) {
+ $child_fields = [
+ 'source_type' => ZBX_WIDGET_FIELD_RESOURCE_GRAPH,
+ 'graphid' => $graphid,
+ 'show_legend' => $this->fields_values['show_legend']
+ ];
+
+ $children[] = [
+ 'widgetid' => (string) $graphid,
+ 'type' => self::GRAPH_WIDGET_ID,
+ 'name' => $name,
+ 'fields' => $child_fields,
+ 'defaults' => $widget->getDefaults()
+ ];
+ }
}
if ($this->hasInput('name')) {
@@ -179,20 +187,16 @@ class CControllerWidgetIteratorGraphPrototypeView extends CControllerWidgetItera
/**
* Get graph prototype widget data for simple graph prototype source.
- *
- * @param array $fields Widget form fields data
- *
- * @return array Dashboard response data
*/
- protected function doSimpleGraphPrototype(array $fields) {
+ protected function doSimpleGraphPrototype(): array {
$options = [
'output' => ['itemid', 'name'],
'selectHosts' => ['name'],
'selectDiscoveryRule' => ['hostid']
];
- $is_template_dashboard = ($this->getContext() === CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD);
- $is_dynamic_item = ($is_template_dashboard || $fields['dynamic'] == WIDGET_DYNAMIC_ITEM);
+ $is_template_dashboard = $this->hasInput('templateid');
+ $is_dynamic_item = ($is_template_dashboard || $this->fields_values['dynamic'] == CWidget::DYNAMIC_ITEM);
$dynamic_hostid = $this->getInput('dynamic_hostid', 0);
@@ -200,7 +204,7 @@ class CControllerWidgetIteratorGraphPrototypeView extends CControllerWidgetItera
// The key of the actual item prototype selected on widget's edit form.
$item_prototype = API::ItemPrototype()->get([
'output' => ['key_'],
- 'itemids' => reset($fields['itemid'])
+ 'itemids' => reset($this->fields_values['itemid'])
]);
if ($item_prototype) {
$item_prototype = reset($item_prototype);
@@ -215,7 +219,7 @@ class CControllerWidgetIteratorGraphPrototypeView extends CControllerWidgetItera
}
else {
// Just fetch the item prototype selected on widget's edit form.
- $options['itemids'] = reset($fields['itemid']);
+ $options['itemids'] = reset($this->fields_values['itemid']);
}
// Use this item prototype as base for collecting created items.
@@ -262,21 +266,24 @@ class CControllerWidgetIteratorGraphPrototypeView extends CControllerWidgetItera
$children = [];
- foreach ($items_collected as $itemid => $name) {
- $child_fields = [
- 'source_type' => ZBX_WIDGET_FIELD_RESOURCE_SIMPLE_GRAPH,
- 'itemid' => $itemid,
- 'show_legend' => $fields['show_legend']
- ];
-
- $children[] = [
- 'widgetid' => (string) $itemid,
- 'type' => WIDGET_GRAPH,
- 'name' => $name,
- 'fields' => $child_fields,
- 'configuration' => CWidgetConfig::getConfiguration(WIDGET_GRAPH, $fields, $this->getInput('view_mode')),
- 'defaults' => CWidgetConfig::getDefaults($this->getContext())[WIDGET_GRAPH]
- ];
+ $widget = APP::ModuleManager()->getModule(self::GRAPH_WIDGET_ID);
+
+ if ($widget !== null) {
+ foreach ($items_collected as $itemid => $name) {
+ $child_fields = [
+ 'source_type' => ZBX_WIDGET_FIELD_RESOURCE_SIMPLE_GRAPH,
+ 'itemid' => $itemid,
+ 'show_legend' => $this->fields_values['show_legend']
+ ];
+
+ $children[] = [
+ 'widgetid' => (string) $itemid,
+ 'type' => self::GRAPH_WIDGET_ID,
+ 'name' => $name,
+ 'fields' => $child_fields,
+ 'defaults' => $widget->getDefaults()
+ ];
+ }
}
if ($this->hasInput('name')) {
@@ -297,13 +304,11 @@ class CControllerWidgetIteratorGraphPrototypeView extends CControllerWidgetItera
}
/**
- * Get graph prototype widget data for no permissions error.
- *
- * @return array Dashboard response data
+ * Get graph prototype widget data for no permission's error.
*/
- protected function inaccessibleError() {
+ protected function inaccessibleError(): array {
return [
- 'name' => $this->getInput('name', $this->getDefaultName()),
+ 'name' => $this->getInput('name', $this->widget->getDefaultName()),
'body' => (new CTableInfo())
->setNoDataMessage(_('No permissions to referred object or it does not exist!'))
->toString()
diff --git a/ui/js/widgets/class.widget.graph-prototype.js b/ui/widgets/graphprototype/assets/js/class.widget.js
index 8d2e194b8aa..6cb0cd11537 100644..100755
--- a/ui/js/widgets/class.widget.graph-prototype.js
+++ b/ui/widgets/graphprototype/assets/js/class.widget.js
@@ -23,4 +23,8 @@ class CWidgetGraphPrototype extends CWidgetIterator {
_updateWidget(widget) {
widget.resize();
}
+
+ _hasPadding() {
+ return false;
+ }
}
diff --git a/ui/widgets/graphprototype/includes/WidgetForm.php b/ui/widgets/graphprototype/includes/WidgetForm.php
new file mode 100644
index 00000000000..3107c113949
--- /dev/null
+++ b/ui/widgets/graphprototype/includes/WidgetForm.php
@@ -0,0 +1,102 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\GraphPrototype\Includes;
+
+use Zabbix\Widgets\{
+ CWidgetField,
+ CWidgetForm
+};
+
+use Zabbix\Widgets\Fields\{
+ CWidgetFieldCheckBox,
+ CWidgetFieldIntegerBox,
+ CWidgetFieldMultiSelectGraphPrototype,
+ CWidgetFieldMultiSelectItemPrototype,
+ CWidgetFieldRadioButtonList
+};
+
+/**
+ * Graph prototype widget form.
+ */
+class WidgetForm extends CWidgetForm {
+
+ private const DEFAULT_COLUMNS_COUNT = 2;
+ private const DEFAULT_ROWS_COUNT = 1;
+
+ public function addFields(): self {
+ $this->addField(
+ (new CWidgetFieldRadioButtonList('source_type', _('Source'), [
+ ZBX_WIDGET_FIELD_RESOURCE_GRAPH_PROTOTYPE => _('Graph prototype'),
+ ZBX_WIDGET_FIELD_RESOURCE_SIMPLE_GRAPH_PROTOTYPE => _('Simple graph prototype')
+ ]))
+ ->setDefault(ZBX_WIDGET_FIELD_RESOURCE_GRAPH_PROTOTYPE)
+ ->setAction('ZABBIX.Dashboard.reloadWidgetProperties()')
+ );
+
+ if (array_key_exists('source_type', $this->values)
+ && $this->values['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_SIMPLE_GRAPH_PROTOTYPE) {
+
+ $field_item_prototype = (new CWidgetFieldMultiSelectItemPrototype('itemid', _('Item prototype'),
+ $this->templateid
+ ))
+ ->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
+ ->setMultiple(false)
+ ->setFilterParameter('numeric', true);
+
+ if ($this->templateid === null) {
+ $field_item_prototype->setFilterParameter('with_simple_graph_item_prototypes', true);
+ }
+
+ $this->addField($field_item_prototype);
+ }
+ else {
+ $this->addField(
+ (new CWidgetFieldMultiSelectGraphPrototype('graphid', _('Graph prototype'), $this->templateid))
+ ->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
+ ->setMultiple(false)
+ );
+ }
+
+ $this
+ ->addField(
+ (new CWidgetFieldCheckBox('show_legend', _('Show legend')))->setDefault(1)
+ )
+ ->addField($this->templateid === null
+ ? new CWidgetFieldCheckBox('dynamic', _('Enable host selection'))
+ : null
+ )
+ ->addField(
+ (new CWidgetFieldIntegerBox('columns', _('Columns'), 1, DASHBOARD_MAX_COLUMNS))
+ ->setDefault(self::DEFAULT_COLUMNS_COUNT)
+ ->setFlags(CWidgetField::FLAG_LABEL_ASTERISK)
+ )
+ ->addField(
+ (new CWidgetFieldIntegerBox('rows', _('Rows'), 1,
+ floor(DASHBOARD_WIDGET_MAX_ROWS / DASHBOARD_WIDGET_MIN_ROWS)
+ ))
+ ->setDefault(self::DEFAULT_ROWS_COUNT)
+ ->setFlags(CWidgetField::FLAG_LABEL_ASTERISK)
+ );
+
+ return $this;
+ }
+}
diff --git a/ui/widgets/graphprototype/manifest.json b/ui/widgets/graphprototype/manifest.json
new file mode 100755
index 00000000000..ae1feb40df3
--- /dev/null
+++ b/ui/widgets/graphprototype/manifest.json
@@ -0,0 +1,27 @@
+{
+ "manifest_version": 2.0,
+ "id": "graphprototype",
+ "type": "widget",
+ "name": "Graph prototype",
+ "namespace": "GraphPrototype",
+ "version": "1.0",
+ "author": "Zabbix SIA",
+ "widget": {
+ "template_support": true,
+ "size": {
+ "width": 16,
+ "height": 5
+ },
+ "js_class": "CWidgetGraphPrototype",
+ "use_time_selector": true
+ },
+ "actions": {
+ "widget.graphprototype.view": {
+ "layout": "layout.json",
+ "view": null
+ }
+ },
+ "assets": {
+ "js": ["class.widget.js"]
+ }
+}
diff --git a/ui/widgets/graphprototype/views/widget.edit.php b/ui/widgets/graphprototype/views/widget.edit.php
new file mode 100755
index 00000000000..4f7bdafbdd1
--- /dev/null
+++ b/ui/widgets/graphprototype/views/widget.edit.php
@@ -0,0 +1,58 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+/**
+ * Graph prototype widget form view.
+ *
+ * @var CView $this
+ * @var array $data
+ */
+
+(new CWidgetFormView($data))
+ ->addField(
+ new CWidgetFieldRadioButtonListView($data['fields']['source_type'])
+ )
+ ->addField(array_key_exists('graphid', $data['fields'])
+ ? new CWidgetFieldMultiSelectGraphPrototypeView($data['fields']['graphid'],
+ $data['captions']['ms']['graph_prototypes']['graphid']
+ )
+ : null
+ )
+ ->addField(array_key_exists('itemid', $data['fields'])
+ ? new CWidgetFieldMultiSelectItemPrototypeView($data['fields']['itemid'],
+ $data['captions']['ms']['item_prototypes']['itemid']
+ )
+ : null
+ )
+ ->addField(
+ new CWidgetFieldCheckBoxView($data['fields']['show_legend'])
+ )
+ ->addField(array_key_exists('dynamic', $data['fields'])
+ ? new CWidgetFieldCheckBoxView($data['fields']['dynamic'])
+ : null
+ )
+ ->addField(
+ new CWidgetFieldIntegerBoxView($data['fields']['columns'])
+ )
+ ->addField(
+ new CWidgetFieldIntegerBoxView($data['fields']['rows'])
+ )
+ ->show();
diff --git a/ui/widgets/hostavail/Widget.php b/ui/widgets/hostavail/Widget.php
new file mode 100755
index 00000000000..940838ff348
--- /dev/null
+++ b/ui/widgets/hostavail/Widget.php
@@ -0,0 +1,31 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\HostAvail;
+
+use Zabbix\Core\CWidget;
+
+class Widget extends CWidget {
+
+ public function getDefaultName(): string {
+ return _('Host availability');
+ }
+}
diff --git a/ui/app/controllers/CControllerWidgetHostAvailView.php b/ui/widgets/hostavail/actions/WidgetView.php
index db696075f0e..42c27b2dc53 100644
--- a/ui/app/controllers/CControllerWidgetHostAvailView.php
+++ b/ui/widgets/hostavail/actions/WidgetView.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,29 +19,26 @@
**/
-class CControllerWidgetHostAvailView extends CControllerWidget {
+namespace Widgets\HostAvail\Actions;
- public function __construct() {
- parent::__construct();
+use API,
+ CControllerDashboardWidgetView,
+ CControllerResponseData,
+ CItemGeneral;
- $this->setType(WIDGET_HOST_AVAIL);
- $this->setValidationRules([
- 'name' => 'string',
- 'fields' => 'json'
- ]);
- }
+class WidgetView extends CControllerDashboardWidgetView {
- protected function doAction() {
- $fields = $this->getForm()->getFieldsData();
-
- $interface_types = CItem::INTERFACE_TYPES_BY_PRIORITY;
+ protected function doAction(): void {
+ $interface_types = CItemGeneral::INTERFACE_TYPES_BY_PRIORITY;
// Sanitize non-existing interface types.
- $fields['interface_type'] = array_values(array_intersect($interface_types, $fields['interface_type']));
+ $this->fields_values['interface_type'] = array_values(
+ array_intersect($interface_types, $this->fields_values['interface_type'])
+ );
- $groupids = $fields['groupids'] ? getSubGroups($fields['groupids']) : null;
+ $groupids = $this->fields_values['groupids'] ? getSubGroups($this->fields_values['groupids']) : null;
- $hosts_types = $fields['interface_type'] ? $fields['interface_type'] : $interface_types;
+ $hosts_types = $this->fields_values['interface_type'] ?: $interface_types;
$hosts_total = array_fill_keys($interface_types, 0);
$hosts_count = array_fill_keys($interface_types, [
@@ -54,10 +51,11 @@ class CControllerWidgetHostAvailView extends CControllerWidget {
'output' => [],
'selectInterfaces' => ['type', 'available'],
'groupids' => $groupids,
- 'filter' => ($fields['maintenance'] == HOST_MAINTENANCE_STATUS_OFF)
+ 'filter' => $this->fields_values['maintenance'] == HOST_MAINTENANCE_STATUS_OFF
? ['status' => HOST_STATUS_MONITORED, 'maintenance_status' => HOST_MAINTENANCE_STATUS_OFF]
: ['status' => HOST_STATUS_MONITORED]
]);
+
$availability_priority = [INTERFACE_AVAILABLE_FALSE, INTERFACE_AVAILABLE_UNKNOWN, INTERFACE_AVAILABLE_TRUE];
foreach ($db_hosts as $host) {
@@ -78,8 +76,8 @@ class CControllerWidgetHostAvailView extends CControllerWidget {
}
$this->setResponse(new CControllerResponseData([
- 'name' => $this->getInput('name', $this->getDefaultName()),
- 'layout' => $fields['layout'],
+ 'name' => $this->getInput('name', $this->widget->getDefaultName()),
+ 'layout' => $this->fields_values['layout'],
'hosts_types' => $hosts_types,
'hosts_count' => $hosts_count,
'hosts_total' => $hosts_total,
diff --git a/ui/widgets/hostavail/assets/js/class.widget.js b/ui/widgets/hostavail/assets/js/class.widget.js
new file mode 100644
index 00000000000..da3018177b7
--- /dev/null
+++ b/ui/widgets/hostavail/assets/js/class.widget.js
@@ -0,0 +1,27 @@
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+class CWidgetHostAvail extends CWidget {
+
+ _hasPadding() {
+ return this._view_mode == ZBX_WIDGET_VIEW_MODE_NORMAL
+ && (this._fields.interface_type === undefined || this._fields.interface_type.length !== 1);
+ }
+}
diff --git a/ui/widgets/hostavail/includes/WidgetForm.php b/ui/widgets/hostavail/includes/WidgetForm.php
new file mode 100644
index 00000000000..9fb67d845b9
--- /dev/null
+++ b/ui/widgets/hostavail/includes/WidgetForm.php
@@ -0,0 +1,61 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\HostAvail\Includes;
+
+use Zabbix\Widgets\CWidgetForm;
+
+use Zabbix\Widgets\Fields\{
+ CWidgetFieldCheckBox,
+ CWidgetFieldCheckBoxList,
+ CWidgetFieldMultiSelectGroup,
+ CWidgetFieldRadioButtonList
+};
+
+/**
+ * Host availability widget form.
+ */
+class WidgetForm extends CWidgetForm {
+
+ public function addFields(): self {
+ return $this
+ ->addField(
+ new CWidgetFieldMultiSelectGroup('groupids', _('Host groups'))
+ )
+ ->addField(
+ new CWidgetFieldCheckBoxList('interface_type', _('Interface type'), [
+ INTERFACE_TYPE_AGENT => _('Zabbix agent'),
+ INTERFACE_TYPE_SNMP => _('SNMP'),
+ INTERFACE_TYPE_JMX => _('JMX'),
+ INTERFACE_TYPE_IPMI => _('IPMI')
+ ])
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('layout', _('Layout'), [
+ STYLE_HORIZONTAL => _('Horizontal'),
+ STYLE_VERTICAL => _('Vertical')
+ ]))->setDefault(STYLE_HORIZONTAL)
+ )
+ ->addField(
+ new CWidgetFieldCheckBox('maintenance', _('Show hosts in maintenance'))
+ );
+ }
+}
diff --git a/ui/widgets/hostavail/manifest.json b/ui/widgets/hostavail/manifest.json
new file mode 100755
index 00000000000..c900192643e
--- /dev/null
+++ b/ui/widgets/hostavail/manifest.json
@@ -0,0 +1,20 @@
+{
+ "manifest_version": 2.0,
+ "id": "hostavail",
+ "type": "widget",
+ "name": "Host availability",
+ "namespace": "HostAvail",
+ "version": "1.0",
+ "author": "Zabbix SIA",
+ "widget": {
+ "js_class": "CWidgetHostAvail",
+ "size": {
+ "width": 6,
+ "height": 3
+ },
+ "refresh_rate": 900
+ },
+ "assets": {
+ "js": ["class.widget.js"]
+ }
+}
diff --git a/ui/include/classes/widgets/views/widget.discovery.form.view.php b/ui/widgets/hostavail/views/widget.edit.php
index 830ec0dd161..61c853f1ecd 100644..100755
--- a/ui/include/classes/widgets/views/widget.discovery.form.view.php
+++ b/ui/widgets/hostavail/views/widget.edit.php
@@ -20,23 +20,23 @@
/**
- * Discovery status widget form view.
+ * Host availability widget form view.
*
* @var CView $this
* @var array $data
*/
-$fields = $data['dialogue']['fields'];
-
-$form = CWidgetHelper::createForm();
-
-$form_grid = CWidgetHelper::createFormGrid($data['dialogue']['name'], $data['dialogue']['type'],
- $data['dialogue']['view_mode'], $data['known_widget_types'],
- $data['templateid'] === null ? $fields['rf_rate'] : null
-);
-
-$form->addItem($form_grid);
-
-return [
- 'form' => $form
-];
+(new CWidgetFormView($data))
+ ->addField(
+ new CWidgetFieldMultiSelectGroupView($data['fields']['groupids'], $data['captions']['ms']['groups']['groupids'])
+ )
+ ->addField(
+ new CWidgetFieldCheckBoxListView($data['fields']['interface_type'])
+ )
+ ->addField(
+ new CWidgetFieldRadioButtonListView($data['fields']['layout'])
+ )
+ ->addField(
+ new CWidgetFieldCheckBoxView($data['fields']['maintenance'])
+ )
+ ->show();
diff --git a/ui/app/views/monitoring.widget.hostavail.view.php b/ui/widgets/hostavail/views/widget.view.php
index 94ca2a936c4..d85f1361486 100644
--- a/ui/app/views/monitoring.widget.hostavail.view.php
+++ b/ui/widgets/hostavail/views/widget.view.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -20,6 +20,8 @@
/**
+ * Host availability widget view.
+ *
* @var CView $this
* @var array $data
*/
@@ -113,18 +115,6 @@ else {
}
}
-$output = [
- 'name' => $data['name'],
- 'body' => $table->toString()
-];
-
-if ($messages = get_and_clear_messages()) {
- $output['messages'] = array_column($messages, 'message');
-}
-
-if ($data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
- CProfiler::getInstance()->stop();
- $output['debug'] = CProfiler::getInstance()->make()->toString();
-}
-
-echo json_encode($output);
+(new CWidgetView($data))
+ ->addItem($table)
+ ->show();
diff --git a/ui/widgets/item/Widget.php b/ui/widgets/item/Widget.php
new file mode 100755
index 00000000000..9a151d3b6f7
--- /dev/null
+++ b/ui/widgets/item/Widget.php
@@ -0,0 +1,55 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\Item;
+
+use Zabbix\Core\CWidget;
+
+class Widget extends CWidget {
+
+ // Form blocks.
+ public const SHOW_DESCRIPTION = 1;
+ public const SHOW_VALUE = 2;
+ public const SHOW_TIME = 3;
+ public const SHOW_CHANGE_INDICATOR = 4;
+
+ // Objects positions.
+ public const POSITION_LEFT = 0;
+ public const POSITION_CENTER = 1;
+ public const POSITION_RIGHT = 2;
+
+ public const POSITION_TOP = 0;
+ public const POSITION_MIDDLE = 1;
+ public const POSITION_BOTTOM = 2;
+
+ public const POSITION_BEFORE = 0;
+ public const POSITION_ABOVE = 1;
+ public const POSITION_AFTER = 2;
+ public const POSITION_BELOW = 3;
+
+ public const CHANGE_INDICATOR_UP = 1;
+ public const CHANGE_INDICATOR_DOWN = 2;
+ public const CHANGE_INDICATOR_UP_DOWN = 3;
+
+ public function getDefaultName(): string {
+ return _('Item value');
+ }
+}
diff --git a/ui/app/controllers/CControllerWidgetItemView.php b/ui/widgets/item/actions/WidgetView.php
index 43b4632b8bc..2e12a94b87d 100644
--- a/ui/app/controllers/CControllerWidgetItemView.php
+++ b/ui/widgets/item/actions/WidgetView.php
@@ -19,29 +19,36 @@
**/
-class CControllerWidgetItemView extends CControllerWidget {
+namespace Widgets\Item\Actions;
- public const CHANGE_INDICATOR_UP = 1;
- public const CHANGE_INDICATOR_DOWN = 2;
- public const CHANGE_INDICATOR_UP_DOWN = 3;
+use API,
+ CControllerDashboardWidgetView,
+ CControllerResponseData,
+ CMacrosResolverHelper,
+ CSettingsHelper,
+ CUrl,
+ CValueMapHelper,
+ Manager;
- public function __construct() {
- parent::__construct();
+use Widgets\Item\Widget;
- $this->setType(WIDGET_ITEM);
- $this->setValidationRules([
- 'name' => 'string',
- 'fields' => 'json',
+use Zabbix\Core\CWidget;
+
+class WidgetView extends CControllerDashboardWidgetView {
+
+ protected function init(): void {
+ parent::init();
+
+ $this->addValidationRules([
'dynamic_hostid' => 'db hosts.hostid'
]);
}
- protected function doAction() {
- $name = $this->getDefaultName();
+ protected function doAction(): void {
+ $name = $this->widget->getDefaultName();
$cells = [];
$url = null;
$error = '';
- $fields = $this->getForm()->getFieldsData();
$history_period = timeUnitToSeconds(CSettingsHelper::get(CSettingsHelper::HISTORY_PERIOD));
$description = '';
$value = null;
@@ -50,15 +57,26 @@ class CControllerWidgetItemView extends CControllerWidget {
$units = '';
$decimals = null;
$last_value = null;
+
+ $options = [
+ 'output' => ['value_type'],
+ 'selectValueMap' => ['mappings'],
+ 'itemids' => $this->fields_values['itemid'],
+ 'webitems' => true,
+ 'preservekeys' => true
+ ];
+
+ $is_template_dashboard = $this->hasInput('templateid');
$is_dynamic = ($this->hasInput('dynamic_hostid')
- && ($this->getContext() === CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD
- || $fields['dynamic'] == WIDGET_DYNAMIC_ITEM)
+ && ($is_template_dashboard || $this->fields_values['dynamic'] == CWidget::DYNAMIC_ITEM)
);
+ $tmp_items = [];
+
if ($is_dynamic) {
$tmp_items = API::Item()->get([
'output' => ['key_'],
- 'itemids' => $fields['itemid'],
+ 'itemids' => $this->fields_values['itemid'],
'webitems' => true
]);
@@ -75,17 +93,8 @@ class CControllerWidgetItemView extends CControllerWidget {
];
}
}
- else {
- $options = [
- 'output' => ['value_type'],
- 'selectValueMap' => ['mappings'],
- 'itemids' => $fields['itemid'],
- 'webitems' => true,
- 'preservekeys' => true
- ];
- }
- $show = array_flip($fields['show']);
+ $show = array_flip($this->fields_values['show']);
/*
* Select original item name in several cases: if user is in normal dashboards or in template dashboards when
@@ -93,25 +102,23 @@ class CControllerWidgetItemView extends CControllerWidget {
* overwritten. Host name can be attached to item name with delimiter when user is in normal dashboards.
*/
if ($this->getInput('name', '') === '') {
- if ($this->getContext() === CWidgetConfig::CONTEXT_DASHBOARD
- || $this->getContext() === CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD
- && $this->hasInput('dynamic_hostid') && $tmp_items) {
+ if (!$is_template_dashboard || ($this->hasInput('dynamic_hostid') && $tmp_items)) {
$options['output'] = array_merge($options['output'], ['name']);
}
- if ($this->getContext() === CWidgetConfig::CONTEXT_DASHBOARD) {
+ if (!$is_template_dashboard) {
$options['selectHosts'] = ['name'];
}
}
// Add other fields in case current widget is set in dynamic mode, template dashboard or has a specified host.
- if ($is_dynamic && $tmp_items || !$is_dynamic) {
+ if (($is_dynamic && $tmp_items) || !$is_dynamic) {
// If description contains user macros, we need "itemid" and "hostid" to resolve them.
- if (array_key_exists(WIDGET_ITEM_SHOW_DESCRIPTION, $show)) {
+ if (array_key_exists(Widget::SHOW_DESCRIPTION, $show)) {
$options['output'] = array_merge($options['output'], ['itemid', 'hostid']);
}
- if (array_key_exists(WIDGET_ITEM_SHOW_VALUE, $show) && $fields['units_show'] == 1) {
+ if (array_key_exists(Widget::SHOW_VALUE, $show) && $this->fields_values['units_show'] == 1) {
$options['output'][] = 'units';
}
}
@@ -128,8 +135,8 @@ class CControllerWidgetItemView extends CControllerWidget {
else {
$items = API::Item()->get($options);
- if ($fields['itemid']) {
- $itemid = $fields['itemid'][0];
+ if ($this->fields_values['itemid']) {
+ $itemid = $this->fields_values['itemid'][0];
}
}
@@ -143,7 +150,7 @@ class CControllerWidgetItemView extends CControllerWidget {
$last_value = $history[$itemid][0]['value'];
// Time can be shown independently.
- if (array_key_exists(WIDGET_ITEM_SHOW_TIME, $show)) {
+ if (array_key_exists(Widget::SHOW_TIME, $show)) {
$time = date(ZBX_FULL_DATE_TIME, (int) $history[$itemid][0]['clock']);
}
@@ -151,17 +158,17 @@ class CControllerWidgetItemView extends CControllerWidget {
case ITEM_VALUE_TYPE_FLOAT:
case ITEM_VALUE_TYPE_UINT64:
// Override item units if needed.
- if (array_key_exists(WIDGET_ITEM_SHOW_VALUE, $show) && $fields['units_show'] == 1) {
- $units = ($fields['units'] === '')
+ if (array_key_exists(Widget::SHOW_VALUE, $show) && $this->fields_values['units_show'] == 1) {
+ $units = $this->fields_values['units'] === ''
? $items[$itemid]['units']
- : $fields['units'];
+ : $this->fields_values['units'];
}
// Apply unit conversion always because it will also convert values to scientific notation.
$raw_units = convertUnitsRaw([
'value' => $last_value,
'units' => $units,
- 'decimals' => $fields['decimal_places']
+ 'decimals' => $this->fields_values['decimal_places']
]);
// Get the converted value (this is not the final value).
$value = $raw_units['value'];
@@ -179,7 +186,7 @@ class CControllerWidgetItemView extends CControllerWidget {
* to 10 (maximum), the value will be converted to 0.0012340000.
*/
if ($raw_units['is_numeric']) {
- $value = self::convertNumeric($value, $fields['decimal_places'], $value_type);
+ $value = self::convertNumeric($value, $this->fields_values['decimal_places'], $value_type);
}
/*
@@ -202,12 +209,12 @@ class CControllerWidgetItemView extends CControllerWidget {
);
// Show of hide change indicator for mapped value.
- if (array_key_exists(WIDGET_ITEM_SHOW_CHANGE_INDICATOR, $show)) {
- $change_indicator = self::CHANGE_INDICATOR_UP_DOWN;
+ if (array_key_exists(Widget::SHOW_CHANGE_INDICATOR, $show)) {
+ $change_indicator = Widget::CHANGE_INDICATOR_UP_DOWN;
}
}
elseif (array_key_exists(1, $history[$itemid])
- && array_key_exists(WIDGET_ITEM_SHOW_CHANGE_INDICATOR, $show)) {
+ && array_key_exists(Widget::SHOW_CHANGE_INDICATOR, $show)) {
/*
* If there is no value mapping and there is more than one value, add up or down change
* indicator. Do not show change indicator if value is the same.
@@ -215,10 +222,10 @@ class CControllerWidgetItemView extends CControllerWidget {
$prev_value = $history[$itemid][1]['value'];
if ($last_value > $prev_value) {
- $change_indicator = self::CHANGE_INDICATOR_UP;
+ $change_indicator = Widget::CHANGE_INDICATOR_UP;
}
elseif ($last_value < $prev_value) {
- $change_indicator = self::CHANGE_INDICATOR_DOWN;
+ $change_indicator = Widget::CHANGE_INDICATOR_DOWN;
}
}
break;
@@ -234,7 +241,7 @@ class CControllerWidgetItemView extends CControllerWidget {
);
if ($mapping !== false) {
- // Currently it is same as in latest data with original value in parenthesis.
+ // Currently, it is same as in the latest data with original value in parentheses.
$value = $mapping.' ('.$value.')';
}
@@ -245,11 +252,11 @@ class CControllerWidgetItemView extends CControllerWidget {
$value = str_replace("\n", " ", $value);
if (array_key_exists(1, $history[$itemid])
- && array_key_exists(WIDGET_ITEM_SHOW_CHANGE_INDICATOR, $show)) {
+ && array_key_exists(Widget::SHOW_CHANGE_INDICATOR, $show)) {
$prev_value = $history[$itemid][1]['value'];
if ($last_value !== $prev_value) {
- $change_indicator = self::CHANGE_INDICATOR_UP_DOWN;
+ $change_indicator = Widget::CHANGE_INDICATOR_UP_DOWN;
}
}
break;
@@ -259,36 +266,32 @@ class CControllerWidgetItemView extends CControllerWidget {
$value_type = ITEM_VALUE_TYPE_TEXT;
// Since there is no value, we can still show time.
- if (array_key_exists(WIDGET_ITEM_SHOW_TIME, $show)) {
+ if (array_key_exists(Widget::SHOW_TIME, $show)) {
$time = date(ZBX_FULL_DATE_TIME);
}
}
if ($this->getInput('name', '') === '') {
- if ($this->getContext() === CWidgetConfig::CONTEXT_DASHBOARD
- || $this->getContext() === CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD
- && $this->hasInput('dynamic_hostid')) {
+ if (!$is_template_dashboard || $this->hasInput('dynamic_hostid')) {
// Resolve original item name when user is in normal dashboards or template dashboards view mode.
$name = $items[$itemid]['name'];
}
- if ($this->getContext() === CWidgetConfig::CONTEXT_DASHBOARD) {
+ if (!$is_template_dashboard) {
$name = $items[$itemid]['hosts'][0]['name'].NAME_DELIMITER.$name;
}
}
/*
* It doesn't matter if item has value or not, description can be resolved separately if needed. If item
- * will have value it will resolve, otherwise it will not.
+ * will have value, it will resolve, otherwise it will not.
*/
- if (array_key_exists(WIDGET_ITEM_SHOW_DESCRIPTION, $show)) {
+ if (array_key_exists(Widget::SHOW_DESCRIPTION, $show)) {
// Overwrite item name with the custom description.
- $items[$itemid]['name'] = $fields['description'];
+ $items[$itemid]['name'] = $this->fields_values['description'];
// Do not resolve macros if using template dashboard. Template dashboards only have edit mode.
- if ($this->getContext() === CWidgetConfig::CONTEXT_DASHBOARD
- || $this->getContext() === CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD
- && $this->hasInput('dynamic_hostid')) {
+ if (!$is_template_dashboard || $this->hasInput('dynamic_hostid')) {
$items = CMacrosResolverHelper::resolveWidgetItemNames($items);
}
@@ -296,7 +299,7 @@ class CControllerWidgetItemView extends CControllerWidget {
$description = $items[$itemid]['name'];
}
- $cells = self::arrangeByCells($fields, [
+ $cells = self::arrangeByCells($this->fields_values, [
'description' => $description,
'value_type' => $value_type,
'units' => $units,
@@ -322,10 +325,10 @@ class CControllerWidgetItemView extends CControllerWidget {
$error = _('No permissions to referred object or it does not exist!');
}
- $bg_color = $fields['bg_color'];
+ $bg_color = $this->fields_values['bg_color'];
if ($last_value !== null) {
- foreach ($fields['thresholds'] as $threshold) {
+ foreach ($this->fields_values['thresholds'] as $threshold) {
if ($threshold['threshold_value'] > $last_value) {
break;
}
@@ -356,7 +359,7 @@ class CControllerWidgetItemView extends CControllerWidget {
* @return string
*/
private static function convertNumeric(string $value, int $decimals, string $value_type): string {
- if ($value >= pow(10, ZBX_FLOAT_DIG)) {
+ if ($value >= (10 ** ZBX_FLOAT_DIG)) {
return sprintf('%.'.ZBX_FLOAT_DIG.'E', $value);
}
@@ -376,118 +379,118 @@ class CControllerWidgetItemView extends CControllerWidget {
*
* @static
*
- * @param array $fields Input fields from the form.
- * @param array $fields['show'] Flags to show description, value, time and change indicator.
- * @param int $fields['desc_v_pos'] Vertical position of the description.
- * @param int $fields['desc_h_pos'] Horizontal position of the description.
- * @param int $fields['desc_bold'] Font weight of the description (0 - normal, 1 - bold).
- * @param int $fields['desc_size'] Font size of the description.
- * @param string $fields['desc_color'] Font color of the description.
- * @param int $fields['value_v_pos'] Vertical position of the value.
- * @param int $fields['value_h_pos'] Horizontal position of the value.
- * @param int $fields['value_bold'] Font weight of the value (0 - normal, 1 - bold).
- * @param int $fields['value_size'] Font size of the value.
- * @param string $fields['value_color'] Font color of the value.
- * @param int $fields['units_show'] Display units or not (0 - hide, 1 - show).
- * @param int $fields['units_pos'] Position of the units.
- * @param int $fields['units_bold'] Font weight of the units (0 - normal, 1 - bold).
- * @param int $fields['units_size'] Font size of the units.
- * @param string $fields['units_color'] Font color of the units.
- * @param int $fields['decimal_size'] Font size of the fraction.
- * @param int $fields['time_v_pos'] Vertical position of the time.
- * @param int $fields['time_h_pos'] Horizontal position of the time.
- * @param int $fields['time_bold'] Font weight of the time (0 - normal, 1 - bold).
- * @param int $fields['time_size'] Font size of the time.
- * @param string $fields['time_color'] Font color of the time.
- * @param array $values Array of pre-processed data that needs to be displayed.
- * @param string $values['description'] Item description with all macros resolved.
- * @param string $values['value_type'] Calculated value type. It can be integer or text.
- * @param string $values['units'] Units of the item. Can be empty string if nothing to show.
- * @param string|null $values['value'] Value of the item or NULL if there is no value.
- * @param string|null $values['decimals'] Decimal places or NULL if there is no decimals to show.
- * @param int|null $values['change_indicator'] Change indicator type or NULL if indicator should not be shown.
- * @param string $values['time'] Time when item received the value or current time if no data.
- * @param array $values['items'] The original array of items.
- * @param string $values['itemid'] Item ID from the host.
+ * @param array $fields_values Input fields from the form.
+ * @param array $fields_values ['show'] Flags to show description, value, time and change indicator.
+ * @param int $fields_values ['desc_v_pos'] Vertical position of the description.
+ * @param int $fields_values ['desc_h_pos'] Horizontal position of the description.
+ * @param int $fields_values ['desc_bold'] Font weight of the description (0 - normal, 1 - bold).
+ * @param int $fields_values ['desc_size'] Font size of the description.
+ * @param string $fields_values ['desc_color'] Font color of the description.
+ * @param int $fields_values ['value_v_pos'] Vertical position of the value.
+ * @param int $fields_values ['value_h_pos'] Horizontal position of the value.
+ * @param int $fields_values ['value_bold'] Font weight of the value (0 - normal, 1 - bold).
+ * @param int $fields_values ['value_size'] Font size of the value.
+ * @param string $fields_values ['value_color'] Font color of the value.
+ * @param int $fields_values ['units_show'] Display units or not (0 - hide, 1 - show).
+ * @param int $fields_values ['units_pos'] Position of the units.
+ * @param int $fields_values ['units_bold'] Font weight of the units (0 - normal, 1 - bold).
+ * @param int $fields_values ['units_size'] Font size of the units.
+ * @param string $fields_values ['units_color'] Font color of the units.
+ * @param int $fields_values ['decimal_size'] Font size of the fraction.
+ * @param int $fields_values ['time_v_pos'] Vertical position of the time.
+ * @param int $fields_values ['time_h_pos'] Horizontal position of the time.
+ * @param int $fields_values ['time_bold'] Font weight of the time (0 - normal, 1 - bold).
+ * @param int $fields_values ['time_size'] Font size of the time.
+ * @param string $fields_values ['time_color'] Font color of the time.
+ * @param array $data Array of pre-processed data that needs to be displayed.
+ * @param string $data ['description'] Item description with all macros resolved.
+ * @param string $data ['value_type'] Calculated value type. It can be integer or text.
+ * @param string $data ['units'] Units of the item. Can be empty string if nothing to show.
+ * @param string|null $data ['value'] Value of the item or NULL if there is no value.
+ * @param string|null $data ['decimals'] Decimal places or NULL if there is no decimals to show.
+ * @param int|null $data ['change_indicator'] Change indicator type or NULL if indicator should not be shown.
+ * @param string $data ['time'] Time when item received the value or current time if no data.
+ * @param array $data ['items'] The original array of items.
+ * @param string $data ['itemid'] Item ID from the host.
*
* @return array
*/
- private static function arrangeByCells(array $fields, array $values): array {
+ private static function arrangeByCells(array $fields_values, array $data): array {
$cells = [];
- $show = array_flip($fields['show']);
+ $show = array_flip($fields_values['show']);
- if (array_key_exists(WIDGET_ITEM_SHOW_DESCRIPTION, $show)) {
- $cells[$fields['desc_v_pos']][$fields['desc_h_pos']] = [
+ if (array_key_exists(Widget::SHOW_DESCRIPTION, $show)) {
+ $cells[$fields_values['desc_v_pos']][$fields_values['desc_h_pos']] = [
'item_description' => [
- 'text' => $values['description'],
- 'font_size' => $fields['desc_size'],
- 'bold' => ($fields['desc_bold'] == 1),
- 'color' => $fields['desc_color']
+ 'text' => $data['description'],
+ 'font_size' => $fields_values['desc_size'],
+ 'bold' => ($fields_values['desc_bold'] == 1),
+ 'color' => $fields_values['desc_color']
]
];
}
- if (array_key_exists(WIDGET_ITEM_SHOW_VALUE, $show)) {
+ if (array_key_exists(Widget::SHOW_VALUE, $show)) {
$item_value_cell = [
- 'value_type' => $values['value_type']
+ 'value_type' => $data['value_type']
];
- if ($fields['units_show'] == 1 && $values['units'] !== '') {
+ if ($fields_values['units_show'] == 1 && $data['units'] !== '') {
$item_value_cell['parts']['units'] = [
- 'text' => $values['units'],
- 'font_size' => $fields['units_size'],
- 'bold' => ($fields['units_bold'] == 1),
- 'color' => $fields['units_color']
+ 'text' => $data['units'],
+ 'font_size' => $fields_values['units_size'],
+ 'bold' => ($fields_values['units_bold'] == 1),
+ 'color' => $fields_values['units_color']
];
- $item_value_cell['units_pos'] = $fields['units_pos'];
+ $item_value_cell['units_pos'] = $fields_values['units_pos'];
}
$item_value_cell['parts']['value'] = [
- 'text' => $values['value'],
- 'font_size' => $fields['value_size'],
- 'bold' => ($fields['value_bold'] == 1),
- 'color' => $fields['value_color']
+ 'text' => $data['value'],
+ 'font_size' => $fields_values['value_size'],
+ 'bold' => ($fields_values['value_bold'] == 1),
+ 'color' => $fields_values['value_color']
];
- if ($values['decimals'] !== null) {
+ if ($data['decimals'] !== null) {
$item_value_cell['parts']['decimals'] = [
- 'text' => $values['decimals'],
- 'font_size' => $fields['decimal_size'],
- 'bold' => ($fields['value_bold'] == 1),
- 'color' => $fields['value_color']
+ 'text' => $data['decimals'],
+ 'font_size' => $fields_values['decimal_size'],
+ 'bold' => ($fields_values['value_bold'] == 1),
+ 'color' => $fields_values['value_color']
];
}
- $cells[$fields['value_v_pos']][$fields['value_h_pos']] = [
+ $cells[$fields_values['value_v_pos']][$fields_values['value_h_pos']] = [
'item_value' => $item_value_cell
];
}
- if (array_key_exists(WIDGET_ITEM_SHOW_CHANGE_INDICATOR, $show) && $values['change_indicator'] !== null) {
+ if (array_key_exists(Widget::SHOW_CHANGE_INDICATOR, $show) && $data['change_indicator'] !== null) {
$colors = [
- self::CHANGE_INDICATOR_UP => $fields['up_color'],
- self::CHANGE_INDICATOR_DOWN => $fields['down_color'],
- self::CHANGE_INDICATOR_UP_DOWN => $fields['updown_color']
+ Widget::CHANGE_INDICATOR_UP => $fields_values['up_color'],
+ Widget::CHANGE_INDICATOR_DOWN => $fields_values['down_color'],
+ Widget::CHANGE_INDICATOR_UP_DOWN => $fields_values['updown_color']
];
// Change indicator can be displayed with or without value.
- $cells[$fields['value_v_pos']][$fields['value_h_pos']]['item_value']['parts']['change_indicator'] = [
- 'type' => $values['change_indicator'],
- 'font_size' => ($values['decimals'] !== null)
- ? max($fields['value_size'], $fields['decimal_size'])
- : $fields['value_size'],
- 'color' => $colors[$values['change_indicator']]
+ $cells[$fields_values['value_v_pos']][$fields_values['value_h_pos']]['item_value']['parts']['change_indicator'] = [
+ 'type' => $data['change_indicator'],
+ 'font_size' => ($data['decimals'] !== null)
+ ? max($fields_values['value_size'], $fields_values['decimal_size'])
+ : $fields_values['value_size'],
+ 'color' => $colors[$data['change_indicator']]
];
}
- if (array_key_exists(WIDGET_ITEM_SHOW_TIME, $show)) {
- $cells[$fields['time_v_pos']][$fields['time_h_pos']] = [
+ if (array_key_exists(Widget::SHOW_TIME, $show)) {
+ $cells[$fields_values['time_v_pos']][$fields_values['time_h_pos']] = [
'item_time' => [
- 'text' => $values['time'],
- 'font_size' => $fields['time_size'],
- 'bold' => ($fields['time_bold'] == 1),
- 'color' => $fields['time_color']
+ 'text' => $data['time'],
+ 'font_size' => $fields_values['time_size'],
+ 'bold' => ($fields_values['time_bold'] == 1),
+ 'color' => $fields_values['time_color']
]
];
}
diff --git a/ui/js/widgets/class.widget.item.js b/ui/widgets/item/assets/js/class.widget.js
index 46c488d5ed9..df49766ae7f 100644..100755
--- a/ui/js/widgets/class.widget.item.js
+++ b/ui/widgets/item/assets/js/class.widget.js
@@ -47,4 +47,8 @@ class CWidgetItem extends CWidget {
this._resize_observer.disconnect();
}
+
+ _hasPadding() {
+ return false;
+ }
}
diff --git a/ui/widgets/item/includes/WidgetForm.php b/ui/widgets/item/includes/WidgetForm.php
new file mode 100644
index 00000000000..a897683828f
--- /dev/null
+++ b/ui/widgets/item/includes/WidgetForm.php
@@ -0,0 +1,247 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\Item\Includes;
+
+use Zabbix\Widgets\{
+ CWidgetField,
+ CWidgetForm
+};
+
+use Zabbix\Widgets\Fields\{
+ CWidgetFieldCheckBox,
+ CWidgetFieldCheckBoxList,
+ CWidgetFieldColor,
+ CWidgetFieldIntegerBox,
+ CWidgetFieldMultiSelectItem,
+ CWidgetFieldRadioButtonList,
+ CWidgetFieldSelect,
+ CWidgetFieldTextArea,
+ CWidgetFieldTextBox,
+ CWidgetFieldThresholds
+};
+
+use Widgets\Item\Widget;
+
+/**
+ * Single item widget form.
+ */
+class WidgetForm extends CWidgetForm {
+
+ private const SIZE_PERCENT_MIN = 1;
+ private const SIZE_PERCENT_MAX = 100;
+
+ private const DEFAULT_DESCRIPTION_SIZE = 15;
+ private const DEFAULT_DECIMAL_SIZE = 35;
+ private const DEFAULT_VALUE_SIZE = 45;
+ private const DEFAULT_UNITS_SIZE = 35;
+ private const DEFAULT_TIME_SIZE = 15;
+
+ public function validate(bool $strict = false): array {
+ $errors = parent::validate($strict);
+
+ // Check if one of the objects (description, value or time) occupies same space.
+ $fields = [
+ ['show' => Widget::SHOW_DESCRIPTION, 'h_pos' => 'desc_h_pos', 'v_pos' => 'desc_v_pos'],
+ ['show' => Widget::SHOW_VALUE, 'h_pos' => 'value_h_pos', 'v_pos' => 'value_v_pos'],
+ ['show' => Widget::SHOW_TIME, 'h_pos' => 'time_h_pos', 'v_pos' => 'time_v_pos']
+ ];
+
+ $fields_count = count($fields);
+ $show = $this->getFieldValue('show');
+
+ for ($i = 0; $i < $fields_count - 1; $i++) {
+ if (!in_array($fields[$i]['show'], $show)) {
+ continue;
+ }
+
+ $i_h_pos = $this->getFieldValue($fields[$i]['h_pos']);
+ $i_v_pos = $this->getFieldValue($fields[$i]['v_pos']);
+
+ for ($j = $i + 1; $j < $fields_count; $j++) {
+ if (!in_array($fields[$j]['show'], $show)) {
+ continue;
+ }
+
+ $j_h_pos = $this->getFieldValue($fields[$j]['h_pos']);
+ $j_v_pos = $this->getFieldValue($fields[$j]['v_pos']);
+
+ if ($i_h_pos == $j_h_pos && $i_v_pos == $j_v_pos) {
+ $errors[] = _('Two or more fields cannot occupy same space.');
+ break 2;
+ }
+ }
+ }
+
+ return $errors;
+ }
+
+ public function addFields(): self {
+ return $this
+ ->addField(
+ (new CWidgetFieldMultiSelectItem('itemid', _('Item'), $this->templateid))
+ ->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
+ ->setMultiple(false)
+ )
+ ->addField(
+ (new CWidgetFieldCheckBoxList('show', _('Show'), [
+ Widget::SHOW_DESCRIPTION => _('Description'),
+ Widget::SHOW_VALUE => _('Value'),
+ Widget::SHOW_TIME => _('Time'),
+ Widget::SHOW_CHANGE_INDICATOR => _('Change indicator')
+ ]))
+ ->setDefault([Widget::SHOW_DESCRIPTION, Widget::SHOW_VALUE, Widget::SHOW_TIME,
+ Widget::SHOW_CHANGE_INDICATOR
+ ])
+ ->setFlags(CWidgetField::FLAG_LABEL_ASTERISK)
+ )
+ ->addField(
+ new CWidgetFieldCheckBox('adv_conf', _('Advanced configuration'))
+ )
+ ->addField(
+ (new CWidgetFieldTextArea('description', _('Description')))
+ ->setDefault('{ITEM.NAME}')
+ ->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('desc_h_pos', _('Horizontal position'), [
+ Widget::POSITION_LEFT => _('Left'),
+ Widget::POSITION_CENTER => _('Center'),
+ Widget::POSITION_RIGHT => _('Right')
+ ]))->setDefault(Widget::POSITION_CENTER)
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('desc_v_pos', _('Vertical position'), [
+ Widget::POSITION_TOP => _('Top'),
+ Widget::POSITION_MIDDLE => _('Middle'),
+ Widget::POSITION_BOTTOM => _('Bottom')
+ ]))->setDefault(Widget::POSITION_BOTTOM)
+ )
+ ->addField(
+ (new CWidgetFieldIntegerBox('desc_size', _('Size'), self::SIZE_PERCENT_MIN, self::SIZE_PERCENT_MAX))
+ ->setDefault(self::DEFAULT_DESCRIPTION_SIZE)
+ )
+ ->addField(
+ new CWidgetFieldCheckBox('desc_bold', _('Bold'))
+ )
+ ->addField(
+ new CWidgetFieldColor('desc_color', _('Color'))
+ )
+ ->addField(
+ (new CWidgetFieldIntegerBox('decimal_places', _('Decimal places'), 0, 10))->setDefault(2)
+ )
+ ->addField(
+ (new CWidgetFieldIntegerBox('decimal_size', _('Size'), self::SIZE_PERCENT_MIN, self::SIZE_PERCENT_MAX))
+ ->setDefault(self::DEFAULT_DECIMAL_SIZE)
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('value_h_pos', _('Horizontal position'), [
+ Widget::POSITION_LEFT => _('Left'),
+ Widget::POSITION_CENTER => _('Center'),
+ Widget::POSITION_RIGHT => _('Right')
+ ]))->setDefault(Widget::POSITION_CENTER)
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('value_v_pos', _('Vertical position'), [
+ Widget::POSITION_TOP => _('Top'),
+ Widget::POSITION_MIDDLE => _('Middle'),
+ Widget::POSITION_BOTTOM => _('Bottom')
+ ]))->setDefault(Widget::POSITION_MIDDLE)
+ )
+ ->addField(
+ (new CWidgetFieldIntegerBox('value_size', _('Size'), self::SIZE_PERCENT_MIN, self::SIZE_PERCENT_MAX))
+ ->setDefault(self::DEFAULT_VALUE_SIZE)
+ )
+ ->addField(
+ (new CWidgetFieldCheckBox('value_bold', _('Bold')))->setDefault(1)
+ )
+ ->addField(
+ new CWidgetFieldColor('value_color', _('Color'))
+ )
+ ->addField(
+ (new CWidgetFieldCheckBox('units_show', _('Units')))->setDefault(1)
+ )
+ ->addField(
+ new CWidgetFieldTextBox('units', _('Units'))
+ )
+ ->addField(
+ (new CWidgetFieldSelect('units_pos', _('Position'), [
+ Widget::POSITION_BEFORE => _('Before value'),
+ Widget::POSITION_ABOVE => _('Above value'),
+ Widget::POSITION_AFTER => _('After value'),
+ Widget::POSITION_BELOW => _('Below value')
+ ]))->setDefault(Widget::POSITION_AFTER)
+ )
+ ->addField(
+ (new CWidgetFieldIntegerBox('units_size', _('Size'), self::SIZE_PERCENT_MIN, self::SIZE_PERCENT_MAX))
+ ->setDefault(self::DEFAULT_UNITS_SIZE)
+ )
+ ->addField(
+ (new CWidgetFieldCheckBox('units_bold', _('Bold')))->setDefault(1)
+ )
+ ->addField(
+ new CWidgetFieldColor('units_color', _('Color'))
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('time_h_pos', _('Horizontal position'), [
+ Widget::POSITION_LEFT => _('Left'),
+ Widget::POSITION_CENTER => _('Center'),
+ Widget::POSITION_RIGHT => _('Right')
+ ]))->setDefault(Widget::POSITION_CENTER)
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('time_v_pos', _('Vertical position'), [
+ Widget::POSITION_TOP => _('Top'),
+ Widget::POSITION_MIDDLE => _('Middle'),
+ Widget::POSITION_BOTTOM => _('Bottom')
+ ]))->setDefault(Widget::POSITION_TOP)
+ )
+ ->addField(
+ (new CWidgetFieldIntegerBox('time_size', _('Size'), self::SIZE_PERCENT_MIN, self::SIZE_PERCENT_MAX))
+ ->setDefault(self::DEFAULT_TIME_SIZE)
+ )
+ ->addField(
+ new CWidgetFieldCheckBox('time_bold', _('Bold'))
+ )
+ ->addField(
+ new CWidgetFieldColor('time_color', _('Color'))
+ )
+ ->addField(
+ new CWidgetFieldColor('up_color', _('Change indicator'))
+ )
+ ->addField(
+ new CWidgetFieldColor('down_color', _('Change indicator'))
+ )
+ ->addField(
+ new CWidgetFieldColor('updown_color', _('Change indicator'))
+ )
+ ->addField(
+ new CWidgetFieldColor('bg_color', _('Background color'))
+ )
+ ->addField(
+ new CWidgetFieldThresholds('thresholds', _('Thresholds'))
+ )
+ ->addField($this->templateid === null
+ ? new CWidgetFieldCheckBox('dynamic', _('Enable host selection'))
+ : null
+ );
+ }
+}
diff --git a/ui/widgets/item/manifest.json b/ui/widgets/item/manifest.json
new file mode 100755
index 00000000000..1d3ec5853d7
--- /dev/null
+++ b/ui/widgets/item/manifest.json
@@ -0,0 +1,20 @@
+{
+ "manifest_version": 2.0,
+ "id": "item",
+ "type": "widget",
+ "name": "Item value",
+ "namespace": "Item",
+ "version": "1.0",
+ "author": "Zabbix SIA",
+ "widget": {
+ "template_support": true,
+ "size": {
+ "width": 4,
+ "height": 3
+ },
+ "js_class": "CWidgetItem"
+ },
+ "assets": {
+ "js": ["class.widget.js"]
+ }
+}
diff --git a/ui/include/classes/widgets/views/js/widget.item.form.view.js.php b/ui/widgets/item/views/widget.edit.js.php
index 4da14e1f08d..0988316ae8b 100644..100755
--- a/ui/include/classes/widgets/views/js/widget.item.form.view.js.php
+++ b/ui/widgets/item/views/widget.edit.js.php
@@ -17,25 +17,28 @@
** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
-?>
+use Widgets\Item\Widget;
+
+?>
+
window.widget_item_form = new class {
init({thresholds_colors}) {
- this.form = document.getElementById('widget-dialogue-form');
+ this._form = document.getElementById('widget-dialogue-form');
- this.show_description = document.getElementById(`show_${<?= WIDGET_ITEM_SHOW_DESCRIPTION ?>}`);
- this.show_value = document.getElementById(`show_${<?= WIDGET_ITEM_SHOW_VALUE ?>}`);
- this.show_time = document.getElementById(`show_${<?= WIDGET_ITEM_SHOW_TIME ?>}`);
- this.show_change_indicator = document.getElementById(`show_${<?= WIDGET_ITEM_SHOW_CHANGE_INDICATOR ?>}`);
+ this._show_description = document.getElementById(`show_${<?= Widget::SHOW_DESCRIPTION ?>}`);
+ this._show_value = document.getElementById(`show_${<?= Widget::SHOW_VALUE ?>}`);
+ this._show_time = document.getElementById(`show_${<?= Widget::SHOW_TIME ?>}`);
+ this._show_change_indicator = document.getElementById(`show_${<?= Widget::SHOW_CHANGE_INDICATOR ?>}`);
- this.advance_configuration = document.getElementById('adv_conf');
- this.units_show = document.getElementById('units_show');
+ this._advance_configuration = document.getElementById('adv_conf');
+ this._units_show = document.getElementById('units_show');
jQuery('#itemid').on('change', () => this.updateWarningIcon());
- for (const colorpicker of this.form.querySelectorAll('.<?= ZBX_STYLE_COLOR_PICKER ?> input')) {
+ for (const colorpicker of this._form.querySelectorAll('.<?= ZBX_STYLE_COLOR_PICKER ?> input')) {
$(colorpicker).colorpicker({
appendTo: ".overlay-dialogue-body",
use_default: !colorpicker.name.includes('thresholds'),
@@ -45,7 +48,7 @@ window.widget_item_form = new class {
});
}
- const show = [this.show_description, this.show_value, this.show_time, this.show_change_indicator];
+ const show = [this._show_description, this._show_value, this._show_time, this._show_change_indicator];
for (const checkbox of show) {
checkbox.addEventListener('change', (e) => {
@@ -58,86 +61,81 @@ window.widget_item_form = new class {
});
}
- for (const checkbox of [this.advance_configuration, this.units_show]) {
+ for (const checkbox of [this._advance_configuration, this._units_show]) {
checkbox.addEventListener('change', () => this.updateForm());
}
colorPalette.setThemeColors(thresholds_colors);
this.updateForm();
- this.updateWarningIcon();
}
updateForm() {
- const show_description_row = this.advance_configuration.checked && this.show_description.checked;
- const show_value_row = this.advance_configuration.checked && this.show_value.checked;
- const show_time_row = this.advance_configuration.checked && this.show_time.checked;
- const show_change_indicator_row = this.advance_configuration.checked && this.show_change_indicator.checked;
- const show_bg_color_row = this.advance_configuration.checked;
- const show_thresholds_row = this.advance_configuration.checked;
-
- for (const element of this.form.querySelectorAll('.js-row-description')) {
+ const show_description_row = this._advance_configuration.checked && this._show_description.checked;
+ const show_value_row = this._advance_configuration.checked && this._show_value.checked;
+ const show_time_row = this._advance_configuration.checked && this._show_time.checked;
+ const show_change_indicator_row = this._advance_configuration.checked && this._show_change_indicator.checked;
+ const show_bg_color_row = this._advance_configuration.checked;
+ const show_thresholds_row = this._advance_configuration.checked;
+
+ for (const element of this._form.querySelectorAll('.fields-group-description')) {
element.style.display = show_description_row ? '' : 'none';
- }
- for (const element of this.form.querySelectorAll('.js-row-description input, .js-row-description textarea')) {
- element.disabled = !show_description_row;
+
+ for (const input of element.querySelectorAll('input, textarea')) {
+ input.disabled = !show_description_row;
+ }
}
- for (const element of this.form.querySelectorAll('.js-row-value')) {
+ for (const element of this._form.querySelectorAll('.fields-group-value')) {
element.style.display = show_value_row ? '' : 'none';
- }
- for (const element of this.form.querySelectorAll('.js-row-value input')) {
- element.disabled = !show_value_row;
+
+ for (const input of element.querySelectorAll('input')) {
+ input.disabled = !show_value_row;
+ }
}
for(const element of document.querySelectorAll('#units, #units_pos, #units_size, #units_bold, #units_color')) {
- element.disabled = !show_value_row || !this.units_show.checked;
+ element.disabled = !show_value_row || !this._units_show.checked;
}
- for (const element of this.form.querySelectorAll('.js-row-time')) {
+ for (const element of this._form.querySelectorAll('.fields-group-time')) {
element.style.display = show_time_row ? '' : 'none';
- }
- for (const element of this.form.querySelectorAll('.js-row-time input')) {
- element.disabled = !show_time_row;
+
+ for (const input of element.querySelectorAll('input')) {
+ input.disabled = !show_time_row;
+ }
}
- for (const element of this.form.querySelectorAll('.js-row-change-indicator')) {
+ for (const element of this._form.querySelectorAll('.fields-group-change-indicator')) {
element.style.display = show_change_indicator_row ? '' : 'none';
- }
- for (const element of this.form.querySelectorAll('.js-row-change-indicator input')) {
- element.disabled = !show_change_indicator_row;
+
+ for (const input of element.querySelectorAll('input')) {
+ input.disabled = !show_change_indicator_row;
+ }
}
- for (const element of this.form.querySelectorAll('.js-row-bg-color')) {
+ for (const element of this._form.querySelectorAll('.js-row-bg-color')) {
element.style.display = show_bg_color_row ? '' : 'none';
- }
- for (const element of this.form.querySelectorAll('.js-row-bg-color input')) {
- element.disabled = !show_bg_color_row;
- }
- for (const element of this.form.querySelectorAll('.js-row-thresholds')) {
- element.style.display = show_thresholds_row ? '' : 'none';
+ for (const input of element.querySelectorAll('input')) {
+ input.disabled = !show_bg_color_row;
+ }
}
- for (const element of this.form.querySelectorAll('.js-row-thresholds input')) {
- element.disabled = !show_thresholds_row;
- }
- }
- setIndicatorColor(name, color) {
- const indicator_ids = {
- up_color: 'change-indicator-up',
- down_color: 'change-indicator-down',
- updown_color: 'change-indicator-updown'
- };
+ for (const element of this._form.querySelectorAll('.js-row-thresholds')) {
+ element.style.display = show_thresholds_row ? '' : 'none';
- document.getElementById(indicator_ids[name])
- .querySelector("polygon").style.fill = (color !== '') ? `#${color}` : '';
+ for (const input of element.querySelectorAll('input')) {
+ input.disabled = !show_thresholds_row;
+ }
+ }
}
updateWarningIcon() {
- document.getElementById('item-value-thresholds-warning').style.display = 'none';
-
+ const thresholds_warning = document.getElementById('item-value-thresholds-warning');
const ms_item_data = $('#itemid').multiSelect('getData');
+ thresholds_warning.style.display = 'none';
+
if (ms_item_data.length > 0) {
const curl = new Curl('jsrpc.php', false);
curl.setArgument('method', 'item_value_type.get');
@@ -150,10 +148,10 @@ window.widget_item_form = new class {
switch (response.result) {
case '<?= ITEM_VALUE_TYPE_FLOAT ?>':
case '<?= ITEM_VALUE_TYPE_UINT64 ?>':
- document.getElementById('item-value-thresholds-warning').style.display = 'none';
+ thresholds_warning.style.display = 'none';
break;
default:
- document.getElementById('item-value-thresholds-warning').style.display = '';
+ thresholds_warning.style.display = '';
}
})
.catch((exception) => {
@@ -161,4 +159,15 @@ window.widget_item_form = new class {
});
}
}
+
+ setIndicatorColor(name, color) {
+ const indicator_ids = {
+ up_color: 'change-indicator-up',
+ down_color: 'change-indicator-down',
+ updown_color: 'change-indicator-updown'
+ };
+
+ document.getElementById(indicator_ids[name])
+ .querySelector("polygon").style.fill = (color !== '') ? `#${color}` : '';
+ }
};
diff --git a/ui/widgets/item/views/widget.edit.php b/ui/widgets/item/views/widget.edit.php
new file mode 100755
index 00000000000..b68f26acae9
--- /dev/null
+++ b/ui/widgets/item/views/widget.edit.php
@@ -0,0 +1,237 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+/**
+ * Item value widget form view.
+ *
+ * @var CView $this
+ * @var array $data
+ */
+
+use Zabbix\Widgets\Fields\CWidgetFieldColumnsList;
+
+$form = new CWidgetFormView($data);
+
+$form
+ ->addField(
+ new CWidgetFieldMultiSelectItemView($data['fields']['itemid'], $data['captions']['ms']['items']['itemid'])
+ )
+ ->addField(
+ (new CWidgetFieldCheckBoxListView($data['fields']['show']))
+ ->addClass(ZBX_STYLE_GRID_COLUMNS)
+ ->addClass(ZBX_STYLE_GRID_COLUMNS_2)
+ )
+ ->addField(
+ new CWidgetFieldCheckBoxView($data['fields']['adv_conf'])
+ )
+ ->addFieldsGroup([
+ _('Description'),
+ makeHelpIcon([
+ _('Supported macros:'),
+ (new CList([
+ '{HOST.*}',
+ '{ITEM.*}',
+ '{INVENTORY.*}',
+ _('User macros')
+ ]))->addClass(ZBX_STYLE_LIST_DASHED)
+ ])
+ ], getDescriptionFieldsGroupViews($form, $data['fields']),
+ 'fields-group-description'
+ )
+ ->addFieldsGroup(_('Value'), getValueFieldsGroupViews($form, $data['fields']),
+ 'fields-group-value'
+ )
+ ->addFieldsGroup(_('Time'), getTimeFieldsGroupViews($form, $data['fields']),
+ 'fields-group-time'
+ )
+ ->addFieldsGroup(_('Change indicator'), getChangeIndicatorFieldsGroupViews($form, $data['fields']),
+ 'fields-group-change-indicator'
+ )
+ ->addField(
+ new CWidgetFieldColorView($data['fields']['bg_color']),
+ 'js-row-bg-color'
+ )
+ ->addField(
+ (new CWidgetFieldThresholdsView($data['fields']['thresholds']))
+ ->setHint(
+ makeWarningIcon(_('This setting applies only to numeric data.'))->setId('item-value-thresholds-warning')
+ ),
+ 'js-row-thresholds'
+ )
+ ->addField(array_key_exists('dynamic', $data['fields'])
+ ? new CWidgetFieldCheckBoxView($data['fields']['dynamic'])
+ : null
+ )
+ ->includeJsFile('widget.edit.js.php')
+ ->addJavaScript('widget_item_form.init('.json_encode([
+ 'thresholds_colors' => CWidgetFieldColumnsList::THRESHOLDS_DEFAULT_COLOR_PALETTE
+ ], JSON_THROW_ON_ERROR).');')
+ ->show();
+
+function getDescriptionFieldsGroupViews(CWidgetFormView $form, array $fields): array {
+ $description = (new CWidgetFieldTextAreaView($fields['description']))
+ ->setAdaptiveWidth(ZBX_TEXTAREA_BIG_WIDTH - 38);
+ $desc_size = new CWidgetFieldIntegerBoxView($fields['desc_size']);
+ $desc_color = new CWidgetFieldColorView($fields['desc_color']);
+
+ return [
+ $form->makeCustomField($description, [
+ new CFormField(
+ $description->getView()->setAttribute('maxlength', DB::getFieldLength('widget_field', 'value_str'))
+ )
+ ]),
+
+ new CWidgetFieldRadioButtonListView($fields['desc_h_pos']),
+
+ $form->makeCustomField($desc_size, [
+ $desc_size->getLabel(),
+ (new CFormField([$desc_size->getView(), '%']))->addClass('field-size')
+ ]),
+
+ new CWidgetFieldRadioButtonListView($fields['desc_v_pos']),
+
+ new CWidgetFieldCheckBoxView($fields['desc_bold']),
+
+ $form->makeCustomField($desc_color, [
+ $desc_color->getLabel()->addClass('offset-3'),
+ new CFormField($desc_color->getView())
+ ])
+ ];
+}
+
+function getValueFieldsGroupViews(CWidgetFormView $form, array $fields): array {
+ $decimal_size = new CWidgetFieldIntegerBoxView($fields['decimal_size']);
+ $value_size = new CWidgetFieldIntegerBoxView($fields['value_size']);
+ $value_color = new CWidgetFieldColorView($fields['value_color']);
+ $units_show = new CWidgetFieldCheckBoxView($fields['units_show']);
+ $units = (new CWidgetFieldTextBoxView($fields['units']))->setAdaptiveWidth(ZBX_TEXTAREA_BIG_WIDTH);
+ $units_size = new CWidgetFieldIntegerBoxView($fields['units_size']);
+ $units_bold = new CWidgetFieldCheckBoxView($fields['units_bold']);
+ $units_color = new CWidgetFieldColorView($fields['units_color']);
+
+ return [
+ new CWidgetFieldIntegerBoxView($fields['decimal_places']),
+
+ $form->makeCustomField($decimal_size, [
+ $decimal_size->getLabel(),
+ (new CFormField([$decimal_size->getView(), '%']))->addClass('field-size')
+ ]),
+
+ new CTag('hr'),
+
+ new CWidgetFieldRadioButtonListView($fields['value_h_pos']),
+
+ $form->makeCustomField($value_size, [
+ $value_size->getLabel(),
+ (new CFormField([$value_size->getView(), '%']))->addClass('field-size')
+ ]),
+
+ new CWidgetFieldRadioButtonListView($fields['value_v_pos']),
+
+ new CWidgetFieldCheckBoxView($fields['value_bold']),
+
+ $form->makeCustomField($value_color, [
+ $value_color->getLabel()->addClass('offset-3'),
+ new CFormField($value_color->getView())
+ ]),
+
+ new CTag('hr'),
+
+ (new CDiv([
+ $units_show->getView(),
+ $units->getLabel()
+ ]))->addClass('units-show'),
+
+ (new CFormField(
+ $units->getView()
+ ))->addClass(CFormField::ZBX_STYLE_FORM_FIELD_FLUID),
+
+ (new CWidgetFieldSelectView($fields['units_pos']))
+ ->setHelpHint(_('Position is ignored for s, uptime and unixtime units.')),
+
+ $form->makeCustomField($units_size, [
+ $units_size->getLabel(),
+ (new CFormField([$units_size->getView(), '%']))->addClass('field-size')
+ ]),
+
+ $form->makeCustomField($units_bold, [
+ $units_bold->getLabel()->addClass('offset-3'),
+ new CFormField($units_bold->getView())
+ ]),
+
+ $form->makeCustomField($units_color, [
+ $units_color->getLabel()->addClass('offset-3'),
+ new CFormField($units_color->getView())
+ ])
+ ];
+}
+
+function getTimeFieldsGroupViews(CWidgetFormView $form, array $fields): array {
+ $time_size = new CWidgetFieldIntegerBoxView($fields['time_size']);
+ $time_color = new CWidgetFieldColorView($fields['time_color']);
+
+ return [
+ new CWidgetFieldRadioButtonListView($fields['time_h_pos']),
+
+ $form->makeCustomField($time_size, [
+ $time_size->getLabel(),
+ (new CFormField([$time_size->getView(), '%']))->addClass('field-size')
+ ]),
+
+ new CWidgetFieldRadioButtonListView($fields['time_v_pos']),
+
+ new CWidgetFieldCheckBoxView($fields['time_bold']),
+
+ $form->makeCustomField($time_color, [
+ $time_color->getLabel()->addClass('offset-3'),
+ new CFormField($time_color->getView())
+ ])
+ ];
+}
+
+function getChangeIndicatorFieldsGroupViews(CWidgetFormView $form, array $fields): array {
+ $up_color = new CWidgetFieldColorView($fields['up_color']);
+ $down_color = new CWidgetFieldColorView($fields['down_color']);
+ $updown_color = new CWidgetFieldColorView($fields['updown_color']);
+
+ return [
+ (new CSvgArrow(['up' => true, 'fill_color' => $fields['up_color']->getValue()]))
+ ->setId('change-indicator-up')
+ ->setSize(14, 20),
+ $form->makeCustomField($up_color, [
+ new CFormField($up_color->getView())
+ ]),
+
+ (new CSvgArrow(['down' => true, 'fill_color' => $fields['down_color']->getValue()]))
+ ->setId('change-indicator-down')
+ ->setSize(14, 20),
+ $form->makeCustomField($down_color, [
+ new CFormField($down_color->getView())
+ ]),
+
+ (new CSvgArrow(['up' => true, 'down' => true, 'fill_color' => $fields['updown_color']->getValue()]))
+ ->setId('change-indicator-updown')
+ ->setSize(14, 20),
+ $form->makeCustomField($updown_color, [
+ new CFormField($updown_color->getView())
+ ])
+ ];
+}
diff --git a/ui/app/views/monitoring.widget.item.view.php b/ui/widgets/item/views/widget.view.php
index 87c88a0efa7..9b5eb07c08b 100644
--- a/ui/app/views/monitoring.widget.item.view.php
+++ b/ui/widgets/item/views/widget.view.php
@@ -20,23 +20,27 @@
/**
+ * Item value widget view.
+ *
* @var CView $this
* @var array $data
*/
+use Widgets\Item\Widget;
+
if ($data['error'] !== '') {
$body = (new CTableInfo())->setNoDataMessage($data['error']);
}
else {
$classes_vertical = [
- WIDGET_ITEM_POS_TOP => 'top',
- WIDGET_ITEM_POS_MIDDLE => 'middle',
- WIDGET_ITEM_POS_BOTTOM => 'bottom'
+ Widget::POSITION_TOP => 'top',
+ Widget::POSITION_MIDDLE => 'middle',
+ Widget::POSITION_BOTTOM => 'bottom'
];
$classes_horizontal = [
- WIDGET_ITEM_POS_LEFT => 'left',
- WIDGET_ITEM_POS_CENTER => 'center',
- WIDGET_ITEM_POS_RIGHT => 'right'
+ Widget::POSITION_LEFT => 'left',
+ Widget::POSITION_CENTER => 'center',
+ Widget::POSITION_RIGHT => 'right'
];
$rows = [];
@@ -97,29 +101,18 @@ else {
$rows[] = new CDiv($cols);
}
- $body = (new CDiv(
+ $body = new CDiv(
new CLink($rows, $data['url'])
- ))->addClass('dashboard-widget-item');
-
- $body->addStyle('background-color: #'.$data['bg_color'].';');
-}
-
-$output = [
- 'name' => $data['name'],
- 'body' => $body->toString()
-];
+ );
-if ($messages = get_and_clear_messages()) {
- $output['messages'] = array_column($messages, 'message');
-}
-
-if ($data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
- CProfiler::getInstance()->stop();
- $output['debug'] = CProfiler::getInstance()->make()->toString();
+ if ($data['bg_color'] !== '') {
+ $body->addStyle('background-color: #'.$data['bg_color'].';');
+ }
}
-echo json_encode($output);
-
+(new CWidgetView($data))
+ ->addItem($body)
+ ->show();
/**
* Prepare content for value cell.
@@ -137,14 +130,14 @@ function drawValueCell(array $cell_data): array {
}
// Units ABOVE value.
- if (array_key_exists('units', $cell_data['parts']) && $cell_data['units_pos'] == WIDGET_ITEM_POS_ABOVE) {
+ if (array_key_exists('units', $cell_data['parts']) && $cell_data['units_pos'] == Widget::POSITION_ABOVE) {
$item_cell[] = $units_div;
}
$item_content_div = (new CDiv())->addClass('item-value-content');
// Units BEFORE value.
- if (array_key_exists('units', $cell_data['parts']) && $cell_data['units_pos'] == WIDGET_ITEM_POS_BEFORE) {
+ if (array_key_exists('units', $cell_data['parts']) && $cell_data['units_pos'] == Widget::POSITION_BEFORE) {
$item_content_div->addItem($units_div);
}
@@ -167,7 +160,7 @@ function drawValueCell(array $cell_data): array {
}
// Units AFTER value.
- if (array_key_exists('units', $cell_data['parts']) && $cell_data['units_pos'] == WIDGET_ITEM_POS_AFTER) {
+ if (array_key_exists('units', $cell_data['parts']) && $cell_data['units_pos'] == Widget::POSITION_AFTER) {
$item_content_div->addItem($units_div);
}
@@ -181,13 +174,13 @@ function drawValueCell(array $cell_data): array {
);
switch ($change_data['type']) {
- case CControllerWidgetItemView::CHANGE_INDICATOR_UP:
+ case Widget::CHANGE_INDICATOR_UP:
$arrow_data = ['up' => true, 'fill_color' => $change_data['color']];
break;
- case CControllerWidgetItemView::CHANGE_INDICATOR_DOWN:
+ case Widget::CHANGE_INDICATOR_DOWN:
$arrow_data = ['down' => true, 'fill_color' => $change_data['color']];
break;
- case CControllerWidgetItemView::CHANGE_INDICATOR_UP_DOWN:
+ case Widget::CHANGE_INDICATOR_UP_DOWN:
$arrow_data = ['up' => true, 'down' => true, 'fill_color' => $change_data['color']];
break;
}
@@ -197,7 +190,7 @@ function drawValueCell(array $cell_data): array {
}
// Units BELOW value.
- if (array_key_exists('units', $cell_data['parts']) && $cell_data['units_pos'] == WIDGET_ITEM_POS_BELOW) {
+ if (array_key_exists('units', $cell_data['parts']) && $cell_data['units_pos'] == Widget::POSITION_BELOW) {
$item_cell[] = $units_div;
}
diff --git a/ui/widgets/map/Widget.php b/ui/widgets/map/Widget.php
new file mode 100755
index 00000000000..ef9af2ca6dd
--- /dev/null
+++ b/ui/widgets/map/Widget.php
@@ -0,0 +1,34 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\Map;
+
+use Zabbix\Core\CWidget;
+
+class Widget extends CWidget {
+
+ public const SOURCETYPE_MAP = 1;
+ public const SOURCETYPE_FILTER = 2;
+
+ public function getDefaultName(): string {
+ return _('Map');
+ }
+}
diff --git a/ui/app/controllers/CControllerWidgetMapView.php b/ui/widgets/map/actions/WidgetView.php
index 58e2504268a..454aeec6e34 100644
--- a/ui/app/controllers/CControllerWidgetMapView.php
+++ b/ui/widgets/map/actions/WidgetView.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -18,27 +18,28 @@
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
-require_once dirname(__FILE__).'/../../include/blocks.inc.php';
-class CControllerWidgetMapView extends CControllerWidget {
+namespace Widgets\Map\Actions;
- public function __construct() {
- parent::__construct();
+use API,
+ CControllerDashboardWidgetView,
+ CControllerResponseData,
+ CMapHelper;
- $this->setType(WIDGET_MAP);
- $this->setValidationRules([
- 'name' => 'string',
+class WidgetView extends CControllerDashboardWidgetView {
+
+ protected function init(): void {
+ parent::init();
+
+ $this->addValidationRules([
'initial_load' => 'in 0,1',
- 'fields' => 'json',
'current_sysmapid' => 'db sysmaps.sysmapid',
'unique_id' => 'string',
'previous_maps' => 'array'
]);
}
- protected function doAction() {
- $fields = $this->getForm()->getFieldsData();
- $sysmap_data = null;
+ protected function doAction(): void {
$previous_map = null;
$sysmapid = null;
$error = null;
@@ -60,11 +61,13 @@ class CControllerWidgetMapView extends CControllerWidget {
if ($this->hasInput('current_sysmapid')) {
$sysmapid = $this->getInput('current_sysmapid');
}
- elseif (array_key_exists('sysmapid', $fields)) {
- $sysmapid = $fields['sysmapid'];
+ elseif (array_key_exists('sysmapid', $this->fields_values)) {
+ $sysmapid = $this->fields_values['sysmapid'];
}
- $sysmap_data = CMapHelper::get(($sysmapid == null) ? [] : [$sysmapid], ['unique_id' => $this->getInput('unique_id')]);
+ $sysmap_data = CMapHelper::get($sysmapid == null ? [] : [$sysmapid],
+ ['unique_id' => $this->getInput('unique_id')]
+ );
if ($sysmapid === null || $sysmap_data['id'] < 0) {
$error = _('No permissions to referred object or it does not exist!');
@@ -79,14 +82,14 @@ class CControllerWidgetMapView extends CControllerWidget {
// Pass variables to view.
$this->setResponse(new CControllerResponseData([
- 'name' => $this->getInput('name', $this->getDefaultName()),
+ 'name' => $this->getInput('name', $this->widget->getDefaultName()),
'sysmap_data' => $sysmap_data ?: [],
'widget_settings' => [
'current_sysmapid' => $sysmapid,
- 'filter_widget_reference' => array_key_exists('filter_widget_reference', $fields)
- ? $fields['filter_widget_reference']
+ 'filter_widget_reference' => array_key_exists('filter_widget_reference', $this->fields_values)
+ ? $this->fields_values['filter_widget_reference']
: null,
- 'source_type' => $fields['source_type'],
+ 'source_type' => $this->fields_values['source_type'],
'previous_map' => $previous_map,
'initial_load' => $this->getInput('initial_load', 1),
'error' => $error
diff --git a/ui/js/widgets/class.widget.map.js b/ui/widgets/map/assets/js/class.widget.js
index 03c90e2b9e0..43f3a568b44 100644..100755
--- a/ui/js/widgets/class.widget.map.js
+++ b/ui/widgets/map/assets/js/class.widget.js
@@ -18,19 +18,26 @@
**/
-const WIDGET_SYSMAP_SOURCETYPE_MAP = 1;
-const WIDGET_SYSMAP_SOURCETYPE_FILTER = 2;
+class CWidgetMap extends CWidget {
-const WIDGET_SYSMAP_EVENT_SUBMAP_SELECT = 'widget-sysmap-submap-select';
+ static SOURCETYPE_MAP = 1;
+ static SOURCETYPE_FILTER = 2;
-class CWidgetMap extends CWidget {
+ static EVENT_SUBMAP_SELECT = 'widget-map.submap-select';
+
+ static WIDGET_NAVTREE_EVENT_MARK = 'widget-navtree.mark';
+ static WIDGET_NAVTREE_EVENT_SELECT = 'widget-navtree.select';
+
+ static getForeignReferenceFields() {
+ return ['filter_widget_reference'];
+ }
_init() {
super._init();
this._map_svg = null;
- this._source_type = this._fields.source_type || WIDGET_SYSMAP_SOURCETYPE_MAP;
+ this._source_type = this._fields.source_type || CWidgetMap.SOURCETYPE_MAP;
this._filter_widget = null;
this._filter_itemid = null;
@@ -61,8 +68,8 @@ class CWidgetMap extends CWidget {
super._doDestroy();
if (this._filter_widget) {
- this._filter_widget.off(WIDGET_NAVTREE_EVENT_MARK, this._events.mark);
- this._filter_widget.off(WIDGET_NAVTREE_EVENT_SELECT, this._events.select);
+ this._filter_widget.off(CWidgetMap.WIDGET_NAVTREE_EVENT_MARK, this._events.mark);
+ this._filter_widget.off(CWidgetMap.WIDGET_NAVTREE_EVENT_SELECT, this._events.select);
}
}
@@ -70,18 +77,17 @@ class CWidgetMap extends CWidget {
super.announceWidgets(widgets);
if (this._filter_widget !== null) {
- this._filter_widget.off(WIDGET_NAVTREE_EVENT_MARK, this._events.mark);
- this._filter_widget.off(WIDGET_NAVTREE_EVENT_SELECT, this._events.select);
+ this._filter_widget.off(CWidgetMap.WIDGET_NAVTREE_EVENT_MARK, this._events.mark);
+ this._filter_widget.off(CWidgetMap.WIDGET_NAVTREE_EVENT_SELECT, this._events.select);
}
- if (this._source_type == WIDGET_SYSMAP_SOURCETYPE_FILTER) {
+ if (this._source_type == CWidgetMap.SOURCETYPE_FILTER) {
for (const widget of widgets) {
- if (widget instanceof CWidgetNavTree
- && widget._fields.reference === this._fields.filter_widget_reference) {
+ if (widget._fields.reference === this._fields.filter_widget_reference) {
this._filter_widget = widget;
- this._filter_widget.on(WIDGET_NAVTREE_EVENT_MARK, this._events.mark);
- this._filter_widget.on(WIDGET_NAVTREE_EVENT_SELECT, this._events.select);
+ this._filter_widget.on(CWidgetMap.WIDGET_NAVTREE_EVENT_MARK, this._events.mark);
+ this._filter_widget.on(CWidgetMap.WIDGET_NAVTREE_EVENT_SELECT, this._events.select);
}
}
}
@@ -90,7 +96,7 @@ class CWidgetMap extends CWidget {
_promiseUpdate() {
if (!this._has_contents || this._map_svg === null) {
if (this._sysmapid !== null
- || this._source_type == WIDGET_SYSMAP_SOURCETYPE_MAP
+ || this._source_type == CWidgetMap.SOURCETYPE_MAP
|| this._filter_widget === null) {
return super._promiseUpdate();
}
@@ -174,7 +180,7 @@ class CWidgetMap extends CWidget {
this._navigateToMap(item.sysmapid);
- this.fire(WIDGET_SYSMAP_EVENT_SUBMAP_SELECT, {
+ this.fire(CWidgetMap.EVENT_SUBMAP_SELECT, {
sysmapid: item.sysmapid,
parent_itemid: item.parent_itemid,
back: true
@@ -221,7 +227,7 @@ class CWidgetMap extends CWidget {
this._navigateToMap(sysmapid);
- this.fire(WIDGET_SYSMAP_EVENT_SUBMAP_SELECT, {
+ this.fire(CWidgetMap.EVENT_SUBMAP_SELECT, {
sysmapid,
parent_itemid: this._filter_itemid
});
@@ -247,4 +253,8 @@ class CWidgetMap extends CWidget {
this._startUpdating();
}
+
+ _hasPadding() {
+ return true;
+ }
}
diff --git a/ui/widgets/map/includes/WidgetForm.php b/ui/widgets/map/includes/WidgetForm.php
new file mode 100644
index 00000000000..c91463cc66f
--- /dev/null
+++ b/ui/widgets/map/includes/WidgetForm.php
@@ -0,0 +1,73 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\Map\Includes;
+
+use Zabbix\Widgets\{
+ CWidgetField,
+ CWidgetForm
+};
+
+use Zabbix\Widgets\Fields\{
+ CWidgetFieldRadioButtonList,
+ CWidgetFieldReference,
+ CWidgetFieldSelectResource,
+ CWidgetFieldWidgetSelect
+};
+
+use Widgets\Map\Widget;
+
+use Zabbix\Core\CWidget;
+
+/**
+ * Map widget form.
+ */
+class WidgetForm extends CWidgetForm {
+
+ private const WIDGET_NAV_TREE = 'navtree';
+
+ public function addFields(): self {
+ $this->addField(
+ (new CWidgetFieldRadioButtonList('source_type', _('Source type'), [
+ Widget::SOURCETYPE_MAP => _('Map'),
+ Widget::SOURCETYPE_FILTER => _('Map navigation tree')
+ ]))
+ ->setDefault(Widget::SOURCETYPE_MAP)
+ ->setAction('ZABBIX.Dashboard.reloadWidgetProperties()')
+ );
+
+ if (!array_key_exists('source_type', $this->values) || $this->values['source_type'] == Widget::SOURCETYPE_MAP) {
+ $this->addField(
+ (new CWidgetFieldSelectResource('sysmapid', _('Map')))
+ ->setResourceType(CWidgetFieldSelectResource::RESOURCE_TYPE_SYSMAP)
+ ->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
+ );
+ }
+ else {
+ $this->addField(
+ (new CWidgetFieldWidgetSelect('filter_widget_reference', _('Filter'), self::WIDGET_NAV_TREE))
+ ->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
+ );
+ }
+
+ return $this;
+ }
+}
diff --git a/ui/include/classes/html/CDashboardWidgetMap.php b/ui/widgets/map/includes/WidgetMap.php
index 701f0d2bed3..1c77957b14c 100644
--- a/ui/include/classes/html/CDashboardWidgetMap.php
+++ b/ui/widgets/map/includes/WidgetMap.php
@@ -19,82 +19,72 @@
**/
+namespace Widgets\Map\Includes;
+
+use CDiv,
+ CLink,
+ CSpan,
+ CTableInfo;
+
+use Widgets\Map\Widget;
+
/**
* Dashboard Map widget class. Creates all widget specific JavaScript and HTML content for map widget's view.
*/
-class CDashboardWidgetMap extends CDiv {
+class WidgetMap extends CDiv
+{
/**
* Reference of linked map navigation tree widget.
- *
- * @var string
*/
- private $filter_widget_reference;
+ private ?string $filter_widget_reference;
/**
* Map that will be linked to 'go back to [previous map name]' link in dashboard map widget.
- *
- * @var array|null - array must contain at least integer value 'sysmapid' and string 'name'.
+ * Array must contain at least integer value 'sysmapid' and string 'name'.
*/
- private $previous_map;
+ private ?array $previous_map;
/**
* Response array of CMapHelper::get() that represents currently opened map.
- *
- * @var array|null
*/
- private $sysmap_data;
+ private array $sysmap_data;
/**
* Requested sysmapid.
- *
- * @var int
*/
- private $current_sysmapid;
+ private ?int $current_sysmapid;
/**
* The type of source of map widget.
- *
- * @var int - allowed values are WIDGET_SYSMAP_SOURCETYPE_MAP and WIDGET_SYSMAP_SOURCETYPE_FILTER.
+ * Allowed values are Widget::SOURCETYPE_MAP and Widget::SOURCETYPE_FILTER.
*/
- private $source_type;
+ private int $source_type;
/**
* Represents either this is initial or repeated load of map widget.
- *
- * @var int - allowed values are 0 and 1.
- */
- private $initial_load;
-
- /**
- * Unique ID of widget.
- *
- * @var string
+ * Allowed values are 0 and 1.
*/
- private $uniqueid;
+ private int $initial_load;
/**
* The error message displayed in map widget.
- *
- * @var string|null
*/
- private $error;
+ private ?string $error;
/**
* Class constructor.
*
- * @param array $sysmap_data An array of requested map in the form created by CMapHelper::get()
- * method.
- * @param array $widget_settings An array contains widget settings.
- * @param string|null $widget_settings['error'] A string of error message or null in case if error is
- * not detected.
- * @param int $widget_settings['current_sysmapid'] An integer of requested sysmapid.
- * @param string $widget_settings['filter_widget_reference'] A string of linked map navigation tree
- * reference.
- * @param int $widget_settings['source_type'] The type of source of map widget.
- * @param array|null $widget_settings['previous_map'] Sysmapid and name of map linked as previous.
- * @param int $widget_settings['initial_load'] Integer represents either this is initial load or
- * repeated.
+ * @param array $sysmap_data An array of requested map in the form created by CMapHelper::get() method.
+ * @param array $widget_settings An array contains widget settings.
+ * string|null $widget_settings['error'] A string of error message or null in case
+ * if error is not detected.
+ * int $widget_settings['current_sysmapid'] An integer of requested sysmapid.
+ * string $widget_settings['filter_widget_reference'] A string of linked map navigation tree reference.
+ * int $widget_settings['source_type'] The type of source of map widget.
+ * array|null $widget_settings['previous_map'] Sysmapid and name of map linked as previous.
+ * int $widget_settings['initial_load'] Integer represents either this is initial load
+ * or repeated.
*/
public function __construct(array $sysmap_data, array $widget_settings) {
parent::__construct();
@@ -110,10 +100,8 @@ class CDashboardWidgetMap extends CDiv {
/**
* A javascript that is used as widget's script_inline parameter.
- *
- * @return string
*/
- public function getScriptData() {
+ public function getScriptData(): array {
$map_data = [
'current_sysmapid' => null,
'filter_widget_reference' => null,
@@ -124,7 +112,7 @@ class CDashboardWidgetMap extends CDiv {
$map_data['current_sysmapid'] = $this->current_sysmapid;
}
- if ($this->source_type == WIDGET_SYSMAP_SOURCETYPE_FILTER
+ if ($this->source_type == Widget::SOURCETYPE_FILTER
&& $this->filter_widget_reference
&& $this->initial_load) {
$map_data['filter_widget_reference'] = $this->filter_widget_reference;
@@ -133,7 +121,7 @@ class CDashboardWidgetMap extends CDiv {
if ($this->sysmap_data && $this->error === null) {
$map_data['map_options'] = $this->sysmap_data;
}
- elseif ($this->error !== null && $this->source_type == WIDGET_SYSMAP_SOURCETYPE_FILTER) {
+ elseif ($this->error !== null && $this->source_type == Widget::SOURCETYPE_FILTER) {
$map_data['error_msg'] = (new CTableInfo())
->setNoDataMessage($this->error)
->toString();
@@ -142,12 +130,15 @@ class CDashboardWidgetMap extends CDiv {
return $map_data;
}
- /**
- * Build an object of HTML used in widget content.
- */
- private function build() {
+ public function toString($destroy = true): string {
+ $this->build();
+
+ return parent::toString($destroy);
+ }
+
+ private function build(): void {
$this->addClass(ZBX_STYLE_SYSMAP);
- $this->setId(uniqid());
+ $this->setId(uniqid('', true));
if ($this->error === null) {
if ($this->previous_map) {
@@ -157,39 +148,32 @@ class CDashboardWidgetMap extends CDiv {
(new CLink(
(new CSpan())
->addClass(ZBX_STYLE_BTN_BACK_MAP)
- ->addItem((new CDiv())->addClass(ZBX_STYLE_BTN_BACK_MAP_ICON))
- ->addItem((new CDiv())
- ->addClass(ZBX_STYLE_BTN_BACK_MAP_CONTENT)
- ->addItem(_s('Go back to %1$s', $this->previous_map['name']))
+ ->addItem(
+ (new CDiv())->addClass(ZBX_STYLE_BTN_BACK_MAP_ICON)
+ )
+ ->addItem(
+ (new CDiv())
+ ->addClass(ZBX_STYLE_BTN_BACK_MAP_CONTENT)
+ ->addItem(_s('Go back to %1$s', $this->previous_map['name']))
),
- '#'
+ '#'
))->addClass('js-previous-map')
);
$this->addItem($go_back_div);
}
- $map_div = (new CDiv((new CDiv($this->sysmap_data['aria_label']))->addClass(ZBX_STYLE_INLINE_SR_ONLY)))
- ->addClass('sysmap-widget-container');
+ $map_div = (new CDiv(
+ (new CDiv($this->sysmap_data['aria_label']))->addClass(ZBX_STYLE_INLINE_SR_ONLY))
+ )->addClass('sysmap-widget-container');
$this->addStyle('position:relative;');
$this->addItem($map_div);
}
- elseif ($this->source_type == WIDGET_SYSMAP_SOURCETYPE_MAP) {
- $this->addItem((new CTableInfo())->setNoDataMessage($this->error));
+ elseif ($this->source_type == Widget::SOURCETYPE_MAP) {
+ $this->addItem(
+ (new CTableInfo())->setNoDataMessage($this->error)
+ );
}
}
-
- /**
- * Gets string representation of widget HTML content.
- *
- * @param bool $destroy
- *
- * @return string
- */
- public function toString($destroy = true) {
- $this->build();
-
- return parent::toString($destroy);
- }
}
diff --git a/ui/widgets/map/manifest.json b/ui/widgets/map/manifest.json
new file mode 100755
index 00000000000..78f6cd2d973
--- /dev/null
+++ b/ui/widgets/map/manifest.json
@@ -0,0 +1,20 @@
+{
+ "manifest_version": 2.0,
+ "id": "map",
+ "type": "widget",
+ "name": "Map",
+ "namespace": "Map",
+ "version": "1.0",
+ "author": "Zabbix SIA",
+ "widget": {
+ "size": {
+ "width": 18,
+ "height": 5
+ },
+ "js_class": "CWidgetMap",
+ "refresh_rate": 900
+ },
+ "assets": {
+ "js": ["class.widget.js"]
+ }
+}
diff --git a/ui/app/views/monitoring.widget.geomap.view.php b/ui/widgets/map/views/widget.edit.php
index 84fa6e1ee17..7c88db3a6ed 100644..100755
--- a/ui/app/views/monitoring.widget.geomap.view.php
+++ b/ui/widgets/map/views/widget.edit.php
@@ -20,26 +20,22 @@
/**
+ * Map widget form view.
+ *
* @var CView $this
* @var array $data
*/
-$output = [
- 'name' => $data['name'],
- 'body' =>
- (new CDiv())
- ->setId($data['unique_id'])
- ->toString(),
- 'geomap' => array_intersect_key($data, array_flip(['config', 'hosts']))
-];
-
-if ($messages = get_and_clear_messages()) {
- $output['messages'] = array_column($messages, 'message');
-}
-
-if ($data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
- CProfiler::getInstance()->stop();
- $output['debug'] = CProfiler::getInstance()->make()->toString();
-}
-
-echo json_encode($output);
+(new CWidgetFormView($data))
+ ->addField(
+ new CWidgetFieldRadioButtonListView($data['fields']['source_type'])
+ )
+ ->addField(array_key_exists('sysmapid', $data['fields'])
+ ? new CWidgetFieldSelectResourceView($data['fields']['sysmapid'], $data['captions']['simple'])
+ : null
+ )
+ ->addField(array_key_exists('filter_widget_reference', $data['fields'])
+ ? new CWidgetFieldWidgetSelectView($data['fields']['filter_widget_reference'])
+ : null
+ )
+ ->show();
diff --git a/ui/widgets/map/views/widget.view.php b/ui/widgets/map/views/widget.view.php
new file mode 100644
index 00000000000..d74b9f53755
--- /dev/null
+++ b/ui/widgets/map/views/widget.view.php
@@ -0,0 +1,36 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+/**
+ * Map widget view.
+ *
+ * @var CView $this
+ * @var array $data
+ */
+
+use Widgets\Map\Includes\WidgetMap;
+
+$item = new WidgetMap($data['sysmap_data'], $data['widget_settings']);
+
+(new CWidgetView($data))
+ ->addItem($item)
+ ->setVar('sysmap_data', $item->getScriptData())
+ ->show();
diff --git a/ui/widgets/navtree/Widget.php b/ui/widgets/navtree/Widget.php
new file mode 100755
index 00000000000..80bb2f455cc
--- /dev/null
+++ b/ui/widgets/navtree/Widget.php
@@ -0,0 +1,49 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\NavTree;
+
+use Zabbix\Core\CWidget;
+
+class Widget extends CWidget {
+
+ // Max depth of navigation tree.
+ public const MAX_DEPTH = 10;
+
+ public function getDefaultName(): string {
+ return _('Map navigation tree');
+ }
+
+ public function getTranslationStrings(): array {
+ return [
+ 'class.widget.js' => [
+ 'Add' => _s('Add'),
+ 'Add child element' => _s('Add child elementsssss'),
+ 'Add multiple maps' => _s('Add multiple maps'),
+ 'Apply' => _s('Apply'),
+ 'Cancel' => _s('Cancel'),
+ 'Edit' => _s('Edit'),
+ 'Edit tree element' => _s('Edit tree element'),
+ 'Remove' => _s('Remove')
+ ]
+ ];
+ }
+}
diff --git a/ui/app/controllers/CControllerWidgetNavTreeItemEdit.php b/ui/widgets/navtree/actions/NavTreeItemEdit.php
index 07ed735aafd..97a1e5e93a4 100644
--- a/ui/app/controllers/CControllerWidgetNavTreeItemEdit.php
+++ b/ui/widgets/navtree/actions/NavTreeItemEdit.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,17 +19,25 @@
**/
-class CControllerWidgetNavTreeItemEdit extends CController {
+namespace Widgets\NavTree\Actions;
- protected function init() {
+use API,
+ CController,
+ CControllerResponseData;
+
+use Widgets\NavTree\Widget;
+
+class NavTreeItemEdit extends CController {
+
+ protected function init(): void {
$this->disableSIDValidation();
}
- protected function checkInput() {
+ protected function checkInput(): bool {
$fields = [
'name' => 'required|string',
'sysmapid' => 'required|db sysmaps.sysmapid',
- 'depth' => 'required|ge 1|le '.WIDGET_NAVIGATION_TREE_MAX_DEPTH
+ 'depth' => 'required|ge 1|le '.Widget::MAX_DEPTH
];
$ret = $this->validateInput($fields);
@@ -40,18 +48,18 @@ class CControllerWidgetNavTreeItemEdit extends CController {
'error' => [
'messages' => array_column(get_and_clear_messages(), 'message')
]
- ])])
+ ], JSON_THROW_ON_ERROR)])
);
}
return $ret;
}
- protected function checkPermissions() {
- return ($this->getUserType() >= USER_TYPE_ZABBIX_USER);
+ protected function checkPermissions(): bool {
+ return $this->getUserType() >= USER_TYPE_ZABBIX_USER;
}
- protected function doAction() {
+ protected function doAction(): void {
$sysmapid = $this->getInput('sysmapid');
$sysmap = ['sysmapid' => $sysmapid, 'name' => ''];
diff --git a/ui/app/controllers/CControllerWidgetNavTreeItemUpdate.php b/ui/widgets/navtree/actions/NavTreeItemUpdate.php
index ef2e47417d4..0aa8ef74316 100644
--- a/ui/app/controllers/CControllerWidgetNavTreeItemUpdate.php
+++ b/ui/widgets/navtree/actions/NavTreeItemUpdate.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -18,20 +18,27 @@
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
-require_once dirname(__FILE__).'/../../include/blocks.inc.php';
-class CControllerWidgetNavTreeItemUpdate extends CController {
+namespace Widgets\NavTree\Actions;
- protected function init() {
+use API,
+ CController,
+ CControllerResponseData;
+
+use Widgets\NavTree\Widget;
+
+class NavTreeItemUpdate extends CController {
+
+ protected function init(): void {
$this->disableSIDValidation();
}
- protected function checkInput() {
+ protected function checkInput(): bool {
$fields = [
'name' => 'required|string|not_empty',
'sysmapid' => 'db sysmaps.sysmapid',
'add_submaps' => 'in 0,1',
- 'depth' => 'ge 1|le '.WIDGET_NAVIGATION_TREE_MAX_DEPTH
+ 'depth' => 'ge 1|le '.Widget::MAX_DEPTH
];
$ret = $this->validateInput($fields);
@@ -42,18 +49,18 @@ class CControllerWidgetNavTreeItemUpdate extends CController {
'error' => [
'messages' => array_column(get_and_clear_messages(), 'message')
]
- ])])
+ ], JSON_THROW_ON_ERROR)])
);
}
return $ret;
}
- protected function checkPermissions() {
- return ($this->getUserType() >= USER_TYPE_ZABBIX_USER);
+ protected function checkPermissions(): bool {
+ return $this->getUserType() >= USER_TYPE_ZABBIX_USER;
}
- protected function doAction() {
+ protected function doAction(): void {
$sysmapid = $this->getInput('sysmapid', 0);
$add_submaps = (int) $this->getInput('add_submaps', 0);
$depth = (int) $this->getInput('depth', 1);
@@ -78,7 +85,7 @@ class CControllerWidgetNavTreeItemUpdate extends CController {
$sysmapids[$sysmapid] = true;
do {
- if ($depth++ > WIDGET_NAVIGATION_TREE_MAX_DEPTH) {
+ if ($depth++ > Widget::MAX_DEPTH) {
break;
}
@@ -121,6 +128,6 @@ class CControllerWidgetNavTreeItemUpdate extends CController {
'preservekeys' => true
])
: []
- ])]));
+ ], JSON_THROW_ON_ERROR)]));
}
}
diff --git a/ui/app/controllers/CControllerWidgetNavTreeView.php b/ui/widgets/navtree/actions/WidgetView.php
index a1b5a2412d2..706789994fc 100644
--- a/ui/app/controllers/CControllerWidgetNavTreeView.php
+++ b/ui/widgets/navtree/actions/WidgetView.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,25 +19,111 @@
**/
-require_once dirname(__FILE__).'/../../include/blocks.inc.php';
+namespace Widgets\NavTree\Actions;
-class CControllerWidgetNavTreeView extends CControllerWidget {
+use API,
+ CControllerDashboardWidgetView,
+ CControllerResponseData,
+ CProfile,
+ CSeverityHelper;
- private $problems_per_severity_tpl;
+class WidgetView extends CControllerDashboardWidgetView {
- public function __construct() {
- parent::__construct();
+ private array $problems_per_severity_tpl;
- $this->setType(WIDGET_NAV_TREE);
- $this->setValidationRules([
+ protected function init(): void {
+ parent::init();
+
+ $this->addValidationRules([
'name' => 'string',
- 'widgetid' => 'db widget.widgetid',
- 'initial_load' => 'in 0,1',
- 'fields' => 'json'
+ 'fields' => 'array'
]);
}
- protected function getNumberOfProblemsBySysmap(array $navtree_items = []) {
+ protected function doAction(): void {
+ // Get list of sysmapids.
+ $sysmapids = [];
+ $navtree_items = [];
+
+ foreach ($this->fields_values['navtree'] as $id => $navtree_item) {
+ $sysmapid = array_key_exists('sysmapid', $navtree_item) ? $navtree_item['sysmapid'] : 0;
+
+ if ($sysmapid != 0) {
+ $sysmapids[$sysmapid] = true;
+ }
+
+ $navtree_items[$id] = [
+ 'parent' => $navtree_item['parent'],
+ 'sysmapid' => $sysmapid,
+ 'child_sysmapids' => []
+ ];
+ }
+
+ // Propagate item mapids to all its parent items.
+ foreach ($navtree_items as $navtree_item) {
+ $parent = $navtree_item['parent'];
+
+ while (array_key_exists($parent, $navtree_items)) {
+ if ($navtree_item['sysmapid'] != 0) {
+ $navtree_items[$parent]['child_sysmapids'][$navtree_item['sysmapid']] = true;
+ }
+ $parent = $navtree_items[$parent]['parent'];
+ }
+ }
+
+ // Get severity levels and colors and select list of sysmapids to count problems per maps.
+ $this->problems_per_severity_tpl = [];
+ $severity_config = [];
+
+ $maps_accessible = $sysmapids
+ ? API::Map()->get([
+ 'output' => [],
+ 'sysmapids' => array_keys($sysmapids),
+ 'preservekeys' => true
+ ])
+ : [];
+
+ for ($severity = TRIGGER_SEVERITY_NOT_CLASSIFIED; $severity < TRIGGER_SEVERITY_COUNT; $severity++) {
+ $this->problems_per_severity_tpl[$severity] = 0;
+ $severity_config[$severity] = [
+ 'name' => CSeverityHelper::getName($severity),
+ 'style_class' => CSeverityHelper::getStatusStyle($severity)
+ ];
+ }
+
+ $widgetid = $this->getInput('widgetid', 0);
+ $navtree_item_selected = 0;
+ $navtree_items_opened = [];
+
+ if ($widgetid) {
+ $pattern = 'web.dashboard.widget.navtree.item-%.toggle';
+ $discard_from_start = strpos($pattern, '%');
+ $discard_from_end = strlen($pattern) - $discard_from_start - 1;
+
+ foreach (CProfile::findByIdxPattern($pattern, $widgetid) as $item_opened) {
+ $navtree_items_opened[] = substr($item_opened, $discard_from_start, -$discard_from_end);
+ }
+
+ $navtree_item_selected = CProfile::get('web.dashboard.widget.navtree.item.selected', 0, $widgetid);
+ }
+
+ $this->setResponse(new CControllerResponseData([
+ 'name' => $this->getInput('name', $this->widget->getDefaultName()),
+ 'navtree' => $this->fields_values['navtree'],
+ 'navtree_item_selected' => $navtree_item_selected,
+ 'navtree_items_opened' => $navtree_items_opened,
+ 'problems' => $this->getNumberOfProblemsBySysmap($navtree_items),
+ 'show_unavailable' => $this->fields_values['show_unavailable'],
+ 'maps_accessible' => array_keys($maps_accessible),
+ 'severity_config' => $severity_config,
+ 'initial_load' => $this->getInput('initial_load', 0),
+ 'user' => [
+ 'debug_mode' => $this->getDebugMode()
+ ]
+ ]));
+ }
+
+ private function getNumberOfProblemsBySysmap(array $navtree_items = []): array {
$response = [];
$sysmapids = [];
@@ -124,7 +210,7 @@ class CControllerWidgetNavTreeView extends CControllerWidget {
break;
case SYSMAP_ELEMENT_TYPE_TRIGGER:
- foreach (zbx_objectValues($selement['elements'], 'triggerid') as $triggerid) {
+ foreach (array_column($selement['elements'], 'triggerid') as $triggerid) {
$problems_per_trigger[$triggerid] = $this->problems_per_severity_tpl;
}
break;
@@ -153,7 +239,7 @@ class CControllerWidgetNavTreeView extends CControllerWidget {
}
// Select lowest severity to reduce amount of data returned by API.
- $severity_min = min(zbx_objectValues($sysmaps, 'severity_min'));
+ $severity_min = min(array_column($sysmaps, 'severity_min'));
// Get triggers related to host groups.
if ($host_groups) {
@@ -240,10 +326,10 @@ class CControllerWidgetNavTreeView extends CControllerWidget {
}
}
- // Count problems occurred in triggers which are related to links.
+ // Count problems occurred in triggers which are related to the links.
foreach ($map['links'] as $link) {
$uncounted_problem_triggers = array_diff_key(
- array_flip(zbx_objectValues($link['linktriggers'], 'triggerid')),
+ array_flip(array_column($link['linktriggers'], 'triggerid')),
$problems_counted
);
@@ -253,9 +339,9 @@ class CControllerWidgetNavTreeView extends CControllerWidget {
// Remove problems which are less important than map's min-severity.
if ($map['severity_min'] > 0) {
- foreach ($problems_to_add as $sev => $probl) {
- if ($map['severity_min'] > $sev) {
- $problems_to_add[$sev] = 0;
+ foreach (array_keys($problems_to_add) as $severity) {
+ if ($map['severity_min'] > $severity) {
+ $problems_to_add[$severity] = 0;
}
}
}
@@ -280,9 +366,9 @@ class CControllerWidgetNavTreeView extends CControllerWidget {
return $response;
}
- protected function getElementProblems(array $selement, array $problems_per_trigger, array $sysmaps,
+ private function getElementProblems(array $selement, array $problems_per_trigger, array $sysmaps,
array $submaps_relations, $severity_min = 0, array &$problems_counted = [], array $triggers_per_hosts = [],
- array $triggers_per_host_groups = []) {
+ array $triggers_per_host_groups = []): ?array {
$problems = null;
switch ($selement['elementtype']) {
@@ -306,7 +392,7 @@ class CControllerWidgetNavTreeView extends CControllerWidget {
case SYSMAP_ELEMENT_TYPE_TRIGGER:
$problems = $this->problems_per_severity_tpl;
$uncounted_problem_triggers = array_diff_key(
- array_flip(zbx_objectValues($selement['elements'], 'triggerid')),
+ array_flip(array_column($selement['elements'], 'triggerid')),
$problems_counted
);
foreach ($uncounted_problem_triggers as $triggerid => $var) {
@@ -343,7 +429,7 @@ class CControllerWidgetNavTreeView extends CControllerWidget {
// Recursively find all submaps in any depth and put them into an array.
$maps_to_process[$submap_element['sysmapid']] = false;
- while (array_filter($maps_to_process, function($item) {return !$item;})) {
+ while (array_filter($maps_to_process, static function($item) {return !$item;})) {
foreach ($maps_to_process as $linked_map => $val) {
$maps_to_process[$linked_map] = true;
@@ -381,7 +467,7 @@ class CControllerWidgetNavTreeView extends CControllerWidget {
foreach ($sysmaps[$sysmapid]['links'] as $link) {
if ($link['permission'] >= PERM_READ) {
$uncounted_problem_triggers = array_diff_key(
- array_flip(zbx_objectValues($link['linktriggers'], 'triggerid')),
+ array_flip(array_column($link['linktriggers'], 'triggerid')),
$problems_counted
);
foreach ($uncounted_problem_triggers as $triggerid => $var) {
@@ -399,9 +485,9 @@ class CControllerWidgetNavTreeView extends CControllerWidget {
// Remove problems which are less important than $severity_min.
if ($problems !== null && $severity_min > 0) {
- foreach ($problems as $sev => $probl) {
- if ($severity_min > $sev) {
- $problems[$sev] = 0;
+ foreach (array_keys($problems) as $severity) {
+ if ($severity_min > $severity) {
+ $problems[$severity] = 0;
}
}
}
@@ -409,91 +495,6 @@ class CControllerWidgetNavTreeView extends CControllerWidget {
return $problems;
}
- protected function doAction() {
- $fields = $this->getForm()->getFieldsData();
- $error = null;
-
- // Get list of sysmapids.
- $sysmapids = [];
- $navtree_items = [];
- foreach ($fields['navtree'] as $id => $navtree_item) {
- $sysmapid = array_key_exists('sysmapid', $navtree_item) ? $navtree_item['sysmapid'] : 0;
- if ($sysmapid != 0) {
- $sysmapids[$sysmapid] = true;
- }
-
- $navtree_items[$id] = [
- 'parent' => $navtree_item['parent'],
- 'sysmapid' => $sysmapid,
- 'child_sysmapids' => []
- ];
- }
-
- // Propagate item mapids to all its parent items.
- foreach ($navtree_items as $navtree_item) {
- $parent = $navtree_item['parent'];
-
- while (array_key_exists($parent, $navtree_items)) {
- if ($navtree_item['sysmapid'] != 0) {
- $navtree_items[$parent]['child_sysmapids'][$navtree_item['sysmapid']] = true;
- }
- $parent = $navtree_items[$parent]['parent'];
- }
- }
-
- // Get severity levels and colors and select list of sysmapids to count problems per maps.
- $this->problems_per_severity_tpl = [];
- $severity_config = [];
-
- $maps_accessible = $sysmapids
- ? API::Map()->get([
- 'output' => [],
- 'sysmapids' => array_keys($sysmapids),
- 'preservekeys' => true
- ])
- : [];
-
- for ($severity = TRIGGER_SEVERITY_NOT_CLASSIFIED; $severity < TRIGGER_SEVERITY_COUNT; $severity++) {
- $this->problems_per_severity_tpl[$severity] = 0;
- $severity_config[$severity] = [
- 'name' => CSeverityHelper::getName($severity),
- 'style_class' => CSeverityHelper::getStatusStyle($severity)
- ];
- }
-
- $widgetid = $this->getInput('widgetid', 0);
- $navtree_item_selected = 0;
- $navtree_items_opened = [];
-
- if ($widgetid) {
- $pattern = 'web.dashboard.widget.navtree.item-%.toggle';
- $discard_from_start = strpos($pattern, '%');
- $discard_from_end = strlen($pattern) - $discard_from_start - 1;
-
- foreach (CProfile::findByIdxPattern($pattern, $widgetid) as $item_opened) {
- $navtree_items_opened[] = substr($item_opened, $discard_from_start, -$discard_from_end);
- }
-
- $navtree_item_selected = CProfile::get('web.dashboard.widget.navtree.item.selected', 0, $widgetid);
- }
-
- $this->setResponse(new CControllerResponseData([
- 'name' => $this->getInput('name', $this->getDefaultName()),
- 'navtree' => $fields['navtree'],
- 'navtree_item_selected' => $navtree_item_selected,
- 'navtree_items_opened' => $navtree_items_opened,
- 'problems' => $this->getNumberOfProblemsBySysmap($navtree_items),
- 'show_unavailable' => $fields['show_unavailable'],
- 'maps_accessible' => array_keys($maps_accessible),
- 'severity_config' => $severity_config,
- 'initial_load' => $this->getInput('initial_load', 0),
- 'error' => $error,
- 'user' => [
- 'debug_mode' => $this->getDebugMode()
- ]
- ]));
- }
-
/**
* Function is used to sum problems in 2 arrays.
*
@@ -507,7 +508,7 @@ class CControllerWidgetNavTreeView extends CControllerWidget {
*
* @return array Array containing problems in both arrays summed.
*/
- protected static function sumArrayValues(array $a1, array $a2) {
+ private static function sumArrayValues(array $a1, array $a2): array {
foreach ($a1 as $key => &$value) {
$value += $a2[$key];
}
diff --git a/ui/js/widgets/class.widget.navtree.js b/ui/widgets/navtree/assets/js/class.widget.js
index b105ba36f69..7ff0f26e5be 100644..100755
--- a/ui/js/widgets/class.widget.navtree.js
+++ b/ui/widgets/navtree/assets/js/class.widget.js
@@ -18,11 +18,17 @@
**/
-const WIDGET_NAVTREE_EVENT_MARK = 'widget-navtree-mark';
-const WIDGET_NAVTREE_EVENT_SELECT = 'widget-navtree-select';
-
class CWidgetNavTree extends CWidget {
+ static EVENT_MARK = 'widget-navtree.mark';
+ static EVENT_SELECT = 'widget-navtree.select';
+
+ static WIDGET_MAP_EVENT_SUBMAP_SELECT = 'widget-map.submap-select';
+
+ static hasReferenceField() {
+ return true;
+ }
+
_init() {
super._init();
@@ -66,7 +72,7 @@ class CWidgetNavTree extends CWidget {
this._maps = [];
for (const widget of widgets) {
- if (widget instanceof CWidgetMap && this._fields.reference === widget._fields.filter_widget_reference) {
+ if (this._fields.reference === widget._fields.filter_widget_reference) {
this._maps.push(widget);
}
}
@@ -228,7 +234,7 @@ class CWidgetNavTree extends CWidget {
[this._widgetid]
);
- this.fire(WIDGET_NAVTREE_EVENT_SELECT, {
+ this.fire(CWidgetNavTree.EVENT_SELECT, {
sysmapid: this._navtree[this._navtree_item_selected].sysmapid,
itemid: this._navtree_item_selected
});
@@ -280,7 +286,7 @@ class CWidgetNavTree extends CWidget {
sysmapid = this._navtree[this._navtree_item_selected].sysmapid;
}
- this.fire(WIDGET_NAVTREE_EVENT_SELECT, {sysmapid, itemid: this._navtree_item_selected});
+ this.fire(CWidgetNavTree.EVENT_SELECT, {sysmapid, itemid: this._navtree_item_selected});
}
}
@@ -312,7 +318,7 @@ class CWidgetNavTree extends CWidget {
if (!this._is_edit_mode) {
for (const widget of this._maps) {
- widget.on(WIDGET_SYSMAP_EVENT_SUBMAP_SELECT, this._events.selectSubmap);
+ widget.on(CWidgetNavTree.WIDGET_MAP_EVENT_SUBMAP_SELECT, this._events.selectSubmap);
}
}
}
@@ -345,7 +351,7 @@ class CWidgetNavTree extends CWidget {
if (!this._is_edit_mode) {
for (const widget of this._maps) {
- widget.off(WIDGET_SYSMAP_EVENT_SUBMAP_SELECT, this._events.selectSubmap);
+ widget.off(CWidgetNavTree.WIDGET_MAP_EVENT_SUBMAP_SELECT, this._events.selectSubmap);
}
}
}
@@ -741,7 +747,7 @@ class CWidgetNavTree extends CWidget {
updateUserProfile('web.dashboard.widget.navtree.item.selected', this._navtree_item_selected, [this._widgetid]);
- this.fire(WIDGET_NAVTREE_EVENT_MARK, {itemid: this._navtree_item_selected});
+ this.fire(CWidgetNavTree.EVENT_MARK, {itemid: this._navtree_item_selected});
return true;
}
diff --git a/ui/include/classes/html/CNavigationTree.php b/ui/widgets/navtree/includes/NavigationTree.php
index 0dfaad22216..559d00237d4 100644
--- a/ui/include/classes/html/CNavigationTree.php
+++ b/ui/widgets/navtree/includes/NavigationTree.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,26 +19,28 @@
**/
-class CNavigationTree extends CDiv {
+namespace Widgets\NavTree\Includes;
- private $error;
- private $data;
+use CDiv;
+
+use Widgets\NavTree\Widget;
+
+class NavigationTree extends CDiv
+{
+
+ private array $data;
public function __construct(array $data = []) {
parent::__construct();
$this->data = $data;
- $this->setId(uniqid());
- $this->addClass(ZBX_STYLE_NAVIGATIONTREE);
+ $this
+ ->setId(uniqid('', true))
+ ->addClass(ZBX_STYLE_NAVIGATIONTREE);
}
- public function setError($value) {
- $this->error = $value;
- return $this;
- }
-
- public function getScriptData() {
+ public function getScriptData(): array {
return [
'problems' => $this->data['problems'],
'severity_levels' => $this->data['severity_config'],
@@ -48,19 +50,17 @@ class CNavigationTree extends CDiv {
'maps_accessible' => array_map('strval', $this->data['maps_accessible']),
'show_unavailable' => $this->data['show_unavailable'],
'initial_load' => $this->data['initial_load'],
- 'max_depth' => WIDGET_NAVIGATION_TREE_MAX_DEPTH
+ 'max_depth' => Widget::MAX_DEPTH
];
}
- private function build() {
- if ($this->error !== null) {
- $this->addClass(ZBX_STYLE_DISABLED);
- }
-
- $this->addItem((new CDiv())->addClass('tree'));
+ private function build(): void {
+ $this->addItem(
+ (new CDiv())->addClass('tree')
+ );
}
- public function toString($destroy = true) {
+ public function toString($destroy = true): string {
$this->build();
return parent::toString($destroy);
diff --git a/ui/widgets/navtree/includes/WidgetForm.php b/ui/widgets/navtree/includes/WidgetForm.php
new file mode 100644
index 00000000000..8cdeb8d4257
--- /dev/null
+++ b/ui/widgets/navtree/includes/WidgetForm.php
@@ -0,0 +1,49 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\NavTree\Includes;
+
+use Zabbix\Widgets\CWidgetForm;
+
+use Zabbix\Widgets\Fields\{
+ CWidgetFieldCheckBox,
+ CWidgetFieldNavTree,
+ CWidgetFieldReference
+};
+
+/**
+ * Map navigation widget form.
+ */
+class WidgetForm extends CWidgetForm {
+
+ public function addFields(): self {
+ return $this
+ ->addField(
+ new CWidgetFieldReference()
+ )
+ ->addField(
+ new CWidgetFieldNavTree('navtree')
+ )
+ ->addField(
+ new CWidgetFieldCheckBox('show_unavailable', _('Show unavailable maps'))
+ );
+ }
+}
diff --git a/ui/widgets/navtree/manifest.json b/ui/widgets/navtree/manifest.json
new file mode 100755
index 00000000000..c61b253e2d7
--- /dev/null
+++ b/ui/widgets/navtree/manifest.json
@@ -0,0 +1,31 @@
+{
+ "manifest_version": 2.0,
+ "id": "navtree",
+ "type": "widget",
+ "name": "Map navigation tree",
+ "namespace": "NavTree",
+ "version": "1.0",
+ "author": "Zabbix SIA",
+ "actions": {
+ "widget.navtree.item.edit": {
+ "class": "NavTreeItemEdit",
+ "view": "navtreeitem.edit",
+ "layout": "layout.json"
+ },
+ "widget.navtree.item.update": {
+ "class": "NavTreeItemUpdate",
+ "layout": "layout.json"
+ }
+ },
+ "widget": {
+ "size": {
+ "width": 6,
+ "height": 5
+ },
+ "js_class": "CWidgetNavTree",
+ "refresh_rate": 900
+ },
+ "assets": {
+ "js": ["class.widget.js"]
+ }
+}
diff --git a/ui/app/views/js/monitoring.widget.navtreeitem.edit.js.php b/ui/widgets/navtree/views/navtreeitem.edit.js.php
index fd68a9c09a0..8a2328db2ef 100644
--- a/ui/app/views/js/monitoring.widget.navtreeitem.edit.js.php
+++ b/ui/widgets/navtree/views/navtreeitem.edit.js.php
@@ -17,13 +17,9 @@
** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
-
-
-/**
- * @var CView $this
- */
?>
+
window.navtreeitem_edit_popup = new class {
init() {
jQuery('#sysmapname').on('change', (e) => {
diff --git a/ui/app/views/monitoring.widget.navtreeitem.edit.php b/ui/widgets/navtree/views/navtreeitem.edit.php
index 3cadc71947b..9abfe7ced60 100644
--- a/ui/app/views/monitoring.widget.navtreeitem.edit.php
+++ b/ui/widgets/navtree/views/navtreeitem.edit.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -20,47 +20,63 @@
/**
+ * Map navigation tree item edit form view.
+ *
* @var CView $this
+ * @var array $data
*/
+use Widgets\NavTree\Widget;
+
$form = (new CForm('post'))
->cleanItems()
->setId('widget-dialogue-form')
->setName('widget_dialogue_form')
->addItem((new CInput('submit', 'submit'))->addStyle('display: none;'));
-$form_list = (new CFormList())
- ->addRow(
+$form_grid = (new CFormGrid())
+ ->addItem([
(new CLabel(_('Name'), 'name'))->setAsteriskMark(),
- (new CTextBox('name', $data['name']))
- ->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
- ->setAttribute('autofocus', 'autofocus')
- ->setAriaRequired()
- )
- ->addRow(_('Linked map'), [
- new CVar('sysmapid', $data['sysmap']['sysmapid']),
- (new CTextBox('sysmapname', $data['sysmap']['name'], true))->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH),
- (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
- (new CButton('select', _('Select')))->addClass(ZBX_STYLE_BTN_GREY)
+ new CFormField(
+ (new CTextBox('name', $data['name']))
+ ->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
+ ->setAttribute('autofocus', 'autofocus')
+ ->setAriaRequired()
+ )
+ ])
+ ->addItem([
+ new CLabel(_('Linked map')),
+ new CFormField([
+ new CVar('sysmapid', $data['sysmap']['sysmapid']),
+ (new CTextBox('sysmapname', $data['sysmap']['name'], true))->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH),
+ (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
+ (new CButton('select', _('Select')))->addClass(ZBX_STYLE_BTN_GREY)
+ ])
]);
-if ($data['depth'] >= WIDGET_NAVIGATION_TREE_MAX_DEPTH) {
- $form_list->addRow(null, _('Cannot add submaps. Max depth reached.'));
+if ($data['depth'] >= Widget::MAX_DEPTH) {
+ $form_grid->addItem([
+ null,
+ new CFormField(_('Cannot add submaps. Max depth reached.'))
+ ]);
}
else {
- $form_list->addRow(null, [
- new CCheckBox('add_submaps', 1),
- new CLabel(_('Add submaps'), 'add_submaps')
+ $form_grid->addItem([
+ null,
+ new CFormField([
+ new CCheckBox('add_submaps', 1),
+ new CLabel(_('Add submaps'), 'add_submaps')
+ ])
]);
}
$form
- ->addItem($form_list)
+ ->addItem($form_grid)
->addItem((new CScriptTag('navtreeitem_edit_popup.init();'))->setOnDocumentReady());
$output = [
'body' => $form->toString(),
- 'script_inline' => $this->readJsFile('monitoring.widget.navtreeitem.edit.js.php')
+ 'script_inline' => $this->readJsFile('navtreeitem.edit.js.php', null, '')
];
if ($messages = get_and_clear_messages()) {
@@ -72,4 +88,4 @@ if ($data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
$output['debug'] = CProfiler::getInstance()->make()->toString();
}
-echo json_encode($output);
+echo json_encode($output, JSON_THROW_ON_ERROR);
diff --git a/ui/widgets/navtree/views/widget.edit.php b/ui/widgets/navtree/views/widget.edit.php
new file mode 100755
index 00000000000..9523d90642d
--- /dev/null
+++ b/ui/widgets/navtree/views/widget.edit.php
@@ -0,0 +1,53 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+/**
+ * Map navigation tree widget form view.
+ *
+ * @var CView $this
+ * @var array $data
+ */
+
+use Zabbix\Widgets\Fields\CWidgetFieldReference;
+
+$form = (new CWidgetFormView($data))
+ ->addFieldVar($data['fields'][CWidgetFieldReference::FIELD_NAME]);
+
+// Add dynamically created fields navtree.name.<N>, navtree.parent.<N>, navtree.order.<N> and navtree.sysmapid.<N>.
+foreach ($data['fields']['navtree']->getValue() as $i => $navtree_item) {
+ $form->addVar($data['fields']['navtree']->getName().'.name.'.$i, $navtree_item['name']);
+
+ if ($navtree_item['order'] != 1) {
+ $form->addVar($data['fields']['navtree']->getName().'.order.'.$i, $navtree_item['order']);
+ }
+
+ if ($navtree_item['parent'] != 0) {
+ $form->addVar($data['fields']['navtree']->getName().'.parent.'.$i, $navtree_item['parent']);
+ }
+
+ if (array_key_exists('sysmapid', $navtree_item)) {
+ $form->addVar($data['fields']['navtree']->getName().'.sysmapid.'.$i, $navtree_item['sysmapid']);
+ }
+}
+
+$form
+ ->addField(new CWidgetFieldCheckBoxView($data['fields']['show_unavailable']))
+ ->show();
diff --git a/ui/app/views/monitoring.widget.navtree.view.php b/ui/widgets/navtree/views/widget.view.php
index 3ec7643f991..ae0eefce964 100644
--- a/ui/app/views/monitoring.widget.navtree.view.php
+++ b/ui/widgets/navtree/views/widget.view.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -20,10 +20,15 @@
/**
+ * Map navigation tree widget view.
+ *
* @var CView $this
+ * @var array $data
*/
-$item = new CNavigationTree([
+use Widgets\NavTree\Includes\NavigationTree;
+
+$item = new NavigationTree([
'problems' => $data['problems'],
'severity_config' => $data['severity_config'],
'initial_load' => $data['initial_load'],
@@ -34,23 +39,7 @@ $item = new CNavigationTree([
'show_unavailable' => $data['show_unavailable']
]);
-if ($data['error'] !== null) {
- $item->setError($data['error']);
-}
-
-$output = [
- 'name' => $data['name'],
- 'body' => $item->toString(),
- 'navtree_data' => $item->getScriptData()
-];
-
-if ($messages = get_and_clear_messages()) {
- $output['messages'] = array_column($messages, 'message');
-}
-
-if ($data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
- CProfiler::getInstance()->stop();
- $output['debug'] = CProfiler::getInstance()->make()->toString();
-}
-
-echo json_encode($output);
+(new CWidgetView($data))
+ ->addItem($item)
+ ->setVar('navtree_data', $item->getScriptData())
+ ->show();
diff --git a/ui/widgets/plaintext/Widget.php b/ui/widgets/plaintext/Widget.php
new file mode 100755
index 00000000000..e5d5e71049b
--- /dev/null
+++ b/ui/widgets/plaintext/Widget.php
@@ -0,0 +1,31 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\PlainText;
+
+use Zabbix\Core\CWidget;
+
+class Widget extends CWidget {
+
+ public function getDefaultName(): string {
+ return _('Plain text');
+ }
+}
diff --git a/ui/app/controllers/CControllerWidgetPlainTextView.php b/ui/widgets/plaintext/actions/WidgetView.php
index 71b445664d2..3eb5972458a 100644
--- a/ui/app/controllers/CControllerWidgetPlainTextView.php
+++ b/ui/widgets/plaintext/actions/WidgetView.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,45 +19,50 @@
**/
-/**
- * Class for Dashboard Plain-text widget view.
- */
-class CControllerWidgetPlainTextView extends CControllerWidget {
+namespace Widgets\PlainText\Actions;
- public function __construct() {
- parent::__construct();
+use API,
+ CArrayHelper,
+ CControllerDashboardWidgetView,
+ CControllerResponseData,
+ CJsScript,
+ CPre,
+ Manager;
- $this->setType(WIDGET_PLAIN_TEXT);
- $this->setValidationRules([
- 'name' => 'string',
- 'fields' => 'json',
+use Zabbix\Core\CWidget;
+
+class WidgetView extends CControllerDashboardWidgetView {
+
+ protected function init(): void {
+ parent::init();
+
+ $this->addValidationRules([
'dynamic_hostid' => 'db hosts.hostid'
]);
}
- protected function doAction() {
- $fields = $this->getForm()->getFieldsData();
+ protected function doAction(): void {
$error = null;
- $dynamic_widget_name = $this->getDefaultName();
+ $dynamic_widget_name = $this->widget->getDefaultName();
$same_host = true;
$items = [];
$histories = [];
// Editing template dashboard?
- if ($this->getContext() === CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD && !$this->hasInput('dynamic_hostid')) {
+ if ($this->hasInput('templateid') && !$this->hasInput('dynamic_hostid')) {
$error = _('No data.');
}
else {
- $is_template_dashboard = ($this->getContext() === CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD);
- $is_dynamic_item = ($is_template_dashboard || $fields['dynamic'] == WIDGET_DYNAMIC_ITEM);
+ $is_template_dashboard = $this->hasInput('templateid');
+ $is_dynamic_item = ($is_template_dashboard || $this->fields_values['dynamic'] == CWidget::DYNAMIC_ITEM);
- if ($fields['itemids']) {
+ if ($this->fields_values['itemids']) {
$items = API::Item()->get([
'output' => ['itemid', 'name', 'key_', 'value_type', 'units', 'valuemapid'],
'selectHosts' => ['name'],
'selectValueMap' => ['mappings'],
- 'itemids' => $fields['itemids'],
+ 'itemids' => $this->fields_values['itemids'],
'webitems' => true,
'preservekeys' => true
]);
@@ -83,14 +88,14 @@ class CControllerWidgetPlainTextView extends CControllerWidget {
$error = _('No permissions to referred object or it does not exist!');
}
else {
- $histories = Manager::History()->getLastValues($items, $fields['show_lines']);
+ $histories = Manager::History()->getLastValues($items, $this->fields_values['show_lines']);
if ($histories) {
- $histories = call_user_func_array('array_merge', $histories);
+ $histories = array_merge(...$histories);
foreach ($histories as &$history) {
$history['value'] = formatHistoryValue($history['value'], $items[$history['itemid']], false);
- $history['value'] = $fields['show_as_html']
+ $history['value'] = $this->fields_values['show_as_html']
? new CJsScript($history['value'])
: new CPre($history['value']);
}
@@ -133,9 +138,9 @@ class CControllerWidgetPlainTextView extends CControllerWidget {
'name' => $this->getInput('name', $dynamic_widget_name),
'items' => $items,
'histories' => $histories,
- 'style' => $fields['style'],
+ 'style' => $this->fields_values['style'],
'same_host' => $same_host,
- 'show_lines' => $fields['show_lines'],
+ 'show_lines' => $this->fields_values['show_lines'],
'error' => $error,
'user' => [
'debug_mode' => $this->getDebugMode()
diff --git a/ui/widgets/plaintext/includes/WidgetForm.php b/ui/widgets/plaintext/includes/WidgetForm.php
new file mode 100644
index 00000000000..ae1d9135e2a
--- /dev/null
+++ b/ui/widgets/plaintext/includes/WidgetForm.php
@@ -0,0 +1,68 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\PlainText\Includes;
+
+use Zabbix\Widgets\{
+ CWidgetField,
+ CWidgetForm
+};
+
+use Zabbix\Widgets\Fields\{
+ CWidgetFieldCheckBox,
+ CWidgetFieldIntegerBox,
+ CWidgetFieldMultiSelectItem,
+ CWidgetFieldRadioButtonList
+};
+
+/**
+ * Plain text widget form.
+ */
+class WidgetForm extends CWidgetForm {
+
+ public function addFields(): self {
+ return $this
+ ->addField(
+ (new CWidgetFieldMultiSelectItem('itemids', _('Items'), $this->templateid))
+ ->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('style', _('Items location'), [
+ STYLE_LEFT => _('Left'),
+ STYLE_TOP => _('Top')
+ ]))->setDefault(STYLE_LEFT)
+ )
+ ->addField(
+ (new CWidgetFieldIntegerBox('show_lines', _('Show lines'), ZBX_MIN_WIDGET_LINES,
+ ZBX_MAX_WIDGET_LINES
+ ))
+ ->setDefault(ZBX_DEFAULT_WIDGET_LINES)
+ ->setFlags(CWidgetField::FLAG_LABEL_ASTERISK)
+ )
+ ->addField(
+ new CWidgetFieldCheckBox('show_as_html', _('Show text as HTML'))
+ )
+ ->addField($this->templateid === null
+ ? new CWidgetFieldCheckBox('dynamic', _('Enable host selection'))
+ : null
+ );
+ }
+}
diff --git a/ui/widgets/plaintext/manifest.json b/ui/widgets/plaintext/manifest.json
new file mode 100755
index 00000000000..0a67be5aea9
--- /dev/null
+++ b/ui/widgets/plaintext/manifest.json
@@ -0,0 +1,16 @@
+{
+ "manifest_version": 2.0,
+ "id": "plaintext",
+ "type": "widget",
+ "name": "Plain text",
+ "namespace": "PlainText",
+ "version": "1.0",
+ "author": "Zabbix SIA",
+ "widget": {
+ "template_support": true,
+ "size": {
+ "width": 6,
+ "height": 3
+ }
+ }
+}
diff --git a/ui/include/classes/widgets/views/widget.systeminfo.form.view.php b/ui/widgets/plaintext/views/widget.edit.php
index 83a7fc8d19f..2da1e13b652 100644..100755
--- a/ui/include/classes/widgets/views/widget.systeminfo.form.view.php
+++ b/ui/widgets/plaintext/views/widget.edit.php
@@ -20,29 +20,27 @@
/**
- * System information widget form view.
+ * Plain text widget form view.
*
* @var CView $this
* @var array $data
*/
-$fields = $data['dialogue']['fields'];
-
-$form = CWidgetHelper::createForm();
-
-$form_grid = CWidgetHelper::createFormGrid($data['dialogue']['name'], $data['dialogue']['type'],
- $data['dialogue']['view_mode'], $data['known_widget_types'],
- $data['templateid'] === null ? $fields['rf_rate'] : null
-);
-
-// Show.
-$form_grid->addItem([
- CWidgetHelper::getLabel($fields['info_type']),
- new CFormField(CWidgetHelper::getRadioButtonList($fields['info_type']))
-]);
-
-$form->addItem($form_grid);
-
-return [
- 'form' => $form
-];
+(new CWidgetFormView($data))
+ ->addField(
+ new CWidgetFieldMultiSelectItemView($data['fields']['itemids'], $data['captions']['ms']['items']['itemids'])
+ )
+ ->addField(
+ new CWidgetFieldRadioButtonListView($data['fields']['style'])
+ )
+ ->addField(
+ new CWidgetFieldIntegerBoxView($data['fields']['show_lines'])
+ )
+ ->addField(
+ new CWidgetFieldCheckBoxView($data['fields']['show_as_html'])
+ )
+ ->addField(array_key_exists('dynamic', $data['fields'])
+ ? new CWidgetFieldCheckBoxView($data['fields']['dynamic'])
+ : null
+ )
+ ->show();
diff --git a/ui/app/views/monitoring.widget.plaintext.view.php b/ui/widgets/plaintext/views/widget.view.php
index 6da0507002e..5ddea6ea7e0 100644
--- a/ui/app/views/monitoring.widget.plaintext.view.php
+++ b/ui/widgets/plaintext/views/widget.view.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -20,6 +20,8 @@
/**
+ * Plain text widget view.
+ *
* @var CView $this
* @var array $data
*/
@@ -74,9 +76,10 @@ else {
}
else {
if (($history_item === null && $row_values)
- || $history_item !== null
- && (($clock != 0 && $history_item['clock'] != $clock)
- || array_key_exists($history_item['itemid'], $row_values))) {
+ || ($history_item !== null && (
+ ($clock != 0 && $history_item['clock'] != $clock)
+ || array_key_exists($history_item['itemid'], $row_values)))
+ ) {
$table_row = [
(new CCol(zbx_date2str(DATE_TIME_FORMAT_SECONDS, $clock)))->addClass(ZBX_STYLE_NOWRAP)
];
@@ -97,18 +100,6 @@ else {
} while ($history_item !== null && $table->getNumRows() < $data['show_lines']);
}
-$output = [
- 'name' => $data['name'],
- 'body' => $table->toString()
-];
-
-if ($messages = get_and_clear_messages()) {
- $output['messages'] = array_column($messages, 'message');
-}
-
-if ($data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
- CProfiler::getInstance()->stop();
- $output['debug'] = CProfiler::getInstance()->make()->toString();
-}
-
-echo json_encode($output);
+(new CWidgetView($data))
+ ->addItem($table)
+ ->show();
diff --git a/ui/widgets/problemhosts/Widget.php b/ui/widgets/problemhosts/Widget.php
new file mode 100755
index 00000000000..038bb9a766f
--- /dev/null
+++ b/ui/widgets/problemhosts/Widget.php
@@ -0,0 +1,31 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\ProblemHosts;
+
+use Zabbix\Core\CWidget;
+
+class Widget extends CWidget {
+
+ public function getDefaultName(): string {
+ return _('Problem hosts');
+ }
+}
diff --git a/ui/app/controllers/CControllerWidgetProblemHostsView.php b/ui/widgets/problemhosts/actions/WidgetView.php
index 5bbebf8efe1..63ff9ee9947 100644
--- a/ui/app/controllers/CControllerWidgetProblemHostsView.php
+++ b/ui/widgets/problemhosts/actions/WidgetView.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,41 +19,35 @@
**/
-require_once dirname(__FILE__).'/../../include/blocks.inc.php';
+namespace Widgets\ProblemHosts\Actions;
-class CControllerWidgetProblemHostsView extends CControllerWidget {
+use API,
+ CArrayHelper,
+ CControllerDashboardWidgetView,
+ CControllerResponseData,
+ CRoleHelper;
- public function __construct() {
- parent::__construct();
+class WidgetView extends CControllerDashboardWidgetView {
- $this->setType(WIDGET_PROBLEM_HOSTS);
- $this->setValidationRules([
- 'name' => 'string',
- 'fields' => 'json'
- ]);
- }
-
- protected function doAction() {
- $fields = $this->getForm()->getFieldsData();
-
- $filter_groupids = $fields['groupids'] ? getSubGroups($fields['groupids']) : null;
- $filter_hostids = $fields['hostids'] ? $fields['hostids'] : null;
- $filter_problem = ($fields['problem'] !== '') ? $fields['problem'] : null;
- $filter_severities = $fields['severities']
- ? $fields['severities']
- : range(TRIGGER_SEVERITY_NOT_CLASSIFIED, TRIGGER_SEVERITY_COUNT - 1);
- $filter_show_suppressed = $fields['show_suppressed'];
- $filter_ext_ack = $fields['ext_ack'];
+ protected function doAction(): void {
+ $filter_groupids = $this->fields_values['groupids'] ? getSubGroups($this->fields_values['groupids']) : null;
+ $filter_hostids = $this->fields_values['hostids'] ?: null;
+ $filter_problem = $this->fields_values['problem'] !== '' ? $this->fields_values['problem'] : null;
+ $filter_severities = $this->fields_values['severities'] ?: range(TRIGGER_SEVERITY_NOT_CLASSIFIED,
+ TRIGGER_SEVERITY_COUNT - 1
+ );
+ $filter_show_suppressed = $this->fields_values['show_suppressed'];
+ $filter_ext_ack = $this->fields_values['ext_ack'];
- if ($fields['exclude_groupids']) {
- $exclude_groupids = getSubGroups($fields['exclude_groupids']);
+ if ($this->fields_values['exclude_groupids']) {
+ $exclude_groupids = getSubGroups($this->fields_values['exclude_groupids']);
if ($filter_hostids === null) {
// Get all groups if no selected groups defined.
if ($filter_groupids === null) {
$filter_groupids = array_keys(API::HostGroup()->get([
'output' => [],
- 'real_hosts' => true,
+ 'with_hosts' => true,
'preservekeys' => true
]));
}
@@ -143,8 +137,8 @@ class CControllerWidgetProblemHostsView extends CControllerWidget {
'name' => $filter_problem
],
'severities' => $filter_severities,
- 'evaltype' => $fields['evaltype'],
- 'tags' => $fields['tags'],
+ 'evaltype' => $this->fields_values['evaltype'],
+ 'tags' => $this->fields_values['tags'],
'acknowledged' => ($filter_ext_ack == EXTACK_OPTION_UNACK) ? false : null,
'suppressed' => ($filter_show_suppressed == ZBX_PROBLEM_SUPPRESSED_FALSE) ? false : null
]);
@@ -232,14 +226,14 @@ class CControllerWidgetProblemHostsView extends CControllerWidget {
// Pass results to view.
$this->setResponse(new CControllerResponseData([
- 'name' => $this->getInput('name', $this->getDefaultName()),
+ 'name' => $this->getInput('name', $this->widget->getDefaultName()),
'filter' => [
- 'hostids' => $fields['hostids'],
- 'problem' => $fields['problem'],
+ 'hostids' => $this->fields_values['hostids'],
+ 'problem' => $this->fields_values['problem'],
'severities' => $filter_severities,
- 'show_suppressed' => $fields['show_suppressed'],
- 'hide_empty_groups' => $fields['hide_empty_groups'],
- 'ext_ack' => $fields['ext_ack']
+ 'show_suppressed' => $this->fields_values['show_suppressed'],
+ 'hide_empty_groups' => $this->fields_values['hide_empty_groups'],
+ 'ext_ack' => $this->fields_values['ext_ack']
],
'hosts_data' => $hosts_data,
'groups' => $groups,
diff --git a/ui/widgets/problemhosts/includes/WidgetForm.php b/ui/widgets/problemhosts/includes/WidgetForm.php
new file mode 100644
index 00000000000..020df198807
--- /dev/null
+++ b/ui/widgets/problemhosts/includes/WidgetForm.php
@@ -0,0 +1,86 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\ProblemHosts\Includes;
+
+use Zabbix\Widgets\{
+ CWidgetField,
+ CWidgetForm
+};
+
+use Zabbix\Widgets\Fields\{
+ CWidgetFieldCheckBox,
+ CWidgetFieldMultiSelectGroup,
+ CWidgetFieldMultiSelectHost,
+ CWidgetFieldRadioButtonList,
+ CWidgetFieldSeverities,
+ CWidgetFieldTags,
+ CWidgetFieldTextBox
+};
+
+/**
+ * Problem hosts widget form.
+ */
+class WidgetForm extends CWidgetForm {
+
+ public function addFields(): self {
+ return $this
+ ->addField(
+ new CWidgetFieldMultiSelectGroup('groupids', _('Host groups'))
+ )
+ ->addField(
+ new CWidgetFieldMultiSelectGroup('exclude_groupids', _('Exclude host groups'))
+ )
+ ->addField(
+ new CWidgetFieldMultiSelectHost('hostids', _('Hosts'))
+ )
+ ->addField(
+ new CWidgetFieldTextBox('problem', _('Problem'))
+ )
+ ->addField(
+ new CWidgetFieldSeverities('severities', _('Severity'))
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('evaltype', _('Tags'), [
+ TAG_EVAL_TYPE_AND_OR => _('And/Or'),
+ TAG_EVAL_TYPE_OR => _('Or')
+ ]))->setDefault(TAG_EVAL_TYPE_AND_OR)
+ )
+ ->addField(
+ new CWidgetFieldTags('tags')
+ )
+ ->addField(
+ new CWidgetFieldCheckBox('show_suppressed', _('Show suppressed problems'))
+ )
+ ->addField(
+ new CWidgetFieldCheckBox('hide_empty_groups', _('Hide groups without problems'))
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('ext_ack', _('Problem display'), [
+ EXTACK_OPTION_ALL => _('All'),
+ EXTACK_OPTION_BOTH => _('Separated'),
+ EXTACK_OPTION_UNACK => _('Unacknowledged only')
+ ]))
+ ->setDefault(EXTACK_OPTION_ALL)
+ ->setFlags(CWidgetField::FLAG_ACKNOWLEDGES)
+ );
+ }
+}
diff --git a/ui/widgets/problemhosts/manifest.json b/ui/widgets/problemhosts/manifest.json
new file mode 100755
index 00000000000..64e49e8a263
--- /dev/null
+++ b/ui/widgets/problemhosts/manifest.json
@@ -0,0 +1,9 @@
+{
+ "manifest_version": 2.0,
+ "id": "problemhosts",
+ "type": "widget",
+ "name": "Problem hosts",
+ "namespace": "ProblemHosts",
+ "version": "1.0",
+ "author": "Zabbix SIA"
+}
diff --git a/ui/widgets/problemhosts/views/widget.edit.php b/ui/widgets/problemhosts/views/widget.edit.php
new file mode 100755
index 00000000000..3aefd30aeb9
--- /dev/null
+++ b/ui/widgets/problemhosts/views/widget.edit.php
@@ -0,0 +1,65 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+/**
+ * Problem hosts widget form view.
+ *
+ * @var CView $this
+ * @var array $data
+ */
+
+$groupids = new CWidgetFieldMultiSelectGroupView($data['fields']['groupids'],
+ $data['captions']['ms']['groups']['groupids']
+);
+
+(new CWidgetFormView($data))
+ ->addField($groupids)
+ ->addField(
+ new CWidgetFieldMultiSelectGroupView($data['fields']['exclude_groupids'],
+ $data['captions']['ms']['groups']['exclude_groupids']
+ )
+ )
+ ->addField(
+ (new CWidgetFieldMultiSelectHostView($data['fields']['hostids'], $data['captions']['ms']['hosts']['hostids']))
+ ->setFilterPreselect(['id' => $groupids->getId(), 'submit_as' => 'groupid'])
+ )
+ ->addField(
+ new CWidgetFieldTextBoxView($data['fields']['problem'])
+ )
+ ->addField(
+ new CWidgetFieldSeveritiesView($data['fields']['severities'])
+ )
+ ->addField(
+ new CWidgetFieldRadioButtonListView($data['fields']['evaltype'])
+ )
+ ->addField(
+ new CWidgetFieldTagsView($data['fields']['tags'])
+ )
+ ->addField(
+ new CWidgetFieldCheckBoxView($data['fields']['show_suppressed'])
+ )
+ ->addField(
+ new CWidgetFieldCheckBoxView($data['fields']['hide_empty_groups'])
+ )
+ ->addField(
+ new CWidgetFieldRadioButtonListView($data['fields']['ext_ack'])
+ )
+ ->show();
diff --git a/ui/app/views/monitoring.widget.problemhosts.view.php b/ui/widgets/problemhosts/views/widget.view.php
index 6057af525a5..0489e1638ff 100644
--- a/ui/app/views/monitoring.widget.problemhosts.view.php
+++ b/ui/widgets/problemhosts/views/widget.view.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -20,6 +20,8 @@
/**
+ * Problem hosts widget view.
+ *
* @var CView $this
* @var array $data
*/
@@ -39,7 +41,7 @@ $table = (new CTableInfo())
$url_group = $data['allowed_ui_problems']
? (new CUrl('zabbix.php'))
->setArgument('action', 'problem.view')
- ->setArgument('filter_name', '')
+ ->setArgument('filter_name')
->setArgument('show', TRIGGERS_OPTION_RECENT_PROBLEM)
->setArgument('hostids', $data['filter']['hostids'])
->setArgument('name', $data['filter']['problem'])
@@ -51,7 +53,7 @@ $url_group = $data['allowed_ui_problems']
$url_host = $data['allowed_ui_problems']
? (new CUrl('zabbix.php'))
->setArgument('action', 'problem.view')
- ->setArgument('filter_name', '')
+ ->setArgument('filter_name')
->setArgument('show', TRIGGERS_OPTION_RECENT_PROBLEM)
->setArgument('name', $data['filter']['problem'])
->setArgument('show_suppressed', ($data['filter']['show_suppressed'] == ZBX_PROBLEM_SUPPRESSED_TRUE)
@@ -125,7 +127,7 @@ foreach ($data['groups'] as $group) {
case EXTACK_OPTION_BOTH:
if ($group['hosts_problematic_count'] != 0) {
- $unack_span = ($last_unack_count !== null) ? [$last_unack_count, ' '._('of').' '] : null;
+ $unack_span = $last_unack_count !== null ? [$last_unack_count, ' '._('of').' '] : null;
$group_row[] = (new CCol([$unack_span, $problematic_count]))
->addClass(CSeverityHelper::getStyle((int) $group['highest_severity']));
}
@@ -151,18 +153,6 @@ foreach ($data['groups'] as $group) {
$table->addRow($group_row);
}
-$output = [
- 'name' => $data['name'],
- 'body' => $table->toString()
-];
-
-if ($messages = get_and_clear_messages()) {
- $output['messages'] = array_column($messages, 'message');
-}
-
-if ($data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
- CProfiler::getInstance()->stop();
- $output['debug'] = CProfiler::getInstance()->make()->toString();
-}
-
-echo json_encode($output);
+(new CWidgetView($data))
+ ->addItem($table)
+ ->show();
diff --git a/ui/widgets/problems/Widget.php b/ui/widgets/problems/Widget.php
new file mode 100755
index 00000000000..1eea9555573
--- /dev/null
+++ b/ui/widgets/problems/Widget.php
@@ -0,0 +1,31 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\Problems;
+
+use Zabbix\Core\CWidget;
+
+class Widget extends CWidget {
+
+ public function getDefaultName(): string {
+ return _('Problems');
+ }
+}
diff --git a/ui/app/controllers/CControllerWidgetProblemsView.php b/ui/widgets/problems/actions/WidgetView.php
index ee71c1ce81d..a9b0d769579 100644
--- a/ui/app/controllers/CControllerWidgetProblemsView.php
+++ b/ui/widgets/problems/actions/WidgetView.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,41 +19,45 @@
**/
-class CControllerWidgetProblemsView extends CControllerWidget {
+namespace Widgets\Problems\Actions;
- public function __construct() {
- parent::__construct();
+use CControllerDashboardWidgetView,
+ CControllerResponseData,
+ CRoleHelper,
+ CScreenProblem,
+ CSettingsHelper;
- $this->setType(WIDGET_PROBLEMS);
- $this->setValidationRules([
- 'name' => 'string',
- 'fields' => 'json',
+class WidgetView extends CControllerDashboardWidgetView {
+
+ protected function init(): void {
+ parent::init();
+
+ $this->addValidationRules([
'initial_load' => 'in 0,1'
]);
}
- protected function doAction() {
- $fields = $this->getForm()->getFieldsData();
-
+ protected function doAction(): void {
$data = CScreenProblem::getData([
- 'show' => $fields['show'],
- 'groupids' => $fields['groupids'],
- 'exclude_groupids' => $fields['exclude_groupids'],
- 'hostids' => $fields['hostids'],
- 'name' => $fields['problem'],
- 'severities' => $fields['severities'],
- 'evaltype' => $fields['evaltype'],
- 'tags' => $fields['tags'],
- 'show_suppressed' => $fields['show_suppressed'],
- 'unacknowledged' => $fields['unacknowledged'],
- 'show_opdata' => $fields['show_opdata']
+ 'show' => $this->fields_values['show'],
+ 'groupids' => $this->fields_values['groupids'],
+ 'exclude_groupids' => $this->fields_values['exclude_groupids'],
+ 'hostids' => $this->fields_values['hostids'],
+ 'name' => $this->fields_values['problem'],
+ 'severities' => $this->fields_values['severities'],
+ 'evaltype' => $this->fields_values['evaltype'],
+ 'tags' => $this->fields_values['tags'],
+ 'show_suppressed' => $this->fields_values['show_suppressed'],
+ 'unacknowledged' => $this->fields_values['unacknowledged'],
+ 'show_opdata' => $this->fields_values['show_opdata']
]);
- list($sortfield, $sortorder) = self::getSorting($fields['sort_triggers']);
+
+ [$sortfield, $sortorder] = self::getSorting($this->fields_values['sort_triggers']);
$data = CScreenProblem::sortData($data, $sortfield, $sortorder);
- if (count($data['problems']) > $fields['show_lines']) {
+ if (count($data['problems']) > $this->fields_values['show_lines']) {
$info = _n('%1$d of %3$d%2$s problem is shown', '%1$d of %3$d%2$s problems are shown',
- min($fields['show_lines'], count($data['problems'])),
+ min($this->fields_values['show_lines'], count($data['problems'])),
(count($data['problems']) > CSettingsHelper::get(CSettingsHelper::SEARCH_LIMIT)) ? '+' : '',
min(CSettingsHelper::get(CSettingsHelper::SEARCH_LIMIT), count($data['problems']))
);
@@ -61,17 +65,18 @@ class CControllerWidgetProblemsView extends CControllerWidget {
else {
$info = '';
}
- $data['problems'] = array_slice($data['problems'], 0, $fields['show_lines'], true);
+ $data['problems'] = array_slice($data['problems'], 0, $this->fields_values['show_lines'], true);
$data = CScreenProblem::makeData($data, [
- 'show' => $fields['show'],
+ 'show' => $this->fields_values['show'],
'details' => 0,
- 'show_opdata' => $fields['show_opdata']
+ 'show_opdata' => $this->fields_values['show_opdata']
]);
- if ($fields['show_tags']) {
- $data['tags'] = makeTags($data['problems'], true, 'eventid', $fields['show_tags'], $fields['tags'], null,
- $fields['tag_name_format'], $fields['tag_priority']
+ if ($this->fields_values['show_tags']) {
+ $data['tags'] = makeTags($data['problems'], true, 'eventid', $this->fields_values['show_tags'],
+ $this->fields_values['tags'], null, $this->fields_values['tag_name_format'],
+ $this->fields_values['tag_priority']
);
}
@@ -80,17 +85,17 @@ class CControllerWidgetProblemsView extends CControllerWidget {
}
$this->setResponse(new CControllerResponseData([
- 'name' => $this->getInput('name', $this->getDefaultName()),
+ 'name' => $this->getInput('name', $this->widget->getDefaultName()),
'initial_load' => (bool) $this->getInput('initial_load', 0),
'fields' => [
- 'show' => $fields['show'],
- 'show_lines' => $fields['show_lines'],
- 'show_tags' => $fields['show_tags'],
- 'show_timeline' => $fields['show_timeline'],
- 'tags' => $fields['tags'],
- 'tag_name_format' => $fields['tag_name_format'],
- 'tag_priority' => $fields['tag_priority'],
- 'show_opdata' => $fields['show_opdata']
+ 'show' => $this->fields_values['show'],
+ 'show_lines' => $this->fields_values['show_lines'],
+ 'show_tags' => $this->fields_values['show_tags'],
+ 'show_timeline' => $this->fields_values['show_timeline'],
+ 'tags' => $this->fields_values['tags'],
+ 'tag_name_format' => $this->fields_values['tag_name_format'],
+ 'tag_priority' => $this->fields_values['tag_priority'],
+ 'show_opdata' => $this->fields_values['show_opdata']
],
'data' => $data,
'info' => $info,
@@ -113,17 +118,7 @@ class CControllerWidgetProblemsView extends CControllerWidget {
]));
}
- /**
- * Get sorting.
- *
- * @param int $sort_triggers
- *
- * @static
- *
- * @return array
- */
- private static function getSorting($sort_triggers)
- {
+ private static function getSorting(int $sort_triggers): array {
switch ($sort_triggers) {
case SCREEN_SORT_TRIGGERS_TIME_ASC:
return ['clock', ZBX_SORT_UP];
diff --git a/ui/js/widgets/class.widget.problems.js b/ui/widgets/problems/assets/js/class.widget.js
index 74f24f02da6..74f24f02da6 100644..100755
--- a/ui/js/widgets/class.widget.problems.js
+++ b/ui/widgets/problems/assets/js/class.widget.js
diff --git a/ui/widgets/problems/includes/WidgetForm.php b/ui/widgets/problems/includes/WidgetForm.php
new file mode 100644
index 00000000000..74ef9ea6810
--- /dev/null
+++ b/ui/widgets/problems/includes/WidgetForm.php
@@ -0,0 +1,159 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\Problems\Includes;
+
+use Zabbix\Widgets\{
+ CWidgetField,
+ CWidgetForm
+};
+
+use Zabbix\Widgets\Fields\{
+ CWidgetFieldCheckBox,
+ CWidgetFieldIntegerBox,
+ CWidgetFieldMultiSelectGroup,
+ CWidgetFieldMultiSelectHost,
+ CWidgetFieldRadioButtonList,
+ CWidgetFieldSelect,
+ CWidgetFieldSeverities,
+ CWidgetFieldTags,
+ CWidgetFieldTextBox
+};
+
+/**
+ * Problems widget form.
+ */
+class WidgetForm extends CWidgetForm {
+
+ private bool $show_tags = false;
+
+ protected function normalizeValues(array $values): array {
+ $values = self::convertDottedKeys($values);
+
+ if (array_key_exists('show_tags', $values)) {
+ $this->show_tags = $values['show_tags'] !== SHOW_TAGS_NONE;
+ }
+
+ return $values;
+ }
+
+ public function addFields(): self {
+ return $this
+ ->addField(
+ (new CWidgetFieldRadioButtonList('show', _('Show'), [
+ TRIGGERS_OPTION_RECENT_PROBLEM => _('Recent problems'),
+ TRIGGERS_OPTION_IN_PROBLEM => _('Problems'),
+ TRIGGERS_OPTION_ALL => _('History')
+ ]))->setDefault(TRIGGERS_OPTION_RECENT_PROBLEM)
+ )
+ ->addField(
+ new CWidgetFieldMultiSelectGroup('groupids', _('Host groups'))
+ )
+ ->addField(
+ new CWidgetFieldMultiSelectGroup('exclude_groupids', _('Exclude host groups'))
+ )
+ ->addField(
+ new CWidgetFieldMultiSelectHost('hostids', _('Hosts'))
+ )
+ ->addField(
+ new CWidgetFieldTextBox('problem', _('Problem'))
+ )
+ ->addField(
+ new CWidgetFieldSeverities('severities', _('Severity'))
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('evaltype', _('Tags'), [
+ TAG_EVAL_TYPE_AND_OR => _('And/Or'),
+ TAG_EVAL_TYPE_OR => _('Or')
+ ]))->setDefault(TAG_EVAL_TYPE_AND_OR)
+ )
+ ->addField(
+ new CWidgetFieldTags('tags')
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('show_tags', _('Show tags'), [
+ SHOW_TAGS_NONE => _('None'),
+ SHOW_TAGS_1 => SHOW_TAGS_1,
+ SHOW_TAGS_2 => SHOW_TAGS_2,
+ SHOW_TAGS_3 => SHOW_TAGS_3
+ ]))->setDefault(SHOW_TAGS_NONE)
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('tag_name_format', _('Tag name'), [
+ TAG_NAME_FULL => _('Full'),
+ TAG_NAME_SHORTENED => _('Shortened'),
+ TAG_NAME_NONE => _('None')
+ ]))
+ ->setDefault(TAG_NAME_FULL)
+ ->setFlags($this->show_tags ? 0x00 : CWidgetField::FLAG_DISABLED)
+ )
+ ->addField(
+ (new CWidgetFieldTextBox('tag_priority', _('Tag display priority')))
+ ->setFlags($this->show_tags ? 0x00 : CWidgetField::FLAG_DISABLED)
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('show_opdata', _('Show operational data'), [
+ OPERATIONAL_DATA_SHOW_NONE => _('None'),
+ OPERATIONAL_DATA_SHOW_SEPARATELY => _('Separately'),
+ OPERATIONAL_DATA_SHOW_WITH_PROBLEM => _('With problem name')
+ ]))->setDefault(OPERATIONAL_DATA_SHOW_NONE)
+ )
+ ->addField(
+ new CWidgetFieldCheckBox('show_suppressed', _('Show suppressed problems'))
+ )
+ ->addField(
+ (new CWidgetFieldCheckBox('unacknowledged', _('Show unacknowledged only')))
+ ->setFlags(CWidgetField::FLAG_ACKNOWLEDGES)
+ )
+ ->addField(
+ (new CWidgetFieldSelect('sort_triggers', _('Sort entries by'), [
+ SCREEN_SORT_TRIGGERS_TIME_DESC => _('Time').' ('._('descending').')',
+ SCREEN_SORT_TRIGGERS_TIME_ASC => _('Time').' ('._('ascending').')',
+ SCREEN_SORT_TRIGGERS_SEVERITY_DESC => _('Severity').' ('._('descending').')',
+ SCREEN_SORT_TRIGGERS_SEVERITY_ASC => _('Severity').' ('._('ascending').')',
+ SCREEN_SORT_TRIGGERS_NAME_DESC => _('Problem').' ('._('descending').')',
+ SCREEN_SORT_TRIGGERS_NAME_ASC => _('Problem').' ('._('ascending').')',
+ SCREEN_SORT_TRIGGERS_HOST_NAME_DESC => _('Host').' ('._('descending').')',
+ SCREEN_SORT_TRIGGERS_HOST_NAME_ASC => _('Host').' ('._('ascending').')'
+ ]))->setDefault(SCREEN_SORT_TRIGGERS_TIME_DESC)
+ )
+ ->addField(
+ (new CWidgetFieldCheckBox('show_timeline', _('Show timeline')))
+ ->setDefault(ZBX_TIMELINE_ON)
+ ->setFlags(
+ !array_key_exists('sort_triggers', $this->values)
+ || !array_key_exists($this->values['sort_triggers'], [
+ SCREEN_SORT_TRIGGERS_TIME_DESC => true,
+ SCREEN_SORT_TRIGGERS_TIME_ASC => true
+ ])
+ ? CWidgetField::FLAG_DISABLED
+ : 0x00
+ )
+ )
+ ->addField(
+ (new CWidgetFieldIntegerBox('show_lines', _('Show lines'), ZBX_MIN_WIDGET_LINES,
+ ZBX_MAX_WIDGET_LINES
+ ))
+ ->setDefault(ZBX_DEFAULT_WIDGET_LINES)
+ ->setFlags(CWidgetField::FLAG_LABEL_ASTERISK)
+ );
+ }
+}
diff --git a/ui/widgets/problems/manifest.json b/ui/widgets/problems/manifest.json
new file mode 100755
index 00000000000..163736d87a9
--- /dev/null
+++ b/ui/widgets/problems/manifest.json
@@ -0,0 +1,15 @@
+{
+ "manifest_version": 2.0,
+ "id": "problems",
+ "type": "widget",
+ "name": "Problems",
+ "namespace": "Problems",
+ "version": "1.0",
+ "author": "Zabbix SIA",
+ "widget": {
+ "js_class": "CWidgetProblems"
+ },
+ "assets": {
+ "js": ["class.widget.js"]
+ }
+}
diff --git a/ui/widgets/problems/views/widget.edit.js.php b/ui/widgets/problems/views/widget.edit.js.php
new file mode 100755
index 00000000000..08a310da9d9
--- /dev/null
+++ b/ui/widgets/problems/views/widget.edit.js.php
@@ -0,0 +1,59 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+?>
+
+
+window.widget_problems_form = new class {
+
+ init({sort_with_enabled_show_timeline}) {
+ this._sort_with_enabled_show_timeline = sort_with_enabled_show_timeline;
+
+ this._show_tags = document.getElementById('show_tags');
+ this._show_tags.addEventListener('change', () => this.updateForm());
+
+ this._sort_triggers = document.getElementById('sort_triggers');
+ this._sort_triggers.addEventListener('change', () => this.updateForm());
+
+ this._show_timeline = document.getElementById('show_timeline');
+ this._show_timeline_value = this._show_timeline.checked;
+
+ this.updateForm();
+ }
+
+ updateForm() {
+ const show_tags = this._show_tags.querySelector('input:checked').value != <?= SHOW_TAGS_NONE ?>;
+
+ document.getElementById('tag_priority').disabled = !show_tags;
+
+ for (const radio of document.querySelectorAll('#tag_name_format input')) {
+ radio.disabled = !show_tags;
+ }
+
+ if (this._sort_with_enabled_show_timeline[this._sort_triggers.value]) {
+ this._show_timeline.disabled = false;
+ this._show_timeline.checked = this._show_timeline_value;
+ }
+ else {
+ this._show_timeline.disabled = true;
+ this._show_timeline_value = this._show_timeline.checked;
+ this._show_timeline.checked = false;
+ }
+ }
+};
diff --git a/ui/widgets/problems/views/widget.edit.php b/ui/widgets/problems/views/widget.edit.php
new file mode 100755
index 00000000000..d1f4ac6bacd
--- /dev/null
+++ b/ui/widgets/problems/views/widget.edit.php
@@ -0,0 +1,93 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+/**
+ * Problems widget form view.
+ *
+ * @var CView $this
+ * @var array $data
+ */
+
+$groupids = new CWidgetFieldMultiSelectGroupView($data['fields']['groupids'],
+ $data['captions']['ms']['groups']['groupids']
+);
+
+(new CWidgetFormView($data))
+ ->addField(
+ new CWidgetFieldRadioButtonListView($data['fields']['show'])
+ )
+ ->addField($groupids)
+ ->addField(
+ new CWidgetFieldMultiSelectGroupView($data['fields']['exclude_groupids'],
+ $data['captions']['ms']['groups']['exclude_groupids']
+ )
+ )
+ ->addField(
+ (new CWidgetFieldMultiSelectHostView($data['fields']['hostids'], $data['captions']['ms']['hosts']['hostids']))
+ ->setFilterPreselect(['id' => $groupids->getId(), 'submit_as' => 'groupid'])
+ )
+ ->addField(
+ new CWidgetFieldTextBoxView($data['fields']['problem'])
+ )
+ ->addField(
+ new CWidgetFieldSeveritiesView($data['fields']['severities'])
+ )
+ ->addField(
+ new CWidgetFieldRadioButtonListView($data['fields']['evaltype'])
+ )
+ ->addField(
+ new CWidgetFieldTagsView($data['fields']['tags'])
+ )
+ ->addField(
+ new CWidgetFieldRadioButtonListView($data['fields']['show_tags'])
+ )
+ ->addField(
+ new CWidgetFieldRadioButtonListView($data['fields']['tag_name_format'])
+ )
+ ->addField(
+ (new CWidgetFieldTextBoxView($data['fields']['tag_priority']))->setPlaceholder(_('comma-separated list'))
+ )
+ ->addField(
+ new CWidgetFieldRadioButtonListView($data['fields']['show_opdata'])
+ )
+ ->addField(
+ new CWidgetFieldCheckBoxView($data['fields']['show_suppressed'])
+ )
+ ->addField(
+ new CWidgetFieldCheckBoxView($data['fields']['unacknowledged'])
+ )
+ ->addField(
+ new CWidgetFieldSelectView($data['fields']['sort_triggers'])
+ )
+ ->addField(
+ new CWidgetFieldCheckBoxView($data['fields']['show_timeline'])
+ )
+ ->addField(
+ new CWidgetFieldIntegerBoxView($data['fields']['show_lines'])
+ )
+ ->includeJsFile('widget.edit.js.php')
+ ->addJavaScript('widget_problems_form.init('.json_encode([
+ 'sort_with_enabled_show_timeline' => [
+ SCREEN_SORT_TRIGGERS_TIME_DESC => true,
+ SCREEN_SORT_TRIGGERS_TIME_ASC => true
+ ]
+ ], JSON_THROW_ON_ERROR).');')
+ ->show();
diff --git a/ui/app/views/monitoring.widget.problems.view.php b/ui/widgets/problems/views/widget.view.php
index 6f2a1abd30c..e0ee472868c 100644
--- a/ui/app/views/monitoring.widget.problems.view.php
+++ b/ui/widgets/problems/views/widget.view.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -20,6 +20,8 @@
/**
+ * Problems widget view.
+ *
* @var CView $this
* @var array $data
*/
@@ -29,8 +31,8 @@ $sort_div = (new CSpan())->addClass(($data['sortorder'] === ZBX_SORT_DOWN) ? ZBX
$url_details = $data['allowed_ui_problems']
? (new CUrl('tr_events.php'))
- ->setArgument('triggerid', '')
- ->setArgument('eventid', '')
+ ->setArgument('triggerid')
+ ->setArgument('eventid')
: null;
$show_timeline = ($data['sortfield'] === 'clock' && $data['fields']['show_timeline']);
@@ -133,6 +135,9 @@ foreach ($data['data']['problems'] as $eventid => $problem) {
$is_acknowledged = ($problem['acknowledged'] == EVENT_ACKNOWLEDGED);
+ $cell_r_clock = '';
+ $cell_status = '';
+
if ($show_recovery_data) {
if ($problem['r_eventid'] != 0) {
$cell_r_clock = ($problem['r_clock'] >= $today)
@@ -142,9 +147,6 @@ foreach ($data['data']['problems'] as $eventid => $problem) {
->addClass(ZBX_STYLE_NOWRAP)
->addClass(ZBX_STYLE_RIGHT);
}
- else {
- $cell_r_clock = '';
- }
$cell_status = new CSpan($value_str);
@@ -188,7 +190,7 @@ foreach ($data['data']['problems'] as $eventid => $problem) {
->setHint(_s('Unsuppressed by: %1$s', $user_unsuppressed));
}
elseif ($problem['suppression_data']) {
- $info_icons[] = makeSuppressedProblemIcon($problem['suppression_data'], false);
+ $info_icons[] = makeSuppressedProblemIcon($problem['suppression_data']);
}
elseif (isEventRecentlySuppressed($problem['acknowledges'], $suppression_action)) {
// Show blinking button if suppression was made but is not yet processed by server.
@@ -327,18 +329,6 @@ if ($data['info'] !== '') {
]);
}
-$output = [
- 'name' => $data['name'],
- 'body' => $table->toString()
-];
-
-if ($messages = get_and_clear_messages()) {
- $output['messages'] = array_column($messages, 'message');
-}
-
-if ($data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
- CProfiler::getInstance()->stop();
- $output['debug'] = CProfiler::getInstance()->make()->toString();
-}
-
-echo json_encode($output);
+(new CWidgetView($data))
+ ->addItem($table)
+ ->show();
diff --git a/ui/widgets/problemsbysv/Widget.php b/ui/widgets/problemsbysv/Widget.php
new file mode 100755
index 00000000000..0ae2847a0af
--- /dev/null
+++ b/ui/widgets/problemsbysv/Widget.php
@@ -0,0 +1,34 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\ProblemsBySv;
+
+use Zabbix\Core\CWidget;
+
+class Widget extends CWidget {
+
+ public const SHOW_GROUPS = 0;
+ public const SHOW_TOTALS = 1;
+
+ public function getDefaultName(): string {
+ return _('Problems by severity');
+ }
+}
diff --git a/ui/widgets/problemsbysv/actions/WidgetView.php b/ui/widgets/problemsbysv/actions/WidgetView.php
new file mode 100644
index 00000000000..ff2ab751808
--- /dev/null
+++ b/ui/widgets/problemsbysv/actions/WidgetView.php
@@ -0,0 +1,77 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\ProblemsBySv\Actions;
+
+use APP,
+ CControllerDashboardWidgetView,
+ CControllerResponseData;
+
+use Widgets\ProblemsBySv\Widget;
+
+require_once APP::getRootDir().'/include/blocks.inc.php';
+
+class WidgetView extends CControllerDashboardWidgetView {
+
+ protected function init(): void {
+ parent::init();
+
+ $this->addValidationRules([
+ 'initial_load' => 'in 0,1'
+ ]);
+ }
+
+ protected function doAction(): void {
+ $filter = [
+ 'groupids' => getSubGroups($this->fields_values['groupids']),
+ 'exclude_groupids' => getSubGroups($this->fields_values['exclude_groupids']),
+ 'hostids' => $this->fields_values['hostids'],
+ 'problem' => $this->fields_values['problem'],
+ 'severities' => $this->fields_values['severities'],
+ 'show_type' => $this->fields_values['show_type'],
+ 'layout' => $this->fields_values['layout'],
+ 'show_suppressed' => $this->fields_values['show_suppressed'],
+ 'hide_empty_groups' => $this->fields_values['hide_empty_groups'],
+ 'show_opdata' => $this->fields_values['show_opdata'],
+ 'ext_ack' => $this->fields_values['ext_ack'],
+ 'show_timeline' => $this->fields_values['show_timeline'],
+ 'evaltype' => $this->fields_values['evaltype'],
+ 'tags' => $this->fields_values['tags']
+ ];
+
+ $data = getSystemStatusData($filter);
+
+ if ($filter['show_type'] == Widget::SHOW_TOTALS) {
+ $data['groups'] = getSystemStatusTotals($data);
+ }
+
+ $this->setResponse(new CControllerResponseData([
+ 'name' => $this->getInput('name', $this->widget->getDefaultName()),
+ 'initial_load' => (bool) $this->getInput('initial_load', 0),
+ 'data' => $data,
+ 'filter' => $filter,
+ 'user' => [
+ 'debug_mode' => $this->getDebugMode()
+ ],
+ 'allowed' => $data['allowed']
+ ]));
+ }
+}
diff --git a/ui/js/widgets/class.widget.problemsbysv.js b/ui/widgets/problemsbysv/assets/js/class.widget.js
index 8571443e8ba..5caedf36c9b 100644..100755
--- a/ui/js/widgets/class.widget.problemsbysv.js
+++ b/ui/widgets/problemsbysv/assets/js/class.widget.js
@@ -20,6 +20,9 @@
class CWidgetProblemsBySv extends CWidget {
+ static SHOW_GROUPS = 0;
+ static SHOW_TOTALS = 1;
+
_registerEvents() {
super._registerEvents();
@@ -61,4 +64,9 @@ class CWidgetProblemsBySv extends CWidget {
$.unsubscribe('acknowledge.create', this._events.acknowledgeCreated);
}
+
+ _hasPadding() {
+ return this._view_mode == ZBX_WIDGET_VIEW_MODE_NORMAL
+ && this._fields.show_type != CWidgetProblemsBySv.SHOW_TOTALS;
+ }
}
diff --git a/ui/widgets/problemsbysv/includes/WidgetForm.php b/ui/widgets/problemsbysv/includes/WidgetForm.php
new file mode 100644
index 00000000000..39b39533711
--- /dev/null
+++ b/ui/widgets/problemsbysv/includes/WidgetForm.php
@@ -0,0 +1,123 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\ProblemsBySv\Includes;
+
+use Zabbix\Widgets\{
+ CWidgetField,
+ CWidgetForm
+};
+
+use Zabbix\Widgets\Fields\{
+ CWidgetFieldCheckBox,
+ CWidgetFieldMultiSelectGroup,
+ CWidgetFieldMultiSelectHost,
+ CWidgetFieldRadioButtonList,
+ CWidgetFieldSeverities,
+ CWidgetFieldTags,
+ CWidgetFieldTextBox
+};
+
+use Widgets\ProblemsBySv\Widget;
+
+/**
+ * Problems by severity widget form.
+ */
+class WidgetForm extends CWidgetForm {
+
+ public function addFields(): self {
+ return $this
+ ->addField(
+ new CWidgetFieldMultiSelectGroup('groupids', _('Host groups'))
+ )
+ ->addField(
+ new CWidgetFieldMultiSelectGroup('exclude_groupids', _('Exclude host groups'))
+ )
+ ->addField(
+ new CWidgetFieldMultiSelectHost('hostids', _('Hosts'))
+ )
+ ->addField(
+ new CWidgetFieldTextBox('problem', _('Problem'))
+ )
+ ->addField(
+ new CWidgetFieldSeverities('severities', _('Severity'))
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('evaltype', _('Tags'), [
+ TAG_EVAL_TYPE_AND_OR => _('And/Or'),
+ TAG_EVAL_TYPE_OR => _('Or')
+ ]))->setDefault(TAG_EVAL_TYPE_AND_OR)
+ )
+ ->addField(
+ new CWidgetFieldTags('tags')
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('show_type', _('Show'), [
+ Widget::SHOW_GROUPS => _('Host groups'),
+ Widget::SHOW_TOTALS => _('Totals')
+ ]))->setDefault(Widget::SHOW_GROUPS)
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('layout', _('Layout'), [
+ STYLE_HORIZONTAL => _('Horizontal'),
+ STYLE_VERTICAL => _('Vertical')
+ ]))
+ ->setDefault(STYLE_HORIZONTAL)
+ ->setFlags(
+ !array_key_exists('show_type', $this->values)
+ || !$this->values['show_type'] == Widget::SHOW_TOTALS
+ ? CWidgetField::FLAG_DISABLED
+ : 0x00
+ )
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('show_opdata', _('Show operational data'), [
+ OPERATIONAL_DATA_SHOW_NONE => _('None'),
+ OPERATIONAL_DATA_SHOW_SEPARATELY => _('Separately'),
+ OPERATIONAL_DATA_SHOW_WITH_PROBLEM => _('With problem name')
+ ]))->setDefault(OPERATIONAL_DATA_SHOW_NONE)
+ )
+ ->addField(
+ new CWidgetFieldCheckBox('show_suppressed', _('Show suppressed problems'))
+ )
+ ->addField(
+ (new CWidgetFieldCheckBox('hide_empty_groups', _('Hide groups without problems')))
+ ->setFlags(
+ array_key_exists('show_type', $this->values)
+ && $this->values['show_type'] == Widget::SHOW_TOTALS
+ ? CWidgetField::FLAG_DISABLED
+ : 0x00
+ )
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('ext_ack', _('Problem display'), [
+ EXTACK_OPTION_ALL => _('All'),
+ EXTACK_OPTION_BOTH => _('Separated'),
+ EXTACK_OPTION_UNACK => _('Unacknowledged only')
+ ]))
+ ->setDefault(EXTACK_OPTION_ALL)
+ ->setFlags(CWidgetField::FLAG_ACKNOWLEDGES)
+ )
+ ->addField(
+ (new CWidgetFieldCheckBox('show_timeline', _('Show timeline')))->setDefault(ZBX_TIMELINE_ON)
+ );
+ }
+}
diff --git a/ui/widgets/problemsbysv/manifest.json b/ui/widgets/problemsbysv/manifest.json
new file mode 100755
index 00000000000..7ece0b1b02d
--- /dev/null
+++ b/ui/widgets/problemsbysv/manifest.json
@@ -0,0 +1,15 @@
+{
+ "manifest_version": 2.0,
+ "id": "problemsbysv",
+ "type": "widget",
+ "name": "Problems by severity",
+ "namespace": "ProblemsBySv",
+ "version": "1.0",
+ "author": "Zabbix SIA",
+ "widget": {
+ "js_class": "CWidgetProblemsBySv"
+ },
+ "assets": {
+ "js": ["class.widget.js"]
+ }
+}
diff --git a/ui/widgets/problemsbysv/views/widget.edit.js.php b/ui/widgets/problemsbysv/views/widget.edit.js.php
new file mode 100755
index 00000000000..add705553ac
--- /dev/null
+++ b/ui/widgets/problemsbysv/views/widget.edit.js.php
@@ -0,0 +1,44 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+use Widgets\ProblemsBySv\Widget;
+
+?>
+
+window.widget_problemsbysv_form = new class {
+
+ init() {
+ this._show_type = document.getElementById('show_type');
+ this._show_type.addEventListener('change', () => this.updateForm());
+
+ this.updateForm();
+ }
+
+ updateForm() {
+ const show_type_totals = this._show_type.querySelector('input:checked').value == <?= Widget::SHOW_TOTALS ?>;
+
+ document.getElementById('hide_empty_groups').disabled = show_type_totals;
+
+ for (const radio of document.querySelectorAll('#layout input')) {
+ radio.disabled = !show_type_totals;
+ }
+ }
+};
diff --git a/ui/widgets/problemsbysv/views/widget.edit.php b/ui/widgets/problemsbysv/views/widget.edit.php
new file mode 100755
index 00000000000..76f97532f26
--- /dev/null
+++ b/ui/widgets/problemsbysv/views/widget.edit.php
@@ -0,0 +1,79 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+/**
+ * Problems by severity widget form view.
+ *
+ * @var CView $this
+ * @var array $data
+ */
+
+$groupids = new CWidgetFieldMultiSelectGroupView($data['fields']['groupids'],
+ $data['captions']['ms']['groups']['groupids']
+);
+
+(new CWidgetFormView($data))
+ ->addField($groupids)
+ ->addField(
+ new CWidgetFieldMultiSelectGroupView($data['fields']['exclude_groupids'],
+ $data['captions']['ms']['groups']['exclude_groupids']
+ )
+ )
+ ->addField(
+ (new CWidgetFieldMultiSelectHostView($data['fields']['hostids'], $data['captions']['ms']['hosts']['hostids']))
+ ->setFilterPreselect(['id' => $groupids->getId(), 'submit_as' => 'groupid'])
+ )
+ ->addField(
+ new CWidgetFieldTextBoxView($data['fields']['problem'])
+ )
+ ->addField(
+ new CWidgetFieldSeveritiesView($data['fields']['severities'])
+ )
+ ->addField(
+ new CWidgetFieldRadioButtonListView($data['fields']['evaltype'])
+ )
+ ->addField(
+ new CWidgetFieldTagsView($data['fields']['tags'])
+ )
+ ->addField(
+ new CWidgetFieldRadioButtonListView($data['fields']['show_type'])
+ )
+ ->addField(
+ new CWidgetFieldRadioButtonListView($data['fields']['layout'])
+ )
+ ->addField(
+ new CWidgetFieldRadioButtonListView($data['fields']['show_opdata'])
+ )
+ ->addField(
+ new CWidgetFieldCheckBoxView($data['fields']['show_suppressed'])
+ )
+ ->addField(
+ new CWidgetFieldCheckBoxView($data['fields']['hide_empty_groups'])
+ )
+ ->addField(
+ new CWidgetFieldRadioButtonListView($data['fields']['ext_ack'])
+ )
+ ->addField(
+ new CWidgetFieldCheckBoxView($data['fields']['show_timeline'])
+ )
+ ->includeJsFile('widget.edit.js.php')
+ ->addJavaScript('widget_problemsbysv_form.init();')
+ ->show();
diff --git a/ui/app/views/monitoring.widget.problemsbysv.view.php b/ui/widgets/problemsbysv/views/widget.view.php
index dbff193b4a6..5c1c01e1551 100644
--- a/ui/app/views/monitoring.widget.problemsbysv.view.php
+++ b/ui/widgets/problemsbysv/views/widget.view.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -20,11 +20,15 @@
/**
+ * Problems by severity widget view.
+ *
* @var CView $this
* @var array $data
*/
-if ($data['filter']['show_type'] == WIDGET_PROBLEMS_BY_SV_SHOW_TOTALS) {
+use Widgets\ProblemsBySv\Widget;
+
+if ($data['filter']['show_type'] == Widget::SHOW_TOTALS) {
$table = makeSeverityTotals($data)
->addClass(ZBX_STYLE_BY_SEVERITY_WIDGET)
->addClass(ZBX_STYLE_TOTALS_LIST)
@@ -50,36 +54,22 @@ else {
? $data['filter']['hide_empty_groups']
: 0;
- $groupurl = (new CUrl('zabbix.php'))
+ $group_url = (new CUrl('zabbix.php'))
->setArgument('action', 'problem.view')
- ->setArgument('filter_name', '')
+ ->setArgument('filter_name')
->setArgument('show', TRIGGERS_OPTION_RECENT_PROBLEM)
- ->setArgument('hostids',
- array_key_exists('hostids', $data['filter']) ? $data['filter']['hostids'] : null
- )
+ ->setArgument('hostids', array_key_exists('hostids', $data['filter']) ? $data['filter']['hostids'] : null)
->setArgument('name', array_key_exists('problem', $data['filter']) ? $data['filter']['problem'] : null)
->setArgument('show_suppressed',
(array_key_exists('show_suppressed', $data['filter']) && $data['filter']['show_suppressed'] == 1) ? 1 : null
);
- $table = makeSeverityTable($data, $hide_empty_groups, $groupurl)
+ $table = makeSeverityTable($data, $hide_empty_groups, $group_url)
->addClass(ZBX_STYLE_BY_SEVERITY_WIDGET)
->setHeader($header)
->setHeadingColumn(0);
}
-$output = [
- 'name' => $data['name'],
- 'body' => $table->toString()
-];
-
-if ($messages = get_and_clear_messages()) {
- $output['messages'] = array_column($messages, 'message');
-}
-
-if ($data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
- CProfiler::getInstance()->stop();
- $output['debug'] = CProfiler::getInstance()->make()->toString();
-}
-
-echo json_encode($output);
+(new CWidgetView($data))
+ ->addItem($table)
+ ->show();
diff --git a/ui/widgets/slareport/Widget.php b/ui/widgets/slareport/Widget.php
new file mode 100755
index 00000000000..55156007717
--- /dev/null
+++ b/ui/widgets/slareport/Widget.php
@@ -0,0 +1,31 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\SlaReport;
+
+use Zabbix\Core\CWidget;
+
+class Widget extends CWidget {
+
+ public function getDefaultName(): string {
+ return _('SLA report');
+ }
+}
diff --git a/ui/app/controllers/CControllerWidgetSlaReportView.php b/ui/widgets/slareport/actions/WidgetView.php
index 18abbac170a..5944ea060f2 100644
--- a/ui/app/controllers/CControllerWidgetSlaReportView.php
+++ b/ui/widgets/slareport/actions/WidgetView.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,30 +19,28 @@
**/
-class CControllerWidgetSlaReportView extends CControllerWidget {
+namespace Widgets\SlaReport\Actions;
- public function __construct() {
- parent::__construct();
+use API,
+ CControllerDashboardWidgetView,
+ CControllerResponseData,
+ CParser,
+ CRangeTimeParser,
+ CRoleHelper,
+ CSettingsHelper,
+ CTimezoneHelper,
+ CWebUser,
+ DateTimeZone;
- $this->setType(WIDGET_SLA_REPORT);
- $this->setValidationRules([
- 'name' => 'string',
- 'fields' => 'json'
- ]);
- }
+class WidgetView extends CControllerDashboardWidgetView {
- /**
- * @throws APIException
- */
protected function doAction(): void {
- $fields = $this->getForm()->getFieldsData();
-
$data = [
- 'name' => $this->getInput('name', $this->getDefaultName()),
+ 'name' => $this->getInput('name', $this->widget->getDefaultName()),
'has_access' => [
CRoleHelper::ACTIONS_MANAGE_SLA => $this->checkAccess(CRoleHelper::ACTIONS_MANAGE_SLA)
],
- 'has_serviceid' => (bool) $fields['serviceid'],
+ 'has_serviceid' => (bool) $this->fields_values['serviceid'],
'has_permissions_error' => false,
'rows_per_page' => CWebUser::$data['rows_per_page'],
'search_limit' => CSettingsHelper::get(CSettingsHelper::SEARCH_LIMIT),
@@ -51,10 +49,10 @@ class CControllerWidgetSlaReportView extends CControllerWidget {
]
];
- $db_slas = $fields['slaid']
+ $db_slas = $this->fields_values['slaid']
? API::Sla()->get([
'output' => ['slaid', 'name', 'period', 'slo', 'timezone', 'status'],
- 'slaids' => $fields['slaid']
+ 'slaids' => $this->fields_values['slaid']
])
: [];
@@ -64,7 +62,7 @@ class CControllerWidgetSlaReportView extends CControllerWidget {
if ($data['sla']['status'] == ZBX_SLA_STATUS_ENABLED) {
$data['services'] = API::Service()->get([
'output' => ['name'],
- 'serviceids' => $fields['serviceid'] ?: null,
+ 'serviceids' => $this->fields_values['serviceid'] ?: null,
'slaids' => $data['sla']['slaid'],
'sortfield' => 'name',
'sortorder' => ZBX_SORT_UP,
@@ -72,10 +70,10 @@ class CControllerWidgetSlaReportView extends CControllerWidget {
'preservekeys' => true
]);
- if ($fields['serviceid'] && !$data['services']) {
+ if ($this->fields_values['serviceid'] && !$data['services']) {
$service_accessible = API::Service()->get([
'output' => [],
- 'serviceids' => $fields['serviceid']
+ 'serviceids' => $this->fields_values['serviceid']
]);
if (!$service_accessible) {
@@ -91,8 +89,8 @@ class CControllerWidgetSlaReportView extends CControllerWidget {
$range_time_parser = new CRangeTimeParser();
- if ($fields['date_from'] !== ''
- && $range_time_parser->parse($fields['date_from']) == CParser::PARSE_SUCCESS) {
+ if ($this->fields_values['date_from'] !== ''
+ && $range_time_parser->parse($this->fields_values['date_from']) == CParser::PARSE_SUCCESS) {
$period_from = $range_time_parser->getDateTime(true, $timezone)->getTimestamp();
if ($period_from < 0 || $period_from > ZBX_MAX_DATE) {
@@ -105,8 +103,8 @@ class CControllerWidgetSlaReportView extends CControllerWidget {
$period_from = null;
}
- if ($fields['date_to'] !== ''
- && $range_time_parser->parse($fields['date_to']) == CParser::PARSE_SUCCESS) {
+ if ($this->fields_values['date_to'] !== ''
+ && $range_time_parser->parse($this->fields_values['date_to']) == CParser::PARSE_SUCCESS) {
$period_to = $range_time_parser->getDateTime(false, $timezone)->getTimestamp();
if ($period_to < 0 || $period_to > ZBX_MAX_DATE) {
@@ -122,7 +120,7 @@ class CControllerWidgetSlaReportView extends CControllerWidget {
$data['sli'] = API::Sla()->getSli([
'slaid' => $data['sla']['slaid'],
'serviceids' => array_slice(array_keys($data['services']), 0, $data['rows_per_page']),
- 'periods' => $fields['show_periods'] !== '' ? $fields['show_periods'] : null,
+ 'periods' => $this->fields_values['show_periods'] !== '' ? $this->fields_values['show_periods'] : null,
'period_from' => $period_from,
'period_to' => $period_to
]);
diff --git a/ui/widgets/slareport/includes/WidgetForm.php b/ui/widgets/slareport/includes/WidgetForm.php
new file mode 100644
index 00000000000..b36086ce6cd
--- /dev/null
+++ b/ui/widgets/slareport/includes/WidgetForm.php
@@ -0,0 +1,127 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\SlaReport\Includes;
+
+use API,
+ CAbsoluteTimeParser,
+ CParser,
+ CTimezoneHelper,
+ DateTimeZone;
+
+use Zabbix\Widgets\{
+ CWidgetField,
+ CWidgetForm
+};
+
+use Zabbix\Widgets\Fields\{
+ CWidgetFieldDatePicker,
+ CWidgetFieldIntegerBox,
+ CWidgetFieldMultiSelectService,
+ CWidgetFieldMultiSelectSla
+};
+
+/**
+ * SLA report widget form.
+ */
+class WidgetForm extends CWidgetForm {
+
+ public function validate(bool $strict = false): array {
+ if ($errors = parent::validate($strict)) {
+ return $errors;
+ }
+
+ $errors = [];
+
+ $slaids = $this->getFieldValue('slaid');
+
+ $slas = $slaids
+ ? API::Sla()->get([
+ 'output' => ['timezone'],
+ 'slaids' => $slaids,
+ 'filter' => [
+ 'status' => ZBX_SLA_STATUS_ENABLED
+ ]
+ ])
+ : [];
+
+ $sla = $slas ? $slas[0] : null;
+
+ $timezone = new DateTimeZone($sla !== null && $sla['timezone'] !== ZBX_DEFAULT_TIMEZONE
+ ? $sla['timezone']
+ : CTimezoneHelper::getSystemTimezone()
+ );
+
+ $absolute_time_parser = new CAbsoluteTimeParser();
+
+ $period_from = null;
+
+ if ($absolute_time_parser->parse($this->getFieldValue('date_from')) == CParser::PARSE_SUCCESS) {
+ $period_from = $absolute_time_parser->getDateTime(true, $timezone)->getTimestamp();
+
+ if ($period_from < 0 || $period_from > ZBX_MAX_DATE) {
+ $period_from = null;
+
+ $errors[] = _s('Incorrect value for field "%1$s": %2$s.', _s('From'), _('a date is expected'));
+ }
+ }
+
+ $period_to = null;
+
+ if ($absolute_time_parser->parse($this->getFieldValue('date_to')) == CParser::PARSE_SUCCESS) {
+ $period_to = $absolute_time_parser->getDateTime(false, $timezone)->getTimestamp();
+
+ if ($period_to < 0 || $period_to > ZBX_MAX_DATE) {
+ $period_to = null;
+
+ $errors[] = _s('Incorrect value for field "%1$s": %2$s.', _s('To'), _('a date is expected'));
+ }
+ }
+
+ if ($period_from !== null && $period_to !== null && $period_to <= $period_from) {
+ $errors[] = _s('"%1$s" date must be less than "%2$s" date.', _('From'), _('To'));
+ }
+
+ return $errors;
+ }
+
+ public function addFields(): self {
+ return $this
+ ->addField(
+ (new CWidgetFieldMultiSelectSla('slaid', _('SLA')))
+ ->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
+ ->setMultiple(false)
+ )
+ ->addField(
+ (new CWidgetFieldMultiSelectService('serviceid', _('Service')))->setMultiple(false)
+ )
+ ->addField(
+ (new CWidgetFieldIntegerBox('show_periods', _('Show periods'), 1, ZBX_SLA_MAX_REPORTING_PERIODS))
+ ->setDefault(ZBX_SLA_DEFAULT_REPORTING_PERIODS)
+ )
+ ->addField(
+ new CWidgetFieldDatePicker('date_from', _('From'), true)
+ )
+ ->addField(
+ new CWidgetFieldDatePicker('date_to', _('To'), true)
+ );
+ }
+}
diff --git a/ui/widgets/slareport/manifest.json b/ui/widgets/slareport/manifest.json
new file mode 100755
index 00000000000..978ee685497
--- /dev/null
+++ b/ui/widgets/slareport/manifest.json
@@ -0,0 +1,12 @@
+{
+ "manifest_version": 2.0,
+ "id": "slareport",
+ "type": "widget",
+ "name": "SLA report",
+ "namespace": "SlaReport",
+ "version": "1.0",
+ "author": "Zabbix SIA",
+ "widget": {
+ "refresh_rate": 0
+ }
+}
diff --git a/ui/include/classes/widgets/views/js/widget.slareport.form.view.js.php b/ui/widgets/slareport/views/widget.edit.js.php
index f1ace3f7ddb..647484b88ed 100644..100755
--- a/ui/include/classes/widgets/views/js/widget.slareport.form.view.js.php
+++ b/ui/widgets/slareport/views/widget.edit.js.php
@@ -23,14 +23,14 @@
window.widget_slareport_form = new class {
init({serviceid_field_id}) {
- this.$service = jQuery(`#${serviceid_field_id}`);
- this.$service.multiSelect('getSelectButton').addEventListener('click', () => this.selectService());
+ this._$service = jQuery(`#${serviceid_field_id}`);
+ this._$service.multiSelect('getSelectButton').addEventListener('click', () => this.selectService());
}
selectService() {
const exclude_serviceids = [];
- for (const service of this.$service.multiSelect('getData')) {
+ for (const service of this._$service.multiSelect('getData')) {
exclude_serviceids.push(service.id);
}
@@ -47,7 +47,7 @@ window.widget_slareport_form = new class {
data.push({id: service.serviceid, name: service.name});
}
- this.$service.multiSelect('addData', data);
+ this._$service.multiSelect('addData', data);
});
}
};
diff --git a/ui/widgets/slareport/views/widget.edit.php b/ui/widgets/slareport/views/widget.edit.php
new file mode 100755
index 00000000000..700de0afe80
--- /dev/null
+++ b/ui/widgets/slareport/views/widget.edit.php
@@ -0,0 +1,55 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+/**
+ * SLA report widget form view.
+ *
+ * @var CView $this
+ * @var array $data
+ */
+
+(new CWidgetFormView($data))
+ ->addField(
+ new CWidgetFieldMultiSelectSlaView($data['fields']['slaid'], $data['captions']['ms']['slas']['slaid'])
+ )
+ ->addField(
+ new CWidgetFieldMultiSelectServiceView($data['fields']['serviceid'],
+ $data['captions']['ms']['services']['serviceid']
+ )
+ )
+ ->addField(
+ new CWidgetFieldIntegerBoxView($data['fields']['show_periods'])
+ )
+ ->addField(
+ (new CWidgetFieldDatePickerView($data['fields']['date_from']))
+ ->setDateFormat(ZBX_DATE)
+ ->setPlaceholder(_('YYYY-MM-DD'))
+ )
+ ->addField(
+ (new CWidgetFieldDatePickerView($data['fields']['date_to']))
+ ->setDateFormat(ZBX_DATE)
+ ->setPlaceholder(_('YYYY-MM-DD'))
+ )
+ ->includeJsFile('widget.edit.js.php')
+ ->addJavaScript('widget_slareport_form.init('.json_encode([
+ 'serviceid_field_id' => $data['fields']['serviceid']->getName()
+ ], JSON_THROW_ON_ERROR).');')
+ ->show();
diff --git a/ui/app/views/monitoring.widget.slareport.view.php b/ui/widgets/slareport/views/widget.view.php
index 9c418f332b0..be524a6979e 100644
--- a/ui/app/views/monitoring.widget.slareport.view.php
+++ b/ui/widgets/slareport/views/widget.view.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -20,6 +20,8 @@
/**
+ * SLA report widget view.
+ *
* @var CView $this
* @var array $data
*/
@@ -128,18 +130,6 @@ else {
}
}
-$output = [
- 'name' => $data['name'],
- 'body' => (new CDiv($report))->addClass('dashboard-widget-slareport')->toString()
-];
-
-if ($messages = get_and_clear_messages()) {
- $output['messages'] = array_column($messages, 'message');
-}
-
-if ($data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
- CProfiler::getInstance()->stop();
- $output['debug'] = CProfiler::getInstance()->make()->toString();
-}
-
-echo json_encode($output);
+(new CWidgetView($data))
+ ->addItem($report)
+ ->show();
diff --git a/ui/widgets/svggraph/Widget.php b/ui/widgets/svggraph/Widget.php
new file mode 100755
index 00000000000..a1c011df9c0
--- /dev/null
+++ b/ui/widgets/svggraph/Widget.php
@@ -0,0 +1,46 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\SvgGraph;
+
+use Widgets\SvgGraph\Includes\WidgetForm;
+
+use Zabbix\Core\CWidget;
+
+class Widget extends CWidget {
+
+ public function getDefaultName(): string {
+ return _('Graph');
+ }
+
+ public function usesTimeSelector(array $fields_values): bool {
+ return !WidgetForm::hasOverrideTime($fields_values);
+ }
+
+ public function getTranslationStrings(): array {
+ return [
+ 'class.widget.js' => [
+ 'Actions' => _s('Actions'),
+ 'Download image' => _s('Download image')
+ ]
+ ];
+ }
+}
diff --git a/ui/widgets/svggraph/actions/WidgetView.php b/ui/widgets/svggraph/actions/WidgetView.php
new file mode 100644
index 00000000000..f0d0591ef3f
--- /dev/null
+++ b/ui/widgets/svggraph/actions/WidgetView.php
@@ -0,0 +1,195 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\SvgGraph\Actions;
+
+use CControllerDashboardWidgetView,
+ CControllerResponseData,
+ CNumberParser,
+ CParser,
+ CRangeTimeParser,
+ CSvgGraphHelper;
+
+use Widgets\SvgGraph\Includes\WidgetForm;
+
+class WidgetView extends CControllerDashboardWidgetView {
+
+ private const GRAPH_WIDTH_MIN = 1;
+ private const GRAPH_WIDTH_MAX = 65535;
+ private const GRAPH_HEIGHT_MIN = 1;
+ private const GRAPH_HEIGHT_MAX = 65535;
+
+ protected function init(): void {
+ parent::init();
+
+ $this->addValidationRules([
+ 'edit_mode' => 'in 0,1',
+ 'content_width' => 'int32|ge '.self::GRAPH_WIDTH_MIN.'|le '.self::GRAPH_WIDTH_MAX,
+ 'content_height' => 'int32|ge '.self::GRAPH_HEIGHT_MIN.'|le '.self::GRAPH_HEIGHT_MAX,
+ 'preview' => 'in 1',
+ 'from' => 'string',
+ 'to' => 'string'
+ ]);
+ }
+
+ protected function doAction(): void {
+ $edit_mode = $this->getInput('edit_mode', 0);
+ $width = (int) $this->getInput('content_width', self::GRAPH_WIDTH_MIN);
+ $height = (int) $this->getInput('content_height', self::GRAPH_HEIGHT_MIN);
+ $preview = (bool) $this->getInput('preview', 0); // Configuration preview.
+
+ $dashboard_time = !WidgetForm::hasOverrideTime($this->fields_values);
+
+ if ($dashboard_time && !$preview) {
+ $from = $this->getInput('from');
+ $to = $this->getInput('to');
+ }
+ else {
+ $from = $this->fields_values['time_from'];
+ $to = $this->fields_values['time_to'];
+ }
+
+ $range_time_parser = new CRangeTimeParser();
+
+ $range_time_parser->parse($from);
+ $time_from = $range_time_parser->getDateTime(true)->getTimestamp();
+
+ $range_time_parser->parse($to);
+ $time_to = $range_time_parser->getDateTime(false)->getTimestamp();
+
+ $parser = new CNumberParser(['with_size_suffix' => true, 'with_time_suffix' => true]);
+
+ $percentile_left_value = $parser->parse($this->fields_values['percentile_left_value']) == CParser::PARSE_SUCCESS
+ ? $parser->calcValue()
+ : null;
+
+ $percentile_right_value = $parser->parse($this->fields_values['percentile_right_value']) == CParser::PARSE_SUCCESS
+ ? $parser->calcValue()
+ : null;
+
+ $lefty_min = $parser->parse($this->fields_values['lefty_min']) == CParser::PARSE_SUCCESS
+ ? $parser->calcValue()
+ : null;
+
+ $lefty_max = $parser->parse($this->fields_values['lefty_max']) == CParser::PARSE_SUCCESS
+ ? $parser->calcValue()
+ : null;
+
+ $righty_min = $parser->parse($this->fields_values['righty_min']) == CParser::PARSE_SUCCESS
+ ? $parser->calcValue()
+ : null;
+
+ $righty_max = $parser->parse($this->fields_values['righty_max']) == CParser::PARSE_SUCCESS
+ ? $parser->calcValue()
+ : null;
+
+ $graph_data = [
+ 'data_sets' => array_values($this->fields_values['ds']),
+ 'data_source' => $this->fields_values['source'],
+ 'dashboard_time' => $dashboard_time,
+ 'displaying' => [
+ 'show_simple_triggers' => $this->fields_values['simple_triggers'] == SVG_GRAPH_SIMPLE_TRIGGERS_ON,
+ 'show_working_time' => $this->fields_values['working_time'] == SVG_GRAPH_WORKING_TIME_ON,
+ 'show_percentile_left' => $this->fields_values['percentile_left'] == SVG_GRAPH_PERCENTILE_LEFT_ON,
+ 'percentile_left_value' => $percentile_left_value,
+ 'show_percentile_right' => $this->fields_values['percentile_right'] == SVG_GRAPH_PERCENTILE_RIGHT_ON,
+ 'percentile_right_value' => $percentile_right_value
+ ],
+ 'time_period' => [
+ 'time_from' => $time_from,
+ 'time_to' => $time_to
+ ],
+ 'axes' => [
+ 'show_left_y_axis' => $this->fields_values['lefty'] == SVG_GRAPH_AXIS_ON,
+ 'left_y_min' => $lefty_min,
+ 'left_y_max' => $lefty_max,
+ 'left_y_units' => $this->fields_values['lefty_units'] == SVG_GRAPH_AXIS_UNITS_STATIC
+ ? $this->fields_values['lefty_static_units']
+ : null,
+ 'show_right_y_axis' => $this->fields_values['righty'] == SVG_GRAPH_AXIS_ON,
+ 'right_y_min' => $righty_min,
+ 'right_y_max' => $righty_max,
+ 'right_y_units' => $this->fields_values['righty_units'] == SVG_GRAPH_AXIS_UNITS_STATIC
+ ? $this->fields_values['righty_static_units']
+ : null,
+ 'show_x_axis' => $this->fields_values['axisx'] == SVG_GRAPH_AXIS_ON
+ ],
+ 'legend' => [
+ 'show_legend' => $this->fields_values['legend'] == SVG_GRAPH_LEGEND_ON,
+ 'legend_columns' => $this->fields_values['legend_columns'],
+ 'legend_lines' => $this->fields_values['legend_lines'],
+ 'legend_statistic' => $this->fields_values['legend_statistic']
+ ],
+ 'problems' => [
+ 'show_problems' => $this->fields_values['show_problems'] == SVG_GRAPH_PROBLEMS_ON,
+ 'graph_item_problems' => $this->fields_values['graph_item_problems'] == SVG_GRAPH_SELECTED_ITEM_PROBLEMS,
+ 'problemhosts' => $this->fields_values['problemhosts'],
+ 'severities' => $this->fields_values['severities'],
+ 'problem_name' => $this->fields_values['problem_name'],
+ 'evaltype' => $this->fields_values['evaltype'],
+ 'tags' => $this->fields_values['tags']
+ ],
+ 'overrides' => array_values($this->fields_values['or'])
+ ];
+
+ $svg_options = CSvgGraphHelper::get($graph_data, $width, $height);
+ if ($svg_options['errors']) {
+ error($svg_options['errors']);
+ }
+
+ if (!$preview) {
+ $svg_options['data'] = zbx_array_merge($svg_options['data'], [
+ 'sbox' => $graph_data['dashboard_time'] && !$edit_mode,
+ 'show_problems' => $graph_data['problems']['show_problems'],
+ 'show_simple_triggers' => $graph_data['displaying']['show_simple_triggers'],
+ 'time_from' => $graph_data['time_period']['time_from'],
+ 'hint_max_rows' => ZBX_WIDGET_ROWS
+ ]);
+ }
+
+ $this->setResponse(new CControllerResponseData([
+ 'name' => $this->getInput('name', $this->widget->getDefaultName()),
+ 'svg' => $svg_options['svg'].$svg_options['legend'],
+ 'svg_options' => $svg_options,
+ 'preview' => $preview,
+ 'info' => $this->makeWidgetInfo(),
+ 'user' => [
+ 'debug_mode' => $this->getDebugMode()
+ ]
+ ]));
+ }
+
+ /**
+ * Make widget specific info to show in widget's header.
+ */
+ private function makeWidgetInfo(): array {
+ $info = [];
+
+ if (WidgetForm::hasOverrideTime($this->fields_values)) {
+ $info[] = [
+ 'icon' => 'btn-info-clock',
+ 'hint' => relativeDateToText($this->fields_values['time_from'], $this->fields_values['time_to'])
+ ];
+ }
+
+ return $info;
+ }
+}
diff --git a/ui/js/widgets/class.widget.svggraph.js b/ui/widgets/svggraph/assets/js/class.widget.js
index 3f832b5cc45..02cb14f77ca 100644..100755
--- a/ui/js/widgets/class.widget.svggraph.js
+++ b/ui/widgets/svggraph/assets/js/class.widget.js
@@ -154,4 +154,8 @@ class CWidgetSvgGraph extends CWidget {
return menu;
}
+
+ _hasPadding() {
+ return true;
+ }
}
diff --git a/ui/widgets/svggraph/includes/WidgetForm.php b/ui/widgets/svggraph/includes/WidgetForm.php
new file mode 100644
index 00000000000..27135b2e10c
--- /dev/null
+++ b/ui/widgets/svggraph/includes/WidgetForm.php
@@ -0,0 +1,470 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\SvgGraph\Includes;
+
+use CNumberParser,
+ CParser,
+ CRangeTimeParser,
+ CSettingsHelper;
+
+use Zabbix\Widgets\{
+ CWidgetField,
+ CWidgetForm
+};
+
+use Zabbix\Widgets\Fields\{
+ CWidgetFieldCheckBox,
+ CWidgetFieldDatePicker,
+ CWidgetFieldGraphDataSet,
+ CWidgetFieldGraphOverride,
+ CWidgetFieldHostPatternSelect,
+ CWidgetFieldNumericBox,
+ CWidgetFieldRadioButtonList,
+ CWidgetFieldRangeControl,
+ CWidgetFieldSelect,
+ CWidgetFieldSeverities,
+ CWidgetFieldTags,
+ CWidgetFieldTextBox
+};
+
+/**
+ * Graph widget form view.
+ */
+class WidgetForm extends CWidgetForm {
+
+ private const PERCENTILE_MIN = 1;
+ private const PERCENTILE_MAX = 100;
+
+ private bool $percentile_left_on = false;
+ private bool $percentile_right_on = false;
+
+ private bool $graph_time_on = false;
+
+ private bool $lefty_on = true;
+ private bool $lefty_units_static = false;
+ private bool $righty_on = true;
+ private bool $righty_units_static = false;
+
+ private bool $legend_on = true;
+ private bool $legend_statistic_on = false;
+
+ private bool $problems_on = false;
+
+ public function validate(bool $strict = false): array {
+ $errors = parent::validate($strict);
+
+ $number_parser_w_suffix = new CNumberParser(['with_size_suffix' => true, 'with_time_suffix' => true]);
+ $number_parser_wo_suffix = new CNumberParser();
+
+ // Percentiles
+ if ($this->getFieldValue('percentile_left') == SVG_GRAPH_PERCENTILE_LEFT_ON) {
+ $percentile_left_value = $this->getFieldValue('percentile_left_value');
+
+ if ($percentile_left_value !== '') {
+ $percentile_left_value_calculated =
+ $number_parser_wo_suffix->parse($percentile_left_value) == CParser::PARSE_SUCCESS
+ ? $number_parser_wo_suffix->calcValue()
+ : null;
+
+ if ($percentile_left_value_calculated === null
+ || $percentile_left_value_calculated < self::PERCENTILE_MIN
+ || $percentile_left_value_calculated > self::PERCENTILE_MAX) {
+ $errors[] = _s('Invalid parameter "%1$s": %2$s.', _('Percentile line (left)'),
+ _s('value must be between "%1$s" and "%2$s"', self::PERCENTILE_MIN, self::PERCENTILE_MAX)
+ );
+ }
+ }
+ }
+
+ if ($this->getFieldValue('percentile_right') == SVG_GRAPH_PERCENTILE_RIGHT_ON) {
+ $percentile_right_value = $this->getFieldValue('percentile_right_value');
+
+ if ($percentile_right_value !== '') {
+ $percentile_right_value_calculated =
+ $number_parser_wo_suffix->parse($percentile_right_value) == CParser::PARSE_SUCCESS
+ ? $number_parser_wo_suffix->calcValue()
+ : null;
+
+ if ($percentile_right_value_calculated === null
+ || $percentile_right_value_calculated < self::PERCENTILE_MIN
+ || $percentile_right_value_calculated > self::PERCENTILE_MAX) {
+ $errors[] = _s('Invalid parameter "%1$s": %2$s.', _('Percentile line (right)'),
+ _s('value must be between "%1$s" and "%2$s"', self::PERCENTILE_MIN, self::PERCENTILE_MAX)
+ );
+ }
+ }
+ }
+
+ // Test graph custom time period.
+ if ($this->getFieldValue('graph_time') == SVG_GRAPH_CUSTOM_TIME_ON) {
+ $errors = array_merge($errors, self::validateTimeSelectorPeriod($this->getFieldValue('time_from'),
+ $this->getFieldValue('time_to')
+ ));
+ }
+
+ // Validate Min/Max values in Axes tab.
+ if ($this->getFieldValue('lefty') == SVG_GRAPH_AXIS_ON) {
+ $lefty_min = $number_parser_w_suffix->parse($this->getFieldValue('lefty_min')) == CParser::PARSE_SUCCESS
+ ? $number_parser_w_suffix->calcValue()
+ : null;
+
+ $lefty_max = $number_parser_w_suffix->parse($this->getFieldValue('lefty_max')) == CParser::PARSE_SUCCESS
+ ? $number_parser_w_suffix->calcValue()
+ : null;
+
+ if ($lefty_min !== null && $lefty_max !== null && $lefty_min >= $lefty_max) {
+ $errors[] = _s('Invalid parameter "%1$s": %2$s.', _('Left Y').'/'._('Max'),
+ _('Y axis MAX value must be greater than Y axis MIN value')
+ );
+ }
+ }
+
+ if ($this->getFieldValue('righty') == SVG_GRAPH_AXIS_ON) {
+ $righty_min = $number_parser_w_suffix->parse($this->getFieldValue('righty_min')) == CParser::PARSE_SUCCESS
+ ? $number_parser_w_suffix->calcValue()
+ : null;
+
+ $righty_max = $number_parser_w_suffix->parse($this->getFieldValue('righty_max')) == CParser::PARSE_SUCCESS
+ ? $number_parser_w_suffix->calcValue()
+ : null;
+
+ if ($righty_min !== null && $righty_max !== null && $righty_min >= $righty_max) {
+ $errors[] = _s('Invalid parameter "%1$s": %2$s.', _('Right Y').'/'._('Max'),
+ _('Y axis MAX value must be greater than Y axis MIN value')
+ );
+ }
+ }
+
+ return $errors;
+ }
+
+ protected function normalizeValues(array $values): array {
+ $values = parent::normalizeValues($values);
+
+ if (array_key_exists('percentile_left', $values)) {
+ $this->percentile_left_on = $values['percentile_left'] == SVG_GRAPH_PERCENTILE_LEFT_ON;
+ }
+
+ if (!$this->percentile_left_on) {
+ unset($values['percentile_left_value']);
+ }
+
+ if (array_key_exists('percentile_right', $values)) {
+ $this->percentile_right_on = $values['percentile_right'] == SVG_GRAPH_PERCENTILE_RIGHT_ON;
+ }
+
+ if (!$this->percentile_right_on) {
+ unset($values['percentile_right_value']);
+ }
+
+ if (array_key_exists('graph_time', $values)) {
+ $this->graph_time_on = $values['graph_time'] == SVG_GRAPH_CUSTOM_TIME_ON;
+ }
+
+ if (!$this->graph_time_on) {
+ unset($values['time_from'], $values['time_to']);
+ }
+
+ if (array_key_exists('lefty', $values)) {
+ $this->lefty_on = $values['lefty'] == SVG_GRAPH_AXIS_ON;
+ }
+
+ if (!$this->lefty_on) {
+ unset($values['lefty_min'], $values['lefty_max'], $values['lefty_units']);
+ }
+
+ if (array_key_exists('lefty_units', $values)) {
+ $this->lefty_units_static = $values['lefty_units'] == SVG_GRAPH_AXIS_UNITS_STATIC;
+ }
+
+ if (!$this->lefty_on || !$this->lefty_units_static) {
+ unset($values['lefty_static_units']);
+ }
+
+ if (array_key_exists('righty', $values)) {
+ $this->righty_on = $values['righty'] == SVG_GRAPH_AXIS_ON;
+ }
+
+ if (!$this->righty_on) {
+ unset($values['righty_min'], $values['righty_max'], $values['righty_units']);
+ }
+
+ if (array_key_exists('righty_units', $values)) {
+ $this->righty_units_static = $values['righty_units'] == SVG_GRAPH_AXIS_UNITS_STATIC;
+ }
+
+ if (!$this->righty_on || !$this->righty_units_static) {
+ unset($values['righty_static_units']);
+ }
+
+ if (array_key_exists('legend', $values)) {
+ $this->legend_on = $values['legend'] == SVG_GRAPH_LEGEND_ON;
+ }
+
+ if (array_key_exists('legend_statistic', $values)) {
+ $this->legend_statistic_on = $values['legend_statistic'] == SVG_GRAPH_LEGEND_STATISTIC_ON;
+ }
+
+ if (array_key_exists('show_problems', $values)) {
+ $this->problems_on = $values['show_problems'] == SVG_GRAPH_PROBLEMS_ON;
+ }
+
+ if (!$this->problems_on) {
+ unset($values['graph_item_problems'], $values['problemhosts'], $values['severities'],
+ $values['problem_name'], $values['evaltype'], $values['tags']
+ );
+ }
+
+ return $values;
+ }
+
+ public function addFields(): self {
+ return $this
+ ->initDataSetFields()
+ ->initDisplayingOptionsFields()
+ ->initTimePeriodFields()
+ ->initAxesFields()
+ ->initLegendFields()
+ ->initProblemsFields()
+ ->initOverridesFields();
+ }
+
+ private function initDataSetFields(): self {
+ return $this->addField(
+ (new CWidgetFieldGraphDataSet('ds', _('Data set')))->setFlags(CWidgetField::FLAG_NOT_EMPTY)
+ );
+ }
+
+ private function initDisplayingOptionsFields(): self {
+ return $this
+ ->addField(
+ (new CWidgetFieldRadioButtonList('source', _('History data selection'), [
+ SVG_GRAPH_DATA_SOURCE_AUTO => _x('Auto', 'history source selection method'),
+ SVG_GRAPH_DATA_SOURCE_HISTORY => _('History'),
+ SVG_GRAPH_DATA_SOURCE_TRENDS => _('Trends')
+ ]))->setDefault(SVG_GRAPH_DATA_SOURCE_AUTO)
+ )
+ ->addField(
+ new CWidgetFieldCheckBox('simple_triggers', _('Simple triggers'))
+ )
+ ->addField(
+ new CWidgetFieldCheckBox('working_time', _('Working time'))
+ )
+ ->addField(
+ new CWidgetFieldCheckBox('percentile_left', _('Percentile line (left)'))
+ )
+ ->addField(
+ (new CWidgetFieldTextBox('percentile_left_value', null))
+ ->setFlags(!$this->percentile_left_on ? CWidgetField::FLAG_DISABLED : 0x00)
+ )
+ ->addField(
+ new CWidgetFieldCheckBox('percentile_right', _('Percentile line (right)'))
+ )
+ ->addField(
+ (new CWidgetFieldTextBox('percentile_right_value', null))
+ ->setFlags(!$this->percentile_right_on ? CWidgetField::FLAG_DISABLED : 0x00)
+ );
+ }
+
+ private function initTimePeriodFields(): self {
+ return $this
+ ->addField(
+ new CWidgetFieldCheckBox('graph_time', _('Set custom time period'))
+ )
+ ->addField(
+ (new CWidgetFieldDatePicker('time_from', _('From')))
+ ->setDefault('now-1h')
+ ->setFlags($this->graph_time_on
+ ? CWidgetField::FLAG_NOT_EMPTY
+ : CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_DISABLED
+ )
+ )
+ ->addField(
+ (new CWidgetFieldDatePicker('time_to', _('To')))
+ ->setDefault('now')
+ ->setFlags($this->graph_time_on
+ ? CWidgetField::FLAG_NOT_EMPTY
+ : CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_DISABLED
+ )
+ );
+ }
+
+ private function initAxesFields(): self {
+ return $this
+ ->addField(
+ (new CWidgetFieldCheckBox('lefty', _('Left Y'), _('Show')))->setDefault(SVG_GRAPH_AXIS_ON)
+ )
+ ->addField(
+ (new CWidgetFieldNumericBox('lefty_min', _('Min')))
+ ->setFullName(_('Left Y').'/'._('Min'))
+ ->setFlags(!$this->lefty_on ? CWidgetField::FLAG_DISABLED : 0x00)
+ )
+ ->addField(
+ (new CWidgetFieldNumericBox('lefty_max', _('Max')))
+ ->setFullName(_('Left Y').'/'._('Max'))
+ ->setFlags(!$this->lefty_on ? CWidgetField::FLAG_DISABLED : 0x00)
+ )
+ ->addField(
+ (new CWidgetFieldSelect('lefty_units', _('Units'), [
+ SVG_GRAPH_AXIS_UNITS_AUTO => _x('Auto', 'history source selection method'),
+ SVG_GRAPH_AXIS_UNITS_STATIC => _x('Static', 'history source selection method')
+ ]))
+ ->setDefault(SVG_GRAPH_AXIS_UNITS_AUTO)
+ ->setFlags(!$this->lefty_on ? CWidgetField::FLAG_DISABLED : 0x00)
+ )
+ ->addField(
+ (new CWidgetFieldTextBox('lefty_static_units'))
+ ->setFlags(!$this->lefty_on || !$this->lefty_units_static ? CWidgetField::FLAG_DISABLED : 0x00)
+ )
+ ->addField(
+ (new CWidgetFieldCheckBox('righty', _('Right Y'), _('Show')))->setDefault(SVG_GRAPH_AXIS_ON)
+ )
+ ->addField(
+ (new CWidgetFieldNumericBox('righty_min', _('Min')))
+ ->setFullName(_('Right Y').'/'._('Min'))
+ ->setFlags(!$this->righty_on ? CWidgetField::FLAG_DISABLED : 0x00)
+ )
+ ->addField(
+ (new CWidgetFieldNumericBox('righty_max', _('Max')))
+ ->setFullName(_('Right Y').'/'._('Max'))
+ ->setFlags(!$this->righty_on ? CWidgetField::FLAG_DISABLED : 0x00)
+ )
+ ->addField(
+ (new CWidgetFieldSelect('righty_units', _('Units'), [
+ SVG_GRAPH_AXIS_UNITS_AUTO => _x('Auto', 'history source selection method'),
+ SVG_GRAPH_AXIS_UNITS_STATIC => _x('Static', 'history source selection method')
+ ]))
+ ->setDefault(SVG_GRAPH_AXIS_UNITS_AUTO)
+ ->setFlags(!$this->righty_on ? CWidgetField::FLAG_DISABLED : 0x00)
+ )
+ ->addField(
+ (new CWidgetFieldTextBox('righty_static_units', null))
+ ->setFlags(!$this->righty_on || !$this->righty_units_static ? CWidgetField::FLAG_DISABLED : 0x00)
+ )
+ ->addField(
+ (new CWidgetFieldCheckBox('axisx', _('X-Axis'), _('Show')))->setDefault(SVG_GRAPH_AXIS_ON)
+ );
+ }
+
+ private function initLegendFields(): self {
+ return $this
+ ->addField(
+ (new CWidgetFieldCheckBox('legend', _('Show legend')))->setDefault(SVG_GRAPH_LEGEND_ON)
+ )
+ ->addField(
+ (new CWidgetFieldCheckBox('legend_statistic', _('Display min/max/avg')))
+ ->setFlags(!$this->legend_on ? CWidgetField::FLAG_DISABLED : 0x00)
+ )
+ ->addField(
+ (new CWidgetFieldRangeControl('legend_lines', _('Number of rows'),
+ SVG_GRAPH_LEGEND_LINES_MIN, SVG_GRAPH_LEGEND_LINES_MAX
+ ))
+ ->setDefault(SVG_GRAPH_LEGEND_LINES_MIN)
+ ->setFlags(!$this->legend_on ? CWidgetField::FLAG_DISABLED : 0x00)
+ )
+ ->addField(
+ (new CWidgetFieldRangeControl('legend_columns', _('Number of columns'),
+ SVG_GRAPH_LEGEND_COLUMNS_MIN, SVG_GRAPH_LEGEND_COLUMNS_MAX
+ ))
+ ->setDefault(SVG_GRAPH_LEGEND_COLUMNS_MAX)
+ ->setFlags(!$this->legend_on || $this->legend_statistic_on ? CWidgetField::FLAG_DISABLED : 0x00)
+ );
+ }
+
+ private function initProblemsFields(): self {
+ return $this
+ ->addField(
+ new CWidgetFieldCheckBox('show_problems', _('Show problems'))
+ )
+ ->addField(
+ (new CWidgetFieldCheckBox('graph_item_problems', _('Selected items only')))
+ ->setDefault(SVG_GRAPH_SELECTED_ITEM_PROBLEMS)
+ ->setFlags(!$this->problems_on ? CWidgetField::FLAG_DISABLED : 0x00)
+ )
+ ->addField(
+ (new CWidgetFieldHostPatternSelect('problemhosts', _('Problem hosts')))
+ ->setFlags(!$this->problems_on ? CWidgetField::FLAG_DISABLED : 0x00)
+ )
+ ->addField(
+ (new CWidgetFieldSeverities('severities', _('Severity')))
+ ->setFlags(!$this->problems_on ? CWidgetField::FLAG_DISABLED : 0x00)
+ )
+ ->addField(
+ (new CWidgetFieldTextBox('problem_name', _('Problem')))
+ ->setFlags(!$this->problems_on ? CWidgetField::FLAG_DISABLED : 0x00)
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('evaltype', _('Tags'), [
+ TAG_EVAL_TYPE_AND_OR => _('And/Or'),
+ TAG_EVAL_TYPE_OR => _('Or')
+ ]))
+ ->setDefault(TAG_EVAL_TYPE_AND_OR)
+ ->setFlags(!$this->problems_on ? CWidgetField::FLAG_DISABLED : 0x00)
+ )
+ ->addField(
+ (new CWidgetFieldTags('tags'))->setFlags(!$this->problems_on ? CWidgetField::FLAG_DISABLED : 0x00)
+ );
+ }
+
+ private function initOverridesFields(): self {
+ return $this->addField(
+ (new CWidgetFieldGraphOverride('or', _('Overrides')))->setFlags(CWidgetField::FLAG_NOT_EMPTY)
+ );
+ }
+
+ /**
+ * Check if widget configuration is set to use overridden time.
+ */
+ public static function hasOverrideTime(array $fields_values): bool {
+ return array_key_exists('graph_time', $fields_values)
+ && $fields_values['graph_time'] == SVG_GRAPH_CUSTOM_TIME_ON;
+ }
+
+ private static function validateTimeSelectorPeriod(string $from, string $to): array {
+ $errors = [];
+ $ts = [];
+ $ts['now'] = time();
+ $range_time_parser = new CRangeTimeParser();
+
+ foreach (['from' => $from, 'to' => $to] as $field => $value) {
+ $range_time_parser->parse($value);
+ $ts[$field] = $range_time_parser->getDateTime($field === 'from')->getTimestamp();
+ }
+
+ $period = $ts['to'] - $ts['from'] + 1;
+ $range_time_parser->parse('now-'.CSettingsHelper::get(CSettingsHelper::MAX_PERIOD));
+ $max_period = 1 + $ts['now'] - $range_time_parser->getDateTime(true)->getTimestamp();
+
+ if ($period < ZBX_MIN_PERIOD) {
+ $errors[] = _n('Minimum time period to display is %1$s minute.',
+ 'Minimum time period to display is %1$s minutes.', (int) (ZBX_MIN_PERIOD / SEC_PER_MIN)
+ );
+ }
+ elseif ($period > $max_period) {
+ $errors[] = _n('Maximum time period to display is %1$s day.',
+ 'Maximum time period to display is %1$s days.', (int) round($max_period / SEC_PER_DAY)
+ );
+ }
+
+ return $errors;
+ }
+}
diff --git a/ui/widgets/svggraph/manifest.json b/ui/widgets/svggraph/manifest.json
new file mode 100755
index 00000000000..db64bfc347d
--- /dev/null
+++ b/ui/widgets/svggraph/manifest.json
@@ -0,0 +1,15 @@
+{
+ "manifest_version": 2.0,
+ "id": "svggraph",
+ "type": "widget",
+ "name": "Graph",
+ "namespace": "SvgGraph",
+ "version": "1.0",
+ "author": "Zabbix SIA",
+ "widget": {
+ "js_class": "CWidgetSvgGraph"
+ },
+ "assets": {
+ "js": ["class.widget.js"]
+ }
+}
diff --git a/ui/include/classes/widgets/views/js/widget.svggraph.form.view.js.php b/ui/widgets/svggraph/views/widget.edit.js.php
index a1512cbcb4e..7764e8e40eb 100644..100755
--- a/ui/include/classes/widgets/views/js/widget.svggraph.form.view.js.php
+++ b/ui/widgets/svggraph/views/widget.edit.js.php
@@ -17,21 +17,24 @@
** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
-?>
+use Zabbix\Widgets\Fields\CWidgetFieldGraphDataSet;
+
+?>
+
window.widget_svggraph_form = new class {
constructor() {
this._dataset_index = 0;
}
- init({form_id, form_tabs_id, color_palette}) {
+ init({form_tabs_id, color_palette}) {
colorPalette.setThemeColors(color_palette);
this._$overlay_body = jQuery('.overlay-dialogue-body');
- this._form = document.getElementById(form_id);
- this._form_id = form_id;
+ this._form = document.getElementById('widget-dialogue-form');
+
this._dataset_wrapper = document.getElementById('data_sets');
@@ -119,8 +122,8 @@ window.widget_svggraph_form = new class {
}
if (e.target.classList.contains('js-click-expend')
- || e.target.classList.contains('color-picker-preview')
- || e.target.classList.contains('<?= ZBX_STYLE_BTN_GREY ?>')) {
+ || e.target.classList.contains('color-picker-preview')
+ || e.target.classList.contains('<?= ZBX_STYLE_BTN_GREY ?>')) {
jQuery('#data_sets').zbx_vertical_accordion('expandNth',
jQuery(e.target).closest('.<?= ZBX_STYLE_LIST_ACCORDION_ITEM ?>').index()
);
@@ -131,7 +134,7 @@ window.widget_svggraph_form = new class {
jQuery(window).trigger('resize');
const dataset = data.section[0];
- if (dataset.dataset.type == '<?= CWidgetHelper::DATASET_TYPE_SINGLE_ITEM ?>') {
+ if (dataset.dataset.type == '<?= CWidgetFieldGraphDataSet::DATASET_TYPE_SINGLE_ITEM ?>') {
const message_block = dataset.querySelector('.no-items-message');
if (dataset.querySelectorAll('.single-item-table-row').length == 0) {
@@ -143,7 +146,7 @@ window.widget_svggraph_form = new class {
jQuery(window).trigger('resize');
const dataset = data.section[0];
- if (dataset.dataset.type == '<?= CWidgetHelper::DATASET_TYPE_SINGLE_ITEM ?>') {
+ if (dataset.dataset.type == '<?= CWidgetFieldGraphDataSet::DATASET_TYPE_SINGLE_ITEM ?>') {
const message_block = dataset.querySelector('.no-items-message');
if (dataset.querySelectorAll('.single-item-table-row').length == 0) {
@@ -191,7 +194,7 @@ window.widget_svggraph_form = new class {
document
.getElementById('dataset-add')
.addEventListener('click', () => {
- this._addDataset(<?= CWidgetHelper::DATASET_TYPE_PATTERN_ITEM ?>);
+ this._addDataset(<?= CWidgetFieldGraphDataSet::DATASET_TYPE_PATTERN_ITEM ?>);
});
document
@@ -199,7 +202,7 @@ window.widget_svggraph_form = new class {
.addEventListener('click', this._addDatasetMenu);
window.addPopupValues = (list) => {
- if (!isset('object', list) || list.object != 'itemid') {
+ if (!isset('object', list) || list.object !== 'itemid') {
return false;
}
@@ -274,13 +277,13 @@ window.widget_svggraph_form = new class {
{
label: <?= json_encode(_('Item pattern')) ?>,
clickCallback: () => {
- widget_svggraph_form._addDataset(<?= CWidgetHelper::DATASET_TYPE_PATTERN_ITEM ?>);
+ widget_svggraph_form._addDataset(<?= CWidgetFieldGraphDataSet::DATASET_TYPE_PATTERN_ITEM ?>);
}
},
{
label: <?= json_encode(_('Item list')) ?>,
clickCallback: () => {
- widget_svggraph_form._addDataset(<?= CWidgetHelper::DATASET_TYPE_SINGLE_ITEM ?>);
+ widget_svggraph_form._addDataset(<?= CWidgetFieldGraphDataSet::DATASET_TYPE_SINGLE_ITEM ?>);
}
}
]
@@ -311,7 +314,7 @@ window.widget_svggraph_form = new class {
_addDataset(type) {
jQuery(this._dataset_wrapper).zbx_vertical_accordion('collapseAll');
- const template = type == <?= CWidgetHelper::DATASET_TYPE_SINGLE_ITEM ?>
+ const template = type == <?= CWidgetFieldGraphDataSet::DATASET_TYPE_SINGLE_ITEM ?>
? new Template(jQuery('#dataset-single-item-tmpl').html())
: new Template(jQuery('#dataset-pattern-item-tmpl').html());
@@ -325,7 +328,7 @@ window.widget_svggraph_form = new class {
this._dataset_wrapper.insertAdjacentHTML('beforeend', template.evaluate({
rowNum: this._dataset_index++,
- color: type == <?= CWidgetHelper::DATASET_TYPE_SINGLE_ITEM ?>
+ color: type == <?= CWidgetFieldGraphDataSet::DATASET_TYPE_SINGLE_ITEM ?>
? ''
: colorPalette.getNextColor(used_colors)
}));
@@ -359,7 +362,7 @@ window.widget_svggraph_form = new class {
const cloned_dataset = this._getOpenedDataset();
- if (dataset.dataset.type == <?= CWidgetHelper::DATASET_TYPE_SINGLE_ITEM ?>) {
+ if (dataset.dataset.type == <?= CWidgetFieldGraphDataSet::DATASET_TYPE_SINGLE_ITEM ?>) {
for (const row of dataset.querySelectorAll('.single-item-table-row')) {
this._addSingleItem(
row.querySelector(`[name^='ds[${dataset.getAttribute('data-set')}][itemids]`).value,
@@ -456,7 +459,7 @@ window.widget_svggraph_form = new class {
srctbl: 'items',
srcfld1: 'itemid',
srcfld2: 'name',
- dstfrm: this._form_id,
+ dstfrm: this._form.id,
numeric: 1,
writeonly: 1,
multiselect: 1,
@@ -571,7 +574,7 @@ window.widget_svggraph_form = new class {
srctbl: 'items',
srcfld1: 'itemid',
srcfld2: 'name',
- dstfrm: widget_svggraph_form._form_id,
+ dstfrm: widget_svggraph_form._form.id,
dstfld1: `items_${dataset_index}_${i}_input`,
dstfld2: `items_${dataset_index}_${i}_name`,
numeric: 1,
@@ -783,7 +786,7 @@ window.widget_svggraph_form = new class {
form_fields.or[i] = jQuery.extend({'hosts': [], 'items': []}, form_fields.or[i]);
}
}
- data.fields = JSON.stringify(form_fields);
+ data.fields = form_fields;
if (preview_data.xhr) {
preview_data.xhr.abort();
diff --git a/ui/widgets/svggraph/views/widget.edit.php b/ui/widgets/svggraph/views/widget.edit.php
new file mode 100755
index 00000000000..0211a20f94c
--- /dev/null
+++ b/ui/widgets/svggraph/views/widget.edit.php
@@ -0,0 +1,289 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+/**
+ * Graph widget form view.
+ *
+ * @var CView $this
+ * @var array $data
+ */
+
+use Zabbix\Widgets\Fields\CWidgetFieldGraphDataSet;
+
+$form = (new CWidgetFormView($data));
+
+$preview = (new CDiv())
+ ->addClass(ZBX_STYLE_SVG_GRAPH_PREVIEW)
+ ->addItem((new CDiv())->setId('svg-graph-preview'));
+
+$form_tabs = (new CTabView())
+ ->addTab('data_set', _('Data set'), getDatasetTab($form, $data['fields']),
+ TAB_INDICATOR_GRAPH_DATASET
+ )
+ ->addTab('displaying_options', _('Displaying options'), getDisplayOptionsTab($form, $data['fields']),
+ TAB_INDICATOR_GRAPH_DISPLAY_OPTIONS
+ )
+ ->addTab('time_period', _('Time period'), getTimePeriodTab($form, $data['fields']),
+ TAB_INDICATOR_GRAPH_TIME
+ )
+ ->addTab('axes', _('Axes'), getAxesTab($form, $data['fields']),
+ TAB_INDICATOR_GRAPH_AXES
+ )
+ ->addTab('legend_tab', _('Legend'), getLegendTab($form, $data['fields']),
+ TAB_INDICATOR_GRAPH_LEGEND
+ )
+ ->addTab('problems', _('Problems'), getProblemsTab($form, $data['fields']),
+ TAB_INDICATOR_GRAPH_PROBLEMS
+ )
+ ->addTab('overrides', _('Overrides'), getOverridesTab($form, $data['fields']),
+ TAB_INDICATOR_GRAPH_OVERRIDES
+ )
+ ->addClass('graph-widget-config-tabs')
+ ->setSelected(0);
+
+$form
+ ->addItem([$preview, $form_tabs])
+ ->addJavaScript($form_tabs->makeJavascript())
+ ->includeJsFile('widget.edit.js.php')
+ ->addJavaScript('widget_svggraph_form.init('.json_encode([
+ 'form_tabs_id' => $form_tabs->getId(),
+ 'color_palette' => CWidgetFieldGraphDataSet::DEFAULT_COLOR_PALETTE
+ ], JSON_THROW_ON_ERROR).');')
+ ->show();
+
+function getDatasetTab(CWidgetFormView $form, array $fields): CFormGrid {
+ $dataset = new CWidgetFieldGraphDataSetView($fields['ds']);
+
+ return new CFormGrid(
+ $form->makeCustomField($dataset, [
+ $dataset->getLabel(),
+ (new CFormField($dataset->getView()))->addClass(ZBX_STYLE_LIST_VERTICAL_ACCORDION),
+ (new CFormField($dataset->getFooterView()))->addClass(ZBX_STYLE_LIST_ACCORDION_FOOT)
+ ])
+ );
+}
+
+function getDisplayOptionsTab(CWidgetFormView $form, array $fields): CDiv {
+ $percentile_left = new CWidgetFieldCheckBoxView($fields['percentile_left']);
+ $percentile_left_value = (new CWidgetFieldTextBoxView($fields['percentile_left_value']))
+ ->setPlaceholder(_('value'))
+ ->setWidth(ZBX_TEXTAREA_TINY_WIDTH);
+
+ $percentile_right = new CWidgetFieldCheckBoxView($fields['percentile_right']);
+ $percentile_right_value = (new CWidgetFieldTextBoxView($fields['percentile_right_value']))
+ ->setPlaceholder(_('value'))
+ ->setWidth(ZBX_TEXTAREA_TINY_WIDTH);
+
+ return (new CDiv())
+ ->addClass(ZBX_STYLE_GRID_COLUMNS)
+ ->addClass(ZBX_STYLE_GRID_COLUMNS_2)
+ ->addItem(
+ new CFormGrid([
+ $form->makeCustomField(
+ new CWidgetFieldRadioButtonListView($fields['source'])
+ ),
+
+ $form->makeCustomField(
+ new CWidgetFieldCheckBoxView($fields['simple_triggers'])
+ ),
+
+ $form->makeCustomField(
+ new CWidgetFieldCheckBoxView($fields['working_time'])
+ )
+ ])
+ )
+ ->addItem(
+ new CFormGrid([
+ $form->makeCustomField($percentile_left, [
+ $percentile_left->getLabel(),
+ new CFormField([
+ $percentile_left->getView(),
+ $percentile_left_value->getView()
+ ])
+ ]),
+
+ $form->makeCustomField($percentile_right, [
+ $percentile_right->getLabel(),
+ new CFormField([
+ $percentile_right->getView(),
+ $percentile_right_value->getView()
+ ])
+ ])
+ ])
+ );
+}
+
+function getTimePeriodTab(CWidgetFormView $form, array $fields): CFormGrid {
+ return new CFormGrid([
+ $form->makeCustomField(
+ new CWidgetFieldCheckBoxView($fields['graph_time'])
+ ),
+
+ $form->makeCustomField(
+ (new CWidgetFieldDatePickerView($fields['time_from']))
+ ->setDateFormat(ZBX_FULL_DATE_TIME)
+ ->setPlaceholder(_('YYYY-MM-DD hh:mm:ss'))
+ ),
+
+ $form->makeCustomField(
+ (new CWidgetFieldDatePickerView($fields['time_to']))
+ ->setDateFormat(ZBX_FULL_DATE_TIME)
+ ->setPlaceholder(_('YYYY-MM-DD hh:mm:ss'))
+ ),
+ ]);
+}
+
+function getAxesTab(CWidgetFormView $form, array $fields): CDiv {
+ $lefty_units = new CWidgetFieldSelectView($fields['lefty_units']);
+ $lefty_static_units = (new CWidgetFieldTextBoxView($fields['lefty_static_units']))
+ ->setPlaceholder(_('value'))
+ ->setWidth(ZBX_TEXTAREA_TINY_WIDTH);
+
+ $righty_units = new CWidgetFieldSelectView($fields['righty_units']);
+ $righty_static_units = (new CWidgetFieldTextBoxView($fields['righty_static_units']))
+ ->setPlaceholder(_('value'))
+ ->setWidth(ZBX_TEXTAREA_TINY_WIDTH);
+
+ return (new CDiv())
+ ->addClass(ZBX_STYLE_GRID_COLUMNS)
+ ->addClass(ZBX_STYLE_GRID_COLUMNS_3)
+ ->addItem(
+ new CFormGrid([
+ $form->makeCustomField(
+ new CWidgetFieldCheckBoxView($fields['lefty'])
+ ),
+
+ $form->makeCustomField(
+ (new CWidgetFieldNumericBoxView($fields['lefty_min']))->setPlaceholder(_('calculated'))
+ ),
+
+ $form->makeCustomField(
+ (new CWidgetFieldNumericBoxView($fields['lefty_max']))->setPlaceholder(_('calculated'))
+ ),
+
+ $form->makeCustomField($lefty_units, [
+ $lefty_units->getLabel(),
+ new CFormField([
+ $lefty_units->getView()->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
+ $lefty_static_units->getView()
+ ])
+ ])
+ ])
+ )
+ ->addItem(
+ new CFormGrid([
+ $form->makeCustomField(
+ new CWidgetFieldCheckBoxView($fields['righty'])
+ ),
+
+ $form->makeCustomField(
+ (new CWidgetFieldNumericBoxView($fields['righty_min']))->setPlaceholder(_('calculated'))
+ ),
+
+ $form->makeCustomField(
+ (new CWidgetFieldNumericBoxView($fields['righty_max']))->setPlaceholder(_('calculated'))
+ ),
+
+ $form->makeCustomField($righty_units, [
+ $righty_units->getLabel(),
+ new CFormField([
+ $righty_units->getView()->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
+ $righty_static_units->getView()
+ ])
+ ])
+ ])
+ )
+ ->addItem(
+ new CFormGrid(
+ $form->makeCustomField(
+ new CWidgetFieldCheckBoxView($fields['axisx'])
+ )
+ )
+ );
+}
+
+function getLegendTab(CWidgetFormView $form, array $fields): CDiv {
+ return (new CDiv())
+ ->addClass(ZBX_STYLE_GRID_COLUMNS)
+ ->addClass(ZBX_STYLE_GRID_COLUMNS_2)
+ ->addItem(
+ new CFormGrid([
+ $form->makeCustomField(
+ new CWidgetFieldCheckBoxView($fields['legend'])
+ ),
+
+ $form->makeCustomField(
+ new CWidgetFieldCheckBoxView($fields['legend_statistic'])
+ )
+ ])
+ )
+ ->addItem(
+ new CFormGrid([
+ $form->makeCustomField(
+ new CWidgetFieldRangeControlView($fields['legend_lines'])
+ ),
+
+ $form->makeCustomField(
+ new CWidgetFieldRangeControlView($fields['legend_columns'])
+ )
+ ])
+ );
+}
+
+function getProblemsTab(CWidgetFormView $form, array $fields): CFormGrid {
+ return new CFormGrid([
+ $form->makeCustomField(
+ new CWidgetFieldCheckBoxView($fields['show_problems'])
+ ),
+
+ $form->makeCustomField(
+ new CWidgetFieldCheckBoxView($fields['graph_item_problems'])
+ ),
+
+ $form->makeCustomField(
+ (new CWidgetFieldHostPatternSelectView($fields['problemhosts']))->setPlaceholder(_('host pattern'))
+ ),
+
+ $form->makeCustomField(
+ new CWidgetFieldSeveritiesView($fields['severities'])
+ ),
+
+ $form->makeCustomField(
+ (new CWidgetFieldTextBoxView($fields['problem_name']))->setPlaceholder(_('problem pattern'))
+ ),
+
+ $form->makeCustomField(
+ new CWidgetFieldRadioButtonListView($fields['evaltype'])
+ ),
+
+ $form->makeCustomField(
+ new CWidgetFieldTagsView($fields['tags'])
+ )
+ ]);
+}
+
+function getOverridesTab(CWidgetFormView $form, array $fields): CFormGrid {
+ return new CFormGrid(
+ $form->makeCustomField(
+ new CWidgetFieldGraphOverrideView($fields['or'])
+ )
+ );
+}
diff --git a/ui/include/classes/widgets/views/widget.favmaps.form.view.php b/ui/widgets/svggraph/views/widget.view.php
index 044ea1f4f57..cbf56edf763 100644
--- a/ui/include/classes/widgets/views/widget.favmaps.form.view.php
+++ b/ui/widgets/svggraph/views/widget.view.php
@@ -20,23 +20,20 @@
/**
- * Favorite maps widget form view.
+ * Graph widget view.
*
* @var CView $this
* @var array $data
*/
-$fields = $data['dialogue']['fields'];
+$view = (new CWidgetView($data))->addItem($data['svg']);
-$form = CWidgetHelper::createForm();
+if (!$data['preview']) {
+ $view->setVar('svg_options', $data['svg_options']);
-$form_grid = CWidgetHelper::createFormGrid($data['dialogue']['name'], $data['dialogue']['type'],
- $data['dialogue']['view_mode'], $data['known_widget_types'],
- $data['templateid'] === null ? $fields['rf_rate'] : null
-);
+ if ($data['info'] !== null) {
+ $view->setVar('info', $data['info']);
+ }
+}
-$form->addItem($form_grid);
-
-return [
- 'form' => $form
-];
+$view->show();
diff --git a/ui/widgets/systeminfo/Widget.php b/ui/widgets/systeminfo/Widget.php
new file mode 100755
index 00000000000..42f863b77b2
--- /dev/null
+++ b/ui/widgets/systeminfo/Widget.php
@@ -0,0 +1,31 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\SystemInfo;
+
+use Zabbix\Core\CWidget;
+
+class Widget extends CWidget {
+
+ public function getDefaultName(): string {
+ return _('System information');
+ }
+}
diff --git a/ui/app/controllers/CControllerWidgetSystemInfoView.php b/ui/widgets/systeminfo/actions/WidgetView.php
index f79b2b17557..e0763c4fc7d 100644
--- a/ui/app/controllers/CControllerWidgetSystemInfoView.php
+++ b/ui/widgets/systeminfo/actions/WidgetView.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,27 +19,20 @@
**/
-require_once __DIR__.'/../../include/blocks.inc.php';
+namespace Widgets\SystemInfo\Actions;
-class CControllerWidgetSystemInfoView extends CControllerWidget {
+use CControllerDashboardWidgetView,
+ CControllerResponseData,
+ CSystemInfoHelper,
+ CWebUser;
- public function __construct() {
- parent::__construct();
-
- $this->setType(WIDGET_SYSTEM_INFO);
- $this->setValidationRules([
- 'name' => 'string',
- 'fields' => 'json'
- ]);
- }
-
- protected function doAction() {
- $fields = $this->getForm()->getFieldsData();
+class WidgetView extends CControllerDashboardWidgetView {
+ protected function doAction(): void {
$this->setResponse(new CControllerResponseData([
- 'name' => $this->getInput('name', $this->getDefaultName()),
+ 'name' => $this->getInput('name', $this->widget->getDefaultName()),
'system_info' => CSystemInfoHelper::getData(),
- 'info_type' => $fields['info_type'],
+ 'info_type' => $this->fields_values['info_type'],
'user_type' => CWebUser::getType(),
'user' => [
'debug_mode' => $this->getDebugMode()
diff --git a/ui/widgets/systeminfo/includes/WidgetForm.php b/ui/widgets/systeminfo/includes/WidgetForm.php
new file mode 100644
index 00000000000..27b92eec41d
--- /dev/null
+++ b/ui/widgets/systeminfo/includes/WidgetForm.php
@@ -0,0 +1,42 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\SystemInfo\Includes;
+
+use Zabbix\Widgets\CWidgetForm;
+
+use Zabbix\Widgets\Fields\CWidgetFieldRadioButtonList;
+
+/**
+ * System information widget form.
+ */
+class WidgetForm extends CWidgetForm {
+
+ public function addFields(): self {
+ return $this
+ ->addField(
+ (new CWidgetFieldRadioButtonList('info_type', _('Show'), [
+ ZBX_SYSTEM_INFO_SERVER_STATS => _('System stats'),
+ ZBX_SYSTEM_INFO_HAC_STATUS => _('High availability nodes')
+ ]))->setDefault(ZBX_SYSTEM_INFO_SERVER_STATS)
+ );
+ }
+}
diff --git a/ui/widgets/systeminfo/manifest.json b/ui/widgets/systeminfo/manifest.json
new file mode 100755
index 00000000000..ec77d9e7503
--- /dev/null
+++ b/ui/widgets/systeminfo/manifest.json
@@ -0,0 +1,12 @@
+{
+ "manifest_version": 2.0,
+ "id": "systeminfo",
+ "type": "widget",
+ "name": "System information",
+ "namespace": "SystemInfo",
+ "version": "1.0",
+ "author": "Zabbix SIA",
+ "widget": {
+ "refresh_rate": 900
+ }
+}
diff --git a/ui/widgets/systeminfo/views/widget.edit.php b/ui/widgets/systeminfo/views/widget.edit.php
new file mode 100755
index 00000000000..1874ccb4fa1
--- /dev/null
+++ b/ui/widgets/systeminfo/views/widget.edit.php
@@ -0,0 +1,33 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+/**
+ * System information widget form view.
+ *
+ * @var CView $this
+ * @var array $data
+ */
+
+(new CWidgetFormView($data))
+ ->addField(
+ new CWidgetFieldRadioButtonListView($data['fields']['info_type'])
+ )
+ ->show();
diff --git a/ui/app/views/monitoring.widget.systeminfo.view.php b/ui/widgets/systeminfo/views/widget.view.php
index 37c71a2b995..021e95b5f70 100644
--- a/ui/app/views/monitoring.widget.systeminfo.view.php
+++ b/ui/widgets/systeminfo/views/widget.view.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -20,6 +20,8 @@
/**
+ * System information widget view.
+ *
* @var CView $this
* @var array $data
*/
@@ -51,18 +53,6 @@ switch ($data['info_type']) {
$body = '';
}
-$output = [
- 'name' => $data['name'],
- 'body' => $body
-];
-
-if ($messages = get_and_clear_messages()) {
- $output['messages'] = array_column($messages, 'message');
-}
-
-if ($data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
- CProfiler::getInstance()->stop();
- $output['debug'] = CProfiler::getInstance()->make()->toString();
-}
-
-echo json_encode($output);
+(new CWidgetView($data))
+ ->addItem($body)
+ ->show();
diff --git a/ui/widgets/tophosts/Widget.php b/ui/widgets/tophosts/Widget.php
new file mode 100755
index 00000000000..14108f1c4dd
--- /dev/null
+++ b/ui/widgets/tophosts/Widget.php
@@ -0,0 +1,36 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\TopHosts;
+
+use Zabbix\Core\CWidget;
+
+class Widget extends CWidget {
+
+ public const DEFAULT_FILL = '#97AAB3';
+
+ public const ORDER_TOP_N = 2;
+ public const ORDER_BOTTOM_N = 3;
+
+ public function getDefaultName(): string {
+ return _('Top hosts');
+ }
+}
diff --git a/ui/app/controllers/CControllerPopupTopHostsColumnEdit.php b/ui/widgets/tophosts/actions/ColumnEdit.php
index 5e67f74638f..6513a3dd2f1 100644
--- a/ui/app/controllers/CControllerPopupTopHostsColumnEdit.php
+++ b/ui/widgets/tophosts/actions/ColumnEdit.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2021 Zabbix SIA
@@ -19,46 +19,56 @@
**/
-class CControllerPopupTopHostsColumnEdit extends CController {
-
- protected $column_defaults = [
- 'name' => '',
- 'data' => CWidgetFieldColumnsList::DATA_ITEM_VALUE,
- 'item' => '',
- 'timeshift' => '',
- 'aggregate_function' => AGGREGATE_NONE,
- 'aggregate_interval' => '1h',
- 'display' => CWidgetFieldColumnsList::DISPLAY_AS_IS,
- 'history' => CWidgetFieldColumnsList::HISTORY_DATA_AUTO,
- 'min' => '',
- 'max' => '',
- 'base_color' => '',
- 'text' => '',
- 'thresholds' => []
+namespace Widgets\TopHosts\Actions;
+
+use CArrayHelper,
+ CController,
+ CControllerResponseData,
+ CNumberParser,
+ CParser;
+
+use Zabbix\Widgets\Fields\CWidgetFieldColumnsList;
+
+class ColumnEdit extends CController {
+
+ protected array $column_defaults = [
+ 'name' => '',
+ 'data' => CWidgetFieldColumnsList::DATA_ITEM_VALUE,
+ 'item' => '',
+ 'timeshift' => '',
+ 'aggregate_function' => AGGREGATE_NONE,
+ 'aggregate_interval' => '1h',
+ 'display' => CWidgetFieldColumnsList::DISPLAY_AS_IS,
+ 'history' => CWidgetFieldColumnsList::HISTORY_DATA_AUTO,
+ 'min' => '',
+ 'max' => '',
+ 'base_color' => '',
+ 'text' => '',
+ 'thresholds' => []
];
- protected function init() {
+ protected function init(): void {
$this->disableSIDValidation();
}
- protected function checkInput() {
+ protected function checkInput(): bool {
// Validation is done by CWidgetFieldColumnsList
$fields = [
- 'name' => 'string',
- 'data' => 'int32',
- 'item' => 'string',
- 'timeshift' => 'string',
- 'aggregate_function' => 'int32',
- 'aggregate_interval' => 'string',
- 'display' => 'int32',
- 'history' => 'int32',
- 'min' => 'string',
- 'max' => 'string',
- 'base_color' => 'string',
- 'thresholds' => 'array',
- 'text' => 'string',
- 'edit' => 'in 1',
- 'update' => 'in 1'
+ 'name' => 'string',
+ 'data' => 'int32',
+ 'item' => 'string',
+ 'timeshift' => 'string',
+ 'aggregate_function' => 'int32',
+ 'aggregate_interval' => 'string',
+ 'display' => 'int32',
+ 'history' => 'int32',
+ 'min' => 'string',
+ 'max' => 'string',
+ 'base_color' => 'string',
+ 'thresholds' => 'array',
+ 'text' => 'string',
+ 'edit' => 'in 1',
+ 'update' => 'in 1'
];
$ret = $this->validateInput($fields) && $this->validateFields($this->getInputAll());
@@ -69,7 +79,7 @@ class CControllerPopupTopHostsColumnEdit extends CController {
'error' => [
'messages' => array_column(get_and_clear_messages(), 'message')
]
- ])]))->disableView()
+ ], JSON_THROW_ON_ERROR)]))->disableView()
);
}
@@ -91,23 +101,23 @@ class CControllerPopupTopHostsColumnEdit extends CController {
return !$errors;
}
- protected function checkPermissions() {
+ protected function checkPermissions(): bool {
return true;
}
- protected function doAction() {
+ protected function doAction(): void {
$input = $this->getInputAll();
unset($input['update']);
if (!$this->hasInput('update')) {
$this->setResponse(new CControllerResponseData([
- 'action' => $this->getAction(),
- 'thresholds_colors' => CWidgetFieldColumnsList::THRESHOLDS_DEFAULT_COLOR_PALETTE,
- 'errors' => hasErrorMessages() ? getMessages() : null,
- 'user' => [
- 'debug_mode' => $this->getDebugMode()
- ]
- ] + $input + $this->column_defaults));
+ 'action' => $this->getAction(),
+ 'thresholds_colors' => CWidgetFieldColumnsList::THRESHOLDS_DEFAULT_COLOR_PALETTE,
+ 'errors' => hasErrorMessages() ? getMessages() : null,
+ 'user' => [
+ 'debug_mode' => $this->getDebugMode()
+ ]
+ ] + $input + $this->column_defaults));
return;
}
@@ -140,6 +150,8 @@ class CControllerPopupTopHostsColumnEdit extends CController {
}
}
- $this->setResponse((new CControllerResponseData(['main_block' => json_encode($input)]))->disableView());
+ $this->setResponse(
+ (new CControllerResponseData(['main_block' => json_encode($input, JSON_THROW_ON_ERROR)]))->disableView()
+ );
}
}
diff --git a/ui/app/controllers/CControllerWidgetTopHostsView.php b/ui/widgets/tophosts/actions/WidgetView.php
index 1eed40c3514..8c9596ba6ef 100644
--- a/ui/app/controllers/CControllerWidgetTopHostsView.php
+++ b/ui/widgets/tophosts/actions/WidgetView.php
@@ -19,51 +19,50 @@
**/
-class CControllerWidgetTopHostsView extends CControllerWidget {
+namespace Widgets\TopHosts\Actions;
- public function __construct() {
- parent::__construct();
+use API,
+ CControllerDashboardWidgetView,
+ CControllerResponseData,
+ CHousekeepingHelper,
+ CMacrosResolverHelper,
+ CNumberParser,
+ CParser,
+ CSettingsHelper,
+ Manager;
- $this->setType(WIDGET_TOP_HOSTS);
- $this->setValidationRules([
- 'name' => 'string',
- 'fields' => 'json'
- ]);
- }
+use Widgets\TopHosts\Widget;
+
+use Zabbix\Widgets\Fields\CWidgetFieldColumnsList;
+
+class WidgetView extends CControllerDashboardWidgetView {
- protected function doAction() {
+ protected function doAction(): void {
$data = [
- 'name' => $this->getInput('name', $this->getDefaultName()),
+ 'name' => $this->getInput('name', $this->widget->getDefaultName()),
'user' => [
'debug_mode' => $this->getDebugMode()
]
];
- $data += self::getData($this->getForm()->getFieldsData());
+ $data += $this->getData();
$this->setResponse(new CControllerResponseData($data));
}
- /**
- * @param array $fields
- *
- * @throws Exception
- *
- * @return array
- */
- private static function getData(array $fields): array {
- $configuration = $fields['columns'];
+ private function getData(): array {
+ $configuration = $this->fields_values['columns'];
- $groupids = $fields['groupids'] ? getSubGroups($fields['groupids']) : null;
- $hostids = $fields['hostids'] ?: null;
+ $groupids = $this->fields_values['groupids'] ? getSubGroups($this->fields_values['groupids']) : null;
+ $hostids = $this->fields_values['hostids'] ?: null;
- if (array_key_exists('tags', $fields)) {
+ if (array_key_exists('tags', $this->fields_values)) {
$hosts = API::Host()->get([
'output' => ['name'],
'groupids' => $groupids,
'hostids' => $hostids,
- 'evaltype' => $fields['evaltype'],
- 'tags' => $fields['tags'],
+ 'evaltype' => $this->fields_values['evaltype'],
+ 'tags' => $this->fields_values['tags'],
'monitored_hosts' => true,
'preservekeys' => true
]);
@@ -76,7 +75,7 @@ class CControllerWidgetTopHostsView extends CControllerWidget {
$time_now = time();
- $master_column = $configuration[$fields['column']];
+ $master_column = $configuration[$this->fields_values['column']];
$master_items_only_numeric_allowed = self::isNumericOnlyColumn($master_column);
$master_items = self::getItems($master_column['item'], $master_items_only_numeric_allowed, $groupids, $hostids);
@@ -95,7 +94,7 @@ class CControllerWidgetTopHostsView extends CControllerWidget {
}
);
- if ($fields['order'] == CWidgetFormTopHosts::ORDER_TOPN) {
+ if ($this->fields_values['order'] == Widget::ORDER_TOP_N) {
if ($master_items_only_numeric_present) {
arsort($master_item_values, SORT_NUMERIC);
@@ -118,7 +117,7 @@ class CControllerWidgetTopHostsView extends CControllerWidget {
}
}
- $master_item_values = array_slice($master_item_values, 0, $fields['count'], true);
+ $master_item_values = array_slice($master_item_values, 0, $this->fields_values['count'], true);
$master_items = array_intersect_key($master_items, $master_item_values);
$master_hostids = [];
@@ -158,7 +157,7 @@ class CControllerWidgetTopHostsView extends CControllerWidget {
unset($threshold);
}
- if ($column_index == $fields['column']) {
+ if ($column_index == $this->fields_values['column']) {
$column_items = $master_items;
$column_item_values = $master_item_values;
@@ -174,7 +173,7 @@ class CControllerWidgetTopHostsView extends CControllerWidget {
}
else {
$numeric_only = self::isNumericOnlyColumn($column);
- $column_items = !$calc_extremes || $column['min'] !== '' && $column['max'] !== ''
+ $column_items = !$calc_extremes || ($column['min'] !== '' && $column['max'] !== '')
? self::getItems($column['item'], $numeric_only, $groupids, array_keys($master_hostids))
: self::getItems($column['item'], $numeric_only, $groupids, $hostids);
@@ -269,25 +268,12 @@ class CControllerWidgetTopHostsView extends CControllerWidget {
];
}
- /**
- * @param array $column
- *
- * @return bool
- */
private static function isNumericOnlyColumn(array $column): bool {
return $column['aggregate_function'] != AGGREGATE_NONE
|| $column['display'] != CWidgetFieldColumnsList::DISPLAY_AS_IS
|| array_key_exists('thresholds', $column);
}
- /**
- * @param string $name
- * @param bool $numeric_only
- * @param array|null $groupids
- * @param array|null $hostids
- *
- * @return array
- */
private static function getItems(string $name, bool $numeric_only, ?array $groupids, ?array $hostids): array {
$items = API::Item()->get([
'output' => ['itemid', 'hostid', 'key_', 'history', 'trends', 'value_type', 'units'],
@@ -318,13 +304,6 @@ class CControllerWidgetTopHostsView extends CControllerWidget {
return $items;
}
- /**
- * @param array $items
- * @param array $column
- * @param int $time_now
- *
- * @return array
- */
private static function getItemValues(array $items, array $column, int $time_now): array {
static $history_period;
@@ -387,14 +366,6 @@ class CControllerWidgetTopHostsView extends CControllerWidget {
return $result;
}
- /**
- * @param array $items
- * @param int $time_from
- * @param int $time_now
- * @param int $data_source
- *
- * @return void
- */
private static function addDataSource(array &$items, int $time_from, int $time_now, int $data_source): void {
if ($data_source == CWidgetFieldColumnsList::HISTORY_DATA_HISTORY
|| $data_source == CWidgetFieldColumnsList::HISTORY_DATA_TRENDS) {
diff --git a/ui/widgets/tophosts/includes/WidgetForm.php b/ui/widgets/tophosts/includes/WidgetForm.php
new file mode 100644
index 00000000000..633f6152c68
--- /dev/null
+++ b/ui/widgets/tophosts/includes/WidgetForm.php
@@ -0,0 +1,139 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2021 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\TopHosts\Includes;
+
+use Zabbix\Widgets\{
+ CWidgetField,
+ CWidgetForm
+};
+
+use Zabbix\Widgets\Fields\{
+ CWidgetFieldColumnsList,
+ CWidgetFieldIntegerBox,
+ CWidgetFieldMultiSelectGroup,
+ CWidgetFieldMultiSelectHost,
+ CWidgetFieldRadioButtonList,
+ CWidgetFieldSelect,
+ CWidgetFieldTags
+};
+
+use Widgets\TopHosts\Widget;
+
+/**
+ * Top hosts data widget form.
+ */
+class WidgetForm extends CWidgetForm {
+
+ private const DEFAULT_HOSTS_COUNT = 10;
+ private const DEFAULT_ORDER_COLUMN = 0;
+
+ private array $field_column_values = [];
+
+ protected function normalizeValues(array $values): array {
+ $values = self::convertDottedKeys($values);
+
+ if (array_key_exists('columnsthresholds', $values)) {
+ foreach ($values['columnsthresholds'] as $column_index => $fields) {
+ $values['columns'][$column_index]['thresholds'] = [];
+
+ foreach ($fields as $field_key => $field_values) {
+ foreach ($field_values as $value_index => $value) {
+ $values['columns'][$column_index]['thresholds'][$value_index][$field_key] = $value;
+ }
+ }
+ }
+ }
+
+ // Apply sortable changes to data.
+ if (array_key_exists('sortorder', $values)) {
+ if (array_key_exists('column', $values) && array_key_exists('columns', $values['sortorder'])) {
+ // Fix selected column index when columns were sorted.
+ $values['column'] = array_search($values['column'], $values['sortorder']['columns'], true);
+ }
+
+ foreach ($values['sortorder'] as $key => $sortorder) {
+ if (!array_key_exists($key, $values)) {
+ continue;
+ }
+
+ $sorted = [];
+
+ foreach ($sortorder as $index) {
+ $sorted[] = $values[$key][$index];
+ }
+
+ $values[$key] = $sorted;
+ }
+ }
+
+ if (array_key_exists('columns', $values)) {
+ foreach ($values['columns'] as $key => $value) {
+ if ($value['data'] == CWidgetFieldColumnsList::DATA_ITEM_VALUE) {
+ $this->field_column_values[$key] = ($value['name'] === '') ? $value['item'] : $value['name'];
+ }
+ }
+ }
+
+ return $values;
+ }
+
+ public function addFields(): self {
+ return $this
+ ->addField(
+ new CWidgetFieldMultiSelectGroup('groupids', _('Host groups'))
+ )
+ ->addField(
+ new CWidgetFieldMultiSelectHost('hostids', _('Hosts'))
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('evaltype', _('Host tags'), [
+ TAG_EVAL_TYPE_AND_OR => _('And/Or'),
+ TAG_EVAL_TYPE_OR => _('Or')
+ ]))->setDefault(TAG_EVAL_TYPE_AND_OR)
+ )
+ ->addField(
+ new CWidgetFieldTags('tags', '')
+ )
+ ->addField(
+ (new CWidgetFieldColumnsList('columns', _('Columns')))->setFlags(CWidgetField::FLAG_LABEL_ASTERISK)
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('order', _('Order'), [
+ Widget::ORDER_TOP_N => _('Top N'),
+ Widget::ORDER_BOTTOM_N => _('Bottom N')
+ ]))->setDefault(Widget::ORDER_TOP_N)
+ )
+ ->addField(
+ (new CWidgetFieldSelect('column', _('Order column'), $this->field_column_values))
+ ->setDefault($this->field_column_values
+ ? self::DEFAULT_ORDER_COLUMN
+ : CWidgetFieldSelect::DEFAULT_VALUE
+ )
+ ->setFlags(CWidgetField::FLAG_LABEL_ASTERISK)
+ )
+ ->addField(
+ (new CWidgetFieldIntegerBox('count', _('Host count'), ZBX_MIN_WIDGET_LINES, ZBX_MAX_WIDGET_LINES))
+ ->setDefault(self::DEFAULT_HOSTS_COUNT)
+ ->setFlags(CWidgetField::FLAG_LABEL_ASTERISK)
+ );
+ }
+}
diff --git a/ui/widgets/tophosts/manifest.json b/ui/widgets/tophosts/manifest.json
new file mode 100755
index 00000000000..6ccb8b33cd2
--- /dev/null
+++ b/ui/widgets/tophosts/manifest.json
@@ -0,0 +1,16 @@
+{
+ "manifest_version": 2.0,
+ "id": "tophosts",
+ "type": "widget",
+ "name": "Top hosts",
+ "namespace": "TopHosts",
+ "version": "1.0",
+ "author": "Zabbix SIA",
+ "actions": {
+ "widget.tophosts.column.edit": {
+ "class": "ColumnEdit",
+ "view": "column.edit",
+ "layout": "layout.json"
+ }
+ }
+}
diff --git a/ui/app/views/js/popup.tophosts.column.edit.js.php b/ui/widgets/tophosts/views/column.edit.js.php
index d11bc9eaac8..d9adf48cebf 100644
--- a/ui/app/views/js/popup.tophosts.column.edit.js.php
+++ b/ui/widgets/tophosts/views/column.edit.js.php
@@ -17,9 +17,12 @@
** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
-?>
+use Zabbix\Widgets\Fields\CWidgetFieldColumnsList;
+
+?>
+
window.tophosts_column_edit_form = new class {
init({form_name, thresholds, thresholds_colors}) {
diff --git a/ui/app/views/popup.tophosts.column.edit.php b/ui/widgets/tophosts/views/column.edit.php
index 10739a1f874..b0d1fc47c6b 100644
--- a/ui/app/views/popup.tophosts.column.edit.php
+++ b/ui/widgets/tophosts/views/column.edit.php
@@ -24,6 +24,8 @@
* @var array $data
*/
+use Zabbix\Widgets\Fields\CWidgetFieldColumnsList;
+
$form = (new CForm())
->setName('tophosts_column')
->addStyle('display: none;')
@@ -73,8 +75,8 @@ $form_grid->addItem([
(new CLabel(_('Text'), 'text'))->setAsteriskMark(),
new CFormField(
(new CTextBox('text', $data['text']))
- ->setAttribute('placeholder', _('Text, supports {INVENTORY.*}, {HOST.*} macros'))
->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
+ ->setAttribute('placeholder', _('Text, supports {INVENTORY.*}, {HOST.*} macros'))
)
]);
@@ -108,8 +110,8 @@ $form_grid->addItem([
new CLabel(_('Time shift'), 'timeshift'),
new CFormField(
(new CTextBox('timeshift', $data['timeshift']))
- ->setAttribute('placeholder', _('none'))
->setWidth(ZBX_TEXTAREA_TINY_WIDTH)
+ ->setAttribute('placeholder', _('none'))
)
]);
@@ -159,7 +161,7 @@ $form_grid->addItem([
->addValue(_('As is'), CWidgetFieldColumnsList::DISPLAY_AS_IS)
->addValue(_('Bar'), CWidgetFieldColumnsList::DISPLAY_BAR)
->addValue(_('Indicators'), CWidgetFieldColumnsList::DISPLAY_INDICATORS)
- ->setModern(true)
+ ->setModern()
)
]);
@@ -176,7 +178,7 @@ $form_grid->addItem([
->addValue(_('Auto'), CWidgetFieldColumnsList::HISTORY_DATA_AUTO)
->addValue(_('History'), CWidgetFieldColumnsList::HISTORY_DATA_HISTORY)
->addValue(_('Trends'), CWidgetFieldColumnsList::HISTORY_DATA_TRENDS)
- ->setModern(true)
+ ->setModern()
)
]);
@@ -191,8 +193,8 @@ $form_grid->addItem([
new CLabel(_('Min'), 'min'),
new CFormField(
(new CTextBox('min', $data['min']))
- ->setAttribute('placeholder', _('calculated'))
->setWidth(ZBX_TEXTAREA_FILTER_SMALL_WIDTH)
+ ->setAttribute('placeholder', _('calculated'))
)
]);
@@ -201,8 +203,8 @@ $form_grid->addItem([
new CLabel(_('Max'), 'max'),
new CFormField(
(new CTextBox('max', $data['max']))
- ->setAttribute('placeholder', _('calculated'))
->setWidth(ZBX_TEXTAREA_FILTER_SMALL_WIDTH)
+ ->setAttribute('placeholder', _('calculated'))
)
]);
@@ -230,7 +232,7 @@ $thresholds = (new CDiv(
->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH);
$thresholds->addItem(
- (new CScriptTemplate('thresholds-row-tmpl'))
+ (new CTemplateTag('thresholds-row-tmpl'))
->addItem((new CRow([
(new CColor('thresholds[#{rowNum}][color]', '#{color}'))->appendColorPickerJs(false),
(new CTextBox('thresholds[#{rowNum}][threshold]', '#{threshold}', false))
@@ -255,16 +257,16 @@ $form
->addItem(
(new CScriptTag('
tophosts_column_edit_form.init('.json_encode([
- 'form_name' => $form->getName(),
- 'thresholds' => $data['thresholds'],
- 'thresholds_colors' => $data['thresholds_colors']
- ]).');
+ 'form_name' => $form->getName(),
+ 'thresholds' => $data['thresholds'],
+ 'thresholds_colors' => $data['thresholds_colors']
+ ], JSON_THROW_ON_ERROR).');
'))->setOnDocumentReady()
);
$output = [
'header' => array_key_exists('edit', $data) ? _('Update column') : _('New column'),
- 'script_inline' => implode('', $scripts).$this->readJsFile('popup.tophosts.column.edit.js.php'),
+ 'script_inline' => implode('', $scripts).$this->readJsFile('column.edit.js.php', null, ''),
'body' => $form->toString(),
'buttons' => [
[
@@ -281,4 +283,4 @@ if ($data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
$output['debug'] = CProfiler::getInstance()->make()->toString();
}
-echo json_encode($output);
+echo json_encode($output, JSON_THROW_ON_ERROR);
diff --git a/ui/include/classes/widgets/views/js/widget.tophosts.form.view.js.php b/ui/widgets/tophosts/views/widget.edit.js.php
index ab39855b96e..5139a711209 100644..100755
--- a/ui/include/classes/widgets/views/js/widget.tophosts.form.view.js.php
+++ b/ui/widgets/tophosts/views/widget.edit.js.php
@@ -22,8 +22,9 @@
window.widget_tophosts_form = new class {
- init(options) {
- this._form = document.getElementById(options.form_id);
+ init() {
+ this._form = document.getElementById('widget-dialogue-form');
+
this._list_columns = document.getElementById('list_columns');
this.initSortable(this._list_columns);
@@ -79,7 +80,7 @@ window.widget_tophosts_form = new class {
case 'add':
this._column_index = this._list_columns.querySelectorAll('tr').length;
- column_popup = PopUp('popup.tophosts.column.edit', {}).$dialogue[0];
+ column_popup = PopUp('widget.tophosts.column.edit', {}).$dialogue[0];
column_popup.addEventListener('dialogue.submit', (e) => this.updateColumns(e));
column_popup.addEventListener('overlay.close', this.removeColorpicker);
break;
@@ -89,7 +90,7 @@ window.widget_tophosts_form = new class {
this._column_index = target.closest('tr').querySelector('[name="sortorder[columns][]"]').value;
- column_popup = PopUp('popup.tophosts.column.edit',
+ column_popup = PopUp('widget.tophosts.column.edit',
{...form_fields.columns[this._column_index], edit: 1}).$dialogue[0];
column_popup.addEventListener('dialogue.submit', (e) => this.updateColumns(e));
column_popup.addEventListener('overlay.close', this.removeColorpicker);
@@ -142,7 +143,7 @@ window.widget_tophosts_form = new class {
ZABBIX.Dashboard.reloadWidgetProperties();
}
- // Need to remove function after subpopups auto close.
+ // Need to remove function after sub-popups auto close.
removeColorpicker() {
$('#color_picker').hide();
}
diff --git a/ui/widgets/tophosts/views/widget.edit.php b/ui/widgets/tophosts/views/widget.edit.php
new file mode 100755
index 00000000000..97d2f27ffab
--- /dev/null
+++ b/ui/widgets/tophosts/views/widget.edit.php
@@ -0,0 +1,85 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+/**
+ * Top hosts widget form view.
+ *
+ * @var CView $this
+ * @var array $data
+ */
+
+use Zabbix\Widgets\Fields\{
+ CWidgetFieldColumnsList,
+ CWidgetFieldSelect
+};
+
+$form = (new CWidgetFormView($data));
+
+$groupids = new CWidgetFieldMultiSelectGroupView($data['fields']['groupids'],
+ $data['captions']['ms']['groups']['groupids']
+);
+
+$form
+ ->addField($groupids)
+ ->addField(
+ (new CWidgetFieldMultiSelectHostView($data['fields']['hostids'], $data['captions']['ms']['hosts']['hostids']))
+ ->setFilterPreselect(['id' => $groupids->getId(), 'submit_as' => 'groupid'])
+ )
+ ->addField(
+ new CWidgetFieldRadioButtonListView($data['fields']['evaltype'])
+ )
+ ->addField(
+ new CWidgetFieldTagsView($data['fields']['tags'])
+ )
+ ->addItem(
+ getColumnsField($form, $data['fields']['columns'])
+ )
+ ->addField(
+ new CWidgetFieldRadioButtonListView($data['fields']['order'])
+ )
+ ->addItem(
+ getColumnField($form, $data['fields']['column'])
+ )
+ ->addField(
+ new CWidgetFieldIntegerBoxView($data['fields']['count'])
+ )
+ ->includeJsFile('widget.edit.js.php')
+ ->addJavaScript('widget_tophosts_form.init();')
+ ->show();
+
+function getColumnsField(CWidgetFormView $form, CWidgetFieldColumnsList $field): array {
+ $columns = new CWidgetFieldColumnsListView($field);
+
+ return $form->makeCustomField($columns, [
+ $columns->getLabel(),
+ (new CFormField($columns->getView()))->addClass(ZBX_STYLE_TABLE_FORMS_SEPARATOR)
+ ]);
+}
+
+function getColumnField(CWidgetFormView $form, CWidgetFieldSelect $field): array {
+ $column = new CWidgetFieldSelectView($field);
+
+ return $form->makeCustomField($column, [
+ $column->getLabel(),
+ (new CFormField($field->getValues() ? $column->getView() : _('Add item column')))
+ ->addClass($column->isDisabled() ? ZBX_STYLE_DISABLED : null)
+ ]);
+}
diff --git a/ui/app/views/monitoring.widget.tophosts.view.php b/ui/widgets/tophosts/views/widget.view.php
index d353b2522dc..463f3672bf5 100644
--- a/ui/app/views/monitoring.widget.tophosts.view.php
+++ b/ui/widgets/tophosts/views/widget.view.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2021 Zabbix SIA
@@ -20,10 +20,16 @@
/**
+ * Top hosts widget view.
+ *
* @var CView $this
* @var array $data
*/
+use Widgets\TopHosts\Widget;
+
+use Zabbix\Widgets\Fields\CWidgetFieldColumnsList;
+
$header = [];
foreach ($data['configuration'] as $column_config) {
@@ -108,7 +114,7 @@ foreach ($data['rows'] as $columns) {
->setValue($column['value'])
->setAttribute('fill', $column_config['base_color'] !== ''
? '#'.$column_config['base_color']
- : ZBX_WIDGET_TOP_HOSTS_DEFAULT_FILL
+ : Widget::DEFAULT_FILL
)
->setAttribute('min', $column_config['min'])
->setAttribute('max', $column_config['max']);
@@ -142,20 +148,6 @@ foreach ($data['rows'] as $columns) {
$table->addRow($row);
}
-$output = [
- 'name' => $data['name'],
- 'body' => (new CDiv($table))
- ->addClass('dashboard-widget-tophosts')
- ->toString()
-];
-
-if ($messages = get_and_clear_messages()) {
- $output['messages'] = array_column($messages, 'message');
-}
-
-if ($data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
- CProfiler::getInstance()->stop();
- $output['debug'] = CProfiler::getInstance()->make()->toString();
-}
-
-echo json_encode($output);
+(new CWidgetView($data))
+ ->addItem($table)
+ ->show();
diff --git a/ui/widgets/trigover/Widget.php b/ui/widgets/trigover/Widget.php
new file mode 100755
index 00000000000..a892ea2c087
--- /dev/null
+++ b/ui/widgets/trigover/Widget.php
@@ -0,0 +1,31 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\TrigOver;
+
+use Zabbix\Core\CWidget;
+
+class Widget extends CWidget {
+
+ public function getDefaultName(): string {
+ return _('Trigger overview');
+ }
+}
diff --git a/ui/widgets/trigover/actions/WidgetView.php b/ui/widgets/trigover/actions/WidgetView.php
new file mode 100644
index 00000000000..064615dcf90
--- /dev/null
+++ b/ui/widgets/trigover/actions/WidgetView.php
@@ -0,0 +1,78 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\TrigOver\Actions;
+
+use CControllerDashboardWidgetView,
+ CControllerResponseData;
+
+class WidgetView extends CControllerDashboardWidgetView {
+
+ protected function init(): void {
+ parent::init();
+
+ $this->addValidationRules([
+ 'initial_load' => 'in 0,1'
+ ]);
+ }
+
+ protected function doAction(): void {
+ $data = [
+ 'name' => $this->getInput('name', $this->widget->getDefaultName()),
+ 'initial_load' => (bool) $this->getInput('initial_load', 0),
+ 'style' => $this->fields_values['style'],
+ 'user' => [
+ 'debug_mode' => $this->getDebugMode()
+ ]
+ ];
+
+ $trigger_options = [
+ 'skipDependent' => ($this->fields_values['show'] == TRIGGERS_OPTION_ALL) ? null : true,
+ 'only_true' => $this->fields_values['show'] == TRIGGERS_OPTION_RECENT_PROBLEM ? true : null,
+ 'filter' => [
+ 'value' => $this->fields_values['show'] == TRIGGERS_OPTION_IN_PROBLEM ? TRIGGER_VALUE_TRUE : null
+ ]
+ ];
+
+ $problem_options = [
+ 'show_suppressed' => $this->fields_values['show_suppressed'],
+ 'show_recent' => $this->fields_values['show'] == TRIGGERS_OPTION_RECENT_PROBLEM ? true : null,
+ 'tags' => array_key_exists('tags', $this->fields_values) && $this->fields_values['tags']
+ ? $this->fields_values['tags']
+ : null,
+ 'evaltype' => array_key_exists('evaltype', $this->fields_values)
+ ? $this->fields_values['evaltype']
+ : TAG_EVAL_TYPE_AND_OR
+ ];
+
+ $host_options = [
+ 'hostids' => $this->fields_values['hostids'] ?: null
+ ];
+
+ [$data['db_hosts'], $data['db_triggers'], $data['dependencies'], $data['triggers_by_name'],
+ $data['hosts_by_name'], $data['exceeded_limit']
+ ] = getTriggersOverviewData(getSubGroups($this->fields_values['groupids']), $host_options, $trigger_options,
+ $problem_options
+ );
+
+ $this->setResponse(new CControllerResponseData($data));
+ }
+}
diff --git a/ui/js/widgets/class.widget.trigerover.js b/ui/widgets/trigover/assets/js/class.widget.js
index 3db90c588e9..3db90c588e9 100644..100755
--- a/ui/js/widgets/class.widget.trigerover.js
+++ b/ui/widgets/trigover/assets/js/class.widget.js
diff --git a/ui/widgets/trigover/includes/WidgetForm.php b/ui/widgets/trigover/includes/WidgetForm.php
new file mode 100644
index 00000000000..a8fdde27a12
--- /dev/null
+++ b/ui/widgets/trigover/includes/WidgetForm.php
@@ -0,0 +1,73 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\TrigOver\Includes;
+
+use Zabbix\Widgets\CWidgetForm;
+
+use Zabbix\Widgets\Fields\{
+ CWidgetFieldCheckBox,
+ CWidgetFieldMultiSelectGroup,
+ CWidgetFieldMultiSelectHost,
+ CWidgetFieldRadioButtonList,
+ CWidgetFieldTags
+};
+
+/**
+ * Trigger overview widget form.
+ */
+class WidgetForm extends CWidgetForm {
+
+ public function addFields(): self {
+ return $this
+ ->addField(
+ (new CWidgetFieldRadioButtonList('show', _('Show'), [
+ TRIGGERS_OPTION_RECENT_PROBLEM => _('Recent problems'),
+ TRIGGERS_OPTION_IN_PROBLEM => _('Problems'),
+ TRIGGERS_OPTION_ALL => _('Any')
+ ]))->setDefault(TRIGGERS_OPTION_RECENT_PROBLEM)
+ )
+ ->addField(
+ new CWidgetFieldMultiSelectGroup('groupids', _('Host groups'))
+ )
+ ->addField(
+ new CWidgetFieldMultiSelectHost('hostids', _('Hosts'))
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('evaltype', _('Tags'), [
+ TAG_EVAL_TYPE_AND_OR => _('And/Or'),
+ TAG_EVAL_TYPE_OR => _('Or')
+ ]))->setDefault(TAG_EVAL_TYPE_AND_OR)
+ )
+ ->addField(
+ new CWidgetFieldTags('tags')
+ )
+ ->addField(
+ new CWidgetFieldCheckBox('show_suppressed', _('Show suppressed problems'))
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('style', _('Hosts location'), [
+ STYLE_LEFT => _('Left'),
+ STYLE_TOP => _('Top')
+ ]))->setDefault(STYLE_LEFT)
+ );
+ }
+}
diff --git a/ui/widgets/trigover/manifest.json b/ui/widgets/trigover/manifest.json
new file mode 100755
index 00000000000..7579d58cb4f
--- /dev/null
+++ b/ui/widgets/trigover/manifest.json
@@ -0,0 +1,15 @@
+{
+ "manifest_version": 2.0,
+ "id": "trigover",
+ "type": "widget",
+ "name": "Trigger overview",
+ "namespace": "TrigOver",
+ "version": "1.0",
+ "author": "Zabbix SIA",
+ "widget": {
+ "js_class": "CWidgetTrigerOver"
+ },
+ "assets": {
+ "js": ["class.widget.js"]
+ }
+}
diff --git a/ui/app/partials/trigoverview.table.left.php b/ui/widgets/trigover/partials/table.left.php
index 58e34cea1bd..58e34cea1bd 100644
--- a/ui/app/partials/trigoverview.table.left.php
+++ b/ui/widgets/trigover/partials/table.left.php
diff --git a/ui/app/partials/trigoverview.table.top.php b/ui/widgets/trigover/partials/table.top.php
index 126d6b8ccb8..126d6b8ccb8 100644
--- a/ui/app/partials/trigoverview.table.top.php
+++ b/ui/widgets/trigover/partials/table.top.php
diff --git a/ui/widgets/trigover/views/widget.edit.php b/ui/widgets/trigover/views/widget.edit.php
new file mode 100755
index 00000000000..bc4354d2908
--- /dev/null
+++ b/ui/widgets/trigover/views/widget.edit.php
@@ -0,0 +1,54 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+/**
+ * Trigger overview widget form view.
+ *
+ * @var CView $this
+ * @var array $data
+ */
+
+$groupids = new CWidgetFieldMultiSelectGroupView($data['fields']['groupids'],
+ $data['captions']['ms']['groups']['groupids']
+);
+
+(new CWidgetFormView($data))
+ ->addField(
+ new CWidgetFieldRadioButtonListView($data['fields']['show'])
+ )
+ ->addField($groupids)
+ ->addField(
+ (new CWidgetFieldMultiSelectHostView($data['fields']['hostids'], $data['captions']['ms']['hosts']['hostids']))
+ ->setFilterPreselect(['id' => $groupids->getId(), 'submit_as' => 'groupid'])
+ )
+ ->addField(
+ new CWidgetFieldRadioButtonListView($data['fields']['evaltype'])
+ )
+ ->addField(
+ new CWidgetFieldTagsView($data['fields']['tags'])
+ )
+ ->addField(
+ new CWidgetFieldCheckBoxView($data['fields']['show_suppressed'])
+ )
+ ->addField(
+ new CWidgetFieldRadioButtonListView($data['fields']['style'])
+ )
+ ->show();
diff --git a/ui/widgets/trigover/views/widget.view.php b/ui/widgets/trigover/views/widget.view.php
new file mode 100644
index 00000000000..fa0322e0084
--- /dev/null
+++ b/ui/widgets/trigover/views/widget.view.php
@@ -0,0 +1,34 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+/**
+ * Trigger overview widget view.
+ *
+ * @var CView $this
+ * @var array $data
+ */
+
+(new CWidgetView($data))
+ ->addItem($data['style'] == STYLE_TOP
+ ? (new CPartial('table.top', $data))->getOutput()
+ : (new CPartial('table.left', $data))->getOutput()
+ )
+ ->show();
diff --git a/ui/widgets/url/Widget.php b/ui/widgets/url/Widget.php
new file mode 100755
index 00000000000..59d6459cd13
--- /dev/null
+++ b/ui/widgets/url/Widget.php
@@ -0,0 +1,31 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\Url;
+
+use Zabbix\Core\CWidget;
+
+class Widget extends CWidget {
+
+ public function getDefaultName(): string {
+ return _('URL');
+ }
+}
diff --git a/ui/app/controllers/CControllerWidgetUrlView.php b/ui/widgets/url/actions/WidgetView.php
index e09881d5dd1..0a3df77d9c7 100644
--- a/ui/app/controllers/CControllerWidgetUrlView.php
+++ b/ui/widgets/url/actions/WidgetView.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,31 +19,37 @@
**/
-class CControllerWidgetUrlView extends CControllerWidget {
+namespace Widgets\Url\Actions;
- public function __construct() {
- parent::__construct();
+use CControllerDashboardWidgetView,
+ CControllerResponseData,
+ CHtmlUrlValidator,
+ CMacrosResolverHelper,
+ CSettingsHelper;
- $this->setType(WIDGET_URL);
- $this->setValidationRules([
- 'name' => 'string',
- 'fields' => 'json',
+use Zabbix\Core\CWidget;
+
+class WidgetView extends CControllerDashboardWidgetView {
+
+ protected function init(): void {
+ parent::init();
+
+ $this->addValidationRules([
'dynamic_hostid' => 'db hosts.hostid'
]);
}
- protected function doAction() {
- $fields = $this->getForm()->getFieldsData();
+ protected function doAction(): void {
$error = null;
- $is_template_dashboard = ($this->getContext() === CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD);
+ $is_template_dashboard = $this->hasInput('templateid');
// Editing template dashboard?
if ($is_template_dashboard && !$this->hasInput('dynamic_hostid')) {
$error = _('No data.');
}
else {
- $is_dynamic_item = ($is_template_dashboard || $fields['dynamic'] == WIDGET_DYNAMIC_ITEM);
+ $is_dynamic_item = ($is_template_dashboard || $this->fields_values['dynamic'] == CWidget::DYNAMIC_ITEM);
$dynamic_hostid = $this->getInput('dynamic_hostid', '0');
@@ -53,22 +59,24 @@ class CControllerWidgetUrlView extends CControllerWidget {
else {
$resolved_url = CMacrosResolverHelper::resolveWidgetURL([
'config' => $is_dynamic_item ? 'widgetURL' : 'widgetURLUser',
- 'url' => $fields['url'],
+ 'url' => $this->fields_values['url'],
'hostid' => $is_dynamic_item ? $dynamic_hostid : '0'
]);
- $fields['url'] = $resolved_url ? $resolved_url : $fields['url'];
+ if ($resolved_url) {
+ $this->fields_values['url'] = $resolved_url;
+ }
}
- if (!$error && !CHtmlUrlValidator::validate($fields['url'], ['allow_user_macro' => false])) {
- $error = _s('Provided URL "%1$s" is invalid.', $fields['url']);
+ if (!$error && !CHtmlUrlValidator::validate($this->fields_values['url'], ['allow_user_macro' => false])) {
+ $error = _s('Provided URL "%1$s" is invalid.', $this->fields_values['url']);
}
}
$this->setResponse(new CControllerResponseData([
- 'name' => $this->getInput('name', $this->getDefaultName()),
+ 'name' => $this->getInput('name', $this->widget->getDefaultName()),
'url' => [
- 'url' => $fields['url'],
+ 'url' => $this->fields_values['url'],
'error' => $error
],
'user' => [
diff --git a/ui/widgets/url/assets/js/class.widget.js b/ui/widgets/url/assets/js/class.widget.js
new file mode 100644
index 00000000000..2bbc25468ed
--- /dev/null
+++ b/ui/widgets/url/assets/js/class.widget.js
@@ -0,0 +1,26 @@
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+class CWidgetUrl extends CWidget {
+
+ _hasPadding() {
+ return false;
+ }
+}
diff --git a/ui/widgets/url/includes/WidgetForm.php b/ui/widgets/url/includes/WidgetForm.php
new file mode 100644
index 00000000000..5227ba8c6af
--- /dev/null
+++ b/ui/widgets/url/includes/WidgetForm.php
@@ -0,0 +1,50 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\Url\Includes;
+
+use Zabbix\Widgets\{
+ CWidgetField,
+ CWidgetForm
+};
+
+use Zabbix\Widgets\Fields\{
+ CWidgetFieldCheckBox,
+ CWidgetFieldUrl
+};
+
+/**
+ * URL widget form.
+ */
+class WidgetForm extends CWidgetForm {
+
+ public function addFields(): self {
+ return $this
+ ->addField(
+ (new CWidgetFieldUrl('url', _('URL')))
+ ->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
+ )
+ ->addField($this->templateid === null
+ ? new CWidgetFieldCheckBox('dynamic', _('Enable host selection'))
+ : null
+ );
+ }
+}
diff --git a/ui/widgets/url/manifest.json b/ui/widgets/url/manifest.json
new file mode 100755
index 00000000000..89fae2d5c34
--- /dev/null
+++ b/ui/widgets/url/manifest.json
@@ -0,0 +1,17 @@
+{
+ "manifest_version": 2.0,
+ "id": "url",
+ "type": "widget",
+ "name": "URL",
+ "namespace": "Url",
+ "version": "1.0",
+ "author": "Zabbix SIA",
+ "widget": {
+ "js_class": "CWidgetUrl",
+ "template_support": true,
+ "refresh_rate": 0
+ },
+ "assets": {
+ "js": ["class.widget.js"]
+ }
+}
diff --git a/ui/include/classes/widgets/views/widget.favgraphs.form.view.php b/ui/widgets/url/views/widget.edit.php
index f2c89a24dae..acce744eedd 100644..100755
--- a/ui/include/classes/widgets/views/widget.favgraphs.form.view.php
+++ b/ui/widgets/url/views/widget.edit.php
@@ -20,23 +20,18 @@
/**
- * Favorite graphs widget form view.
+ * URL widget form view.
*
* @var CView $this
* @var array $data
*/
-$fields = $data['dialogue']['fields'];
-
-$form = CWidgetHelper::createForm();
-
-$form_grid = CWidgetHelper::createFormGrid($data['dialogue']['name'], $data['dialogue']['type'],
- $data['dialogue']['view_mode'], $data['known_widget_types'],
- $data['templateid'] === null ? $fields['rf_rate'] : null
-);
-
-$form->addItem($form_grid);
-
-return [
- 'form' => $form
-];
+(new CWidgetFormView($data))
+ ->addField(
+ new CWidgetFieldUrlView($data['fields']['url'])
+ )
+ ->addField(array_key_exists('dynamic', $data['fields'])
+ ? new CWidgetFieldCheckBoxView($data['fields']['dynamic'])
+ : null
+ )
+ ->show();
diff --git a/ui/app/views/monitoring.widget.url.view.php b/ui/widgets/url/views/widget.view.php
index 6543fac574c..f9ad0e05158 100644
--- a/ui/app/views/monitoring.widget.url.view.php
+++ b/ui/widgets/url/views/widget.view.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -20,7 +20,10 @@
/**
+ * URL widget form view.
+ *
* @var CView $this
+ * @var array $data
*/
if ($data['url']['error'] !== null) {
@@ -34,18 +37,6 @@ else {
}
}
-$output = [
- 'name' => $data['name'],
- 'body' => $item->toString()
-];
-
-if ($messages = get_and_clear_messages()) {
- $output['messages'] = array_column($messages, 'message');
-}
-
-if ($data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
- CProfiler::getInstance()->stop();
- $output['debug'] = CProfiler::getInstance()->make()->toString();
-}
-
-echo json_encode($output);
+(new CWidgetView($data))
+ ->addItem($item)
+ ->show();
diff --git a/ui/widgets/web/Widget.php b/ui/widgets/web/Widget.php
new file mode 100755
index 00000000000..2876651451b
--- /dev/null
+++ b/ui/widgets/web/Widget.php
@@ -0,0 +1,31 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\Web;
+
+use Zabbix\Core\CWidget;
+
+class Widget extends CWidget {
+
+ public function getDefaultName(): string {
+ return _('Web monitoring');
+ }
+}
diff --git a/ui/app/controllers/CControllerWidgetWebView.php b/ui/widgets/web/actions/WidgetView.php
index 2ba1f59accc..dc13e46a1df 100644
--- a/ui/app/controllers/CControllerWidgetWebView.php
+++ b/ui/widgets/web/actions/WidgetView.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -19,29 +19,28 @@
**/
-class CControllerWidgetWebView extends CControllerWidget {
+namespace Widgets\Web\Actions;
- public function __construct() {
- parent::__construct();
+use API,
+ CApiTagHelper,
+ CArrayHelper,
+ CControllerDashboardWidgetView,
+ CControllerResponseData,
+ CRoleHelper,
+ Manager;
- $this->setType(WIDGET_WEB);
- $this->setValidationRules([
- 'name' => 'string',
- 'fields' => 'json'
- ]);
- }
+class WidgetView extends CControllerDashboardWidgetView {
- protected function doAction() {
- $fields = $this->getForm()->getFieldsData();
+ protected function doAction(): void {
+ $filter_groupids = $this->fields_values['groupids'] ? getSubGroups($this->fields_values['groupids']) : null;
+ $filter_hostids = $this->fields_values['hostids'] ?: null;
+ $filter_maintenance = ($this->fields_values['maintenance'] == 0) ? 0 : null;
- $filter_groupids = $fields['groupids'] ? getSubGroups($fields['groupids']) : null;
- $filter_hostids = $fields['hostids'] ? $fields['hostids'] : null;
- $filter_maintenance = ($fields['maintenance'] == 0) ? 0 : null;
-
- if ($fields['exclude_groupids']) {
- $exclude_groupids = getSubGroups($fields['exclude_groupids']);
+ if ($this->fields_values['exclude_groupids']) {
+ $exclude_groupids = getSubGroups($this->fields_values['exclude_groupids']);
if ($filter_hostids === null) {
+
// Get all groups if no selected groups defined.
if ($filter_groupids === null) {
$filter_groupids = array_keys(API::HostGroup()->get([
@@ -98,11 +97,13 @@ class CControllerWidgetWebView extends CControllerWidget {
unset($group);
// Fetch links between HTTP tests and host groups.
- $where_tags = (array_key_exists('tags', $fields) && $fields['tags'])
- ? CApiTagHelper::addWhereCondition($fields['tags'], $fields['evaltype'], 'ht', 'httptest_tag', 'httptestid')
+ $where_tags = (array_key_exists('tags', $this->fields_values) && $this->fields_values['tags'])
+ ? CApiTagHelper::addWhereCondition($this->fields_values['tags'], $this->fields_values['evaltype'], 'ht',
+ 'httptest_tag', 'httptestid'
+ )
: '';
- $result = DbFetchArray(DBselect($s=
+ $result = DbFetchArray(DBselect(
'SELECT DISTINCT ht.httptestid,hg.groupid'.
' FROM httptest ht,hosts_groups hg'.
' WHERE ht.hostid=hg.hostid'.
@@ -113,7 +114,7 @@ class CControllerWidgetWebView extends CControllerWidget {
));
// Fetch HTTP test execution data.
- $httptest_data = Manager::HttpTest()->getLastData(zbx_objectValues($result, 'httptestid'));
+ $httptest_data = Manager::HttpTest()->getLastData(array_column($result, 'httptestid'));
foreach ($result as $row) {
$group = &$groups[$row['groupid']];
@@ -129,7 +130,7 @@ class CControllerWidgetWebView extends CControllerWidget {
}
$this->setResponse(new CControllerResponseData([
- 'name' => $this->getInput('name', $this->getDefaultName()),
+ 'name' => $this->getInput('name', $this->widget->getDefaultName()),
'groups' => $groups,
'user' => [
'debug_mode' => $this->getDebugMode()
diff --git a/ui/widgets/web/includes/WidgetForm.php b/ui/widgets/web/includes/WidgetForm.php
new file mode 100644
index 00000000000..66c5e4dc40b
--- /dev/null
+++ b/ui/widgets/web/includes/WidgetForm.php
@@ -0,0 +1,63 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+namespace Widgets\Web\Includes;
+
+use Zabbix\Widgets\CWidgetForm;
+
+use Zabbix\Widgets\Fields\{
+ CWidgetFieldCheckBox,
+ CWidgetFieldMultiSelectGroup,
+ CWidgetFieldMultiSelectHost,
+ CWidgetFieldRadioButtonList,
+ CWidgetFieldTags
+};
+
+/**
+ * Web monitoring widget form.
+ */
+class WidgetForm extends CWidgetForm {
+
+ public function addFields(): self {
+ return $this
+ ->addField(
+ new CWidgetFieldMultiSelectGroup('groupids', _('Host groups'))
+ )
+ ->addField(
+ new CWidgetFieldMultiSelectGroup('exclude_groupids', _('Exclude host groups'))
+ )
+ ->addField(
+ new CWidgetFieldMultiSelectHost('hostids', _('Hosts'))
+ )
+ ->addField(
+ (new CWidgetFieldRadioButtonList('evaltype', _('Tags'), [
+ TAG_EVAL_TYPE_AND_OR => _('And/Or'),
+ TAG_EVAL_TYPE_OR => _('Or')
+ ]))->setDefault(TAG_EVAL_TYPE_AND_OR)
+ )
+ ->addField(
+ new CWidgetFieldTags('tags')
+ )
+ ->addField(
+ (new CWidgetFieldCheckBox('maintenance', _('Show hosts in maintenance')))->setDefault(1)
+ );
+ }
+}
diff --git a/ui/widgets/web/manifest.json b/ui/widgets/web/manifest.json
new file mode 100755
index 00000000000..b25bf093139
--- /dev/null
+++ b/ui/widgets/web/manifest.json
@@ -0,0 +1,15 @@
+{
+ "manifest_version": 2.0,
+ "id": "web",
+ "type": "widget",
+ "name": "Web monitoring",
+ "namespace": "Web",
+ "version": "1.0",
+ "author": "Zabbix SIA",
+ "widget": {
+ "size": {
+ "width": 6,
+ "height": 3
+ }
+ }
+}
diff --git a/ui/widgets/web/views/widget.edit.php b/ui/widgets/web/views/widget.edit.php
new file mode 100755
index 00000000000..f49a111499f
--- /dev/null
+++ b/ui/widgets/web/views/widget.edit.php
@@ -0,0 +1,53 @@
+<?php declare(strict_types = 0);
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+/**
+ * Web monitoring widget form view.
+ *
+ * @var CView $this
+ * @var array $data
+ */
+
+$groupids = new CWidgetFieldMultiSelectGroupView($data['fields']['groupids'],
+ $data['captions']['ms']['groups']['groupids']
+);
+
+(new CWidgetFormView($data))
+ ->addField($groupids)
+ ->addField(
+ new CWidgetFieldMultiSelectGroupView($data['fields']['exclude_groupids'],
+ $data['captions']['ms']['groups']['exclude_groupids']
+ )
+ )
+ ->addField(
+ (new CWidgetFieldMultiSelectHostView($data['fields']['hostids'], $data['captions']['ms']['hosts']['hostids']))
+ ->setFilterPreselect(['id' => $groupids->getId(), 'submit_as' => 'groupid'])
+ )
+ ->addField(
+ new CWidgetFieldRadioButtonListView($data['fields']['evaltype'])
+ )
+ ->addField(
+ new CWidgetFieldTagsView($data['fields']['tags'])
+ )
+ ->addField(
+ new CWidgetFieldCheckBoxView($data['fields']['maintenance'])
+ )
+ ->show();
diff --git a/ui/app/views/monitoring.widget.web.view.php b/ui/widgets/web/views/widget.view.php
index dd4297af86e..d9d00083f69 100644
--- a/ui/app/views/monitoring.widget.web.view.php
+++ b/ui/widgets/web/views/widget.view.php
@@ -1,4 +1,4 @@
-<?php
+<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2022 Zabbix SIA
@@ -20,6 +20,8 @@
/**
+ * Web monitoring widget view.
+ *
* @var CView $this
* @var array $data
*/
@@ -53,24 +55,12 @@ foreach ($data['groups'] as $group) {
$table->addRow([
$group_name,
- ($group['ok'] != 0) ? (new CSpan($group['ok']))->addClass(ZBX_STYLE_GREEN) : '',
- ($group['failed'] != 0) ? (new CSpan($group['failed']))->addClass(ZBX_STYLE_RED) : '',
- ($group['unknown'] != 0) ? (new CSpan($group['unknown']))->addClass(ZBX_STYLE_GREY) : ''
+ $group['ok'] != 0 ? (new CSpan($group['ok']))->addClass(ZBX_STYLE_GREEN) : '',
+ $group['failed'] != 0 ? (new CSpan($group['failed']))->addClass(ZBX_STYLE_RED) : '',
+ $group['unknown'] != 0 ? (new CSpan($group['unknown']))->addClass(ZBX_STYLE_GREY) : ''
]);
}
-$output = [
- 'name' => $data['name'],
- 'body' => $table->toString()
-];
-
-if ($messages = get_and_clear_messages()) {
- $output['messages'] = array_column($messages, 'message');
-}
-
-if ($data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
- CProfiler::getInstance()->stop();
- $output['debug'] = CProfiler::getInstance()->make()->toString();
-}
-
-echo json_encode($output);
+(new CWidgetView($data))
+ ->addItem($table)
+ ->show();