Skip to content

Commit

Permalink
enable paginating for job list under admin dashboard
Browse files Browse the repository at this point in the history
  • Loading branch information
thanhleviet committed Nov 21, 2024
1 parent 2860ab7 commit a69a608
Show file tree
Hide file tree
Showing 3 changed files with 212 additions and 62 deletions.
19 changes: 11 additions & 8 deletions src/main/html/webapp/components/admin/job/list/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,24 @@ import Control from 'can-control';
import $ from 'jquery';
import 'helpers/helpers';

import 'helpers/helpers';

import JobTable from './table/';

import template from './list.stache';

export default Control.extend({

"init": function (element, options) {
$(element).html(template());
$(element).fadeIn();

new JobTable("#job-list-running-ltq", { state: "running-ltq" });
new JobTable("#job-list-current", { state: "current" });

// Initialize running jobs table without pagination
new JobTable("#job-list-running-ltq", {
state: "running-ltq",
showControls: false // Don't show search/pagination for running jobs
});

// Initialize completed jobs table with pagination
new JobTable("#job-list-current", {
state: "current",
showControls: true // Show search/pagination for completed jobs
});
}

});
176 changes: 140 additions & 36 deletions src/main/html/webapp/components/admin/job/list/table/table.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,130 @@ import template from './table.stache';

export default Control.extend({

"init": function(element, options) {
defaults: {
pageSize: 10,
currentPage: 1,
searchQuery: '',
totalJobs: 0,
showControls: false
},

"init": function (element, options) {
this.element = element;

const storedPageSize = localStorage.getItem(`${this.options.state}_pageSize`);
if (storedPageSize) {
options.pageSize = parseInt(storedPageSize, 10);
}

this.options = $.extend({}, this.defaults, options);
this.loadJobs();
},

loadJobs: function () {
var that = this;
JobAdminDetails.findAll({
state: options.state
}, function(jobs) {
$.each(jobs, function(key, job) {
state: this.options.state
}, function (response) {
// Assuming response has both jobs array and counts
const jobs = response.jobs || response; // Handle both formats
const jobCounts = {
running: response.running || 0,
waiting: response.waiting || 0,
success: response.success || 0,
failed: response.failed || 0,
pending: response.pending || 0,
canceled: response.canceled || 0
};

$.each(jobs, function (key, job) {
job.syncTime();
});
$(element).html(template({
jobs: jobs

// Calculate pagination data
const totalJobs = jobs.length;
const totalPages = Math.ceil(totalJobs / that.options.pageSize);
const startIndex = (that.options.currentPage - 1) * that.options.pageSize;
const endIndex = Math.min(startIndex + that.options.pageSize, totalJobs);

// Slice the jobs array for current page
const paginatedJobs = jobs.slice(startIndex, endIndex);

// Generate array of page numbers
const pages = [];
for (let i = 1; i <= totalPages; i++) {
pages.push(i);
}

$(that.element).html(template({
jobs: paginatedJobs,
jobCounts: jobCounts, // Use the counts from the API
pageSize: that.options.pageSize,
currentPage: that.options.currentPage,
searchQuery: that.options.searchQuery,
showControls: that.options.showControls,
showPagination: that.options.showControls && totalJobs > that.options.pageSize,
totalJobs: totalJobs,
startIndex: startIndex + 1,
endIndex: endIndex,
pages: pages,
canGoPrevious: that.options.currentPage > 1,
canGoNext: that.options.currentPage < totalPages
}));
}, function(response) {
new ErrorPage(element, response);
}, function (response) {
new ErrorPage(that.element, response);
});
},

'.page-size-select change': function (el, ev) {
const newPageSize = parseInt($(el).val(), 10);
if (newPageSize !== this.options.pageSize) {
localStorage.setItem(`${this.options.state}_pageSize`, newPageSize);

this.options.pageSize = newPageSize;
this.options.currentPage = 1; // Reset to first page
this.loadJobs();
}
},

'.previous-page click': function (el, ev) {
if (this.options.currentPage > 1) {
this.options.currentPage--;
this.loadJobs();
}
},

'.next-page click': function (el, ev) {
this.options.currentPage++;
this.loadJobs();
},

'.page-number click': function (el, ev) {
this.options.currentPage = parseInt($(el).data('page'), 10);
this.loadJobs();
},

'.search-input keyup': function (el, ev) {
const searchQuery = $(el).val().toLowerCase();
const rows = $('tbody tr');

rows.each(function () {
const jobId = $(this).find('td:nth-child(3) a').text().toLowerCase();
const application = $(this).find('td:nth-child(3) small').text().toLowerCase();

if (jobId.includes(searchQuery) || application.includes(searchQuery)) {
$(this).show();
} else {
$(this).hide();
}
});
},

'.delete-btn click': function(el, ev) {
'.delete-btn click': function (el, ev) {
var tr = $(el).closest('tr');
var job = domData.get.call(tr[0], 'job');

bootbox.confirm("Are you sure you want to delete <b>" + job.attr('id') + "</b>?", function(result) {
bootbox.confirm("Are you sure you want to delete <b>" + job.attr('id') + "</b>?", function (result) {
if (result) {

var okButton = $("button[data-bb-handler='confirm']");
Expand All @@ -43,11 +147,11 @@ export default Control.extend({
var cancelButton = $("button[data-bb-handler='cancel']");
cancelButton.hide('hide');

job.destroy(function() {
job.destroy(function () {
// go to jobs page
bootbox.hideAll();
window.location.hash = "!pages/jobs";
}, function(response) {
}, function (response) {
bootbox.hideAll();
showErrorDialog("Job could not be deleted", response);
});
Expand All @@ -59,12 +163,12 @@ export default Control.extend({

},

'.cancel-btn click': function(el, ev) {
'.cancel-btn click': function (el, ev) {

var tr = $(el).closest('tr');
var job = domData.get.call(tr[0], 'job');

bootbox.confirm("Are you sure you want to cancel <b>" + job.attr('id') + "</b>?", function(result) {
bootbox.confirm("Are you sure you want to cancel <b>" + job.attr('id') + "</b>?", function (result) {
if (result) {

var okButton = $("button[data-bb-handler='confirm']");
Expand All @@ -76,9 +180,9 @@ export default Control.extend({
var operation = new JobOperation();
operation.attr('id', job.attr('id'));
operation.attr('action', 'cancel');
operation.save(function() {
operation.save(function () {
bootbox.hideAll();
}, function(response) {
}, function (response) {
bootbox.hideAll();
showErrorDialog("Job could not be canceld", response);
});
Expand All @@ -89,95 +193,95 @@ export default Control.extend({

},

'.priority-btn click': function(el, ev) {
'.priority-btn click': function (el, ev) {

var tr = $(el).closest('tr');
var job = domData.get.call(tr[0], 'job');
var that = this;
$.get('api/v2/admin/jobs/' + job.attr('id') + '/priority').then(
function(data) {
function (data) {
bootbox.alert(data);
that.init(that.element, that.options);
},
function(response) {
function (response) {
showErrorDialog("Operation failed", response);
});
},

'.archive-btn click': function(el, ev) {
'.archive-btn click': function (el, ev) {
var tr = $(el).closest('tr');
var job = domData.get.call(tr[0], 'job');
var that = this;

bootbox.confirm("Are you sure you want to archive <b>" + job.attr('id') + "</b> now? <b>All results will be deleted!</b>", function(result) {
bootbox.confirm("Are you sure you want to archive <b>" + job.attr('id') + "</b> now? <b>All results will be deleted!</b>", function (result) {
if (result) {
$.get('api/v2/admin/jobs/' + job.attr('id') + '/archive').then(
function(data) {
function (data) {
bootbox.alert(data);
that.init(that.element, that.options);
},
function(response) {
function (response) {
showErrorDialog("Operation failed", response);
});
}
});
},

'.reset-downloads-btn click': function(el, ev) {
'.reset-downloads-btn click': function (el, ev) {
var tr = $(el).closest('tr');
var job = domData.get.call(tr[0], 'job');
$.get('api/v2/admin/jobs/' + job.attr('id') + '/reset').then(
function(data) {
function (data) {
bootbox.alert(data);
},
function(response) {
function (response) {
showErrorDialog("Operation failed", response);
});
},

'.unlimited-downloads-btn click': function(el, ev) {
'.unlimited-downloads-btn click': function (el, ev) {
var tr = $(el).closest('tr');
var job = domData.get.call(tr[0], 'job');
$.get('api/v2/admin/jobs/' + job.attr('id') + '/reset?max=-1').then(
function(data) {
function (data) {
bootbox.alert(data);
},
function(response) {
function (response) {
showErrorDialog("Operation failed", response);
});
},


'.retire-btn click': function(el, ev) {
'.retire-btn click': function (el, ev) {
var tr = $(el).closest('tr');
var job = domData.get.call(tr[0], 'job');
var that = this;
$.get('api/v2/admin/jobs/' + job.attr('id') + '/retire').then(
function(data) {
function (data) {
bootbox.alert(data);
that.init(that.element, that.options);
},
function(response) {
function (response) {
showErrorDialog("Operation failed", response);
});
},

'.change-retire-date-btn click': function(el, ev) {
'.change-retire-date-btn click': function (el, ev) {
var tr = $(el).closest('tr');
var job = domData.get.call(tr[0], 'job');
var that = this;

bootbox.confirm(
'<h4>Retire Date</h4><p>Please enter the number of days:</p><form><input class="form-control" id="message" name="message" value="1">',
function(result) {
function (result) {
if (result) {
var days = $('#message').val();
$.get('api/v2/admin/jobs/' + job.attr('id') + '/change-retire/' + days).then(
function(data) {
function (data) {
bootbox.alert(data);
that.init(that.element, that.options);
},
function(response) {
function (response) {
showErrorDialog("Operation failed", response);
});
}
Expand Down
Loading

0 comments on commit a69a608

Please sign in to comment.