mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
N°3649 - Activity panel: Continue improvement following the alpha feedbacks
- Change caselog entry form, now 1 per caselog - Remove entry form from activity tab - Change entries filters, now present on all tabs but states are specific to each tab
This commit is contained in:
@@ -45,6 +45,8 @@ $(function()
|
||||
activity_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"]',
|
||||
compose_button: '[data-role="ibo-activity-panel--add-caselog-entry-button"]',
|
||||
caselog_entry_form: '[data-role="ibo-caselog-entry-form"]',
|
||||
entry_group: '[data-role="ibo-activity-panel--entry-group"]',
|
||||
entry: '[data-role="ibo-activity-entry"]',
|
||||
entry_medallion: '[data-role="ibo-activity-entry--medallion"]',
|
||||
@@ -53,6 +55,12 @@ $(function()
|
||||
edits_entry_long_description: '[data-role="ibo-edits-entry--long-description"]',
|
||||
edits_entry_long_description_toggler: '[data-role="ibo-edits-entry--long-description-toggler"]',
|
||||
},
|
||||
enums: {
|
||||
tab_types: {
|
||||
caselog: 'caselog',
|
||||
activity: 'activity',
|
||||
}
|
||||
},
|
||||
|
||||
// the constructor
|
||||
_create: function()
|
||||
@@ -60,6 +68,9 @@ $(function()
|
||||
this.element.addClass('ibo-activity-panel');
|
||||
this._bindEvents();
|
||||
this._ReformatDateTimes();
|
||||
|
||||
// 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});
|
||||
},
|
||||
// events bound via _bind are removed automatically
|
||||
// revert other modifications here
|
||||
@@ -72,33 +83,47 @@ $(function()
|
||||
const me = this;
|
||||
const oBodyElem = $('body');
|
||||
|
||||
// Click on the panel collapse/expand toggler
|
||||
// Tabs title
|
||||
// - Click on the panel collapse/expand toggler
|
||||
this.element.find(this.js_selectors.panel_size_toggler).on('click', function(oEvent){
|
||||
me._onPanelSizeTogglerClick(oEvent);
|
||||
});
|
||||
// Click on a tab title
|
||||
// - Click on a tab title
|
||||
this.element.find(this.js_selectors.tab_title).on('click', function(oEvent){
|
||||
me._onTabTitleClick(oEvent, $(this));
|
||||
});
|
||||
|
||||
// Change on an activity filter
|
||||
// Tabs toolbar
|
||||
// - Change on an activity filter
|
||||
this.element.find(this.js_selectors.activity_filter).on('change', function(){
|
||||
me._onActivityFilterChange($(this));
|
||||
});
|
||||
// Click on open all case log messages
|
||||
// - Click on open all case log messages
|
||||
this.element.find(this.js_selectors.caselog_tab_open_all).on('click', function(){
|
||||
me._onCaseLogOpenAllClick($(this));
|
||||
});
|
||||
// Click on close all case log messages
|
||||
// - Click on close all case log messages
|
||||
this.element.find(this.js_selectors.caselog_tab_close_all).on('click', function(){
|
||||
me._onCaseLogCloseAllClick($(this));
|
||||
});
|
||||
|
||||
// Click on a closed case log message
|
||||
// Entry form
|
||||
// - Click on the compose button
|
||||
this.element.find(this.js_selectors.compose_button).on('click', function(oEvent){
|
||||
me._onComposeButtonClick(oEvent);
|
||||
});
|
||||
// - Cancelled form
|
||||
this.element.on('cancelled_form.caselog_entry_form.itop', function(){
|
||||
me._onCancelledEntryForm();
|
||||
});
|
||||
// - Submitted form
|
||||
|
||||
// Entries
|
||||
// - Click on a closed case log message
|
||||
this.element.find(this.js_selectors.entry_group).on('click', '.'+this.css_classes.is_closed + ' ' + this.js_selectors.entry_main_information, function(oEvent){
|
||||
me._onCaseLogClosedMessageClick($(this).closest(me.js_selectors.entry));
|
||||
});
|
||||
// Click on an edits entry's long description toggler
|
||||
// - Click on an edits entry's long description toggler
|
||||
this.element.find(this.js_selectors.edits_entry_long_description_toggler).on('click', function(oEvent){
|
||||
me._onEditsLongDescriptionTogglerClick(oEvent, $(this).closest(me.js_selectors.entry));
|
||||
});
|
||||
@@ -151,7 +176,7 @@ $(function()
|
||||
},
|
||||
_onActivityFilterChange: function(oInputElem)
|
||||
{
|
||||
this._ApplyEntryFilters();
|
||||
this._ApplyEntriesFilters();
|
||||
},
|
||||
_onCaseLogOpenAllClick: function(oIconElem)
|
||||
{
|
||||
@@ -163,6 +188,34 @@ $(function()
|
||||
const sCaseLogAttCode = oIconElem.closest(this.js_selectors.tab_toggler).attr('data-caselog-attribute-code');
|
||||
this._CloseAllMessages(sCaseLogAttCode);
|
||||
},
|
||||
/**
|
||||
* @param oEvent {Object}
|
||||
* @return {void}
|
||||
* @private
|
||||
*/
|
||||
_onComposeButtonClick: function(oEvent)
|
||||
{
|
||||
oEvent.preventDefault();
|
||||
|
||||
const oActiveTabData = this._GetActiveTabData();
|
||||
// If on a caselog tab, open its form
|
||||
if (this.enums.tab_types.caselog === oActiveTabData.type) {
|
||||
this._ShowCaseLogTab(oActiveTabData.att_code);
|
||||
this._ShowCaseLogsEntryForms();
|
||||
}
|
||||
// Else if on the activity tab, check which case log tab to go to
|
||||
else {
|
||||
// TODO 3.0.0: Make a tab popover menu selection
|
||||
console.log('TO IMPLEMENT');
|
||||
|
||||
// If only 1 editbale case log, open this one
|
||||
// Else, open a popover menu to choose one
|
||||
}
|
||||
},
|
||||
_onCancelledEntryForm: function()
|
||||
{
|
||||
this._HideCaseLogsEntryForms();
|
||||
},
|
||||
_onCaseLogClosedMessageClick: function(oEntryElem)
|
||||
{
|
||||
this._OpenMessage(oEntryElem);
|
||||
@@ -215,19 +268,91 @@ $(function()
|
||||
});
|
||||
},
|
||||
// - Helpers on tabs
|
||||
/**
|
||||
* @returns {Object} Data on the active tab:
|
||||
*
|
||||
* - Its type
|
||||
* - Optionally, its attribute code
|
||||
* - Optionally, its rank
|
||||
* @private
|
||||
*/
|
||||
_GetActiveTabData: function()
|
||||
{
|
||||
const oTabTogglerElem = this.element.find(this.js_selectors.tab_toggler + '.' + this.css_classes.is_active);
|
||||
|
||||
// Consistency check
|
||||
if(oTabTogglerElem.length === 0) {
|
||||
throw 'No active tab, this should not be possible.';
|
||||
}
|
||||
|
||||
const sTabType = oTabTogglerElem.attr('data-tab-type');
|
||||
let oTabData = {
|
||||
type: sTabType,
|
||||
};
|
||||
|
||||
// Additional data for caselog tab
|
||||
if (this.enums.tab_types.caselog === sTabType) {
|
||||
oTabData.att_code = oTabTogglerElem.attr('data-caselog-attribute-code');
|
||||
oTabData.rank = oTabTogglerElem.attr('data-caselog-rank');
|
||||
}
|
||||
|
||||
return oTabData;
|
||||
},
|
||||
/**
|
||||
* @returns {Object} Active tab toolbar jQuery element
|
||||
* @private
|
||||
*/
|
||||
_GetActiveTabToolbarElement: function()
|
||||
{
|
||||
const oActiveTabData = this._GetActiveTabData();
|
||||
let sSelector = this.js_selectors.tab_toolbar + '[data-tab-type="' + oActiveTabData.type + '"]';
|
||||
|
||||
if (this.enums.tab_types.caselog === oActiveTabData.type) {
|
||||
sSelector += '[data-caselog-attribute-code="' + oActiveTabData.att_code + '"]';
|
||||
}
|
||||
|
||||
return this.element.find(sSelector);
|
||||
},
|
||||
_ShowCaseLogTab: function(sCaseLogAttCode)
|
||||
{
|
||||
// Show only entries from this case log
|
||||
this._HideAllEntries();
|
||||
this.element.find(this.js_selectors.entry+'[data-entry-caselog-attribute-code="'+sCaseLogAttCode+'"]').removeClass(this.css_classes.is_hidden);
|
||||
this._UpdateEntryGroupsVisibility();
|
||||
// this._HideAllEntries();
|
||||
//this.element.find(this.js_selectors.entry+'[data-entry-caselog-attribute-code="'+sCaseLogAttCode+'"]').removeClass(this.css_classes.is_hidden);
|
||||
this._ShowAllEntries();
|
||||
this._ApplyEntriesFilters();
|
||||
},
|
||||
_ShowActivityTab: function()
|
||||
{
|
||||
// Show all entries but regarding the current filters
|
||||
this._OpenAllMessages();
|
||||
//this._OpenAllMessages();
|
||||
this._ShowAllEntries();
|
||||
this._ApplyEntryFilters();
|
||||
this._ApplyEntriesFilters();
|
||||
},
|
||||
/**
|
||||
* Show all case logs entry forms.
|
||||
* Event is triggered on the corresponding elements.
|
||||
*
|
||||
* @return {void}
|
||||
* @private
|
||||
*/
|
||||
_ShowCaseLogsEntryForms: function()
|
||||
{
|
||||
this.element.find(this.js_selectors.caselog_entry_form).trigger('show_form.caselog_entry_form.itop');
|
||||
this.element.find(this.js_selectors.compose_button).addClass(this.css_classes.is_hidden);
|
||||
},
|
||||
/**
|
||||
* Hide all case logs entry forms.
|
||||
* Event is triggered on the corresponding elements.
|
||||
*
|
||||
* @return {void}
|
||||
* @private
|
||||
*/
|
||||
_HideCaseLogsEntryForms: function()
|
||||
{
|
||||
this.element.find(this.js_selectors.caselog_entry_form).trigger('hide_form.caselog_entry_form.itop');
|
||||
this.element.find(this.js_selectors.compose_button).removeClass(this.css_classes.is_hidden);
|
||||
|
||||
// TODO 3.0.0: Release lock
|
||||
},
|
||||
// - Helpers on messages
|
||||
_OpenMessage: function(oEntryElem)
|
||||
@@ -250,12 +375,12 @@ $(function()
|
||||
this.element.find(this.js_selectors.entry + sExtraSelector)[sCallback](this.css_classes.is_closed);
|
||||
},
|
||||
// - Helpers on entries
|
||||
_ApplyEntryFilters: function()
|
||||
_ApplyEntriesFilters: function()
|
||||
{
|
||||
const me = this;
|
||||
|
||||
// For each filter, show/hide corresponding entries
|
||||
this.element.find(this.js_selectors.activity_filter).each(function(){
|
||||
this._GetActiveTabToolbarElement().find(this.js_selectors.activity_filter).each(function(){
|
||||
const aTargetEntryTypes = $(this).attr('data-target-entry-types').split(' ');
|
||||
const sCallbackMethod = ($(this).prop('checked')) ? '_ShowEntries' : '_HideEntries';
|
||||
|
||||
@@ -270,6 +395,8 @@ $(function()
|
||||
$(this).find(me.js_selectors.entry_medallion).removeClass(me.css_classes.is_visible);
|
||||
$(this).find(me.js_selectors.entry + ':visible:last').find(me.js_selectors.entry_medallion).addClass(me.css_classes.is_visible);
|
||||
});
|
||||
|
||||
this._UpdateEntryGroupsVisibility();
|
||||
},
|
||||
_ShowAllEntries: function()
|
||||
{
|
||||
|
||||
@@ -24,7 +24,6 @@ $(function() {
|
||||
options:
|
||||
{
|
||||
submit_mode: 'autonomous',
|
||||
target_type: null,
|
||||
text_input_id: '',
|
||||
},
|
||||
css_classes:
|
||||
@@ -38,7 +37,6 @@ $(function() {
|
||||
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--add-caselog-entry-button"]',
|
||||
main_actions: '[data-role="ibo-caselog-entry-form--action-buttons--main-actions"]',
|
||||
cancel_button: '[data-role="ibo-caselog-entry-form--action-buttons--main-actions"] [data-role="ibo-button"][name="cancel"]',
|
||||
send_button: '[data-role="ibo-caselog-entry-form--action-buttons--main-actions"] [data-role="ibo-button"][name="send"]',
|
||||
@@ -50,11 +48,6 @@ $(function() {
|
||||
{
|
||||
autonomous: 'autonomous',
|
||||
bridged: 'bridged',
|
||||
},
|
||||
target_type:
|
||||
{
|
||||
caselog: 'caselog',
|
||||
activity: 'activity',
|
||||
}
|
||||
},
|
||||
|
||||
@@ -76,19 +69,10 @@ $(function() {
|
||||
}
|
||||
|
||||
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
|
||||
@@ -106,22 +90,23 @@ $(function() {
|
||||
|
||||
// Form buttons
|
||||
this.element.find(this.js_selectors.cancel_button).on('click', function(oEvent){
|
||||
me._HideEntryForm();
|
||||
me.element.trigger('cancelled_form.caselog_entry_form.itop');
|
||||
});
|
||||
this.element.find(this.js_selectors.send_button).on('click', function(oEvent){
|
||||
// Avoid form being submitted
|
||||
oEvent.preventDefault();
|
||||
// TODO 3.0.0: To be refactored next
|
||||
// // Avoid form being submitted
|
||||
// oEvent.preventDefault();
|
||||
//
|
||||
// let sCaselogAttCode = me.element.closest(me.js_selectors.activity_panel_toolbar).attr('data-caselog-attribute-code');
|
||||
// me._SubmitEntryToCaselog(me._GetInputData(), sCaselogAttCode);
|
||||
});
|
||||
|
||||
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');
|
||||
}
|
||||
// Form show/hide
|
||||
this.element.on('show_form.caselog_entry_form.itop', function(){
|
||||
me._ShowEntryForm();
|
||||
});
|
||||
this.element.on('hide_form.caselog_entry_form.itop', function(){
|
||||
me._HideEntryForm();
|
||||
});
|
||||
|
||||
// Caselog selection
|
||||
@@ -165,11 +150,11 @@ $(function() {
|
||||
// - Form
|
||||
_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);
|
||||
|
||||
// TODO 3.0.0: This should also clear the form (input, lock, send button, ...)
|
||||
},
|
||||
// - Bridged form input
|
||||
/**
|
||||
|
||||
@@ -30,26 +30,15 @@ class CaseLogEntryForm extends UIContentBlock
|
||||
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\Base\Component\Input\RichText\RichText $oTextInput The main input to write a case log entry */
|
||||
protected $oTextInput;
|
||||
/** @var \Combodo\iTop\Application\UI\Base\Component\PopoverMenu\PopoverMenu Menu for possible options on the send button */
|
||||
@@ -68,7 +57,6 @@ class CaseLogEntryForm extends UIContentBlock
|
||||
{
|
||||
parent::__construct($sId);
|
||||
$this->sSubmitMode = static::DEFAULT_SUBMIT_MODE;
|
||||
$this->sContainerTabType = static::DEFAULT_CONTAINER_TAB_TYPE;
|
||||
$this->SetTextInput(new RichText());
|
||||
$this->aMainActionButtons = [];
|
||||
$this->aExtraActionButtons = [];
|
||||
@@ -137,28 +125,6 @@ class CaseLogEntryForm extends UIContentBlock
|
||||
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\Base\Component\Input\RichText\RichText
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
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}) }}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
$('#{{ oUIBlock.GetId() }}').caselog_entry_form({
|
||||
submit_mode: '{{ oUIBlock.GetSubmitMode() }}',
|
||||
target_tab: '{{ oUIBlocl.GetContainerTabType() }}',
|
||||
text_input_id: '{{ oUIBlock.GetTextInput().GetId()}}'
|
||||
});
|
||||
Reference in New Issue
Block a user