Skip to content

Commit 1d5386f

Browse files
committed
Merge branch 'tags' into dev
2 parents 606c190 + 88525ec commit 1d5386f

22 files changed

Lines changed: 491 additions & 193 deletions

src/Controllers/CategoriesController.php

Lines changed: 81 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -226,39 +226,85 @@ protected function add_reasons_to($request)
226226
*/
227227
protected function add_tags_to($request)
228228
{
229-
$tag_rules = $tag_messages = [];
229+
$a_kept_tags = $a_key_names = $a_names = $tag_rules = $tag_messages = [];
230230

231231
// Allow alphanumeric and the following: ? @ / - _
232-
$tag_rule = "required|regex:/^[A-Za-z0-9?@\/\-_\s]+$/";
232+
$tag_rule = "required|regex:" . trans('panichd::admin.tag-regex');
233233

234-
// Add validation for new tags like it were fields
235-
$a_tags_new = [];
236-
if ($request->input('new_tags')) {
237-
$i = 0;
238-
foreach ($request->input('new_tags') as $tag) {
239-
$a_tags_new[] = $tag;
240-
$request['tag'.++$i] = $tag;
241-
$tag_rules['tag'.$i] = $tag_rule;
242-
$tag_messages['tag'.$i.'.regex'] = trans('panichd::admin.category-tag-not-valid-format', ['tag'=>$tag]);
243-
}
244-
}
234+
$c_tags = Tag::all();
245235

246236
$a_tags_update = [];
247237
for ($i = 0; $i < $request->input('tags_count'); $i++) {
248-
if (!$request->input('jquery_delete_tag_'.$i) != "") {
249-
// Add validation for renamed tags
250-
if ($request->exists('jquery_tag_name_'.$i) and $request->input('jquery_tag_id_'.$i) != "") {
251-
$tag = $request->input('jquery_tag_name_'.$i);
252-
$request->merge(['jquery_tag_name_'.$i=>$tag]);
253-
$a_tags_update[$request->input('jquery_tag_id_'.$i)]['name'] = $tag;
254-
$request['jquery_tag_name_'.$i] = $tag;
255-
$tag_rules['jquery_tag_name_'.$i] = $tag_rule;
256-
$tag_messages['jquery_tag_name_'.$i.'.regex'] = trans('panichd::admin.category-tag-not-valid-format', ['tag'=>$tag]);
238+
$tag = $c_tags->first(function($q)use($request, $i){
239+
return $q->id == $request->{'jquery_tag_id_'.$i};
240+
});
241+
242+
if ($request->has('jquery_tag_id_'.$i) and !$request->has('jquery_delete_tag_'.$i) and !is_null($tag)) {
243+
// Tag has been kept in category
244+
$a_kept_tags [$i] = $tag;
245+
246+
if ($request->exists('jquery_tag_name_'.$i)) {
247+
// Add new name for rule preparation
248+
$a_key_names[$i] = $request->{'jquery_tag_name_' . $i};
249+
250+
}else{
251+
// Add current name (has not changed) for rule preparation
252+
$a_key_names[$i] = $tag->name;
257253
}
254+
}
255+
}
256+
257+
// Names for new tags rule preparation
258+
$a_names = array_values($a_key_names);
259+
260+
foreach ($a_kept_tags as $i => $tag){
261+
// Add validation for renamed tags
262+
if ($request->exists('jquery_tag_name_'.$i)) {
263+
// New tag name
264+
$new_name = $request->input('jquery_tag_name_'.$i);
265+
266+
$request->merge(['jquery_tag_name_'.$i=>$new_name]);
267+
$a_tags_update[$request->input('jquery_tag_id_'.$i)]['name'] = $new_name;
268+
$request['jquery_tag_name_'.$i] = $new_name;
269+
270+
// Rule for an updated tag
271+
$a_this_not_in = $a_key_names;
272+
unset($a_this_not_in[$i]);
273+
$tag_rules['jquery_tag_name_'.$i] = $tag_rule . ($a_this_not_in ? '|not_in:' . implode(',', array_values($a_this_not_in)) : '');
274+
275+
// Add specific validation error messages
276+
$tag_messages['jquery_tag_name_' . $i . '.required'] = trans('panichd::admin.update-tag-validation-empty', ['name' => $tag->name]);
277+
$tag_messages['jquery_tag_name_' . $i . '.regex'] = trans('panichd::admin.category-tag-not-valid-format', ['tag'=>$new_name]);
278+
$tag_messages['jquery_tag_name_' . $i . '.not_in'] = trans('panichd::admin.tag-validation-two', ['name' => $new_name]);
279+
280+
}
258281

259-
// Add colors for tag update
260-
if ($request->input('jquery_tag_color_'.$i) != "") {
261-
$a_tags_update[$request->input('jquery_tag_id_'.$i)]['color'] = $request->input('jquery_tag_color_'.$i);
282+
// Add colors for tag update
283+
if ($request->input('jquery_tag_color_'.$i) != "") {
284+
$a_tags_update[$request->input('jquery_tag_id_'.$i)]['color'] = $request->input('jquery_tag_color_'.$i);
285+
}
286+
}
287+
288+
// Add validation for new tags
289+
$a_tags_new = [];
290+
if ($request->filled('new_tags')) {
291+
foreach ($request->input('new_tags') as $id) {
292+
if (!$request->has('jquery_delete_tag_' . $id)){
293+
// Rule for new tag
294+
$tag_rules['jquery_tag_name_' . $id] = $tag_rule . ($a_names ? '|not_in:' . implode(',', $a_names) : '');
295+
296+
// Add tag name to array
297+
$a_names[] = $request->{'jquery_tag_name_' . $id};
298+
299+
// Add specific validation error messages
300+
$tag_messages['jquery_tag_name_' . $id . '.required'] = trans('panichd::admin.new-tag-validation-empty');
301+
$tag_messages['jquery_tag_name_' . $id . '.regex'] = trans('panichd::admin.category-tag-not-valid-format', ['tag' => $request->{'jquery_tag_name_' . $id}]);
302+
$tag_messages['jquery_tag_name_' . $id . '.not_in'] = trans('panichd::admin.tag-validation-two', ['name' => $request->{'jquery_tag_name_' . $id}]);
303+
304+
$a_tags_new[] = [
305+
'name' => $request->{'jquery_tag_name_' . $id},
306+
'color' => $request->{'jquery_tag_color_'.$id}
307+
];
262308
}
263309
}
264310
}
@@ -284,7 +330,7 @@ protected function do_validate($request, $rules, $reason_messages)
284330
'email_name' => 'required|string',
285331
'email' => 'required|email',
286332
]);
287-
}
333+
}
288334

289335
$this->validate($request, $rules, $reason_messages);
290336
}
@@ -396,12 +442,16 @@ protected function sync_category_tags($request, $category, $a_tags_new, $a_tags_
396442
}
397443

398444
// Add new tags
399-
foreach ($a_tags_new as $tag) {
400-
$new = Tag::whereHas('categories', function ($q) use ($category) {
401-
$q->where('id', $category->id);
402-
})->where('name', $tag)->firstOrCreate(['name'=>$tag]);
445+
foreach ($a_tags_new as $a_tag) {
446+
$a_colors = explode('_', $a_tag['color']);
447+
448+
$new_tag = Tag::create([
449+
'name' => $a_tag['name'],
450+
'bg_color' => $a_colors[0],
451+
'text_color' => $a_colors[1]
452+
]);
403453

404-
$tags[] = $new->id;
454+
$tags[] = $new_tag->id;
405455
}
406456

407457
// Sync all category tags

src/Controllers/TicketsController.php

Lines changed: 69 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1394,7 +1394,18 @@ protected function validation_common($request, $new_ticket = true)
13941394
'owner_id' => 'required|exists:' . $this->member->getTable() . ',id',
13951395
'category_id' => 'required|in:'.$allowed_categories,
13961396
'content' => 'required|min:6',
1397-
];
1397+
];
1398+
1399+
// Custom validation messages
1400+
$custom_messages = [
1401+
'subject.required' => trans ('panichd::lang.validate-ticket-subject.required'),
1402+
'subject.min' => trans ('panichd::lang.validate-ticket-subject.min'),
1403+
'content.required' => trans ('panichd::lang.validate-ticket-content.required'),
1404+
'content.min' => trans ('panichd::lang.validate-ticket-content.min'),
1405+
'start_date_year.in' => trans ('panichd::lang.validate-ticket-start_date'),
1406+
'limit_date_year.in' => trans ('panichd::lang.validate-ticket-limit_date'),
1407+
];
1408+
13981409
$a_result_errors = [];
13991410

14001411
if ($permission_level > 1) {
@@ -1460,6 +1471,26 @@ protected function validation_common($request, $new_ticket = true)
14601471
}
14611472
}
14621473

1474+
// New tags validation
1475+
if ($request->has('new_tags') and $request->filled('new_tags')) {
1476+
// Current category tag names array
1477+
$a_names = Tag::whereHas('categories', function($query)use($request){ $query->where('id', $request->category_id); })->pluck('name')->toArray();
1478+
1479+
foreach ($request->input('new_tags') as $id) {
1480+
if (!$request->has('jquery_delete_tag_' . $id)){
1481+
// Rule for new tag
1482+
$fields['jquery_tag_name_' . $id] = "required|regex:" . trans('panichd::admin.tag-regex') . ($a_names ? '|not_in:' . implode(',', $a_names) : '');
1483+
1484+
// Add tag name to array
1485+
$a_names[] = $request->{'jquery_tag_name_' . $id};
1486+
1487+
// Add specific validation error messages
1488+
$custom_messages['jquery_tag_name_' . $id . '.required'] = trans('panichd::admin.new-tag-validation-empty');
1489+
$custom_messages['jquery_tag_name_' . $id . '.regex'] = trans('panichd::admin.category-tag-not-valid-format', ['tag' => $request->{'jquery_tag_name_' . $id}]);
1490+
$custom_messages['jquery_tag_name_' . $id . '.not_in'] = trans('panichd::admin.tag-validation-two', ['name' => $request->{'jquery_tag_name_' . $id}]);
1491+
}
1492+
}
1493+
}
14631494

14641495
$a_intervention = $common_data['a_intervention'] = $this->purifyInterventionHtml($request->get('intervention'));
14651496
$request->merge([
@@ -1472,16 +1503,6 @@ protected function validation_common($request, $new_ticket = true)
14721503
}
14731504
}
14741505

1475-
// Custom validation messages
1476-
$custom_messages = [
1477-
'subject.required' => trans ('panichd::lang.validate-ticket-subject.required'),
1478-
'subject.min' => trans ('panichd::lang.validate-ticket-subject.min'),
1479-
'content.required' => trans ('panichd::lang.validate-ticket-content.required'),
1480-
'content.min' => trans ('panichd::lang.validate-ticket-content.min'),
1481-
'start_date_year.in' => trans ('panichd::lang.validate-ticket-start_date'),
1482-
'limit_date_year.in' => trans ('panichd::lang.validate-ticket-limit_date'),
1483-
];
1484-
14851506
// Form validation
14861507
$validator = Validator::make($request->all(), $fields, $custom_messages);
14871508

@@ -2060,7 +2081,6 @@ public function update(Request $request, $id)
20602081
*/
20612082
protected function sync_ticket_tags($request, $ticket)
20622083
{
2063-
20642084
// Get marked current tags
20652085
$input_tags = $request->input('category_'.$request->input('category_id').'_tags');
20662086
if (!$input_tags) {
@@ -2070,16 +2090,50 @@ protected function sync_ticket_tags($request, $ticket)
20702090
// Valid tags has all category tags
20712091
$category_tags = $ticket->category->tags()->get();
20722092
$category_tags = (version_compare(app()->version(), '5.3.0', '>=')) ? $category_tags->pluck('id')->toArray() : $category_tags->lists('id')->toArray();
2073-
// Valid tags has ticket tags that doesn't have category
2093+
2094+
// Valid tags has ticket tags that doesn't have category
20742095
$ticket_only_tags = Tag::doesntHave('categories')->whereHas('tickets', function ($q2) use ($ticket) {
20752096
$q2->where('id', $ticket->id);
20762097
})->get();
20772098
$ticket_only_tags = (version_compare(app()->version(), '5.3.0', '>=')) ? $ticket_only_tags->pluck('id')->toArray() : $ticket_only_tags->lists('id')->toArray();
20782099

2079-
$tags = array_intersect($input_tags, array_merge($category_tags, $ticket_only_tags));
2100+
// Filter valid assigned tags
2101+
$all_ticket_tags = array_intersect($input_tags, array_merge($category_tags, $ticket_only_tags));
2102+
2103+
// Add new tags
2104+
if ($request->has('new_tags') and $request->filled('new_tags')) {
2105+
foreach ($request->input('new_tags') as $id) {
2106+
$colors = $request->{'jquery_tag_color_'.$id};
2107+
$a_colors = explode('_', $colors);
2108+
if (!$request->has('jquery_delete_tag_' . $id)){
2109+
// Create new tag
2110+
$tag = Tag::create([
2111+
'name' => $request->{'jquery_tag_name_' . $id},
2112+
'bg_color' => $a_colors[0],
2113+
'text_color' => $a_colors[1]
2114+
]);
2115+
2116+
// Attach tag to the ticket category
2117+
$ticket->category()->first()->tags()->attach($tag);
2118+
2119+
// Attach tag to ticket
2120+
$all_ticket_tags[] = $tag->id;
2121+
}
2122+
}
2123+
}
2124+
2125+
// List old tags
2126+
$old_tags = $ticket->tags()->pluck('id')->toArray();
2127+
2128+
// Check if tag list has changed
2129+
sort($old_tags);
2130+
sort($all_ticket_tags);
2131+
if($old_tags != $all_ticket_tags){
2132+
$ticket->touch();
2133+
}
20802134

20812135
// Sync all ticket tags
2082-
$ticket->tags()->sync($tags);
2136+
$ticket->tags()->sync($all_ticket_tags);
20832137

20842138
// Delete orphan tags (Without any related categories or tickets)
20852139
Tag::doesntHave('categories')->doesntHave('tickets')->delete();

src/Models/Tag.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
class Tag extends Model
88
{
99
protected $table = 'panichd_tags';
10-
protected $fillable = ['name'];
10+
protected $fillable = ['name', 'text_color', 'bg_color'];
1111

1212
/**
1313
* Get related categories.

src/Public/css/panichd.css

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ h1, h2, h3, h4, h5, h6 {
6161
.btn-xs {
6262
padding : .4rem;
6363
font-size : .9rem;
64-
line-height : .5;
64+
line-height : .5rem;
6565
border-radius : .2rem;
6666
}
6767

@@ -303,6 +303,9 @@ h1, h2, h3, h4, h5, h6 {
303303
.btn.btn-tag {
304304
border: transparent;
305305
}
306+
.btn-tag.btn-xs {
307+
line-height: 0.9rem;
308+
}
306309

307310
.card-highlight {
308311
border-color: #FFE171;

src/Translations/ca/admin.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@
134134
'category-index-email' => 'Remitent de notificacions',
135135
'category-index-reasons' => 'Raons tancament',
136136
'category-index-tags' => 'Etiquetes',
137+
137138
'category-create-title' => 'Crear Nova Categoria',
138139
'category-create-name' => 'Nom',
139140
'category-create-email' => 'Remitent de notificacions',
@@ -153,19 +154,29 @@
153154
'category-create-color' => 'Color',
154155
'category-create-new-tickets' => 'Qui pot crear tiquets',
155156
'category-create-new-tickets-help' => 'Nivell mínim a la categoria per a crear tiquets',
157+
156158
'category-edit-title' => 'Editar Categoria: :name',
159+
157160
'category-edit-closing-reasons' => 'Tancaments de tiquet',
158161
'category-edit-closing-reasons-help' => 'Opcions que l\'usuari haurà de triar quan tanqui un tiquet',
159162
'category-edit-reason' => 'Raó de tancament',
160163
'category-edit-reason-label' => 'Raó',
161164
'category-edit-reason-status' => 'Estat',
162165
'category-delete-reason' => 'Eliminar raó',
166+
163167
'category-edit-new-tags' => 'Etiq. noves',
164168
'category-edit-current-tags' => 'Etiq. actuals',
169+
'category-edit-new-tag-title' => 'Crear etiqueta nova',
170+
'category-edit-new-tag-default' => 'Etiqueta nova',
165171
'category-edit-tag' => 'Editar etiqueta',
166172
'category-edit-tag-background' => 'Fons',
167173
'category-edit-tag-text' => 'Text',
168174

175+
'tag-regex' => '/^[A-Za-z\x{00C0}-\x{017F}·\'0-9?@\/\-_\s]+$/u',
176+
'new-tag-validation-empty' => 'No pots registrar una etiqueta amb el nom en blanc',
177+
'update-tag-validation-empty' => 'No pots deixar en blanc el nom de l\'etiqueta abans anomenada ":name"',
178+
'tag-validation-two' => 'Has indicat dues etiquetes amb el mateix nom ":name"',
179+
169180
// Category form validation
170181
'category-reason-is-empty' => 'La raó de tancament :number no té text',
171182
'category-reason-too-short' => 'La raó de tancament :number amb el nom ":name" requereix :min caràcters',

src/Translations/en/admin.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@
135135
'category-index-email' => 'Notifications email',
136136
'category-index-reasons' => 'Closing reasons',
137137
'category-index-tags' => 'Tags',
138+
138139
'category-create-title' => 'Create New Category',
139140
'category-create-name' => 'Name',
140141
'category-create-email' => 'Notifications email',
@@ -154,24 +155,35 @@
154155
'category-create-color' => 'Color',
155156
'category-create-new-tickets' => 'Who may create tickets',
156157
'category-create-new-tickets-help' => 'Minimum level to create tickets in category',
158+
157159
'category-edit-title' => 'Edit Category: :name',
160+
158161
'category-edit-closing-reasons' => 'Ticket closing reasons',
159162
'category-edit-closing-reasons-help' => 'Options that user may choose when closing ticket',
160163
'category-edit-reason' => 'Closing reason',
161164
'category-edit-reason-label' => 'Reason',
162165
'category-edit-reason-status' => 'Status',
163166
'category-delete-reason' => 'Delete reason',
167+
164168
'category-edit-new-tags' => 'New tags',
165169
'category-edit-current-tags' => 'Current tags',
170+
'category-edit-new-tag-title' => 'Create a new tag',
171+
'category-edit-new-tag-default' => 'New tag',
166172
'category-edit-tag' => 'Edit tag',
167173
'category-edit-tag-background' => 'Background',
168174
'category-edit-tag-text' => 'Text',
175+
176+
'new-tag-validation-empty' => 'You cannot register a tag with an empty name',
177+
'update-tag-validation-empty' => 'You cannot leave blank the tag name of the one previously named ":name"',
169178

170179
// Category form validation
171180
'category-reason-is-empty' => 'Closing reason :number has no text',
172181
'category-reason-too-short' => 'Closing reason :number with name ":name" requires :min characters',
173182
'category-reason-no-status' => 'Closing reason :number with name ":name" requires a defined status',
183+
184+
'tag-regex' => '/^[A-Za-z0-9?@\/\-_\s]+$/',
174185
'category-tag-not-valid-format' => 'Tag ":tag" format is not valid',
186+
'tag-validation-two' => 'You have introduced two tags with the same name ":name"',
175187

176188
// $admin_route_path/member/____
177189
'member-index-title' => 'Members management',

src/Translations/es/admin.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,20 @@
103103
'category-create-title' => 'Crear Categoría Nueva',
104104
'category-create-name' => 'Nombre',
105105
'category-create-color' => 'Color',
106-
'category-edit-title' => 'Editar Categoría: :name',
106+
'category-edit-title' => 'Editar Categoria: :name',
107+
108+
'category-edit-new-tags' => 'Etiq. nuevas',
109+
'category-edit-current-tags' => 'Etiq. actuales',
110+
'category-edit-new-tag-title' => 'Crear etiqueta nueva',
111+
'category-edit-new-tag-default' => 'Etiqueta nueva',
112+
'category-edit-tag' => 'Editar etiqueta',
113+
'category-edit-tag-background' => 'Fondo',
114+
'category-edit-tag-text' => 'Texto',
115+
116+
'tag-regex' => '/^[A-Za-z\x{00C0}-\x{017F}0-9?@\/\-_\s]+$/u',
117+
'new-tag-validation-empty' => 'No puedes registrar una etiqueta con el nombre en blanco',
118+
'update-tag-validation-empty' => 'No puedes dejar en blanco el nombre de la etiqueta con nombre anterior ":name"',
119+
'tag-validation-two' => 'Has indicado dos etiquetas con el mismo nombre ":name"',
107120

108121
// $admin_route_path/priority/____
109122
'priority-index-title' => 'Administración de Prioridades',

0 commit comments

Comments
 (0)