N°2847 - ActivityPanel: Rework for new UX

- Add MetaModel::GetCaseLogs($sClass) function
- Rename ActivityNewEntryForm to CaseLogEntryForm
- Rework ActivityPanel and CaseLogEntryForm markup / CSS
- Change for 1 CaseLogEntryForm per tab (caselogs and activity) with specific "Add entry..." choices
This commit is contained in:
Molkobain
2020-11-20 16:11:43 +01:00
parent 1e7d4e5c31
commit 7d0f1f46d3
25 changed files with 1027 additions and 537 deletions

View File

@@ -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();

View File

@@ -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";

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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 >> ',

View File

@@ -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();
});
}
});
});

View File

@@ -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 +'"]'
);

View File

@@ -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);
}
});
});

View File

@@ -37,8 +37,8 @@ namespace Composer\Autoload;
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be>
* @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();

View File

@@ -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',

View File

@@ -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 {

View File

@@ -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',

View File

@@ -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');

View File

@@ -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,
<<<JS
$(this).parents('[data-role="ibo-activity-new-entry-form--action-buttons--right-actions"]').trigger('submit', ['caselog', '$sCaseLogAttCode']);
JS
));
}
$oMenu->AddSection('ibo-activity-new-entry-new-entry--submit--caselogs')
->SetItems('ibo-activity-new-entry-new-entry--submit--caselogs', $aItems);
return $oMenu;
}
}

View File

@@ -1,154 +0,0 @@
<?php
/**
* @copyright Copyright (C) 2010-2020 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\Application\UI\Layout\ActivityPanel\ActivityNewEntryForm;
use Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenu;
use Combodo\iTop\Application\UI\Layout\UIContentBlock;
use Combodo\iTop\Application\UI\UIBlock;
/**
* Class ActivityNewEntryForm
*
* @package Combodo\iTop\Application\UI\Layout\ActivityPanel\ActivityNewEntryForm
*/
class ActivityNewEntryForm extends UIContentBlock
{
// Overloaded constants
public const BLOCK_CODE = 'ibo-activitynewentryform';
public const HTML_TEMPLATE_REL_PATH = 'layouts/activity-panel/activitynewentryform/layout';
public const JS_TEMPLATE_REL_PATH = 'layouts/activity-panel/activitynewentryform/layout';
public const JS_FILES_REL_PATH = [
'js/layouts/activity-panel/activity-new-entry-form.js',
];
/** @var \Combodo\iTop\Application\UI\Component\Input\RichText\RichText $oFormTextInput */
protected $oFormTextInput;
/** @var \Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenu */
protected $oCaseLogSelectionPopOverMenu;
/** @var array $aTextInputActionButtons */
protected $aTextInputActionButtons;
/** @var array $aFormActionButtons */
protected $aFormActionButtons;
/**
* ActivityNewEntryForm constructor.
*
* @param null $sName
*/
public function __construct($sName = null)
{
parent::__construct($sName);
$this->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;
}
}

View File

@@ -1,42 +0,0 @@
<?php
/**
* @copyright Copyright (C) 2010-2020 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\Application\UI\Layout\ActivityPanel\ActivityNewEntryFormFactory;
use Combodo\iTop\Application\UI\Component\Button\ButtonFactory;
use Combodo\iTop\Application\UI\Component\Input\RichText\RichText;
use Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenuFactory;
use Combodo\iTop\Application\UI\Layout\ActivityPanel\ActivityNewEntryForm\ActivityNewEntryForm;
/**
* Class ActivityNewEntryFormFactory
*
* @internal
* @author Stephen Abello <stephen.abello@combodo.com>
* @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;
}
}

View File

@@ -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;
}
}

View File

@@ -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');

View File

@@ -0,0 +1,297 @@
<?php
/*
* @copyright Copyright (C) 2010-2020 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\Application\UI\Layout\ActivityPanel\CaseLogEntryForm;
use cmdbAbstractObject;
use Combodo\iTop\Application\UI\Component\Input\RichText\RichText;
use Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenu;
use Combodo\iTop\Application\UI\Layout\UIContentBlock;
use Combodo\iTop\Application\UI\UIBlock;
/**
* Class CaseLogEntryForm
*
* @package Combodo\iTop\Application\UI\Layout\ActivityPanel\CaseLogEntryForm
*/
class CaseLogEntryForm extends UIContentBlock
{
// Overloaded constants
public const BLOCK_CODE = 'ibo-caselog-entry-form';
public const HTML_TEMPLATE_REL_PATH = 'layouts/activity-panel/caselog-entry-form/layout';
public const JS_TEMPLATE_REL_PATH = 'layouts/activity-panel/caselog-entry-form/layout';
public const JS_FILES_REL_PATH = [
'js/layouts/activity-panel/caselog-entry-form.js',
];
/** @var string Form is autonomous and can send data on its own */
public const ENUM_SUBMIT_MODE_AUTONOMOUS = 'autonomous';
/** @var string Form is bridged to its host object form */
public const ENUM_SUBMIT_MODE_BRIDGED = 'bridged';
/** @var string Container of the form is a specific caselog tab */
public const ENUM_CONTAINER_TAB_TYPE_CASELOG = 'caselog';
/** @var string Container of the form is the activity tab */
public const ENUM_CONTAINER_TAB_TYPE_ACTIVITY = 'activity';
/** @var string */
public const DEFAULT_SUBMIT_MODE = self::ENUM_SUBMIT_MODE_AUTONOMOUS;
/** @var string */
public const DEFAULT_CONTAINER_TAB_TYPE = self::ENUM_CONTAINER_TAB_TYPE_ACTIVITY;
/**
* @var string Whether the form can send data on its own or if it's bridged with its host object form
* @see static::ENUM_SUBMIT_MODE_XXX
*/
protected $sSubmitMode;
/**
* @var string Whether the form container is a caselog tab or an activity tab
* @see static::ENUM_CONTAINER_TAB_TYPE_XXX
*/
protected $sContainerTabType;
/** @var \Combodo\iTop\Application\UI\Component\Input\RichText\RichText $oTextInput The main input to write a case log entry */
protected $oTextInput;
/** @var \Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenu Menu for possible options on the send button */
protected $oSendButtonPopoverMenu;
/** @var array $aMainActionButtons The form main actions (send, cancel, ...) */
protected $aMainActionButtons;
/** @var array $aExtraActionButtons The form extra actions, can be populated through a public API */
protected $aExtraActionButtons;
/**
* CaseLogEntryForm constructor.
*
* @param null $sName
*/
public function __construct($sName = null)
{
parent::__construct($sName);
$this->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;
}
}

View File

@@ -0,0 +1,164 @@
<?php
/*
* @copyright Copyright (C) 2010-2020 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\Application\UI\Layout\ActivityPanel\CaseLogEntryFormFactory;
use cmdbAbstractObject;
use Combodo\iTop\Application\UI\Component\Button\Button;
use Combodo\iTop\Application\UI\Component\Button\ButtonFactory;
use Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenu;
use Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenuItem\PopoverMenuItemFactory;
use Combodo\iTop\Application\UI\Layout\ActivityPanel\CaseLogEntryForm\CaseLogEntryForm;
use DBObject;
use DBObjectSet;
use Dict;
use MetaModel;
use JSPopupMenuItem;
use UserRights;
/**
* Class CaseLogEntryFormFactory
*
* @internal
* @author Stephen Abello <stephen.abello@combodo.com>
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
* @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'),
<<<JS
$(this).closest('[data-role="{$sCaseLogEntryFormDataRole}"]').trigger('add_to_caselog.caselog_entry_form.itop', {caselog_att_code: '{$sCaseLogAttCode}'});
JS
)
);
$oMenu->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(),
<<<JS
$(this).closest('[data-role="{$sCaseLogEntryFormDataRole}"]').trigger('add_to_caselog.caselog_entry_form.itop', {caselog_att_code: '{$sCaseLogAttCode}', stimulus_code: '{$sStimulusCode}'});
JS
)
);
$oMenu->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),
<<<JS
$(this).closest('[data-role="{$sCaseLogEntryFormDataRole}"]').trigger('add_to_caselog.caselog_entry_form.itop', {caselog_att_code: '{$sCaseLogAttCode}'});
JS
)
);
$oMenu->AddItem($sSectionId, $oMenuItem);
}
return $oMenu;
}
}

View File

@@ -1,18 +0,0 @@
<div id="{{ oUIBlock.GetId() }}" class="ibo-activity-new-entry-form ibo-is-closed" data-role="ibo-activity-new-entry-form">
<div class="ibo-activity-new-entry-form--text-input" data-role="ibo-activity-new-entry-form--text-input">
{{ render_block(oUIBlock.GetFormTextInput(), {aPage: aPage}) }}
</div>
<div class="ibo-activity-new-entry-form--actions">
<div class="ibo-activity-new-entry-form--action-buttons--left-actions">
{% for TextInputActionButton in oUIBlock.GetTextInputActionButtons() %}
{{ render_block(TextInputActionButton, {aPage: aPage}) }}
{% endfor %}
</div>
<div class="ibo-activity-new-entry-form--action-buttons--right-actions" data-role="ibo-activity-new-entry-form--action-buttons--right-actions">
{% for FormActionButton in oUIBlock.GetFormActionButtons() %}
{{ render_block(FormActionButton, {aPage: aPage}) }}
{% endfor %}
{{ render_block(oUIBlock.GetCaseLogSelectionPopOverMenu(), {aPage: aPage}) }}
</div>
</div>
</div>

View File

@@ -1 +0,0 @@
$('#{{ oUIBlock.GetId() }}').activity_new_entry_form({target_tab: 'activity', text_input_id: '{{ oUIBlock.GetFormTextInput().GetId()}}' });

View File

@@ -0,0 +1,23 @@
<form id="{{ oUIBlock.GetId() }}"
class="ibo-caselog-entry-form {% if oUIBlock.IsSubmitAutonomous %}ibo-is-closed{% endif %}"
data-role="ibo-caselog-entry-form"
data-submit-mode="{{ oUIBlock.GetSubmitMode() }}"
data-container-tab-type="{{ oUIBlock.GetContainerTabType() }}"
method="post">
<div class="ibo-caselog-entry-form--text-input" data-role="ibo-caselog-entry-form--text-input">
{{ render_block(oUIBlock.GetTextInput(), {aPage: aPage}) }}
</div>
<div class="ibo-caselog-entry-form--actions">
<div class="ibo-caselog-entry-form--action-buttons--left-actions" data-role="ibo-caselog-entry-form--action-buttons--left-actions">
{% for TextInputActionButton in oUIBlock.GetExtraActionButtons() %}
{{ render_block(TextInputActionButton, {aPage: aPage}) }}
{% endfor %}
</div>
<div class="ibo-caselog-entry-form--action-buttons--right-actions" data-role="ibo-caselog-entry-form--action-buttons--right-actions">
{% for FormActionButton in oUIBlock.GetMainActionButtons() %}
{{ render_block(FormActionButton, {aPage: aPage}) }}
{% endfor %}
{{ render_block(oUIBlock.GetSendButtonPopoverMenu(), {aPage: aPage}) }}
</div>
</div>
</form>

View File

@@ -0,0 +1,4 @@
$('#{{ oUIBlock.GetId() }}').caselog_entry_form({
target_tab: '{{ oUIBlocl.GetContainerTabType }}',
text_input_id: '{{ oUIBlock.GetTextInput().GetId()}}'
});

View File

@@ -1,79 +1,98 @@
<div id="{{ oUIBlock.GetId() }}" class="ibo-activity-panel" data-role="ibo-activity-panel" data-object-class="{{ oUIBlock.GetObjectClass() }}" data-object-id="{{ oUIBlock.GetObjectId() }}" data-object-mode="{{ oUIBlock.GetObjectMode() }}">
<div class="ibo-activity-panel--header">
<div class="ibo-activity-panel--tabs">
<div class="ibo-activity-panel--tabs-togglers">
{% for sCaseLogAttCode, aCaseLogData in oUIBlock.GetCaseLogTabs() %}
<div class="ibo-activity-panel--tab ibo-activity-panel--tab-for-caselog ibo-activity-panel--tab-for-caselog-{{ loop.index }}" data-role="ibo-activity-panel--tab" data-tab-type="caselog" data-caselog-attribute-code="{{ sCaseLogAttCode }}" data-caselog-rank="{{ loop.index }}">
<div class="ibo-activity-panel--tab-toggler ibo-activity-panel--tab-toggler-for-caselog ibo-activity-panel--tab-toggler-for-caselog-{{ loop.index }}" data-role="ibo-activity-panel--tab-toggler" data-tab-type="caselog" data-caselog-attribute-code="{{ sCaseLogAttCode }}" data-caselog-rank="{{ loop.index }}">
<a href="#" class="ibo-activity-panel--tab-title" data-role="ibo-activity-panel--tab-title">
<span class="ibo-activity-panel--tab-decoration"></span>
<span class="ibo-activity-panel--tab-text">{{ aCaseLogData.title }}</span>
<span class="ibo-activity-panel--tab-title-decoration"></span>
<span class="ibo-activity-panel--tab-title-text" title="{{ aCaseLogData.title }}">{{ aCaseLogData.title }}</span>
</a>
<div class="ibo-activity-panel--tab-toolbar">
<div class="ibo-activity-panel--tab-left-actions">
<a href="#" class="ibo-activity-panel--tab-action ibo-activity-panel--tab-action-open-all" data-role="ibo-activity-panel--caselog-open-all" data-tooltip-content="{{ 'UI:Layout:ActivityPanel:Tab:Caselog:Toolbar:OpenAll:Tooltip'|dict_s }}">
</div>
{% endfor %}
<div class="ibo-activity-panel--tab-toggler ibo-activity-panel--tab-toggler-for-activity ibo-is-active" data-role="ibo-activity-panel--tab-toggler" data-tab-type="activity">
<a href="#" class="ibo-activity-panel--tab-title" data-role="ibo-activity-panel--tab-title">
<span class="ibo-activity-panel--tab-title-text" title="{{ 'UI:Layout:ActivityPanel:Tab:Activity:Title'|dict_s }}">{{ 'UI:Layout:ActivityPanel:Tab:Activity:Title'|dict_s }}</span>
</a>
</div>
<div class="ibo-activity-panel--size-toggler" data-role="ibo-activity-panel--size-toggler">
<a href="#" class="ibo-activity-panel--expand-icon"
data-role="ibo-activity-panel--expand-icon"
data-tooltip-content="{{ 'UI:Layout:ActivityPanel:SizeToggler:Expand:Tooltip'|dict_s }}">
<span class="fas fa-fw fa-expand-alt"></span>
</a>
<a href="#" class="ibo-activity-panel--collapse-icon"
data-role="ibo-activity-panel--collapse-icon"
data-tooltip-content="{{ 'UI:Layout:ActivityPanel:SizeToggler:Collapse:Tooltip'|dict_s }}">
<span class="fas fa-fw fa-compress-alt"></span>
</a>
</div>
</div>
<div class="ibo-activity-panel--tabs-toolbars">
{% for sCaseLogAttCode, aCaseLogData in oUIBlock.GetCaseLogTabs() %}
<div class="ibo-activity-panel--tab-toolbar ibo-activity-panel--tab-toolbar-for-caselog ibo-activity-panel--tab-toolbar-for-caselog-{{ loop.index }}" data-role="ibo-activity-panel--tab-toolbar" data-tab-type="caselog" data-caselog-attribute-code="{{ sCaseLogAttCode }}" data-caselog-rank="{{ loop.index }}">
<div class="ibo-activity-panel--tab-toolbar-actions">
<div class="ibo-activity-panel--tab-toolbar-left-actions">
<a href="#" class="ibo-activity-panel--tab-toolbar-action ibo-activity-panel--tab-toolbar-action-open-all" data-role="ibo-activity-panel--caselog-open-all" data-tooltip-content="{{ 'UI:Layout:ActivityPanel:Tab:Caselog:Toolbar:OpenAll:Tooltip'|dict_s }}">
<span class="fas fa-book-open"></span>
</a>
<a href="#" class="ibo-activity-panel--tab-action ibo-activity-panel--tab-action-close-all" data-role="ibo-activity-panel--caselog-close-all" data-tooltip-content="{{ 'UI:Layout:ActivityPanel:Tab:Caselog:Toolbar:CloseAll:Tooltip'|dict_s }}">
<a href="#" class="ibo-activity-panel--tab-toolbar-action ibo-activity-panel--tab-toolbar-action-close-all" data-role="ibo-activity-panel--caselog-close-all" data-tooltip-content="{{ 'UI:Layout:ActivityPanel:Tab:Caselog:Toolbar:CloseAll:Tooltip'|dict_s }}">
<span class="fas fa-book"></span>
</a>
</div>
<div class="ibo-activity-panel--tab-right-actions">
<span class="ibo-activity-panel--tab-info ibo-activity-panel--tab-info-authors-count" data-tooltip-content="{{ 'UI:Layout:ActivityPanel:Tab:Caselog:Toolbar:AuthorsCount:Tooltip'|dict_s }}">
<span class="ibo-activity-panel--tab-info-text">{{ aCaseLogData.authors|length }}</span>
<span class="ibo-activity-panel--tab-info-icon fas fa-users"></span>
<div class="ibo-activity-panel--tab-toolbar-right-actions">
<span class="ibo-activity-panel--tab-toolbar-info ibo-activity-panel--tab-toolbar-info-authors-count" data-tooltip-content="{{ 'UI:Layout:ActivityPanel:Tab:Caselog:Toolbar:AuthorsCount:Tooltip'|dict_s }}">
<span class="ibo-activity-panel--tab-toolbar-info-text">{{ aCaseLogData.authors|length }}</span>
<span class="ibo-activity-panel--tab-toolbar-info-icon fas fa-users"></span>
</span>
<span class="ibo-activity-panel--tab-info ibo-activity-panel--tab-info-messages-count" data-tooltip-content="{{ 'UI:Layout:ActivityPanel:Tab:Caselog:Toolbar:MessagesCount:Tooltip'|dict_s }}">
<span class="ibo-activity-panel--tab-info-text">{{ aCaseLogData.total_messages_count }}</span>
<span class="ibo-activity-panel--tab-info-icon fas fa-comment-alt"></span>
<span class="ibo-activity-panel--tab-toolbar-info ibo-activity-panel--tab-toolbar-info-messages-count" data-tooltip-content="{{ 'UI:Layout:ActivityPanel:Tab:Caselog:Toolbar:MessagesCount:Tooltip'|dict_s }}">
<span class="ibo-activity-panel--tab-toolbar-info-text">{{ aCaseLogData.total_messages_count }}</span>
<span class="ibo-activity-panel--tab-toolbar-info-icon fas fa-comment-alt"></span>
</span>
</div>
</div>
{% if oUIBlock.HasCaseLogTabEntryForm(sCaseLogAttCode) %}
<div class="ibo-activity-panel--tab-toggler-entry-form" data-role="ibo-activity-panel--tab-toggler-entry-form">
{{ render_block(oUIBlock.GetCaseLogTabEntryForm(sCaseLogAttCode)) }}
</div>
{% endif %}
</div>
{% endfor %}
<div class="ibo-activity-panel--tab ibo-activity-panel--tab-for-activity ibo-is-active" data-role="ibo-activity-panel--tab" data-tab-type="activity">
<a href="#" class="ibo-activity-panel--tab-title" data-role="ibo-activity-panel--tab-title">
<span class="ibo-activity-panel--tab-text">{{ 'UI:Layout:ActivityPanel:Tab:Activity:Title'|dict_s }}</span>
</a>
<div class="ibo-activity-panel--tab-toolbar">
<div class="ibo-activity-panel--tab-middle-actions">
<div class="ibo-activity-panel--tab-toolbar ibo-activity-panel--tab-toolbar-for-activity ibo-is-active" data-role="ibo-activity-panel--tab-toolbar" data-tab-type="activity">
<div class="ibo-activity-panel--tab-toolbar-actions">
<div class="ibo-activity-panel--tab-toolbar-middle-actions">
{% if oUIBlock.HasCaseLogTabs() %}
<label class="ibo-activity-panel--tab-action"
<label class="ibo-activity-panel--tab-toolbar-action"
data-tooltip-content="{{ 'UI:Layout:ActivityPanel:Tab:Activity:Toolbar:CaselogsFilter:Tooltip'|dict_s }}">
<input type="checkbox" name="caselogs" data-role="ibo-activity-panel--activity-filter" data-target-entry-types="caselog" checked />
{{ 'UI:Layout:ActivityPanel:Tab:Activity:Toolbar:CaselogsFilter:Title'|dict_s }}
</label>
{% endif %}
{% if oUIBlock.HasLifecycle() %}
<label class="ibo-activity-panel--tab-action"
<label class="ibo-activity-panel--tab-toolbar-action"
data-tooltip-content="{{ 'UI:Layout:ActivityPanel:Tab:Activity:Toolbar:TransitionsFilter:Tooltip'|dict_s }}">
<input type="checkbox" name="transitions" data-role="ibo-activity-panel--activity-filter" data-target-entry-types="transition" checked />
{{ 'UI:Layout:ActivityPanel:Tab:Activity:Toolbar:TransitionsFilter:Title'|dict_s }}
</label>
{% endif %}
<label class="ibo-activity-panel--tab-action"
<label class="ibo-activity-panel--tab-toolbar-action"
data-tooltip-content="{{ 'UI:Layout:ActivityPanel:Tab:Activity:Toolbar:EditsFilter:Tooltip'|dict_s }}">
<input type="checkbox" name="edits" data-role="ibo-activity-panel--activity-filter" data-target-entry-types="edits" checked />
{{ 'UI:Layout:ActivityPanel:Tab:Activity:Toolbar:EditsFilter:Title'|dict_s }}
</label>
</div>
</div>
{% if oUIBlock.HasActivityTabEntryForm() %}
<div class="ibo-activity-panel--tab-toggler-entry-form" data-role="ibo-activity-panel--tab-toggler-entry-form">
{{ render_block(oUIBlock.GetActivityTabEntryForm()) }}
</div>
{% endif %}
</div>
</div>
<div class="ibo-activity-panel--size-toggler" data-role="ibo-activity-panel--size-toggler">
<a href="#" class="ibo-activity-panel--expand-icon"
data-role="ibo-activity-panel--expand-icon"
data-tooltip-content="{{ 'UI:Layout:ActivityPanel:SizeToggler:Expand:Tooltip'|dict_s }}">
<span class="fas fa-fw fa-expand-alt"></span>
</a>
<a href="#" class="ibo-activity-panel--collapse-icon"
data-role="ibo-activity-panel--collapse-icon"
data-tooltip-content="{{ 'UI:Layout:ActivityPanel:SizeToggler:Collapse:Tooltip'|dict_s }}">
<span class="fas fa-fw fa-compress-alt"></span>
</a>
</div>
</div>
{% if oUIBlock.HasNewEntryForm() %}
{{ render_block(oUIBlock.GetNewEntryForm()) }}
<a href="#" class="ibo-activity-panel--body--add-caselog-entry--toggler" data-role="ibo-activity-panel--body--add-caselog-entry--toggler"><i class="fas fa-feather"></i></a>
{% if oUIBlock.HasActivityTabEntryForm() %}
{% if oUIBlock.GetActivityTabEntryForm().IsSubmitAutonomous() %}
<a href="#" class="ibo-activity-panel--body--add-caselog-entry--toggler" data-role="ibo-activity-panel--body--add-caselog-entry--toggler"><i class="fas fa-feather"></i></a>
{% endif %}
{% endif %}
<div class="ibo-activity-panel--body">
{% if oUIBlock.GetGroupedEntries()|length > 0 %}