mirror of
https://github.com/Combodo/iTop.git
synced 2026-08-21 21:58:20 +02:00
Compare commits
3 Commits
issue/9954
...
feature/91
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e7e87ff8b | ||
|
|
7e3b4af093 | ||
|
|
aff09a731f |
@@ -58,6 +58,17 @@ abstract class ApplicationPopupMenuItem
|
||||
return $this->sLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sLabel
|
||||
*
|
||||
* @api
|
||||
* @since 3.3.0
|
||||
*/
|
||||
public function SetLabel($sLabel)
|
||||
{
|
||||
$this->sLabel = $sLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the CSS classes
|
||||
*
|
||||
|
||||
@@ -95,7 +95,21 @@ interface iPopupMenuExtension
|
||||
* @todo
|
||||
*/
|
||||
public const PORTAL_MENU_ACTIONS = 10;
|
||||
|
||||
/**
|
||||
* Get the list of items to be added to the backoffice top-bar items
|
||||
* $param is null for now, in a distant future we want to give a complete context
|
||||
*/
|
||||
public const MENU_TOPBAR_ACTIONS = 11;
|
||||
/**
|
||||
* Get the list of items to be added to the actions on a given form field (i.e. the attribute of an object)
|
||||
* $param is an array: ['object' => DBObject, att_code => attribute code , mode => edit/read]
|
||||
*/
|
||||
public const MENU_OBJDETAILS_FIELD_ACTIONS = 12;
|
||||
/**
|
||||
* Get the list of items to be added to the actions in the activity panel (read-only mode)
|
||||
* $param = ['object' => DBObject, caselog_att_code => caselog attribute code or 'activity']
|
||||
*/
|
||||
public const MENU_OBJDETAILS_ACTIVITY_PANEL_ACTIONS = 13;
|
||||
/**
|
||||
* Get the list of items to be added to a menu.
|
||||
*
|
||||
|
||||
@@ -1065,6 +1065,14 @@ HTML
|
||||
}
|
||||
}
|
||||
$val['value_raw'] = ($bExcludeRawValue === false) ? $this->Get($sAttCode) : '';
|
||||
$val['actions'] = [];
|
||||
|
||||
/** @var \iPopupMenuExtension $oExtensionInstance */
|
||||
foreach (MetaModel::EnumPlugins('iPopupMenuExtension') as $oExtensionInstance) {
|
||||
foreach ($oExtensionInstance::EnumItems(iPopupMenuExtension::MENU_OBJDETAILS_FIELD_ACTIONS, ['object' => $this, 'att_code' => $sAttCode, 'mode' => $bEditMode ? 'edit' : 'read']) as $oMenuItem) {
|
||||
$val['actions'][] = $oMenuItem;
|
||||
}
|
||||
}
|
||||
|
||||
// The field is visible, add it to the current column
|
||||
$oField = FieldUIBlockFactory::MakeFromParams($val);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
@import "alert";
|
||||
@import "button";
|
||||
@import "button-separator";
|
||||
@import "button-group";
|
||||
@import "breadcrumbs";
|
||||
@import "quick-create";
|
||||
|
||||
20
css/backoffice/components/_button-separator.scss
Normal file
20
css/backoffice/components/_button-separator.scss
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2026 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
$ibo-button-separator--width: 1px !default;
|
||||
$ibo-button-separator--height: 16px !default;
|
||||
$ibo-button-separator--margin-x: 0.75rem !default;
|
||||
$ibo-button-separator--margin-y: $ibo-spacing-0 !default;
|
||||
$ibo-button-separator--border-size: 1px !default;
|
||||
$ibo-button-separator--border-color: $ibo-color-grey-500 !default;
|
||||
|
||||
.ibo-button-separator {
|
||||
display: inline-flex;
|
||||
border-right: $ibo-button-separator--border-size solid $ibo-button-separator--border-color;
|
||||
width: $ibo-button-separator--width;
|
||||
height: $ibo-button-separator--height;
|
||||
margin: $ibo-button-separator--margin-y $ibo-button-separator--margin-x;
|
||||
}
|
||||
|
||||
@@ -264,4 +264,22 @@ $ibo-field--enable-bulk--checkbox--margin-left: $ibo-spacing-300 !default;
|
||||
|
||||
.ibo-input-select--action-buttons a {
|
||||
@extend %ibo-hyperlink-inherited-colors;
|
||||
}
|
||||
}
|
||||
|
||||
.ibo-field--label {
|
||||
.ibo-field--action:not(.ibo-button-separator) {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
padding: 0;
|
||||
border-radius: $ibo-field--fullscreen-toggler--border-radius;
|
||||
font-size: $ibo-font-size-50;
|
||||
vertical-align: center;
|
||||
~ .ibo-field--action {
|
||||
margin-left: 2px;
|
||||
}
|
||||
}
|
||||
.ibo-field--action.ibo-button-separator {
|
||||
margin: 0 2px;
|
||||
vertical-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
*/
|
||||
|
||||
@import "navigation-menu";
|
||||
@import "top-bar";
|
||||
@import "content";
|
||||
@import "details";
|
||||
@import "tab-container/tab-container";
|
||||
@@ -15,4 +14,5 @@
|
||||
@import "wizard-container/wizard-container";
|
||||
@import "object/all";
|
||||
@import "activity-panel/all";
|
||||
@import "extension/all";
|
||||
@import "extension/all";
|
||||
@import "top-bar/all";
|
||||
73
css/backoffice/layout/activity-panel/_activity-action.scss
Normal file
73
css/backoffice/layout/activity-panel/_activity-action.scss
Normal file
@@ -0,0 +1,73 @@
|
||||
$ibo-activity-panel--activity-actions--right: 12px !default;
|
||||
$ibo-activity-panel--activity-actions--top: 76px + $ibo-activity-panel--activity-actions--right +36px + 8px !default;
|
||||
$ibo-activity-panel--activity-action--diameter: 36px !default;
|
||||
$ibo-activity-panel--activity-action--background-color: $ibo-color-primary-600 !default;
|
||||
$ibo-activity-panel--activity-action--background-color--on-hover: $ibo-color-primary-500 !default;
|
||||
$ibo-activity-panel--activity-action--background-color--is-active: $ibo-color-primary-700 !default;
|
||||
$ibo-activity-panel--activity-action--color: $ibo-color-white-100 !default;
|
||||
$ibo-activity-panel--activity-action--border-radius: $ibo-border-radius-full !default;
|
||||
$ibo-activity-panel--activity-action--box-shadow: $ibo-elevation-100 !default;
|
||||
$ibo-activity-panel--activity-action--hover--box-shadow: $ibo-elevation-200 !default;
|
||||
|
||||
$ibo-activity-panel--activity-action--icon--height: 100% !default;
|
||||
$ibo-activity-panel--activity-action--icon--width: $ibo-activity-panel--activity-action--icon--height !default;
|
||||
$ibo-activity-panel--activity-action--icon--font-size: $ibo-font-size-200 !default;
|
||||
$ibo-activity-panel--activity-action--icon--line-height: 33px !default;
|
||||
$ibo-activity-panel--activity-action-separator--width: 24px !default;
|
||||
$ibo-activity-panel--activity-action-separator--height: 1px !default;
|
||||
$ibo-activity-panel--activity-action-separator--background-color: $ibo-color-grey-500 !default;
|
||||
|
||||
|
||||
.ibo-activity-panel--activity-actions {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
right: $ibo-activity-panel--activity-actions--right;
|
||||
top: $ibo-activity-panel--activity-actions--top;
|
||||
&.ibo-is-hidden{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.ibo-activity-panel--activity-action {
|
||||
@extend %ibo-baseline-centered-content;
|
||||
|
||||
width: $ibo-activity-panel--activity-action--diameter;
|
||||
height: $ibo-activity-panel--activity-action--diameter;
|
||||
|
||||
background-color: $ibo-activity-panel--activity-action--background-color;
|
||||
color: $ibo-activity-panel--activity-action--color;
|
||||
|
||||
border-radius: $ibo-activity-panel--activity-action--border-radius;
|
||||
box-shadow: $ibo-activity-panel--activity-action--box-shadow;
|
||||
|
||||
> i{
|
||||
text-align: center;
|
||||
height: $ibo-activity-panel--activity-action--icon--height;
|
||||
width: $ibo-activity-panel--activity-action--icon--width;
|
||||
font-size: $ibo-activity-panel--activity-action--icon--font-size;
|
||||
line-height: $ibo-activity-panel--activity-action--icon--line-height;
|
||||
}
|
||||
&:hover {
|
||||
color: $ibo-activity-panel--activity-action--color;
|
||||
background-color: $ibo-activity-panel--activity-action--background-color--on-hover;
|
||||
box-shadow: $ibo-activity-panel--activity-action--hover--box-shadow;
|
||||
}
|
||||
&:active {
|
||||
color: $ibo-activity-panel--activity-action--color;
|
||||
background-color: $ibo-activity-panel--activity-action--background-color--is-active;
|
||||
}
|
||||
&.ibo-is-hidden{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.ibo-activity-panel--activity-action-separator {
|
||||
display: block;
|
||||
width: $ibo-activity-panel--activity-action-separator--width;
|
||||
height: $ibo-activity-panel--activity-action-separator--height;
|
||||
margin: auto;
|
||||
background-color: $ibo-activity-panel--activity-action-separator--background-color;
|
||||
}
|
||||
@@ -10,3 +10,4 @@
|
||||
@import "transition-entry";
|
||||
@import "edits-entry";
|
||||
@import "notification-entry";
|
||||
@import "activity-action";
|
||||
|
||||
@@ -59,4 +59,8 @@ $ibo-caselog-entry-form--lock-message--margin-left: 1rem !default;
|
||||
}
|
||||
.ibo-caselog-entry-form--action-buttons--main-actions > .ibo-popover-menu {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.ibo-caselog-entry-form--action-buttons--extra-actions .ibo-button-separator{
|
||||
vertical-align: center ;
|
||||
}
|
||||
2
css/backoffice/layout/top-bar/_all.scss
Normal file
2
css/backoffice/layout/top-bar/_all.scss
Normal file
@@ -0,0 +1,2 @@
|
||||
@import "top-bar";
|
||||
@import "top-bar-action";
|
||||
36
css/backoffice/layout/top-bar/_top-bar-action.scss
Normal file
36
css/backoffice/layout/top-bar/_top-bar-action.scss
Normal file
@@ -0,0 +1,36 @@
|
||||
$ibo-top-bar-quick-action--head--background-color: $ibo-color-white-100 !default;
|
||||
|
||||
$ibo-top-bar-quick-action--icon-padding-x: $ibo-spacing-500 !default;
|
||||
$ibo-top-bar-quick-action--icon-padding-y: $ibo-spacing-0 !default;
|
||||
$ibo-top-bar-quick-action--icon--color: $ibo-color-primary-600 !default;
|
||||
$ibo-top-bar-quick-action--icon--color--on-hover: $ibo-color-primary-700 !default;
|
||||
$ibo-top-bar-quick-action--icon--color--on-active: $ibo-color-primary-800 !default;
|
||||
|
||||
.ibo-top-bar-quick-action{
|
||||
position: relative;
|
||||
@extend %ibo-full-height-content;
|
||||
}
|
||||
.ibo-top-bar-quick-action--head{
|
||||
@extend %ibo-full-height-content;
|
||||
height: 100%;
|
||||
background-color: $ibo-top-bar-quick-action--head--background-color;
|
||||
}
|
||||
.ibo-top-bar-quick-action--icon{
|
||||
color: $ibo-top-bar-quick-action--icon--color;
|
||||
align-self: center;
|
||||
padding: $ibo-top-bar-quick-action--icon-padding-y $ibo-top-bar-quick-action--icon-padding-x;
|
||||
@extend %ibo-font-ral-nor-400;
|
||||
|
||||
&:hover{
|
||||
color: $ibo-top-bar-quick-action--icon--color--on-hover;
|
||||
}
|
||||
&:active{
|
||||
color: $ibo-top-bar-quick-action--icon--color--on-active;
|
||||
}
|
||||
}
|
||||
|
||||
.ibo-top-bar-quick-action-separator {
|
||||
width: 2px;
|
||||
background-color: $ibo-color-grey-300;
|
||||
margin: 0 8px;
|
||||
}
|
||||
@@ -71,6 +71,8 @@ $(function()
|
||||
authors_count: '[data-role="ibo-activity-panel--tab-toolbar-info-authors-count"]',
|
||||
messages_count: '[data-role="ibo-activity-panel--tab-toolbar-info-messages-count"]',
|
||||
compose_button: '[data-role="ibo-activity-panel--add-caselog-entry-button"]',
|
||||
activity_actions: '[data-role="ibo-activity-panel--activity-actions"]',
|
||||
activity_action: '[data-role="ibo-activity-panel--activity-action"]',
|
||||
compose_menu: '#ibo-activity-panel--compose-menu',
|
||||
compose_menu_item: '#ibo-activity-panel--compose-menu [data-role="ibo-popover-menu--item"]',
|
||||
caselog_entry_form: '[data-role="ibo-caselog-entry-form"]',
|
||||
@@ -194,6 +196,11 @@ $(function()
|
||||
this.element.find(this.js_selectors.compose_button).on('click', function (oEvent) {
|
||||
me._onComposeButtonClick(oEvent);
|
||||
});
|
||||
|
||||
this.element.find('[data-role="ibo-activity-panel--activity-action"]').on('click', function (oEvent) {
|
||||
me._onActivityActionClick(oEvent, $(this));
|
||||
});
|
||||
|
||||
// - Click on the compose menu items
|
||||
this.element.find(this.js_selectors.compose_menu_item).on('click', function (oEvent) {
|
||||
me._onComposeMenuItemClick(oEvent, $(this));
|
||||
@@ -375,6 +382,25 @@ $(function()
|
||||
|
||||
// Else, the compose menu will open automatically
|
||||
},
|
||||
|
||||
_onActivityActionClick: function (oEvent, oActionElem) {
|
||||
oEvent.preventDefault();
|
||||
const oActiveTabData = this._GetActiveTabData();
|
||||
const oActionElement = $(oEvent.target).closest(this.js_selectors.activity_action);
|
||||
const oActionElementMenu = $('#'+oActionElement.attr('id')+'-menu');
|
||||
const oTabCode = oActiveTabData.type === 'caselog' ? oActiveTabData.att_code : oActiveTabData.type;
|
||||
const oActionElementMenuItem = oActionElementMenu.find('[data-caselog-attribute-code="'+oTabCode+'"]');
|
||||
|
||||
// If the current tab has a corresponding menu item, click on it to trigger it directly
|
||||
if (oActionElementMenuItem.length > 0) {
|
||||
// Note: Stop propagation to avoid the menu to be opened automatically by the popover handler
|
||||
oEvent.stopImmediatePropagation();
|
||||
// TODO: Need fix for URL items as synthetic clicks doesn't open URLs
|
||||
oActionElementMenuItem.click();
|
||||
}
|
||||
// Else let the popover menu open automatically, the user will have to choose a case log
|
||||
},
|
||||
|
||||
/**
|
||||
* @param oEvent {Object}
|
||||
* @param oItemElem {Object} jQuery object representing the clicked item
|
||||
@@ -784,6 +810,7 @@ $(function()
|
||||
_ShowCaseLogsEntryForms: function () {
|
||||
this.element.find(this.js_selectors.caselog_entry_form).trigger('show_form.caselog_entry_form.itop');
|
||||
this.element.find(this.js_selectors.compose_button).addClass(this.css_classes.is_hidden);
|
||||
this.element.find(this.js_selectors.activity_actions).addClass(this.css_classes.is_hidden);
|
||||
},
|
||||
/**
|
||||
* Hide all case logs entry forms.
|
||||
@@ -795,6 +822,7 @@ $(function()
|
||||
_HideCaseLogsEntryForms: function () {
|
||||
this.element.find(this.js_selectors.caselog_entry_form).trigger('hide_form.caselog_entry_form.itop');
|
||||
this.element.find(this.js_selectors.compose_button).removeClass(this.css_classes.is_hidden);
|
||||
this.element.find(this.js_selectors.activity_actions).removeClass(this.css_classes.is_hidden);
|
||||
},
|
||||
/**
|
||||
* Empty all case logs entry forms
|
||||
|
||||
@@ -157,6 +157,9 @@ return array(
|
||||
'Combodo\\iTop\\Application\\TwigBase\\UI\\UIBlockNode' => $baseDir . '/sources/Application/TwigBase/UI/UIBlockNode.php',
|
||||
'Combodo\\iTop\\Application\\TwigBase\\UI\\UIBlockParser' => $baseDir . '/sources/Application/TwigBase/UI/UIBlockParser.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\AbstractUIBlockFactory' => $baseDir . '/sources/Application/UI/Base/AbstractUIBlockFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Common\\Action\\tActionCommon' => $baseDir . '/sources/Application/UI/Base/Common/Action/tActionCommon.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Common\\Action\\tActionJs' => $baseDir . '/sources/Application/UI/Base/Common/Action/tActionJs.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Common\\Action\\tActionURL' => $baseDir . '/sources/Application/UI/Base/Common/Action/tActionURL.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Alert\\Alert' => $baseDir . '/sources/Application/UI/Base/Component/Alert/Alert.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Alert\\AlertUIBlockFactory' => $baseDir . '/sources/Application/UI/Base/Component/Alert/AlertUIBlockFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Badge\\Badge' => $baseDir . '/sources/Application/UI/Base/Component/Badge/Badge.php',
|
||||
@@ -166,6 +169,7 @@ return array(
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\ButtonGroup\\ButtonGroupUIBlockFactory' => $baseDir . '/sources/Application/UI/Base/Component/ButtonGroup/ButtonGroupUIBlockFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Button\\Button' => $baseDir . '/sources/Application/UI/Base/Component/Button/Button.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Button\\ButtonJS' => $baseDir . '/sources/Application/UI/Base/Component/Button/ButtonJS.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Button\\ButtonSeparator' => $baseDir . '/sources/Application/UI/Base/Component/Button/ButtonSeparator.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Button\\ButtonUIBlockFactory' => $baseDir . '/sources/Application/UI/Base/Component/Button/ButtonUIBlockFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Button\\ButtonURL' => $baseDir . '/sources/Application/UI/Base/Component/Button/ButtonURL.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\CollapsibleSection\\CollapsibleSection' => $baseDir . '/sources/Application/UI/Base/Component/CollapsibleSection/CollapsibleSection.php',
|
||||
@@ -269,6 +273,11 @@ return array(
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\ActivityEntry\\NotificationEntry' => $baseDir . '/sources/Application/UI/Base/Layout/ActivityPanel/ActivityEntry/NotificationEntry.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\ActivityEntry\\TransitionEntry' => $baseDir . '/sources/Application/UI/Base/Layout/ActivityPanel/ActivityEntry/TransitionEntry.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\ActivityPanel' => $baseDir . '/sources/Application/UI/Base/Layout/ActivityPanel/ActivityPanel.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\ActivityPanelAction\\ActivityPanelAction' => $baseDir . '/sources/Application/UI/Base/Layout/ActivityPanel/ActivityPanelAction/ActivityPanelAction.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\ActivityPanelAction\\ActivityPanelActionFactory' => $baseDir . '/sources/Application/UI/Base/Layout/ActivityPanel/ActivityPanelAction/ActivityPanelActionFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\ActivityPanelAction\\ActivityPanelActionJS' => $baseDir . '/sources/Application/UI/Base/Layout/ActivityPanel/ActivityPanelAction/ActivityPanelActionJS.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\ActivityPanelAction\\ActivityPanelActionSeparator' => $baseDir . '/sources/Application/UI/Base/Layout/ActivityPanel/ActivityPanelAction/ActivityPanelActionSeparator.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\ActivityPanelAction\\ActivityPanelActionURL' => $baseDir . '/sources/Application/UI/Base/Layout/ActivityPanel/ActivityPanelAction/ActivityPanelActionURL.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\ActivityPanelFactory' => $baseDir . '/sources/Application/UI/Base/Layout/ActivityPanel/ActivityPanelFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\ActivityPanelHelper' => $baseDir . '/sources/Application/UI/Base/Layout/ActivityPanel/ActivityPanelHelper.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\ActivityPanelPrint' => $baseDir . '/sources/Application/UI/Base/Layout/ActivityPanel/ActivityPanelPrint.php',
|
||||
@@ -295,6 +304,11 @@ return array(
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\TabContainer\\Tab\\AjaxTab' => $baseDir . '/sources/Application/UI/Base/Layout/TabContainer/Tab/AjaxTab.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\TabContainer\\Tab\\Tab' => $baseDir . '/sources/Application/UI/Base/Layout/TabContainer/Tab/Tab.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\TopBar\\TopBar' => $baseDir . '/sources/Application/UI/Base/Layout/TopBar/TopBar.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\TopBar\\TopBarAction\\TopBarQuickAction' => $baseDir . '/sources/Application/UI/Base/Layout/TopBar/TopBarQuickAction/TopBarQuickAction.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\TopBar\\TopBarAction\\TopBarQuickActionFactory' => $baseDir . '/sources/Application/UI/Base/Layout/TopBar/TopBarQuickAction/TopBarQuickActionFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\TopBar\\TopBarAction\\TopBarQuickActionJS' => $baseDir . '/sources/Application/UI/Base/Layout/TopBar/TopBarQuickAction/TopBarQuickActionJS.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\TopBar\\TopBarAction\\TopBarQuickActionSeparator' => $baseDir . '/sources/Application/UI/Base/Layout/TopBar/TopBarQuickAction/TopBarQuickActionSeparator.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\TopBar\\TopBarAction\\TopBarQuickActionURL' => $baseDir . '/sources/Application/UI/Base/Layout/TopBar/TopBarQuickAction/TopBarQuickActionURL.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\TopBar\\TopBarFactory' => $baseDir . '/sources/Application/UI/Base/Layout/TopBar/TopBarFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\UIContentBlock' => $baseDir . '/sources/Application/UI/Base/Layout/UIContentBlock.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\UIContentBlockUIBlockFactory' => $baseDir . '/sources/Application/UI/Base/Layout/UIContentBlockUIBlockFactory.php',
|
||||
|
||||
@@ -558,6 +558,9 @@ class ComposerStaticInitfc0e9e9dea11dcbb6272414776c30685
|
||||
'Combodo\\iTop\\Application\\TwigBase\\UI\\UIBlockNode' => __DIR__ . '/../..' . '/sources/Application/TwigBase/UI/UIBlockNode.php',
|
||||
'Combodo\\iTop\\Application\\TwigBase\\UI\\UIBlockParser' => __DIR__ . '/../..' . '/sources/Application/TwigBase/UI/UIBlockParser.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\AbstractUIBlockFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/AbstractUIBlockFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Common\\Action\\tActionCommon' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Common/Action/tActionCommon.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Common\\Action\\tActionJs' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Common/Action/tActionJs.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Common\\Action\\tActionURL' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Common/Action/tActionURL.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Alert\\Alert' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Alert/Alert.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Alert\\AlertUIBlockFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Alert/AlertUIBlockFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Badge\\Badge' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Badge/Badge.php',
|
||||
@@ -567,6 +570,7 @@ class ComposerStaticInitfc0e9e9dea11dcbb6272414776c30685
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\ButtonGroup\\ButtonGroupUIBlockFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/ButtonGroup/ButtonGroupUIBlockFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Button\\Button' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Button/Button.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Button\\ButtonJS' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Button/ButtonJS.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Button\\ButtonSeparator' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Button/ButtonSeparator.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Button\\ButtonUIBlockFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Button/ButtonUIBlockFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Button\\ButtonURL' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Button/ButtonURL.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\CollapsibleSection\\CollapsibleSection' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/CollapsibleSection/CollapsibleSection.php',
|
||||
@@ -670,6 +674,11 @@ class ComposerStaticInitfc0e9e9dea11dcbb6272414776c30685
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\ActivityEntry\\NotificationEntry' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/ActivityPanel/ActivityEntry/NotificationEntry.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\ActivityEntry\\TransitionEntry' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/ActivityPanel/ActivityEntry/TransitionEntry.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\ActivityPanel' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/ActivityPanel/ActivityPanel.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\ActivityPanelAction\\ActivityPanelAction' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/ActivityPanel/ActivityPanelAction/ActivityPanelAction.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\ActivityPanelAction\\ActivityPanelActionFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/ActivityPanel/ActivityPanelAction/ActivityPanelActionFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\ActivityPanelAction\\ActivityPanelActionJS' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/ActivityPanel/ActivityPanelAction/ActivityPanelActionJS.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\ActivityPanelAction\\ActivityPanelActionSeparator' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/ActivityPanel/ActivityPanelAction/ActivityPanelActionSeparator.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\ActivityPanelAction\\ActivityPanelActionURL' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/ActivityPanel/ActivityPanelAction/ActivityPanelActionURL.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\ActivityPanelFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/ActivityPanel/ActivityPanelFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\ActivityPanelHelper' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/ActivityPanel/ActivityPanelHelper.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\ActivityPanelPrint' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/ActivityPanel/ActivityPanelPrint.php',
|
||||
@@ -696,6 +705,11 @@ class ComposerStaticInitfc0e9e9dea11dcbb6272414776c30685
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\TabContainer\\Tab\\AjaxTab' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/TabContainer/Tab/AjaxTab.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\TabContainer\\Tab\\Tab' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/TabContainer/Tab/Tab.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\TopBar\\TopBar' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/TopBar/TopBar.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\TopBar\\TopBarAction\\TopBarQuickAction' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/TopBar/TopBarQuickAction/TopBarQuickAction.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\TopBar\\TopBarAction\\TopBarQuickActionFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/TopBar/TopBarQuickAction/TopBarQuickActionFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\TopBar\\TopBarAction\\TopBarQuickActionJS' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/TopBar/TopBarQuickAction/TopBarQuickActionJS.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\TopBar\\TopBarAction\\TopBarQuickActionSeparator' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/TopBar/TopBarQuickAction/TopBarQuickActionSeparator.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\TopBar\\TopBarAction\\TopBarQuickActionURL' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/TopBar/TopBarQuickAction/TopBarQuickActionURL.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\TopBar\\TopBarFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/TopBar/TopBarFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\UIContentBlock' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/UIContentBlock.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\UIContentBlockUIBlockFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/UIContentBlockUIBlockFactory.php',
|
||||
|
||||
100
sources/Application/UI/Base/Common/Action/tActionCommon.php
Normal file
100
sources/Application/UI/Base/Common/Action/tActionCommon.php
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2026 Combodo SAS
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Base\Common\Action;
|
||||
|
||||
/**
|
||||
* Trait tActionCommon
|
||||
*
|
||||
* Shared properties and accessors for UI actions.
|
||||
*
|
||||
* @package Combodo\iTop\Application\UI\Base\Common\Action
|
||||
* @internal
|
||||
* @since 3.3.0
|
||||
*/
|
||||
trait tActionCommon
|
||||
{
|
||||
protected string $sUid;
|
||||
protected string $sLabel;
|
||||
protected string $sIconClass = '';
|
||||
protected ?string $sTooltip = null;
|
||||
protected array $aCssClasses = [];
|
||||
|
||||
public function GetUID(): string
|
||||
{
|
||||
return $this->sUid;
|
||||
}
|
||||
|
||||
public function SetUID(string $sUid)
|
||||
{
|
||||
$this->sUid = $sUid;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function GetLabel(): string
|
||||
{
|
||||
return $this->sLabel;
|
||||
}
|
||||
|
||||
public function SetLabel(string $sLabel)
|
||||
{
|
||||
$this->sLabel = $sLabel;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function GetIconClass(): string
|
||||
{
|
||||
return $this->sIconClass;
|
||||
}
|
||||
|
||||
public function SetIconClass(string $sIconClass)
|
||||
{
|
||||
$this->sIconClass = $sIconClass;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function GetTooltip(): ?string
|
||||
{
|
||||
return $this->sTooltip;
|
||||
}
|
||||
|
||||
public function SetTooltip(?string $sTooltip)
|
||||
{
|
||||
$this->sTooltip = $sTooltip;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function GetCssClasses(): array
|
||||
{
|
||||
return $this->aCssClasses;
|
||||
}
|
||||
|
||||
public function SetCssClasses(array $aCssClasses)
|
||||
{
|
||||
$this->aCssClasses = $aCssClasses;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function AddCssClass(string $sCssClass)
|
||||
{
|
||||
$this->aCssClasses[] = $sCssClass;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
70
sources/Application/UI/Base/Common/Action/tActionJs.php
Normal file
70
sources/Application/UI/Base/Common/Action/tActionJs.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2026 Combodo SAS
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Base\Common\Action;
|
||||
|
||||
/**
|
||||
* Trait tActionJs
|
||||
*
|
||||
* Shared properties and accessors for JS-based actions.
|
||||
*
|
||||
* @package Combodo\iTop\Application\UI\Base\Common\Action
|
||||
* @internal
|
||||
* @since 3.3.0
|
||||
*/
|
||||
trait tActionJs
|
||||
{
|
||||
protected string $sJsCode;
|
||||
protected string $sUrl = '#';
|
||||
protected array $aIncludeJSFiles = [];
|
||||
|
||||
public function GetJsCode(): string
|
||||
{
|
||||
return $this->sJsCode;
|
||||
}
|
||||
|
||||
public function SetJsCode(string $sJsCode)
|
||||
{
|
||||
$this->sJsCode = $sJsCode;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function GetUrl(): string
|
||||
{
|
||||
return $this->sUrl;
|
||||
}
|
||||
|
||||
public function SetUrl(string $sUrl)
|
||||
{
|
||||
$this->sUrl = $sUrl;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function GetIncludeJSFiles(): array
|
||||
{
|
||||
return $this->aIncludeJSFiles;
|
||||
}
|
||||
|
||||
public function SetIncludeJSFiles(array $aIncludeJSFiles)
|
||||
{
|
||||
$this->aIncludeJSFiles = $aIncludeJSFiles;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
58
sources/Application/UI/Base/Common/Action/tActionURL.php
Normal file
58
sources/Application/UI/Base/Common/Action/tActionURL.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2026 Combodo SAS
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Base\Common\Action;
|
||||
|
||||
/**
|
||||
* Trait tActionURL
|
||||
*
|
||||
* Shared properties and accessors for URL-based actions.
|
||||
*
|
||||
* @package Combodo\iTop\Application\UI\Base\Common\Action
|
||||
* @internal
|
||||
* @since 3.3.0
|
||||
*/
|
||||
trait tActionURL
|
||||
{
|
||||
protected string $sUrl;
|
||||
protected ?string $sTarget = null;
|
||||
|
||||
public function GetUrl(): string
|
||||
{
|
||||
return $this->sUrl;
|
||||
}
|
||||
|
||||
public function SetUrl(string $sUrl)
|
||||
{
|
||||
$this->sUrl = $sUrl;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function GetTarget(): ?string
|
||||
{
|
||||
return $this->sTarget;
|
||||
}
|
||||
|
||||
public function SetTarget(?string $sTarget)
|
||||
{
|
||||
$this->sTarget = $sTarget;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2026 Combodo SAS
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Base\Component\Button;
|
||||
|
||||
use Combodo\iTop\Application\UI\Base\UIBlock;
|
||||
|
||||
/**
|
||||
* Class ButtonSeparator
|
||||
*
|
||||
* @internal
|
||||
* @since 3.3.0
|
||||
*/
|
||||
class ButtonSeparator extends UIBlock
|
||||
{
|
||||
public const BLOCK_CODE = 'ibo-button-separator';
|
||||
public const DEFAULT_HTML_TEMPLATE_REL_PATH = 'base/components/button/separator/layout';
|
||||
public const DEFAULT_JS_TEMPLATE_REL_PATH = null;
|
||||
}
|
||||
|
||||
@@ -20,8 +20,12 @@
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Base\Component\Button;
|
||||
|
||||
use ApplicationPopupMenuItem;
|
||||
use Combodo\iTop\Application\UI\Base\AbstractUIBlockFactory;
|
||||
use Dict;
|
||||
use JSPopupMenuItem;
|
||||
use SeparatorPopupMenuItem;
|
||||
use URLPopupMenuItem;
|
||||
use utils;
|
||||
|
||||
/**
|
||||
@@ -376,6 +380,122 @@ class ButtonUIBlockFactory extends AbstractUIBlockFactory
|
||||
return $oButton;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ApplicationPopupMenuItem $oPopupItem
|
||||
* @param string $sColor
|
||||
* @param string $sActionType
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\Base\Component\Button\Button|\Combodo\iTop\Application\UI\Base\Component\Button\ButtonSeparator|null
|
||||
*/
|
||||
public static function MakeIconButtonFromApplicationPopupMenuItem(ApplicationPopupMenuItem $oPopupItem, $sColor = Button::ENUM_COLOR_SCHEME_NEUTRAL, $sActionType = Button::ENUM_ACTION_TYPE_ALTERNATIVE): Button|ButtonSeparator|null
|
||||
{
|
||||
if ($oPopupItem instanceof JSPopupMenuItem) {
|
||||
$sTooltip = $oPopupItem->GetTooltip();
|
||||
if (!utils::IsNotNullOrEmptyString($sTooltip)) {
|
||||
$sTooltip = $oPopupItem->GetLabel();
|
||||
}
|
||||
|
||||
$oButton = self::MakeIconAction(
|
||||
$oPopupItem->GetIconClass(),
|
||||
$sTooltip
|
||||
);
|
||||
|
||||
$oButton->SetOnClickJsCode($oPopupItem->GetJsCode());
|
||||
foreach ($oPopupItem->GetLinkedScripts() as $sLinkedScript) {
|
||||
$oButton->AddJsFileRelPath($sLinkedScript);
|
||||
}
|
||||
$oButton->SetActionType($sActionType);
|
||||
$oButton->SetColor($sColor);
|
||||
|
||||
return $oButton;
|
||||
} elseif ($oPopupItem instanceof URLPopupMenuItem) {
|
||||
$sTooltip = $oPopupItem->GetTooltip();
|
||||
if (!utils::IsNotNullOrEmptyString($sTooltip)) {
|
||||
$sTooltip = $oPopupItem->GetLabel();
|
||||
}
|
||||
|
||||
$oButton = self::MakeIconLink(
|
||||
$oPopupItem->GetIconClass(),
|
||||
$sTooltip,
|
||||
$oPopupItem->GetURL(),
|
||||
$oPopupItem->GetTarget(),
|
||||
);
|
||||
|
||||
$oButton->SetActionType($sActionType);
|
||||
$oButton->SetColor($sColor);
|
||||
|
||||
return $oButton;
|
||||
} elseif ($oPopupItem instanceof SeparatorPopupMenuItem) {
|
||||
$oSeparator = new ButtonSeparator($oPopupItem->GetUID());
|
||||
$oSeparator->SetCSSClasses($oPopupItem->GetCssClasses());
|
||||
return $oSeparator;
|
||||
}
|
||||
|
||||
// Should never happen, but just in case a new type is added, return null
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ApplicationPopupMenuItem $oPopupItem
|
||||
* @param string $sColor
|
||||
* @param string $sActionType
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\Base\Component\Button\Button|\Combodo\iTop\Application\UI\Base\Component\Button\ButtonSeparator|null
|
||||
*/
|
||||
public static function MakeButtonFromApplicationPopupMenuItem(ApplicationPopupMenuItem $oPopupItem, $sColor = Button::ENUM_COLOR_SCHEME_NEUTRAL, $sActionType = Button::ENUM_ACTION_TYPE_ALTERNATIVE): Button|ButtonSeparator|null
|
||||
{
|
||||
if ($oPopupItem instanceof JSPopupMenuItem) {
|
||||
$oButton = self::MakeForAction(
|
||||
$oPopupItem->GetLabel(),
|
||||
$sColor,
|
||||
$sActionType,
|
||||
);
|
||||
|
||||
if (utils::IsNotNullOrEmptyString($oPopupItem->GetIconClass())) {
|
||||
$oButton->SetIconClass($oPopupItem->GetIconClass());
|
||||
}
|
||||
if (utils::IsNotNullOrEmptyString($oPopupItem->GetTooltip())) {
|
||||
$oButton->SetTooltip($oPopupItem->GetTooltip());
|
||||
}
|
||||
|
||||
$oButton->SetOnClickJsCode($oPopupItem->GetJsCode());
|
||||
|
||||
foreach ($oPopupItem->GetLinkedScripts() as $sLinkedScript) {
|
||||
$oButton->AddJsFileRelPath($sLinkedScript);
|
||||
}
|
||||
|
||||
return $oButton;
|
||||
} elseif ($oPopupItem instanceof URLPopupMenuItem) {
|
||||
$oButton = self::MakeForLink(
|
||||
$oPopupItem->GetLabel(),
|
||||
$oPopupItem->GetURL(),
|
||||
$sColor,
|
||||
$sActionType,
|
||||
$oPopupItem->GetTarget()
|
||||
);
|
||||
|
||||
if (utils::IsNotNullOrEmptyString($oPopupItem->GetIconClass())) {
|
||||
$oButton->SetIconClass($oPopupItem->GetIconClass());
|
||||
}
|
||||
if (utils::IsNotNullOrEmptyString($oPopupItem->GetTooltip())) {
|
||||
$oButton->SetTooltip($oPopupItem->GetTooltip());
|
||||
}
|
||||
if (utils::IsNotNullOrEmptyString($oPopupItem->GetTarget())) {
|
||||
$oButton->SetTarget($oPopupItem->GetTarget());
|
||||
}
|
||||
|
||||
return $oButton;
|
||||
} elseif ($oPopupItem instanceof SeparatorPopupMenuItem) {
|
||||
$oSeparator = new ButtonSeparator($oPopupItem->GetUID());
|
||||
$oSeparator->SetCSSClasses($oPopupItem->GetCssClasses());
|
||||
return $oSeparator;
|
||||
}
|
||||
|
||||
// Should never happen, but just in case a new type is added, return null
|
||||
|
||||
return null;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------
|
||||
// Link buttons, mostly used outside forms, to redirect somewhere whilst keeping a button aspect
|
||||
//----------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -57,14 +57,16 @@ class Field extends UIContentBlock
|
||||
/** @var string */
|
||||
protected $sComments;
|
||||
|
||||
protected $oValue;
|
||||
|
||||
protected $aActions = [];
|
||||
|
||||
public function __construct(string $sLabel, ?UIBlock $oValue = null, ?string $sId = null)
|
||||
{
|
||||
parent::__construct($sId);
|
||||
$this->sLabel = $sLabel;
|
||||
$this->sValueId = null;
|
||||
if (!is_null($oValue)) {
|
||||
$this->AddSubBlock($oValue);
|
||||
}
|
||||
$this->oValue = $oValue;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -287,6 +289,10 @@ class Field extends UIContentBlock
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function HasValue(): bool
|
||||
{
|
||||
return !is_null($this->oValue);
|
||||
}
|
||||
/**
|
||||
* @return \Combodo\iTop\Application\UI\Base\UIBlock
|
||||
*/
|
||||
@@ -390,4 +396,36 @@ class Field extends UIContentBlock
|
||||
{
|
||||
return utils::IsNotNullOrEmptyString($this->GetDescription());
|
||||
}
|
||||
|
||||
public function GetActions(): array
|
||||
{
|
||||
return $this->aActions;
|
||||
}
|
||||
public function AddAction(UIBlock $oAction)
|
||||
{
|
||||
$this->aActions[] = $oAction;
|
||||
return $this;
|
||||
}
|
||||
public function HasActions(): bool
|
||||
{
|
||||
return !empty($this->aActions);
|
||||
}
|
||||
|
||||
public function SetActions(array $aActions)
|
||||
{
|
||||
$this->aActions = $aActions;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function GetSubBlocks(): array
|
||||
{
|
||||
$aSubBlocks = [];
|
||||
if (!is_null($this->oValue)) {
|
||||
$aSubBlocks[$this->oValue->GetId()] = $this->oValue;
|
||||
}
|
||||
foreach ($this->aActions as $oAction) {
|
||||
$aSubBlocks[$oAction->GetId()] = $oAction;
|
||||
}
|
||||
return $aSubBlocks;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,10 @@
|
||||
namespace Combodo\iTop\Application\UI\Base\Component\Field;
|
||||
|
||||
use Combodo\iTop\Application\UI\Base\AbstractUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Button\ButtonUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Html\Html;
|
||||
use Combodo\iTop\Application\UI\Base\Component\PopoverMenu\PopoverMenu;
|
||||
use Combodo\iTop\Application\UI\Base\Component\PopoverMenu\PopoverMenuFactory;
|
||||
use Combodo\iTop\Application\UI\Base\UIBlock;
|
||||
|
||||
/**
|
||||
@@ -67,6 +70,36 @@ class FieldUIBlockFactory extends AbstractUIBlockFactory
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($aParams['actions'])) {
|
||||
//TODO make this a configuration parameter
|
||||
$iMaxActions = 50;
|
||||
$aActions = [];
|
||||
// Create a button for a few action or a kebab button for multiple actions that a more than what's configured
|
||||
if (count($aParams['actions']) > $iMaxActions) {
|
||||
$oKebabButton = ButtonUIBlockFactory::MakeIconAction('fas fa-ellipsis-v', 'More actions', 'kebab');
|
||||
$oKebabButton->AddCSSClass('ibo-field--action');
|
||||
|
||||
$aKebabActions = [];
|
||||
foreach ($aParams['actions'] as $oAction) {
|
||||
$aKebabActions[] = $oAction->GetMenuItem();
|
||||
}
|
||||
//TODO: Make a dict entry for the kebab menu label
|
||||
$oKebabPopoverMenu = PopoverMenuFactory::MakeMenuForActions($oField->GetId().'--kebab-menu', $aKebabActions);
|
||||
$oKebabPopoverMenu->SetTogglerFromBlock($oKebabButton);
|
||||
$oKebabPopoverMenu->SetContainer(PopoverMenu::ENUM_CONTAINER_BODY);
|
||||
|
||||
$aActions[] = $oKebabButton;
|
||||
$aActions[] = $oKebabPopoverMenu;
|
||||
} else {
|
||||
foreach ($aParams['actions'] as $oAction) {
|
||||
$oActionButton = ButtonUIBlockFactory::MakeIconButtonFromApplicationPopupMenuItem($oAction);
|
||||
$oActionButton->AddCSSClass('ibo-field--action');
|
||||
$aActions[] = $oActionButton;
|
||||
}
|
||||
}
|
||||
$oField->SetActions($aActions);
|
||||
}
|
||||
|
||||
return $oField;
|
||||
}
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ class ActivityPanel extends UIBlock
|
||||
protected $bPrefilterStateChangesOnLogs;
|
||||
/** @var bool */
|
||||
protected $bPrefilterEditsOnLogs;
|
||||
|
||||
protected array $aActivityActions = [];
|
||||
/**
|
||||
* ActivityPanel constructor.
|
||||
*
|
||||
@@ -939,6 +939,10 @@ class ActivityPanel extends UIBlock
|
||||
|
||||
$aSubBlocks[$this->GetComposeMenu()->GetId()] = $this->GetComposeMenu();
|
||||
|
||||
foreach ($this->GetActivityActions() as $oActivityAction) {
|
||||
$aSubBlocks[$oActivityAction->GetId()] = $oActivityAction;
|
||||
}
|
||||
|
||||
return $aSubBlocks;
|
||||
}
|
||||
|
||||
@@ -950,4 +954,26 @@ class ActivityPanel extends UIBlock
|
||||
{
|
||||
return \UserRights::IsActionAllowed($this->GetObjectClass(), UR_ACTION_MODIFY);
|
||||
}
|
||||
|
||||
public function HasActivityActions(): bool
|
||||
{
|
||||
return count($this->aActivityActions) > 0;
|
||||
}
|
||||
|
||||
public function GetActivityActions(): array
|
||||
{
|
||||
return $this->aActivityActions;
|
||||
}
|
||||
|
||||
public function SetActivityActions(array $aActivityActions)
|
||||
{
|
||||
$this->aActivityActions = $aActivityActions;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function AddActivityAction($oActivityAction)
|
||||
{
|
||||
$this->aActivityActions[] = $oActivityAction;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2026 Combodo SAS
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Base\Layout\ActivityPanel\ActivityPanelAction;
|
||||
|
||||
use Combodo\iTop\Application\UI\Base\Common\Action\tActionCommon;
|
||||
use Combodo\iTop\Application\UI\Base\Component\PopoverMenu\PopoverMenu;
|
||||
use Combodo\iTop\Application\UI\Base\UIBlock;
|
||||
|
||||
/**
|
||||
* Class ActivityPanelAction
|
||||
*
|
||||
* @package Combodo\iTop\Application\UI\Base\Layout\ActivityPanel\ActivityPanelAction
|
||||
* @internal
|
||||
* @since 3.3.0
|
||||
*/
|
||||
abstract class ActivityPanelAction extends UIBlock
|
||||
{
|
||||
use tActionCommon;
|
||||
// Overloaded constants
|
||||
public const BLOCK_CODE = 'ibo-activity-panel-action';
|
||||
public const DEFAULT_HTML_TEMPLATE_REL_PATH = 'base/layouts/activity-panel/activity-panel-action/layout';
|
||||
public const DEFAULT_JS_TEMPLATE_REL_PATH = 'base/layouts/activity-panel/activity-panel-action/layout';
|
||||
public const DEFAULT_JS_FILES_REL_PATH = [
|
||||
];
|
||||
public const DEFAULT_CSS_FILES_REL_PATH = [
|
||||
];
|
||||
|
||||
/** @var array<string, array<\ApplicationPopupMenuItem>> */
|
||||
protected array $aPopupItems = [];
|
||||
protected ?PopoverMenu $oPopoverMenu = null;
|
||||
|
||||
public function __construct(string $sLabel, string $sIconClass, ?string $sTooltip = null, ?string $sId = null)
|
||||
{
|
||||
parent::__construct($sId);
|
||||
$this->sUid = $sId ?? $this->GetId();
|
||||
$this->sLabel = $sLabel;
|
||||
$this->sIconClass = $sIconClass;
|
||||
$this->sTooltip = $sTooltip;
|
||||
}
|
||||
|
||||
public function SetPopupItems(array $aPopupItems)
|
||||
{
|
||||
$this->aPopupItems = $aPopupItems;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function AddPopupItem(string $sSectionId, \ApplicationPopupMenuItem $oPopupItem)
|
||||
{
|
||||
if (!array_key_exists($sSectionId, $this->aPopupItems)) {
|
||||
$this->aPopupItems[$sSectionId] = [];
|
||||
}
|
||||
|
||||
$this->aPopupItems[$sSectionId][] = $oPopupItem;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function GetPopupItems(): array
|
||||
{
|
||||
return $this->aPopupItems;
|
||||
}
|
||||
|
||||
public function SetPopoverMenu(PopoverMenu $oPopoverMenu)
|
||||
{
|
||||
$this->oPopoverMenu = $oPopoverMenu;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function GetPopoverMenu(): ?PopoverMenu
|
||||
{
|
||||
return $this->oPopoverMenu;
|
||||
}
|
||||
|
||||
public function HasPopoverMenu(): bool
|
||||
{
|
||||
return $this->oPopoverMenu !== null;
|
||||
}
|
||||
|
||||
public function GetSubBlocks(): array
|
||||
{
|
||||
if (false === $this->HasPopoverMenu()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [$this->oPopoverMenu->GetId() => $this->oPopoverMenu];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2026 Combodo SAS
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Base\Layout\ActivityPanel\ActivityPanelAction;
|
||||
|
||||
use ApplicationPopupMenuItem;
|
||||
use Combodo\iTop\Application\UI\Base\Component\PopoverMenu\PopoverMenu;
|
||||
use Combodo\iTop\Application\UI\Base\Component\PopoverMenu\PopoverMenuItem\PopoverMenuItemFactory;
|
||||
use JSPopupMenuItem;
|
||||
use SeparatorPopupMenuItem;
|
||||
use URLPopupMenuItem;
|
||||
|
||||
/**
|
||||
* Class ActivityPanelActionJS
|
||||
*
|
||||
* @package Combodo\iTop\Application\UI\Base\Layout\ActivityPanel\ActivityPanelAction
|
||||
* @internal
|
||||
* @since 3.3.0
|
||||
*/
|
||||
class ActivityPanelActionFactory
|
||||
{
|
||||
/**
|
||||
* @param array $aPopupItems as follow:
|
||||
* [ 'case-log-attribute-code' => [ ApplicationPopupMenuItem1, ... ], ... ]
|
||||
* or
|
||||
* [ 'case-log-attribute-code' => ['label' => 'Displayed label', 'items' => [ ApplicationPopupMenuItem1, ... ]], ... ]
|
||||
* @return ActivityPanelAction[]
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function MakeFromApplicationPopupItems(array $aPopupItems)
|
||||
{
|
||||
$aActionsByUid = [];
|
||||
|
||||
foreach ($aPopupItems as $sSectionId => $aSectionData) {
|
||||
$sSectionLabel = (string) $sSectionId;
|
||||
$aSectionPopupItems = $aSectionData;
|
||||
if (is_array($aSectionData) && array_key_exists('items', $aSectionData)) {
|
||||
$aSectionPopupItems = $aSectionData['items'];
|
||||
if (array_key_exists('label', $aSectionData)) {
|
||||
$sSectionLabel = (string) $aSectionData['label'];
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_array($aSectionPopupItems)) {
|
||||
$aSectionPopupItems = [$aSectionPopupItems];
|
||||
}
|
||||
|
||||
// Special index as separators aren't meant to be multiple action across different caselogs
|
||||
$iSectionSeparatorIndex = 0;
|
||||
foreach ($aSectionPopupItems as $oPopupItem) {
|
||||
if (!$oPopupItem instanceof ApplicationPopupMenuItem) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sUid = $oPopupItem->GetUID();
|
||||
if ($oPopupItem instanceof SeparatorPopupMenuItem) {
|
||||
$iSectionSeparatorIndex++;
|
||||
$sUid = 'ibo-activity-panel--activity-action-separator--'.$iSectionSeparatorIndex;
|
||||
}
|
||||
if (!isset($aActionsByUid[$sUid])) {
|
||||
$oActivityAction = static::MakeFromApplicationPopupItem($oPopupItem);
|
||||
if ($oActivityAction === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (false === ($oActivityAction instanceof ActivityPanelActionSeparator)) {
|
||||
$oPopoverMenu = new PopoverMenu($oActivityAction->GetId().'-menu');
|
||||
$oPopoverMenu->SetContainer(PopoverMenu::ENUM_CONTAINER_BODY);
|
||||
$oPopoverMenu->SetTogglerFromBlock($oActivityAction);
|
||||
$oActivityAction->SetPopoverMenu($oPopoverMenu);
|
||||
}
|
||||
|
||||
$aActionsByUid[$sUid] = $oActivityAction;
|
||||
}
|
||||
|
||||
if ($aActionsByUid[$sUid] instanceof ActivityPanelActionSeparator) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$oPopupItemForPopoverMenuItem = clone $oPopupItem;
|
||||
$oPopupItemForPopoverMenuItem->SetLabel($sSectionLabel);
|
||||
$oPopupItemForPopoverMenuItem->SetIconClass('');
|
||||
|
||||
$oPopoverMenuItem = PopoverMenuItemFactory::MakeFromApplicationPopupMenuItem($oPopupItemForPopoverMenuItem);
|
||||
$oPopoverMenuItem->AddDataAttribute('caselog-attribute-code', (string) $sSectionId);
|
||||
$aActionsByUid[$sUid]->GetPopoverMenu()->AddItem((string) $sSectionId, $oPopoverMenuItem);
|
||||
}
|
||||
}
|
||||
|
||||
return array_values($aActionsByUid);
|
||||
}
|
||||
|
||||
public static function MakeFromApplicationPopupItem($oPopupItem): ?ActivityPanelAction
|
||||
{
|
||||
if ($oPopupItem instanceof JSPopupMenuItem) {
|
||||
$oAction = new ActivityPanelActionJS(
|
||||
$oPopupItem->GetLabel(),
|
||||
$oPopupItem->GetIconClass(),
|
||||
$oPopupItem->GetTooltip(),
|
||||
$oPopupItem->GetUID()
|
||||
);
|
||||
$oAction->SetJsCode($oPopupItem->GetJsCode());
|
||||
$oAction->SetUrl($oPopupItem->GetUrl());
|
||||
$oAction->SetIncludeJSFiles($oPopupItem->GetLinkedScripts());
|
||||
|
||||
return $oAction;
|
||||
} elseif ($oPopupItem instanceof URLPopupMenuItem) {
|
||||
$oAction = new ActivityPanelActionURL(
|
||||
$oPopupItem->GetLabel(),
|
||||
$oPopupItem->GetIconClass(),
|
||||
$oPopupItem->GetTooltip(),
|
||||
$oPopupItem->GetUID()
|
||||
);
|
||||
$oAction->SetUrl($oPopupItem->GetUrl());
|
||||
$oAction->SetTarget($oPopupItem->GetTarget());
|
||||
|
||||
return $oAction;
|
||||
} elseif ($oPopupItem instanceof SeparatorPopupMenuItem) {
|
||||
return new ActivityPanelActionSeparator($oPopupItem->GetUID());
|
||||
}
|
||||
|
||||
// Should never happen, but just in case a new type is added, return null
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected static function ClonePopupItemWithLabel(ApplicationPopupMenuItem $oPopupItem, string $sLabel): ApplicationPopupMenuItem
|
||||
{
|
||||
$oClonedPopupItem = clone $oPopupItem;
|
||||
$oClonedPopupItem->SetLabel($sLabel);
|
||||
|
||||
return $oClonedPopupItem;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2026 Combodo SAS
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Base\Layout\ActivityPanel\ActivityPanelAction;
|
||||
|
||||
use Combodo\iTop\Application\UI\Base\Common\Action\tActionJs;
|
||||
|
||||
/**
|
||||
* Class ActivityPanelActionJS
|
||||
*
|
||||
* @package Combodo\iTop\Application\UI\Base\Layout\ActivityPanel\ActivityPanelAction
|
||||
* @internal
|
||||
* @since 3.3.0
|
||||
*/
|
||||
class ActivityPanelActionJS extends ActivityPanelAction
|
||||
{
|
||||
use tActionJs;
|
||||
// Overloaded constants
|
||||
public const BLOCK_CODE = 'ibo-activity-panel-action-js';
|
||||
public const DEFAULT_HTML_TEMPLATE_REL_PATH = 'base/layouts/activity-panel/activity-action/activity-action-js';
|
||||
public const DEFAULT_JS_TEMPLATE_REL_PATH = 'base/layouts/activity-panel/activity-action/activity-action-js';
|
||||
public const DEFAULT_JS_FILES_REL_PATH = [
|
||||
];
|
||||
public const DEFAULT_CSS_FILES_REL_PATH = [
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2026 Combodo SAS
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Base\Layout\ActivityPanel\ActivityPanelAction;
|
||||
|
||||
/**
|
||||
* Class ActivityPanelActionSeparator
|
||||
*
|
||||
* @package Combodo\iTop\Application\UI\Base\Layout\ActivityPanel\ActivityPanelAction
|
||||
* @internal
|
||||
* @since 3.3.0
|
||||
*/
|
||||
class ActivityPanelActionSeparator extends ActivityPanelAction
|
||||
{
|
||||
public const DEFAULT_HTML_TEMPLATE_REL_PATH = 'base/layouts/activity-panel/activity-action/activity-action-separator';
|
||||
public const DEFAULT_JS_TEMPLATE_REL_PATH = null;
|
||||
|
||||
/**
|
||||
* @param string|null $sId
|
||||
*/
|
||||
public function __construct(?string $sId = null)
|
||||
{
|
||||
parent::__construct('', '', null, $sId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2026 Combodo SAS
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Base\Layout\ActivityPanel\ActivityPanelAction;
|
||||
|
||||
use Combodo\iTop\Application\UI\Base\Common\Action\tActionURL;
|
||||
|
||||
/**
|
||||
* Class ActivityPanelActionURL
|
||||
*
|
||||
* @package Combodo\iTop\Application\UI\Base\Layout\ActivityPanel\ActivityPanelAction
|
||||
* @internal
|
||||
* @since 3.3.0
|
||||
*/
|
||||
class ActivityPanelActionURL extends ActivityPanelAction
|
||||
{
|
||||
use tActionURL;
|
||||
// Overloaded constants
|
||||
public const BLOCK_CODE = 'ibo-activity-panel-action-url';
|
||||
public const DEFAULT_HTML_TEMPLATE_REL_PATH = 'base/layouts/activity-panel/activity-action/activity-action-url';
|
||||
public const DEFAULT_JS_TEMPLATE_REL_PATH = 'base/layouts/activity-panel/activity-action/activity-action-url';
|
||||
public const DEFAULT_JS_FILES_REL_PATH = [
|
||||
];
|
||||
public const DEFAULT_CSS_FILES_REL_PATH = [
|
||||
];
|
||||
}
|
||||
@@ -22,12 +22,15 @@ namespace Combodo\iTop\Application\UI\Base\Layout\ActivityPanel;
|
||||
|
||||
use cmdbAbstractObject;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\ActivityPanel\ActivityEntry\ActivityEntryFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\ActivityPanel\ActivityPanelAction\ActivityPanelActionFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\ActivityPanel\CaseLogEntryForm\CaseLogEntryFormFactory;
|
||||
use DBObject;
|
||||
use DBObjectSearch;
|
||||
use DBObjectSet;
|
||||
use Dict;
|
||||
use Exception;
|
||||
use ExecutionKPI;
|
||||
use iPopupMenuExtension;
|
||||
use IssueLog;
|
||||
use MetaModel;
|
||||
|
||||
@@ -172,6 +175,53 @@ class ActivityPanelFactory
|
||||
}
|
||||
}
|
||||
|
||||
if ($sMode === cmdbAbstractObject::ENUM_DISPLAY_MODE_VIEW) {
|
||||
$aActionItems = [];
|
||||
/** @var \iPopupMenuExtension $oExtensionInstance */
|
||||
foreach (MetaModel::EnumPlugins('iPopupMenuExtension') as $oExtensionInstance) {
|
||||
// Iterate over every case log tab to retrieve the actions for each of them
|
||||
foreach ($aCaseLogTabs as $sCaseLogAttCode => $aCaseLogData) {
|
||||
$aCaselogActions = [];
|
||||
|
||||
// Let's iterate over the menu items for this case log
|
||||
foreach ($oExtensionInstance::EnumItems(iPopupMenuExtension::MENU_OBJDETAILS_ACTIVITY_PANEL_ACTIONS, ['object' => $oObject, 'caselog_att_code' => $sCaseLogAttCode]) as $oMenuItem) {
|
||||
$aCaselogActions[] = $oMenuItem;
|
||||
}
|
||||
|
||||
if (empty($aCaselogActions)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create a new section for the case log if it doesn't exist yet
|
||||
if (!array_key_exists($sCaseLogAttCode, $aActionItems)) {
|
||||
$aActionItems[$sCaseLogAttCode] = [
|
||||
'label' => MetaModel::GetLabel($sObjClass, $sCaseLogAttCode),
|
||||
'items' => [],
|
||||
];
|
||||
}
|
||||
|
||||
$aActionItems[$sCaseLogAttCode]['items'] = array_merge($aActionItems[$sCaseLogAttCode]['items'], $aCaselogActions);
|
||||
}
|
||||
|
||||
$aActivityItems = [];
|
||||
// Don't forget 1 last iteration for the activity tab
|
||||
foreach ($oExtensionInstance::EnumItems(iPopupMenuExtension::MENU_OBJDETAILS_ACTIVITY_PANEL_ACTIONS, ['object' => $oObject, 'caselog_att_code' => 'activity']) as $oMenuItem) {
|
||||
$aActivityItems[] = $oMenuItem;
|
||||
}
|
||||
if (!empty($aActivityItems)) {
|
||||
if (!array_key_exists('activity', $aActionItems)) {
|
||||
$aActionItems['activity'] = [
|
||||
'label' => Dict::S('UI:Layout:ActivityPanel:Tab:Activity:Title'),
|
||||
'items' => [],
|
||||
];
|
||||
}
|
||||
$aActionItems['activity']['items'] = array_merge($aActionItems['activity']['items'], $aActivityItems);
|
||||
}
|
||||
}
|
||||
|
||||
$oActivityPanel->SetActivityActions(ActivityPanelActionFactory::MakeFromApplicationPopupItems($aActionItems));
|
||||
}
|
||||
|
||||
$oKPI->ComputeStatsForExtension(new ActivityPanelFactory(), 'MakeForObjectDetails');
|
||||
|
||||
return $oActivityPanel;
|
||||
|
||||
@@ -12,10 +12,12 @@ use Combodo\iTop\Application\UI\Base\Component\Button\Button;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Button\ButtonUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\ButtonGroup\ButtonGroupUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\PopoverMenu\PopoverMenu;
|
||||
use Combodo\iTop\Application\UI\Base\Component\PopoverMenu\PopoverMenuFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\PopoverMenu\PopoverMenuItem\PopoverMenuItemFactory;
|
||||
use DBObject;
|
||||
use DBObjectSet;
|
||||
use Dict;
|
||||
use iPopupMenuExtension;
|
||||
use JSPopupMenuItem;
|
||||
use MetaModel;
|
||||
use UserRights;
|
||||
@@ -48,6 +50,30 @@ class CaseLogEntryFormFactory
|
||||
$oCaseLogEntryForm->AddMainActionButtons($oSaveButton);
|
||||
}
|
||||
|
||||
// Build extra actions
|
||||
$aPopupItems = [];
|
||||
/** @var \iPopupMenuExtension $oExtensionInstance */
|
||||
foreach (MetaModel::EnumPlugins('iPopupMenuExtension') as $oExtensionInstance) {
|
||||
foreach ($oExtensionInstance::EnumItems(iPopupMenuExtension::MENU_OBJDETAILS_FIELD_ACTIONS, ['object' => $oObject, 'att_code' => $sCaseLogAttCode, 'mode' => $sObjectMode === cmdbAbstractObject::ENUM_DISPLAY_MODE_EDIT ? 'edit' : 'read']) as $oMenuItem) {
|
||||
$aPopupItems[] = $oMenuItem;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($aPopupItems)) {
|
||||
$aActions = [];
|
||||
// Create a button for each extra action, the UI will be responsible for displaying them in a dropdown if there are too many
|
||||
foreach ($aPopupItems as $oAction) {
|
||||
$oActionButton = ButtonUIBlockFactory::MakeButtonFromApplicationPopupMenuItem($oAction);
|
||||
$oActionButton->AddCSSClass('ibo-field--action');
|
||||
$aActions[] = $oActionButton;
|
||||
}
|
||||
|
||||
foreach ($aActions as $oAction) {
|
||||
$oAction->AddCSSClass('ibo-caselog-entry-form--extra-action');
|
||||
$oCaseLogEntryForm->AddExtraActionButtons($oAction);
|
||||
}
|
||||
}
|
||||
|
||||
return $oCaseLogEntryForm;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@ use Combodo\iTop\Application\UI\Base\Component\Breadcrumbs\Breadcrumbs;
|
||||
use Combodo\iTop\Application\UI\Base\Component\GlobalSearch\GlobalSearch;
|
||||
use Combodo\iTop\Application\UI\Base\Component\QuickCreate\QuickCreate;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Toolbar\Toolbar;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\TopBar\TopBarAction\TopBarQuickAction;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\TopBar\TopBarAction\TopBarQuickActionJS;
|
||||
use Combodo\iTop\Application\UI\Base\UIBlock;
|
||||
|
||||
/**
|
||||
@@ -48,6 +50,8 @@ class TopBar extends UIBlock
|
||||
protected $oBreadcrumbs;
|
||||
/** @var Toolbar|null */
|
||||
protected $oToolbar;
|
||||
/** @var array $aActions */
|
||||
protected array $aActions = [];
|
||||
|
||||
/**
|
||||
* TopBar constructor.
|
||||
@@ -205,7 +209,8 @@ class TopBar extends UIBlock
|
||||
{
|
||||
$aSubBlocks = [];
|
||||
|
||||
$aSubBlocksNames = ['QuickCreate', 'GlobalSearch', 'Breadcrumbs', 'Toolbar'];
|
||||
// Add single objects
|
||||
$aSubBlocksNames = ['QuickCreate', 'GlobalSearch', 'Breadcrumbs', 'Toolbar', ];
|
||||
foreach ($aSubBlocksNames as $sSubBlockName) {
|
||||
$sHasMethodName = 'Has'.$sSubBlockName;
|
||||
if (true === call_user_func_array([$this, $sHasMethodName], [])) {
|
||||
@@ -214,6 +219,40 @@ class TopBar extends UIBlock
|
||||
}
|
||||
}
|
||||
|
||||
// Add object arrays
|
||||
$aSubBlocksNames = ['Actions'];
|
||||
foreach ($aSubBlocksNames as $sSubBlockName) {
|
||||
$sHasMethodName = 'Has'.$sSubBlockName;
|
||||
if (true === call_user_func_array([$this, $sHasMethodName], [])) {
|
||||
$sPropertyName = 'a'.$sSubBlockName;
|
||||
foreach ($this->$sPropertyName as $oSubBlock) {
|
||||
$aSubBlocks[$oSubBlock->GetId()] = $oSubBlock;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $aSubBlocks;
|
||||
}
|
||||
|
||||
public function HasActions(): bool
|
||||
{
|
||||
return count($this->GetActions()) > 0;
|
||||
}
|
||||
|
||||
public function GetActions(): array
|
||||
{
|
||||
return $this->aActions;
|
||||
}
|
||||
|
||||
public function SetActions(array $aActions)
|
||||
{
|
||||
$this->aActions = $aActions;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function AddAction(TopBarQuickAction $oAction)
|
||||
{
|
||||
$this->aActions[] = $oAction;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,9 @@ namespace Combodo\iTop\Application\UI\Base\Layout\TopBar;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Breadcrumbs\Breadcrumbs;
|
||||
use Combodo\iTop\Application\UI\Base\Component\GlobalSearch\GlobalSearchFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\QuickCreate\QuickCreateFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\TopBar\TopBarAction\TopBarQuickActionFactory;
|
||||
use iPopupMenuExtension;
|
||||
use MetaModel;
|
||||
use utils;
|
||||
|
||||
/**
|
||||
@@ -58,6 +61,13 @@ class TopBarFactory
|
||||
$oTopBar->SetGlobalSearch(GlobalSearchFactory::MakeFromUserHistory());
|
||||
}
|
||||
|
||||
/** @var \iPopupMenuExtension $oExtensionInstance */
|
||||
foreach (MetaModel::EnumPlugins('iPopupMenuExtension') as $oExtensionInstance) {
|
||||
foreach ($oExtensionInstance::EnumItems(iPopupMenuExtension::MENU_TOPBAR_ACTIONS, []) as $oMenuItem) {
|
||||
$oTopBar->AddAction(TopBarQuickActionFactory::MakeFromApplicationPopupItem($oMenuItem));
|
||||
}
|
||||
}
|
||||
|
||||
if (utils::GetConfig()->Get('breadcrumb.enabled') === true) {
|
||||
$oBreadcrumbs = new Breadcrumbs($aBreadcrumbsEntry, Breadcrumbs::BLOCK_CODE);
|
||||
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2026 Combodo SAS
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Base\Layout\TopBar\TopBarAction;
|
||||
|
||||
use Combodo\iTop\Application\UI\Base\UIBlock;
|
||||
|
||||
/**
|
||||
* Class TopBarAction
|
||||
*
|
||||
* @package Combodo\iTop\Application\UI\Base\Layout\TopBar\TopBarAction
|
||||
* @internal
|
||||
* @since 3.3.0
|
||||
*/
|
||||
abstract class TopBarQuickAction extends UIBlock
|
||||
{
|
||||
// Overloaded constants
|
||||
public const BLOCK_CODE = 'ibo-top-bar-quick-action';
|
||||
public const DEFAULT_HTML_TEMPLATE_REL_PATH = 'base/layouts/top-bar/top-bar-quick-action/layout';
|
||||
public const DEFAULT_JS_TEMPLATE_REL_PATH = 'base/layouts/top-bar/top-bar-quick-action/layout';
|
||||
public const DEFAULT_JS_FILES_REL_PATH = [
|
||||
];
|
||||
public const DEFAULT_CSS_FILES_REL_PATH = [
|
||||
];
|
||||
|
||||
protected string $sLabel;
|
||||
protected string $sIconClass;
|
||||
protected ?string $sTooltip = null;
|
||||
|
||||
/**
|
||||
* TopBarAction constructor.
|
||||
*
|
||||
* @param string $sLabel
|
||||
* @param string $sIconClass
|
||||
* @param string|null $sTooltip
|
||||
* @param string|null $sId
|
||||
*
|
||||
* @throws \CoreException
|
||||
* @throws \DictExceptionMissingString
|
||||
*/
|
||||
public function __construct(string $sLabel, string $sIconClass, ?string $sTooltip = null, ?string $sId = null)
|
||||
{
|
||||
parent::__construct($sId);
|
||||
$this->sLabel = $sLabel;
|
||||
$this->sIconClass = $sIconClass;
|
||||
$this->sTooltip = $sTooltip;
|
||||
}
|
||||
|
||||
public function GetLabel(): string
|
||||
{
|
||||
return $this->sLabel;
|
||||
}
|
||||
|
||||
public function SetLabel(string $sLabel): TopBarQuickAction
|
||||
{
|
||||
$this->sLabel = $sLabel;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function GetIconClass(): string
|
||||
{
|
||||
return $this->sIconClass;
|
||||
}
|
||||
|
||||
public function SetIconClass(string $sIconClass): TopBarQuickAction
|
||||
{
|
||||
$this->sIconClass = $sIconClass;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function GetTooltip(): ?string
|
||||
{
|
||||
return $this->sTooltip;
|
||||
}
|
||||
|
||||
public function SetTooltip(?string $sTooltip): TopBarQuickAction
|
||||
{
|
||||
$this->sTooltip = $sTooltip;
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2026 Combodo SAS
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Base\Layout\TopBar\TopBarAction;
|
||||
|
||||
use JSPopupMenuItem;
|
||||
use SeparatorPopupMenuItem;
|
||||
use URLPopupMenuItem;
|
||||
|
||||
/**
|
||||
* Class TopBarActionFactory
|
||||
*
|
||||
* @package Combodo\iTop\Application\UI\Base\Layout\TopBar\TopBarAction
|
||||
* @internal
|
||||
* @since 3.0.0
|
||||
*/
|
||||
class TopBarQuickActionFactory
|
||||
{
|
||||
public static function MakeFromApplicationPopupItem($oApplicationPopupItem): ?TopBarQuickAction
|
||||
{
|
||||
if ($oApplicationPopupItem instanceof JSPopupMenuItem) {
|
||||
$oTopBarAction = new TopBarQuickActionJS(
|
||||
$oApplicationPopupItem->GetLabel(),
|
||||
$oApplicationPopupItem->GetIconClass(),
|
||||
$oApplicationPopupItem->GetTooltip(),
|
||||
$oApplicationPopupItem->GetUID()
|
||||
);
|
||||
$oTopBarAction->SetJsCode($oApplicationPopupItem->GetJsCode());
|
||||
$oTopBarAction->SetUrl($oApplicationPopupItem->GetUrl());
|
||||
|
||||
$oTopBarAction->SetIncludeJSFiles($oApplicationPopupItem->GetLinkedScripts());
|
||||
return $oTopBarAction;
|
||||
} elseif ($oApplicationPopupItem instanceof URLPopupMenuItem) {
|
||||
$oTopBarAction = new TopBarQuickActionURL(
|
||||
$oApplicationPopupItem->GetLabel(),
|
||||
$oApplicationPopupItem->GetIconClass(),
|
||||
$oApplicationPopupItem->GetTooltip(),
|
||||
$oApplicationPopupItem->GetUID()
|
||||
);
|
||||
$oTopBarAction->SetUrl($oApplicationPopupItem->GetUrl());
|
||||
$oTopBarAction->SetTarget($oApplicationPopupItem->GetTarget());
|
||||
return $oTopBarAction;
|
||||
} elseif ($oApplicationPopupItem instanceof SeparatorPopupMenuItem) {
|
||||
$oTopBarAction = new TopBarQuickActionSeparator($oApplicationPopupItem->GetUID());
|
||||
$oTopBarAction->SetCSSClasses($oApplicationPopupItem->GetCssClasses());
|
||||
return $oTopBarAction;
|
||||
}
|
||||
|
||||
// Should never happen, but just in case a new type is added, return null
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2026 Combodo SAS
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Base\Layout\TopBar\TopBarAction;
|
||||
|
||||
use Combodo\iTop\Application\UI\Base\Common\Action\tActionJs;
|
||||
use Combodo\iTop\Application\UI\Base\UIBlock;
|
||||
|
||||
/**
|
||||
* Class TopBarActionJS
|
||||
*
|
||||
* @package Combodo\iTop\Application\UI\Base\Layout\TopBar\TopBarAction
|
||||
* @internal
|
||||
* @since 3.3.0
|
||||
*/
|
||||
class TopBarQuickActionJS extends TopBarQuickAction
|
||||
{
|
||||
use tActionJs;
|
||||
public const DEFAULT_HTML_TEMPLATE_REL_PATH = 'base/layouts/top-bar/top-bar-quick-action/top-bar-quick-action-js';
|
||||
public const DEFAULT_JS_TEMPLATE_REL_PATH = 'base/layouts/top-bar/top-bar-quick-action/top-bar-quick-action-js';
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2026 Combodo SAS
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Base\Layout\TopBar\TopBarAction;
|
||||
|
||||
/**
|
||||
* Class TopBarQuickActionSeparator
|
||||
*
|
||||
* @package Combodo\iTop\Application\UI\Base\Layout\TopBar\TopBarAction
|
||||
* @internal
|
||||
* @since 3.3.0
|
||||
*/
|
||||
class TopBarQuickActionSeparator extends TopBarQuickAction
|
||||
{
|
||||
public const DEFAULT_HTML_TEMPLATE_REL_PATH = 'base/layouts/top-bar/top-bar-quick-action/top-bar-quick-action-separator';
|
||||
public const DEFAULT_JS_TEMPLATE_REL_PATH = null;
|
||||
|
||||
/**
|
||||
* @param string|null $sId
|
||||
*
|
||||
* @throws \CoreException
|
||||
* @throws \DictExceptionMissingString
|
||||
*/
|
||||
public function __construct(?string $sId = null)
|
||||
{
|
||||
parent::__construct('', '', null, $sId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2026 Combodo SAS
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Base\Layout\TopBar\TopBarAction;
|
||||
|
||||
use Combodo\iTop\Application\UI\Base\Common\Action\tActionURL;
|
||||
|
||||
/**
|
||||
* Class TopBarActionURL
|
||||
*
|
||||
* @package Combodo\iTop\Application\UI\Base\Layout\TopBar\TopBarAction
|
||||
* @internal
|
||||
* @since 3.3.0
|
||||
*/
|
||||
class TopBarQuickActionURL extends TopBarQuickAction
|
||||
{
|
||||
use tActionURL;
|
||||
public const DEFAULT_HTML_TEMPLATE_REL_PATH = 'base/layouts/top-bar/top-bar-quick-action/top-bar-quick-action-url';
|
||||
public const DEFAULT_JS_TEMPLATE_REL_PATH = 'base/layouts/top-bar/top-bar-quick-action/top-bar-quick-action-url';
|
||||
}
|
||||
11
templates/base/components/button/separator/layout.html.twig
Normal file
11
templates/base/components/button/separator/layout.html.twig
Normal file
@@ -0,0 +1,11 @@
|
||||
{# @copyright Copyright (C) 2010-2026 Combodo SAS #}
|
||||
{# @license http://opensource.org/licenses/AGPL-3.0 #}
|
||||
{% apply spaceless %}
|
||||
<span id="{{ oUIBlock.GetId() }}"
|
||||
class="{{ oUIBlock.GetBlocksInheritanceCSSClassesAsString() }}
|
||||
{% if oUIBlock.GetAdditionalCSSClassesAsString() %}{{ oUIBlock.GetAdditionalCSSClassesAsString() }}{% endif %}
|
||||
{% if oUIBlock.IsHidden() %}ibo-is-hidden{% endif %}"
|
||||
data-role="ibo-button-separator">
|
||||
</span>
|
||||
{% endapply %}
|
||||
|
||||
@@ -26,6 +26,13 @@
|
||||
{% if oUIBlock.HasDescription() %}
|
||||
<span class="ibo-has-description" data-tooltip-content="{{ oUIBlock.GetDescription() }}" data-tooltip-max-width="600px" ></span>
|
||||
{% endif %}
|
||||
{% if oUIBlock.HasActions() %}
|
||||
<span class="ibo-field--actions">
|
||||
{% for oAction in oUIBlock.GetActions() %}
|
||||
{{ render_block(oAction, {aPage: aPage}) }}
|
||||
{% endfor %}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if oUIBlock.GetLayout() == constant("Combodo\\iTop\\Application\\UI\\Base\\Component\\Field\\Field::ENUM_FIELD_LAYOUT_LARGE") %}
|
||||
{% if oUIBlock.GetComments() %}
|
||||
<div class="ibo-field--comments">{{ oUIBlock.GetComments()|raw }}</div>
|
||||
@@ -33,9 +40,9 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="ibo-field--value" {% if oUIBlock.GetValueId() %}id="{{ oUIBlock.GetValueId() }}"{% endif %}>
|
||||
{% for oSubBlock in oUIBlock.GetSubBlocks() %}
|
||||
{{ render_block(oSubBlock, {aPage: aPage}) }}
|
||||
{% endfor %}
|
||||
{% if oUIBlock.HasValue() %}
|
||||
{{ render_block(oUIBlock.GetValue(), {aPage: aPage}) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if oUIBlock.GetLayout() != constant("Combodo\\iTop\\Application\\UI\\Base\\Component\\Field\\Field::ENUM_FIELD_LAYOUT_LARGE") %}
|
||||
{% if oUIBlock.GetComments() %}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
<a href="{{ oUIBlock.GetUrl() }}"
|
||||
id="{{ oUIBlock.GetId() }}"
|
||||
class="{{ oUIBlock.GetBlocksInheritanceCSSClassesAsString() }} {{ oUIBlock.GetAdditionalCSSClassesAsString() }} ibo-activity-panel--activity-action"
|
||||
data-role="ibo-activity-panel--activity-action"
|
||||
{% if oUIBlock.GetTooltip() is not empty %}
|
||||
data-tooltip-content="{{ oUIBlock.GetTooltip() }}"
|
||||
aria-label="{{ oUIBlock.GetTooltip() }}"
|
||||
{% endif %}
|
||||
>
|
||||
{% if oUIBlock.GetIconClass() is not empty %}
|
||||
<i class="{{ oUIBlock.GetIconClass() }}"></i>
|
||||
{% endif %}
|
||||
{# <span>{{ oUIBlock.GetLabel() }}</span>#}
|
||||
</a>
|
||||
{% if oUIBlock.HasPopoverMenu() %}
|
||||
{{ render_block(oUIBlock.GetPopoverMenu()) }}
|
||||
{% endif %}
|
||||
@@ -0,0 +1 @@
|
||||
{# Probably not needed, activity panel will handle interactions with popovermenu #}
|
||||
@@ -0,0 +1,4 @@
|
||||
<span id="{{ oUIBlock.GetId() }}"
|
||||
class="{{ oUIBlock.GetBlocksInheritanceCSSClassesAsString() }} {{ oUIBlock.GetAdditionalCSSClassesAsString() }} ibo-activity-panel--activity-action-separator"
|
||||
data-role="ibo-activity-panel--activity-action-separator">
|
||||
</span>
|
||||
@@ -0,0 +1,17 @@
|
||||
<a href="{{ oUIBlock.GetUrl() }}"
|
||||
id="{{ oUIBlock.GetId() }}"
|
||||
class="{{ oUIBlock.GetBlocksInheritanceCSSClassesAsString() }} {{ oUIBlock.GetAdditionalCSSClassesAsString() }} ibo-activity-panel--activity-action"
|
||||
data-role="ibo-activity-panel--activity-action"
|
||||
{% if oUIBlock.GetTooltip() is not empty %}
|
||||
data-tooltip-content="{{ oUIBlock.GetTooltip() }}"
|
||||
aria-label="{{ oUIBlock.GetTooltip() }}"
|
||||
{% endif %}
|
||||
>
|
||||
{% if oUIBlock.GetIconClass() is not empty %}
|
||||
<i class="{{ oUIBlock.GetIconClass() }}"></i>
|
||||
{% endif %}
|
||||
{# <span>{{ oUIBlock.GetLabel() }}</span>#}
|
||||
</a>
|
||||
{% if oUIBlock.HasPopoverMenu() %}
|
||||
{{ render_block(oUIBlock.GetPopoverMenu()) }}
|
||||
{% endif %}
|
||||
@@ -0,0 +1 @@
|
||||
{# Probably not needed, activity panel will handle interactions with popovermenu #}
|
||||
@@ -84,6 +84,13 @@
|
||||
{{ render_block(oUIBlock.GetComposeMenu()) }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if oUIBlock.HasActivityActions() %}
|
||||
<div class="ibo-activity-panel--activity-actions" data-role="ibo-activity-panel--activity-actions">
|
||||
{% for oActivityAction in oUIBlock.GetActivityActions() %}
|
||||
{{ render_block(oActivityAction) }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="ibo-activity-panel--body" data-role="ibo-activity-panel--body">
|
||||
{% if oUIBlock.GetGroupedEntries()|length > 0 %}
|
||||
{% for aEntryGroup in oUIBlock.GetGroupedEntries() %}
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
{% if oUIBlock.HasGlobalSearch() %}
|
||||
{{ render_block(oUIBlock.GetGlobalSearch(), {aPage: aPage}) }}
|
||||
{% endif %}
|
||||
{% for oAction in oUIBlock.GetActions() %}
|
||||
{{ render_block(oAction, {aPage: aPage}) }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% if oUIBlock.HasBreadcrumbs() %}
|
||||
{{ render_block(oUIBlock.GetBreadcrumbs(), {aPage: aPage}) }}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{# Probably not needed, abstract #}
|
||||
@@ -0,0 +1,13 @@
|
||||
<div id="{{ oUIBlock.GetId() }}"
|
||||
data-role="ibo-top-bar-quick-action">
|
||||
<div class="ibo-top-bar-quick-action--head" data-role="ibo-top-bar-quick-action--head">
|
||||
<a href="{{ oUIBlock.GetURL() }}" class="ibo-top-bar-quick-action--icon" data-role="ibo-top-bar-quick-action--icon"
|
||||
aria-label="{{ oUIBlock.GetTooltip() }}"
|
||||
data-tooltip-content="{{ oUIBlock.GetTooltip() }}"
|
||||
data-tooltip-placement="bottom-start"
|
||||
data-tooltip-distance-offset="25"
|
||||
>
|
||||
<span class="{{ oUIBlock.GetIconClass() }}"></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,4 @@
|
||||
$('#{{ oUIBlock.GetId() }} [data-role="ibo-top-bar-quick-action--icon"]').on('click', function (event) {
|
||||
event.preventDefault();
|
||||
{{ oUIBlock.GetJsCode()|raw }}
|
||||
});
|
||||
@@ -0,0 +1,4 @@
|
||||
<div id="{{ oUIBlock.GetId() }}"
|
||||
class="ibo-top-bar-quick-action ibo-top-bar-quick-action-separator"
|
||||
data-role="ibo-top-bar-quick-action-separator">
|
||||
</div>
|
||||
@@ -0,0 +1,14 @@
|
||||
<div id="{{ oUIBlock.GetId() }}"
|
||||
data-role="ibo-top-bar-quick-action">
|
||||
<div class="ibo-top-bar-quick-action--head" data-role="ibo-top-bar-quick-action--head">
|
||||
<a href="{{ oUIBlock.GetURL() }}" class="ibo-top-bar-quick-action--icon" data-role="ibo-top-bar-quick-action--icon"
|
||||
target="{{ oUIBlock.GetTarget() }}"
|
||||
aria-label="{{ oUIBlock.GetTooltip() }}"
|
||||
data-tooltip-content="{{ oUIBlock.GetTooltip() }}"
|
||||
data-tooltip-placement="bottom-start"
|
||||
data-tooltip-distance-offset="25"
|
||||
>
|
||||
<span class="{{ oUIBlock.GetIconClass() }}"></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1 @@
|
||||
{# Probably not needed #}
|
||||
Reference in New Issue
Block a user