aboutsummaryrefslogtreecommitdiff
path: root/src/database-prod.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/database-prod.ts')
-rw-r--r--src/database-prod.ts86
1 files changed, 76 insertions, 10 deletions
diff --git a/src/database-prod.ts b/src/database-prod.ts
index 57b9974..d41e829 100644
--- a/src/database-prod.ts
+++ b/src/database-prod.ts
@@ -1,9 +1,13 @@
-import { getCourseId } from "./utils-ENV.js";
+import { assert } from "./assert.ts";
+import { getCourseId, getSesskey } from "./utils-ENV.js";
const DB_TEMPLATE_LIST_HEADER = `
<table class="table table-striped">
<thead>
<tr>
+ <th>ChangeId</th>
+ <th>Date</th>
+ <th>Coach</th>
<th>Json</th>
</tr>
</thead>
@@ -11,6 +15,7 @@ const DB_TEMPLATE_LIST_HEADER = `
`;
const DB_TEMPLATE_LIST_ENTRY = `
<tr class="db-row">
+ <td class="db-cell" data-key="changeId">##id##</td>
<td class="db-cell" data-key="date">##timeadded##</td>
<td class="db-cell" data-key="coach">##user##</td>
<td class="db-cell" data-key="json">[[Json]]</td>
@@ -45,7 +50,7 @@ async function findGraduationDb() {
return new DB(Number(dbId));
}
}
- console.assert(false, "Graduation DB not found");
+ assert(false, "Graduation DB not found");
}
interface DatabaseParams {
@@ -58,22 +63,56 @@ interface DatabaseEntry {
class DB {
id: number;
+ d: Promise<number> | null = null;
- constructor(id: number) {
+ constructor(id: number, d?: number) {
this.id = id;
+ if (typeof d !== "undefined") {
+ this.d = new Promise((resolve) => {
+ resolve(d);
+ });
+ }
}
async fetchEntries(params?: DatabaseParams) {
- return loadFromDatabaseActivity(this.id, params);
+ return loadFromDatabaseActivity(this, params);
}
async saveEntry(json: string) {
- return addEntryToDatabaseActivity(this.id, json);
+ return addEntryToDatabaseActivity(this, json);
+ }
+
+ async deleteEntries(entryIds: [number]) {
+ return deleteFromDatabaseActivity(await this.getD(), entryIds);
+ }
+
+ async getD() {
+ if (this.d === null) this.d = fetchDFromDatabaseActivity(this);
+ return this.d;
}
}
-async function loadFromDatabaseActivity(id: string | number, params?: DatabaseParams) {
- let dbUrl = `${window.location.origin}/mod/data/view.php?id=${id}&mode=list&perpage=1000`;
+const dRegex = /d=(\d+)/;
+function getDFromDbDoc(db: DB, dbDoc: Document) {
+ const urlWithD = dbDoc.querySelector<HTMLInputElement>('input[name="pageurl"]')!.value;
+ const match = dRegex.exec(urlWithD);
+ if (match === null) {
+ console.error(`d of database ${db.id} not found`);
+ return -1;
+ }
+ return Number(match[1]);
+}
+
+async function fetchDFromDatabaseActivity(db: DB): Promise<number> {
+ let dbUrl = `${window.location.origin}/mod/data/view.php?id=${db.id}`;
+ const dbRes = await fetch(encodeURI(dbUrl));
+ const dbDoc = new DOMParser().parseFromString(await dbRes.text(), "text/html");
+
+ return getDFromDbDoc(db, dbDoc);
+}
+
+async function loadFromDatabaseActivity(db: DB, params?: DatabaseParams) {
+ let dbUrl = `${window.location.origin}/mod/data/view.php?id=${db.id}&mode=list&perpage=1000`;
// TODO(muhq): Why does this not include entries?
if (typeof params !== "undefined") {
dbUrl += "&filter=1&advanced=1";
@@ -84,6 +123,13 @@ async function loadFromDatabaseActivity(id: string | number, params?: DatabasePa
const dbRes = await fetch(encodeURI(dbUrl));
const dbDoc = new DOMParser().parseFromString(await dbRes.text(), "text/html");
+
+ if (db.d === null) {
+ db.d = new Promise((resolve) => {
+ resolve(getDFromDbDoc(db, dbDoc));
+ });
+ }
+
let data: any[] = [];
dbDoc.querySelectorAll(".db-row").forEach((row) => {
let entry: DatabaseEntry = {};
@@ -107,9 +153,9 @@ async function getGraduationDb() {
return (await graduationDb)!;
}
-async function addEntryToDatabaseActivity(id: number, json: string) {
+async function addEntryToDatabaseActivity(db: DB, json: string) {
// TODO(muhq): do not fetch the form
- const url = `/mod/data/edit.php?id=${id}`;
+ const url = `/mod/data/edit.php?id=${db.id}`;
const editRes = await fetch(url);
const editDoc = new DOMParser().parseFromString(await editRes.text(), "text/html");
const form = editDoc.querySelector<HTMLFormElement>('div[role="main"] > form');
@@ -127,9 +173,29 @@ async function addEntryToDatabaseActivity(id: number, json: string) {
return await fetch("/mod/data/edit.php", {
method: "POST",
- // Set the FormData instance as the request body
body: formData,
});
}
+async function deleteFromDatabaseActivity(d: number, entryIds: [number]) {
+ const promises = [];
+ assert(d != -1, "DB has no valid d yet.");
+ for (const entryId of entryIds) {
+ const formData = new FormData();
+
+ formData.set("d", String(d));
+ formData.set("sesskey", getSesskey());
+ formData.set("confirm", "1");
+ formData.set("delete", String(entryId));
+
+ promises.push(
+ fetch("/mod/data/view.php", {
+ method: "POST",
+ body: formData,
+ }),
+ );
+ }
+ return Promise.all(promises);
+}
+
export { DB, DatabaseEntry, DatabaseParams, getGraduationDb };