mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-24 11:08:45 +02:00
N°3190 - Edit n:n LinkedSetIndirect in object details using a tagset-like widget
- Add generic set block ui component - Add model link set (direct and indirect) attribute (display style) - Add model link set direct allowed values - Create link set viewer block UI (BlockLinksSetDisplayAsProperty) - Add set block ui factory for linkset - Add object factory and create new endpoint in object controller (with data binder) - Add link set model, link set repository and link set data transformer services
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
{% block iboInputLabel %}
|
||||
{% endblock %}
|
||||
{% block iboInput %}
|
||||
<input type="{{ oUIBlock.GetType() }}" id="{{ oUIBlock.GetId() }}" name="{{ oUIBlock.GetName() }}" value="{{ oUIBlock.GetValue()|raw }}"
|
||||
|
||||
<input type="{{ oUIBlock.GetType() }}" id="{{ oUIBlock.GetId() }}" name="{{ oUIBlock.GetName() }}" value="{{ oUIBlock.GetValue() }}"
|
||||
class="{{ oUIBlock.GetBlocksInheritanceCSSClassesAsString() }} {{ oUIBlock.GetAdditionalCSSClassesAsString() }} {% if oUIBlock.IsHidden() %}ibo-is-hidden{% endif %}"
|
||||
data-role="ibo-input"
|
||||
{% if oUIBlock.IsChecked() %} checked="checked"{% endif %}
|
||||
|
||||
26
templates/base/components/input/set/layout.html.twig
Normal file
26
templates/base/components/input/set/layout.html.twig
Normal file
@@ -0,0 +1,26 @@
|
||||
{# @copyright Copyright (C) 2010-2021 Combodo SARL #}
|
||||
{# @license http://opensource.org/licenses/AGPL-3.0 #}
|
||||
|
||||
{# Set ui block #}
|
||||
<select
|
||||
id="{{ oUIBlock.GetId() }}"
|
||||
name="{{ oUIBlock.GetName() }}"
|
||||
multiple
|
||||
style="display: none;"
|
||||
>
|
||||
</select>
|
||||
|
||||
{# Options template #}
|
||||
{% if oUIBlock.HasOptionsTemplate() %}
|
||||
<template id="{{ oUIBlock.GetId() }}_options_template">
|
||||
{% include oUIBlock.GetOptionsTemplate() %}
|
||||
</template>
|
||||
{% endif %}
|
||||
|
||||
{# Items template #}
|
||||
{% if oUIBlock.HasItemsTemplate() %}
|
||||
<template id="{{ oUIBlock.GetId() }}_items_template">
|
||||
{% include oUIBlock.GetItemsTemplate() %}
|
||||
</template>
|
||||
{% endif %}
|
||||
|
||||
206
templates/base/components/input/set/layout.ready.js.twig
Normal file
206
templates/base/components/input/set/layout.ready.js.twig
Normal file
@@ -0,0 +1,206 @@
|
||||
|
||||
{# @copyright Copyright (C) 2010-2021 Combodo SARL #}
|
||||
{# @license http://opensource.org/licenses/AGPL-3.0 #}
|
||||
|
||||
{# SET WIDGET #}
|
||||
{% set oDataProvider = oUIBlock.GetDataProvider() %}
|
||||
let oWidget{{ oUIBlock.GetId() }} = $('#{{ oUIBlock.GetId() }}').selectize({
|
||||
|
||||
{# Global options #}
|
||||
{% if oDataProvider.IsAjaxProviderType %}
|
||||
preload: true, {# call ajax directly #}
|
||||
loadingClass: '',
|
||||
{% endif %}
|
||||
itemClass: 'item attribute-set-item',
|
||||
hasError: {{ oUIBlock.HasError()|var_export() }},
|
||||
placeholder: '{{ oUIBlock.GetPlaceholder() }}',
|
||||
|
||||
{# Remove button plugin #}
|
||||
plugins: {
|
||||
{# PLUGIN update operations #}
|
||||
'combodo_update_operations' : {},
|
||||
{# PLUGIN combodo auto position #}
|
||||
'combodo_auto_position' : {
|
||||
maxDropDownHeight: 300, {# in px #}
|
||||
},
|
||||
{# PLUGIN combodo add button #}
|
||||
{% if oUIBlock.HasAddOptionButton() %}
|
||||
'combodo_add_button' : {
|
||||
title: '{{ oUIBlock.GetAddButtonTitle() }}'
|
||||
},
|
||||
{% endif %}
|
||||
{% if oUIBlock.IsMultiValuesSynthesis() %}
|
||||
'combodo_multi_values_synthesis' : {
|
||||
|
||||
tooltip_links_will_be_created_for_all_objects: '{{ 'UI:Links:Bulk:LinkWillBeCreatedForAllObjects'|dict_s }}',
|
||||
tooltip_links_will_be_deleted_from_all_objects: '{{ 'UI:Links:Bulk:LinkWillBeDeletedFromAllObjects'|dict_s }}',
|
||||
tooltip_links_will_be_created_for_one_object: '{{ 'UI:Links:Bulk:LinkWillBeCreatedFor1Object'|dict_s }}',
|
||||
tooltip_links_will_be_deleted_from_one_object: '{{ 'UI:Links:Bulk:LinkWillBeDeletedFrom1Object'|dict_s }}',
|
||||
tooltip_links_will_be_created_for_x_objects: '{{ 'UI:Links:Bulk:LinkWillBeCreatedForXObjects'|dict_s }}',
|
||||
tooltip_links_will_be_deleted_from_x_objects: '{{ 'UI:Links:Bulk:LinkWillBeDeletedFromXObjects'|dict_s }}',
|
||||
tooltip_links_exist_for_all_objects: '{{ 'UI:Links:Bulk:LinkExistForAllObjects'|dict_s }}',
|
||||
tooltip_links_exist_for_one_object: '{{ 'UI:Links:Bulk:LinkExistForOneObject'|dict_s }}',
|
||||
tooltip_links_exist_for_x_objects: '{{ 'UI:Links:Bulk:LinkExistForXObjects'|dict_s }}',
|
||||
},
|
||||
{% endif %}
|
||||
{# PLUGIN remove button #}
|
||||
{% if oUIBlock.HasRemoveItemButton() %}
|
||||
'remove_button' : {},
|
||||
{% endif %}
|
||||
},
|
||||
|
||||
{# Max items you can select #}
|
||||
{% if oUIBlock.GetMaxItems() is not empty %}
|
||||
maxItems: {{ oUIBlock.GetMaxItems() }},
|
||||
{% endif %}
|
||||
|
||||
{# Max options available #}
|
||||
{% if oUIBlock.GetMaxOptions() is not empty %}
|
||||
maxOptions: {{ oUIBlock.GetMaxOptions() }},
|
||||
{% endif %}
|
||||
|
||||
{# Data fields #}
|
||||
valueField: '{{ oDataProvider.GetDataValueField() }}',
|
||||
labelField: '{{ oDataProvider.GetDataLabelField() }}',
|
||||
searchField: {{ oDataProvider.GetDataSearchFields()|json_encode()|raw }},
|
||||
optgroupField: '{{ oDataProvider.GetGroupField() }}',
|
||||
tooltipField: '{{ oDataProvider.GetTooltipField() }}',
|
||||
|
||||
{# Initial options data, may be oveeride by ajax load method #}
|
||||
options: {{ oDataProvider.GetOptions()|json_encode()|raw }},
|
||||
|
||||
{# Groups data #}
|
||||
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',
|
||||
|
||||
{# Ajax data load #}
|
||||
{% if oDataProvider.IsAjaxProviderType %}
|
||||
load: function (query, callback) {
|
||||
let me = this;
|
||||
$.ajax({
|
||||
url: '{{ get_absolute_url_app_root() }}pages/ajax.render.php?route={{ oDataProvider.GetRoute() }}&search=' + query + '{{ oDataProvider.GetParamsAsQueryString|raw }}',
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
data: me.convertParamArray('{{ oDataProvider.GetPostParamsAsJsonString()|raw }}'),
|
||||
error: function (e) {
|
||||
callback();
|
||||
console.error(e);
|
||||
if(!me.settings.hasError) {
|
||||
me.toggleErrorClass(true);
|
||||
}
|
||||
},
|
||||
success: function (res) {
|
||||
|
||||
// Handle errors
|
||||
if(!me.settings.hasError){
|
||||
me.toggleErrorClass(!res.data.success);
|
||||
if(!res.data.success) return;
|
||||
}
|
||||
|
||||
// Retrieve current input value
|
||||
let aSelectedItems = me.getValue();
|
||||
// Filter old options data to keep selected values
|
||||
let options = Object.values(me.options);
|
||||
options = options.filter(item => aSelectedItems.includes(item['{{ oDataProvider.GetDataValueField() }}']));
|
||||
// Merge kept and new values
|
||||
options = $.merge(options, res.data.search_data);
|
||||
// Compute groups
|
||||
$.each(options, function(index, value) {
|
||||
me.addOptionGroup(value['{{ oDataProvider.GetGroupField() }}'], {
|
||||
label: value['{{ oDataProvider.GetGroupField() }}'],
|
||||
value: value['{{ oDataProvider.GetGroupField() }}']
|
||||
});
|
||||
});
|
||||
// Clear all options
|
||||
me.clearOptions();
|
||||
// Add merged values
|
||||
callback(options);
|
||||
// Restore input value
|
||||
me.addItems(aSelectedItems, true);
|
||||
}
|
||||
});
|
||||
},
|
||||
{% endif %}
|
||||
|
||||
{# Renderers #}
|
||||
render: {
|
||||
|
||||
{# Options #}
|
||||
{% if oUIBlock.HasOptionsTemplate() %}
|
||||
option: function(option) {
|
||||
return CombodoGlobalToolbox.RenderTemplate('#{{ oUIBlock.GetId() }}_options_template', option, this.settings.optionClass)[0].outerHTML;
|
||||
},
|
||||
{% endif %}
|
||||
|
||||
{# Items #}
|
||||
{% if oUIBlock.HasItemsTemplate() %}
|
||||
item: function (item) {
|
||||
return CombodoGlobalToolbox.RenderTemplate('#{{ oUIBlock.GetId() }}_items_template', item, this.settings.itemClass)[0].outerHTML;
|
||||
},
|
||||
{% endif %}
|
||||
|
||||
},
|
||||
|
||||
onInitialize: function(){
|
||||
|
||||
/**
|
||||
* Function to convert param array.
|
||||
*
|
||||
* EVAL_JAVASCRIPT{code_to_eval}
|
||||
*/
|
||||
this.convertParamArray = function(paramArray){
|
||||
let postParam = JSON.parse(paramArray);
|
||||
let data = {};
|
||||
Object.entries(postParam).forEach(([key, value]) => {
|
||||
let matches = null;
|
||||
if(typeof(value) === 'string'){
|
||||
matches = value.match(/^EVAL_JAVASCRIPT{(.*)}$/);
|
||||
}
|
||||
if(matches != null){
|
||||
data[key] = eval(matches[1]);
|
||||
}
|
||||
else{
|
||||
data[key] = value;
|
||||
}
|
||||
});
|
||||
return data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function to show error.
|
||||
*
|
||||
*/
|
||||
this.toggleErrorClass = function(bValue){
|
||||
this.$control.toggleClass('selectize-input-error', bValue);
|
||||
};
|
||||
|
||||
{# Error #}
|
||||
this.toggleErrorClass(this.settings.hasError);
|
||||
},
|
||||
|
||||
|
||||
{# On item add #}
|
||||
onItemAdd: function(value, $item){
|
||||
$item.addClass(this.settings.itemClass);
|
||||
$item.attr({
|
||||
'data-tooltip-content': this.options[value][this.settings.tooltipField],
|
||||
'data-tooltip-html-enabled': true
|
||||
});
|
||||
CombodoTooltip.InitTooltipFromMarkup($item);
|
||||
},
|
||||
|
||||
{# plugin combodo_add_button #}
|
||||
{% if oUIBlock.HasAddOptionButton() %}
|
||||
onAdd: function(){
|
||||
alert('todo on add option');
|
||||
},
|
||||
{% endif %}
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
{# @copyright Copyright (C) 2010-2021 Combodo SARL #}
|
||||
{# @license http://opensource.org/licenses/AGPL-3.0 #}
|
||||
|
||||
<div class="option simple-option-renderer" role="option">
|
||||
|
||||
<div class="simple-option-renderer--container" data-template-add-class="class">
|
||||
|
||||
<i class="simple-option-renderer--container--icon" data-template-add-class="icon"></i>
|
||||
|
||||
<span class="simple-option-renderer--container--label" data-template-text="label">
|
||||
</span>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
Reference in New Issue
Block a user