diff --git a/core/metamodel.class.php b/core/metamodel.class.php index d940b9f5e..79f0c541b 100644 --- a/core/metamodel.class.php +++ b/core/metamodel.class.php @@ -1553,6 +1553,7 @@ abstract class MetaModel { $aLinkedSets = array(); foreach (self::ListAttributeDefs($sClass) as $sAttCode => $oAtt) { + // Note: Careful, this will only return SUB-classes, which does NOT include AttributeLinkedset itself! We might want to use "is_a()" instead. if (is_subclass_of($oAtt, 'AttributeLinkedSet')) { $aLinkedSets[$sAttCode] = $oAtt; } @@ -1600,6 +1601,27 @@ abstract class MetaModel } } + /** @var array Cache for caselog attributes of the classes */ + protected static $m_aCaseLogsAttributesCache = []; + + /** + * Return an array of attribute codes for the caselogs attributes of $sClass + * + * @param string $sClass + * + * @return array + * @throws \CoreException + * @since 3.0.0 + */ + final public static function GetCaseLogs(string $sClass) + { + if (!isset(static::$m_aCaseLogsAttributesCache[$sClass])) { + static::$m_aCaseLogsAttributesCache[$sClass] = self::GetAttributesList($sClass, ['AttributeCaseLog']); + } + + return static::$m_aCaseLogsAttributesCache[$sClass]; + } + /** @var array */ protected static $m_aTrackForwardCache = array(); diff --git a/css/backoffice/layout/_all.scss b/css/backoffice/layout/_all.scss index 2d2fe150e..785faab4c 100644 --- a/css/backoffice/layout/_all.scss +++ b/css/backoffice/layout/_all.scss @@ -30,5 +30,5 @@ @import "activity-panel/caselog-entry"; @import "activity-panel/edits-entry"; @import "activity-panel/transition-entry"; -@import "activity-panel/activity-new-entry-form"; +@import "activity-panel/caselog-entry-form"; @import "blocks-integrations/panel-with-tab-container"; diff --git a/css/backoffice/layout/activity-panel/_activity-panel.scss b/css/backoffice/layout/activity-panel/_activity-panel.scss index 39237ae1d..3352c0b47 100644 --- a/css/backoffice/layout/activity-panel/_activity-panel.scss +++ b/css/backoffice/layout/activity-panel/_activity-panel.scss @@ -24,45 +24,48 @@ $ibo-activity-panel--padding-x: 16px !default; $ibo-activity-panel--padding-y: 0 !default; /* - Header */ -$ibo-activity-panel--header--padding-x: $ibo-activity-panel--padding-x * 3 !default; /* We need to increase this so the size toggler which will be set in abs. pos. can overlap it nicely */ $ibo-activity-panel--header--background-color: $ibo-color-grey-100 !default; $ibo-activity-panel--size-toggler--color: $ibo-color-grey-600 !default; $ibo-activity-panel--size-toggler--on-hover--color: $ibo-color-grey-800 !default; -/* - Tab */ -$ibo-activity-panel--tab--caselog-highlight-colors: $ibo-caselog-highlight-colors !default; -$ibo-activity-panel--tab--is-active--background-color: $ibo-color-grey-200 !default; +/* - Tabs togglers*/ +$ibo-activity-panel--tabs-togglers--padding-x: $ibo-activity-panel--padding-x * 3 !default; /* We need to increase this so the size toggler which will be set in abs. pos. can overlap it nicely */ + +/* - Tab toggler */ +$ibo-activity-panel--tab-toggler--caselog-highlight-colors: $ibo-caselog-highlight-colors !default; +$ibo-activity-panel--tab-toggler--is-active--background-color: $ibo-color-grey-200 !default; /* - Tab title */ $ibo-activity-panel--tab-title--padding-x: 16px !default; $ibo-activity-panel--tab-title--padding-y: 8px !default; -$ibo-activity-panel--tab-title--on-hover--background-color: $ibo-activity-panel--tab--is-active--background-color !default; -$ibo-activity-panel--tab-title--is-active--background-color: $ibo-activity-panel--tab--is-active--background-color !default; +$ibo-activity-panel--tab-title--on-hover--background-color: $ibo-activity-panel--tab-toggler--is-active--background-color !default; +$ibo-activity-panel--tab-title--is-active--background-color: $ibo-activity-panel--tab-toggler--is-active--background-color !default; -$ibo-activity-panel--tab-decoration--width: 12px !default; -$ibo-activity-panel--tab-decoration--height: $ibo-activity-panel--tab-decoration--width !default; -$ibo-activity-panel--tab-decoration--margin-right: 8px !default; -$ibo-activity-panel--tab-decoration--border-radius: $ibo-border-radius-300 !default; +$ibo-activity-panel--tab-title-decoration--width: 12px !default; +$ibo-activity-panel--tab-title-decoration--height: $ibo-activity-panel--tab-title-decoration--width !default; +$ibo-activity-panel--tab-title-decoration--margin-right: 8px !default; +$ibo-activity-panel--tab-title-decoration--border-radius: $ibo-border-radius-300 !default; -$ibo-activity-panel--tab-text--max-width: 100px !default; +$ibo-activity-panel--tab-title-text--max-width: 100px !default; /* - Tab toolbar */ $ibo-activity-panel--tab-toolbar--padding-x: $ibo-activity-panel--padding-x !default; -$ibo-activity-panel--tab-toolbar--height: 32px !default; $ibo-activity-panel--tab-toolbar--text-color: $ibo-color-grey-800 !default; -$ibo-activity-panel--tab-toolbar--background-color: $ibo-activity-panel--tab--is-active--background-color !default; +$ibo-activity-panel--tab-toolbar--background-color: $ibo-activity-panel--tab-toggler--is-active--background-color !default; -$ibo-activity-panel--tab-for-caselog--elements-spacing: 16px !default; -$ibo-activity-panel--tab-for-caselog--icon-margin-left: 8px !default; -$ibo-activity-panel--tab-for-caselog--icons-separator-content: "-" !default; -$ibo-activity-panel--tab-for-caselog--icons-separator-margin-x: 8px !default; +$ibo-activity-panel--tab-toolbar-actions--height: 32px !default; -$ibo-activity-panel--tab-for-activity--elements-spacing: 36px !default; -$ibo-activity-panel--tab-for-activity---checkbox-margin-right: 8px !default; +$ibo-activity-panel--tab-toolbar-for-caselog--elements-spacing: 16px !default; +$ibo-activity-panel--tab-toolbar-for-caselog--icon-margin-left: 8px !default; +$ibo-activity-panel--tab-toolbar-for-caselog--icons-separator-content: "-" !default; +$ibo-activity-panel--tab-toolbar-for-caselog--icons-separator-margin-x: 8px !default; + +$ibo-activity-panel--tab-toolbar-for-activity--elements-spacing: 36px !default; +$ibo-activity-panel--tab-toolbar-for-activity--checkbox-margin-right: 8px !default; /* - Body */ -$ibo-activity-panel--body--padding-top: $ibo-activity-panel--tab-toolbar--height + 16px !default; +$ibo-activity-panel--body--padding-top: $ibo-activity-panel--padding-x !default; $ibo-activity-panel--body--padding-x: $ibo-activity-panel--padding-x !default; $ibo-activity-panel--body--placeholder--margin-top: 16px !default; @@ -92,10 +95,6 @@ $ibo-activity-panel--body--placeholder-hint--color: $ibo-color-grey-800 !default /* Header */ .ibo-activity-panel--header{ position: relative; - padding-left: $ibo-activity-panel--header--padding-x; - padding-right: $ibo-activity-panel--header--padding-x; - @extend %ibo-fully-centered-content; - background-color: $ibo-activity-panel--header--background-color; /* Remove hyperlinks default color */ @@ -103,26 +102,38 @@ $ibo-activity-panel--body--placeholder-hint--color: $ibo-color-grey-800 !default color: $ibo-activity-panel--tab-toolbar--text-color; } } -.ibo-activity-panel--tabs{ +/* Size toggler */ +.ibo-activity-panel--size-toggler{ + position: absolute; + right: $ibo-activity-panel--padding-x; + top: 0; + bottom: 0; @extend %ibo-fully-centered-content; + color: $ibo-activity-panel--size-toggler--color; + + &:hover{ + color: $ibo-activity-panel--size-toggler--on-hover--color; + } } -/* Tab */ -.ibo-activity-panel--tab{ +/* Tabs togglers */ +.ibo-activity-panel--tabs-togglers{ + position: relative; /* For size toggler */ + padding-left: $ibo-activity-panel--tabs-togglers--padding-x; + padding-right: $ibo-activity-panel--tabs-togglers--padding-x; + @extend %ibo-fully-centered-content; +} +.ibo-activity-panel--tab-toggler{ &.ibo-is-active{ .ibo-activity-panel--tab-title{ background-color: $ibo-activity-panel--tab-title--is-active--background-color; } - .ibo-activity-panel--tab-toolbar{ - display: flex; - flex-wrap: wrap; - } } } /* - Specific decoration regarding the case log rank */ -@each $sColor in $ibo-activity-panel--tab--caselog-highlight-colors { - .ibo-activity-panel--tab-for-caselog-#{index($ibo-activity-panel--tab--caselog-highlight-colors, $sColor)}{ - .ibo-activity-panel--tab-decoration{ +@each $sColor in $ibo-activity-panel--tab-toggler--caselog-highlight-colors { + .ibo-activity-panel--tab-toggler-for-caselog-#{index($ibo-activity-panel--tab-toggler--caselog-highlight-colors, $sColor)}{ + .ibo-activity-panel--tab-title-decoration{ background-color: $sColor; } } @@ -137,95 +148,83 @@ $ibo-activity-panel--body--placeholder-hint--color: $ibo-color-grey-800 !default background-color: $ibo-activity-panel--tab-title--on-hover--background-color; } } -.ibo-activity-panel--tab-decoration{ +.ibo-activity-panel--tab-title-decoration{ display: inline-flex; - margin-right: $ibo-activity-panel--tab-decoration--margin-right; - width: $ibo-activity-panel--tab-decoration--width; - height: $ibo-activity-panel--tab-decoration--height; - border-radius: $ibo-activity-panel--tab-decoration--border-radius; + margin-right: $ibo-activity-panel--tab-title-decoration--margin-right; + width: $ibo-activity-panel--tab-title-decoration--width; + height: $ibo-activity-panel--tab-title-decoration--height; + border-radius: $ibo-activity-panel--tab-title-decoration--border-radius; @extend %ibo-depression-100; } -.ibo-activity-panel--tab-text{ - max-width: $ibo-activity-panel--tab-text--max-width; +.ibo-activity-panel--tab-title-text{ + max-width: $ibo-activity-panel--tab-title-text--max-width; @extend %ibo-text-truncated-with-ellipsis; } /* Tab toolbar */ .ibo-activity-panel--tab-toolbar{ display: none; - align-items: center; - position: absolute; - top: 100%; - left: 0; - right: 0; - height: $ibo-activity-panel--tab-toolbar--height; + flex-direction: column; padding-left: $ibo-activity-panel--tab-toolbar--padding-x; padding-right: $ibo-activity-panel--tab-toolbar--padding-x; background-color: $ibo-activity-panel--tab-toolbar--background-color; + + &.ibo-is-active{ + display: flex; + } } -.ibo-activity-panel--tab-left-actions, -.ibo-activity-panel--tab-right-actions{ +.ibo-activity-panel--tab-toolbar-actions{ + @extend %ibo-fully-centered-content; + flex-wrap: wrap; + height: $ibo-activity-panel--tab-toolbar-actions--height; +} +.ibo-activity-panel--tab-toolbar-left-actions, +.ibo-activity-panel--tab-toolbar-middle-actions, +.ibo-activity-panel--tab-toolbar-right-actions{ @extend %ibo-vertically-centered-content; } -.ibo-activity-panel--tab-middle-actions{ +.ibo-activity-panel--tab-toolbar-action{ @extend %ibo-fully-centered-content; } -.ibo-activity-panel--tab-action{ - @extend %ibo-baseline-centered-content; -} -.ibo-activity-panel--tab-for-caselog{ - .ibo-activity-panel--tab-toolbar{ +.ibo-activity-panel--tab-toolbar-for-caselog{ + .ibo-activity-panel--tab-toolbar-actions{ justify-content: space-between; - .ibo-activity-panel--tab-action{ + .ibo-activity-panel--tab-toolbar-action{ &:not(:first-child){ &::before{ - content: $ibo-activity-panel--tab-for-caselog--icons-separator-content; - margin: 0 $ibo-activity-panel--tab-for-caselog--icons-separator-margin-x; + content: $ibo-activity-panel--tab-toolbar-for-caselog--icons-separator-content; + margin: 0 $ibo-activity-panel--tab-toolbar-for-caselog--icons-separator-margin-x; } } } - .ibo-activity-panel--tab-info{ - > .ibo-activity-panel--tab-info-icon{ - margin-left: $ibo-activity-panel--tab-for-caselog--icon-margin-left; + .ibo-activity-panel--tab-toolbar-info{ + > .ibo-activity-panel--tab-toolbar-info-icon{ + margin-left: $ibo-activity-panel--tab-toolbar-for-caselog--icon-margin-left; } &:not(:first-child){ - margin-left: $ibo-activity-panel--tab-for-caselog--elements-spacing; + margin-left: $ibo-activity-panel--tab-toolbar-for-caselog--elements-spacing; } } } } -.ibo-activity-panel--tab-for-activity{ - .ibo-activity-panel--tab-toolbar{ +.ibo-activity-panel--tab-toolbar-for-activity{ + .ibo-activity-panel--tab-toolbar-actions{ justify-content: center; - .ibo-activity-panel--tab-action{ + .ibo-activity-panel--tab-toolbar-action{ > input{ - margin-right: $ibo-activity-panel--tab-for-activity---checkbox-margin-right; + margin-right: $ibo-activity-panel--tab-toolbar-for-activity--checkbox-margin-right; } &:not(:first-child){ - margin-left: $ibo-activity-panel--tab-for-activity--elements-spacing; + margin-left: $ibo-activity-panel--tab-toolbar-for-activity--elements-spacing; } } } } -/* Size toggler */ -.ibo-activity-panel--size-toggler{ - position: absolute; - right: $ibo-activity-panel--padding-x; - top: 0; - bottom: 0; - @extend %ibo-fully-centered-content; - color: $ibo-activity-panel--size-toggler--color; - - &:hover{ - color: $ibo-activity-panel--size-toggler--on-hover--color; - } -} - /* Body */ .ibo-activity-panel--body{ padding-top: $ibo-activity-panel--body--padding-top; diff --git a/css/backoffice/layout/activity-panel/_activity-new-entry-form.scss b/css/backoffice/layout/activity-panel/_caselog-entry-form.scss similarity index 75% rename from css/backoffice/layout/activity-panel/_activity-new-entry-form.scss rename to css/backoffice/layout/activity-panel/_caselog-entry-form.scss index bf1d31fd8..a0fabdc29 100644 --- a/css/backoffice/layout/activity-panel/_activity-new-entry-form.scss +++ b/css/backoffice/layout/activity-panel/_caselog-entry-form.scss @@ -3,14 +3,14 @@ * license http://opensource.org/licenses/AGPL-3.0 */ -$ibo-activity-new-entry-form--width: 100% !default; -$ibo-activity-new-entry-form--background-color: $ibo-activity-panel--tab-toolbar--background-color !default; -$ibo-activity-new-entry-form--padding: $ibo-activity-panel--tab-toolbar--height 14px 14px 14px !default; +$ibo-caselog-entry-form--width: 100% !default; +$ibo-caselog-entry-form--background-color: $ibo-activity-panel--tab-toolbar--background-color !default; -$ibo-activity-new-entry-form--actions--margin-top: 5px !default; +$ibo-caselog-entry-form--actions--margin-top: 6px !default; +$ibo-caselog-entry-form--actions--margin-bottom: 8px !default; $ibo-activity-panel--body--add-caselog-entry--toggler--right: 4px !default; -$ibo-activity-panel--body--add-caselog-entry--toggler--margin-top: calc(#{$ibo-activity-panel--tab-toolbar--height} + 4px) !default; +$ibo-activity-panel--body--add-caselog-entry--toggler--margin-top: calc(#{$ibo-activity-panel--tab-toolbar-actions--height} + 4px) !default; $ibo-activity-panel--body--add-caselog-entry--toggler--diameter: 36px !default; $ibo-activity-panel--body--add-caselog-entry--toggler--background-color: $ibo-color-primary-600 !default; $ibo-activity-panel--body--add-caselog-entry--toggler--color: $ibo-color-white-100 !default; @@ -21,24 +21,22 @@ $ibo-activity-panel--body--add-caselog-entry--toggler--icon--height: 100% !defau $ibo-activity-panel--body--add-caselog-entry--toggler--icon--width: $ibo-activity-panel--body--add-caselog-entry--toggler--icon--height !default; $ibo-activity-panel--body--add-caselog-entry--toggler--icon--font-size: 16px !default; $ibo-activity-panel--body--add-caselog-entry--toggler--icon--line-height: 33px !default; -.ibo-activity-new-entry-form{ - $ibo-activity-new-entry-form--width: 100%; - background-color: $ibo-activity-new-entry-form--background-color; - padding: $ibo-activity-new-entry-form--padding; - &.ibo-is-opened{ - display: block; - } +.ibo-caselog-entry-form{ + display: block; + width: 100%; + background-color: $ibo-caselog-entry-form--background-color; + &.ibo-is-closed{ display: none; } } -.ibo-activity-new-entry-form--actions{ +.ibo-caselog-entry-form--actions{ display: flex; justify-content: space-between; - margin-top: $ibo-activity-new-entry-form--actions--margin-top; + margin-top: $ibo-caselog-entry-form--actions--margin-top; + margin-bottom: $ibo-caselog-entry-form--actions--margin-bottom; } - .ibo-activity-panel--body--add-caselog-entry--toggler{ @extend %ibo-baseline-centered-content; position: absolute; @@ -67,6 +65,6 @@ $ibo-activity-panel--body--add-caselog-entry--toggler--icon--line-height: 33px ! display: none; } } -.ibo-activity-new-entry-form--action-buttons--right-actions > .ibo-popover-menu{ +.ibo-caselog-entry-form--action-buttons--right-actions > .ibo-popover-menu{ z-index: 1; } \ No newline at end of file diff --git a/dictionaries/en.dictionary.itop.ui.php b/dictionaries/en.dictionary.itop.ui.php index 58c61c314..fe460c08c 100644 --- a/dictionaries/en.dictionary.itop.ui.php +++ b/dictionaries/en.dictionary.itop.ui.php @@ -398,6 +398,9 @@ Dict::Add('EN US', 'English', 'English', array( 'UI:Button:Cancel' => 'Cancel', 'UI:Button:Close' => 'Close', 'UI:Button:Apply' => 'Apply', + 'UI:Button:Send' => 'Send', + 'UI:Button:AddEntryAndWithChoice' => 'Add entry and...', + 'UI:Button:AddEntryToWithChoice' => 'Add entry to...', 'UI:Button:Back' => ' << Back ', 'UI:Button:Restart' => ' |<< Restart ', 'UI:Button:Next' => ' Next >> ', diff --git a/js/layouts/activity-panel/activity-new-entry-form.js b/js/layouts/activity-panel/activity-new-entry-form.js deleted file mode 100644 index 3eb2f87af..000000000 --- a/js/layouts/activity-panel/activity-new-entry-form.js +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2013-2020 Combodo SARL - * - * 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 - */ - -; -$(function() { - $.widget('itop.activity_new_entry_form', - { - // default options - options: - { - target_caselog: null, - target_type: null, - text_input_id: '', - }, - css_classes: - { - is_opened: 'ibo-is-opened', - is_closed: 'ibo-is-closed', - is_hidden: 'ibo-is-hidden', - }, - js_selectors: - { - panel: '[data-role="ibo-activity-panel"]', - toggler: '[data-role="ibo-activity-panel--body--add-caselog-entry--toggler"]', - form: '[data-role="ibo-activity-new-entry-form"]', - right_actions: '[data-role="ibo-activity-new-entry-form--action-buttons--right-actions"]', - caselog_picker: '[data-role="ibo-popover-menu"]', - }, - - // the constructor - _create: function () { - let me = this; - me._HideNewEntryForm(); - $(this.element).find(this.js_selectors.caselog_picker).popover_menu({toggler: this.js_selectors.right_actions}); - $(this.js_selectors.toggler).on('click', function(oEvent){ - me._ShowNewEntryForm(); - }); - $(this.js_selectors.panel).on('show-caselog-tab', function(oEvent, sTabType, sCaseLogAttCode){ - me.options.target_type = sTabType; - if(sTabType === 'caselog') - { - me.options.target_caselog = sCaseLogAttCode; - } - }); - $(this.js_selectors.right_actions).on('submit', function(oEvent, sTargetType, sTargetCaseLog){ - sTargetType = (sTargetType !== undefined) ? sTargetType : me.options.target_type; - sTargetCaseLog = (sTargetCaseLog !== undefined) ? sTargetCaseLog : me.options.target_caselog; - if(sTargetType === 'caselog') - { - me._SubmitNewEntryToCaselog(CKEDITOR.instances[me.options.text_input_id].getData(), sTargetCaseLog) - } - else - { - $(this).children(me.js_selectors.caselog_picker).popover_menu('openPopup'); - } - }); - $(this.js_selectors.right_actions).on('cancel', function(oEvent){ - me._HideNewEntryForm(); - }); - }, - _ShowNewEntryForm: function () { - $(this.js_selectors.form).addClass(this.css_classes.is_opened).removeClass(this.css_classes.is_closed); - $(this.js_selectors.toggler).addClass(this.css_classes.is_hidden); - }, - _HideNewEntryForm: function () { - $(this.js_selectors.form).addClass(this.css_classes.is_closed).removeClass(this.css_classes.is_opened); - $(this.js_selectors.toggler).removeClass(this.css_classes.is_hidden); - //$(this).children(this.js_selectors.caselog_picker).popover_menu('closePopup'); - }, - _SubmitNewEntryToCaselog: function(sData, sCaselog) - { - const me = this; - let oParams = { - 'operation' : 'add_caselog_entry', - 'class' : $(me.js_selectors.panel).attr('data-object-class'), - 'id' : $(me.js_selectors.panel).attr('data-object-id'), - 'caselog_new_entry': sData, - 'caselog_attcode' : sCaselog, - 'caselog_rank' : $(me.js_selectors.panel).activity_panel('GetCaseLogRank', sCaselog), - } - //TODO 3.0.0 Handle errors - $.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', oParams, function(sNewEntry){ - $(me.js_selectors.panel).activity_panel('AddEntry', sNewEntry, 'caselog:' + sCaselog) - me._HideNewEntryForm(); - }); - } - }); -}); \ No newline at end of file diff --git a/js/layouts/activity-panel/activity-panel.js b/js/layouts/activity-panel/activity-panel.js index 1685730a9..eca754117 100644 --- a/js/layouts/activity-panel/activity-panel.js +++ b/js/layouts/activity-panel/activity-panel.js @@ -38,8 +38,9 @@ $(function() js_selectors: { panel_size_toggler: '[data-role="ibo-activity-panel--size-toggler"]', - tab: '[data-role="ibo-activity-panel--tab"]', + tab_toggler: '[data-role="ibo-activity-panel--tab-toggler"]', tab_title: '[data-role="ibo-activity-panel--tab-title"]', + tab_toolbar: '[data-role="ibo-activity-panel--tab-toolbar"]', activity_tab_filter: '[data-role="ibo-activity-panel--activity-filter"]', caselog_tab_open_all: '[data-role="ibo-activity-panel--caselog-open-all"]', caselog_tab_close_all: '[data-role="ibo-activity-panel--caselog-close-all"]', @@ -121,17 +122,25 @@ $(function() // Avoid anchor glitch oEvent.preventDefault(); - const oTabElem = oTabTitleElem.closest(this.js_selectors.tab); + const oTabTogglerElem = oTabTitleElem.closest(this.js_selectors.tab_toggler); + const sTabType = oTabTogglerElem.attr('data-tab-type'); - this.element.find(this.js_selectors.tab).removeClass(this.css_classes.is_active); - oTabElem.addClass(this.css_classes.is_active); + // Show tab toggler + this.element.find(this.js_selectors.tab_toggler).removeClass(this.css_classes.is_active); + oTabTogglerElem.addClass(this.css_classes.is_active); - if(oTabElem.attr('data-tab-type') === 'caselog') + // Show toolbar and entries + this.element.find(this.js_selectors.tab_toolbar).removeClass(this.css_classes.is_active); + if(sTabType === 'caselog') { - this._ShowCaseLogTab(oTabElem.attr('data-caselog-attribute-code')) + const sCaselogAttCode = oTabTogglerElem.attr('data-caselog-attribute-code'); + + this.element.find(this.js_selectors.tab_toolbar + '[data-tab-type="caselog"][data-caselog-attribute-code="' + sCaselogAttCode + '"]').addClass(this.css_classes.is_active); + this._ShowCaseLogTab(sCaselogAttCode); } else { + this.element.find(this.js_selectors.tab_toolbar + '[data-tab-type="activity"]').addClass(this.css_classes.is_active); this._ShowActivityTab(); } }, @@ -141,12 +150,12 @@ $(function() }, _onCaseLogOpenAllClick: function(oIconElem) { - const sCaseLogAttCode = oIconElem.closest(this.js_selectors.tab).attr('data-caselog-attribute-code'); + const sCaseLogAttCode = oIconElem.closest(this.js_selectors.tab_toggler).attr('data-caselog-attribute-code'); this._OpenAllMessages(sCaseLogAttCode); }, _onCaseLogCloseAllClick: function(oIconElem) { - const sCaseLogAttCode = oIconElem.closest(this.js_selectors.tab).attr('data-caselog-attribute-code'); + const sCaseLogAttCode = oIconElem.closest(this.js_selectors.tab_toggler).attr('data-caselog-attribute-code'); this._CloseAllMessages(sCaseLogAttCode); }, _onCaseLogClosedMessageClick: function(oEntryElem) @@ -170,6 +179,15 @@ $(function() }, // Methods + // - Helpers on host object + _GetHostObjectClass: function() + { + return this.element.attr('data-object-class'); + }, + _GetHostObjectID: function() + { + return this.element.attr('data-object-id'); + }, // - Helpers on dates /** * Reformat date times to be relative (only if they are not too far in the past) @@ -198,7 +216,6 @@ $(function() this._HideAllEntries(); this.element.find(this.js_selectors.entry+'[data-entry-caselog-attribute-code="'+sCaseLogAttCode+'"]').removeClass(this.css_classes.is_hidden); this._UpdateEntryGroupsVisibility(); - this.element.trigger('show-caselog-tab', ['caselog', sCaseLogAttCode]); }, _ShowActivityTab: function() { @@ -206,7 +223,6 @@ $(function() this._OpenAllMessages(); this._ShowAllEntries(); this._ApplyEntryFilters(); - this.element.trigger('show-caselog-tab', 'activity'); }, // - Helpers on messages _OpenMessage: function(oEntryElem) @@ -311,7 +327,7 @@ $(function() _GetCaseLogRank: function(sCaseLog) { let iIdx = 0; - let oCaselogTab = this.element.find(this.js_selectors.tab + + let oCaselogTab = this.element.find(this.js_selectors.tab_toggler + '[data-tab-type="caselog"]' + '[data-caselog-attribute-code="'+ sCaseLog +'"]' ); diff --git a/js/layouts/activity-panel/caselog-entry-form.js b/js/layouts/activity-panel/caselog-entry-form.js new file mode 100644 index 000000000..32896c2ea --- /dev/null +++ b/js/layouts/activity-panel/caselog-entry-form.js @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2013-2020 Combodo SARL + * + * 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 + */ + +; +$(function() { + $.widget('itop.caselog_entry_form', + { + // default options + options: + { + submit_mode: 'autonomous', + submit_button_disabled: true, + target_type: null, + text_input_id: '', + }, + css_classes: + { + is_opened: 'ibo-is-opened', + is_closed: 'ibo-is-closed', + is_hidden: 'ibo-is-hidden', + }, + js_selectors: + { + activity_panel: '[data-role="ibo-activity-panel"]', + activity_panel_toolbar: '[data-role="ibo-activity-panel--tab-toolbar"]', + form: '[data-role="ibo-caselog-entry-form"]', // Any caselog entry form + toggler: '[data-role="ibo-activity-panel--body--add-caselog-entry--toggler"]', + right_actions: '[data-role="ibo-caselog-entry-form--action-buttons--right-actions"]', + cancel_button: '[data-role="ibo-caselog-entry-form--action-buttons--right-actions"] [data-role="ibo-button"][name="cancel"]', + send_button: '[data-role="ibo-caselog-entry-form--action-buttons--right-actions"] [data-role="ibo-button"][name="send"]', + send_choices_picker: '[data-role="ibo-caselog-entry-form--action-buttons--right-actions"] [data-role="ibo-button"][name="send"] + [data-role="ibo-popover-menu"]', + }, + enums: + { + submit_mode: + { + autonomous: 'autonomous', + bridged: 'bridged', + }, + target_type: + { + caselog: 'caselog', + activity: 'activity', + } + }, + + // the constructor + _create: function () { + let me = this; + + this._UpdateSubmitButtonState(); + if(this._IsSubmitAutonomous()) + { + this._HideEntryForm(); + } + else + { + this._ShowEntryForm(); + } + + this._bindEvents(); + + // TODO 3.0.0: Modify PopoverMenu so we can pass it the ID of the block triggering the open/close + $(this.element).find(this.js_selectors.send_choices_picker).popover_menu({toggler: this.js_selectors.send_button}); + + }, + _bindEvents: function() { + let me = this; + + // Composer toggle + this.element.closest(this.js_selectors.activity_panel).find(this.js_selectors.toggler).on('click', function(oEvent){ + me._ShowEntryForm(); + }); + + // Enable send button only when content + CKEDITOR.on('instanceReady', function(oEvent){ + // Handle only the current CKEditor instance + if(oEvent.editor.name === me.options.text_input_id) { + CKEDITOR.instances[me.options.text_input_id].on('change', function(){ + me._UpdateSubmitButtonState(); + }); + } + }); + + // Form buttons + this.element.find(this.js_selectors.cancel_button).on('click', function(oEvent){ + me._HideEntryForm(); + }); + this.element.find(this.js_selectors.send_button).on('click', function(oEvent){ + // Avoid form being submitted + oEvent.preventDefault(); + + if(me.options.target_type === 'caselog') + { + let sCaselogAttCode = me.element.closest(me.js_selectors.activity_panel_toolbar).attr('data-caselog-attribute-code'); + me._SubmitEntryToCaselog(me._GetInputData(), sCaselogAttCode); + } + else + { + // TODO 3.0.0: Modify public methods of popover_menu to open/close to match other widgets naming conventions + me.element.find(me.js_selectors.send_choices_picker).popover_menu('openPopup'); + } + }); + + // Caselog selection + this.element.on('add_to_caselog.caselog_entry_form.itop', function(oEvent, oData){ + const sCaseLogAttCode = oData.caselog_att_code; + const sStimulusCode = oData.stimulus_code !== undefined ? oData.stimulus_code : null; + + me._SubmitEntryToCaselog(me._GetInputData(), sCaseLogAttCode, sStimulusCode); + }); + }, + _SubmitEntryToCaselog: function(sEntryContent, sCaselogAttCode, sStimulusCode = null){ + const me = this; + const sObjClass = this.element.closest(this.js_selectors.activity_panel).attr('data-object-class'); + const sObjId = this.element.closest(this.js_selectors.activity_panel).attr('data-object-id'); + + let oParams = { + 'operation' : 'add_caselog_entry', + 'class' : sObjClass, + 'id' : sObjId, + 'caselog_new_entry': sEntryContent, + 'caselog_attcode' : sCaselogAttCode, + 'caselog_rank' : this.element.closest(this.js_selectors.activity_panel).activity_panel('GetCaseLogRank', sCaselogAttCode), + } + //TODO 3.0.0 Handle errors + $.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', oParams, function(sNewEntry){ + me.element.closest(me.js_selectors.activity_panel).activity_panel('AddEntry', sNewEntry, 'caselog:' + sCaselogAttCode) + me._EmptyInput(); + me._HideEntryForm(); + + // Redirect to stimulus + if(sStimulusCode !== null){ + window.location.href = GetAbsoluteUrlAppRoot()+'pages/UI.php?operation=stimulus&class='+sObjClass+'&id='+sObjId+'&stimulus='+sStimulusCode; + } + }); + }, + + // Helpers + _IsSubmitAutonomous: function() { + return this.options.submit_mode === this.enums.submit_mode.autonomous; + }, + _ShowEntryForm: function () { + this.element.closest(this.js_selectors.activity_panel).find(this.js_selectors.form).removeClass(this.css_classes.is_closed); + this.element.closest(this.js_selectors.activity_panel).find(this.js_selectors.toggler).addClass(this.css_classes.is_hidden); + }, + _HideEntryForm: function () { + this.element.closest(this.js_selectors.activity_panel).find(this.js_selectors.form).addClass(this.css_classes.is_closed); + this.element.closest(this.js_selectors.activity_panel).find(this.js_selectors.toggler).removeClass(this.css_classes.is_hidden); + }, + _EmptyInput: function() { + CKEDITOR.instances[this.options.text_input_id].setData(''); + }, + _GetInputData: function() { + return (CKEDITOR.instances[this.options.text_input_id] === undefined) ? '' : CKEDITOR.instances[this.options.text_input_id].getData(); + }, + _UpdateSubmitButtonState: function(){ + const bIsInputEmpty = this._GetInputData() === ''; + + this.element.find(this.js_selectors.send_button).prop('disabled', bIsInputEmpty); + } + }); +}); \ No newline at end of file diff --git a/lib/composer/ClassLoader.php b/lib/composer/ClassLoader.php index 1a58957d2..fce8549f0 100644 --- a/lib/composer/ClassLoader.php +++ b/lib/composer/ClassLoader.php @@ -37,8 +37,8 @@ namespace Composer\Autoload; * * @author Fabien Potencier * @author Jordi Boggiano - * @see https://www.php-fig.org/psr/psr-0/ - * @see https://www.php-fig.org/psr/psr-4/ + * @see http://www.php-fig.org/psr/psr-0/ + * @see http://www.php-fig.org/psr/psr-4/ */ class ClassLoader { @@ -60,7 +60,7 @@ class ClassLoader public function getPrefixes() { if (!empty($this->prefixesPsr0)) { - return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); + return call_user_func_array('array_merge', $this->prefixesPsr0); } return array(); diff --git a/lib/composer/autoload_classmap.php b/lib/composer/autoload_classmap.php index fe751fb15..d147bc395 100644 --- a/lib/composer/autoload_classmap.php +++ b/lib/composer/autoload_classmap.php @@ -212,10 +212,10 @@ return array( 'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityEntry\\CaseLogEntry' => $baseDir . '/sources/application/UI/Layout/ActivityPanel/ActivityEntry/CaseLogEntry.php', 'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityEntry\\EditsEntry' => $baseDir . '/sources/application/UI/Layout/ActivityPanel/ActivityEntry/EditsEntry.php', 'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityEntry\\TransitionEntry' => $baseDir . '/sources/application/UI/Layout/ActivityPanel/ActivityEntry/TransitionEntry.php', - 'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityNewEntryFormFactory\\ActivityNewEntryFormFactory' => $baseDir . '/sources/application/UI/Layout/ActivityPanel/ActivityNewEntryForm/ActivityNewEntryFormFactory.php', - 'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityNewEntryForm\\ActivityNewEntryForm' => $baseDir . '/sources/application/UI/Layout/ActivityPanel/ActivityNewEntryForm/ActivityNewEntryForm.php', 'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityPanel' => $baseDir . '/sources/application/UI/Layout/ActivityPanel/ActivityPanel.php', 'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityPanelFactory' => $baseDir . '/sources/application/UI/Layout/ActivityPanel/ActivityPanelFactory.php', + 'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\CaseLogEntryFormFactory\\CaseLogEntryFormFactory' => $baseDir . '/sources/application/UI/Layout/ActivityPanel/CaseLogEntryForm/CaseLogEntryFormFactory.php', + 'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\CaseLogEntryForm\\CaseLogEntryForm' => $baseDir . '/sources/application/UI/Layout/ActivityPanel/CaseLogEntryForm/CaseLogEntryForm.php', 'Combodo\\iTop\\Application\\UI\\Layout\\Dashboard\\DashboardColumn' => $baseDir . '/sources/application/UI/Layout/Dashboard/DashboardColumn.php', 'Combodo\\iTop\\Application\\UI\\Layout\\Dashboard\\DashboardLayout' => $baseDir . '/sources/application/UI/Layout/Dashboard/DashboardLayout.php', 'Combodo\\iTop\\Application\\UI\\Layout\\Dashboard\\DashboardRow' => $baseDir . '/sources/application/UI/Layout/Dashboard/DashboardRow.php', @@ -294,7 +294,6 @@ return array( 'Combodo\\iTop\\Renderer\\RenderingOutput' => $baseDir . '/sources/Renderer/RenderingOutput.php', 'Combodo\\iTop\\TwigExtension' => $baseDir . '/application/twigextension.class.inc.php', 'CompileCSSService' => $baseDir . '/application/themehandler.class.inc.php', - 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', 'Config' => $baseDir . '/core/config.class.inc.php', 'ConfigException' => $baseDir . '/core/config.class.inc.php', 'ConfigPlaceholdersResolver' => $baseDir . '/core/config.class.inc.php', @@ -494,6 +493,7 @@ return array( 'PDFBulkExport' => $baseDir . '/core/pdfbulkexport.class.inc.php', 'PDFPage' => $baseDir . '/sources/application/WebPage/PDFPage.php', 'PEAR' => $vendorDir . '/pear/pear-core-minimal/src/PEAR.php', + 'PEAR_Error' => $vendorDir . '/pear/pear-core-minimal/src/PEAR.php', 'PEAR_ErrorStack' => $vendorDir . '/pear/pear-core-minimal/src/PEAR/ErrorStack.php', 'PEAR_Exception' => $vendorDir . '/pear/pear_exception/PEAR/Exception.php', 'PHP_LexerGenerator' => $baseDir . '/core/oql/build/PHP/LexerGenerator.php', @@ -1044,6 +1044,7 @@ return array( 'Symfony\\Component\\Cache\\Adapter\\TagAwareAdapter' => $vendorDir . '/symfony/cache/Adapter/TagAwareAdapter.php', 'Symfony\\Component\\Cache\\Adapter\\TagAwareAdapterInterface' => $vendorDir . '/symfony/cache/Adapter/TagAwareAdapterInterface.php', 'Symfony\\Component\\Cache\\Adapter\\TraceableAdapter' => $vendorDir . '/symfony/cache/Adapter/TraceableAdapter.php', + 'Symfony\\Component\\Cache\\Adapter\\TraceableAdapterEvent' => $vendorDir . '/symfony/cache/Adapter/TraceableAdapter.php', 'Symfony\\Component\\Cache\\Adapter\\TraceableTagAwareAdapter' => $vendorDir . '/symfony/cache/Adapter/TraceableTagAwareAdapter.php', 'Symfony\\Component\\Cache\\CacheItem' => $vendorDir . '/symfony/cache/CacheItem.php', 'Symfony\\Component\\Cache\\DataCollector\\CacheDataCollector' => $vendorDir . '/symfony/cache/DataCollector/CacheDataCollector.php', @@ -1066,6 +1067,7 @@ return array( 'Symfony\\Component\\Cache\\Simple\\Psr6Cache' => $vendorDir . '/symfony/cache/Simple/Psr6Cache.php', 'Symfony\\Component\\Cache\\Simple\\RedisCache' => $vendorDir . '/symfony/cache/Simple/RedisCache.php', 'Symfony\\Component\\Cache\\Simple\\TraceableCache' => $vendorDir . '/symfony/cache/Simple/TraceableCache.php', + 'Symfony\\Component\\Cache\\Simple\\TraceableCacheEvent' => $vendorDir . '/symfony/cache/Simple/TraceableCache.php', 'Symfony\\Component\\Cache\\Traits\\AbstractTrait' => $vendorDir . '/symfony/cache/Traits/AbstractTrait.php', 'Symfony\\Component\\Cache\\Traits\\ApcuTrait' => $vendorDir . '/symfony/cache/Traits/ApcuTrait.php', 'Symfony\\Component\\Cache\\Traits\\ArrayTrait' => $vendorDir . '/symfony/cache/Traits/ArrayTrait.php', @@ -1154,6 +1156,8 @@ return array( 'Symfony\\Component\\Config\\Resource\\FileResource' => $vendorDir . '/symfony/config/Resource/FileResource.php', 'Symfony\\Component\\Config\\Resource\\GlobResource' => $vendorDir . '/symfony/config/Resource/GlobResource.php', 'Symfony\\Component\\Config\\Resource\\ReflectionClassResource' => $vendorDir . '/symfony/config/Resource/ReflectionClassResource.php', + 'Symfony\\Component\\Config\\Resource\\ReflectionMethodHhvmWrapper' => $vendorDir . '/symfony/config/Resource/ReflectionClassResource.php', + 'Symfony\\Component\\Config\\Resource\\ReflectionParameterHhvmWrapper' => $vendorDir . '/symfony/config/Resource/ReflectionClassResource.php', 'Symfony\\Component\\Config\\Resource\\ResourceInterface' => $vendorDir . '/symfony/config/Resource/ResourceInterface.php', 'Symfony\\Component\\Config\\Resource\\SelfCheckingResourceChecker' => $vendorDir . '/symfony/config/Resource/SelfCheckingResourceChecker.php', 'Symfony\\Component\\Config\\Resource\\SelfCheckingResourceInterface' => $vendorDir . '/symfony/config/Resource/SelfCheckingResourceInterface.php', @@ -1330,6 +1334,8 @@ return array( 'Symfony\\Component\\DependencyInjection\\Compiler\\FactoryReturnTypePass' => $vendorDir . '/symfony/dependency-injection/Compiler/FactoryReturnTypePass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\InlineServiceDefinitionsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/InlineServiceDefinitionsPass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\LoggingFormatter' => $vendorDir . '/symfony/dependency-injection/Compiler/LoggingFormatter.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\MergeExtensionConfigurationContainerBuilder' => $vendorDir . '/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\MergeExtensionConfigurationParameterBag' => $vendorDir . '/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\MergeExtensionConfigurationPass' => $vendorDir . '/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\PassConfig' => $vendorDir . '/symfony/dependency-injection/Compiler/PassConfig.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\PriorityTaggedServiceTrait' => $vendorDir . '/symfony/dependency-injection/Compiler/PriorityTaggedServiceTrait.php', @@ -1439,6 +1445,7 @@ return array( 'Symfony\\Component\\DependencyInjection\\Loader\\GlobFileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/GlobFileLoader.php', 'Symfony\\Component\\DependencyInjection\\Loader\\IniFileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/IniFileLoader.php', 'Symfony\\Component\\DependencyInjection\\Loader\\PhpFileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/PhpFileLoader.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\ProtectedPhpFileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/PhpFileLoader.php', 'Symfony\\Component\\DependencyInjection\\Loader\\XmlFileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/XmlFileLoader.php', 'Symfony\\Component\\DependencyInjection\\Loader\\YamlFileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/YamlFileLoader.php', 'Symfony\\Component\\DependencyInjection\\Parameter' => $vendorDir . '/symfony/dependency-injection/Parameter.php', @@ -1462,6 +1469,7 @@ return array( 'Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcher' => $vendorDir . '/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php', 'Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcherInterface' => $vendorDir . '/symfony/event-dispatcher/Debug/TraceableEventDispatcherInterface.php', 'Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener' => $vendorDir . '/symfony/event-dispatcher/Debug/WrappedListener.php', + 'Symfony\\Component\\EventDispatcher\\DependencyInjection\\ExtractingEventDispatcher' => $vendorDir . '/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php', 'Symfony\\Component\\EventDispatcher\\DependencyInjection\\RegisterListenersPass' => $vendorDir . '/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php', 'Symfony\\Component\\EventDispatcher\\Event' => $vendorDir . '/symfony/event-dispatcher/Event.php', 'Symfony\\Component\\EventDispatcher\\EventDispatcher' => $vendorDir . '/symfony/event-dispatcher/EventDispatcher.php', @@ -1729,6 +1737,7 @@ return array( 'Symfony\\Component\\Routing\\Loader\\GlobFileLoader' => $vendorDir . '/symfony/routing/Loader/GlobFileLoader.php', 'Symfony\\Component\\Routing\\Loader\\ObjectRouteLoader' => $vendorDir . '/symfony/routing/Loader/ObjectRouteLoader.php', 'Symfony\\Component\\Routing\\Loader\\PhpFileLoader' => $vendorDir . '/symfony/routing/Loader/PhpFileLoader.php', + 'Symfony\\Component\\Routing\\Loader\\ProtectedPhpFileLoader' => $vendorDir . '/symfony/routing/Loader/PhpFileLoader.php', 'Symfony\\Component\\Routing\\Loader\\XmlFileLoader' => $vendorDir . '/symfony/routing/Loader/XmlFileLoader.php', 'Symfony\\Component\\Routing\\Loader\\YamlFileLoader' => $vendorDir . '/symfony/routing/Loader/YamlFileLoader.php', 'Symfony\\Component\\Routing\\Matcher\\Dumper\\DumperCollection' => $vendorDir . '/symfony/routing/Matcher/Dumper/DumperCollection.php', diff --git a/lib/composer/autoload_real.php b/lib/composer/autoload_real.php index 4f1c7e5ca..e8c595bf1 100644 --- a/lib/composer/autoload_real.php +++ b/lib/composer/autoload_real.php @@ -13,17 +13,12 @@ class ComposerAutoloaderInit0018331147de7601e7552f7da8e3bb8b } } - /** - * @return \Composer\Autoload\ClassLoader - */ public static function getLoader() { if (null !== self::$loader) { return self::$loader; } - require __DIR__ . '/platform_check.php'; - spl_autoload_register(array('ComposerAutoloaderInit0018331147de7601e7552f7da8e3bb8b', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); spl_autoload_unregister(array('ComposerAutoloaderInit0018331147de7601e7552f7da8e3bb8b', 'loadClassLoader')); @@ -34,7 +29,7 @@ class ComposerAutoloaderInit0018331147de7601e7552f7da8e3bb8b $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); if ($useStaticLoader) { - require __DIR__ . '/autoload_static.php'; + require_once __DIR__ . '/autoload_static.php'; call_user_func(\Composer\Autoload\ComposerStaticInit0018331147de7601e7552f7da8e3bb8b::getInitializer($loader)); } else { diff --git a/lib/composer/autoload_static.php b/lib/composer/autoload_static.php index 1e748c42c..092f016c6 100644 --- a/lib/composer/autoload_static.php +++ b/lib/composer/autoload_static.php @@ -442,10 +442,10 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b 'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityEntry\\CaseLogEntry' => __DIR__ . '/../..' . '/sources/application/UI/Layout/ActivityPanel/ActivityEntry/CaseLogEntry.php', 'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityEntry\\EditsEntry' => __DIR__ . '/../..' . '/sources/application/UI/Layout/ActivityPanel/ActivityEntry/EditsEntry.php', 'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityEntry\\TransitionEntry' => __DIR__ . '/../..' . '/sources/application/UI/Layout/ActivityPanel/ActivityEntry/TransitionEntry.php', - 'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityNewEntryFormFactory\\ActivityNewEntryFormFactory' => __DIR__ . '/../..' . '/sources/application/UI/Layout/ActivityPanel/ActivityNewEntryForm/ActivityNewEntryFormFactory.php', - 'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityNewEntryForm\\ActivityNewEntryForm' => __DIR__ . '/../..' . '/sources/application/UI/Layout/ActivityPanel/ActivityNewEntryForm/ActivityNewEntryForm.php', 'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityPanel' => __DIR__ . '/../..' . '/sources/application/UI/Layout/ActivityPanel/ActivityPanel.php', 'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityPanelFactory' => __DIR__ . '/../..' . '/sources/application/UI/Layout/ActivityPanel/ActivityPanelFactory.php', + 'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\CaseLogEntryFormFactory\\CaseLogEntryFormFactory' => __DIR__ . '/../..' . '/sources/application/UI/Layout/ActivityPanel/CaseLogEntryForm/CaseLogEntryFormFactory.php', + 'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\CaseLogEntryForm\\CaseLogEntryForm' => __DIR__ . '/../..' . '/sources/application/UI/Layout/ActivityPanel/CaseLogEntryForm/CaseLogEntryForm.php', 'Combodo\\iTop\\Application\\UI\\Layout\\Dashboard\\DashboardColumn' => __DIR__ . '/../..' . '/sources/application/UI/Layout/Dashboard/DashboardColumn.php', 'Combodo\\iTop\\Application\\UI\\Layout\\Dashboard\\DashboardLayout' => __DIR__ . '/../..' . '/sources/application/UI/Layout/Dashboard/DashboardLayout.php', 'Combodo\\iTop\\Application\\UI\\Layout\\Dashboard\\DashboardRow' => __DIR__ . '/../..' . '/sources/application/UI/Layout/Dashboard/DashboardRow.php', @@ -524,7 +524,6 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b 'Combodo\\iTop\\Renderer\\RenderingOutput' => __DIR__ . '/../..' . '/sources/Renderer/RenderingOutput.php', 'Combodo\\iTop\\TwigExtension' => __DIR__ . '/../..' . '/application/twigextension.class.inc.php', 'CompileCSSService' => __DIR__ . '/../..' . '/application/themehandler.class.inc.php', - 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', 'Config' => __DIR__ . '/../..' . '/core/config.class.inc.php', 'ConfigException' => __DIR__ . '/../..' . '/core/config.class.inc.php', 'ConfigPlaceholdersResolver' => __DIR__ . '/../..' . '/core/config.class.inc.php', @@ -724,6 +723,7 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b 'PDFBulkExport' => __DIR__ . '/../..' . '/core/pdfbulkexport.class.inc.php', 'PDFPage' => __DIR__ . '/../..' . '/sources/application/WebPage/PDFPage.php', 'PEAR' => __DIR__ . '/..' . '/pear/pear-core-minimal/src/PEAR.php', + 'PEAR_Error' => __DIR__ . '/..' . '/pear/pear-core-minimal/src/PEAR.php', 'PEAR_ErrorStack' => __DIR__ . '/..' . '/pear/pear-core-minimal/src/PEAR/ErrorStack.php', 'PEAR_Exception' => __DIR__ . '/..' . '/pear/pear_exception/PEAR/Exception.php', 'PHP_LexerGenerator' => __DIR__ . '/../..' . '/core/oql/build/PHP/LexerGenerator.php', @@ -1274,6 +1274,7 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b 'Symfony\\Component\\Cache\\Adapter\\TagAwareAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/TagAwareAdapter.php', 'Symfony\\Component\\Cache\\Adapter\\TagAwareAdapterInterface' => __DIR__ . '/..' . '/symfony/cache/Adapter/TagAwareAdapterInterface.php', 'Symfony\\Component\\Cache\\Adapter\\TraceableAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/TraceableAdapter.php', + 'Symfony\\Component\\Cache\\Adapter\\TraceableAdapterEvent' => __DIR__ . '/..' . '/symfony/cache/Adapter/TraceableAdapter.php', 'Symfony\\Component\\Cache\\Adapter\\TraceableTagAwareAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/TraceableTagAwareAdapter.php', 'Symfony\\Component\\Cache\\CacheItem' => __DIR__ . '/..' . '/symfony/cache/CacheItem.php', 'Symfony\\Component\\Cache\\DataCollector\\CacheDataCollector' => __DIR__ . '/..' . '/symfony/cache/DataCollector/CacheDataCollector.php', @@ -1296,6 +1297,7 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b 'Symfony\\Component\\Cache\\Simple\\Psr6Cache' => __DIR__ . '/..' . '/symfony/cache/Simple/Psr6Cache.php', 'Symfony\\Component\\Cache\\Simple\\RedisCache' => __DIR__ . '/..' . '/symfony/cache/Simple/RedisCache.php', 'Symfony\\Component\\Cache\\Simple\\TraceableCache' => __DIR__ . '/..' . '/symfony/cache/Simple/TraceableCache.php', + 'Symfony\\Component\\Cache\\Simple\\TraceableCacheEvent' => __DIR__ . '/..' . '/symfony/cache/Simple/TraceableCache.php', 'Symfony\\Component\\Cache\\Traits\\AbstractTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/AbstractTrait.php', 'Symfony\\Component\\Cache\\Traits\\ApcuTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/ApcuTrait.php', 'Symfony\\Component\\Cache\\Traits\\ArrayTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/ArrayTrait.php', @@ -1384,6 +1386,8 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b 'Symfony\\Component\\Config\\Resource\\FileResource' => __DIR__ . '/..' . '/symfony/config/Resource/FileResource.php', 'Symfony\\Component\\Config\\Resource\\GlobResource' => __DIR__ . '/..' . '/symfony/config/Resource/GlobResource.php', 'Symfony\\Component\\Config\\Resource\\ReflectionClassResource' => __DIR__ . '/..' . '/symfony/config/Resource/ReflectionClassResource.php', + 'Symfony\\Component\\Config\\Resource\\ReflectionMethodHhvmWrapper' => __DIR__ . '/..' . '/symfony/config/Resource/ReflectionClassResource.php', + 'Symfony\\Component\\Config\\Resource\\ReflectionParameterHhvmWrapper' => __DIR__ . '/..' . '/symfony/config/Resource/ReflectionClassResource.php', 'Symfony\\Component\\Config\\Resource\\ResourceInterface' => __DIR__ . '/..' . '/symfony/config/Resource/ResourceInterface.php', 'Symfony\\Component\\Config\\Resource\\SelfCheckingResourceChecker' => __DIR__ . '/..' . '/symfony/config/Resource/SelfCheckingResourceChecker.php', 'Symfony\\Component\\Config\\Resource\\SelfCheckingResourceInterface' => __DIR__ . '/..' . '/symfony/config/Resource/SelfCheckingResourceInterface.php', @@ -1560,6 +1564,8 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b 'Symfony\\Component\\DependencyInjection\\Compiler\\FactoryReturnTypePass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/FactoryReturnTypePass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\InlineServiceDefinitionsPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/InlineServiceDefinitionsPass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\LoggingFormatter' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/LoggingFormatter.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\MergeExtensionConfigurationContainerBuilder' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\MergeExtensionConfigurationParameterBag' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\MergeExtensionConfigurationPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\PassConfig' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/PassConfig.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\PriorityTaggedServiceTrait' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/PriorityTaggedServiceTrait.php', @@ -1669,6 +1675,7 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b 'Symfony\\Component\\DependencyInjection\\Loader\\GlobFileLoader' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/GlobFileLoader.php', 'Symfony\\Component\\DependencyInjection\\Loader\\IniFileLoader' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/IniFileLoader.php', 'Symfony\\Component\\DependencyInjection\\Loader\\PhpFileLoader' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/PhpFileLoader.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\ProtectedPhpFileLoader' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/PhpFileLoader.php', 'Symfony\\Component\\DependencyInjection\\Loader\\XmlFileLoader' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/XmlFileLoader.php', 'Symfony\\Component\\DependencyInjection\\Loader\\YamlFileLoader' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/YamlFileLoader.php', 'Symfony\\Component\\DependencyInjection\\Parameter' => __DIR__ . '/..' . '/symfony/dependency-injection/Parameter.php', @@ -1692,6 +1699,7 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b 'Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcher' => __DIR__ . '/..' . '/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php', 'Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcherInterface' => __DIR__ . '/..' . '/symfony/event-dispatcher/Debug/TraceableEventDispatcherInterface.php', 'Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener' => __DIR__ . '/..' . '/symfony/event-dispatcher/Debug/WrappedListener.php', + 'Symfony\\Component\\EventDispatcher\\DependencyInjection\\ExtractingEventDispatcher' => __DIR__ . '/..' . '/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php', 'Symfony\\Component\\EventDispatcher\\DependencyInjection\\RegisterListenersPass' => __DIR__ . '/..' . '/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php', 'Symfony\\Component\\EventDispatcher\\Event' => __DIR__ . '/..' . '/symfony/event-dispatcher/Event.php', 'Symfony\\Component\\EventDispatcher\\EventDispatcher' => __DIR__ . '/..' . '/symfony/event-dispatcher/EventDispatcher.php', @@ -1959,6 +1967,7 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b 'Symfony\\Component\\Routing\\Loader\\GlobFileLoader' => __DIR__ . '/..' . '/symfony/routing/Loader/GlobFileLoader.php', 'Symfony\\Component\\Routing\\Loader\\ObjectRouteLoader' => __DIR__ . '/..' . '/symfony/routing/Loader/ObjectRouteLoader.php', 'Symfony\\Component\\Routing\\Loader\\PhpFileLoader' => __DIR__ . '/..' . '/symfony/routing/Loader/PhpFileLoader.php', + 'Symfony\\Component\\Routing\\Loader\\ProtectedPhpFileLoader' => __DIR__ . '/..' . '/symfony/routing/Loader/PhpFileLoader.php', 'Symfony\\Component\\Routing\\Loader\\XmlFileLoader' => __DIR__ . '/..' . '/symfony/routing/Loader/XmlFileLoader.php', 'Symfony\\Component\\Routing\\Loader\\YamlFileLoader' => __DIR__ . '/..' . '/symfony/routing/Loader/YamlFileLoader.php', 'Symfony\\Component\\Routing\\Matcher\\Dumper\\DumperCollection' => __DIR__ . '/..' . '/symfony/routing/Matcher/Dumper/DumperCollection.php', diff --git a/pages/ajax.render.php b/pages/ajax.render.php index 01e3850dd..29d0081ed 100644 --- a/pages/ajax.render.php +++ b/pages/ajax.render.php @@ -2968,7 +2968,7 @@ EOF $sClass = utils::ReadPostedParam('class', '', 'class'); $sClassLabel = MetaModel::GetName($sClass); $id = utils::ReadPostedParam('id', ''); - // TODO 3.0.0 Handle transactions token + // TODO 3.0.0 Handle transactions token which is not passed yet $sTransactionId = utils::ReadPostedParam('transaction_id', '', 'transaction_id'); $sCaseLogAttCode = utils::ReadPostedParam('caselog_attcode', ''); $sCaseLogNewEntry = utils::ReadPostedParam('caselog_new_entry', '', 'raw'); diff --git a/sources/application/UI/Component/PopoverMenu/PopoverMenuFactory.php b/sources/application/UI/Component/PopoverMenu/PopoverMenuFactory.php index db5f18b94..b7025c7fa 100644 --- a/sources/application/UI/Component/PopoverMenu/PopoverMenuFactory.php +++ b/sources/application/UI/Component/PopoverMenu/PopoverMenuFactory.php @@ -244,27 +244,4 @@ class PopoverMenuFactory return $oMenu; } - public static function MakeMenuForActivityNewEntryFormSubmit(array $aCaseLogs): PopoverMenu - { - $oMenu = new PopoverMenu(); - $sMenuId = $oMenu->GetId(); - - $aItems = []; - foreach ($aCaseLogs as $sCaseLogAttCode => $sCaseLogLabel) { - // JS - $aItems[] = PopoverMenuItemFactory::MakeFromApplicationPopupMenuItem( - new JSPopupMenuItem( - $sCaseLogAttCode, - $sCaseLogLabel, - <<AddSection('ibo-activity-new-entry-new-entry--submit--caselogs') - ->SetItems('ibo-activity-new-entry-new-entry--submit--caselogs', $aItems); - - return $oMenu; - } } \ No newline at end of file diff --git a/sources/application/UI/Layout/ActivityPanel/ActivityNewEntryForm/ActivityNewEntryForm.php b/sources/application/UI/Layout/ActivityPanel/ActivityNewEntryForm/ActivityNewEntryForm.php deleted file mode 100644 index dee2a0042..000000000 --- a/sources/application/UI/Layout/ActivityPanel/ActivityNewEntryForm/ActivityNewEntryForm.php +++ /dev/null @@ -1,154 +0,0 @@ -aFormActionButtons = []; - $this->aTextInputActionButtons = []; - } - - - /** - * @return \Combodo\iTop\Application\UI\Component\Input\RichText\RichText - */ - public function GetFormTextInput(): \Combodo\iTop\Application\UI\Component\Input\RichText\RichText - { - return $this->oFormTextInput; - } - - /** - * @param \Combodo\iTop\Application\UI\Component\Input\RichText\RichText $oFormTextInput - * @return $this - */ - public function SetFormTextInput(\Combodo\iTop\Application\UI\Component\Input\RichText\RichText $oFormTextInput): ActivityNewEntryForm - { - $this->oFormTextInput = $oFormTextInput; - return $this; - } - - /** - * @return array - */ - public function GetTextInputActionButtons(): array - { - return $this->aTextInputActionButtons; - } - - /** - * @param array $aTextInputActionButtons - * @return $this - */ - public function SetTextInputActionButtons(array $aTextInputActionButtons): ActivityNewEntryForm - { - $this->aTextInputActionButtons = $aTextInputActionButtons; - return $this; - } - - /** - * @param \Combodo\iTop\Application\UI\UIBlock $oTextInputActionButtons - */ - public function AddTextInputActionButtons(UIBlock $oTextInputActionButtons): void - { - $this->aTextInputActionButtons[] = $oTextInputActionButtons; - } - - /** - * @return mixed - */ - public function GetFormActionButtons() - { - return $this->aFormActionButtons; - } - - /** - * @param array $aFormActionButtons - * @return $this - */ - public function SetFormActionButtons(array $aFormActionButtons): ActivityNewEntryForm - { - $this->aFormActionButtons = $aFormActionButtons; - return $this; - } - - /** - * @param UIBlock $oFormActionButtons - */ - public function AddFormActionButtons(UIBlock $oFormActionButtons): void - { - $this->aFormActionButtons[] = $oFormActionButtons; - } - - /** - * @return PopoverMenu - */ - public function GetCaseLogSelectionPopOverMenu(): PopoverMenu - { - return $this->oCaseLogSelectionPopOverMenu; - } - - /** - * @param PopoverMenu $oCaseLogSelectionPopOverMenu - * @return $this - */ - public function SetCaseLogSelectionPopOverMenu(PopoverMenu $oCaseLogSelectionPopOverMenu): ActivityNewEntryForm - { - $this->oCaseLogSelectionPopOverMenu = $oCaseLogSelectionPopOverMenu; - return $this; - } - - - public function GetSubBlocks() : array - { - $aSubBlocks = []; - $aSubBlocks[$this->GetFormTextInput()->GetId()] = $this->GetFormTextInput(); - foreach ($this->GetTextInputActionButtons() as $oTextInputActionButton) - { - $aSubBlocks[$oTextInputActionButton->GetId()] = $oTextInputActionButton; - } - foreach ($this->GetFormActionButtons() as $oFormActionButton) - { - $aSubBlocks[$oFormActionButton->GetId()] = $oFormActionButton; - } - $oCaseLogSelectionPopOverMenu = $this->GetCaseLogSelectionPopOverMenu(); - $aSubBlocks[$oCaseLogSelectionPopOverMenu->GetId()] = $oCaseLogSelectionPopOverMenu; - - return $aSubBlocks; - } - -} \ No newline at end of file diff --git a/sources/application/UI/Layout/ActivityPanel/ActivityNewEntryForm/ActivityNewEntryFormFactory.php b/sources/application/UI/Layout/ActivityPanel/ActivityNewEntryForm/ActivityNewEntryFormFactory.php deleted file mode 100644 index 46c0a5f41..000000000 --- a/sources/application/UI/Layout/ActivityPanel/ActivityNewEntryForm/ActivityNewEntryFormFactory.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @package Combodo\iTop\Application\UI\Layout\ActivityPanel\ActivityNewEntryFormFactory - * @since 3.0.0 - */ -class ActivityNewEntryFormFactory -{ - public static function MakeForObjectDetailsActivityPanel($aCaseLogs): ActivityNewEntryForm - { - $oActivityNewEntryForm = new ActivityNewEntryForm(); - $oActivityNewEntryForm->SetFormTextInput(new RichText()); - $oActivityNewEntryForm->AddFormActionButtons(ButtonFactory::MakeForSecondaryAction('Cancel') - ->SetOnClickJsCode("$(this).parents('[data-role=\"ibo-activity-new-entry-form--action-buttons--right-actions\"]').trigger('cancel');")); - $oActivityNewEntryForm->AddFormActionButtons(ButtonFactory::MakeForPrimaryAction('Send') - ->SetColor('cyan') - ->SetIconClass('fas fa-paper-plane') - ->SetOnClickJsCode("$(this).parents('[data-role=\"ibo-activity-new-entry-form--action-buttons--right-actions\"]').trigger('submit');")); - //$oActivityNewEntryForm->AddTextInputActionButtons(ButtonFactory::MakeForSecondaryAction('Templates')->SetColor('blue')); - - $oActivityNewEntryForm->SetCaseLogSelectionPopOverMenu(PopoverMenuFactory::MakeMenuForActivityNewEntryFormSubmit($aCaseLogs)); - - return $oActivityNewEntryForm; - } -} \ No newline at end of file diff --git a/sources/application/UI/Layout/ActivityPanel/ActivityPanel.php b/sources/application/UI/Layout/ActivityPanel/ActivityPanel.php index ade95ffef..670e7c015 100644 --- a/sources/application/UI/Layout/ActivityPanel/ActivityPanel.php +++ b/sources/application/UI/Layout/ActivityPanel/ActivityPanel.php @@ -26,7 +26,7 @@ use Combodo\iTop\Application\UI\Component\Button\ButtonFactory; use Combodo\iTop\Application\UI\Component\Input\RichText\RichText; use Combodo\iTop\Application\UI\Layout\ActivityPanel\ActivityEntry\ActivityEntry; use Combodo\iTop\Application\UI\Layout\ActivityPanel\ActivityEntry\CaseLogEntry; -use Combodo\iTop\Application\UI\Layout\ActivityPanel\ActivityNewEntryForm\ActivityNewEntryForm; +use Combodo\iTop\Application\UI\Layout\ActivityPanel\CaseLogEntryForm\CaseLogEntryForm; use Combodo\iTop\Application\UI\UIBlock; use DBObject; use Exception; @@ -65,8 +65,10 @@ class ActivityPanel extends UIBlock protected $bAreEntriesSorted; /** @var bool $bHasLifecycle True if the host object has a lifecycle */ protected $bHasLifecycle; - /** @var \Combodo\iTop\Application\UI\Layout\ActivityPanel\ActivityNewEntryForm\ActivityNewEntryForm $NewEntryForm */ - protected $oNewEntryForm; + /** @var \Combodo\iTop\Application\UI\Layout\ActivityPanel\CaseLogEntryForm\CaseLogEntryForm $oActivityTabEntryForm New entry form for the activity tab which is different from the case log tabs */ + protected $oActivityTabEntryForm; + /** @var \Combodo\iTop\Application\UI\Layout\ActivityPanel\CaseLogEntryForm\CaseLogEntryForm[] $aCaseLogTabsEntryForms */ + protected $aCaseLogTabsEntryForms; /** * ActivityPanel constructor. @@ -83,6 +85,7 @@ class ActivityPanel extends UIBlock parent::__construct($sId); $this->InitializeCaseLogTabs(); + $this->InitializeCaseLogTabsEntryForms(); $this->SetObject($oObject); $this->SetObjectMode(cmdbAbstractObject::DEFAULT_OBJECT_MODE); $this->SetEntries($aEntries); @@ -105,7 +108,9 @@ class ActivityPanel extends UIBlock // Initialize the case log tabs $this->InitializeCaseLogTabs(); - $aCaseLogAttCodes = MetaModel::GetAttributesList($sObjectClass, ['AttributeCaseLog']); + $this->InitializeCaseLogTabsEntryForms(); + + $aCaseLogAttCodes = MetaModel::GetCaseLogs($sObjectClass); foreach($aCaseLogAttCodes as $sCaseLogAttCode) { $this->AddCaseLogTab($sCaseLogAttCode); @@ -459,6 +464,67 @@ class ActivityPanel extends UIBlock return !empty($this->aCaseLogs); } + /** + * Empty the caselogs entry forms + * + * @return $this + */ + protected function InitializeCaseLogTabsEntryForms() + { + $this->aCaseLogTabsEntryForms = []; + return $this; + } + + /** + * Return all entry forms for all case log tabs + * + * @return \Combodo\iTop\Application\UI\Layout\ActivityPanel\CaseLogEntryForm\CaseLogEntryForm[] + */ + public function GetCaseLogTabsEntryForms(): array + { + return $this->aCaseLogTabsEntryForms; + } + + /** + * Set the $oCaseLogEntryForm for the $sCaseLogId tab. + * Note: If there is no caselog for that ID, it will proceed silently. + * + * @param string $sCaseLogId + * @param \Combodo\iTop\Application\UI\Layout\ActivityPanel\CaseLogEntryForm\CaseLogEntryForm $oCaseLogEntryForm + * + * @return $this + */ + public function SetCaseLogTabEntryForm(string $sCaseLogId, CaseLogEntryForm $oCaseLogEntryForm) + { + if ($this->HasCaseLogTab($sCaseLogId)){ + $this->aCaseLogTabsEntryForms[$sCaseLogId] = $oCaseLogEntryForm; + } + + return $this; + } + + /** + * Return the caselog entry form for the $sCaseLogId tab + * + * @param string $sCaseLogId + * + * @return \Combodo\iTop\Application\UI\Layout\ActivityPanel\CaseLogEntryForm\CaseLogEntryForm + */ + public function GetCaseLogTabEntryForm(string $sCaseLogId) + { + return $this->aCaseLogTabsEntryForms[$sCaseLogId]; + } + + /** + * @param string $sCaseLogId + * + * @return bool + */ + public function HasCaseLogTabEntryForm(string $sCaseLogId): bool + { + return !empty($this->aCaseLogTabsEntryForms[$sCaseLogId]); + } + /** * Return true if the host object has a lifecycle * @@ -480,31 +546,59 @@ class ActivityPanel extends UIBlock $oDateTimeFormat = AttributeDateTime::GetFormat(); return $oDateTimeFormat->ToMomentJS(); } - - public function GetNewEntryForm() + + /** + * Return the entry form for the activity tab + * + * @see $oActivityTabEntryForm + * @return \Combodo\iTop\Application\UI\Layout\ActivityPanel\CaseLogEntryForm\CaseLogEntryForm + */ + public function GetActivityTabEntryForm(): CaseLogEntryForm { - return $this->oNewEntryForm; - } - - public function SetNewEntryForm($oNewEntryForm) - { - $this->oNewEntryForm = $oNewEntryForm; - return $this; - } - - public function HasNewEntryForm() - { - return $this->oNewEntryForm !== null; + return $this->oActivityTabEntryForm; } + /** + * Set the entry form for the activity tab + * + * @param \Combodo\iTop\Application\UI\Layout\ActivityPanel\CaseLogEntryForm\CaseLogEntryForm $oCaseLogEntryForm + * @see $oActivityTabEntryForm + * + * @return $this + * + */ + public function SetActivityTabEntryForm(CaseLogEntryForm $oCaseLogEntryForm) + { + $this->oActivityTabEntryForm = $oCaseLogEntryForm; + return $this; + } + + /** + * Return true is there is an entry form for the activity tab + * + * @return bool + */ + public function HasActivityTabEntryForm() + { + return $this->oActivityTabEntryForm !== null; + } + + /** + * @inheritdoc + */ public function GetSubBlocks() { $aSubBlocks = array(); - if ($this->HasNewEntryForm()) - { - $oNewEntryForm = $this->GetNewEntryForm(); + + foreach($this->GetCaseLogTabsEntryForms() as $sCaseLogId => $oCaseLogEntryForm) { + $aSubBlocks[$oCaseLogEntryForm->GetId()] = $oCaseLogEntryForm; + } + + if ($this->HasActivityTabEntryForm()) { + $oNewEntryForm = $this->GetActivityTabEntryForm(); $aSubBlocks[$oNewEntryForm->GetId()] = $oNewEntryForm; } + return $aSubBlocks; } } \ No newline at end of file diff --git a/sources/application/UI/Layout/ActivityPanel/ActivityPanelFactory.php b/sources/application/UI/Layout/ActivityPanel/ActivityPanelFactory.php index 7e8cdede7..a3e89adc3 100644 --- a/sources/application/UI/Layout/ActivityPanel/ActivityPanelFactory.php +++ b/sources/application/UI/Layout/ActivityPanel/ActivityPanelFactory.php @@ -24,7 +24,7 @@ use cmdbAbstractObject; use CMDBChangeOpSetAttributeCaseLog; use Combodo\iTop\Application\UI\Layout\ActivityPanel\ActivityEntry\ActivityEntryFactory; use Combodo\iTop\Application\UI\Layout\ActivityPanel\ActivityEntry\EditsEntry; -use Combodo\iTop\Application\UI\Layout\ActivityPanel\ActivityNewEntryFormFactory\ActivityNewEntryFormFactory; +use Combodo\iTop\Application\UI\Layout\ActivityPanel\CaseLogEntryFormFactory\CaseLogEntryFormFactory; use DBObject; use DBObjectSearch; use DBObjectSet; @@ -65,10 +65,14 @@ class ActivityPanelFactory $oActivityPanel = new ActivityPanel($oObject); $oActivityPanel->SetObjectMode($sMode); - // Retrieve case logs entries + // Prepare caselogs $aCaseLogAttCodes = array_keys($oActivityPanel->GetCaseLogTabs()); foreach($aCaseLogAttCodes as $sCaseLogAttCode) { + // Add new entry block + $oActivityPanel->SetCaseLogTabEntryForm($sCaseLogAttCode, CaseLogEntryFormFactory::MakeForCaselogTab($oObject, $sCaseLogAttCode, $sMode)); + + // Retrieve case logs entries /** @var \ormCaseLog $oCaseLog */ $oCaseLog = $oObject->Get($sCaseLogAttCode); foreach($oCaseLog->GetAsArray() as $aOrmEntry) @@ -78,16 +82,13 @@ class ActivityPanelFactory } } - if($oActivityPanel->HasCaseLogTabs()) - { - //TODO 3.0.0 check write rights - $aCaseLogsForNewEntryForm = []; - foreach ($aCaseLogAttCodes as $sCaseLogAttCode){ - $aCaseLogsForNewEntryForm[$sCaseLogAttCode] = MetaModel::GetLabel($sObjClass, $sCaseLogAttCode); - } - - $oActivityPanel->SetNewEntryForm(ActivityNewEntryFormFactory::MakeForObjectDetailsActivityPanel($aCaseLogsForNewEntryForm)); + //TODO 3.0.0: Check write rights + if($oActivityPanel->HasCaseLogTabs()) { + + } + $oActivityPanel->SetActivityTabEntryForm(CaseLogEntryFormFactory::MakeForActivityTab($oObject, $sMode)); + // Retrieve history changes (including case logs entries) // - Prepare query to retrieve changes $oChangesSearch = DBObjectSearch::FromOQL('SELECT CMDBChangeOp WHERE objclass = :obj_class AND objkey = :obj_key'); diff --git a/sources/application/UI/Layout/ActivityPanel/CaseLogEntryForm/CaseLogEntryForm.php b/sources/application/UI/Layout/ActivityPanel/CaseLogEntryForm/CaseLogEntryForm.php new file mode 100644 index 000000000..4aab9c873 --- /dev/null +++ b/sources/application/UI/Layout/ActivityPanel/CaseLogEntryForm/CaseLogEntryForm.php @@ -0,0 +1,297 @@ +sSubmitMode = static::DEFAULT_SUBMIT_MODE; + $this->sContainerTabType = static::DEFAULT_CONTAINER_TAB_TYPE; + $this->SetTextInput(new RichText()); + $this->aMainActionButtons = []; + $this->aExtraActionButtons = []; + } + + /** + * @see $sSubmitMode + * + * @return string + */ + public function GetSubmitMode(): string + { + return $this->sSubmitMode; + } + + /** + * @param string $sSubmitMode + * @see $sSubmitMode + * + * @return $this + */ + public function SetSubmitMode(string $sSubmitMode) + { + $this->sSubmitMode = $sSubmitMode; + return $this; + } + + /** + * Set the submit mode (autonomous, bridged) from the host object mode (create, edit, view, ...) + * eg. create => bridged, view => autonomous. + * + * @param string $sObjectMode + * @see $sSubmitMode + * @see cmdbAbstractObject::ENUM_OBJECT_MODE_XXX + * + * @return $this + */ + public function SetSubmitModeFromHostObjectMode($sObjectMode) + { + switch ($sObjectMode){ + case cmdbAbstractObject::ENUM_OBJECT_MODE_CREATE: + case cmdbAbstractObject::ENUM_OBJECT_MODE_EDIT: + $sSubmitMode = static::ENUM_SUBMIT_MODE_BRIDGED; + break; + + case cmdbAbstractObject::ENUM_OBJECT_MODE_VIEW: + case cmdbAbstractObject::ENUM_OBJECT_MODE_STIMULUS: + default: + $sSubmitMode = static::ENUM_SUBMIT_MODE_AUTONOMOUS; + break; + } + + $this->SetSubmitMode($sSubmitMode); + return $this; + } + + /** + * Return true if the submit mode is autonomous + * + * @see $sSubmitMode + * + * @return bool + */ + public function IsSubmitAutonomous(): bool + { + return $this->GetSubmitMode() === static::ENUM_SUBMIT_MODE_AUTONOMOUS; + } + + /** + * @see $sContainerTabType + * + * @return string + */ + public function GetContainerTabType(): string + { + return $this->sContainerTabType; + } + + /** + * @param string $sContainerTabType + * @see $sContainerTabType + * + * @return $this + */ + public function SetContainerTabType(string $sContainerTabType) + { + $this->sContainerTabType = $sContainerTabType; + return $this; + } + + /** + * @return \Combodo\iTop\Application\UI\Component\Input\RichText\RichText + */ + public function GetTextInput(): RichText + { + return $this->oTextInput; + } + + /** + * @param \Combodo\iTop\Application\UI\Component\Input\RichText\RichText $oTextInput + * + * @return $this + */ + public function SetTextInput(RichText $oTextInput) + { + $this->oTextInput = $oTextInput; + return $this; + } + + /** + * @return \Combodo\iTop\Application\UI\UIBlock[] + */ + public function GetMainActionButtons() + { + return $this->aMainActionButtons; + } + + /** + * Set all main action buttons at once, replacing all existing ones + * + * @param array $aFormActionButtons + * @return $this + */ + public function SetMainActionButtons(array $aFormActionButtons) + { + $this->aMainActionButtons = $aFormActionButtons; + return $this; + } + + /** + * @param \Combodo\iTop\Application\UI\UIBlock $oMainActionButton + * @return $this; + */ + public function AddMainActionButtons(UIBlock $oMainActionButton) + { + $this->aMainActionButtons[] = $oMainActionButton; + return $this; + } + + /** + * @return \Combodo\iTop\Application\UI\UIBlock[] + */ + public function GetExtraActionButtons() + { + return $this->aExtraActionButtons; + } + + /** + * Set all extra action buttons at once, replacing all existing ones + * + * @param array $aExtraActionButtons + * @see $aExtraActionButtons + * + * @return $this + */ + public function SetExtraActionButtons(array $aExtraActionButtons) + { + $this->aExtraActionButtons = $aExtraActionButtons; + return $this; + } + + /** + * @param \Combodo\iTop\Application\UI\UIBlock $oExtraActionButton + * + * @return $this; + * @see $aExtraActionButtons + * + */ + public function AddExtraActionButtons(UIBlock $oExtraActionButton) + { + $this->aExtraActionButtons[] = $oExtraActionButton; + return $this; + } + + /** + * @return \Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenu + */ + public function GetSendButtonPopoverMenu(): PopoverMenu + { + return $this->oSendButtonPopoverMenu; + } + + /** + * @param \Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenu $oCaseLogSelectionPopOverMenu + * @return $this + */ + public function SetSendButtonPopoverMenu(PopoverMenu $oCaseLogSelectionPopOverMenu) + { + $this->oSendButtonPopoverMenu = $oCaseLogSelectionPopOverMenu; + return $this; + } + + /** + * Return true is there is a PopoverMenu for the send button + * + * @return bool + */ + public function HasSendButtonPopoverMenu(): bool + { + return $this->oSendButtonPopoverMenu !== null; + } + + /** + * @inheritdoc + */ + public function GetSubBlocks(): array + { + $aSubBlocks = []; + $aSubBlocks[$this->GetTextInput()->GetId()] = $this->GetTextInput(); + + foreach ($this->GetExtraActionButtons() as $oExtraActionButton) + { + $aSubBlocks[$oExtraActionButton->GetId()] = $oExtraActionButton; + } + + foreach ($this->GetMainActionButtons() as $oMainActionButton) + { + $aSubBlocks[$oMainActionButton->GetId()] = $oMainActionButton; + } + + $aSubBlocks[$this->GetSendButtonPopoverMenu()->GetId()] = $this->GetSendButtonPopoverMenu(); + + return $aSubBlocks; + } + +} \ No newline at end of file diff --git a/sources/application/UI/Layout/ActivityPanel/CaseLogEntryForm/CaseLogEntryFormFactory.php b/sources/application/UI/Layout/ActivityPanel/CaseLogEntryForm/CaseLogEntryFormFactory.php new file mode 100644 index 000000000..f7503d633 --- /dev/null +++ b/sources/application/UI/Layout/ActivityPanel/CaseLogEntryForm/CaseLogEntryFormFactory.php @@ -0,0 +1,164 @@ + + * @author Guillaume Lajarige + * @package Combodo\iTop\Application\UI\Layout\ActivityPanel\CaseLogEntryFormFactory + * @since 3.0.0 + */ +class CaseLogEntryFormFactory +{ + public static function MakeForCaselogTab(DBObject $oObject, string $sCaseLogAttCode, string $sObjectMode = cmdbAbstractObject::DEFAULT_OBJECT_MODE) + { + $oCaseLogEntryForm = new CaseLogEntryForm(); + $oCaseLogEntryForm->SetSubmitModeFromHostObjectMode($sObjectMode) + ->AddMainActionButtons(static::PrepareCancelButton()) + ->AddMainActionButtons(static::PrepareSendButton()->SetLabel(Dict::S('UI:Button:AddEntryAndWithChoice'))) + ->SetSendButtonPopoverMenu(static::PrepareSendActionSelectionPopoverMenu($oObject, $sCaseLogAttCode)); + + return $oCaseLogEntryForm; + } + + public static function MakeForActivityTab(DBObject $oObject, string $sObjectMode = cmdbAbstractObject::DEFAULT_OBJECT_MODE) + { + $oCaseLogEntryForm = new CaseLogEntryForm(); + $oCaseLogEntryForm->SetSubmitModeFromHostObjectMode($sObjectMode) + ->AddMainActionButtons(static::PrepareCancelButton()) + ->AddMainActionButtons(static::PrepareSendButton()->SetLabel(Dict::S('UI:Button:AddEntryToWithChoice'))); + + $oCaseLogEntryForm->SetSendButtonPopoverMenu(static::PrepareTargetCaseLogSelectionPopoverMenu($oObject)); + + return $oCaseLogEntryForm; + } + + /** + * @return \Combodo\iTop\Application\UI\Component\Button\Button + */ + protected static function PrepareCancelButton(): Button + { + return ButtonFactory::MakeForSecondaryAction(Dict::S('UI:Button:Cancel'), 'cancel', 'cancel'); + } + + /** + * @return \Combodo\iTop\Application\UI\Component\Button\Button + */ + protected static function PrepareSendButton(): Button + { + $oButton = ButtonFactory::MakeForPrimaryAction(Dict::S('UI:Button:Send'), 'send', 'send'); + $oButton->SetIconClass('fas fa-paper-plane'); + + return $oButton; + } + + protected static function PrepareSendActionSelectionPopoverMenu(DBObject $oObject, string $sCaseLogAttCode): PopoverMenu + { + $sObjClass = get_class($oObject); + + $oMenu = new PopoverMenu(); + $sSectionId = 'send-actions'; + $oMenu->AddSection($sSectionId); + + $sCaseLogEntryFormDataRole = CaseLogEntryForm::BLOCK_CODE; + + // Standard, just save + $oMenuItem = PopoverMenuItemFactory::MakeFromApplicationPopupMenuItem( + new JSPopupMenuItem( + CaseLogEntryForm::BLOCK_CODE.'--add-action--'.$sCaseLogAttCode.'--save', + Dict::S('UI:Button:Save'), + <<AddItem($sSectionId, $oMenuItem); + + // Transitions + // Note: This code is inspired from cmdbAbstract::DisplayModifyForm(), it might be better to factorize it + $aTransitions = $oObject->EnumTransitions(); + if (!isset($aExtraParams['custom_operation']) && count($aTransitions)) { + $oSetToCheckRights = DBObjectSet::FromObject($oObject); + $aStimuli = Metamodel::EnumStimuli($sObjClass); + foreach ($aTransitions as $sStimulusCode => $aTransitionDef) { + $iActionAllowed = (get_class($aStimuli[$sStimulusCode]) == 'StimulusUserAction') ? UserRights::IsStimulusAllowed($sObjClass, + $sStimulusCode, $oSetToCheckRights) : UR_ALLOWED_NO; + switch ($iActionAllowed) { + case UR_ALLOWED_YES: + $oMenuItem = PopoverMenuItemFactory::MakeFromApplicationPopupMenuItem( + new JSPopupMenuItem( + CaseLogEntryForm::BLOCK_CODE.'--add-action--'.$sCaseLogAttCode.'--stimulus--'.$sStimulusCode, + $aStimuli[$sStimulusCode]->GetLabel(), + <<AddItem($sSectionId, $oMenuItem); + break; + } + } + } + + + return $oMenu; + } + + /** + * Return a PopoverMenu with the list of the caselog attributes of $oObject + * + * @param \DBObject $oObject + * + * @return \Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenu + * @throws \CoreException + * @throws \Exception + */ + protected static function PrepareTargetCaseLogSelectionPopoverMenu(DBObject $oObject): PopoverMenu + { + $sObjClass = get_class($oObject); + + $oMenu = new PopoverMenu(); + $sSectionId = 'target-caselogs'; + $oMenu->AddSection($sSectionId); + + $sCaseLogEntryFormDataRole = CaseLogEntryForm::BLOCK_CODE; + + foreach(MetaModel::GetCaseLogs($sObjClass) as $sCaseLogAttCode) { + $oMenuItem = PopoverMenuItemFactory::MakeFromApplicationPopupMenuItem( + new JSPopupMenuItem( + CaseLogEntryForm::BLOCK_CODE.'--target-caselog--'.$sCaseLogAttCode, + MetaModel::GetLabel($sObjClass, $sCaseLogAttCode), + <<AddItem($sSectionId, $oMenuItem); + } + + return $oMenu; + } +} \ No newline at end of file diff --git a/templates/layouts/activity-panel/activitynewentryform/layout.html.twig b/templates/layouts/activity-panel/activitynewentryform/layout.html.twig deleted file mode 100644 index 5868fc759..000000000 --- a/templates/layouts/activity-panel/activitynewentryform/layout.html.twig +++ /dev/null @@ -1,18 +0,0 @@ -
-
- {{ render_block(oUIBlock.GetFormTextInput(), {aPage: aPage}) }} -
-
-
- {% for TextInputActionButton in oUIBlock.GetTextInputActionButtons() %} - {{ render_block(TextInputActionButton, {aPage: aPage}) }} - {% endfor %} -
-
- {% for FormActionButton in oUIBlock.GetFormActionButtons() %} - {{ render_block(FormActionButton, {aPage: aPage}) }} - {% endfor %} - {{ render_block(oUIBlock.GetCaseLogSelectionPopOverMenu(), {aPage: aPage}) }} -
-
-
\ No newline at end of file diff --git a/templates/layouts/activity-panel/activitynewentryform/layout.js.twig b/templates/layouts/activity-panel/activitynewentryform/layout.js.twig deleted file mode 100644 index 18b486aa5..000000000 --- a/templates/layouts/activity-panel/activitynewentryform/layout.js.twig +++ /dev/null @@ -1 +0,0 @@ -$('#{{ oUIBlock.GetId() }}').activity_new_entry_form({target_tab: 'activity', text_input_id: '{{ oUIBlock.GetFormTextInput().GetId()}}' }); \ No newline at end of file diff --git a/templates/layouts/activity-panel/caselog-entry-form/layout.html.twig b/templates/layouts/activity-panel/caselog-entry-form/layout.html.twig new file mode 100644 index 000000000..a0bbda57e --- /dev/null +++ b/templates/layouts/activity-panel/caselog-entry-form/layout.html.twig @@ -0,0 +1,23 @@ +
+
+ {{ render_block(oUIBlock.GetTextInput(), {aPage: aPage}) }} +
+
+
+ {% for TextInputActionButton in oUIBlock.GetExtraActionButtons() %} + {{ render_block(TextInputActionButton, {aPage: aPage}) }} + {% endfor %} +
+
+ {% for FormActionButton in oUIBlock.GetMainActionButtons() %} + {{ render_block(FormActionButton, {aPage: aPage}) }} + {% endfor %} + {{ render_block(oUIBlock.GetSendButtonPopoverMenu(), {aPage: aPage}) }} +
+
+
\ No newline at end of file diff --git a/templates/layouts/activity-panel/caselog-entry-form/layout.js.twig b/templates/layouts/activity-panel/caselog-entry-form/layout.js.twig new file mode 100644 index 000000000..8173eb6f9 --- /dev/null +++ b/templates/layouts/activity-panel/caselog-entry-form/layout.js.twig @@ -0,0 +1,4 @@ +$('#{{ oUIBlock.GetId() }}').caselog_entry_form({ + target_tab: '{{ oUIBlocl.GetContainerTabType }}', + text_input_id: '{{ oUIBlock.GetTextInput().GetId()}}' +}); \ No newline at end of file diff --git a/templates/layouts/activity-panel/layout.html.twig b/templates/layouts/activity-panel/layout.html.twig index 0e9cbc049..f518124f1 100644 --- a/templates/layouts/activity-panel/layout.html.twig +++ b/templates/layouts/activity-panel/layout.html.twig @@ -1,79 +1,98 @@
-
+
{% for sCaseLogAttCode, aCaseLogData in oUIBlock.GetCaseLogTabs() %} -
+
- - {{ aCaseLogData.title }} + + {{ aCaseLogData.title }} - +
+ {% for sCaseLogAttCode, aCaseLogData in oUIBlock.GetCaseLogTabs() %} +
+
+ -
- - {{ aCaseLogData.authors|length }} - +
+ + {{ aCaseLogData.authors|length }} + - - {{ aCaseLogData.total_messages_count }} - + + {{ aCaseLogData.total_messages_count }} +
+ {% if oUIBlock.HasCaseLogTabEntryForm(sCaseLogAttCode) %} +
+ {{ render_block(oUIBlock.GetCaseLogTabEntryForm(sCaseLogAttCode)) }} +
+ {% endif %}
{% endfor %} -
- - {{ 'UI:Layout:ActivityPanel:Tab:Activity:Title'|dict_s }} - -
-
+
+
+
{% if oUIBlock.HasCaseLogTabs() %} - {% endif %} {% if oUIBlock.HasLifecycle() %} - {% endif %} -
+ {% if oUIBlock.HasActivityTabEntryForm() %} +
+ {{ render_block(oUIBlock.GetActivityTabEntryForm()) }} +
+ {% endif %}
-
- {% if oUIBlock.HasNewEntryForm() %} - {{ render_block(oUIBlock.GetNewEntryForm()) }} - + {% if oUIBlock.HasActivityTabEntryForm() %} + {% if oUIBlock.GetActivityTabEntryForm().IsSubmitAutonomous() %} + + {% endif %} {% endif %}
{% if oUIBlock.GetGroupedEntries()|length > 0 %}