N°5074 - Linkset datatable actions row improvements

Linkset updates, feedbacks 09/12:

- Distinguish action label and tool tip message
- Change default action button label Ok => Confirm
- Use action label in place of default confirm button label
- Attach do not show again preference key to table instance
- Obsolescence flag for link selection (select all)  issue correction
This commit is contained in:
bdalsass
2022-12-20 10:10:25 +01:00
committed by GitHub
parent 64146b6e1b
commit eda11e97e3
16 changed files with 109 additions and 27 deletions

View File

@@ -383,7 +383,7 @@ Dict::Add('EN US', 'English', 'English', array(
<li>Manage the most important asset of your IT: Documentation.</li>
</ul>
</p>',
'UI:WelcomeMenu:Text'=> '<div>Congratulations, you landed on '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
'UI:WelcomeMenu:Text' => '<div>Congratulations, you landed on '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<div>This version features a brand new modern and accessible backoffice design.</div>
@@ -404,6 +404,7 @@ We hope youll enjoy this version as much as we enjoyed imagining and creating
'UI:Button:GlobalSearch' => 'Search',
'UI:Button:Search' => ' Search ',
'UI:Button:Clear' => ' Clear ',
'UI:Button:Confirm' => ' Confirm ',
'UI:Button:SearchInHierarchy' => 'Search in hierarchy',
'UI:Button:Query' => ' Query ',
'UI:Button:Ok' => 'Ok',

View File

@@ -367,7 +367,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
<li>Contrôlez l\'actif le plus important de votre SI&nbsp;: la documentation.</li>
</ul>
</p>',
'UI:WelcomeMenu:Text'=> '<div>Félicitations, vous avez atterri sur '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.' !</div>
'UI:WelcomeMenu:Text' => '<div>Félicitations, vous avez atterri sur '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.' !</div>
<div>Cette version présente un tout nouveau design moderne et accessible pour la console de support.</div>
@@ -388,6 +388,7 @@ Nous espérons que vous aimerez cette version autant que nous avons eu du plaisi
'UI:Button:GlobalSearch' => 'Rechercher',
'UI:Button:Search' => 'Rechercher',
'UI:Button:Clear' => ' Clear ~~',
'UI:Button:Confirm' => 'Confirmer',
'UI:Button:SearchInHierarchy' => 'Rechercher dans la hiérarchie',
'UI:Button:Query' => ' Lancer la requête ',
'UI:Button:Ok' => 'Ok',

View File

@@ -19,8 +19,10 @@
// Display DataTable
Dict::Add('EN US', 'English', 'English', array(
'UI:Links:ActionRow:detach' => 'Detach item',
'UI:Links:ActionRow:detach:confirmation' => 'Do you really want to detach <b>{item}</b> from current object ?',
'UI:Links:ActionRow:delete' => 'Delete item',
'UI:Links:ActionRow:delete:confirmation' => 'Do you really want to delete <b>{item}</b> from current object ?',
'UI:Links:ActionRow:Detach' => 'Detach',
'UI:Links:ActionRow:Detach+' => 'Detach this object',
'UI:Links:ActionRow:Detach:Confirmation' => 'Do you really want to detach <b>{item}</b> from current object ?',
'UI:Links:ActionRow:Delete' => 'Delete',
'UI:Links:ActionRow:Delete+' => 'Delete this object',
'UI:Links:ActionRow:Delete:Confirmation' => 'Do you really want to delete <b>{item}</b> from current object ?',
));

View File

@@ -0,0 +1,28 @@
<?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
*/
// Display DataTable
Dict::Add('FR FR', 'French', 'Français', array(
'UI:Links:ActionRow:Detach' => 'Détacher',
'UI:Links:ActionRow:Detach+' => 'Détacher cet objet',
'UI:Links:ActionRow:Detach:Confirmation' => 'Voulez-vous détacher <b>{item}</b> de l\'objet courant ?',
'UI:Links:ActionRow:Delete' => 'Supprimer',
'UI:Links:ActionRow:Delete+' => 'Supprimer cet objet',
'UI:Links:ActionRow:Delete:Confirmation' => 'Voulez-vous supprimer <b>{item}</b> de l\'objet courant ?',
));

View File

@@ -652,6 +652,10 @@ $(function()
}
}
return aRes;
},
Remove: function(oCheckbox) // for public access
{
this._removeRow(oCheckbox);
}
});
});

View File

@@ -370,6 +370,7 @@ CombodoModal.OpenConfirmationModal = function(oOptions, aData) {
oOptions = $.extend({
title: Dict.S('UI:Modal:DefaultConfirmationTitle'),
content: '',
confirm_button_label: null,
do_not_show_again_pref_key: null,
callback_on_confirm: null,
callback_on_cancel: null,
@@ -394,7 +395,7 @@ CombodoModal.OpenConfirmationModal = function(oOptions, aData) {
}
},
{
text: Dict.S('UI:Button:Ok'),
text: oOptions.confirm_button_label ?? Dict.S('UI:Button:Confirm'),
class: 'ibo-is-primary',
callback_on_click: function () {
// Call confirm handler and close dialog

View File

@@ -337,6 +337,7 @@ try
}
}
$oWidget = new UILinksWidgetDirect($sClass, $sAttCode, $iInputId);
$oFullSetFilter->SetShowObsoleteData(utils::ShowObsoleteData());
$oWidget->DoAddObjects($oPage, $oFullSetFilter);
break;

View File

@@ -213,7 +213,7 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory
array_key_exists('tooltip', $aAction) ? Dict::S($aAction['tooltip']) : '',
array_key_exists('name', $aAction) ? $aAction['name'] : 'undefined'
);
$oButton->SetDataAttributes(['action-id' => $iKey, 'table-id' => $oTable->GetId()]);
$oButton->SetDataAttributes(['label' => Dict::S($aAction['label']), 'action-id' => $iKey, 'table-id' => $oTable->GetId()]);
$oToolbar->AddSubBlock($oButton);
}

View File

@@ -25,6 +25,7 @@ trait tTableRowActions
/**
* @var $aRowActions array array of row actions
* action => {
* label: string,
* tooltip: string,
* icon_classes: string,
* js_row_action: string,

View File

@@ -134,6 +134,26 @@ abstract class AbstractBlockLinksViewTable extends UIContentBlock
$this->AddSubBlock($oBlock->GetRenderContent($oPage, $this->GetExtraParam(), 'rel_'.$this->sAttCode));
}
/**
* GetTableId.
*
* @return string table identifier
*/
protected function GetTableId(): string
{
return $this->sObjectClass.'_'.$this->sAttCode;
}
/**
* GetDoNotShowAgainPreferenceKey.
*
* @return string do not show again preference key
*/
protected function GetDoNotShowAgainPreferenceKey(): string
{
return "{$this->GetTableId()}.remove_link.do_not_show_again";
}
/**
* GetExtraParam.
*

View File

@@ -237,11 +237,27 @@ class BlockDirectLinksEditTable extends UIContentBlock
$aRowActions = array();
if (!$this->oAttributeLinkedSet->GetReadOnly()) {
$aRowActions[] = array(
'tooltip' => 'remove link',
'icon_classes' => 'fas fa-minus',
'js_row_action' => "$('#{$this->oUILinksDirectWidget->GetInputId()}').directlinks('instance')._deleteRow($(':checkbox', oTrElement));",
);
switch ($this->oAttributeLinkedSet->GetRelationType()) {
case LINKSET_RELATIONTYPE_LINK:
$aRowActions[] = array(
'label' => 'UI:Links:ActionRow:Detach',
'tooltip' => 'UI:Links:ActionRow:Detach+',
'icon_classes' => 'fas fa-minus',
'js_row_action' => "$('#{$this->oUILinksDirectWidget->GetInputId()}').directlinks('Remove', $(':checkbox', oTrElement));",
);
break;
case LINKSET_RELATIONTYPE_PROPERTY:
$aRowActions[] = array(
'label' => 'UI:Links:ActionRow:Delete',
'tooltip' => 'UI:Links:ActionRow:Delete+',
'icon_classes' => 'fas fa-trash',
'js_row_action' => "$('#{$this->oUILinksDirectWidget->GetInputId()}').directlinks('Remove', $(':checkbox', oTrElement));",
);
break;
}
}
return $aRowActions;

View File

@@ -35,7 +35,7 @@ class BlockDirectLinksViewTable extends AbstractBlockLinksViewTable
'object_id' => $this->oDbObject->GetKey(),
'menu' => MetaModel::GetConfig()->Get('allow_menu_on_linkset'),
'default' => $this->GetDefault(),
'table_id' => $this->sObjectClass.'_'.$this->sAttCode,
'table_id' => $this->GetTableId(),
'row_actions' => $this->GetRowActions(),
);
}
@@ -51,26 +51,28 @@ class BlockDirectLinksViewTable extends AbstractBlockLinksViewTable
case LINKSET_RELATIONTYPE_LINK:
$aRowActions[] = array(
'tooltip' => 'UI:Links:ActionRow:detach',
'label' => 'UI:Links:ActionRow:Detach',
'tooltip' => 'UI:Links:ActionRow:Detach+',
'icon_classes' => 'fas fa-minus',
'js_row_action' => "LinkSetWorker.DetachLinkedObject('{$this->sTargetClass}', aRowData['{$this->sTargetClass}/_key_/raw'], '{$this->oAttDef->GetExtKeyToMe()}');",
'confirmation' => [
'message' => 'UI:Links:ActionRow:detach:confirmation',
'message' => 'UI:Links:ActionRow:Detach:Confirmation',
'message_row_data' => "{$this->sTargetClass}/hyperlink",
'do_not_show_again_pref_key' => 'LinkSetWorker.DetachLinkedObject',
'do_not_show_again_pref_key' => $this->GetDoNotShowAgainPreferenceKey(),
],
);
break;
case LINKSET_RELATIONTYPE_PROPERTY:
$aRowActions[] = array(
'tooltip' => 'UI:Links:ActionRow:delete',
'label' => 'UI:Links:ActionRow:Delete',
'tooltip' => 'UI:Links:ActionRow:Delete+',
'icon_classes' => 'fas fa-trash',
'js_row_action' => "LinkSetWorker.DeleteLinkedObject('{$this->oAttDef->GetLinkedClass()}', aRowData['{$this->oAttDef->GetLinkedClass()}/_key_/raw']);",
'confirmation' => [
'message' => 'UI:Links:ActionRow:delete:confirmation',
'message' => 'UI:Links:ActionRow:Delete:Confirmation',
'message_row_data' => "{$this->sTargetClass}/hyperlink",
'do_not_show_again_pref_key' => 'LinkSetWorker.DeleteLinkedObject',
'do_not_show_again_pref_key' => $this->GetDoNotShowAgainPreferenceKey(),
],
);
break;

View File

@@ -430,7 +430,8 @@ JS
if (!$this->oAttributeLinkedSetIndirect->GetReadOnly()) {
$aRowActions[] = array(
'tooltip' => 'remove link',
'label' => 'UI:Links:ActionRow:Detach',
'tooltip' => 'UI:Links:ActionRow:Detach+',
'icon_classes' => 'fas fa-minus',
'js_row_action' => "oWidget{$this->oUILinksWidget->GetInputId()}.Remove(oTrElement);",
);

View File

@@ -44,7 +44,7 @@ class BlockIndirectLinksViewTable extends AbstractBlockLinksViewTable
'view_link' => false,
'menu' => false,
'display_limit' => true,
'table_id' => $this->sObjectClass.'_'.$this->sAttCode,
'table_id' => $this->GetTableId(),
'zlist' => false,
'extra_fields' => $this->GetAttCodesToDisplay(),
'row_actions' => $this->GetRowActions(),
@@ -59,13 +59,14 @@ class BlockIndirectLinksViewTable extends AbstractBlockLinksViewTable
if (!$this->oAttDef->GetReadOnly()) {
$aRowActions[] = array(
'tooltip' => 'UI:Links:ActionRow:detach',
'label' => 'UI:Links:ActionRow:Detach',
'tooltip' => 'UI:Links:ActionRow:Detach+',
'icon_classes' => 'fas fa-minus',
'js_row_action' => "LinkSetWorker.DeleteLinkedObject('{$this->oAttDef->GetLinkedClass()}', aRowData['Link/_key_/raw']);",
'confirmation' => [
'message' => 'UI:Links:ActionRow:detach:confirmation',
'message' => 'UI:Links:ActionRow:Detach:Confirmation',
'message_row_data' => "Remote/hyperlink",
'do_not_show_again_pref_key' => 'LinkSetWorker.DetachLinkedObject',
'do_not_show_again_pref_key' => $this->GetDoNotShowAgainPreferenceKey(),
],
);

View File

@@ -747,6 +747,7 @@ class AjaxRenderController
} else {
$oFullSetFilter = new DBObjectSearch($sRemoteClass);
}
$oFullSetFilter->SetShowObsoleteData(utils::ShowObsoleteData());
$oWidget->DoAddIndirectLinks($oPage, $iMaxAddedId, $oFullSetFilter, $oObj);
$oKPI->ComputeAndReport('Data write');
}

View File

@@ -10,21 +10,23 @@
// variables accessible from action row js
let oDatatable = $('#{{ oUIBlock.GetId() }}').DataTable();
let oTrElement = $(this).closest('tr');
let sLabel = $(this).data('label');
let iActionId = $(this).data('action-id');
let aRowData = oDatatable.row(oTrElement).data();
{% if aAction.confirmation is defined %}
// Prepare confirmation message
let sMessage = '{{ 'UI:Datatables:RowActions:ConfirmationMessage'|dict_s }}';
let sMessage = `{{ 'UI:Datatables:RowActions:ConfirmationMessage'|dict_s|raw }}`;
{% if aAction.confirmation.message is defined %}
sMessage = '{{ aAction.confirmation.message|dict_s|raw }}';
sMessage = `{{ aAction.confirmation.message|dict_s|raw }}`;
{% endif %}
// Handle action row with confirmation modal
CombodoModal.OpenConfirmationModal({
title: '{{ 'UI:Datatables:RowActions:ConfirmationDialog'|dict_s }}',
content: sMessage.replaceAll('{item}', aRowData['{{ aAction.confirmation.message_row_data }}']),
confirm_button_label: sLabel,
callback_on_confirm: ActionRowFunction{{ oUIBlock.GetId() }}{{ loop.index0 }},
{% if aAction.confirmation.do_not_show_again_pref_key is defined %}
do_not_show_again_pref_key: '{{ aAction.confirmation.do_not_show_again_pref_key }}',