mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-30 14:08:46 +02:00
N°2847 - Add activity panel to object details (and some variables renaming)
This commit is contained in:
278
js/layouts/activity-panel.js
Normal file
278
js/layouts/activity-panel.js
Normal file
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* 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_panel',
|
||||
{
|
||||
// default options
|
||||
options:
|
||||
{
|
||||
datetime_format: null,
|
||||
datetimes_reformat_limit: 14, // In days
|
||||
},
|
||||
css_classes:
|
||||
{
|
||||
is_expanded: 'ibo-is-expanded',
|
||||
is_closed: 'ibo-is-closed',
|
||||
is_active: 'ibo-is-active',
|
||||
is_hidden: 'ibo-is-hidden',
|
||||
},
|
||||
js_selectors:
|
||||
{
|
||||
panel_size_toggler: '[data-role="ibo-activity-panel--size-toggler"]',
|
||||
tab: '[data-role="ibo-activity-panel--tab"]',
|
||||
tab_title: '[data-role="ibo-activity-panel--tab-title"]',
|
||||
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"]',
|
||||
entry_group: '[data-role="ibo-activity-panel--entry-group"]',
|
||||
entry: '[data-role="ibo-activity-entry"]',
|
||||
entry_main_information: '[data-role="ibo-activity-entry--main-information"]',
|
||||
entry_datetime: '[data-role="ibo-activity-entry--datetime"]'
|
||||
},
|
||||
|
||||
// the constructor
|
||||
_create: function()
|
||||
{
|
||||
this.element.addClass('ibo-activity-panel');
|
||||
this._bindEvents();
|
||||
this._ReformatDateTimes();
|
||||
},
|
||||
// events bound via _bind are removed automatically
|
||||
// revert other modifications here
|
||||
_destroy: function()
|
||||
{
|
||||
this.element.removeClass('ibo-activity-panel');
|
||||
},
|
||||
_bindEvents: function()
|
||||
{
|
||||
const me = this;
|
||||
const oBodyElem = $('body');
|
||||
|
||||
// Click on collapse/expand toggler
|
||||
this.element.find(this.js_selectors.panel_size_toggler).on('click', function(oEvent){
|
||||
me._onTogglerClick(oEvent);
|
||||
});
|
||||
// Click on tab title
|
||||
this.element.find(this.js_selectors.tab_title).on('click', function(oEvent){
|
||||
me._onTabTitleClick(oEvent, $(this));
|
||||
});
|
||||
// Change on activity filters
|
||||
this.element.find(this.js_selectors.activity_tab_filter).on('change', function(){
|
||||
me._onActivityFilterChange($(this));
|
||||
});
|
||||
// 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
|
||||
this.element.find(this.js_selectors.caselog_tab_close_all).on('click', function(){
|
||||
me._onCaseLogCloseAllClick($(this));
|
||||
});
|
||||
// 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));
|
||||
});
|
||||
// Mostly for outside clicks that should close elements
|
||||
oBodyElem.on('click', function(oEvent){
|
||||
me._onBodyClick(oEvent);
|
||||
});
|
||||
// Mostly for hotkeys
|
||||
oBodyElem.on('keyup', function(oEvent){
|
||||
me._onBodyKeyUp(oEvent);
|
||||
});
|
||||
},
|
||||
|
||||
// Events callbacks
|
||||
_onTogglerClick: function(oEvent)
|
||||
{
|
||||
// Avoid anchor glitch
|
||||
oEvent.preventDefault();
|
||||
|
||||
// Toggle menu
|
||||
this.element.toggleClass(this.css_classes.is_expanded);
|
||||
},
|
||||
_onTabTitleClick: function(oEvent, oTabTitleElem)
|
||||
{
|
||||
// Avoid anchor glitch
|
||||
oEvent.preventDefault();
|
||||
|
||||
const oTabElem = oTabTitleElem.closest(this.js_selectors.tab);
|
||||
|
||||
this.element.find(this.js_selectors.tab).removeClass(this.css_classes.is_active);
|
||||
oTabElem.addClass(this.css_classes.is_active);
|
||||
|
||||
if(oTabElem.attr('data-tab-type') === 'caselog')
|
||||
{
|
||||
this._ShowCaseLogTab(oTabElem.attr('data-caselog-attribute-code'))
|
||||
}
|
||||
else
|
||||
{
|
||||
this._ShowActivityTab();
|
||||
}
|
||||
},
|
||||
_onActivityFilterChange: function(oInputElem)
|
||||
{
|
||||
this._ApplyEntryFilters();
|
||||
},
|
||||
_onCaseLogOpenAllClick: function(oIconElem)
|
||||
{
|
||||
const sCaseLogAttCode = oIconElem.closest(this.js_selectors.tab).attr('data-caselog-attribute-code');
|
||||
this._OpenAllMessages(sCaseLogAttCode);
|
||||
},
|
||||
_onCaseLogCloseAllClick: function(oIconElem)
|
||||
{
|
||||
const sCaseLogAttCode = oIconElem.closest(this.js_selectors.tab).attr('data-caselog-attribute-code');
|
||||
this._CloseAllMessages(sCaseLogAttCode);
|
||||
},
|
||||
_onCaseLogClosedMessageClick: function(oEntryElem)
|
||||
{
|
||||
this._OpenMessage(oEntryElem);
|
||||
},
|
||||
_onBodyClick: function(oEvent)
|
||||
{
|
||||
|
||||
},
|
||||
_onBodyKeyUp: function(oEvent)
|
||||
{
|
||||
|
||||
},
|
||||
|
||||
// Methods
|
||||
// - Helpers on dates
|
||||
/**
|
||||
* Reformat date times to be relative (only if they are not too far in the past)
|
||||
* @private
|
||||
*/
|
||||
_ReformatDateTimes: function()
|
||||
{
|
||||
const me = this;
|
||||
|
||||
this.element.find(this.js_selectors.entry_datetime).each(function(){
|
||||
const oEntryDateTime = moment($(this).text(), me.options.datetime_format);
|
||||
const oNowDateTime = moment();
|
||||
|
||||
// Reformat date time only if it is not too far in the past (eg. "2 years ago" is not easy to interpret)
|
||||
const fDays = moment.duration(oNowDateTime.diff(oEntryDateTime)).asDays();
|
||||
if(fDays < me.options.datetimes_reformat_limit)
|
||||
{
|
||||
$(this).text( moment($(this).text(), me.options.datetime_format).fromNow() );
|
||||
}
|
||||
});
|
||||
},
|
||||
// - Helpers on tabs
|
||||
_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();
|
||||
},
|
||||
_ShowActivityTab: function()
|
||||
{
|
||||
// Show all entries but regarding the current filters
|
||||
this._OpenAllMessages();
|
||||
this._ShowAllEntries();
|
||||
this._ApplyEntryFilters();
|
||||
},
|
||||
// - Helpers on messages
|
||||
_OpenMessage: function(oEntryElem)
|
||||
{
|
||||
oEntryElem.removeClass(this.css_classes.is_closed);
|
||||
},
|
||||
_OpenAllMessages: function(sCaseLogAttCode = null)
|
||||
{
|
||||
this._SwitchAllMessages('open', sCaseLogAttCode);
|
||||
},
|
||||
_CloseAllMessages: function(sCaseLogAttCode = null)
|
||||
{
|
||||
this._SwitchAllMessages('close', sCaseLogAttCode);
|
||||
},
|
||||
_SwitchAllMessages: function(sMode, sCaseLogAttCode = null)
|
||||
{
|
||||
const sExtraSelector = (sCaseLogAttCode === null) ? '' : '[data-entry-caselog-attribute-code="' + sCaseLogAttCode+'"]';
|
||||
const sCallback = (sMode === 'open') ? 'removeClass' : 'addClass';
|
||||
|
||||
this.element.find(this.js_selectors.entry + sExtraSelector)[sCallback](this.css_classes.is_closed);
|
||||
},
|
||||
// - Helpers on entries
|
||||
_ApplyEntryFilters: function()
|
||||
{
|
||||
const me = this;
|
||||
|
||||
this.element.find(this.js_selectors.activity_tab_filter).each(function(){
|
||||
const aTargetEntryTypes = $(this).attr('data-target-entry-types').split(' ');
|
||||
const sCallbackMethod = ($(this).prop('checked')) ? '_ShowEntries' : '_HideEntries';
|
||||
|
||||
for(let iIdx in aTargetEntryTypes)
|
||||
{
|
||||
me[sCallbackMethod](aTargetEntryTypes[iIdx]);
|
||||
}
|
||||
});
|
||||
},
|
||||
_ShowAllEntries: function()
|
||||
{
|
||||
this.element.find(this.js_selectors.entry).removeClass(this.css_classes.is_hidden);
|
||||
this._UpdateEntryGroupsVisibility();
|
||||
},
|
||||
_HideAllEntries: function()
|
||||
{
|
||||
this.element.find(this.js_selectors.entry).addClass(this.css_classes.is_hidden);
|
||||
this._UpdateEntryGroupsVisibility();
|
||||
},
|
||||
/**
|
||||
* Show entries of type sEntryType but do not hide the others
|
||||
*
|
||||
* @param sEntryType string
|
||||
* @private
|
||||
*/
|
||||
_ShowEntries: function(sEntryType)
|
||||
{
|
||||
this.element.find(this.js_selectors.entry+'[data-entry-type="'+sEntryType+'"]').removeClass(this.css_classes.is_hidden);
|
||||
this._UpdateEntryGroupsVisibility();
|
||||
},
|
||||
/**
|
||||
* Hide entries of type sEntryType but do not hide the others
|
||||
*
|
||||
* @param sEntryType string
|
||||
* @private
|
||||
*/
|
||||
_HideEntries: function(sEntryType)
|
||||
{
|
||||
this.element.find(this.js_selectors.entry+'[data-entry-type="'+sEntryType+'"]').addClass(this.css_classes.is_hidden);
|
||||
this._UpdateEntryGroupsVisibility();
|
||||
},
|
||||
_UpdateEntryGroupsVisibility: function()
|
||||
{
|
||||
const me = this;
|
||||
|
||||
this.element.find(this.js_selectors.entry_group).each(function(){
|
||||
if($(this).find(me.js_selectors.entry + ':not(.' + me.css_classes.is_hidden + ')').length === 0)
|
||||
{
|
||||
$(this).addClass(me.css_classes.is_hidden);
|
||||
}
|
||||
else
|
||||
{
|
||||
$(this).removeClass(me.css_classes.is_hidden);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user