diff --git a/datamodels/2.x/itop-portal-base/portal/src/controllers/managebrickcontroller.class.inc.php b/datamodels/2.x/itop-portal-base/portal/src/controllers/managebrickcontroller.class.inc.php
index 78c43c713..8cf008288 100644
--- a/datamodels/2.x/itop-portal-base/portal/src/controllers/managebrickcontroller.class.inc.php
+++ b/datamodels/2.x/itop-portal-base/portal/src/controllers/managebrickcontroller.class.inc.php
@@ -23,6 +23,7 @@ use AttributeDate;
use AttributeDateTime;
use AttributeDefinition;
use AttributeImage;
+use AttributeTagSet;
use BinaryExpression;
use CMDBSource;
use Combodo\iTop\Portal\Brick\AbstractBrick;
@@ -585,6 +586,7 @@ class ManageBrickController extends BrickController
if ($oAttDef->IsExternalKey())
{
$sValue = $oCurrentRow->GetAsHTML($sItemAttr.'_friendlyname');
+ $sSortValue = $oCurrentRow->Get($sItemAttr.'_friendlyname');
// Adding a view action on the external keys
if ($oCurrentRow->Get($sItemAttr) !== $oAttDef->GetNullValue())
@@ -614,24 +616,28 @@ class ManageBrickController extends BrickController
$sUrl = $oAttDef->Get('default_image');
}
$sValue = '
';
+ $sSortValue = null;
}
- elseif ($oAttDef instanceof \AttributeTagSet)
+ elseif ($oAttDef instanceof AttributeTagSet)
{
/** @var \ormTagSet $oSetValues */
$oSetValues = $oCurrentRow->Get($sItemAttr);
$aCodes = $oSetValues->GetTags();
/** @var \AttributeTagSet $oAttDef */
$sValue = $oAttDef->GenerateViewHtmlForValues($aCodes, '', false);
+ $sSortValue = implode(' ', $aCodes);
}
else
{
$sValue = $oAttDef->GetAsHTML($oCurrentRow->Get($sItemAttr));
+ $sSortValue = $oCurrentRow->Get($sItemAttr);
}
unset($oAttDef);
$aItemAttrs[$sItemAttr] = array(
'att_code' => $sItemAttr,
'value' => $sValue,
+ 'sort_value' => $sSortValue,
'actions' => $aActions
);
}
diff --git a/datamodels/2.x/itop-portal-base/portal/src/views/bricks/manage/layout-table.html.twig b/datamodels/2.x/itop-portal-base/portal/src/views/bricks/manage/layout-table.html.twig
index 8872e9924..80a14a764 100644
--- a/datamodels/2.x/itop-portal-base/portal/src/views/bricks/manage/layout-table.html.twig
+++ b/datamodels/2.x/itop-portal-base/portal/src/views/bricks/manage/layout-table.html.twig
@@ -39,8 +39,7 @@
{% endif %}
{% endif %}
@@ -68,12 +67,12 @@
var columnsProperties = {
{% for aAreaData in aGroupingAreasData %}
- '{{ aAreaData.sId }}': {{ aAreaData.aColumnsDefinition|json_encode()|raw }},
+ '{{ aAreaData.sId }}': {{ aAreaData.aColumnsDefinition|json_encode()|raw }},
{% endfor %}
};
var rawData = {
{% for aAreaData in aGroupingAreasData %}
- '{{ aAreaData.sId }}': {{ aAreaData.aItems|json_encode()|raw }},
+ '{{ aAreaData.sId }}': {{ aAreaData.aItems|json_encode()|raw }},
{% endfor %}
};
@@ -107,43 +106,48 @@
"defaultContent": "",
"type": "html",
"data": "attributes." + key + ".att_code",
- "render": function (att_code, type, row) {
- var cellElem;
- var itemActions;
- var itemPrimarayAction;
+ "render": {
+ _: function (att_code, type, row) {
+ var cellElem;
+ var itemActions;
+ var itemPrimarayAction;
- // Preparing action on the cell
- // Note : For now we will use only one action, the secondary actions are therefore not implemented. Only the data structure is done.
- itemActions = row.attributes[att_code].actions;
+ // Preparing action on the cell
+ // Note : For now we will use only one action, the secondary actions are therefore not implemented. Only the data structure is done.
+ itemActions = row.attributes[att_code].actions;
- // Preparing the cell data
- cellElem = (itemActions.length > 0) ? $('') : $('');
- cellElem.html(row.attributes[att_code].value);
- // Building actions
- if (itemActions.length > 0) {
- // - Primary action
- itemPrimaryAction = itemActions[0];
- switch (itemPrimaryAction.type) {
- case '{{ constant('Combodo\\iTop\\Portal\\Brick\\ManageBrick::ENUM_ACTION_VIEW') }}':
- url = '{{ app.url_generator.generate('p_object_view', {'sObjectClass': '-objectClass-', 'sObjectId': '-objectId-'})|raw }}'.replace(/-objectClass-/, itemPrimaryAction.class).replace(/-objectId-/, itemPrimaryAction.id);
- break;
- case '{{ constant('Combodo\\iTop\\Portal\\Brick\\ManageBrick::ENUM_ACTION_EDIT') }}':
- url = '{{ app.url_generator.generate('p_object_edit', {'sObjectClass': '-objectClass-', 'sObjectId': '-objectId-'})|raw }}'.replace(/-objectClass-/, itemPrimaryAction.class).replace(/-objectId-/, itemPrimaryAction.id);
- break;
- default:
- url = '#';
- //console.log('Action "'+itemPrimaryAction+'" not implemented');
- break;
- }
- SetActionUrl(cellElem, url);
- SetActionOpeningTarget(cellElem, itemPrimaryAction.opening_target);
+ // Preparing the cell data
+ cellElem = (itemActions.length > 0) ? $('') : $('');
+ cellElem.html(row.attributes[att_code].value);
+ // Building actions
+ if (itemActions.length > 0) {
+ // - Primary action
+ itemPrimaryAction = itemActions[0];
+ switch (itemPrimaryAction.type) {
+ case '{{ constant('Combodo\\iTop\\Portal\\Brick\\ManageBrick::ENUM_ACTION_VIEW') }}':
+ url = '{{ app.url_generator.generate('p_object_view', {'sObjectClass': '-objectClass-', 'sObjectId': '-objectId-'})|raw }}'.replace(/-objectClass-/, itemPrimaryAction.class).replace(/-objectId-/, itemPrimaryAction.id);
+ break;
+ case '{{ constant('Combodo\\iTop\\Portal\\Brick\\ManageBrick::ENUM_ACTION_EDIT') }}':
+ url = '{{ app.url_generator.generate('p_object_edit', {'sObjectClass': '-objectClass-', 'sObjectId': '-objectId-'})|raw }}'.replace(/-objectClass-/, itemPrimaryAction.class).replace(/-objectId-/, itemPrimaryAction.id);
+ break;
+ default:
+ url = '#';
+ //console.log('Action "'+itemPrimaryAction+'" not implemented');
+ break;
+ }
+ SetActionUrl(cellElem, url);
+ SetActionOpeningTarget(cellElem, itemPrimaryAction.opening_target);
- // - Secondary actions
- // Not done for now, only the data structure is ready in case we need it later
- }
+ // - Secondary actions
+ // Not done for now, only the data structure is ready in case we need it later
+ }
- return cellElem.prop('outerHTML');
- },
+ return cellElem.prop('outerHTML');
+ },
+ sort: function (att_code, type, row) {
+ return row.attributes[att_code].sort_value;
+ },
+ },
});
}
// UI extensions buttons
@@ -221,115 +225,116 @@
$(document).ready(function () {
{% for aAreaData in aGroupingAreasData %}
- {% set sAreaId = aAreaData.sId %}
+ {% set sAreaId = aAreaData.sId %}
- $(function () {
- $('[data-toggle="tooltip"]').tooltip()
- });
-
- showTableLoader($('#table-{{ sAreaId }}'));
- var oTable{{ sAreaId }} = $('#table-{{ sAreaId }}').DataTable({
- "language": {
- "processing": "{{ 'Portal:Datatables:Language:Processing'|dict_s }}",
- "search": "{{ 'Portal:Datatables:Language:Search'|dict_s }}",
- "lengthMenu": "{{ 'Portal:Datatables:Language:LengthMenu'|dict_s }}",
- "zeroRecords": "{{ 'Portal:Datatables:Language:ZeroRecords'|dict_s }}",
- "info": "{{ 'Portal:Datatables:Language:Info'|dict_s }}",
- "infoEmpty": "{{ 'Portal:Datatables:Language:InfoEmpty'|dict_s }}",
- "infoFiltered": "({{ 'Portal:Datatables:Language:InfoFiltered'|dict_s }})",
- "emptyTable": "{{ 'Portal:Datatables:Language:EmptyTable'|dict_s }}",
- "paginate": {
- "first": "{{ 'Portal:Datatables:Language:Paginate:First'|dict_s }}",
- "previous": "{{ 'Portal:Datatables:Language:Paginate:Previous'|dict_s }}",
- "next": "{{ 'Portal:Datatables:Language:Paginate:Next'|dict_s }}",
- "last": "{{ 'Portal:Datatables:Language:Paginate:Last'|dict_s }}"
+ showTableLoader($('#table-{{ sAreaId }}'));
+ var oTable{{ sAreaId }} = $('#table-{{ sAreaId }}').DataTable({
+ "language": {
+ "processing": "{{ 'Portal:Datatables:Language:Processing'|dict_s }}",
+ "search": "{{ 'Portal:Datatables:Language:Search'|dict_s }}",
+ "lengthMenu": "{{ 'Portal:Datatables:Language:LengthMenu'|dict_s }}",
+ "zeroRecords": "{{ 'Portal:Datatables:Language:ZeroRecords'|dict_s }}",
+ "info": "{{ 'Portal:Datatables:Language:Info'|dict_s }}",
+ "infoEmpty": "{{ 'Portal:Datatables:Language:InfoEmpty'|dict_s }}",
+ "infoFiltered": "({{ 'Portal:Datatables:Language:InfoFiltered'|dict_s }})",
+ "emptyTable": "{{ 'Portal:Datatables:Language:EmptyTable'|dict_s }}",
+ "paginate": {
+ "first": "{{ 'Portal:Datatables:Language:Paginate:First'|dict_s }}",
+ "previous": "{{ 'Portal:Datatables:Language:Paginate:Previous'|dict_s }}",
+ "next": "{{ 'Portal:Datatables:Language:Paginate:Next'|dict_s }}",
+ "last": "{{ 'Portal:Datatables:Language:Paginate:Last'|dict_s }}"
+ },
+ "aria": {
+ "sortAscending": ": {{ 'Portal:Datatables:Language:Sort:Ascending'|dict_s }}",
+ "sortDescending": ": {{ 'Portal:Datatables:Language:Sort:Descending'|dict_s }}"
+ }
},
- "aria": {
- "sortAscending": ": {{ 'Portal:Datatables:Language:Sort:Ascending'|dict_s }}",
- "sortDescending": ": {{ 'Portal:Datatables:Language:Sort:Descending'|dict_s }}"
- }
- },
- "lengthMenu": [[10, 20, 50, -1], [10, 20, 50, "{{ 'Portal:Datatables:Language:DisplayLength:All'|dict_s }}"]],
- "displayLength": {{ constant('Combodo\\iTop\\Portal\\Brick\\ManageBrick::DEFAULT_LIST_LENGTH') }},
- "dom": '<"row"<"col-sm-6"l><"col-sm-6"<"visible-xs"p>>>t<"row"<"col-sm-6"i><"col-sm-6"p>>',
- "columns": getColumnsDefinition('{{ sAreaId }}'),
- "order": [],
- "rowCallback": function (oRow, oData) {
- if (oData.highlight_class !== undefined) {
- var sHighlightClass = oData.highlight_class;
- var sBSHiglightClass = '';
+ "lengthMenu": [[10, 20, 50, -1], [10, 20, 50, "{{ 'Portal:Datatables:Language:DisplayLength:All'|dict_s }}"]],
+ "displayLength": {{ constant('Combodo\\iTop\\Portal\\Brick\\ManageBrick::DEFAULT_LIST_LENGTH') }},
+ "dom": '<"row"<"col-sm-6"l><"col-sm-6"<"visible-xs"p>>>t<"row"<"col-sm-6"i><"col-sm-6"p>>',
+ "columns": getColumnsDefinition('{{ sAreaId }}'),
+ "order": [],
+ "rowCallback": function (oRow, oData) {
+ if (oData.highlight_class !== undefined) {
+ var sHighlightClass = oData.highlight_class;
+ var sBSHiglightClass = '';
- // Adding classic iTop class
- $(oRow).addClass(sHighlightClass);
- // Adding mapped BS class
- if (sHighlightClass === '{{ constant('HILIGHT_CLASS_CRITICAL') }}') {
- sBSHiglightClass = 'danger';
+ // Adding classic iTop class
+ $(oRow).addClass(sHighlightClass);
+ // Adding mapped BS class
+ if (sHighlightClass === '{{ constant('HILIGHT_CLASS_CRITICAL') }}') {
+ sBSHiglightClass = 'danger';
+ }
+ else if (sHighlightClass === '{{ constant('HILIGHT_CLASS_WARNING') }}') {
+ sBSHiglightClass = 'warning';
+ }
+ else if (sHighlightClass === '{{ constant('HILIGHT_CLASS_OK') }}') {
+ sBSHiglightClass = 'success';
+ }
+ $(oRow).addClass(sBSHiglightClass);
}
- else if (sHighlightClass === '{{ constant('HILIGHT_CLASS_WARNING') }}') {
- sBSHiglightClass = 'warning';
+ },
+ "drawCallback": function (settings) {
+ // Hiding pagination if only one page
+ if ($(this).closest('.dataTables_wrapper').find('.dataTables_paginate:last .paginate_button:not(.previous):not(.next)').length < 2) {
+ $(this).closest('.dataTables_wrapper').find('.dataTables_paginate, .dataTables_info').hide();
}
- else if (sHighlightClass === '{{ constant('HILIGHT_CLASS_OK') }}') {
- sBSHiglightClass = 'success';
+ else {
+ $(this).closest('.dataTables_wrapper').find('.dataTables_paginate, .dataTables_info').show();
}
- $(oRow).addClass(sBSHiglightClass);
- }
- },
- "drawCallback": function (settings) {
- // Hiding pagination if only one page
- if ($(this).closest('.dataTables_wrapper').find('.dataTables_paginate:last .paginate_button:not(.previous):not(.next)').length < 2) {
- $(this).closest('.dataTables_wrapper').find('.dataTables_paginate, .dataTables_info').hide();
- }
- else {
- $(this).closest('.dataTables_wrapper').find('.dataTables_paginate, .dataTables_info').show();
- }
- },
- {% if sDataLoading == constant('Combodo\\iTop\\Portal\\Brick\\AbstractBrick::ENUM_DATA_LOADING_FULL') %}
- "data": rawData['{{ sAreaId }}'],
- {% else %}
- "processing": true,
- "serverSide": true,
- {#"searchDelay": 1000, // can be used to increase time between server calls when typing search query#}
- "ajax": {
- "url": "{{ app.url_generator.generate('p_manage_brick_lazy', {'sBrickId': sBrickId, 'sGroupingTab': sGroupingTab, 'sGroupingArea': sAreaId})|raw }}",
- "data": function (d) {
- d.iPageNumber = Math.floor(d.start / d.length) + 1;
- d.iListLength = d.length;
- d.columns = null;
- d.orders = null;
+ },
+ {% if sDataLoading == constant('Combodo\\iTop\\Portal\\Brick\\AbstractBrick::ENUM_DATA_LOADING_FULL') %}
+ "data": rawData['{{ sAreaId }}'],
+ {% else %}
+ "processing": true,
+ "serverSide": true,
+ {#"searchDelay": 1000, // can be used to increase time between server calls when typing search query#}
+ "ajax": {
+ "url": "{{ app.url_generator.generate('p_manage_brick_lazy', {'sBrickId': sBrickId, 'sGroupingTab': sGroupingTab, 'sGroupingArea': sAreaId})|raw }}",
+ "data": function (d) {
+ d.iPageNumber = Math.floor(d.start / d.length) + 1;
+ d.iListLength = d.length;
+ d.columns = null;
+ d.orders = null;
- {% if sSearchValue is not null %}
- // Sets default filter value
- if (d.draw === 1) {
- $('#table-{{ sAreaId }}_filter input').val('{{ sSearchValue }}');
- d.search.value = $('#table-{{ sAreaId }}_filter input').val();
- }
- {% endif %}
- if (d.search.value) {
- d.sSearchValue = d.search.value;
+ {% if sSearchValue is not null %}
+ // Sets default filter value
+ if (d.draw === 1) {
+ $('#table-{{ sAreaId }}_filter input').val('{{ sSearchValue }}');
+ d.search.value = $('#table-{{ sAreaId }}_filter input').val();
+ }
+ {% endif %}
+ if (d.search.value) {
+ d.sSearchValue = d.search.value;
+ }
}
}
- }
- {% endif %}
- });
+ {% endif %}
+ });
- // Overrides filter input to apply throttle. Otherwise, an ajax request is send each time a key is pressed
- // Also removes accents from search string
- // Note : The '.off()' call is to unbind event from DataTables that where triggered before we could intercept anything
- $('#table-{{ sAreaId }}_filter input').off().on('keyup', function () {
- var me = this;
+ // Overrides filter input to apply throttle. Otherwise, an ajax request is send each time a key is pressed
+ // Also removes accents from search string
+ // Note : The '.off()' call is to unbind event from DataTables that where triggered before we could intercept anything
+ $('#table-{{ sAreaId }}_filter input').off().on('keyup', function () {
+ var me = this;
- clearTimeout(oKeyTimeout);
- oKeyTimeout = setTimeout(function () {
- oTable{{ sAreaId }}.search(me.value.latinise()).draw();
- }, iSearchThrottle);
- });// Shows a loader in the table when processing
- $('#table-{{ sAreaId }}').on('processing.dt', function (event, settings, processing) {
+ clearTimeout(oKeyTimeout);
+ oKeyTimeout = setTimeout(function () {
+ oTable{{ sAreaId }}.search(me.value.latinise()).draw();
+ }, iSearchThrottle);
+ });// Shows a loader in the table when processing
+ $('#table-{{ sAreaId }}').on('processing.dt', function (event, settings, processing) {
if (processing === true) {
showTableLoader($(this));
}
});
{% endfor %}
+ // Enable tooltips
+ $(function () {
+ $('[data-toggle="tooltip"]').tooltip()
+ });
+
// Auto collapse item actions popup
$('body').click(function () {
$('table .item-action-wrapper.collapse.in').collapse('hide');