mirror of
https://github.com/hrfee/jfa-go.git
synced 2026-01-18 16:47:42 +01:00
settings: add "tasks" button (advanced)
added a GET /tasks route to list tasks with a description (untranslated, but this is mostly a dev feature anyway). Loaded in a modal by enabling advanced settings and pressing the Tasks button at the top (where logs, backups, restart are). Also added some icons in settings, and removed some redundant "flex flex-row"s on buttons and reduced the spacing in those with icons to gap-1.
This commit is contained in:
@@ -69,11 +69,18 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="modal-logs" class="modal">
|
<div id="modal-logs" class="modal">
|
||||||
<div class="relative mx-auto my-[10%] w-4/5 lg:w-2/3 content content card">
|
<div class="relative mx-auto my-[10%] w-4/5 lg:w-2/3 content card">
|
||||||
<span class="heading">{{ .strings.logs }}<span class="modal-close">×</span></span>
|
<span class="heading">{{ .strings.logs }}<span class="modal-close">×</span></span>
|
||||||
<pre class="monospace" id="log-area"></pre>
|
<pre class="monospace" id="log-area"></pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="modal-tasks" class="modal">
|
||||||
|
<div class="relative mx-auto my-[10%] w-min card flex flex-col gap-2">
|
||||||
|
<h1 class="heading">{{ .strings.tasks }}<span class="modal-close">×</span></h1>
|
||||||
|
<p class="content">{{ .strings.tasksDescription }}</p>
|
||||||
|
<div id="modal-tasks-list" class="flex flex-col gap-2"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div id="modal-modify-user" class="modal">
|
<div id="modal-modify-user" class="modal">
|
||||||
<form class="card relative mx-auto my-[10%] w-11/12 sm:w-4/5 lg:w-1/3" id="form-modify-user" href="">
|
<form class="card relative mx-auto my-[10%] w-11/12 sm:w-4/5 lg:w-1/3" id="form-modify-user" href="">
|
||||||
<span class="heading"><span id="header-modify-user"></span> <span class="modal-close">×</span></span>
|
<span class="heading"><span id="header-modify-user"></span> <span class="modal-close">×</span></span>
|
||||||
@@ -737,7 +744,7 @@
|
|||||||
<input type="search" class="field ~neutral @low input search mr-2" id="accounts-search" placeholder="{{ .strings.search }}">
|
<input type="search" class="field ~neutral @low input search mr-2" id="accounts-search" placeholder="{{ .strings.search }}">
|
||||||
<span class="button ~neutral @low center inside-input rounded-s-none accounts-search-clear" aria-label="{{ .strings.clearSearch }}" text="{{ .strings.clearSearch }}"><i class="ri-close-line"></i></span>
|
<span class="button ~neutral @low center inside-input rounded-s-none accounts-search-clear" aria-label="{{ .strings.clearSearch }}" text="{{ .strings.clearSearch }}"><i class="ri-close-line"></i></span>
|
||||||
<div class="tooltip left">
|
<div class="tooltip left">
|
||||||
<button class="button ~info @low center h-full accounts-search-server flex flex-row gap-1" aria-label="{{ .strings.searchAllRecords }}" text="{{ .strings.searchAllRecords }}">
|
<button class="button ~info @low center h-full accounts-search-server gap-1" aria-label="{{ .strings.searchAllRecords }}" text="{{ .strings.searchAllRecords }}">
|
||||||
<i class="ri-search-line"></i>
|
<i class="ri-search-line"></i>
|
||||||
<span>{{ .strings.searchAll }}</span>
|
<span>{{ .strings.searchAll }}</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -831,8 +838,9 @@
|
|||||||
<span class="text-2xl font-medium italic text-center">{{ .strings.noResultsFound }}</span>
|
<span class="text-2xl font-medium italic text-center">{{ .strings.noResultsFound }}</span>
|
||||||
<span class="text-sm font-light italic unfocused text-center" id="accounts-no-local-results">{{ .strings.noResultsFoundLocally }}</span>
|
<span class="text-sm font-light italic unfocused text-center" id="accounts-no-local-results">{{ .strings.noResultsFoundLocally }}</span>
|
||||||
<div class="flex flex-row">
|
<div class="flex flex-row">
|
||||||
<button class="button ~neutral @low accounts-search-clear flex flex-row gap-2">
|
<button class="button ~neutral @low accounts-search-clear gap-1">
|
||||||
<span>{{ .strings.clearSearch }}</span><i class="ri-close-line"></i>
|
<i class="ri-close-line"></i>
|
||||||
|
<span>{{ .strings.clearSearch }}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -840,7 +848,7 @@
|
|||||||
<div class="flex flex-row gap-2 justify-center">
|
<div class="flex flex-row gap-2 justify-center">
|
||||||
<button class="button ~neutral @low" id="accounts-load-more">{{ .strings.loadMore }}</button>
|
<button class="button ~neutral @low" id="accounts-load-more">{{ .strings.loadMore }}</button>
|
||||||
<button class="button ~neutral @low accounts-load-all">{{ .strings.loadAll }}</button>
|
<button class="button ~neutral @low accounts-load-all">{{ .strings.loadAll }}</button>
|
||||||
<button class="button ~info @low center accounts-search-server flex flex-row gap-1" aria-label="{{ .strings.searchAllRecords }}" text="{{ .strings.searchAllRecords }}">
|
<button class="button ~info @low center accounts-search-server gap-1" aria-label="{{ .strings.searchAllRecords }}" text="{{ .strings.searchAllRecords }}">
|
||||||
<i class="ri-search-line"></i>
|
<i class="ri-search-line"></i>
|
||||||
<span>{{ .strings.searchAllRecords }}</span>
|
<span>{{ .strings.searchAllRecords }}</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -863,7 +871,7 @@
|
|||||||
<input type="search" class="field ~neutral @low input search mr-2" id="activity-search" placeholder="{{ .strings.search }}">
|
<input type="search" class="field ~neutral @low input search mr-2" id="activity-search" placeholder="{{ .strings.search }}">
|
||||||
<span class="button ~neutral @low center inside-input rounded-s-none activity-search-clear" aria-label="{{ .strings.clearSearch }}" text="{{ .strings.clearSearch }}"><i class="ri-close-line"></i></span>
|
<span class="button ~neutral @low center inside-input rounded-s-none activity-search-clear" aria-label="{{ .strings.clearSearch }}" text="{{ .strings.clearSearch }}"><i class="ri-close-line"></i></span>
|
||||||
<div class="tooltip left">
|
<div class="tooltip left">
|
||||||
<button class="button ~info @low center h-full activity-search-server flex flex-row gap-1" aria-label="{{ .strings.searchAllRecords }}" text="{{ .strings.searchAllRecords }}">
|
<button class="button ~info @low center h-full activity-search-server gap-1" aria-label="{{ .strings.searchAllRecords }}" text="{{ .strings.searchAllRecords }}">
|
||||||
<i class="ri-search-line"></i>
|
<i class="ri-search-line"></i>
|
||||||
<span>{{ .strings.searchAll }}</span>
|
<span>{{ .strings.searchAll }}</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -890,8 +898,9 @@
|
|||||||
<span class="text-2xl font-medium italic text-center">{{ .strings.noResultsFound }}</span>
|
<span class="text-2xl font-medium italic text-center">{{ .strings.noResultsFound }}</span>
|
||||||
<span class="text-sm font-light italic unfocused text-center" id="activity-no-local-results">{{ .strings.noResultsFoundLocally }}</span>
|
<span class="text-sm font-light italic unfocused text-center" id="activity-no-local-results">{{ .strings.noResultsFoundLocally }}</span>
|
||||||
<div class="flex flex-row">
|
<div class="flex flex-row">
|
||||||
<button class="button ~neutral @low activity-search-clear flex flex-row gap-2">
|
<button class="button ~neutral @low activity-search-clear gap-1">
|
||||||
<span>{{ .strings.clearSearch }}</span><i class="ri-close-line"></i>
|
<i class="ri-close-line"></i>
|
||||||
|
<span>{{ .strings.clearSearch }}</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="button ~neutral @low unfocused" id="activity-keep-searching">{{ .strings.keepSearching }}</button>
|
<button class="button ~neutral @low unfocused" id="activity-keep-searching">{{ .strings.keepSearching }}</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -902,7 +911,7 @@
|
|||||||
<div class="flex flex-row gap-2 justify-center">
|
<div class="flex flex-row gap-2 justify-center">
|
||||||
<button class="button ~neutral @low" id="activity-load-more">{{ .strings.loadMore }}</button>
|
<button class="button ~neutral @low" id="activity-load-more">{{ .strings.loadMore }}</button>
|
||||||
<button class="button ~neutral @low activity-load-all">{{ .strings.loadAll }}</button>
|
<button class="button ~neutral @low activity-load-all">{{ .strings.loadAll }}</button>
|
||||||
<button class="button ~info @low center activity-search-server flex flex-row gap-1" aria-label="{{ .strings.searchAllRecords }}" text="{{ .strings.searchAllRecords }}">
|
<button class="button ~info @low center activity-search-server gap-1" aria-label="{{ .strings.searchAllRecords }}" text="{{ .strings.searchAllRecords }}">
|
||||||
<i class="ri-search-line"></i>
|
<i class="ri-search-line"></i>
|
||||||
<span>{{ .strings.searchAllRecords }}</span>
|
<span>{{ .strings.searchAllRecords }}</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -920,10 +929,11 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-row justify-start md:justify-end gap-2 w-full">
|
<div class="flex flex-row justify-start md:justify-end gap-2 w-full">
|
||||||
|
<span class="button ~neutral @low gap-1 unfocused" id="settings-tasks"><i class="ri-calendar-schedule-line"></i>{{ .strings.tasks }}</span>
|
||||||
<span class="button ~neutral @low" id="settings-logs">{{ .strings.logs }}</span>
|
<span class="button ~neutral @low" id="settings-logs">{{ .strings.logs }}</span>
|
||||||
<span class="button ~info @low" id="settings-backups">{{ .strings.backups }}</span>
|
<span class="button ~info @low gap-1" id="settings-backups"><i class="icon ri-file-copy-line"></i>{{ .strings.backups }}</span>
|
||||||
<span class="button ~neutral @low" id="settings-restart">{{ .strings.settingsRestart }}</span>
|
<span class="button ~neutral @low gap-1" id="settings-restart"><i class="icon ri-restart-line"></i>{{ .strings.settingsRestart }}</span>
|
||||||
<span class="button ~urge @low unfocused" id="settings-save">{{ .strings.settingsSave }}</span>
|
<span class="button ~urge @low unfocused gap-1" id="settings-save"><i class="icon ri-save-line"></i>{{ .strings.settingsSave }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col md:flex-row gap-3">
|
<div class="flex flex-col md:flex-row gap-3">
|
||||||
|
|||||||
@@ -46,6 +46,8 @@
|
|||||||
"userLabel": "User Label",
|
"userLabel": "User Label",
|
||||||
"userLabelDescription": "Label to apply to users created with this invite.",
|
"userLabelDescription": "Label to apply to users created with this invite.",
|
||||||
"logs": "Logs",
|
"logs": "Logs",
|
||||||
|
"tasks": "Tasks",
|
||||||
|
"tasksDescription": "Tasks are large actions that may be run periodically in the background. You can manually trigger them here if you wish.",
|
||||||
"announce": "Announce",
|
"announce": "Announce",
|
||||||
"templates": "Templates",
|
"templates": "Templates",
|
||||||
"subject": "Subject",
|
"subject": "Subject",
|
||||||
@@ -58,6 +60,7 @@
|
|||||||
"unlink": "Unlink Account",
|
"unlink": "Unlink Account",
|
||||||
"deleted": "Deleted",
|
"deleted": "Deleted",
|
||||||
"disabled": "Disabled",
|
"disabled": "Disabled",
|
||||||
|
"run": "Run",
|
||||||
"sendPWR": "Send Password Reset",
|
"sendPWR": "Send Password Reset",
|
||||||
"noResultsFound": "No Results Found",
|
"noResultsFound": "No Results Found",
|
||||||
"noResultsFoundLocally": "Only loaded records were searched. You can load more, or perform the search over all records on the server.",
|
"noResultsFoundLocally": "Only loaded records were searched. You can load more, or perform the search over all records on the server.",
|
||||||
@@ -264,7 +267,8 @@
|
|||||||
"errorInvalidDate": "Date is invalid.",
|
"errorInvalidDate": "Date is invalid.",
|
||||||
"errorInvalidJSON": "Invalid JSON.",
|
"errorInvalidJSON": "Invalid JSON.",
|
||||||
"updateAvailable": "A new update is available, check settings.",
|
"updateAvailable": "A new update is available, check settings.",
|
||||||
"noUpdatesAvailable": "No new updates available."
|
"noUpdatesAvailable": "No new updates available.",
|
||||||
|
"runTask": "Triggered task."
|
||||||
},
|
},
|
||||||
"quantityStrings": {
|
"quantityStrings": {
|
||||||
"modifySettingsFor": {
|
"modifySettingsFor": {
|
||||||
|
|||||||
10
models.go
10
models.go
@@ -492,3 +492,13 @@ type PagePathsDTO struct {
|
|||||||
// The subdirectory the app is meant to be accessed from ("Reverse proxy subfolder")
|
// The subdirectory the app is meant to be accessed from ("Reverse proxy subfolder")
|
||||||
TrueBase string `json:"TrueBase"`
|
TrueBase string `json:"TrueBase"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TasksDTO struct {
|
||||||
|
Tasks []TaskDTO `json:"tasks"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TaskDTO struct {
|
||||||
|
URL string `json:"url"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description string ` json:"description"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -244,6 +244,7 @@ func (app *appContext) loadRoutes(router *gin.Engine) {
|
|||||||
api.POST(p+"/config", app.ModifyConfig)
|
api.POST(p+"/config", app.ModifyConfig)
|
||||||
api.POST(p+"/restart", app.restart)
|
api.POST(p+"/restart", app.restart)
|
||||||
api.GET(p+"/logs", app.GetLog)
|
api.GET(p+"/logs", app.GetLog)
|
||||||
|
api.GET(p+"/tasks", app.TaskList)
|
||||||
api.POST(p+"/tasks/housekeeping", app.TaskHousekeeping)
|
api.POST(p+"/tasks/housekeeping", app.TaskHousekeeping)
|
||||||
api.POST(p+"/tasks/users", app.TaskUserCleanup)
|
api.POST(p+"/tasks/users", app.TaskUserCleanup)
|
||||||
if app.config.Section("jellyseerr").Key("enabled").MustBool(false) {
|
if app.config.Section("jellyseerr").Key("enabled").MustBool(false) {
|
||||||
|
|||||||
29
tasks.go
29
tasks.go
@@ -7,6 +7,35 @@ import (
|
|||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// @Summary List existing task routes, with friendly names and descriptions.
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {object} TasksDTO
|
||||||
|
// @Router /tasks [get]
|
||||||
|
// @Security Bearer
|
||||||
|
// @tags Tasks
|
||||||
|
func (app *appContext) TaskList(gc *gin.Context) {
|
||||||
|
resp := TasksDTO{Tasks: []TaskDTO{
|
||||||
|
TaskDTO{
|
||||||
|
URL: "/tasks/housekeeping",
|
||||||
|
Name: "Housekeeping",
|
||||||
|
Description: "General housekeeping tasks: Clearing expired invites & activities, unused contact details & captchas, etc.",
|
||||||
|
},
|
||||||
|
TaskDTO{
|
||||||
|
URL: "/tasks/users",
|
||||||
|
Name: "Users",
|
||||||
|
Description: "Checks for (pending) account expiries and performs the appropriate actions.",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
if app.config.Section("jellyseerr").Key("enabled").MustBool(false) {
|
||||||
|
resp.Tasks = append(resp.Tasks, TaskDTO{
|
||||||
|
URL: "/tasks/jellyseerr",
|
||||||
|
Name: "Jellyseerr user import",
|
||||||
|
Description: "Imports existing users into jellyfin and synchronizes contact details. Should only need to be run once when the feature is enabled, which is done automatically.",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
gc.JSON(200, resp)
|
||||||
|
}
|
||||||
|
|
||||||
// @Summary Triggers general housekeeping tasks: Clearing expired invites, activities, unused contact details, captchas, etc.
|
// @Summary Triggers general housekeeping tasks: Clearing expired invites, activities, unused contact details, captchas, etc.
|
||||||
// @Success 204
|
// @Success 204
|
||||||
// @Router /tasks/housekeeping [post]
|
// @Router /tasks/housekeeping [post]
|
||||||
|
|||||||
@@ -74,6 +74,8 @@ window.availableProfiles = window.availableProfiles || [];
|
|||||||
window.modals.matrix = new Modal(document.getElementById("modal-matrix"));
|
window.modals.matrix = new Modal(document.getElementById("modal-matrix"));
|
||||||
|
|
||||||
window.modals.logs = new Modal(document.getElementById("modal-logs"));
|
window.modals.logs = new Modal(document.getElementById("modal-logs"));
|
||||||
|
|
||||||
|
window.modals.tasks = new Modal(document.getElementById("modal-tasks"));
|
||||||
|
|
||||||
window.modals.backedUp = new Modal(document.getElementById("modal-backed-up"));
|
window.modals.backedUp = new Modal(document.getElementById("modal-backed-up"));
|
||||||
|
|
||||||
|
|||||||
@@ -936,14 +936,17 @@ export class settingsList {
|
|||||||
private _settings: Settings;
|
private _settings: Settings;
|
||||||
private _advanced: boolean = false;
|
private _advanced: boolean = false;
|
||||||
|
|
||||||
private _searchbox: HTMLInputElement = document.getElementById("settings-search") as HTMLInputElement;
|
private _searchbox = document.getElementById("settings-search") as HTMLInputElement;
|
||||||
private _clearSearchboxButtons: Array<HTMLButtonElement> = Array.from(document.getElementsByClassName("settings-search-clear")) as Array<HTMLButtonElement>;
|
private _clearSearchboxButtons = Array.from(document.getElementsByClassName("settings-search-clear")) as Array<HTMLButtonElement>;
|
||||||
|
|
||||||
private _noResultsPanel: HTMLElement = document.getElementById("settings-not-found");
|
private _noResultsPanel: HTMLElement = document.getElementById("settings-not-found");
|
||||||
|
|
||||||
private _backupSortDirection = document.getElementById("settings-backups-sort-direction") as HTMLButtonElement;
|
private _backupSortDirection = document.getElementById("settings-backups-sort-direction") as HTMLButtonElement;
|
||||||
private _backupSortAscending = true;
|
private _backupSortAscending = true;
|
||||||
|
|
||||||
|
private _tasksList: TasksList;
|
||||||
|
private _tasksButton = document.getElementById("settings-tasks") as HTMLButtonElement;
|
||||||
|
|
||||||
// Must be called -after- all section have been added.
|
// Must be called -after- all section have been added.
|
||||||
// Takes all groups at once since members might contain each other.
|
// Takes all groups at once since members might contain each other.
|
||||||
addGroups = (groups: Group[]) => {
|
addGroups = (groups: Group[]) => {
|
||||||
@@ -1160,6 +1163,9 @@ export class settingsList {
|
|||||||
this._backup();
|
this._backup();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this._tasksList = new TasksList();
|
||||||
|
this._tasksButton.onclick = this._tasksList.load;
|
||||||
|
|
||||||
document.addEventListener("settings-show-panel", (event: CustomEvent) => {
|
document.addEventListener("settings-show-panel", (event: CustomEvent) => {
|
||||||
this._showPanel(event.detail as string);
|
this._showPanel(event.detail as string);
|
||||||
});
|
});
|
||||||
@@ -1187,17 +1193,21 @@ export class settingsList {
|
|||||||
|
|
||||||
advancedEnableToggle.onchange = () => {
|
advancedEnableToggle.onchange = () => {
|
||||||
document.dispatchEvent(new CustomEvent("settings-advancedState", { detail: advancedEnableToggle.checked }));
|
document.dispatchEvent(new CustomEvent("settings-advancedState", { detail: advancedEnableToggle.checked }));
|
||||||
|
};
|
||||||
|
document.addEventListener("settings-advancedState", () => {
|
||||||
const parent = advancedEnableToggle.parentElement;
|
const parent = advancedEnableToggle.parentElement;
|
||||||
this._advanced = advancedEnableToggle.checked;
|
this._advanced = advancedEnableToggle.checked;
|
||||||
if (this._advanced) {
|
if (this._advanced) {
|
||||||
parent.classList.add("~urge");
|
parent.classList.add("~urge");
|
||||||
parent.classList.remove("~neutral");
|
parent.classList.remove("~neutral");
|
||||||
|
this._tasksButton.classList.remove("unfocused");
|
||||||
} else {
|
} else {
|
||||||
parent.classList.add("~neutral");
|
parent.classList.add("~neutral");
|
||||||
parent.classList.remove("~urge");
|
parent.classList.remove("~urge");
|
||||||
|
this._tasksButton.classList.add("unfocused");
|
||||||
}
|
}
|
||||||
this._searchbox.oninput(null);
|
this._searchbox.oninput(null);
|
||||||
};
|
});
|
||||||
advancedEnableToggle.checked = false;
|
advancedEnableToggle.checked = false;
|
||||||
|
|
||||||
this._searchbox.oninput = () => {
|
this._searchbox.oninput = () => {
|
||||||
@@ -1746,3 +1756,58 @@ class MessageEditor {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TasksList {
|
||||||
|
private _list: HTMLElement = document.getElementById("modal-tasks-list");
|
||||||
|
|
||||||
|
load = () => _get("/tasks", null, (req: XMLHttpRequest) => {
|
||||||
|
if (req.readyState != 4) return;
|
||||||
|
if (req.status != 200) return;
|
||||||
|
let resp = req.response["tasks"] as TaskDTO[];
|
||||||
|
this._list.textContent = "";
|
||||||
|
for (let t of resp) {
|
||||||
|
const task = new Task(t);
|
||||||
|
this._list.appendChild(task.asElement());
|
||||||
|
}
|
||||||
|
window.modals.tasks.show();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TaskDTO {
|
||||||
|
url: string;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Task {
|
||||||
|
private _el: HTMLElement;
|
||||||
|
asElement = () => { return this._el };
|
||||||
|
constructor(t: TaskDTO) {
|
||||||
|
this._el = document.createElement("div");
|
||||||
|
this._el.classList.add("aside", "flex", "flex-row", "gap-4", "justify-between", "dark:shadow-md")
|
||||||
|
this._el.innerHTML = `
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<div class="flex flex-row gap-2 items-baseline w-max">
|
||||||
|
<h2 class="heading text-2xl">${t.name}</h2>
|
||||||
|
<span class="text-sm font-mono">${t.url}</span>
|
||||||
|
</div>
|
||||||
|
<p class="max-w-[40ch] wrap-break-word text-justify">${t.description}</p>
|
||||||
|
</div>
|
||||||
|
<button class="button ~urge @low p-6">${window.lang.strings("run")}</button>
|
||||||
|
`;
|
||||||
|
const button = this._el.querySelector("button") as HTMLButtonElement;
|
||||||
|
button.onclick = () => {
|
||||||
|
addLoader(button);
|
||||||
|
_post(t.url, null, (req: XMLHttpRequest) => {
|
||||||
|
if (req.readyState != 4) return;
|
||||||
|
removeLoader(button);
|
||||||
|
setTimeout(window.modals.tasks.close, 1000)
|
||||||
|
if (req.status != 204) {
|
||||||
|
window.notifications.customError("errorRunTask", window.lang.notif("errorFailureCheckLogs"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.notifications.customSuccess("runTask", window.lang.notif("runTask"));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -123,6 +123,7 @@ declare interface Modals {
|
|||||||
sendPWR?: Modal;
|
sendPWR?: Modal;
|
||||||
pwr?: Modal;
|
pwr?: Modal;
|
||||||
logs: Modal;
|
logs: Modal;
|
||||||
|
tasks: Modal;
|
||||||
email?: Modal;
|
email?: Modal;
|
||||||
enableReferralsUser?: Modal;
|
enableReferralsUser?: Modal;
|
||||||
enableReferralsProfile?: Modal;
|
enableReferralsProfile?: Modal;
|
||||||
|
|||||||
Reference in New Issue
Block a user