mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
N°5904 - Use attribute linked set edit mode to enable actions (#440)
* Add corresponding buttons depending on old edit mode (need to check with piR pour récuperer l'ancienne valeur. * N°5904 - Handle attribute linked set edit_mode * N°5904 Move calls to private jquery widget methods to public * N°5904 - Worker improvements add button on link tagset * Change itop set widget to new set block UI (5) * Change itop set widget to new set block UI (5) * Renommage variables JS avec le prefix combodo * Search dialog block id conflict with form id * add moved js files in iTopWebPage compatibility list --------- Co-authored-by: Stephen Abello <stephen.abello@combodo.com>
This commit is contained in:
@@ -2337,7 +2337,7 @@ EOF
|
||||
if (array_key_exists('bulk_context', $aArgs)) {
|
||||
$oTagSetBlock = LinksSetUIBlockFactory::MakeForBulkLinkSet($iId, $oAttDef, $value, $sWizardHelperJsVarName, $aArgs['bulk_context']);
|
||||
} else {
|
||||
$oTagSetBlock = LinksSetUIBlockFactory::MakeForLinkSet($iId, $oAttDef, $value, $sWizardHelperJsVarName);
|
||||
$oTagSetBlock = LinksSetUIBlockFactory::MakeForLinkSet($iId, $oAttDef, $value, $sWizardHelperJsVarName, $aArgs['this']);
|
||||
}
|
||||
$oTagSetBlock->SetName("attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}");
|
||||
$aEventsList[] = 'validate';
|
||||
|
||||
@@ -685,15 +685,15 @@ JS
|
||||
}
|
||||
$oFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
||||
$oBlock = new DisplayBlock($oFilter, 'search', false, $aParams);
|
||||
$oPage->AddUiBlock($oBlock->GetDisplay($oPage, $this->iId,
|
||||
$oPage->AddUiBlock($oBlock->GetDisplay($oPage, 'dtc_'.$this->iId,
|
||||
array(
|
||||
'menu' => false,
|
||||
'currentId' => $this->iId,
|
||||
'table_id' => "dr_{$this->iId}",
|
||||
'menu' => false,
|
||||
'currentId' => $this->iId,
|
||||
'table_id' => "dr_{$this->iId}",
|
||||
'table_inner_id' => "{$this->iId}_results",
|
||||
'selection_mode' => true,
|
||||
'selection_type' => 'single',
|
||||
'cssCount' => '#count_'.$this->iId.'_results',
|
||||
'cssCount' => '#count_'.$this->iId.'_results',
|
||||
)
|
||||
));
|
||||
$sCancel = Dict::S('UI:Button:Cancel');
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
let LinkSetWorker = new function(){
|
||||
|
||||
// defines
|
||||
const ROUTER_BASE_URL = '../pages/ajax.render.php';
|
||||
const ROUTE_LINK_SET_DELETE_OBJECT = 'linkset.delete_linked_object';
|
||||
const ROUTE_LINK_SET_DETACH_OBJECT = 'linkset.detach_linked_object';
|
||||
const ROUTE_LINK_SET_MODIFY_OBJECT = 'object.modify';
|
||||
const ROUTE_LINK_SET_CREATE_OBJECT = 'linkset.create_linked_object';
|
||||
|
||||
/**
|
||||
* CallAjaxDeleteLinkedObject.
|
||||
*
|
||||
* @param sLinkedObjectClass
|
||||
* @param sLinkedObjectKey
|
||||
* @param sTableId
|
||||
* @constructor
|
||||
*/
|
||||
const CallAjaxDeleteLinkedObject = function(sLinkedObjectClass, sLinkedObjectKey, sTableId){
|
||||
let oTableSettingsDialog = $('#datatable_dlg_datatable_' + sTableId);
|
||||
|
||||
$.post(`${ROUTER_BASE_URL}?route=${ROUTE_LINK_SET_DELETE_OBJECT}`, {
|
||||
linked_object_class: sLinkedObjectClass,
|
||||
linked_object_key: sLinkedObjectKey,
|
||||
transaction_id: $('#linkset_transactions_id').val()
|
||||
}, function (data) {
|
||||
if(data.data.success === true){
|
||||
oTableSettingsDialog.DataTableSettings('DoRefresh');
|
||||
}
|
||||
else{
|
||||
CombodoModal.OpenInformativeModal(data.data.error_message, 'error');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* CallAjaxDetachLinkedObject.
|
||||
*
|
||||
* @param sLinkedObjectClass
|
||||
* @param sLinkedObjectKey
|
||||
* @param sExternalKeyAttCode
|
||||
* @param sTableId
|
||||
* @constructor
|
||||
*/
|
||||
const CallAjaxDetachLinkedObject = function(sLinkedObjectClass, sLinkedObjectKey, sExternalKeyAttCode, sTableId){
|
||||
let oTableSettingsDialog = $('#datatable_dlg_datatable_' + sTableId);
|
||||
|
||||
$.post(`${ROUTER_BASE_URL}?route=${ROUTE_LINK_SET_DETACH_OBJECT}`, {
|
||||
linked_object_class: sLinkedObjectClass,
|
||||
linked_object_key: sLinkedObjectKey,
|
||||
external_key_att_code: sExternalKeyAttCode,
|
||||
transaction_id: $('#linkset_transactions_id').val()
|
||||
}, function (data) {
|
||||
if(data.data.success === true){
|
||||
oTableSettingsDialog.DataTableSettings('DoRefresh');
|
||||
}
|
||||
else{
|
||||
CombodoModal.OpenInformativeModal(data.data.error_message, 'error');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* CallAjaxModifyLinkedObject.
|
||||
*
|
||||
* @param {string} sLinkedObjectClass
|
||||
* @param {string} sLinkedObjectKey
|
||||
* @param {string} sTableId
|
||||
* @constructor
|
||||
*/
|
||||
const CallAjaxModifyLinkedObject = function(sLinkedObjectClass, sLinkedObjectKey, sTableId){
|
||||
let oTable = $('#datatable_' + sTableId);
|
||||
let oTableSettingsDialog = $('#datatable_dlg_datatable_' + sTableId);
|
||||
|
||||
let oOptions = {
|
||||
title: Dict.S('UI:Links:ActionRow:Modify:Modal:Title'),
|
||||
content: {
|
||||
endpoint: `${ROUTER_BASE_URL}?route=${ROUTE_LINK_SET_MODIFY_OBJECT}`,
|
||||
data: {
|
||||
class: sLinkedObjectClass,
|
||||
id: sLinkedObjectKey,
|
||||
},
|
||||
},
|
||||
extra_options: {
|
||||
callback_on_modal_close: function () {
|
||||
oTableSettingsDialog.DataTableSettings('DoRefresh');
|
||||
$(this).find("form").remove();
|
||||
$(this).dialog('destroy');
|
||||
}
|
||||
},
|
||||
}
|
||||
CombodoModal.OpenModal(oOptions);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sTableId
|
||||
*/
|
||||
const CallAjaxCreateLinkedObject = function(sTableId){
|
||||
let oTable = $('#datatable_' + sTableId);
|
||||
let oTableSettingsDialog = $('#datatable_dlg_datatable_' + sTableId);
|
||||
let sClass = oTable.closest('[data-role="ibo-block-links-table"]').attr('data-link-class');
|
||||
let sAttCode = oTable.closest('[data-role="ibo-block-links-table"]').attr('data-link-attcode');
|
||||
let sHostObjectClass = oTable.closest('[data-role="ibo-object-details"]').attr('data-object-class');
|
||||
let sHostObjectId = oTable.closest('[data-role="ibo-object-details"]').attr('data-object-id');
|
||||
|
||||
let oOptions = {
|
||||
title: Dict.S('UI:Layout:ObjectDetails:New:Modal:Title'),
|
||||
content: {
|
||||
endpoint: `${ROUTER_BASE_URL}?route=${ROUTE_LINK_SET_CREATE_OBJECT}`,
|
||||
data: {
|
||||
class: sClass,
|
||||
att_code: sAttCode,
|
||||
host_class: sHostObjectClass,
|
||||
host_id: sHostObjectId
|
||||
}
|
||||
},
|
||||
extra_options: {
|
||||
callback_on_modal_close: function () {
|
||||
oTableSettingsDialog.DataTableSettings('DoRefresh');
|
||||
$(this).find("form").remove();
|
||||
$(this).dialog('destroy');
|
||||
}
|
||||
},
|
||||
}
|
||||
CombodoModal.OpenModal(oOptions);
|
||||
};
|
||||
|
||||
return {
|
||||
DeleteLinkedObject: CallAjaxDeleteLinkedObject,
|
||||
DetachLinkedObject: CallAjaxDetachLinkedObject,
|
||||
ModifyLinkedObject: CallAjaxModifyLinkedObject,
|
||||
CreateLinkedObject: CallAjaxCreateLinkedObject
|
||||
}
|
||||
};
|
||||
@@ -33,15 +33,9 @@ $(function()
|
||||
submit_to: '../pages/ajax.render.php',
|
||||
submit_parameters: {},
|
||||
labels: {
|
||||
// 'delete': 'Delete',
|
||||
// modify: 'Modify...' ,
|
||||
creation_title: 'Creation of a new object...' ,
|
||||
// create: 'Create...',
|
||||
// add: 'Add...',
|
||||
// remove: 'Remove',
|
||||
selection_title: 'Objects selection'
|
||||
},
|
||||
// buttons: ['create', 'delete'],
|
||||
oWizardHelper: null
|
||||
},
|
||||
|
||||
@@ -56,12 +50,6 @@ $(function()
|
||||
|
||||
this.datatable = this.element.find('table.listResults');
|
||||
|
||||
// var aButtonsTypes = ['delete', 'remove', 'modify', 'add', 'create'];
|
||||
// this.oButtons = {};
|
||||
// for(k in aButtonsTypes)
|
||||
// {
|
||||
// this.oButtons[aButtonsTypes[k]] = $('<button class="ibo-button ibo-is-regular ibo-is-neutral" type="button">' + this.options.labels[aButtonsTypes[k]] + '</button>');
|
||||
// }
|
||||
this.indicator = $('<span></span>');
|
||||
this.inputToBeCreated = $('<input type="hidden" name="'+this.options.input_name+'_tbc" value="{}">');
|
||||
this.toBeCreated = {};
|
||||
@@ -80,27 +68,9 @@ $(function()
|
||||
.after(this.inputToBeRemoved)
|
||||
.after(this.indicator);
|
||||
|
||||
// for (k in this.options.buttons) {
|
||||
// this.element.after(this.oButtons[this.options.buttons[k]]).after(' ');
|
||||
// }
|
||||
|
||||
this.element.find('.selectList'+this.id).bind('change', function () {
|
||||
me._updateButtons();
|
||||
});
|
||||
// this.oButtons['delete'].on('click', function () {
|
||||
// me._deleteSelection();
|
||||
// });
|
||||
// this.oButtons['create'].on('click', function () {
|
||||
// me._createRow();
|
||||
// });
|
||||
// this.oButtons['remove'].on('click', function () {
|
||||
// $('.selectList'+me.id+':checked', me.element).each(function () {
|
||||
// me._removeRow($(this));
|
||||
// });
|
||||
// });
|
||||
// this.oButtons['add'].on('click', function () {
|
||||
// me._selectToAdd();
|
||||
// });
|
||||
|
||||
this._updateButtons();
|
||||
|
||||
@@ -132,24 +102,16 @@ $(function()
|
||||
}
|
||||
},
|
||||
_updateButtons: function () {
|
||||
var oChecked = $('.selectList'+this.id+':checked', this.element);
|
||||
const oChecked = $('.selectList'+this.id+':checked', this.element);
|
||||
switch (oChecked.length) {
|
||||
case 0:
|
||||
// this.oButtons['delete'].prop('disabled', true);
|
||||
// this.oButtons['remove'].prop('disabled', true);
|
||||
// this.oButtons['modify'].prop('disabled', true);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// this.oButtons['delete'].prop('disabled', false);
|
||||
// this.oButtons['remove'].prop('disabled', false);
|
||||
// this.oButtons['modify'].prop('disabled', false);
|
||||
$('[data-role="ibo-button"][data-action="delete"]', this.element).prop('disabled', true);
|
||||
$('[data-role="ibo-button"][data-action="detach"]', this.element).prop('disabled', true);
|
||||
break;
|
||||
|
||||
default:
|
||||
// this.oButtons['delete'].prop('disabled', false);
|
||||
// this.oButtons['remove'].prop('disabled', false);
|
||||
// this.oButtons['modify'].prop('disabled', true);
|
||||
$('[data-role="ibo-button"][data-action="delete"]', this.element).prop('disabled', false);
|
||||
$('[data-role="ibo-button"][data-action="detach"]', this.element).prop('disabled', false);
|
||||
break;
|
||||
}
|
||||
},
|
||||
@@ -186,7 +148,7 @@ $(function()
|
||||
this.oDlg.dialog('option', {position: {my: "center", at: "center", of: window}});
|
||||
},
|
||||
_createRow: function () {
|
||||
// this.oButtons['create'].prop('disabled', true);
|
||||
$('[data-role="ibo-button"][data-action="create"]', this.element).prop('disabled', true);
|
||||
this.indicator.html('<img src="../images/indicator.gif">');
|
||||
oParams = this.options.submit_parameters;
|
||||
oParams.operation = 'createObject';
|
||||
@@ -225,14 +187,14 @@ $(function()
|
||||
}
|
||||
});
|
||||
me.indicator.html('');
|
||||
// me.oButtons['create'].prop('disabled', false);
|
||||
$('[data-role="ibo-button"][data-action="create"]', this.element).prop('disabled', false);
|
||||
me._updateDlgPosition();
|
||||
|
||||
});
|
||||
},
|
||||
_selectToAdd: function()
|
||||
{
|
||||
// this.oButtons['add'].prop('disabled', true);
|
||||
$('[data-role="ibo-button"][data-action="add"]', this.element).prop('disabled', true);
|
||||
this.indicator.html('<img src="../images/indicator.gif">');
|
||||
oParams = this.options.submit_parameters;
|
||||
oParams.operation = 'selectObjectsToAdd';
|
||||
@@ -298,7 +260,7 @@ $(function()
|
||||
|
||||
});
|
||||
me.indicator.html('');
|
||||
// me.oButtons['add'].prop('disabled', false);
|
||||
$('[data-role="ibo-button"][data-action="add"]', this.element).prop('disabled', false);
|
||||
if (me.options.do_search)
|
||||
{
|
||||
me._onSearchToAdd();
|
||||
@@ -468,7 +430,7 @@ $(function()
|
||||
|
||||
me._updateTable();
|
||||
me.indicator.html('');
|
||||
// me.oButtons['add'].prop('disabled', false);
|
||||
$('[data-role="ibo-button"][data-action="add"]', this.element).prop('disabled', false);
|
||||
|
||||
me._updateTableInformation();
|
||||
});
|
||||
@@ -535,7 +497,7 @@ $(function()
|
||||
oParams.tempId = nextIdx;
|
||||
var me = this;
|
||||
|
||||
// this.oButtons['create'].prop('disabled', true);
|
||||
$('[data-role="ibo-button"][data-action="create"]', this.element).prop('disabled', true);
|
||||
this.indicator.html('<img src="../images/indicator.gif">');
|
||||
|
||||
$.post(this.options.submit_to, oParams, function (data) {
|
||||
@@ -545,7 +507,7 @@ $(function()
|
||||
|
||||
me._updateTable();
|
||||
me.indicator.html('');
|
||||
// me.oButtons['create'].prop('disabled', false);
|
||||
$('[data-role="ibo-button"][data-action="create"]', this.element).prop('disabled', false);
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -656,6 +618,18 @@ $(function()
|
||||
Remove: function(oCheckbox) // for public access
|
||||
{
|
||||
this._removeRow(oCheckbox);
|
||||
},
|
||||
selectToAdd: function(){
|
||||
this._selectToAdd();
|
||||
},
|
||||
removeSelection: function(){
|
||||
this._removeSelection();
|
||||
},
|
||||
createRow: function(){
|
||||
this._createRow();
|
||||
},
|
||||
deleteSelection: function(){
|
||||
this._deleteSelection();
|
||||
}
|
||||
});
|
||||
});
|
||||
46
js/links/links_set.js
Normal file
46
js/links/links_set.js
Normal file
@@ -0,0 +1,46 @@
|
||||
let CombodoLinkSet = new function () {
|
||||
|
||||
/**
|
||||
* Create a new link object and add it to set widget.
|
||||
*
|
||||
* @param sLinkedClass
|
||||
* @param sCode
|
||||
* @param sHostObjectClass
|
||||
* @param sHostObjectKey
|
||||
* @param sRemoteExtKey
|
||||
* @param sRemoteClass
|
||||
* @param oWidget
|
||||
* @constructor
|
||||
*/
|
||||
const CallCreateLinkedObject = function(sLinkedClass, sCode, sHostObjectClass, sHostObjectKey, sRemoteExtKey, sRemoteClass, oWidget)
|
||||
{
|
||||
// Create link object
|
||||
CombodoLinkSetWorker.CreateLinkedObject(sLinkedClass, sCode, sHostObjectClass, sHostObjectKey,
|
||||
function(){
|
||||
$(this).find("form").remove();
|
||||
$(this).dialog('destroy');
|
||||
},
|
||||
function(event, data){
|
||||
|
||||
// We have just create a link object, now request the remote object
|
||||
CombodoLinkSetWorker.GetRemoteObject(data.data.object.class_name, data.data.object.key, sRemoteExtKey, sRemoteClass, function(data){
|
||||
|
||||
// Add the new remote object in widget set options list
|
||||
const selectize = oWidget[0].selectize;
|
||||
selectize.addOption(data.data.object);
|
||||
selectize.refreshOptions(false);
|
||||
|
||||
// Select the new remote object
|
||||
selectize.addItem(data.data.object.key);
|
||||
|
||||
// Add to initial values, to handle remove action
|
||||
selectize.addInitialValue(data.data.object.key);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
CreateLinkedObject: CallCreateLinkedObject,
|
||||
}
|
||||
};
|
||||
106
js/links/links_set_worker.js
Normal file
106
js/links/links_set_worker.js
Normal file
@@ -0,0 +1,106 @@
|
||||
let CombodoLinkSetWorker = new function(){
|
||||
|
||||
// defines
|
||||
const ROUTER_BASE_URL = '../pages/ajax.render.php';
|
||||
const ROUTE_LINK_SET_DELETE_OBJECT = 'linkset.delete_linked_object';
|
||||
const ROUTE_LINK_SET_DETACH_OBJECT = 'linkset.detach_linked_object';
|
||||
const ROUTE_LINK_SET_CREATE_OBJECT = 'linkset.create_linked_object';
|
||||
const ROUTE_LINK_GET_REMOTE_OBJECT = 'linkset.get_remote_object';
|
||||
|
||||
/**
|
||||
* CallAjaxDeleteLinkedObject.
|
||||
*
|
||||
* @param {string} sLinkedObjectClass
|
||||
* @param {string} sLinkedObjectKey
|
||||
* @param oOnResponseCallback
|
||||
* @constructor
|
||||
*/
|
||||
const CallAjaxDeleteLinkedObject = function(sLinkedObjectClass, sLinkedObjectKey, oOnResponseCallback){
|
||||
|
||||
$.post(`${ROUTER_BASE_URL}?route=${ROUTE_LINK_SET_DELETE_OBJECT}`, {
|
||||
linked_object_class: sLinkedObjectClass,
|
||||
linked_object_key: sLinkedObjectKey,
|
||||
transaction_id: $('#linkset_transactions_id').val()
|
||||
}, oOnResponseCallback);
|
||||
};
|
||||
|
||||
/**
|
||||
* CallAjaxDetachLinkedObject.
|
||||
*
|
||||
* @param {string} sLinkedObjectClass
|
||||
* @param {string} sLinkedObjectKey
|
||||
* @param {string} sExternalKeyAttCode
|
||||
* @param oOnResponseCallback
|
||||
* @constructor
|
||||
*/
|
||||
const CallAjaxDetachLinkedObject = function(sLinkedObjectClass, sLinkedObjectKey, sExternalKeyAttCode, oOnResponseCallback){
|
||||
|
||||
$.post(`${ROUTER_BASE_URL}?route=${ROUTE_LINK_SET_DETACH_OBJECT}`, {
|
||||
linked_object_class: sLinkedObjectClass,
|
||||
linked_object_key: sLinkedObjectKey,
|
||||
external_key_att_code: sExternalKeyAttCode,
|
||||
transaction_id: $('#linkset_transactions_id').val()
|
||||
}, oOnResponseCallback);
|
||||
};
|
||||
|
||||
/**
|
||||
* CallAjaxCreateLinkedObject.
|
||||
*
|
||||
* @param {string} sClass
|
||||
* @param {string} sAttCode
|
||||
* @param {string} sHostObjectClass
|
||||
* @param {string} sHostObjectId
|
||||
* @param oOnModalCloseCallback
|
||||
* @param oOnFormSubmittedCallback
|
||||
*/
|
||||
const CallAjaxCreateLinkedObject = function(sClass, sAttCode, sHostObjectClass, sHostObjectId, oOnModalCloseCallback = null, oOnFormSubmittedCallback = null){
|
||||
|
||||
let oOptions = {
|
||||
title: Dict.S('UI:Links:New:Modal:Title'),
|
||||
content: {
|
||||
endpoint: `${ROUTER_BASE_URL}?route=${ROUTE_LINK_SET_CREATE_OBJECT}`,
|
||||
data: {
|
||||
class: sClass,
|
||||
att_code: sAttCode,
|
||||
host_class: sHostObjectClass,
|
||||
host_id: sHostObjectId
|
||||
}
|
||||
},
|
||||
extra_options: {
|
||||
callback_on_modal_close: oOnModalCloseCallback
|
||||
},
|
||||
}
|
||||
|
||||
const oModal = CombodoModal.OpenModal(oOptions);
|
||||
if(oOnFormSubmittedCallback !== null){
|
||||
oModal.on('itop.form.submitted', 'form', oOnFormSubmittedCallback);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* CallGetRemoteObject.
|
||||
*
|
||||
* @param sLinkedObjectClass
|
||||
* @param sLinkedObjectKey
|
||||
* @param sExternalKeyAttCode
|
||||
* @param sRemoteClass
|
||||
* @param oOnResponseCallback
|
||||
* @constructor
|
||||
*/
|
||||
const CallGetRemoteObject = function(sLinkedObjectClass, sLinkedObjectKey, sExternalKeyAttCode, sRemoteClass, oOnResponseCallback){
|
||||
|
||||
$.post(`${ROUTER_BASE_URL}?route=${ROUTE_LINK_GET_REMOTE_OBJECT}`, {
|
||||
linked_object_class: sLinkedObjectClass,
|
||||
linked_object_key: sLinkedObjectKey,
|
||||
external_key_att_code: sExternalKeyAttCode,
|
||||
remote_class: sRemoteClass
|
||||
}, oOnResponseCallback);
|
||||
};
|
||||
|
||||
return {
|
||||
DeleteLinkedObject: CallAjaxDeleteLinkedObject,
|
||||
DetachLinkedObject: CallAjaxDetachLinkedObject,
|
||||
CreateLinkedObject: CallAjaxCreateLinkedObject,
|
||||
GetRemoteObject: CallGetRemoteObject
|
||||
}
|
||||
};
|
||||
116
js/links/links_view_table_widget.js
Normal file
116
js/links/links_view_table_widget.js
Normal file
@@ -0,0 +1,116 @@
|
||||
$(function()
|
||||
{
|
||||
// the widget definition, where "itop" is the namespace,
|
||||
// "links_view_table" the widget name
|
||||
$.widget( "itop.links_view_table",
|
||||
{
|
||||
|
||||
// default options
|
||||
options:
|
||||
{
|
||||
link_class: null,
|
||||
external_key_to_me: null
|
||||
},
|
||||
|
||||
// the constructor
|
||||
_create: function () {
|
||||
$Table = $('table', this.element);
|
||||
this.$tableSettingsDialog = $('#datatable_dlg_' + $Table.attr('id'));
|
||||
},
|
||||
|
||||
// the destructor
|
||||
_destroy: function () {
|
||||
},
|
||||
|
||||
/**
|
||||
* DeleteLinkedObject.
|
||||
*
|
||||
* @param sLinkedObjectKey
|
||||
* @param oTrElement
|
||||
* @constructor
|
||||
*/
|
||||
DeleteLinkedObject: function (sLinkedObjectKey, oTrElement) {
|
||||
|
||||
const me = this;
|
||||
|
||||
// link object deletion
|
||||
CombodoLinkSetWorker.DeleteLinkedObject(this.options.link_class, sLinkedObjectKey, function (data) {
|
||||
if (data.data.success === true) {
|
||||
oTrElement.remove();
|
||||
} else {
|
||||
CombodoModal.OpenInformativeModal(data.data.error_message, 'error');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* DetachLinkedObject.
|
||||
*
|
||||
* @param sLinkedObjectKey
|
||||
* @param oTrElement
|
||||
* @constructor
|
||||
*/
|
||||
DetachLinkedObject: function (sLinkedObjectKey, oTrElement) {
|
||||
|
||||
const me = this;
|
||||
|
||||
// link object unlink
|
||||
CombodoLinkSetWorker.DetachLinkedObject(this.options.link_class, sLinkedObjectKey, this.options.external_key_to_me, function (data) {
|
||||
if (data.data.success === true) {
|
||||
oTrElement.remove();
|
||||
} else {
|
||||
CombodoModal.OpenInformativeModal(data.data.error_message, 'error');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* CreateLinkedObject.
|
||||
*
|
||||
*/
|
||||
CreateLinkedObject: function () {
|
||||
|
||||
const me = this;
|
||||
|
||||
// retrieve table
|
||||
const $Table = $('table', this.element);
|
||||
|
||||
// retrieve context parameters
|
||||
const sClass = $Table.closest('[data-role="ibo-block-links-table"]').attr('data-link-class');
|
||||
const sAttCode = $Table.closest('[data-role="ibo-block-links-table"]').attr('data-link-attcode');
|
||||
const sHostObjectClass = $Table.closest('[data-role="ibo-object-details"]').attr('data-object-class');
|
||||
const sHostObjectId = $Table.closest('[data-role="ibo-object-details"]').attr('data-object-id');
|
||||
|
||||
// link object creation
|
||||
CombodoLinkSetWorker.CreateLinkedObject(sClass, sAttCode, sHostObjectClass, sHostObjectId, function(){
|
||||
$(this).find("form").remove();
|
||||
$(this).dialog('destroy');
|
||||
},function (event, data) {
|
||||
if(data.success){
|
||||
me.$tableSettingsDialog.DataTableSettings('DoRefresh');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* ModifyLinkedObject.
|
||||
*
|
||||
* @param {string} sLinkedObjectKey
|
||||
*/
|
||||
ModifyLinkedObject: function (sLinkedObjectKey) {
|
||||
|
||||
const me = this;
|
||||
|
||||
// link object modification
|
||||
ObjectWorker.ModifyObject(this.options.link_class, sLinkedObjectKey, function () {
|
||||
$(this).find("form").remove();
|
||||
$(this).dialog('destroy');
|
||||
}, function(event, data){
|
||||
if(data.success) {
|
||||
me.$tableSettingsDialog.DataTableSettings('DoRefresh');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
});
|
||||
});
|
||||
60
js/objects/objects_worker.js
Normal file
60
js/objects/objects_worker.js
Normal file
@@ -0,0 +1,60 @@
|
||||
let ObjectWorker = new function(){
|
||||
|
||||
// defines
|
||||
const ROUTER_BASE_URL = '../pages/ajax.render.php';
|
||||
const ROUTE_MODIFY_OBJECT = 'object.modify';
|
||||
const ROUTE_GET_OBJECT = 'object.get';
|
||||
|
||||
/**
|
||||
* CallAjaxModifyObject.
|
||||
*
|
||||
* @param {string} sObjectClass
|
||||
* @param {string} sObjectKey
|
||||
* @param oOnModalCloseCallback
|
||||
* @param oOnFormSubmittedCallback
|
||||
* @constructor
|
||||
*/
|
||||
const CallAjaxModifyObject = function(sObjectClass, sObjectKey, oOnModalCloseCallback, oOnFormSubmittedCallback){
|
||||
|
||||
let oOptions = {
|
||||
title: Dict.S('UI:Links:ActionRow:Modify:Modal:Title'),
|
||||
content: {
|
||||
endpoint: `${ROUTER_BASE_URL}?route=${ROUTE_MODIFY_OBJECT}`,
|
||||
data: {
|
||||
class: sObjectClass,
|
||||
id: sObjectKey,
|
||||
},
|
||||
},
|
||||
extra_options: {
|
||||
callback_on_modal_close: oOnModalCloseCallback
|
||||
},
|
||||
}
|
||||
|
||||
const oModal = CombodoModal.OpenModal(oOptions);
|
||||
if(oOnFormSubmittedCallback !== null){
|
||||
oModal.on('itop.form.submitted', 'form', oOnFormSubmittedCallback);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* CallAjaxGetObject.
|
||||
*
|
||||
* @param {string} sObjectClass
|
||||
* @param {string} sObjectKey
|
||||
* @param oOnResponseCallback
|
||||
* @constructor
|
||||
*/
|
||||
const CallAjaxGetObject = function(sObjectClass, sObjectId, oOnResponseCallback){
|
||||
|
||||
$.post(`${ROUTER_BASE_URL}?route=${ROUTE_GET_OBJECT}`, {
|
||||
object_class: sObjectClass,
|
||||
object_key: sObjectId,
|
||||
}, oOnResponseCallback);
|
||||
};
|
||||
|
||||
|
||||
return {
|
||||
ModifyObject: CallAjaxModifyObject,
|
||||
GetObject: CallAjaxGetObject
|
||||
}
|
||||
};
|
||||
@@ -78,14 +78,14 @@ Selectize.define("combodo_multi_values_synthesis", function (aOptions) {
|
||||
}
|
||||
// Element exist in default selection,
|
||||
// click allow user to switch between add or ignore states
|
||||
if(oSelf.settings.initial.includes(sItemValue)) {
|
||||
if(oSelf.plugins.settings.combodo_update_operations.initial.includes(sItemValue)) {
|
||||
oSelf.listenClick($Item, sItemValue);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// If no operation to restore
|
||||
if(!oSelf.settings.initial.includes(sItemValue)) {
|
||||
if(!oSelf.plugins.settings.combodo_update_operations.initial.includes(sItemValue)) {
|
||||
|
||||
// Element doesn't exist in initial value, we mark it as added
|
||||
oSelf.Add($Item, sItemValue);
|
||||
@@ -112,7 +112,7 @@ Selectize.define("combodo_multi_values_synthesis", function (aOptions) {
|
||||
const $Item = oSelf.getItem(sItem);
|
||||
|
||||
// Element doesn't exist in default selection,
|
||||
if(!oSelf.settings.initial.includes(sItem)) {
|
||||
if(!oSelf.plugins.settings.combodo_update_operations.initial.includes(sItem)) {
|
||||
|
||||
// Remove operation
|
||||
delete aOperations[sItem];
|
||||
|
||||
@@ -15,11 +15,18 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
Selectize.define("combodo_update_operations", function () {
|
||||
Selectize.define("combodo_update_operations", function (aOptions) {
|
||||
|
||||
// Selectize instance
|
||||
let oSelf = this;
|
||||
|
||||
// Plugin options
|
||||
aOptions = $.extend({
|
||||
initial: [],
|
||||
},
|
||||
aOptions
|
||||
);
|
||||
|
||||
// Plugin variables
|
||||
oSelf.bIsInitialized = false;
|
||||
oSelf.operations = {};
|
||||
@@ -88,7 +95,7 @@ Selectize.define("combodo_update_operations", function () {
|
||||
|
||||
// Scan items in current value and not in initial value
|
||||
aCurrentItems.forEach(function(e){
|
||||
if(!oSelf.settings.initial.includes(e)){
|
||||
if(!aOptions.initial.includes(e)){
|
||||
oSelf.operations[e] = {
|
||||
operation: 'add',
|
||||
data: CombodoGlobalToolbox.ExtractArrayItemsContainingThisKeyAndValue(aCurrentOptions, oSelf.settings.valueField, e)
|
||||
@@ -97,7 +104,7 @@ Selectize.define("combodo_update_operations", function () {
|
||||
});
|
||||
|
||||
// scan items in initial value and not in current value
|
||||
oSelf.settings.initial.forEach(function(e){
|
||||
aOptions.initial.forEach(function(e){
|
||||
if(!aCurrentItems.includes(e)){
|
||||
oSelf.operations[e] = {
|
||||
operation: 'remove',
|
||||
@@ -109,4 +116,12 @@ Selectize.define("combodo_update_operations", function () {
|
||||
};
|
||||
})();
|
||||
|
||||
// Declare addInitialValue function
|
||||
oSelf.addInitialValue = (function () {
|
||||
return function (value) {
|
||||
aOptions.initial.push(value);
|
||||
oSelf.updateOperationsInput();
|
||||
};
|
||||
})();
|
||||
|
||||
});
|
||||
@@ -5,7 +5,7 @@
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
'reference' => '9482139b5aec9978f05b1cbb0542b24c18681819',
|
||||
'reference' => 'f25f91ad79b38d9dcbe2a175bdb2fd2635255968',
|
||||
'name' => 'combodo/itop',
|
||||
'dev' => true,
|
||||
),
|
||||
@@ -25,7 +25,7 @@
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
'reference' => '9482139b5aec9978f05b1cbb0542b24c18681819',
|
||||
'reference' => 'f25f91ad79b38d9dcbe2a175bdb2fd2635255968',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'combodo/tcpdf' => array(
|
||||
|
||||
@@ -34,7 +34,6 @@ $oP->add_linked_script("../js/json.js");
|
||||
$oP->add_linked_script("../js/forms-json-utils.js");
|
||||
$oP->add_linked_script("../js/wizardhelper.js");
|
||||
$oP->add_linked_script("../js/wizard.utils.js");
|
||||
$oP->add_linked_script("../js/linkswidget.js");
|
||||
$oP->add_linked_script("../js/extkeywidget.js");
|
||||
$oP->add_linked_script("../js/jquery.blockUI.js");
|
||||
|
||||
|
||||
@@ -37,7 +37,6 @@ try
|
||||
$oP->add_linked_script("../js/forms-json-utils.js");
|
||||
$oP->add_linked_script("../js/wizardhelper.js");
|
||||
$oP->add_linked_script("../js/wizard.utils.js");
|
||||
$oP->add_linked_script("../js/linkswidget.js");
|
||||
$oP->add_linked_script("../js/extkeywidget.js");
|
||||
$oP->add_linked_script("../js/jquery.blockUI.js");
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ class Set extends AbstractInput
|
||||
public const DEFAULT_JS_ON_READY_TEMPLATE_REL_PATH = 'base/components/input/set/layout';
|
||||
|
||||
public const DEFAULT_JS_FILES_REL_PATH = [
|
||||
'js/links/links_set_worker.js',
|
||||
'js/selectize/plugin_combodo_add_button.js',
|
||||
'js/selectize/plugin_combodo_auto_position.js',
|
||||
'js/selectize/plugin_combodo_update_operations.js',
|
||||
@@ -55,6 +56,9 @@ class Set extends AbstractInput
|
||||
/** @var bool $bHasAddOptionButton Enable add option button */
|
||||
private bool $bHasAddOptionButton;
|
||||
|
||||
/** @var string|null $sAddOptionButtonJsOnClick JS code to execute on button click */
|
||||
private ?string $sAddOptionButtonJsOnClick;
|
||||
|
||||
/** @var string $sAddButtonTitle Add button title */
|
||||
private string $sAddButtonTitle;
|
||||
|
||||
@@ -103,6 +107,7 @@ class Set extends AbstractInput
|
||||
$this->iMaxOptions = null;
|
||||
$this->bHasRemoveItemButton = true;
|
||||
$this->bHasAddOptionButton = false;
|
||||
$this->sAddOptionButtonJsOnClick = null;
|
||||
$this->sAddButtonTitle = Dict::S('UI:Button:Create');
|
||||
$this->bIsPreloadEnabled = false;
|
||||
$this->sTemplateOptions = null;
|
||||
@@ -183,6 +188,30 @@ class Set extends AbstractInput
|
||||
return $this->bHasRemoveItemButton;
|
||||
}
|
||||
|
||||
/**
|
||||
* SetAddOptionButtonJsOnClick.
|
||||
*
|
||||
* @param string $sJsOnClick
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function SetAddOptionButtonJsOnClick(string $sJsOnClick): Set
|
||||
{
|
||||
$this->sAddOptionButtonJsOnClick = $sJsOnClick;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* GetAddOptionButtonJsOnClick.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetAddOptionButtonJsOnClick(): string
|
||||
{
|
||||
return $this->sAddOptionButtonJsOnClick;
|
||||
}
|
||||
|
||||
/**
|
||||
* SetHasAddOptionButton.
|
||||
*
|
||||
|
||||
@@ -32,10 +32,12 @@ use WebPage;
|
||||
abstract class AbstractBlockLinksViewTable extends UIContentBlock
|
||||
{
|
||||
// Overloaded constants
|
||||
public const BLOCK_CODE = 'ibo-abstract-block-links-view-table';
|
||||
public const DEFAULT_JS_TEMPLATE_REL_PATH = 'application/links/layout';
|
||||
public const DEFAULT_JS_FILES_REL_PATH = [
|
||||
'js/links/link_set_worker.js',
|
||||
public const BLOCK_CODE = 'ibo-abstract-block-links-view-table';
|
||||
public const DEFAULT_JS_ON_READY_TEMPLATE_REL_PATH = 'application/links/layout';
|
||||
public const DEFAULT_JS_FILES_REL_PATH = [
|
||||
'js/links/links_view_table_widget.js',
|
||||
'js/links/links_set_worker.js',
|
||||
'js/objects/objects_worker.js',
|
||||
'js/wizardhelper.js',
|
||||
];
|
||||
|
||||
@@ -70,7 +72,7 @@ abstract class AbstractBlockLinksViewTable extends UIContentBlock
|
||||
*/
|
||||
public function __construct(WebPage $oPage, DBObject $oDbObject, string $sObjectClass, string $sAttCode, AttributeLinkedSet $oAttDef)
|
||||
{
|
||||
parent::__construct('', ["ibo-block-links-table"]);
|
||||
parent::__construct("links_view_table_$sAttCode", ["ibo-block-links-table"]);
|
||||
|
||||
// retrieve parameters
|
||||
$this->oAttDef = $oAttDef;
|
||||
@@ -204,6 +206,8 @@ abstract class AbstractBlockLinksViewTable extends UIContentBlock
|
||||
|
||||
|
||||
/**
|
||||
* GetAttCode.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetAttCode(): string
|
||||
@@ -211,4 +215,33 @@ abstract class AbstractBlockLinksViewTable extends UIContentBlock
|
||||
return $this->sAttCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* GetLinkedClass.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function GetLinkedClass()
|
||||
{
|
||||
return $this->oAttDef->GetLinkedClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* GetExternalKeyToMe.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function GetExternalKeyToMe()
|
||||
{
|
||||
return $this->oAttDef->GetExtKeyToMe();
|
||||
}
|
||||
|
||||
/**
|
||||
* GetWidgetName.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetWidgetName(): string
|
||||
{
|
||||
return "oWidget{$this->GetId()}";
|
||||
}
|
||||
}
|
||||
@@ -6,18 +6,28 @@
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Links\Direct;
|
||||
|
||||
use ApplicationContext;
|
||||
use ArchivedObjectException;
|
||||
use AttributeLinkedSet;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Alert\AlertUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Button\ButtonUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Html\Html;
|
||||
use Combodo\iTop\Application\UI\Base\Component\MedallionIcon\MedallionIcon;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Toolbar\Toolbar;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Toolbar\ToolbarUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\iUIBlock;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlock;
|
||||
use ConfigException;
|
||||
use CoreException;
|
||||
use CoreUnexpectedValue;
|
||||
use DBObjectSet;
|
||||
use Dict;
|
||||
use DictExceptionMissingString;
|
||||
use Exception;
|
||||
use MetaModel;
|
||||
use MySQLException;
|
||||
use UILinksWidgetDirect;
|
||||
use utils;
|
||||
use WebPage;
|
||||
|
||||
/**
|
||||
* Class BlockDirectLinksEditTable
|
||||
@@ -31,40 +41,43 @@ class BlockDirectLinksEditTable extends UIContentBlock
|
||||
// Overloaded constants
|
||||
public const BLOCK_CODE = 'ibo-block-direct-links-edit-table';
|
||||
public const DEFAULT_JS_TEMPLATE_REL_PATH = 'application/links/direct/block-direct-links-edit-table/layout';
|
||||
public const DEFAULT_JS_FILES_REL_PATH = [
|
||||
'js/links/links_direct_widget.js',
|
||||
];
|
||||
|
||||
/** @var \UILinksWidgetDirect */
|
||||
public \UILinksWidgetDirect $oUILinksDirectWidget;
|
||||
/** @var UILinksWidgetDirect $oUILinksDirectWidget */
|
||||
public UILinksWidgetDirect $oUILinksDirectWidget;
|
||||
|
||||
/** @var \AttributeLinkedSet */
|
||||
private \AttributeLinkedSet $oAttributeLinkedSet;
|
||||
/** @var AttributeLinkedSet $oAttributeLinkedSet */
|
||||
private AttributeLinkedSet $oAttributeLinkedSet;
|
||||
|
||||
/** @var string */
|
||||
/** @var string $sInputName */
|
||||
public string $sInputName;
|
||||
|
||||
/** @var array */
|
||||
/** @var array $aLabels */
|
||||
public array $aLabels;
|
||||
|
||||
/** @var string */
|
||||
/** @var string $sSubmitUrl */
|
||||
public string $sSubmitUrl;
|
||||
|
||||
/** @var string */
|
||||
/** @var string $sWizHelper */
|
||||
public string $sWizHelper;
|
||||
|
||||
/** @var string */
|
||||
/** @var string $sJSDoSearch */
|
||||
public string $sJSDoSearch;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param \UILinksWidgetDirect $oUILinksDirectWidget
|
||||
* @param UILinksWidgetDirect $oUILinksDirectWidget
|
||||
* @param string $sId
|
||||
*
|
||||
* @throws \ConfigException
|
||||
* @throws \CoreException
|
||||
* @throws \DictExceptionMissingString
|
||||
* @throws \Exception
|
||||
* @throws ConfigException
|
||||
* @throws CoreException
|
||||
* @throws DictExceptionMissingString
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct(\UILinksWidgetDirect $oUILinksDirectWidget, string $sId)
|
||||
public function __construct(UILinksWidgetDirect $oUILinksDirectWidget, string $sId)
|
||||
{
|
||||
parent::__construct($sId, ["ibo-block-direct-links--edit-in-place"]);
|
||||
|
||||
@@ -73,18 +86,14 @@ class BlockDirectLinksEditTable extends UIContentBlock
|
||||
|
||||
// compute
|
||||
$this->aLabels = array(
|
||||
'delete' => Dict::S('UI:Button:Delete'),
|
||||
'creation_title' => Dict::Format('UI:CreationTitle_Class', MetaModel::GetName($this->oUILinksDirectWidget->GetLinkedClass())),
|
||||
'create' => Dict::Format('UI:ClickToCreateNew', MetaModel::GetName($this->oUILinksDirectWidget->GetLinkedClass())),
|
||||
'remove' => Dict::S('UI:Button:Remove'),
|
||||
'add' => Dict::Format('UI:AddAnExisting_Class', MetaModel::GetName($this->oUILinksDirectWidget->GetLinkedClass())),
|
||||
'selection_title' => Dict::Format('UI:SelectionOf_Class', MetaModel::GetName($this->oUILinksDirectWidget->GetLinkedClass())),
|
||||
);
|
||||
$oContext = new \ApplicationContext();
|
||||
$this->sSubmitUrl = \utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?'.$oContext->GetForLink();
|
||||
$oContext = new ApplicationContext();
|
||||
$this->sSubmitUrl = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?'.$oContext->GetForLink();
|
||||
|
||||
// Don't automatically launch the search if the table is huge
|
||||
$bDoSearch = !\utils::IsHighCardinality($this->oUILinksDirectWidget->GetLinkedClass());
|
||||
$bDoSearch = !utils::IsHighCardinality($this->oUILinksDirectWidget->GetLinkedClass());
|
||||
$this->sJSDoSearch = $bDoSearch ? 'true' : 'false';
|
||||
|
||||
// Initialization
|
||||
@@ -98,7 +107,7 @@ class BlockDirectLinksEditTable extends UIContentBlock
|
||||
* Initialisation.
|
||||
*
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
private function Init()
|
||||
{
|
||||
@@ -109,8 +118,8 @@ class BlockDirectLinksEditTable extends UIContentBlock
|
||||
* Initialize UI.
|
||||
*
|
||||
* @return void
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
* @throws CoreException
|
||||
* @throws Exception
|
||||
*/
|
||||
private function InitUI()
|
||||
{
|
||||
@@ -118,15 +127,14 @@ class BlockDirectLinksEditTable extends UIContentBlock
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WebPage $oPage
|
||||
* @param \DBObjectSet $oValue
|
||||
* @param WebPage $oPage
|
||||
* @param DBObjectSet $oValue
|
||||
* @param string $sFormPrefix
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function InitTable(\WebPage $oPage, $oValue, string $sFormPrefix)
|
||||
public function InitTable(WebPage $oPage, DBObjectSet $oValue, string $sFormPrefix)
|
||||
{
|
||||
/** @todo fields initialization */
|
||||
$this->sInputName = $sFormPrefix.'attr_'.$this->oUILinksDirectWidget->GetAttCode();
|
||||
$this->sWizHelper = 'oWizardHelper'.$sFormPrefix;
|
||||
|
||||
@@ -138,7 +146,7 @@ class BlockDirectLinksEditTable extends UIContentBlock
|
||||
$oDatatable->SetOptions(['select_mode' => 'custom', 'disable_hyperlinks' => true]);
|
||||
|
||||
// Panel
|
||||
$aTablePanel = PanelUIBlockFactory::MakeForClass($this->oUILinksDirectWidget->GetLinkedClass(), $this->oAttributeLinkedSet->GetLabel())
|
||||
$oTablePanel = PanelUIBlockFactory::MakeForClass($this->oUILinksDirectWidget->GetLinkedClass(), $this->oAttributeLinkedSet->GetLabel())
|
||||
->SetSubTitle(Dict::Format('UI:Pagination:HeaderNoSelection', count($aRows)))
|
||||
->SetIcon(MetaModel::GetClassIcon($this->oUILinksDirectWidget->GetLinkedClass(), false))
|
||||
->AddCSSClass('ibo-datatable-panel');
|
||||
@@ -146,30 +154,17 @@ class BlockDirectLinksEditTable extends UIContentBlock
|
||||
// - Panel description
|
||||
$sDescription = $this->oAttributeLinkedSet->GetDescription();
|
||||
if (utils::IsNotNullOrEmptyString($sDescription)) {
|
||||
$oTitleBlock = $aTablePanel->GetTitleBlock()
|
||||
$oTitleBlock = $oTablePanel->GetTitleBlock()
|
||||
->AddDataAttribute('tooltip-content', $sDescription)
|
||||
->AddDataAttribute('tooltip-max-width', 'min(600px, 90vw)') // Allow big description to be wide enough while shrinking on small screens
|
||||
->AddCSSClass('ibo-has-description');
|
||||
}
|
||||
|
||||
// Toolbar and actions
|
||||
$oToolbar = ToolbarUIBlockFactory::MakeForButton();
|
||||
$oActionButtonUnlink = ButtonUIBlockFactory::MakeNeutral('Unlink');
|
||||
$oActionButtonUnlink->SetOnClickJsCode("$('#{$this->oUILinksDirectWidget->GetInputId()}').directlinks('instance')._removeSelection();");
|
||||
$oToolbar->AddSubBlock($oActionButtonUnlink);
|
||||
$oActionButtonLink = ButtonUIBlockFactory::MakeNeutral('Link');
|
||||
$oActionButtonLink->SetOnClickJsCode("$('#{$this->oUILinksDirectWidget->GetInputId()}').directlinks('instance')._selectToAdd();");
|
||||
$oToolbar->AddSubBlock($oActionButtonLink);
|
||||
$oActionButtonCreate = ButtonUIBlockFactory::MakeNeutral('Create');
|
||||
$oActionButtonCreate->SetOnClickJsCode("$('#{$this->oUILinksDirectWidget->GetInputId()}').directlinks('instance')._createRow();");
|
||||
$oToolbar->AddSubBlock($oActionButtonCreate);
|
||||
$oActionButtonDelete = ButtonUIBlockFactory::MakeNeutral('Delete');
|
||||
$oActionButtonDelete->SetOnClickJsCode("$('#{$this->oUILinksDirectWidget->GetInputId()}').directlinks('instance')._deleteSelection();");
|
||||
|
||||
$oToolbar->AddSubBlock($oActionButtonDelete);
|
||||
$aTablePanel->AddToolbarBlock($oToolbar);
|
||||
$aTablePanel->AddSubBlock($oDatatable);
|
||||
$this->AddSubBlock($aTablePanel);
|
||||
$oToolbar = $this->InitToolBar();
|
||||
$oTablePanel->AddToolbarBlock($oToolbar);
|
||||
$oTablePanel->AddSubBlock($oDatatable);
|
||||
$this->AddSubBlock($oTablePanel);
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
$oAlert = AlertUIBlockFactory::MakeForDanger('error', Dict::S('UI:Datatables:Language:Error'));
|
||||
@@ -179,18 +174,70 @@ class BlockDirectLinksEditTable extends UIContentBlock
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* InitToolBar.
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\Base\Component\Toolbar\Toolbar
|
||||
*/
|
||||
private function InitToolBar(): Toolbar
|
||||
{
|
||||
$oToolbar = ToolbarUIBlockFactory::MakeForButton();
|
||||
|
||||
// until a full link set refactoring (continue using edit_mode property)
|
||||
switch ($this->oAttributeLinkedSet->GetEditMode()) {
|
||||
case LINKSET_EDITMODE_NONE: // The linkset is read-only
|
||||
break;
|
||||
|
||||
case LINKSET_EDITMODE_ADDONLY: // The only possible action is to open (in a new window) the form to create a new object
|
||||
$oActionButtonLink = ButtonUIBlockFactory::MakeNeutral('Link', 'link');
|
||||
$oActionButtonLink->AddDataAttribute('action', 'add');
|
||||
$oActionButtonLink->SetOnClickJsCode("$('#{$this->oUILinksDirectWidget->GetInputId()}').directlinks('selectToAdd');");
|
||||
$oToolbar->AddSubBlock($oActionButtonLink);
|
||||
break;
|
||||
|
||||
case LINKSET_EDITMODE_INPLACE: // The whole linkset can be edited 'in-place'
|
||||
$oActionButtonCreate = ButtonUIBlockFactory::MakeNeutral('Create', 'create');
|
||||
$oActionButtonCreate->AddDataAttribute('action', 'create');
|
||||
$oActionButtonCreate->SetOnClickJsCode("$('#{$this->oUILinksDirectWidget->GetInputId()}').directlinks('createRow');");
|
||||
$oToolbar->AddSubBlock($oActionButtonCreate);
|
||||
$oActionButtonDelete = ButtonUIBlockFactory::MakeNeutral('Delete', 'delete');
|
||||
$oActionButtonDelete->AddDataAttribute('action', 'delete');
|
||||
$oActionButtonDelete->SetOnClickJsCode("$('#{$this->oUILinksDirectWidget->GetInputId()}').directlinks('deleteSelection');");
|
||||
$oToolbar->AddSubBlock($oActionButtonDelete);
|
||||
break;
|
||||
|
||||
case LINKSET_EDITMODE_ADDREMOVE: // The whole linkset can be edited 'in-place'
|
||||
$oActionButtonUnlink = ButtonUIBlockFactory::MakeNeutral('Unlink', 'unlink');
|
||||
$oActionButtonUnlink->AddDataAttribute('action', 'detach');
|
||||
$oActionButtonUnlink->SetOnClickJsCode("$('#{$this->oUILinksDirectWidget->GetInputId()}').directlinks('removeSelection');");
|
||||
$oToolbar->AddSubBlock($oActionButtonUnlink);
|
||||
$oActionButtonLink = ButtonUIBlockFactory::MakeNeutral('Link', 'link');
|
||||
$oActionButtonLink->AddDataAttribute('action', 'add');
|
||||
$oActionButtonLink->SetOnClickJsCode("$('#{$this->oUILinksDirectWidget->GetInputId()}').directlinks('selectToAdd');");
|
||||
$oToolbar->AddSubBlock($oActionButtonLink);
|
||||
break;
|
||||
|
||||
case LINKSET_EDITMODE_ACTIONS: // Show the usual 'Actions' popup menu
|
||||
default:
|
||||
|
||||
}
|
||||
|
||||
return $oToolbar;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return table rows.
|
||||
*
|
||||
* @param \DBObjectSet $oValue
|
||||
* @param DBObjectSet $oValue
|
||||
*
|
||||
* @return array
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \DictExceptionMissingString
|
||||
* @throws \MySQLException
|
||||
* @throws \Exception
|
||||
* @throws ArchivedObjectException
|
||||
* @throws CoreException
|
||||
* @throws CoreUnexpectedValue
|
||||
* @throws DictExceptionMissingString
|
||||
* @throws MySQLException
|
||||
* @throws Exception
|
||||
*/
|
||||
private function GetTableRows(\WebPage $oPage, \DBObjectSet $oValue): array
|
||||
{
|
||||
@@ -220,6 +267,41 @@ class BlockDirectLinksEditTable extends UIContentBlock
|
||||
return ($bSafe) ? \utils::GetSafeId($sFieldId) : $sFieldId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert edit_mode to relation type.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
private function ConvertEditModeToRelationType(): ?string
|
||||
{
|
||||
switch ($this->oAttributeLinkedSet->GetEditMode()) {
|
||||
case LINKSET_EDITMODE_INPLACE:
|
||||
return LINKSET_RELATIONTYPE_PROPERTY;
|
||||
case LINKSET_EDITMODE_ADDREMOVE:
|
||||
return LINKSET_RELATIONTYPE_LINK;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert edit_mode to read only.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function ConvertEditModeToReadOnly(): bool
|
||||
{
|
||||
switch ($this->oAttributeLinkedSet->GetEditMode()) {
|
||||
case LINKSET_EDITMODE_NONE:
|
||||
case LINKSET_EDITMODE_ADDONLY:
|
||||
case LINKSET_EDITMODE_ACTIONS:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return row actions.
|
||||
*
|
||||
@@ -229,9 +311,9 @@ class BlockDirectLinksEditTable extends UIContentBlock
|
||||
{
|
||||
$aRowActions = array();
|
||||
|
||||
if (!$this->oAttributeLinkedSet->GetReadOnly()) {
|
||||
if (!$this->ConvertEditModeToReadOnly()) {
|
||||
|
||||
switch ($this->oAttributeLinkedSet->GetRelationType()) {
|
||||
switch ($this->ConvertEditModeToRelationType()) {
|
||||
|
||||
case LINKSET_RELATIONTYPE_LINK:
|
||||
$aRowActions[] = array(
|
||||
|
||||
@@ -37,9 +37,9 @@ class BlockDirectLinksViewTable extends AbstractBlockLinksViewTable
|
||||
'default' => $this->GetDefault(),
|
||||
'table_id' => $this->GetTableId(),
|
||||
'row_actions' => $this->GetRowActions(),
|
||||
'currentId' => $this->GetTableId(),
|
||||
'currentId' => $this->GetTableId(),
|
||||
'panel_title' => $this->oAttDef->GetLabel(),
|
||||
'panel_icon' => MetaModel::GetClassIcon($this->GetTargetClass(), false),
|
||||
'panel_icon' => MetaModel::GetClassIcon($this->GetTargetClass(), false),
|
||||
);
|
||||
|
||||
// Description
|
||||
@@ -50,9 +50,9 @@ class BlockDirectLinksViewTable extends AbstractBlockLinksViewTable
|
||||
// Add creation in modal if the linkset is not readonly
|
||||
if (!$this->oAttDef->GetReadOnly()) {
|
||||
$aExtraParams['creation_in_modal_is_allowed'] = true;
|
||||
$aExtraParams['creation_in_modal_js_handler'] = 'LinkSetWorker.CreateLinkedObject("'.$this->GetTableId().'");';
|
||||
$aExtraParams['creation_in_modal_js_handler'] = "{$this->GetWidgetName()}.links_view_table('CreateLinkedObject');";
|
||||
}
|
||||
|
||||
|
||||
return $aExtraParams;
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ class BlockDirectLinksViewTable extends AbstractBlockLinksViewTable
|
||||
'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()}', '{$this->GetTableId()}');",
|
||||
'js_row_action' => "{$this->GetWidgetName()}.links_view_table('DetachLinkedObject', aRowData['{$this->sTargetClass}/_key_/raw'], oTrElement);",
|
||||
'confirmation' => [
|
||||
'message' => 'UI:Links:ActionRow:Detach:Confirmation',
|
||||
'message_row_data' => "{$this->sTargetClass}/hyperlink",
|
||||
@@ -84,7 +84,7 @@ class BlockDirectLinksViewTable extends AbstractBlockLinksViewTable
|
||||
'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'], '{$this->GetTableId()}');",
|
||||
'js_row_action' => "{$this->GetWidgetName()}.links_view_table('DeleteLinkedObject', aRowData['{$this->oAttDef->GetLinkedClass()}/_key_/raw'], oTrElement);",
|
||||
'confirmation' => [
|
||||
'message' => 'UI:Links:ActionRow:Delete:Confirmation',
|
||||
'message_row_data' => "{$this->sTargetClass}/hyperlink",
|
||||
@@ -97,7 +97,7 @@ class BlockDirectLinksViewTable extends AbstractBlockLinksViewTable
|
||||
'label' => 'UI:Links:ActionRow:Modify',
|
||||
'tooltip' => 'UI:Links:ActionRow:Modify+',
|
||||
'icon_classes' => 'fas fa-pen',
|
||||
'js_row_action' => "LinkSetWorker.ModifyLinkedObject('{$this->sTargetClass}', aRowData['{$this->oAttDef->GetLinkedClass()}/_key_/raw'], '{$this->GetTableId()}');",
|
||||
'js_row_action' => "{$this->GetWidgetName()}.links_view_table('ModifyLinkedObject', aRowData['{$this->oAttDef->GetLinkedClass()}/_key_/raw']);",
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,19 +6,23 @@
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Links\Indirect;
|
||||
|
||||
use AttributeLinkedSetIndirect;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Alert\AlertUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Button\ButtonUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Html\Html;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\MedallionIcon\MedallionIcon;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Toolbar\ToolbarUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\iUIBlock;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlock;
|
||||
use ConfigException;
|
||||
use CoreException;
|
||||
use DBObject;
|
||||
use Exception;
|
||||
use Dict;
|
||||
use MetaModel;
|
||||
use UILinksWidget;
|
||||
use utils;
|
||||
use WebPage;
|
||||
|
||||
/**
|
||||
* Class BlockIndirectLinksEditTable
|
||||
@@ -32,12 +36,15 @@ class BlockIndirectLinksEditTable extends UIContentBlock
|
||||
// Overloaded constants
|
||||
public const BLOCK_CODE = 'ibo-block-indirect-links-edit-table';
|
||||
public const DEFAULT_JS_TEMPLATE_REL_PATH = 'application/links/indirect/block-indirect-links-edit-table/layout';
|
||||
public const DEFAULT_JS_FILES_REL_PATH = [
|
||||
'js/links/links_widget.js',
|
||||
];
|
||||
|
||||
/** @var \UILinksWidget */
|
||||
public \UILinksWidget $oUILinksWidget;
|
||||
/** @var UILinksWidget $oUILinksWidget */
|
||||
public UILinksWidget $oUILinksWidget;
|
||||
|
||||
/** @var \AttributeLinkedSetIndirect */
|
||||
private \AttributeLinkedSetIndirect $oAttributeLinkedSetIndirect;
|
||||
/** @var AttributeLinkedSetIndirect $oAttributeLinkedSetIndirect */
|
||||
private AttributeLinkedSetIndirect $oAttributeLinkedSetIndirect;
|
||||
|
||||
/** @var string */
|
||||
public string $sDuplicates;
|
||||
@@ -60,13 +67,13 @@ class BlockIndirectLinksEditTable extends UIContentBlock
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param \UILinksWidget $oUILinksWidget
|
||||
* @param UILinksWidget $oUILinksWidget
|
||||
*
|
||||
* @throws \ConfigException
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
* @throws ConfigException
|
||||
* @throws CoreException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct(\UILinksWidget $oUILinksWidget)
|
||||
public function __construct(UILinksWidget $oUILinksWidget)
|
||||
{
|
||||
parent::__construct("linkedset_{$oUILinksWidget->GetLinkedSetId()}", ["ibo-block-indirect-links--edit"]);
|
||||
|
||||
@@ -88,7 +95,7 @@ class BlockIndirectLinksEditTable extends UIContentBlock
|
||||
* Initialization.
|
||||
*
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
private function Init()
|
||||
{
|
||||
@@ -99,8 +106,8 @@ class BlockIndirectLinksEditTable extends UIContentBlock
|
||||
* Initialize UI.
|
||||
*
|
||||
* @return void
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
* @throws CoreException
|
||||
* @throws Exception
|
||||
*/
|
||||
private function InitUI()
|
||||
{
|
||||
@@ -109,37 +116,6 @@ class BlockIndirectLinksEditTable extends UIContentBlock
|
||||
$this->AddDeferredBlock($oDeferredBlock);
|
||||
}
|
||||
|
||||
/**
|
||||
* CreateTableInformationAlert.
|
||||
*
|
||||
* @return iUIBlock
|
||||
*/
|
||||
private function CreateTableInformationAlert(): iUIBlock
|
||||
{
|
||||
// Selection alert
|
||||
$oAlert = AlertUIBlockFactory::MakeNeutral('', '', "linkedset_{$this->oUILinksWidget->GetInputId()}_alert_information");
|
||||
$oAlert->AddCSSClasses([
|
||||
'ibo-table--alert-information',
|
||||
]);
|
||||
$oAlert->SetIsClosable(false);
|
||||
$oAlert->SetIsCollapsible(false);
|
||||
$oAlert->AddSubBlock(new Html('<span class="ibo-table--alert-information--label" data-role="ibo-datatable-selection-value"></span>'));
|
||||
|
||||
// Delete button
|
||||
$oUIButton = ButtonUIBlockFactory::MakeForDestructiveAction("Détacher les {$this->oUILinksWidget->GetRemoteClass()}", 'table-selection');
|
||||
$oUIButton->SetOnClickJsCode("oWidget{$this->oUILinksWidget->GetInputId()}.RemoveSelected();");
|
||||
$oUIButton->AddCSSClass('ibo-table--alert-information--delete-button');
|
||||
$oAlert->AddSubBlock($oUIButton);
|
||||
|
||||
// Add button
|
||||
$oUIAddButton = ButtonUIBlockFactory::MakeForPrimaryAction("Attacher des {$this->oUILinksWidget->GetRemoteClass()}", 'table-selection');
|
||||
$oUIAddButton->AddCSSClass('ibo-table--alert-information--add-button');
|
||||
$oUIAddButton->SetOnClickJsCode("oWidget{$this->oUILinksWidget->GetInputId()}.AddObjects();");
|
||||
$oAlert->AddSubBlock($oUIAddButton);
|
||||
|
||||
return $oAlert;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WebPage $oPage
|
||||
* @param $oValue
|
||||
@@ -149,6 +125,9 @@ class BlockIndirectLinksEditTable extends UIContentBlock
|
||||
* @param $aTableConfig
|
||||
*
|
||||
* @return void
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
*/
|
||||
public function InitTable(\WebPage $oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj, $aTableConfig)
|
||||
{
|
||||
@@ -192,7 +171,7 @@ class BlockIndirectLinksEditTable extends UIContentBlock
|
||||
]);
|
||||
|
||||
// Panel
|
||||
$aTablePanel = PanelUIBlockFactory::MakeForClass($this->oUILinksWidget->GetRemoteClass(), $this->oAttributeLinkedSetIndirect->GetLabel())
|
||||
$oTablePanel = PanelUIBlockFactory::MakeForClass($this->oUILinksWidget->GetRemoteClass(), $this->oAttributeLinkedSetIndirect->GetLabel())
|
||||
->SetSubTitle(Dict::Format('UI:Pagination:HeaderNoSelection', count($aForm)))
|
||||
->SetIcon(MetaModel::GetClassIcon($this->oUILinksWidget->GetRemoteClass(), false))
|
||||
->AddCSSClass('ibo-datatable-panel');
|
||||
@@ -200,7 +179,7 @@ class BlockIndirectLinksEditTable extends UIContentBlock
|
||||
// - Panel description
|
||||
$sDescription = $this->oAttributeLinkedSetIndirect->GetDescription();
|
||||
if (utils::IsNotNullOrEmptyString($sDescription)) {
|
||||
$oTitleBlock = $aTablePanel->GetTitleBlock()
|
||||
$oTitleBlock = $oTablePanel->GetTitleBlock()
|
||||
->AddDataAttribute('tooltip-content', $sDescription)
|
||||
->AddDataAttribute('tooltip-max-width', 'min(600px, 90vw)') // Allow big description to be wide enough while shrinking on small screens
|
||||
->AddCSSClass('ibo-has-description');
|
||||
@@ -214,10 +193,10 @@ class BlockIndirectLinksEditTable extends UIContentBlock
|
||||
$oActionButtonLink = ButtonUIBlockFactory::MakeNeutral('Link');
|
||||
$oActionButtonLink->SetOnClickJsCode("oWidget{$this->oUILinksWidget->GetInputId()}.AddObjects();");
|
||||
$oToolbar->AddSubBlock($oActionButtonLink);
|
||||
$aTablePanel->AddToolbarBlock($oToolbar);
|
||||
$aTablePanel->AddSubBlock($oDataTable);
|
||||
$oTablePanel->AddToolbarBlock($oToolbar);
|
||||
$oTablePanel->AddSubBlock($oDataTable);
|
||||
|
||||
$this->AddSubBlock($aTablePanel);
|
||||
$this->AddSubBlock($oTablePanel);
|
||||
$this->AddSubBlock(InputUIBlockFactory::MakeForHidden("{$sFormPrefix}{$this->oUILinksWidget->GetInputId()}", '', "{$sFormPrefix}{$this->oUILinksWidget->GetInputId()}"));
|
||||
}
|
||||
|
||||
@@ -238,7 +217,7 @@ class BlockIndirectLinksEditTable extends UIContentBlock
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function GetFormRow(\WebPage $oP, \DBObject $oLinkedObj, $linkObjOrId, $aArgs, $oCurrentObj, $iUniqueId, $bReadOnly = false)
|
||||
public function GetFormRow(WebPage $oP, DBObject $oLinkedObj, $linkObjOrId, $aArgs, $oCurrentObj, $iUniqueId, $bReadOnly = false)
|
||||
{
|
||||
$sPrefix = "{$this->oUILinksWidget->GetAttCode()}{$this->oUILinksWidget->GetNameSuffix()}";
|
||||
$aRow = array();
|
||||
|
||||
@@ -58,11 +58,12 @@ class BlockIndirectLinksViewTable extends AbstractBlockLinksViewTable
|
||||
if ($this->oAttDef->HasDescription()) {
|
||||
$aExtraParams['panel_title_tooltip'] = $this->oAttDef->GetDescription();
|
||||
}
|
||||
|
||||
|
||||
// Add creation in modal if the linkset is not readonly
|
||||
if (!$this->oAttDef->GetReadOnly()) {
|
||||
$sHostClass = get_class($this->oDbObject);
|
||||
$aExtraParams['creation_in_modal_is_allowed'] = true;
|
||||
$aExtraParams['creation_in_modal_js_handler'] = 'LinkSetWorker.CreateLinkedObject("'.$this->GetTableId().'");';
|
||||
$aExtraParams['creation_in_modal_js_handler'] = "{$this->GetWidgetName()}.links_view_table('CreateLinkedObject');";
|
||||
}
|
||||
|
||||
return $aExtraParams;
|
||||
@@ -79,7 +80,7 @@ class BlockIndirectLinksViewTable extends AbstractBlockLinksViewTable
|
||||
'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'], '{$this->GetTableId()}');",
|
||||
'js_row_action' => "{$this->GetWidgetName()}.links_view_table('DeleteLinkedObject', aRowData['Link/_key_/raw'], oTrElement);",
|
||||
'confirmation' => [
|
||||
'message' => 'UI:Links:ActionRow:Detach:Confirmation',
|
||||
'message_row_data' => "Remote/hyperlink",
|
||||
@@ -91,7 +92,7 @@ class BlockIndirectLinksViewTable extends AbstractBlockLinksViewTable
|
||||
'label' => 'UI:Links:ActionRow:Modify',
|
||||
'tooltip' => 'UI:Links:ActionRow:Modify+',
|
||||
'icon_classes' => 'fas fa-pen',
|
||||
'js_row_action' => "LinkSetWorker.ModifyLinkedObject('{$this->oAttDef->GetLinkedClass()}', aRowData['Link/_key_/raw'], '{$this->GetTableId()}');",
|
||||
'js_row_action' => "{$this->GetWidgetName()}.links_view_table('ModifyLinkedObject', aRowData['Link/_key_/raw']);",
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ use Combodo\iTop\Service\Links\LinksBulkDataPostProcessor;
|
||||
use Combodo\iTop\Service\Links\LinkSetDataTransformer;
|
||||
use Combodo\iTop\Service\Links\LinkSetModel;
|
||||
use Combodo\iTop\Service\Links\LinkSetRepository;
|
||||
use DBObject;
|
||||
use iDBObjectSetIterator;
|
||||
|
||||
/**
|
||||
@@ -46,10 +47,11 @@ class LinksSetUIBlockFactory extends SetUIBlockFactory
|
||||
* @param AttributeLinkedSet $oAttDef Link set attribute definition
|
||||
* @param iDBObjectSetIterator $oDbObjectSet Link set value
|
||||
* @param string $sWizardHelperJsVarName Wizard helper name
|
||||
* @param DBObject|null $oHostDbObject Host DB object
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\Base\Component\Input\Set\Set
|
||||
*/
|
||||
public static function MakeForLinkSet(string $sId, AttributeLinkedSet $oAttDef, iDBObjectSetIterator $oDbObjectSet, string $sWizardHelperJsVarName): Set
|
||||
public static function MakeForLinkSet(string $sId, AttributeLinkedSet $oAttDef, iDBObjectSetIterator $oDbObjectSet, string $sWizardHelperJsVarName, DBObject $oHostDbObject = null): Set
|
||||
{
|
||||
$sTargetClass = LinkSetModel::GetTargetClass($oAttDef);
|
||||
$sTargetField = LinkSetModel::GetTargetField($oAttDef);
|
||||
@@ -57,6 +59,16 @@ class LinksSetUIBlockFactory extends SetUIBlockFactory
|
||||
// Set UI block for OQL
|
||||
$oSetUIBlock = SetUIBlockFactory::MakeForOQL($sId, $sTargetClass, $oAttDef->GetValuesDef()->GetFilterExpression(), $sWizardHelperJsVarName);
|
||||
|
||||
$oSetUIBlock->AddJsFileRelPath('js/links/links_set.js');
|
||||
|
||||
// Add button behaviour
|
||||
if (in_array($oAttDef->GetEditMode(), [LINKSET_EDITMODE_ADDREMOVE, LINKSET_EDITMODE_ADDONLY, LINKSET_EDITMODE_INPLACE, LINKSET_EDITMODE_ACTIONS])
|
||||
&& $oHostDbObject !== null) {
|
||||
$sHostClass = get_class($oHostDbObject);
|
||||
$oSetUIBlock->SetHasAddOptionButton(true);
|
||||
$oSetUIBlock->SetAddOptionButtonJsOnClick("CombodoLinkSet.CreateLinkedObject('{$oAttDef->GetLinkedClass()}', '{$oAttDef->GetCode()}', '{$sHostClass}', '{$oHostDbObject->GetKey()}', '{$sTargetField}', '{$sTargetClass}', oWidget{$oSetUIBlock->GetId()} );");
|
||||
}
|
||||
|
||||
// Current value
|
||||
$aCurrentValues = LinkSetDataTransformer::Decode($oDbObjectSet, $sTargetClass, $sTargetField);
|
||||
|
||||
|
||||
@@ -47,6 +47,9 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
|
||||
// - DisplayableGraph, impact analysis
|
||||
'js/raphael-min.js',
|
||||
'js/jquery.mousewheel.js',
|
||||
/** - links widgets moved in links folder @since 3.1.0 * */
|
||||
'js/links/links_direct_widget.js',
|
||||
'js/links/links_widget.js',
|
||||
];
|
||||
/** @inheritDoc */
|
||||
protected const COMPATIBILITY_DEPRECATED_LINKED_SCRIPTS_REL_PATH = [
|
||||
|
||||
@@ -18,6 +18,7 @@ use Combodo\iTop\Service\Base\ObjectRepository;
|
||||
use CoreCannotSaveObjectException;
|
||||
use DeleteException;
|
||||
use Dict;
|
||||
use Exception;
|
||||
use IssueLog;
|
||||
use iTopOwnershipLock;
|
||||
use iTopWebPage;
|
||||
@@ -90,6 +91,8 @@ class ObjectController extends AbstractController
|
||||
|
||||
/* Alerts the results */
|
||||
sPosting.done(function(data) {
|
||||
// fire event
|
||||
oForm.trigger('itop.form.submitted', [data]);
|
||||
if(data.success !== undefined && data.success === true) {
|
||||
oForm.closest('[data-role="ibo-modal"]').dialog('close');
|
||||
}
|
||||
@@ -151,6 +154,7 @@ JS;
|
||||
|
||||
$sClass = utils::ReadPostedParam('class', '', 'class');
|
||||
$sClassLabel = MetaModel::GetName($sClass);
|
||||
$sFormPrefix = utils::ReadPostedParam('formPrefix', '', FILTER_SANITIZE_STRING);
|
||||
$sTransactionId = utils::ReadPostedParam('transaction_id', '', 'transaction_id');
|
||||
$aErrors = array();
|
||||
$aWarnings = array();
|
||||
@@ -203,7 +207,7 @@ JS;
|
||||
$oObj->Set($sStateAttCode, $sTargetState);
|
||||
}
|
||||
}
|
||||
$aErrors = $oObj->UpdateObjectFromPostedForm();
|
||||
$aErrors = $oObj->UpdateObjectFromPostedForm($sFormPrefix);
|
||||
}
|
||||
if (isset($oObj) && is_object($oObj))
|
||||
{
|
||||
@@ -260,6 +264,7 @@ JS;
|
||||
// Nothing more to do
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
$aResult['success'] = true;
|
||||
$aResult['data'] = ['object' => ObjectRepository::ConvertObjectToArray($oObj, $sClass)];
|
||||
} else {
|
||||
ReloadAndDisplay($oPage, $oObj, 'create', $sMessage, 'ok');
|
||||
}
|
||||
@@ -543,8 +548,6 @@ JS;
|
||||
'js/forms-json-utils.js',
|
||||
'js/wizardhelper.js',
|
||||
'js/wizard.utils.js',
|
||||
'js/linkswidget.js',
|
||||
'js/linksdirectwidget.js',
|
||||
'js/extkeywidget.js',
|
||||
'js/jquery.blockUI.js',
|
||||
];
|
||||
@@ -589,4 +592,33 @@ JS;
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* OperationGet.
|
||||
*
|
||||
* @return JsonPage
|
||||
*/
|
||||
public function OperationGet(): JsonPage
|
||||
{
|
||||
$oPage = new JsonPage();
|
||||
$bSuccess = true;
|
||||
$aObjectData = null;
|
||||
|
||||
// Retrieve query params
|
||||
$sObjectClass = utils::ReadParam('object_class', '', false, utils::ENUM_SANITIZATION_FILTER_STRING);
|
||||
$sObjectKey = utils::ReadParam('object_key', '', false, utils::ENUM_SANITIZATION_FILTER_STRING);
|
||||
|
||||
// Retrieve object
|
||||
try {
|
||||
$oObject = MetaModel::GetObject($sObjectClass, $sObjectKey);
|
||||
$aObjectData = ObjectRepository::ConvertObjectToArray($oObject, $sObjectClass);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$bSuccess = false;
|
||||
}
|
||||
|
||||
return $oPage->SetData([
|
||||
'object' => $aObjectData,
|
||||
'success' => $bSuccess,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ use AjaxPage;
|
||||
use cmdbAbstractObject;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Form\FormUIBlockFactory;
|
||||
use Combodo\iTop\Controller\AbstractController;
|
||||
use Combodo\iTop\Service\Base\ObjectRepository;
|
||||
use Exception;
|
||||
use JsonPage;
|
||||
use CoreException;
|
||||
@@ -169,8 +170,8 @@ class LinkSetController extends AbstractController
|
||||
$aPrefillParam = array('source_obj' => $oSourceObj);
|
||||
$oObj->PrefillForm('creation_from_editinplace', $aPrefillParam);
|
||||
// We display this form in a modal, once we submit (in ajax) we probably want to only close the modal
|
||||
$sFormOnSubmitJsCode =
|
||||
<<<JS
|
||||
$sFormOnSubmitJsCode =
|
||||
<<<JS
|
||||
event.preventDefault();
|
||||
if(bOnSubmitForm === true)
|
||||
{
|
||||
@@ -180,6 +181,8 @@ class LinkSetController extends AbstractController
|
||||
|
||||
/* Alerts the results */
|
||||
sPosting.done(function(data) {
|
||||
// fire event
|
||||
oForm.trigger('itop.form.submitted', [data]);
|
||||
if(data.success !== undefined && data.success === true) {
|
||||
oForm.closest('[data-role="ibo-modal"]').dialog('close');
|
||||
}
|
||||
@@ -195,18 +198,20 @@ class LinkSetController extends AbstractController
|
||||
JS
|
||||
;
|
||||
$aExtraParams = [
|
||||
'noRelations' => true,
|
||||
'noRelations' => true,
|
||||
'hide_transitions' => true,
|
||||
'fieldsFlags' => $aFieldFlags,
|
||||
'js_handlers' => [
|
||||
'form_on_submit' => $sFormOnSubmitJsCode,
|
||||
'formPrefix' => $sAttCode,
|
||||
'fieldsFlags' => $aFieldFlags,
|
||||
'js_handlers' => [
|
||||
'form_on_submit' => $sFormOnSubmitJsCode,
|
||||
'cancel_button_on_click' =>
|
||||
<<<JS
|
||||
function() {
|
||||
$(this).closest('[data-role="ibo-modal"]').dialog('close');
|
||||
};
|
||||
JS
|
||||
]
|
||||
,
|
||||
],
|
||||
];
|
||||
cmdbAbstractObject::DisplayCreationForm($oPage, $sRealClass, $oObj, array(), $aExtraParams);
|
||||
}
|
||||
@@ -234,13 +239,50 @@ JS
|
||||
return false;
|
||||
JS
|
||||
);
|
||||
|
||||
|
||||
// - Add a select and a button to validate the form
|
||||
$oClassForm->AddSubBlock(cmdbAbstractObject::DisplayBlockSelectClassToCreate( $sProposedRealClass, MetaModel::GetName($sProposedRealClass), $aPossibleClasses));
|
||||
$oClassForm->AddSubBlock(cmdbAbstractObject::DisplayBlockSelectClassToCreate($sProposedRealClass, MetaModel::GetName($sProposedRealClass), $aPossibleClasses));
|
||||
|
||||
$oPage->AddUiBlock($oClassForm);
|
||||
}
|
||||
|
||||
return $oPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* OperationGetRemoteObject.
|
||||
*
|
||||
* @return JsonPage
|
||||
*/
|
||||
public function OperationGetRemoteObject(): JsonPage
|
||||
{
|
||||
$oPage = new JsonPage();
|
||||
$bSuccess = true;
|
||||
$aObjectData = null;
|
||||
|
||||
// Retrieve query params
|
||||
$sObjectClass = utils::ReadParam('linked_object_class', '', false, utils::ENUM_SANITIZATION_FILTER_STRING);
|
||||
$sObjectKey = utils::ReadParam('linked_object_key', '', false, utils::ENUM_SANITIZATION_FILTER_STRING);
|
||||
$sRemoteClass = utils::ReadParam('remote_class', null, false, utils::ENUM_SANITIZATION_FILTER_STRING);
|
||||
$sRemoteExtKey = utils::ReadParam('external_key_att_code', null, false, utils::ENUM_SANITIZATION_FILTER_STRING);
|
||||
|
||||
// Retrieve object
|
||||
try {
|
||||
$oObject = MetaModel::GetObject($sObjectClass, $sObjectKey);
|
||||
$sLinkKey = $oObject->GetKey();
|
||||
if ($sRemoteExtKey !== null) {
|
||||
$oObject = MetaModel::GetObject($sRemoteClass, $oObject->Get($sRemoteExtKey));
|
||||
}
|
||||
$aObjectData = ObjectRepository::ConvertObjectToArray($oObject, $sObjectClass);
|
||||
$aObjectData['link_keys'] = [$sObjectKey];
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$bSuccess = false;
|
||||
}
|
||||
|
||||
return $oPage->SetData([
|
||||
'object' => $aObjectData,
|
||||
'success' => $bSuccess,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -140,19 +140,8 @@ class ObjectRepository
|
||||
$oDbObjectSet->Rewind();
|
||||
while ($oObject = $oDbObjectSet->Fetch()) {
|
||||
|
||||
// Prepare objet data
|
||||
$aObjectData = [];
|
||||
|
||||
// Object key
|
||||
$aObjectData['key'] = $oObject->GetKey();
|
||||
|
||||
// Fill loaded columns...
|
||||
foreach ($aFieldsToLoad as $sField) {
|
||||
$aObjectData[$sField] = $oObject->Get($sField);
|
||||
}
|
||||
|
||||
// Compute others data
|
||||
$aResult[] = ObjectRepository::ComputeOthersData($oObject, $sObjectClass, $aObjectData, $aComplementAttributeSpec, $sObjectImageAttCode);
|
||||
$aResult[] = self::ConvertObjectToArray($oObject, $sObjectClass, $aFieldsToLoad, $aComplementAttributeSpec, $sObjectImageAttCode);
|
||||
}
|
||||
|
||||
return $aResult;
|
||||
@@ -199,6 +188,9 @@ class ObjectRepository
|
||||
{
|
||||
try {
|
||||
|
||||
// object class
|
||||
$aData['class_name'] = get_class($oDbObject);
|
||||
|
||||
// Obsolescence flag
|
||||
$aData['obsolescence_flag'] = $oDbObject->IsObsolete();
|
||||
|
||||
@@ -260,4 +252,50 @@ class ObjectRepository
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ConvertObjectToArray.
|
||||
*
|
||||
* @param DBObject $oObject
|
||||
* @param string $sObjectClass
|
||||
* @param array|null $aFieldsToLoad
|
||||
* @param array|null $aComplementAttributeSpec
|
||||
* @param string|null $sObjectImageAttCode
|
||||
*
|
||||
* @return array
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \DictExceptionMissingString
|
||||
*/
|
||||
public static function ConvertObjectToArray(DBObject $oObject, string $sObjectClass, array $aFieldsToLoad = null, array $aComplementAttributeSpec = null, string $sObjectImageAttCode = null): array
|
||||
{
|
||||
// Retrieve friendly name complementary specification
|
||||
if ($aComplementAttributeSpec === null) {
|
||||
$aComplementAttributeSpec = MetaModel::GetNameSpec($sObjectClass, FriendlyNameType::COMPLEMENTARY);
|
||||
}
|
||||
|
||||
// Retrieve image attribute code
|
||||
if ($sObjectImageAttCode === null) {
|
||||
$sObjectImageAttCode = MetaModel::GetImageAttributeCode($sObjectClass);
|
||||
}
|
||||
|
||||
// Fields to load
|
||||
if ($aFieldsToLoad === null) {
|
||||
$aFieldsToLoad = self::GetDefaultFieldsToLoad($aComplementAttributeSpec, $sObjectImageAttCode);
|
||||
}
|
||||
|
||||
// Prepare objet data
|
||||
$aObjectData = [];
|
||||
|
||||
// Object key
|
||||
$aObjectData['key'] = $oObject->GetKey();
|
||||
|
||||
// Fill loaded columns...
|
||||
foreach ($aFieldsToLoad as $sField) {
|
||||
$aObjectData[$sField] = $oObject->Get($sField);
|
||||
}
|
||||
|
||||
// Compute others data
|
||||
return ObjectRepository::ComputeOthersData($oObject, $sObjectClass, $aObjectData, $aComplementAttributeSpec, $sObjectImageAttCode);
|
||||
}
|
||||
|
||||
}
|
||||
8
templates/application/links/layout.ready.js.twig
Normal file
8
templates/application/links/layout.ready.js.twig
Normal file
@@ -0,0 +1,8 @@
|
||||
{# @copyright Copyright (C) 2010-2021 Combodo SARL #}
|
||||
{# @license http://opensource.org/licenses/AGPL-3.0 #}
|
||||
{% apply spaceless %}
|
||||
{{ oUIBlock.GetWidgetName() }} = $('#{{ oUIBlock.GetId() }}').links_view_table({
|
||||
link_class: '{{ oUIBlock.GetLinkedClass() }}',
|
||||
external_key_to_me: '{{ oUIBlock.GetExternalKeyToMe() }}'
|
||||
});
|
||||
{% endapply %}
|
||||
@@ -1,4 +1,4 @@
|
||||
<div id="datatable_dlg_{{ oUIBlock.GetTableId() }}" style="display: none;" class=" {{ oUIBlock.GetBlockCode() }}">
|
||||
<div id="datatable_dlg_{{ oUIBlock.GetTableId() }}" style="display: none;" class=" {{ oUIBlock.GetBlockCode() }}" role="datatable-settings-dialog">
|
||||
<input type="hidden" name="action" value="none">
|
||||
<form id="form_{{ oUIBlock.GetTableId() }}" onsubmit="return false">
|
||||
<div>
|
||||
|
||||
@@ -18,7 +18,9 @@ let oWidget{{ oUIBlock.GetId() }} = $('#{{ oUIBlock.GetId() }}').selectize({
|
||||
{# Remove button plugin #}
|
||||
plugins: {
|
||||
{# PLUGIN update operations #}
|
||||
'combodo_update_operations' : {},
|
||||
'combodo_update_operations' : {
|
||||
initial: {{ oUIBlock.GetValue()|raw }},
|
||||
},
|
||||
{# PLUGIN combodo auto position #}
|
||||
'combodo_auto_position' : {
|
||||
maxDropDownHeight: 300, {# in px #}
|
||||
@@ -73,7 +75,6 @@ let oWidget{{ oUIBlock.GetId() }} = $('#{{ oUIBlock.GetId() }}').selectize({
|
||||
optgroups: {{ oDataProvider.GetOptionsGroups()|json_encode()|raw }},
|
||||
|
||||
{# Items data #}
|
||||
initial: {{ oUIBlock.GetValue()|raw }},
|
||||
items: {{ oUIBlock.GetValue()|raw }},
|
||||
|
||||
inputClass: 'ibo-input ibo-input-selectize ibo-input-set attribute-set selectize-input',
|
||||
@@ -197,9 +198,12 @@ let oWidget{{ oUIBlock.GetId() }} = $('#{{ oUIBlock.GetId() }}').selectize({
|
||||
{# plugin combodo_add_button #}
|
||||
{% if oUIBlock.HasAddOptionButton() %}
|
||||
onAdd: function(){
|
||||
alert('todo on add option');
|
||||
{{ oUIBlock.GetAddOptionButtonJsOnClick()|raw }}
|
||||
|
||||
},
|
||||
{% endif %}
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user