Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert Ticket Listing to Vue.js #63

Merged
merged 46 commits into from
Jul 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
bf12083
Initial conversion started
nirix Jun 28, 2022
85f74dc
PHP 8.0+
nirix Jun 29, 2022
d61ebad
Tooling tweaks
nirix Jun 29, 2022
c9fa299
Minor theme improvements
nirix Jun 29, 2022
8589582
Ticket listing styling
nirix Jun 29, 2022
6901797
Progress on ticket filters
nirix Jun 29, 2022
ec97e1f
FontAwesome
nirix Jun 30, 2022
f29abe6
Add/remove ticket filters and values
nirix Jun 30, 2022
90ef10d
Handle filter condition changes
nirix Jun 30, 2022
45561fe
Update success button ring colour
nirix Jun 30, 2022
f7c3538
Tweak filter UI
nirix Jun 30, 2022
0634798
Handle ticket filter application
nirix Jun 30, 2022
5031cb6
Convert query string to filters
nirix Jun 30, 2022
09a640a
Add Luxon
nirix Jul 1, 2022
1a037d2
Ticket filter styling and animation
nirix Jul 1, 2022
d102d9d
Ticket columns
nirix Jul 1, 2022
e965250
Update button styles
nirix Jul 1, 2022
42e05a0
Cleanup old code
nirix Jul 1, 2022
86b436c
Implement filter datasets
nirix Jul 1, 2022
01ae25c
Convert `allOpen` and `allClosed` to statuses
nirix Jul 2, 2022
454ba9c
Cleanup older files
nirix Jul 2, 2022
52e84e3
PHP 7/8 fixes
nirix Jul 2, 2022
dca340c
Add custom fields API route
nirix Jul 2, 2022
fdb898d
Add custom fields to Tickets endpoint
nirix Jul 2, 2022
a17f3f9
Add custom fields to TicketColumns component
nirix Jul 2, 2022
f9ab5b1
Show/hide custom fields
nirix Jul 2, 2022
7ec42ea
Custom field filtering
nirix Jul 2, 2022
c5a2288
Update custom field type options
nirix Jul 2, 2022
6508bd3
Promises everywhere
nirix Jul 2, 2022
77d0310
Update filter name width
nirix Jul 2, 2022
34c35ba
Implement auth info endpoint
nirix Jul 2, 2022
149d064
Strip comments from install.sql before executing
nirix Jul 2, 2022
6774b93
Begin Mass Actions component
nirix Jul 2, 2022
b3cf2df
Fix primary button colours
nirix Jul 2, 2022
b1f2b88
Implement auth/user store
nirix Jul 3, 2022
f057e27
Mass Actions fields
nirix Jul 3, 2022
aa78f49
Add Type filter
nirix Jul 3, 2022
c6dc17e
Update Avalon
nirix Jul 3, 2022
024f6be
Add project members endpoint
nirix Jul 3, 2022
ca9a446
Update styling along with custom checkbox
nirix Jul 3, 2022
9b0fdb5
Implement backend project members endpoint
nirix Jul 3, 2022
92cc280
Cleanup styling
nirix Jul 3, 2022
d3d14a6
Implement mass action updating
nirix Jul 4, 2022
13e68b3
Add EasyMDE to handle mass actions comment
nirix Jul 4, 2022
0703c52
Cleanup
nirix Jul 4, 2022
cb8664b
Implement pagination
nirix Jul 4, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module.exports = {
"eslint:recommended",
"@vue/eslint-config-typescript/recommended",
],
parser: "vue-eslint-parser",
rules: {
"comma-dangle": ["error", "always-multiline"],
},
Expand Down
9 changes: 8 additions & 1 deletion .prettierrc.json
Original file line number Diff line number Diff line change
@@ -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"
}
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"editor.formatOnSave": true,
"cSpell.ignoreWords": [
"TRAQ",
"axios"
"axios",
"roadmap"
]
}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
132 changes: 32 additions & 100 deletions assets/js/mass_actions.js
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -19,101 +19,33 @@
* along with Traq. If not, see <http://www.gnu.org/licenses/>.
*/

$(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")
}
})
})
})
191 changes: 95 additions & 96 deletions assets/js/ticket_tasks.js
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -19,107 +19,106 @@
* along with Traq. If not, see <http://www.gnu.org/licenses/>.
*/

$(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")
})
})
})
})
Loading