Skip to content

Commit e2bdbf4

Browse files
committed
Merge branch 'release/2.3.0'
2 parents 1a984e1 + 8e9e233 commit e2bdbf4

File tree

9 files changed

+404
-161
lines changed

9 files changed

+404
-161
lines changed

ajax/get_entity_tags.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
include ("../../../inc/includes.php");
4+
5+
header("Content-Type: text/html; charset=UTF-8");
6+
Html::header_nocache();
7+
Session::checkLoginUser();
8+
9+
if (!isset($_REQUEST['name'])) {
10+
exit;
11+
}
12+
13+
echo PluginTagTag::getTagForEntityName($_REQUEST['name']);

composer.lock

Lines changed: 165 additions & 83 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

css/tag.css

Lines changed: 21 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,43 @@
1-
.tag_select {
1+
.tag_select + .select2-container {
22
font-size: 11px;
3-
width: 500px;
3+
width: calc(100% - 20px);
4+
max-width: 100%;
45
}
56

6-
@media screen and (max-width: 700px) {
7-
.tag_select {
8-
width: 80%;
9-
}
7+
.tag_select + .select2-container .select2-selection--multiple {
8+
border: 1px solid #D3D3D3;
9+
margin: 0;
10+
height: 22px;
11+
min-height: 30px;
1012
}
1113

12-
.tag_select.select2-container .select2-search-choice {
13-
border: none;
14-
background: none;
15-
box-shadow: none;
16-
margin: 4px 1px;
17-
padding: 4px 0 3px 18px;
14+
.tag_select + .select2-container
15+
.select2-selection--multiple .select2-selection__choice {
16+
margin-top: 2px;
17+
margin-right: 2px;
1818
}
1919

20-
#mainformtable .tag_select.select2-container .select2-choices {
21-
background-image: none;
22-
border: 1px solid #D3D3D3;
23-
border-radius: 4px;
24-
box-shadow: none;
25-
}
26-
27-
#mainformtable .tag_select.select2-dropdown-open .select2-choices {
28-
border-bottom-color: transparent;
29-
border-bottom-left-radius: 0;
30-
border-bottom-right-radius: 0;
20+
.tag_select + .select2-container
21+
.select2-selection--multiple .select2-selection__rendered {
22+
padding-left: 2px;
3123
}
3224

3325
.tag_select.select2-container .select2-search-choice-close {
3426
color: #000;
3527
}
3628

3729
.tag_choice {
38-
padding: 3px;
3930
border-radius: 3px;
40-
}
41-
42-
.select2-choices.no-negative-margin .tag_choice {
31+
padding: 4px 8px;
32+
margin: 2px;
4333
display: inline-block;
44-
padding-right: 5px;
45-
margin: 1px;
34+
font-size: 11px;
4635
}
4736

48-
.select2-choices:not(.no-negative-margin) .tag_choice {
49-
margin-left: -18px;
50-
padding-left: 18px;
37+
.tab_cadre_pager span.tag_choice {
38+
margin: 2px;
5139
}
5240

5341
.select2-results .tag_choice {
5442
padding: 2px 4px;
55-
}
56-
57-
.tag_select_results .select2-highlighted {
58-
color: inherit;
59-
}
43+
}

hook.php

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,14 @@ function plugin_datainjection_populate_tag() {
4141
$INJECTABLE_TYPES['PluginTagTagInjection'] = 'tag';
4242
}
4343

44-
function plugin_tag_getAddSearchOptions($itemtype) {
44+
function plugin_tag_getAddSearchOptionsNew($itemtype) {
4545
if (!PluginTagTag::canItemtype($itemtype)) {
4646
return [];
4747
}
4848

49-
return [
50-
PluginTagTag::S_OPTION => [
49+
$options = [
50+
[
51+
'id' => PluginTagTag::S_OPTION,
5152
'table' => PluginTagTag::getTable(),
5253
'field' => 'name',
5354
'name' => PluginTagTag::getTypeName(2),
@@ -66,30 +67,48 @@ function plugin_tag_getAddSearchOptions($itemtype) {
6667
]
6768
]
6869
];
70+
71+
$item = new $itemtype;
72+
if ($item->isEntityAssign()) {
73+
$options [] = [
74+
'id' => (PluginTagTag::S_OPTION + 1),
75+
'table' => PluginTagTag::getTable(),
76+
'field' => 'name',
77+
'name' => PluginTagTag::getTypeName(2)." - ".__("Entity"),
78+
'datatype' => 'string',
79+
'searchtype' => 'contains',
80+
'massiveaction' => false,
81+
'forcegroupby' => true,
82+
'usehaving' => true,
83+
'joinparams' => [
84+
'condition' => "AND 1=1", // to force distinct complex id than the previous option
85+
'beforejoin' => [
86+
'table' => 'glpi_plugin_tag_tagitems',
87+
'joinparams' => [
88+
'jointype' => 'itemtype_item',
89+
'specific_itemtype' => 'Entity',
90+
'beforejoin' => [
91+
'table' => 'glpi_entities',
92+
]
93+
]
94+
]
95+
]
96+
];
97+
}
98+
99+
return $options;
69100
}
70101

71102
function plugin_tag_giveItem($type, $field, $data, $num, $linkfield = "") {
72103
switch ($field) {
73104
case PluginTagTag::S_OPTION:
105+
case PluginTagTag::S_OPTION+1:
74106
$out = '<div class="tag_select select2-container" style="width: 100%;">
75107
<div class="select2-choices no-negative-margin">';
76108
$separator = '';
77-
$plugintagtag = new PluginTagTag();
78-
79109
foreach ($data[$num] as $tag) {
80110
if (isset($tag['id']) && isset($tag['name'])) {
81-
$plugintagtag->getFromDB($tag['id']);
82-
$color = $plugintagtag->fields["color"];
83-
$style = "";
84-
if (!empty($color)) {
85-
$style .= "background-color: $color; color: ".idealTextColor($color);
86-
} else {
87-
$style .= "border: 1px solid #BBB;";
88-
}
89-
90-
$out .= '<span class="select2-search-choice tag_choice"
91-
style="padding-left:5px;'.$style.'">'.
92-
$separator.$tag['name'].'</span>';
111+
$out .= PluginTagTag::getSingleTag($tag['id'], $separator);
93112
//For export (CSV, PDF) of GLPI core
94113
$separator = '<span style="display:none">, </span>';
95114
}
@@ -102,20 +121,6 @@ function plugin_tag_giveItem($type, $field, $data, $num, $linkfield = "") {
102121
}
103122

104123

105-
function idealTextColor($hexTripletColor) {
106-
$nThreshold = 105;
107-
$hexTripletColor = str_replace('#', '', $hexTripletColor);
108-
$components = [
109-
'R' => hexdec(substr($hexTripletColor, 0, 2)),
110-
'G' => hexdec(substr($hexTripletColor, 2, 2)),
111-
'B' => hexdec(substr($hexTripletColor, 4, 2)),
112-
];
113-
$bgDelta = ($components['R'] * 0.299)
114-
+ ($components['G'] * 0.587)
115-
+ ($components['B'] * 0.114);
116-
return (((255 - $bgDelta) < $nThreshold) ? "#000000" : "#ffffff");
117-
}
118-
119124
function plugin_tag_addHaving($link, $nott, $itemtype, $id, $val, $num) {
120125
$searchopt = &Search::getOptions($itemtype);
121126
$table = $searchopt[$id]["table"];

inc/tag.class.php

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ static function showTagDropdown($params = []) {
457457

458458
// find values for this items
459459
$values = [];
460-
if ($params['id']) {
460+
if (isset($params['id'])) {
461461
foreach ($tag_item->find('items_id='.$params['id'].'
462462
AND itemtype="'.$itemtype.'"') as $found_item) {
463463
$values[] = $found_item['plugin_tag_tags_id'];
@@ -511,8 +511,9 @@ static function showTagDropdown($params = []) {
511511
// call select2 lib for this input
512512
echo Html::scriptBlock("$(function() {
513513
$('#tag_select_$rand').select2({
514-
templateResult: formatOption,
515-
templateSelection: formatOption,
514+
width: 'calc(100% - 20px)',
515+
templateResult: formatOptionResult,
516+
templateSelection: formatOptionSelection,
516517
formatSearching: '".__("Loading...")."',
517518
dropdownCssClass: 'tag_select_results',
518519
data: ".json_encode($select2_tags).",
@@ -537,6 +538,41 @@ static function showTagDropdown($params = []) {
537538
}
538539
}
539540

541+
static function getTagForEntityName($completename = "") {
542+
$plus_rootentity = sprintf(__('%1$s + %2$s'), '', __('Child entities'));
543+
$completename = Html::entity_decode_deep($completename);
544+
$completename = trim(str_replace($plus_rootentity, '', $completename));
545+
$entities_id = Entity::getEntityIDByCompletename($completename);
546+
547+
$out = "";
548+
if ($entities_id >= 0) {
549+
$tag_item = new PluginTagTagItem();
550+
foreach ($tag_item->find("items_id = $entities_id
551+
AND itemtype = 'Entity'") as $found_item) {
552+
$out .= PluginTagTag::getSingleTag($found_item['plugin_tag_tags_id']);
553+
}
554+
}
555+
556+
return $out;
557+
}
558+
559+
static function getSingleTag($tag_id, $separator = '') {
560+
$plugintagtag = new self();
561+
$plugintagtag->getFromDB($tag_id);
562+
$color = $plugintagtag->fields["color"];
563+
$style = "";
564+
if (!empty($color)) {
565+
$inv_color = idealTextColor($color);
566+
$style .= "background-color: $color; border: 1px solid $inv_color; color: $inv_color";
567+
} else {
568+
$style .= "border: 1px solid #BBB;";
569+
}
570+
571+
return "<span class='select2-search-choice tag_choice'
572+
style='padding-left:5px;$style'>".
573+
$separator.$plugintagtag->fields['name'].'</span>';
574+
}
575+
540576
function prepareInputForAdd($input) {
541577
if (!$this->checkMandatoryFields($input)) {
542578
return false;

js/common.js

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
function rgb2hex(rgb){
1+
var rgb2hex = function(rgb){
22
rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);
33
return (rgb && rgb.length === 4) ? "#" +
44
("0" + parseInt(rgb[1],10).toString(16)).slice(-2) +
55
("0" + parseInt(rgb[2],10).toString(16)).slice(-2) +
66
("0" + parseInt(rgb[3],10).toString(16)).slice(-2) : '';
7-
}
7+
};
88

9-
function idealTextColor(hexTripletColor) {
9+
var idealTextColor = function(hexTripletColor) {
1010
var nThreshold = 105;
1111
if (hexTripletColor.indexOf('rgb') != -1) {
1212
hexTripletColor = rgb2hex(hexTripletColor);
@@ -18,10 +18,24 @@ function idealTextColor(hexTripletColor) {
1818
B: parseInt(hexTripletColor.substring(4, 6), 16)
1919
};
2020
var bgDelta = (components.R * 0.299) + (components.G * 0.587) + (components.B * 0.114);
21-
return ((255 - bgDelta) < nThreshold) ? "#000000" : "#ffffff";
21+
return ((255 - bgDelta) < nThreshold) ? "#000000" : "#E6E6E6";
2222
}
2323

24-
function formatOption(option) {
24+
var formatOptionSelection = function(option, container) {
25+
if (typeof option.color != 'undefined'
26+
&& option.color.length > 0) {
27+
var invertedcolor = idealTextColor(option.color);
28+
$(container)
29+
.css("background-color", option.color)
30+
.css("border-color", invertedcolor)
31+
.css("color", invertedcolor)
32+
.children('.select2-selection__choice__remove')
33+
.css("color", invertedcolor);
34+
}
35+
return option.text;
36+
};
37+
38+
var formatOptionResult = function(option, container) {
2539
var template = "<span class='tag_choice' style='";
2640
if (typeof option.color != 'undefined'
2741
&& option.color !== "") {
@@ -34,4 +48,4 @@ function formatOption(option) {
3448
template+= "'>" + option.text + "</span>";
3549

3650
return $(template);
37-
}
51+
};

js/entity.js

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
$(function() {
2+
var items_id = getUrlParameter('id');
3+
4+
//only in edit form
5+
if (items_id == undefined) {
6+
return;
7+
}
8+
9+
$(".ui-tabs-panel:visible").ready(function() {
10+
setEntityTag();
11+
})
12+
13+
$("#tabspanel + div.ui-tabs").on("tabsload", function() {
14+
setTimeout(function() {
15+
setEntityTag();
16+
}, 300);
17+
});
18+
});
19+
20+
var setEntityTag = function() {
21+
22+
// find entity title for ticket
23+
var regex = /.+(-\s.+\s[0-9]+)*\s\((.+)\)/;
24+
var entity_title = $('#page .tab_cadre_pager tr.tab_bg_2:first-child td.b.big, \
25+
#mainformtable tr.headerRow:first-child th:first-child').filter(
26+
function() {
27+
return regex.test($(this).text());
28+
}
29+
);
30+
31+
var entity_element = null;
32+
var entity_name = null;
33+
34+
if (entity_title.length > 0) {
35+
entity_element = entity_title.first();
36+
var matches = entity_element.text().match(regex);
37+
entity_name = matches[2];
38+
} else {
39+
// find entity title for all objects except tickets
40+
// check first the th with recursive select
41+
var entity_title = $('#mainformtable tr.headerRow > th:nth-child(2) > .tab_format tr')
42+
.has('select[name=is_recursive]')
43+
.children('th:first-child');
44+
45+
if (entity_title.length > 0) {
46+
entity_element = entity_title;
47+
entity_name = entity_element.text();
48+
}
49+
}
50+
51+
if (null === entity_element || entity_element.hasClass('tags_already_set')) {
52+
return;
53+
}
54+
55+
entity_element.addClass('tags_already_set');
56+
57+
$.ajax({
58+
url: CFG_GLPI.root_doc + '/plugins/tag/ajax/get_entity_tags.php',
59+
data: {
60+
'name': entity_name,
61+
},
62+
success: function(response) {
63+
entity_element.html(function() {
64+
if ($(this).html().indexOf(')') > 0) {
65+
return $(this).html().replace(/\)$/, response + ')');
66+
} else {
67+
return $(this).html() + response;
68+
}
69+
});
70+
}
71+
});
72+
};
73+
74+
var getUrlParameter = function(val) {
75+
var result = undefined,
76+
tmp = [];
77+
78+
location.search
79+
.substr(1) // remove '?'
80+
.split("&")
81+
.forEach(function (item) {
82+
tmp = item.split("=");
83+
if (tmp[0] === val) {
84+
result = decodeURIComponent(tmp[1]);
85+
}
86+
});
87+
return result;
88+
};

0 commit comments

Comments
 (0)