Feature/modals - generic modal API (#373)

Default modal JS Implementation:

Add title option
Add buttons option
Change template cloning
Confirmation Modal:

Add implementation
Do not show again functionality
Web Page:

Add blocks array with twig loop insertion
This commit is contained in:
bdalsass
2022-12-06 10:18:59 +01:00
committed by GitHub
parent 98a53a46f0
commit dbe7fae82e
29 changed files with 322 additions and 345 deletions

View File

@@ -151,17 +151,3 @@ $ibo-fieldsorter--selected--background-color: $ibo-color-blue-200 !default;
} }
#table-row-action-confirmation-dialog{
.ibo-row-action--confirmation--explanation{
margin-bottom: 16px;
}
.ibo-row-action--confirmation--do-not-show-again--checkbox{
height: auto;
display: inline-block;
width: auto;
}
}

View File

@@ -1,4 +1,18 @@
/* /*
* @copyright Copyright (C) 2010-2021 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
/* SCSS variables */
$ibo-modal-option--do-not-show-again--margin-top: $ibo-spacing-500 !default;
// Modal Option - Do not show again
.ibo-modal-option--do-not-show-again{
margin-top: $ibo-modal-option--do-not-show-again--margin-top;
.ibo-modal-option--do-not-show-again--checkbox{
height: auto;
display: inline-block;
width: auto;
}
}

View File

@@ -126,7 +126,7 @@ CombodoModal._InstantiateModal = function(oModalElem, oOptions) {
oModalElem.find('.modal-content').html(oOptions.content); oModalElem.find('.modal-content').html(oOptions.content);
// Internal callbacks // Internal callbacks
this._OnContentLoaded(oModalElem, oOptions.callbackOnContentLoaded); this._OnContentLoaded(oModalElem, oOptions.callback_on_content_loaded);
// Manually triggers bootstrap event in order to keep listeners working // Manually triggers bootstrap event in order to keep listeners working
oModalElem.trigger('loaded.bs.modal'); oModalElem.trigger('loaded.bs.modal');
@@ -148,7 +148,7 @@ CombodoModal._InstantiateModal = function(oModalElem, oOptions) {
} }
// Internal callbacks // Internal callbacks
me._OnContentLoaded(oModalElem, oOptions.callbackOnContentLoaded); me._OnContentLoaded(oModalElem, oOptions.callback_on_content_loaded);
//Manually triggers bootstrap event in order to keep listeners working //Manually triggers bootstrap event in order to keep listeners working
oModalElem.trigger('loaded.bs.modal'); oModalElem.trigger('loaded.bs.modal');

View File

@@ -0,0 +1,22 @@
<?php
/**
* Copyright (C) 2013-2021 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
*/
Dict::Add('EN US', 'English', 'English', array(
'UI:Modal:Confirmation:DefaultTitle' => 'Confirmation',
));

View File

@@ -0,0 +1,22 @@
<?php
/**
* Copyright (C) 2013-2021 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
*/
Dict::Add('FR FR', 'French', 'Français', array(
'UI:Modal:DefaultConfirmationTitle' => 'Confirmation',
));

View File

@@ -3,9 +3,6 @@
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
const TABLE_ACTION_CONFIRMATION_PREFIX = 'table_action_row';
const TABLE_ACTION_CONFIRMATION_DIALOG_SELECTOR = '#table-row-action-confirmation-dialog';
/** /**
* Return column JSON declaration for row actions. * Return column JSON declaration for row actions.
* Could be part of column or columnDefs declaration of datatable.js. * Could be part of column or columnDefs declaration of datatable.js.
@@ -30,77 +27,4 @@ function getRowActionsColumnDefinition(sTableId, iColumnTargetIndex = -1)
} }
return aColumn; return aColumn;
} }
/**
* HandleActionRowConfirmation.
*
* @param sTitle title for confirmation dialog
* @param sMessage message of the confirmation dialog
* @param sDoNotShowAgainPreferenceKey iTop preference key to store "do not show again" flag
* @param oConfirmHandler confirm button handler
* @param aConfirmHandlerData confirm button handler data
* @constructor
*/
const HandleActionRowConfirmation = function (sTitle, sMessage, sDoNotShowAgainPreferenceKey, oConfirmHandler, aConfirmHandlerData){
// confirmation preference
if(sDoNotShowAgainPreferenceKey != null){
// retrieve need confirmation user preference
let bNeedConfirmation = GetUserPreferenceAsBoolean(`${TABLE_ACTION_CONFIRMATION_PREFIX}.${sDoNotShowAgainPreferenceKey}`, true);
// confirm handler if no confirmation requested
if(!bNeedConfirmation){
oConfirmHandler(aConfirmHandlerData.datatable, aConfirmHandlerData.tr_element, aConfirmHandlerData.action_id, aConfirmHandlerData.row_data);
return;
}
}
// fill confirmation dialog
$('.ibo-row-action--confirmation--explanation', $(TABLE_ACTION_CONFIRMATION_DIALOG_SELECTOR)).html(sMessage);
$('.ibo-row-action--confirmation--do-not-show-again', $(TABLE_ACTION_CONFIRMATION_DIALOG_SELECTOR)).toggle(sDoNotShowAgainPreferenceKey != null);
// open confirmation dialog
$(TABLE_ACTION_CONFIRMATION_DIALOG_SELECTOR).dialog({
autoOpen: false,
minWidth: 400,
modal: true,
title: sTitle,
autoOpen: true,
position: {my: "center center", at: "center center", of: $('body')},
close: function () {
// destroy dialog object
$(TABLE_ACTION_CONFIRMATION_DIALOG_SELECTOR).dialog( "destroy" );
},
buttons: [
{
text: Dict.S('UI:Button:Cancel'),
class: 'ibo-is-alternative',
click: function () {
// close dialog
$(TABLE_ACTION_CONFIRMATION_DIALOG_SELECTOR).dialog('close');
}
},
{
text: Dict.S('UI:Button:Ok'),
class: 'ibo-is-primary',
click: function () {
// handle "do not show again" user preference
if(sDoNotShowAgainPreferenceKey != null){
// save preference
const bDoNotShowAgain = $(this).find($('.ibo-row-action--confirmation--do-not-show-again--checkbox')).prop('checked');
if (bDoNotShowAgain) {
SetUserPreference(`${TABLE_ACTION_CONFIRMATION_PREFIX}.${sDoNotShowAgainPreferenceKey}`, 'false', true);
}
}
// call confirm handler and close dialog
if(oConfirmHandler(aConfirmHandlerData.datatable, aConfirmHandlerData.tr_element, aConfirmHandlerData.action_id, aConfirmHandlerData.row_data)){
$(TABLE_ACTION_CONFIRMATION_DIALOG_SELECTOR).dialog('close');
}
}
},
],
});
}

View File

@@ -111,6 +111,13 @@ $(function () {
} }
}); });
// Append row actions column
if (me.options.bHasRowActions) {
sThead += "<th></th>";
let iColumnCount = aOptions['columns'].length;
aOptions["columns"][iColumnCount] = getRowActionsColumnDefinition(oParams.list_id);
}
parentElt.append("<table id=\""+me.options.sListId+"\" width=\"100%\" class=\"ibo-datatable\">"+ parentElt.append("<table id=\""+me.options.sListId+"\" width=\"100%\" class=\"ibo-datatable\">"+
"<thead><tr>"+sThead+"</tr></thead></table>"); "<thead><tr>"+sThead+"</tr></thead></table>");
aOptions["lengthMenu"] = [[oParams.end, oParams.end * 2, oParams.end * 3, oParams.end * 4, -1], [oParams.end, oParams.end * 2, oParams.end * 3, oParams.end * 4, aOptions["lengthMenu"]]]; aOptions["lengthMenu"] = [[oParams.end, oParams.end * 2, oParams.end * 3, oParams.end * 4, -1], [oParams.end, oParams.end * 2, oParams.end * 3, oParams.end * 4, aOptions["lengthMenu"]]];

View File

@@ -201,7 +201,10 @@ CombodoModal._InstantiateModal = function(oModalElem, oOptions) {
width: 'auto', width: 'auto',
height: 'auto', height: 'auto',
modal: oOptions.extra_options.modal ?? true, modal: oOptions.extra_options.modal ?? true,
close: oOptions.extra_options.callback_on_modal_close,
autoOpen: oOptions.auto_open, autoOpen: oOptions.auto_open,
title: oOptions.title,
buttons: this._ConvertButtonDefinition(oOptions.buttons)
}; };
// Resize to desired size // Resize to desired size
@@ -245,7 +248,7 @@ CombodoModal._InstantiateModal = function(oModalElem, oOptions) {
{ {
case 'string': case 'string':
oModalElem.html(oOptions.content); oModalElem.html(oOptions.content);
this._OnContentLoaded(oModalElem, oOptions.callbackOnContentLoaded); this._OnContentLoaded(oModalElem, oOptions.callback_on_content_loaded);
break; break;
case 'object': case 'object':
@@ -274,7 +277,7 @@ CombodoModal._InstantiateModal = function(oModalElem, oOptions) {
me._CenterModalInViewport(oModalElem); me._CenterModalInViewport(oModalElem);
}, 500); }, 500);
me._OnContentLoaded(oModalElem, oOptions.callbackOnContentLoaded); me._OnContentLoaded(oModalElem, oOptions.callback_on_content_loaded);
} }
); );
break; break;
@@ -313,6 +316,28 @@ CombodoModal._InstantiateModal = function(oModalElem, oOptions) {
return true; return true;
}; };
/**
* Convert generic buttons definitions to jquery ui dialog definitions.
*
* @param aButtonsDefinitions
* @returns {*[]}
* @constructor
*/
CombodoModal._ConvertButtonDefinition = function(aButtonsDefinitions){
const aConverted = [];
aButtonsDefinitions.forEach(element => {
const aButton = {
text: element.text,
class: element.class,
click: element.callback_on_click
}
aConverted.push(aButton);
}
);
return aConverted;
}
/** /**
* @override * @override
* @inheritDoc * @inheritDoc
@@ -323,6 +348,85 @@ CombodoModal._CenterModalInViewport = function (oModalElem) {
}); });
}; };
/**
* Open a standard confirmation modal and put the content into it.
*
* @param oOptions array @see CombodoModal.OpenModal + {do_not_show_again_pref_key: string, callback_on_confirm: function, callback_on_cancel}
* @param aData data passed to callbacks
* @returns object The jQuery object of the modal element
*/
CombodoModal.OpenConfirmationModal = function(oOptions, aData) {
// Check do not show again preference key
if(oOptions.do_not_show_again_pref_key !== null){
if(GetUserPreference(oOptions.do_not_show_again_pref_key, false)){
if(oOptions.callback_on_confirm !== null){
oOptions.callback_on_confirm(...aData);
}
return;
}
}
// Merge external options with confirmation modal default options
oOptions = $.extend({
title: Dict.S('UI:Modal:DefaultConfirmationTitle'),
content: '',
do_not_show_again_pref_key: null,
callback_on_confirm: null,
callback_on_cancel: null,
extra_options: {
callback_on_modal_close: function () {
$(this).dialog( "destroy" ); // destroy dialog object
}
},
buttons: [
{
text: Dict.S('UI:Button:Cancel'),
class: 'ibo-is-alternative',
callback_on_click: function () {
// call confirm handler and close dialog
let bCanClose = true;
if(oOptions.callback_on_cancel != null){
bCanClose = oOptions.callback_on_cancel(...aData) !== false;
}
if(bCanClose){
$(this).dialog('close'); // close dialog
}
}
},
{
text: Dict.S('UI:Button:Ok'),
class: 'ibo-is-primary',
callback_on_click: function () {
// Call confirm handler and close dialog
let bCanClose = true;
if(oOptions.callback_on_confirm != null){
bCanClose = oOptions.callback_on_confirm(...aData) !== false;
}
if(bCanClose){
$(this).dialog('close'); // close dialog
// Handle "do not show again" user preference
let bDoNotShowAgain = oOptions.do_not_show_again_pref_key !== null ?
$('[name="do_not_show_again"]', $(this)).prop('checked') :
false;
if (bDoNotShowAgain) {
SetUserPreference(oOptions.do_not_show_again_pref_key, true, true);
}
}
}
}
],
callback_on_content_loaded: function(oModalContentElement){
// Add option do not show again from template
if(oOptions.do_not_show_again_pref_key !== null) {
oModalContentElement.append($('#ibo-modal-option--do-not-show-again-template').html());
}
}
}, oOptions);
// Open modal
CombodoModal.OpenModal(oOptions);
}
// Processing on each pages of the backoffice // Processing on each pages of the backoffice
$(document).ready(function(){ $(document).ready(function(){
// Initialize global keyboard shortcuts // Initialize global keyboard shortcuts

View File

@@ -1121,6 +1121,7 @@ let CombodoModal = {
* *
* @param sTargetUrl {String} * @param sTargetUrl {String}
* @param bCloseOtherModals {String} * @param bCloseOtherModals {String}
* @param callbackOnContentLoaded {function}
* @return {Object} The jQuery object representing the modal element * @return {Object} The jQuery object representing the modal element
* @api * @api
*/ */
@@ -1145,7 +1146,7 @@ let CombodoModal = {
}; };
if (callbackOnContentLoaded !== undefined) { if (callbackOnContentLoaded !== undefined) {
oOptions.callbackOnContentLoaded = callbackOnContentLoaded; oOptions.callback_on_content_loaded = callbackOnContentLoaded;
} }
// Opening modal // Opening modal
@@ -1170,10 +1171,12 @@ let CombodoModal = {
usage: 'clone', // Either 'clone' or 'replace' usage: 'clone', // Either 'clone' or 'replace'
selector: this._GetDefaultBaseModalSelector() // Either a selector of the modal element used to base this one on or the modal element itself selector: this._GetDefaultBaseModalSelector() // Either a selector of the modal element used to base this one on or the modal element itself
}, },
title: undefined, // Title of the modal
content: undefined, // Either a string, an object containing the endpoint / data or undefined to keep base modal content as-is content: undefined, // Either a string, an object containing the endpoint / data or undefined to keep base modal content as-is
buttons: null,
size: 'auto', // Either 'auto' / 'xs' / 'sm' / 'md' / 'lg' or specific height & width via {width: '80px', height: '100px'} size: 'auto', // Either 'auto' / 'xs' / 'sm' / 'md' / 'lg' or specific height & width via {width: '80px', height: '100px'}
auto_open: true, // true for the modal to open automatically on instantiation auto_open: true, // true for the modal to open automatically on instantiation
callbackOnContentLoaded: null, // Callback to call once the content is loaded. Arguments will be oModalElem (the jQuery object representing the modal) callback_on_content_loaded: null, // Callback to call once the content is loaded. Arguments will be oModalElem (the jQuery object representing the modal) callback_on_content_loaded
extra_options: {}, // Extra options to pass to the modal lib directly if they are not handled by the CombodoModal widget yet extra_options: {}, // Extra options to pass to the modal lib directly if they are not handled by the CombodoModal widget yet
}, },
oOptions oOptions
@@ -1206,7 +1209,7 @@ let CombodoModal = {
if (oOptions.base_modal.usage === 'clone') { if (oOptions.base_modal.usage === 'clone') {
// Clone modal using a real template // Clone modal using a real template
if (oSelectorElem[0].tagName === 'TEMPLATE') { if (oSelectorElem[0].tagName === 'TEMPLATE') {
oModalElem = $(oSelectorElem[0].content.firstElementChild.cloneNode(true)); oModalElem = $(oSelectorElem.html());
} }
// Clone modal using an existing element // Clone modal using an existing element
else { else {
@@ -1216,8 +1219,7 @@ let CombodoModal = {
// Force modal to have an HTML ID, otherwise it can lead to complications, especially with the portal_leave_handle.js // Force modal to have an HTML ID, otherwise it can lead to complications, especially with the portal_leave_handle.js
// See N°3469 // See N°3469
let sModalID = (oOptions.id !== null) ? oOptions.id : 'modal-with-generated-id-'+Date.now(); let sModalID = (oOptions.id !== null) ? oOptions.id : 'modal-with-generated-id-'+Date.now();
oModalElem.attr('id', sModalID) oModalElem.attr('id', sModalID);
.appendTo('body');
} }
// - Get an existing modal in the DOM // - Get an existing modal in the DOM
else { else {
@@ -1291,5 +1293,16 @@ let CombodoModal = {
callback(oModalElem); callback(oModalElem);
} }
} }
},
/**
* Open a standard confirmation modal and put the content into it.
*
* @param oOptions
* @returns object The jQuery object of the modal element
*/
OpenConfirmationModal: function(oOptions) {
// Meant for overlaoding
CombodoJSConsole.Debug('CombodoModal.OpenConfirmationModal not implemented');
} }
}; };

View File

@@ -24,8 +24,21 @@ use Composer\Semver\VersionParser;
*/ */
class InstalledVersions class InstalledVersions
{ {
/**
* @var mixed[]|null
* @psalm-var array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}|array{}|null
*/
private static $installed; private static $installed;
/**
* @var bool|null
*/
private static $canGetVendors; private static $canGetVendors;
/**
* @var array[]
* @psalm-var array<string, array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
*/
private static $installedByVendor = array(); private static $installedByVendor = array();
/** /**

View File

@@ -145,10 +145,6 @@ return array(
'CAS_Request_Exception' => $vendorDir . '/apereo/phpcas/source/CAS/Request/Exception.php', 'CAS_Request_Exception' => $vendorDir . '/apereo/phpcas/source/CAS/Request/Exception.php',
'CAS_Request_MultiRequestInterface' => $vendorDir . '/apereo/phpcas/source/CAS/Request/MultiRequestInterface.php', 'CAS_Request_MultiRequestInterface' => $vendorDir . '/apereo/phpcas/source/CAS/Request/MultiRequestInterface.php',
'CAS_Request_RequestInterface' => $vendorDir . '/apereo/phpcas/source/CAS/Request/RequestInterface.php', 'CAS_Request_RequestInterface' => $vendorDir . '/apereo/phpcas/source/CAS/Request/RequestInterface.php',
'CAS_ServiceBaseUrl_AllowedListDiscovery' => $vendorDir . '/apereo/phpcas/source/CAS/ServiceBaseUrl/AllowedListDiscovery.php',
'CAS_ServiceBaseUrl_Base' => $vendorDir . '/apereo/phpcas/source/CAS/ServiceBaseUrl/Base.php',
'CAS_ServiceBaseUrl_Interface' => $vendorDir . '/apereo/phpcas/source/CAS/ServiceBaseUrl/Interface.php',
'CAS_ServiceBaseUrl_Static' => $vendorDir . '/apereo/phpcas/source/CAS/ServiceBaseUrl/Static.php',
'CAS_Session_PhpSession' => $vendorDir . '/apereo/phpcas/source/CAS/Session/PhpSession.php', 'CAS_Session_PhpSession' => $vendorDir . '/apereo/phpcas/source/CAS/Session/PhpSession.php',
'CAS_TypeMismatchException' => $vendorDir . '/apereo/phpcas/source/CAS/TypeMismatchException.php', 'CAS_TypeMismatchException' => $vendorDir . '/apereo/phpcas/source/CAS/TypeMismatchException.php',
'CLILikeWebPage' => $baseDir . '/sources/Application/WebPage/CLILikeWebPage.php', 'CLILikeWebPage' => $baseDir . '/sources/Application/WebPage/CLILikeWebPage.php',
@@ -233,8 +229,6 @@ return array(
'Combodo\\iTop\\Application\\UI\\Base\\Component\\DataTable\\StaticTable\\FormTable\\FormTable' => $baseDir . '/sources/Application/UI/Base/Component/DataTable/StaticTable/FormTable/FormTable.php', 'Combodo\\iTop\\Application\\UI\\Base\\Component\\DataTable\\StaticTable\\FormTable\\FormTable' => $baseDir . '/sources/Application/UI/Base/Component/DataTable/StaticTable/FormTable/FormTable.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\DataTable\\StaticTable\\StaticTable' => $baseDir . '/sources/Application/UI/Base/Component/DataTable/StaticTable/StaticTable.php', 'Combodo\\iTop\\Application\\UI\\Base\\Component\\DataTable\\StaticTable\\StaticTable' => $baseDir . '/sources/Application/UI/Base/Component/DataTable/StaticTable/StaticTable.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\DataTable\\tTableRowActions' => $baseDir . '/sources/Application/UI/Base/Component/DataTable/tTableRowActions.php', 'Combodo\\iTop\\Application\\UI\\Base\\Component\\DataTable\\tTableRowActions' => $baseDir . '/sources/Application/UI/Base/Component/DataTable/tTableRowActions.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Dialog\\Dialog' => $baseDir . '/sources/Application/UI/Base/Component/Dialog/Dialog.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Dialog\\DialogUIBlockFactory' => $baseDir . '/sources/Application/UI/Base/Component/Dialog/DialogUIBlockFactory.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\FieldBadge\\FieldBadge' => $baseDir . '/sources/Application/UI/Base/Component/FieldBadge/FieldBadge.php', 'Combodo\\iTop\\Application\\UI\\Base\\Component\\FieldBadge\\FieldBadge' => $baseDir . '/sources/Application/UI/Base/Component/FieldBadge/FieldBadge.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\FieldBadge\\FieldBadgeUIBlockFactory' => $baseDir . '/sources/Application/UI/Base/Component/FieldBadge/FieldBadgeUIBlockFactory.php', 'Combodo\\iTop\\Application\\UI\\Base\\Component\\FieldBadge\\FieldBadgeUIBlockFactory' => $baseDir . '/sources/Application/UI/Base/Component/FieldBadge/FieldBadgeUIBlockFactory.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\FieldSet\\FieldSet' => $baseDir . '/sources/Application/UI/Base/Component/FieldSet/FieldSet.php', 'Combodo\\iTop\\Application\\UI\\Base\\Component\\FieldSet\\FieldSet' => $baseDir . '/sources/Application/UI/Base/Component/FieldSet/FieldSet.php',
@@ -262,6 +256,7 @@ return array(
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\TextArea' => $baseDir . '/sources/Application/UI/Base/Component/Input/TextArea.php', 'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\TextArea' => $baseDir . '/sources/Application/UI/Base/Component/Input/TextArea.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\tInputLabel' => $baseDir . '/sources/Application/UI/Base/Component/Input/tInputLabel.php', 'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\tInputLabel' => $baseDir . '/sources/Application/UI/Base/Component/Input/tInputLabel.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\MedallionIcon\\MedallionIcon' => $baseDir . '/sources/Application/UI/Base/Component/MedallionIcon/MedallionIcon.php', 'Combodo\\iTop\\Application\\UI\\Base\\Component\\MedallionIcon\\MedallionIcon' => $baseDir . '/sources/Application/UI/Base/Component/MedallionIcon/MedallionIcon.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Modal\\DoNotShowAgainOptionBlock' => $baseDir . '/sources/Application/UI/Base/Component/Modal/DoNotShowAgainOptionBlock.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Panel\\Panel' => $baseDir . '/sources/Application/UI/Base/Component/Panel/Panel.php', 'Combodo\\iTop\\Application\\UI\\Base\\Component\\Panel\\Panel' => $baseDir . '/sources/Application/UI/Base/Component/Panel/Panel.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Panel\\PanelUIBlockFactory' => $baseDir . '/sources/Application/UI/Base/Component/Panel/PanelUIBlockFactory.php', 'Combodo\\iTop\\Application\\UI\\Base\\Component\\Panel\\PanelUIBlockFactory' => $baseDir . '/sources/Application/UI/Base/Component/Panel/PanelUIBlockFactory.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Pill\\Pill' => $baseDir . '/sources/Application/UI/Base/Component/Pill/Pill.php', 'Combodo\\iTop\\Application\\UI\\Base\\Component\\Pill\\Pill' => $baseDir . '/sources/Application/UI/Base/Component/Pill/Pill.php',

View File

@@ -510,10 +510,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'CAS_Request_Exception' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/Request/Exception.php', 'CAS_Request_Exception' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/Request/Exception.php',
'CAS_Request_MultiRequestInterface' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/Request/MultiRequestInterface.php', 'CAS_Request_MultiRequestInterface' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/Request/MultiRequestInterface.php',
'CAS_Request_RequestInterface' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/Request/RequestInterface.php', 'CAS_Request_RequestInterface' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/Request/RequestInterface.php',
'CAS_ServiceBaseUrl_AllowedListDiscovery' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/ServiceBaseUrl/AllowedListDiscovery.php',
'CAS_ServiceBaseUrl_Base' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/ServiceBaseUrl/Base.php',
'CAS_ServiceBaseUrl_Interface' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/ServiceBaseUrl/Interface.php',
'CAS_ServiceBaseUrl_Static' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/ServiceBaseUrl/Static.php',
'CAS_Session_PhpSession' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/Session/PhpSession.php', 'CAS_Session_PhpSession' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/Session/PhpSession.php',
'CAS_TypeMismatchException' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/TypeMismatchException.php', 'CAS_TypeMismatchException' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/TypeMismatchException.php',
'CLILikeWebPage' => __DIR__ . '/../..' . '/sources/Application/WebPage/CLILikeWebPage.php', 'CLILikeWebPage' => __DIR__ . '/../..' . '/sources/Application/WebPage/CLILikeWebPage.php',
@@ -598,8 +594,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Combodo\\iTop\\Application\\UI\\Base\\Component\\DataTable\\StaticTable\\FormTable\\FormTable' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/DataTable/StaticTable/FormTable/FormTable.php', 'Combodo\\iTop\\Application\\UI\\Base\\Component\\DataTable\\StaticTable\\FormTable\\FormTable' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/DataTable/StaticTable/FormTable/FormTable.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\DataTable\\StaticTable\\StaticTable' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/DataTable/StaticTable/StaticTable.php', 'Combodo\\iTop\\Application\\UI\\Base\\Component\\DataTable\\StaticTable\\StaticTable' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/DataTable/StaticTable/StaticTable.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\DataTable\\tTableRowActions' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/DataTable/tTableRowActions.php', 'Combodo\\iTop\\Application\\UI\\Base\\Component\\DataTable\\tTableRowActions' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/DataTable/tTableRowActions.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Dialog\\Dialog' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Dialog/Dialog.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Dialog\\DialogUIBlockFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Dialog/DialogUIBlockFactory.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\FieldBadge\\FieldBadge' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/FieldBadge/FieldBadge.php', 'Combodo\\iTop\\Application\\UI\\Base\\Component\\FieldBadge\\FieldBadge' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/FieldBadge/FieldBadge.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\FieldBadge\\FieldBadgeUIBlockFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/FieldBadge/FieldBadgeUIBlockFactory.php', 'Combodo\\iTop\\Application\\UI\\Base\\Component\\FieldBadge\\FieldBadgeUIBlockFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/FieldBadge/FieldBadgeUIBlockFactory.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\FieldSet\\FieldSet' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/FieldSet/FieldSet.php', 'Combodo\\iTop\\Application\\UI\\Base\\Component\\FieldSet\\FieldSet' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/FieldSet/FieldSet.php',
@@ -627,6 +621,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\TextArea' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Input/TextArea.php', 'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\TextArea' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Input/TextArea.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\tInputLabel' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Input/tInputLabel.php', 'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\tInputLabel' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Input/tInputLabel.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\MedallionIcon\\MedallionIcon' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/MedallionIcon/MedallionIcon.php', 'Combodo\\iTop\\Application\\UI\\Base\\Component\\MedallionIcon\\MedallionIcon' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/MedallionIcon/MedallionIcon.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Modal\\DoNotShowAgainOptionBlock' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Modal/DoNotShowAgainOptionBlock.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Panel\\Panel' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Panel/Panel.php', 'Combodo\\iTop\\Application\\UI\\Base\\Component\\Panel\\Panel' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Panel/Panel.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Panel\\PanelUIBlockFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Panel/PanelUIBlockFactory.php', 'Combodo\\iTop\\Application\\UI\\Base\\Component\\Panel\\PanelUIBlockFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Panel/PanelUIBlockFactory.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Pill\\Pill' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Pill/Pill.php', 'Combodo\\iTop\\Application\\UI\\Base\\Component\\Pill\\Pill' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Pill/Pill.php',

View File

@@ -5,7 +5,7 @@
'type' => 'project', 'type' => 'project',
'install_path' => __DIR__ . '/../../', 'install_path' => __DIR__ . '/../../',
'aliases' => array(), 'aliases' => array(),
'reference' => 'cdde765a85ee0262181e3c493183b1fb80536e74', 'reference' => '64d9eef7c926f98aa1aabe61294397be308dd885',
'name' => 'combodo/itop', 'name' => 'combodo/itop',
'dev' => true, 'dev' => true,
), ),
@@ -25,7 +25,7 @@
'type' => 'project', 'type' => 'project',
'install_path' => __DIR__ . '/../../', 'install_path' => __DIR__ . '/../../',
'aliases' => array(), 'aliases' => array(),
'reference' => 'cdde765a85ee0262181e3c493183b1fb80536e74', 'reference' => '64d9eef7c926f98aa1aabe61294397be308dd885',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'combodo/tcpdf' => array( 'combodo/tcpdf' => array(

View File

@@ -214,7 +214,7 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory
array_key_exists('tooltip', $aAction) ? Dict::S($aAction['tooltip']) : '', array_key_exists('tooltip', $aAction) ? Dict::S($aAction['tooltip']) : '',
array_key_exists('name', $aAction) ? $aAction['name'] : 'undefined' array_key_exists('name', $aAction) ? $aAction['name'] : 'undefined'
); );
$oButton->SetDataAttributes(['action-id' => $iKey]); $oButton->SetDataAttributes(['action-id' => $iKey, 'tooltip-append-to' => 'body']);
$oToolbar->AddSubBlock($oButton); $oToolbar->AddSubBlock($oButton);
} }

View File

@@ -7,8 +7,6 @@
namespace Combodo\iTop\Application\UI\Base\Component\DataTable; namespace Combodo\iTop\Application\UI\Base\Component\DataTable;
use Combodo\iTop\Application\UI\Base\Component\Dialog\DialogUIBlockFactory; use Combodo\iTop\Application\UI\Base\Component\Dialog\DialogUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
/** /**
* Trait tTableRowActions * Trait tTableRowActions
@@ -33,11 +31,11 @@ trait tTableRowActions
* confirmation => { * confirmation => {
* message: string, * message: string,
* message_row_data: string, * message_row_data: string,
* remember_choice_pref_key: string * do_not_show_again_pref_key: string
* } * }
* } * }
*/ */
protected $aRowActions; protected $aRowActions = [];
/** /**
* Set row actions. * Set row actions.
@@ -82,31 +80,4 @@ trait tTableRowActions
{ {
return DataTableUIBlockFactory::MakeActionRowToolbarTemplate($this); return DataTableUIBlockFactory::MakeActionRowToolbarTemplate($this);
} }
/**
* GetRowActionsConfirmDialog.
*
* @return \Combodo\iTop\Application\UI\Base\Component\Html\Html
*/
public function GetRowActionsConfirmDialog()
{
static::$bDialogInitialized = true;
$oDialog = DialogUIBlockFactory::MakeNeutral('', '<div class="ibo-row-action--confirmation--explanation"></div>', 'table-row-action-confirmation-dialog');
$oContent = UIContentBlockUIBlockFactory::MakeStandard();
$oContent->AddCSSClass('ibo-row-action--confirmation--do-not-show-again');
$checkBox = InputUIBlockFactory::MakeStandard('checkbox', 'do_not_show_again', false);
$checkBox->AddCSSClass('ibo-row-action--confirmation--do-not-show-again--checkbox');
$checkBox->SetLabel(\Dict::S('UI:UserPref:DoNotShowAgain'));
$oContent->AddSubBlock($checkBox);
$oDialog->AddSubBlock($oContent);
return $oDialog;
}
public function GetRowActionsConfirmDialogInitializedFlag()
{
return static::$bDialogInitialized;
}
} }

View File

@@ -1,109 +0,0 @@
<?php
/**
* Copyright (C) 2013-2021 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
*/
namespace Combodo\iTop\Application\UI\Base\Component\Dialog;
use Combodo\iTop\Application\UI\Base\Component\Html\Html;
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlock;
/**
*
* @package Combodo\iTop\Application\UI\Base\Component\Dialog
* @since 3.1.0
*/
class Dialog extends UIContentBlock
{
// Overloaded constants
public const BLOCK_CODE = 'ibo-dialog';
public const DEFAULT_HTML_TEMPLATE_REL_PATH = 'base/components/dialog/layout';
public const DEFAULT_JS_ON_READY_TEMPLATE_REL_PATH = 'base/components/dialog/layout';
public const DEFAULT_JS_FILES_REL_PATH = [
'js/components/dialog.js',
];
/** @var string $sTitle */
protected string $sTitle;
/** @var string $sContent */
protected string $sContent;
/**
* Alert constructor.
*
* @param string $sTitle
* @param string $sContent
* @param string|null $sId
*/
public function __construct(string $sTitle = '', string $sContent = '', ?string $sId = null)
{
parent::__construct($sId);
$this->sContent = $sContent;
if (!empty($sContent)) {
$this->AddSubBlock(new Html($sContent));
}
}
/**
* @return string
*/
public function GetTitle(): string
{
return $this->sTitle;
}
/**
* @param string $sTitle Title of the alert
*
* @return $this
*/
public function SetTitle(string $sTitle): Dialog
{
$this->sTitle = $sTitle;
return $this;
}
/**
* Return the raw HTML content, should be already sanitized.
*
* @return string
*/
public function GetContent(): string
{
return $this->sContent;
}
/**
* Set the raw HTML content, must be already sanitized.
*
* @param string $sContent The raw HTML content, must be already sanitized
*
* @return $this
*/
public function SetContent(string $sContent): Dialog
{
$this->sContent = $sContent;
return $this;
}
}

View File

@@ -1,54 +0,0 @@
<?php
/**
* Copyright (C) 2013-2021 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
*/
namespace Combodo\iTop\Application\UI\Base\Component\Dialog;
use Combodo\iTop\Application\UI\Base\AbstractUIBlockFactory;
/**
* Class DialogUIBlockFactory
*
* @api
*
* @since 3.1.0
* @package Combodo\iTop\Application\UI\Base\Component\Dialog
*/
class DialogUIBlockFactory extends AbstractUIBlockFactory
{
/** @inheritDoc */
public const TWIG_TAG_NAME = 'UIDialog';
/** @inheritDoc */
public const UI_BLOCK_CLASS_NAME = Dialog::class;
/**
* Make a basis Dialog component
*
* @param string $sTitle Title of the alert
* @param string $sContent The raw HTML content, must be already sanitized
* @param string|null $sId id of the html block
*
* @return \Combodo\iTop\Application\UI\Base\Component\Alert\Alert
*/
public static function MakeNeutral(string $sTitle = '', string $sContent = '', ?string $sId = null)
{
return new Dialog($sTitle, $sContent, $sId);
}
}

View File

@@ -0,0 +1,59 @@
<?php
/**
* Copyright (C) 2013-2023 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
*/
namespace Combodo\iTop\Application\UI\Base\Component\Modal;
use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlock;
use Dict;
/**
*
* @package Combodo\iTop\Application\UI\Base\Component\Modal
* @since 3.1.0
*/
class DoNotShowAgainOptionBlock extends UIContentBlock
{
/**
* Constructor.
*
* @param string|null $sId
*/
public function __construct(string $sId = null)
{
parent::__construct($sId, ['ibo-modal-option--do-not-show-again']);
// initialize UI
$this->InitUI();
}
/**
* Initialize UI.
*
* @return void
*/
private function InitUI()
{
// Create checkbox
$oCheckBox = InputUIBlockFactory::MakeStandard('checkbox', 'do_not_show_again', false);
$oCheckBox->AddCSSClass('ibo-modal-option--do-not-show-again--checkbox');
$oCheckBox->SetLabel(Dict::S('UI:UserPref:DoNotShowAgain'));
$this->AddSubBlock($oCheckBox);
}
}

View File

@@ -20,6 +20,7 @@
namespace Combodo\iTop\Application\UI\Base\Component\Template; namespace Combodo\iTop\Application\UI\Base\Component\Template;
use Combodo\iTop\Application\UI\Base\AbstractUIBlockFactory; use Combodo\iTop\Application\UI\Base\AbstractUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlock;
/** /**
* Class TemplateUIBlockFactory * Class TemplateUIBlockFactory
@@ -47,4 +48,17 @@ class TemplateUIBlockFactory extends AbstractUIBlockFactory
{ {
return new Template($sId); return new Template($sId);
} }
/**
* Make a Template component with a block inside.
*
* @return \Combodo\iTop\Application\UI\Base\Component\Template\Template
*/
public static function MakeForBlock(string $sId, UIContentBlock $oContentBlock)
{
$oBlock = TemplateUIBlockFactory::MakeStandard($sId);
$oBlock->AddSubBlock($oContentBlock);
return $oBlock;
}
} }

View File

@@ -55,9 +55,9 @@ class BlockDirectLinksViewTable extends AbstractBlockLinksViewTable
'icon_classes' => 'fas fa-minus', 'icon_classes' => 'fas fa-minus',
'js_row_action' => "LinkSetWorker.DetachLinkedObject('{$this->sTargetClass}', aRowData['{$this->sTargetClass}/_key_/raw'], '{$this->oAttDef->GetExtKeyToMe()}');", 'js_row_action' => "LinkSetWorker.DetachLinkedObject('{$this->sTargetClass}', aRowData['{$this->sTargetClass}/_key_/raw'], '{$this->oAttDef->GetExtKeyToMe()}');",
'confirmation' => [ 'confirmation' => [
'message' => 'UI:Links:ActionRow:detach:confirmation', 'message' => 'UI:Links:ActionRow:detach:confirmation',
'message_row_data' => "{$this->sTargetClass}/hyperlink", 'message_row_data' => "{$this->sTargetClass}/hyperlink",
'remember_choice_pref_key' => 'LinkSetWorker.DetachLinkedObject', 'do_not_show_again_pref_key' => 'LinkSetWorker.DetachLinkedObject',
], ],
); );
break; break;
@@ -68,9 +68,9 @@ class BlockDirectLinksViewTable extends AbstractBlockLinksViewTable
'icon_classes' => 'fas fa-trash', 'icon_classes' => 'fas fa-trash',
'js_row_action' => "LinkSetWorker.DeleteLinkedObject('{$this->oAttDef->GetLinkedClass()}', aRowData['{$this->oAttDef->GetLinkedClass()}/_key_/raw']);", 'js_row_action' => "LinkSetWorker.DeleteLinkedObject('{$this->oAttDef->GetLinkedClass()}', aRowData['{$this->oAttDef->GetLinkedClass()}/_key_/raw']);",
'confirmation' => [ 'confirmation' => [
'message' => 'UI:Links:ActionRow:delete:confirmation', 'message' => 'UI:Links:ActionRow:delete:confirmation',
'message_row_data' => "{$this->sTargetClass}/hyperlink", 'message_row_data' => "{$this->sTargetClass}/hyperlink",
'remember_choice_pref_key' => 'LinkSetWorker.DeleteLinkedObject', 'do_not_show_again_pref_key' => 'LinkSetWorker.DeleteLinkedObject',
], ],
); );
break; break;

View File

@@ -63,9 +63,9 @@ class BlockIndirectLinksViewTable extends AbstractBlockLinksViewTable
'icon_classes' => 'fas fa-minus', 'icon_classes' => 'fas fa-minus',
'js_row_action' => "LinkSetWorker.DeleteLinkedObject('{$this->oAttDef->GetLinkedClass()}', aRowData['Link/_key_/raw']);", 'js_row_action' => "LinkSetWorker.DeleteLinkedObject('{$this->oAttDef->GetLinkedClass()}', aRowData['Link/_key_/raw']);",
'confirmation' => [ 'confirmation' => [
'message' => 'UI:Links:ActionRow:detach:confirmation', 'message' => 'UI:Links:ActionRow:detach:confirmation',
'message_row_data' => "Remote/hyperlink", 'message_row_data' => "Remote/hyperlink",
'remember_choice_pref_key' => 'LinkSetWorker.DetachLinkedObject', 'do_not_show_again_pref_key' => 'LinkSetWorker.DetachLinkedObject',
], ],
); );

View File

@@ -8,7 +8,9 @@
use Combodo\iTop\Application\TwigBase\Twig\TwigHelper; use Combodo\iTop\Application\TwigBase\Twig\TwigHelper;
use Combodo\iTop\Application\UI\Base\Component\Alert\AlertUIBlockFactory; use Combodo\iTop\Application\UI\Base\Component\Alert\AlertUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Breadcrumbs\Breadcrumbs; use Combodo\iTop\Application\UI\Base\Component\Breadcrumbs\Breadcrumbs;
use Combodo\iTop\Application\UI\Base\Component\Modal\DoNotShowAgainOptionBlock;
use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory; use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Template\TemplateUIBlockFactory;
use Combodo\iTop\Application\UI\Base\iUIBlock; use Combodo\iTop\Application\UI\Base\iUIBlock;
use Combodo\iTop\Application\UI\Base\Layout\iUIContentBlock; use Combodo\iTop\Application\UI\Base\Layout\iUIContentBlock;
use Combodo\iTop\Application\UI\Base\Layout\NavigationMenu\NavigationMenu; use Combodo\iTop\Application\UI\Base\Layout\NavigationMenu\NavigationMenu;
@@ -210,6 +212,9 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
$this->add_dict_entry('UI:DisconnectedDlgTitle'); $this->add_dict_entry('UI:DisconnectedDlgTitle');
$this->add_dict_entry('UI:LoginAgain'); $this->add_dict_entry('UI:LoginAgain');
$this->add_dict_entry('UI:StayOnThePage'); $this->add_dict_entry('UI:StayOnThePage');
// Modals
$this->add_dict_entries('UI:Modal:');
} }
/** /**
@@ -891,6 +896,9 @@ HTML;
// - Prepare content // - Prepare content
$aData['aLayouts']['oPageContent'] = $this->GetContentLayout(); $aData['aLayouts']['oPageContent'] = $this->GetContentLayout();
$aData['aDeferredBlocks']['oPageContent'] = $this->GetDeferredBlocks($this->GetContentLayout()); $aData['aDeferredBlocks']['oPageContent'] = $this->GetDeferredBlocks($this->GetContentLayout());
// - Prepare generic templates
$aData['aTemplates'] = array();
$aData['aTemplates'][] = TemplateUIBlockFactory::MakeForBlock('ibo-modal-option--do-not-show-again-template', new DoNotShowAgainOptionBlock());
// - Retrieve layouts linked files // - Retrieve layouts linked files
// Note: Adding them now instead of in the template allow us to remove duplicates and lower the browser parsing time // Note: Adding them now instead of in the template allow us to remove duplicates and lower the browser parsing time
@@ -1241,4 +1249,5 @@ EOF
return parent::SetBlockParam($sKey, $value); return parent::SetBlockParam($sKey, $value);
} }
} }

View File

@@ -28,7 +28,4 @@
{% if oUIBlock.HasRowActions() %} {% if oUIBlock.HasRowActions() %}
{{ render_block(oUIBlock.GetRowActionsTemplate()) }} {{ render_block(oUIBlock.GetRowActionsTemplate()) }}
{% if not oUIBlock.GetRowActionsConfirmDialogInitializedFlag() %}
{{ render_block(oUIBlock.GetRowActionsConfirmDialog()) }}
{% endif %}
{% endif %} {% endif %}

View File

@@ -420,6 +420,7 @@ var aOptions{{ sListIDForVarSuffix }} = {
oData: {{ oUIBlock.GetJsonAjaxData() |raw }}, oData: {{ oUIBlock.GetJsonAjaxData() |raw }},
oDefaultSettings: {{ oUIBlock.GetOption("oDefaultSettings")|raw }}, oDefaultSettings: {{ oUIBlock.GetOption("oDefaultSettings")|raw }},
oLabels: {moveup: "{{ 'UI:Button:MoveUp'|dict_s }}", movedown: "{{ 'UI:Button:MoveDown'|dict_s }}"}, oLabels: {moveup: "{{ 'UI:Button:MoveUp'|dict_s }}", movedown: "{{ 'UI:Button:MoveDown'|dict_s }}"},
bHasRowActions: {{ oUIBlock.HasRowActions()|var_export }},
}; };
if ($('#datatable_dlg_{{ oUIBlock.GetId() }}').hasClass('itop-datatable')) if ($('#datatable_dlg_{{ oUIBlock.GetId() }}').hasClass('itop-datatable'))

View File

@@ -15,23 +15,21 @@
{% if aAction.confirmation is defined %} {% if aAction.confirmation is defined %}
// Handle action row with confirmation // Prepare confirmation message
let sTitle = '{{ 'UI:Datatables:RowActions:ConfirmationDialog'|dict_s }}';
let sMessage = '{{ 'UI:Datatables:RowActions:ConfirmationMessage'|dict_s }}'; let sMessage = '{{ 'UI:Datatables:RowActions:ConfirmationMessage'|dict_s }}';
{% if aAction.confirmation.message is defined %} {% if aAction.confirmation.message is defined %}
sMessage = '{{ aAction.confirmation.message|dict_s|raw }}'; sMessage = '{{ aAction.confirmation.message|dict_s|raw }}';
sMessage = sMessage.replaceAll('{item}', aRowData['{{ aAction.confirmation.message_row_data }}']);
{% endif %} {% endif %}
let sPrefKey = null;
{% if aAction.confirmation.remember_choice_pref_key is defined %} // Handle action row with confirmation modal
sPrefKey = '{{ aAction.confirmation.remember_choice_pref_key }}'; CombodoModal.OpenConfirmationModal({
{% endif %} title: '{{ 'UI:Datatables:RowActions:ConfirmationDialog'|dict_s }}',
HandleActionRowConfirmation (sTitle, sMessage, sPrefKey, ActionRowFunction{{ oUIBlock.GetId() }}{{ loop.index0 }}, { content: sMessage.replaceAll('{item}', aRowData['{{ aAction.confirmation.message_row_data }}']),
action_id: iActionId, callback_on_confirm: ActionRowFunction{{ oUIBlock.GetId() }}{{ loop.index0 }},
datatable: oDatatable, {% if aAction.confirmation.do_not_show_again_pref_key is defined %}
tr_element: oTrElement, do_not_show_again_pref_key: '{{ aAction.confirmation.do_not_show_again_pref_key }}',
row_data: aRowData {% endif %}
}); }, [oDatatable, oTrElement, iActionId, aRowData]);
{% else %} {% else %}

View File

@@ -21,7 +21,4 @@
{% if oUIBlock.HasRowActions() %} {% if oUIBlock.HasRowActions() %}
{{ render_block(oUIBlock.GetRowActionsTemplate()) }} {{ render_block(oUIBlock.GetRowActionsTemplate()) }}
{% if not oUIBlock.GetRowActionsConfirmDialogInitializedFlag() %}
{{ render_block(oUIBlock.GetRowActionsConfirmDialog()) }}
{% endif %}
{% endif %} {% endif %}

View File

@@ -48,7 +48,4 @@
{% if oUIBlock.HasRowActions() %} {% if oUIBlock.HasRowActions() %}
{{ render_block(oUIBlock.GetRowActionsTemplate()) }} {{ render_block(oUIBlock.GetRowActionsTemplate()) }}
{% if not oUIBlock.GetRowActionsConfirmDialogInitializedFlag() %}
{{ render_block(oUIBlock.GetRowActionsConfirmDialog()) }}
{% endif %}
{% endif %} {% endif %}

View File

@@ -1,4 +0,0 @@
$('#{{ oUIBlock.GetId() }}').alert({
bOpenedByDefault: {{ oUIBlock.IsOpenedByDefault()|var_export }}
{% if oUIBlock.IsSaveCollapsibleStateEnabled() %}, collapsibleStateStorageKey: '{{ oUIBlock.GetSessionCollapsibleStateStorageKey() }}'{% endif %}
});

View File

@@ -45,6 +45,12 @@
<template id="ibo-modal-template"> <template id="ibo-modal-template">
<div class="ibo-modal" data-role="ibo-modal">TODO 3.1: Please wait</div> <div class="ibo-modal" data-role="ibo-modal">TODO 3.1: Please wait</div>
</template> </template>
{# Templates #}
{% for oTemplate in aTemplates %}
{{ render_block(oTemplate, {aPage: aPage}) }}
{% endfor %}
{% endblock %} {% endblock %}
{% block iboCapturedOutput %} {% block iboCapturedOutput %}