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:
Molkobain
2021-01-25 18:04:14 +01:00
parent 4f9d133670
commit 599c4ebad8
5 changed files with 158 additions and 82 deletions

View File

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

View File

@@ -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
/**

View File

@@ -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
*/

View File

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

View File

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