diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 2ec566d8c..a4b6b19bf 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -8,6 +8,7 @@ module.exports = { "eslint:recommended", "@vue/eslint-config-typescript/recommended", ], + parser: "vue-eslint-parser", rules: { "comma-dangle": ["error", "always-multiline"], }, diff --git a/.prettierrc.json b/.prettierrc.json index 6879e2f5b..db1175caf 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,4 +1,11 @@ { + "printWidth": 160, + "tabWidth": 2, + "endOfLine": "lf", + "tabs": false, "semi": false, - "trailingComma": "es5" + "trailingComma": "es5", + "quoteProps": "as-needed", + "bracketSpacing": true, + "arrowParens": "always" } \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index d523d01e4..c3bbe1ee2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,6 +3,7 @@ "editor.formatOnSave": true, "cSpell.ignoreWords": [ "TRAQ", - "axios" + "axios", + "roadmap" ] } \ No newline at end of file diff --git a/README.md b/README.md index beeb323a9..70d0e35e0 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Traq is a PHP powered project manager, capable of tracking issues for multiple p Requirements ------------ -- PHP 7.4+ +- PHP 8.0+ - MariaDB _(or MySQL)_ - Apache mod_rewrite or server configured to use `index.php` as the 404 page. diff --git a/assets/js/mass_actions.js b/assets/js/mass_actions.js index c5b6fdcdc..a9e31ae94 100644 --- a/assets/js/mass_actions.js +++ b/assets/js/mass_actions.js @@ -1,7 +1,7 @@ /*! * Traq - * Copyright (C) 2009-2013 Traq.io - * Copyright (C) 2009-2013 J. Polgar + * Copyright (C) 2009-2022 Traq.io + * Copyright (C) 2009-2022 J. Polgar * https://github.com/nirix * * This file is part of Traq. @@ -19,101 +19,33 @@ * along with Traq. If not, see . */ -$(document).ready(function(){ - // Get selected tickets. - var selected_tickets = $.cookie('selected_tickets'); - - // Selected users - var selected_users = []; - - // If there are none, set empty array. - if (!selected_tickets) { - selected_tickets = []; - } else { - selected_tickets = JSON.parse($.cookie('selected_tickets')); - } - - // Set form value - $('#mass_actions input[name="tickets"]').val(JSON.stringify(selected_tickets)); - - // Save selected tickets. - var saveSelectedTickets = function() { - $.cookie('selected_tickets', JSON.stringify(selected_tickets)); - - // Show mass actions form - if (selected_tickets.length > 0) { - $('#mass_actions').slideDown('fast'); - } else { - $('#mass_actions').slideUp('fast'); - } - - $('#mass_actions input[name="tickets"]').val(JSON.stringify(selected_tickets)); - }; - - // Check selected tickets - $(selected_tickets).each(function(i, ticket_id){ - $('#mass_action_ticket_' + ticket_id).prop('checked', true); - $('#mass_actions').show(); - }); - - $('#tickets .mass_actions #select_all_tickets').on('click', function(){ - var select_all = $(this).is(':checked'); - $('#tickets input[type="checkbox"][name^="tickets"]').each(function(){ - var ticket_id = $(this).val(); - if (select_all && !$(this).is(':checked')) { - $(this).prop('checked', true); - selected_tickets.push(ticket_id); - } else if(!select_all && $(this).is(':checked')) { - $(this).prop('checked', false); - selected_tickets = $.grep(selected_tickets, function(a){ return a != ticket_id; }); - } - saveSelectedTickets(); - }); - }); - - // Loop over checkboxes - $('#tickets .mass_actions input[type="checkbox"][name^="tickets"]').each(function(){ - // Add click event - $(this).on('click', function(){ - var ticket_id = $(this).val(); - - // Add ticket ID to selected tickets - if ($(this).is(':checked')) { - selected_tickets.push(ticket_id); - } else { - selected_tickets = $.grep(selected_tickets, function(a){ return a != ticket_id; }); - $('#tickets #select_all_tickets').prop('checked', false); - } - saveSelectedTickets(); - }); - }); - - // I'm not particularly proud of the code below, but then again I'm not at all - // proud of the 3.x codebase, so screw it, I'll make it better in 4.x. - - $('#select_all_users').on('click', function(){ - if ($(this).is(':checked')) { - $('#users .mass_actions input').each(function(){ - $(this).prop('checked', true); - }); - - // $('#mass_actions').slideDown('fast'); - } else { - $('#users .mass_actions input').each(function(){ - $(this).prop('checked', false); - }); - - // $('#mass_actions').slideUp('fast'); - } - }); - - $('#users .mass_actions input').each(function(){ - $(this).on('click', function(){ - if ($('#users .mass_actions input:checked').length > 0) { - $('#mass_actions').slideDown('fast'); - } else { - $('#mass_actions').slideUp('fast'); - } - }); - }); -}); +jQuery(document).ready(function () { + // I'm not particularly proud of the code below, but then again I'm not at all + // proud of the 3.x codebase, so screw it, I'll make it better in 4.x. + + jQuery("#select_all_users").on("click", function () { + if (jQuery(this).is(":checked")) { + jQuery("#users .mass_actions input").each(function () { + jQuery(this).prop("checked", true) + }) + + // jQuery('#mass_actions').slideDown('fast'); + } else { + jQuery("#users .mass_actions input").each(function () { + jQuery(this).prop("checked", false) + }) + + // jQuery('#mass_actions').slideUp('fast'); + } + }) + + jQuery("#users .mass_actions input").each(function () { + jQuery(this).on("click", function () { + if (jQuery("#users .mass_actions input:checked").length > 0) { + jQuery("#mass_actions").slideDown("fast") + } else { + jQuery("#mass_actions").slideUp("fast") + } + }) + }) +}) diff --git a/assets/js/ticket_tasks.js b/assets/js/ticket_tasks.js index b0c3e761d..4829622c9 100644 --- a/assets/js/ticket_tasks.js +++ b/assets/js/ticket_tasks.js @@ -1,7 +1,7 @@ /*! * Traq - * Copyright (C) 2009-2013 Traq.io - * Copyright (C) 2009-2013 J. Polgar + * Copyright (C) 2009-2022 Traq.io + * Copyright (C) 2009-2022 J. Polgar * https://github.com/nirix * * This file is part of Traq. @@ -19,107 +19,106 @@ * along with Traq. If not, see . */ -$(document).ready(function(){ - // Manage ticket tasks - $(document).on('click', '#manage_ticket_tasks', function(){ - $('#overlay').load($(this).attr('data-url') + '?overlay=true', function(){ - var tasks = $('#ticket_tasks_data input[name="tasks"]').val(); +jQuery(document).ready(function () { + // Manage ticket tasks + jQuery(document).on("click", "#manage_ticket_tasks", function () { + jQuery("#overlay").load(jQuery(this).attr("data-url") + "?overlay=true", function () { + var tasks = jQuery('#ticket_tasks_data input[name="tasks"]').val() - if (tasks == '') { - tasks = new Array(); - } else { - tasks = JSON.parse(tasks); - } + if (tasks == "") { + tasks = new Array() + } else { + tasks = JSON.parse(tasks) + } - $(tasks).each(function(task_id, task){ - $("#ticket_tasks_manager #task_count").val(tasks.length); - $.get( - traq.base + '_misc/ticket_tasks_bit', - { id: task_id, completed: String(task.completed), task: task.task }, - function(data){ - $('#ticket_tasks_manager .tasks').append(data); - } - ); - }); - $('#overlay').overlay(); - }); - }); + jQuery(tasks).each(function (task_id, task) { + jQuery("#ticket_tasks_manager #task_count").val(tasks.length) + $.get(traq.base + "_misc/ticket_tasks_bit", { id: task_id, completed: String(task.completed), task: task.task }, function (data) { + jQuery("#ticket_tasks_manager .tasks").append(data) + }) + }) + jQuery("#overlay").overlay() + }) + }) - // Add ticket task - $(document).on('click', "#ticket_tasks_manager #add_task", function(){ - var task_id = parseInt($("#task_count").val()); - $.get(traq.base + '_misc/ticket_tasks_bit?id=' + task_id, function(data){ - $("#task_count").val(task_id += 1); - $("#ticket_tasks_manager .tasks").append($(data).hide()).find('.task:last').slideDown('fast', function(){ - $(this).find('[type=text]').focus(); - }); - }); - }); + // Add ticket task + jQuery(document).on("click", "#ticket_tasks_manager #add_task", function () { + var task_id = parseInt(jQuery("#task_count").val()) + $.get(traq.base + "_misc/ticket_tasks_bit?id=" + task_id, function (data) { + jQuery("#task_count").val((task_id += 1)) + jQuery("#ticket_tasks_manager .tasks") + .append(jQuery(data).hide()) + .find(".task:last") + .slideDown("fast", function () { + jQuery(this).find("[type=text]").focus() + }) + }) + }) - // Process ticket tasks form data - $(document).on('click', "#overlay #set_ticket_tasks", function(){ - close_overlay(function(){ - var task_count = parseInt($("#task_count").val()); - var data = new Array(); - $('#ticket_tasks_manager input[name*="tasks"]').each(function(){ - var e = $(this); - var task_id = parseInt(e.attr('data-task-id')); + // Process ticket tasks form data + jQuery(document).on("click", "#overlay #set_ticket_tasks", function () { + close_overlay(function () { + var task_count = parseInt(jQuery("#task_count").val()) + var data = new Array() + jQuery('#ticket_tasks_manager input[name*="tasks"]').each(function () { + var e = jQuery(this) + var task_id = parseInt(e.attr("data-task-id")) - if (!data[task_id]) { - data[task_id] = {} - } + if (!data[task_id]) { + data[task_id] = {} + } - // Checkbox - if (e.attr('type') == 'checkbox') { - if (e.is(':checked')) { - data[task_id].completed = true; - } else { - data[task_id].completed = false; - } - } - // Text - else if(e.attr('type') == 'text') { - data[task_id].task = e.val(); - } - }); - $("#ticket_tasks_data input[name='task_count']").val(task_count); - $("#ticket_tasks_data input[name='tasks']").val(JSON.stringify(data)); - }); - }); + // Checkbox + if (e.attr("type") == "checkbox") { + if (e.is(":checked")) { + data[task_id].completed = true + } else { + data[task_id].completed = false + } + } + // Text + else if (e.attr("type") == "text") { + data[task_id].task = e.val() + } + }) + jQuery("#ticket_tasks_data input[name='task_count']").val(task_count) + jQuery("#ticket_tasks_data input[name='tasks']").val(JSON.stringify(data)) + }) + }) - // Delete ticket task - $(document).on('click', '#overlay button.delete_ticket_task', function(){ - var e = $(this); - $("#overlay #ticket_task_bit_" + e.attr('data-task-id')).slideUp('fast', function(){ - $(this).remove(); - }); - }); + // Delete ticket task + jQuery(document).on("click", "#overlay button.delete_ticket_task", function () { + var e = jQuery(this) + jQuery("#overlay #ticket_task_bit_" + e.attr("data-task-id")).slideUp("fast", function () { + jQuery(this).remove() + }) + }) - // Toggle task state - $(document).on('click', '#ticket_info #tasks .task input[type="checkbox"]', function(){ - var task_id = $(this).attr('data-task-task'); - var completed = false; + // Toggle task state + jQuery(document).on("click", '#ticket_info #tasks .task input[type="checkbox"]', function () { + var task_id = jQuery(this).attr("data-task-task") + var completed = false - // Get task state - if ($(this).is(':checked')) { - completed = true; - } + // Get task state + if (jQuery(this).is(":checked")) { + completed = true + } - // Update task - $.ajax({ - url: $(this).attr('data-url'), - data: { completed: completed }, - beforeSend: function(){ - // Disable tasks - $('#tasks input[type="checkbox"]').each(function(){ - $(this).attr('disabled','disabled'); - }); - } - }).done(function(){ - // Enable tasks - $('#tasks input[type="checkbox"]').each(function(){ - $(this).removeAttr('disabled'); - }); - }); - }); -}); + // Update task + $.ajax({ + url: jQuery(this).attr("data-url"), + data: { completed: completed }, + beforeSend: function () { + // Disable tasks + jQuery('#tasks input[type="checkbox"]').each(function () { + jQuery(this).attr("disabled", "disabled") + }) + }, + }).done(function () { + // Enable tasks + jQuery('#tasks input[type="checkbox"]').each(function () { + jQuery(this).removeAttr("disabled") + }) + }) + }) +}) diff --git a/assets/js/traq.js b/assets/js/traq.js index 8a1caaff8..ee0c47718 100644 --- a/assets/js/traq.js +++ b/assets/js/traq.js @@ -1,7 +1,7 @@ /*! * Traq - * Copyright (C) 2009-2014 Traq.io - * Copyright (C) 2009-2014 Jack P. + * Copyright (C) 2009-2022 Traq.io + * Copyright (C) 2009-2022 Jack P. * https://github.com/nirix * * This file is part of Traq. @@ -21,256 +21,246 @@ // The main Traq object var traq = { - base: '/', - load_ticket_template: function(){ - var type_id = $("#type option:selected").val(); - - $("#description").load(traq.base + '_ajax/ticket_template/' + type_id); - - traq.show_hide_custom_fields() - }, - show_hide_custom_fields: function(){ - var type_id = $("#type option:selected").val(); - - // Toggle visibility for custom fields that aren't relveant - // for the selected type. - $(".properties .custom_field").each(function(){ - var field = $(this); - - // Hide the field - field.hide(); - - // Check if it is for 0 (all) or the selected type ID and show it. - if (field.hasClass('field-for-type-0') || field.hasClass('field-for-type-' + type_id)) { - field.show(); - } - }); - } -}; + base: "/", + load_ticket_template: function () { + var type_id = jQuery("#type option:selected").val() + + jQuery("#description").load(traq.base + "_ajax/ticket_template/" + type_id) + + traq.show_hide_custom_fields() + }, + show_hide_custom_fields: function () { + var type_id = jQuery("#type option:selected").val() + + // Toggle visibility for custom fields that aren't relveant + // for the selected type. + jQuery(".properties .custom_field").each(function () { + var field = jQuery(this) + + // Hide the field + field.hide() + + // Check if it is for 0 (all) or the selected type ID and show it. + if (field.hasClass("field-for-type-0") || field.hasClass("field-for-type-" + type_id)) { + field.show() + } + }) + }, +} // Cookies, nom nom nom -$.cookie.defaults.path = '/'; +$.cookie.defaults.path = "/" // Language object -var language = {}; +var language = {} // Instead of that annoying popup confirm box // how about a nice simple popover box. // Credit to arturo182 -var popover_confirm = function(parent, message, callback) { - var outerDiv = $('
').addClass('popover_confirm'); - var innerDiv = $('
'); - - innerDiv.append($('