aboutsummaryrefslogtreecommitdiff
path: root/_wui
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2023-12-22 03:05:23 +0700
committerShulhan <ms@kilabit.info>2023-12-22 03:09:46 +0700
commit65c66728904a8a26fa8593cfe6a7d39e45c0ef1f (patch)
tree305795254aac3d52af173783479616c68012491b /_wui
parentaa64efe9e8957da6c122f9decaaa78dca83d14ee (diff)
downloadawwan-65c66728904a8a26fa8593cfe6a7d39e45c0ef1f.tar.xz
_wui: implement button to stop execution
The Stop button call "DELETE /awwan/api/execute?id=" with id is the previous execution ID. Implements: https://todo.sr.ht/~shulhan/awwan/9
Diffstat (limited to '_wui')
-rw-r--r--_wui/awwan.ts38
-rw-r--r--_wui/index.html5
-rw-r--r--_wui/main.js34
3 files changed, 62 insertions, 15 deletions
diff --git a/_wui/awwan.ts b/_wui/awwan.ts
index 95b7f97..942730b 100644
--- a/_wui/awwan.ts
+++ b/_wui/awwan.ts
@@ -27,6 +27,7 @@ const CLASS_AWWAN_EXECUTE = "awwan_execute";
const ID_INP_LINE_RANGE = "com_inp_line_range";
const ID_BTN_EXEC_LOCAL = "com_btn_local";
const ID_BTN_EXEC_REMOTE = "com_btn_remote";
+const ID_BTN_STOP = "com_btn_stop";
const ID_COM_RESIZE_EDITOR = "com_resize_editor";
@@ -98,7 +99,7 @@ export function renderHtml() {
<div id="${ID_OUTPUT_WRAPPER}" class="output">
<div>
<div class="${CLASS_AWWAN_EXECUTE}">
- <span id="exec_icon">&#9898;</span>
+ <button id="${ID_BTN_STOP}" disabled="true">&#9899; Stop</button>
Execute line
<input id="${ID_INP_LINE_RANGE}" placeholder="Ex: 1,2-4,5-"/>
on
@@ -152,6 +153,7 @@ export class Awwan {
private orgContent: string = "";
private _posx: number = 0;
private _posy: number = 0;
+ private execID = "";
constructor() {
renderHtml();
@@ -182,7 +184,7 @@ export class Awwan {
});
}
- el = document.getElementById("exec_icon");
+ el = document.getElementById(ID_BTN_STOP);
if (el) {
this.elExecIcon = el;
}
@@ -535,6 +537,23 @@ export class Awwan {
this.doSaveFile(this.request.script, this.request.content);
}
+ async onClickStop() {
+ const httpRes = await fetch(`/awwan/api/execute?id=${this.execID}`, {
+ method: "DELETE",
+ headers: {
+ Accept: "application/json",
+ },
+ });
+
+ const res = await httpRes.json();
+ if (res.code != 200) {
+ this.notifError(`Stop failed: ${res.message}`);
+ return;
+ }
+
+ this.notifInfo(res.message);
+ }
+
editorOnSave(content: string) {
this.doSaveFile(this.request.script, content);
}
@@ -628,6 +647,8 @@ export class Awwan {
// Stream the execution output using Server-sent events.
+ this.execID = execRes.id;
+
const execTail = new EventSource(
`/awwan/api/execute/tail?id=${execRes.id}`,
);
@@ -663,17 +684,24 @@ export class Awwan {
private preExecute() {
this.comBtnLocal.disabled = true;
this.comBtnPlay.disabled = true;
- this.elExecIcon.innerHTML = "&#128993;";
+ this.elExecIcon.innerHTML = "&#128993; Stop";
}
private whileExecute() {
- this.elExecIcon.innerHTML = "&#128994;";
+ this.elExecIcon.disabled = false;
+ this.elExecIcon.innerHTML = "&#128994; Stop";
+ this.elExecIcon.onclick = () => {
+ this.onClickStop();
+ };
}
private postExecute() {
this.comBtnLocal.disabled = false;
this.comBtnPlay.disabled = false;
- this.elExecIcon.innerHTML = "&#9898;";
+ this.elExecIcon.innerHTML = "&#9899; Stop";
+ this.elExecIcon.disabled = true;
+ this.elExecIcon.onclick = null;
+ this.execID = "";
}
private async newNode(isDir: boolean) {
diff --git a/_wui/index.html b/_wui/index.html
index b2b4a0e..792ef85 100644
--- a/_wui/index.html
+++ b/_wui/index.html
@@ -135,11 +135,6 @@
height: 27em;
}
- #exec_icon {
- font-size: 14pt;
- vertical-align: middle;
- }
-
#output {
background-color: lavender;
border: 1px solid silver;
diff --git a/_wui/main.js b/_wui/main.js
index 41d2933..e6d2a72 100644
--- a/_wui/main.js
+++ b/_wui/main.js
@@ -419,6 +419,7 @@ var awwan = (() => {
var ID_INP_LINE_RANGE = "com_inp_line_range";
var ID_BTN_EXEC_LOCAL = "com_btn_local";
var ID_BTN_EXEC_REMOTE = "com_btn_remote";
+ var ID_BTN_STOP = "com_btn_stop";
var ID_COM_RESIZE_EDITOR = "com_resize_editor";
var ID_OUTPUT_WRAPPER = "output_wrapper";
var ID_OUTPUT = "output";
@@ -455,7 +456,7 @@ var awwan = (() => {
<div id="${ID_OUTPUT_WRAPPER}" class="output">
<div>
<div class="${CLASS_AWWAN_EXECUTE}">
- <span id="exec_icon">&#9898;</span>
+ <button id="${ID_BTN_STOP}" disabled="true">&#9899; Stop</button>
Execute line
<input id="${ID_INP_LINE_RANGE}" placeholder="Ex: 1,2-4,5-"/>
on
@@ -486,6 +487,7 @@ var awwan = (() => {
this.orgContent = "";
this._posx = 0;
this._posy = 0;
+ this.execID = "";
renderHtml();
let el;
el = document.getElementById(ID_AWWAN_NAV_LEFT);
@@ -508,7 +510,7 @@ var awwan = (() => {
this._posx = 0;
});
}
- el = document.getElementById("exec_icon");
+ el = document.getElementById(ID_BTN_STOP);
if (el) {
this.elExecIcon = el;
}
@@ -806,6 +808,20 @@ var awwan = (() => {
this.request.content = content;
this.doSaveFile(this.request.script, this.request.content);
}
+ async onClickStop() {
+ const httpRes = await fetch(`/awwan/api/execute?id=${this.execID}`, {
+ method: "DELETE",
+ headers: {
+ Accept: "application/json"
+ }
+ });
+ const res = await httpRes.json();
+ if (res.code != 200) {
+ this.notifError(`Stop failed: ${res.message}`);
+ return;
+ }
+ this.notifInfo(res.message);
+ }
editorOnSave(content) {
this.doSaveFile(this.request.script, content);
}
@@ -883,6 +899,7 @@ var awwan = (() => {
this.notifInfo(
`Execute submitted ${execRes.script} on ${execRes.mode} with ID=${execRes.id}`
);
+ this.execID = execRes.id;
const execTail = new EventSource(
`/awwan/api/execute/tail?id=${execRes.id}`
);
@@ -916,15 +933,22 @@ var awwan = (() => {
preExecute() {
this.comBtnLocal.disabled = true;
this.comBtnPlay.disabled = true;
- this.elExecIcon.innerHTML = "&#128993;";
+ this.elExecIcon.innerHTML = "&#128993; Stop";
}
whileExecute() {
- this.elExecIcon.innerHTML = "&#128994;";
+ this.elExecIcon.disabled = false;
+ this.elExecIcon.innerHTML = "&#128994; Stop";
+ this.elExecIcon.onclick = () => {
+ this.onClickStop();
+ };
}
postExecute() {
this.comBtnLocal.disabled = false;
this.comBtnPlay.disabled = false;
- this.elExecIcon.innerHTML = "&#9898;";
+ this.elExecIcon.innerHTML = "&#9899; Stop";
+ this.elExecIcon.disabled = true;
+ this.elExecIcon.onclick = null;
+ this.execID = "";
}
async newNode(isDir) {
if (!this.currentNode) {