mirror of
https://github.com/ditatompel/xmr-remote-nodes.git
synced 2025-01-08 05:52:10 +07:00
Make cron datatable filterable
This commit is contained in:
parent
ffaa9b37d3
commit
8821ad7995
5 changed files with 98 additions and 19 deletions
|
@ -10,7 +10,7 @@
|
||||||
DtSrAutoRefresh
|
DtSrAutoRefresh
|
||||||
} from '$lib/components/datatables/server';
|
} from '$lib/components/datatables/server';
|
||||||
|
|
||||||
const handler = new DataHandler([], { rowsPerPage: 1000, totalRows: 0 });
|
const handler = new DataHandler([], { rowsPerPage: 10, totalRows: 0 });
|
||||||
let rows = handler.getRows();
|
let rows = handler.getRows();
|
||||||
|
|
||||||
/** @type {string | number} */
|
/** @type {string | number} */
|
||||||
|
@ -73,8 +73,8 @@
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<option value={-1}>Any</option>
|
<option value={-1}>Any</option>
|
||||||
<option value={1}>Running</option>
|
<option value="1">Running</option>
|
||||||
<option value={0}>Idle</option>
|
<option value="0">Idle</option>
|
||||||
</select>
|
</select>
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
|
@ -89,8 +89,8 @@
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<option value={-1}>Any</option>
|
<option value={-1}>Any</option>
|
||||||
<option value={1}>Yes</option>
|
<option value="1">Yes</option>
|
||||||
<option value={0}>No</option>
|
<option value="0">No</option>
|
||||||
</select>
|
</select>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -1,18 +1,23 @@
|
||||||
import { apiUri } from '$lib/utils/common';
|
import { apiUri } from '$lib/utils/common';
|
||||||
|
import { goto } from '$app/navigation';
|
||||||
|
|
||||||
/** @param {import('@vincjo/datatables/remote/state')} state */
|
/** @param {import('@vincjo/datatables/remote/state')} state */
|
||||||
export const loadData = async (state) => {
|
export const loadData = async (state) => {
|
||||||
const response = await fetch(apiUri(`/api/v1/crons?${getParams(state)}`));
|
const response = await fetch(apiUri(`/api/v1/crons?${getParams(state)}`));
|
||||||
const json = await response.json();
|
const json = await response.json();
|
||||||
|
if (json.data === null) {
|
||||||
|
goto('/login');
|
||||||
|
return;
|
||||||
|
}
|
||||||
state.setTotalRows(json.data.length ?? 0);
|
state.setTotalRows(json.data.length ?? 0);
|
||||||
return json.data ?? [];
|
return json.data.items ?? [];
|
||||||
};
|
};
|
||||||
|
|
||||||
const getParams = ({ pageNumber, rowsPerPage, sort, filters }) => {
|
const getParams = ({ pageNumber, rowsPerPage, sort, filters }) => {
|
||||||
let params = `page=${pageNumber}&limit=${rowsPerPage}`;
|
let params = `page=${pageNumber}&limit=${rowsPerPage}`;
|
||||||
|
|
||||||
if (sort) {
|
if (sort) {
|
||||||
params += `&orderBy=${sort.orderBy}&orderDir=${sort.direction}`;
|
params += `&sort_by=${sort.orderBy}&sort_direction=${sort.direction}`;
|
||||||
}
|
}
|
||||||
if (filters) {
|
if (filters) {
|
||||||
params += filters.map(({ filterBy, value }) => `&${filterBy}=${value}`).join('');
|
params += filters.map(({ filterBy, value }) => `&${filterBy}=${value}`).join('');
|
||||||
|
|
|
@ -355,8 +355,18 @@ func ProcessJob(c *fiber.Ctx) error {
|
||||||
|
|
||||||
func Crons(c *fiber.Ctx) error {
|
func Crons(c *fiber.Ctx) error {
|
||||||
cronRepo := repo.NewCron(database.GetDB())
|
cronRepo := repo.NewCron(database.GetDB())
|
||||||
|
query := repo.CronQueryParams{
|
||||||
|
RowsPerPage: c.QueryInt("limit", 10),
|
||||||
|
Page: c.QueryInt("page", 1),
|
||||||
|
SortBy: c.Query("sort_by", "id"),
|
||||||
|
SortDirection: c.Query("sort_direction", "desc"),
|
||||||
|
Title: c.Query("title"),
|
||||||
|
Description: c.Query("description"),
|
||||||
|
IsEnabled: c.QueryInt("is_enabled", -1),
|
||||||
|
CronState: c.QueryInt("cron_state", -1),
|
||||||
|
}
|
||||||
|
|
||||||
crons, err := cronRepo.Crons()
|
crons, err := cronRepo.Crons(query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||||
"status": "error",
|
"status": "error",
|
||||||
|
@ -367,7 +377,7 @@ func Crons(c *fiber.Ctx) error {
|
||||||
|
|
||||||
return c.JSON(fiber.Map{
|
return c.JSON(fiber.Map{
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
"message": "Crons",
|
"message": "Success",
|
||||||
"data": crons,
|
"data": crons,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ func V1Api(app *fiber.App) {
|
||||||
v1.Post("/prober", CookieProtected, Prober)
|
v1.Post("/prober", CookieProtected, Prober)
|
||||||
v1.Patch("/prober/:id", CookieProtected, Prober)
|
v1.Patch("/prober/:id", CookieProtected, Prober)
|
||||||
v1.Delete("/prober/:id", CookieProtected, Prober)
|
v1.Delete("/prober/:id", CookieProtected, Prober)
|
||||||
|
v1.Get("/crons", CookieProtected, Crons)
|
||||||
v1.Get("/nodes", MoneroNodes)
|
v1.Get("/nodes", MoneroNodes)
|
||||||
v1.Post("/nodes", AddNode)
|
v1.Post("/nodes", AddNode)
|
||||||
v1.Get("/nodes/id/:id", MoneroNode)
|
v1.Get("/nodes/id/:id", MoneroNode)
|
||||||
|
@ -24,5 +25,4 @@ func V1Api(app *fiber.App) {
|
||||||
v1.Get("/countries", Countries)
|
v1.Get("/countries", Countries)
|
||||||
v1.Get("/job", CheckProber, GiveJob)
|
v1.Get("/job", CheckProber, GiveJob)
|
||||||
v1.Post("/job", CheckProber, ProcessJob)
|
v1.Post("/job", CheckProber, ProcessJob)
|
||||||
v1.Get("/crons", Crons)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ package repo
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
"slices"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ditatompel/xmr-nodes/internal/database"
|
"github.com/ditatompel/xmr-nodes/internal/database"
|
||||||
|
@ -10,14 +12,14 @@ import (
|
||||||
|
|
||||||
type CronRepository interface {
|
type CronRepository interface {
|
||||||
RunCronProcess()
|
RunCronProcess()
|
||||||
Crons() ([]CronTask, error)
|
Crons(q CronQueryParams) (CronTasks, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type CronRepo struct {
|
type CronRepo struct {
|
||||||
db *database.DB
|
db *database.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
type CronTask struct {
|
type Cron struct {
|
||||||
Id int `json:"id" db:"id"`
|
Id int `json:"id" db:"id"`
|
||||||
Title string `json:"title" db:"title"`
|
Title string `json:"title" db:"title"`
|
||||||
Slug string `json:"slug" db:"slug"`
|
Slug string `json:"slug" db:"slug"`
|
||||||
|
@ -68,15 +70,77 @@ func (repo *CronRepo) RunCronProcess() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *CronRepo) Crons() ([]CronTask, error) {
|
type CronQueryParams struct {
|
||||||
tasks := []CronTask{}
|
Title string
|
||||||
query := `SELECT * FROM tbl_cron`
|
Description string
|
||||||
err := repo.db.Select(&tasks, query)
|
IsEnabled int
|
||||||
return tasks, err
|
CronState int
|
||||||
|
RowsPerPage int
|
||||||
|
Page int
|
||||||
|
SortBy string
|
||||||
|
SortDirection string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *CronRepo) queueList() ([]CronTask, error) {
|
type CronTasks struct {
|
||||||
tasks := []CronTask{}
|
TotalRows int `json:"total_rows"`
|
||||||
|
RowsPerPage int `json:"rows_per_page"`
|
||||||
|
Items []*Cron `json:"items"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repo *CronRepo) Crons(q CronQueryParams) (CronTasks, error) {
|
||||||
|
queryParams := []interface{}{}
|
||||||
|
whereQueries := []string{}
|
||||||
|
where := ""
|
||||||
|
|
||||||
|
if q.Title != "" {
|
||||||
|
whereQueries = append(whereQueries, "title LIKE ?")
|
||||||
|
queryParams = append(queryParams, "%"+q.Title+"%")
|
||||||
|
}
|
||||||
|
if q.Description != "" {
|
||||||
|
whereQueries = append(whereQueries, "description LIKE ?")
|
||||||
|
queryParams = append(queryParams, "%"+q.Description+"%")
|
||||||
|
}
|
||||||
|
if q.IsEnabled != -1 {
|
||||||
|
whereQueries = append(whereQueries, "is_enabled = ?")
|
||||||
|
queryParams = append(queryParams, q.IsEnabled)
|
||||||
|
}
|
||||||
|
if q.CronState != -1 {
|
||||||
|
whereQueries = append(whereQueries, "cron_state = ?")
|
||||||
|
queryParams = append(queryParams, q.CronState)
|
||||||
|
}
|
||||||
|
if len(whereQueries) > 0 {
|
||||||
|
where = "WHERE " + strings.Join(whereQueries, " AND ")
|
||||||
|
}
|
||||||
|
tasks := CronTasks{}
|
||||||
|
|
||||||
|
queryTotalRows := fmt.Sprintf("SELECT COUNT(id) FROM tbl_cron %s", where)
|
||||||
|
err := repo.db.QueryRow(queryTotalRows, queryParams...).Scan(&tasks.TotalRows)
|
||||||
|
if err != nil {
|
||||||
|
return tasks, err
|
||||||
|
}
|
||||||
|
queryParams = append(queryParams, q.RowsPerPage, (q.Page-1)*q.RowsPerPage)
|
||||||
|
allowedSort := []string{"id", "run_every", "last_run", "next_run", "run_time"}
|
||||||
|
sortBy := "id"
|
||||||
|
if slices.Contains(allowedSort, q.SortBy) {
|
||||||
|
sortBy = q.SortBy
|
||||||
|
}
|
||||||
|
sortDirection := "DESC"
|
||||||
|
if q.SortDirection == "asc" {
|
||||||
|
sortDirection = "ASC"
|
||||||
|
}
|
||||||
|
|
||||||
|
query := fmt.Sprintf("SELECT id, title, slug, description, run_every, last_run, next_run, run_time, cron_state, is_enabled FROM tbl_cron %s ORDER BY %s %s LIMIT ? OFFSET ?", where, sortBy, sortDirection)
|
||||||
|
err = repo.db.Select(&tasks.Items, query, queryParams...)
|
||||||
|
if err != nil {
|
||||||
|
return tasks, err
|
||||||
|
}
|
||||||
|
tasks.RowsPerPage = q.RowsPerPage
|
||||||
|
|
||||||
|
return tasks, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repo *CronRepo) queueList() ([]Cron, error) {
|
||||||
|
tasks := []Cron{}
|
||||||
query := `SELECT id, run_every, last_run, slug, next_run, cron_state FROM tbl_cron
|
query := `SELECT id, run_every, last_run, slug, next_run, cron_state FROM tbl_cron
|
||||||
WHERE is_enabled = ? AND next_run <= ?`
|
WHERE is_enabled = ? AND next_run <= ?`
|
||||||
err := repo.db.Select(&tasks, query, 1, time.Now().Unix())
|
err := repo.db.Select(&tasks, query, 1, time.Now().Unix())
|
||||||
|
|
Loading…
Reference in a new issue