Rewrite AddInstanceDialog
Object oriented it is
This commit is contained in:
parent
5534bc3942
commit
2be0658ed9
4 changed files with 101 additions and 35 deletions
|
@ -1,5 +1,6 @@
|
||||||
// This file handles the "Add an instance" dialog
|
// This file handles the "Add an instance" dialog
|
||||||
|
|
||||||
|
import { FormDialog, ONCE } from "./dialog.mjs";
|
||||||
import { findButtonOrFail, findFormOrFail, findInputOrFail } from "./dom.mjs";
|
import { findButtonOrFail, findFormOrFail, findInputOrFail } from "./dom.mjs";
|
||||||
|
|
||||||
export function parseHost(host: string): { host: string, secure: boolean } | null {
|
export function parseHost(host: string): { host: string, secure: boolean } | null {
|
||||||
|
@ -13,43 +14,66 @@ export function parseHost(host: string): { host: string, secure: boolean } | nul
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initializeAddInstanceDialog(
|
type AddInstanceDialogData = {
|
||||||
dialog: HTMLDialogElement,
|
|
||||||
callback: (
|
|
||||||
host: string,
|
host: string,
|
||||||
secure: boolean,
|
secure: boolean,
|
||||||
autoQueryMetadata: boolean,
|
autoQueryMetadata: boolean,
|
||||||
) => void
|
};
|
||||||
): {
|
|
||||||
showAddInstanceDialog: () => void,
|
|
||||||
hideAddInstanceDialog: () => void,
|
|
||||||
} {
|
|
||||||
const showAddInstanceDialog = () => dialog.showModal();
|
|
||||||
const hideAddInstanceDialog = () => dialog.close();
|
|
||||||
|
|
||||||
const form = findFormOrFail(dialog, ".addInstanceForm");
|
export class AddInstanceDialog extends FormDialog {
|
||||||
const instanceHost = findInputOrFail(form, "#instanceHost");
|
protected instanceHost: HTMLInputElement;
|
||||||
const autoQueryMetadata = findInputOrFail(form, "#autoQueryMetadata");
|
protected autoQueryMetadata: HTMLInputElement;
|
||||||
const closeButton = findButtonOrFail(form, ".close");
|
protected closeButton: HTMLButtonElement;
|
||||||
|
|
||||||
instanceHost.addEventListener("input", e => {
|
constructor(dialog: HTMLDialogElement, initializeDOM: boolean = true) {
|
||||||
if (parseHost(instanceHost.value) === null)
|
super(dialog, findFormOrFail(dialog, ".addInstanceForm"));
|
||||||
instanceHost.setCustomValidity("Invalid instance hostname or URL");
|
this.instanceHost = findInputOrFail(this.form, "#instanceHost");
|
||||||
else
|
this.autoQueryMetadata = findInputOrFail(this.form, "#autoQueryMetadata");
|
||||||
instanceHost.setCustomValidity("");
|
this.closeButton = findButtonOrFail(this.form, ".close");
|
||||||
});
|
|
||||||
|
|
||||||
form.addEventListener("submit", e => {
|
if (initializeDOM) this.initializeDOM();
|
||||||
// A sane browser doesn't allow for submitting the form if the above validation fails
|
}
|
||||||
const { host, secure } = parseHost(instanceHost.value)!;
|
|
||||||
callback(host, secure, autoQueryMetadata.checked);
|
|
||||||
form.reset();
|
|
||||||
});
|
|
||||||
|
|
||||||
closeButton.addEventListener("click", e => hideAddInstanceDialog());
|
|
||||||
|
|
||||||
|
#getDataIfValid(): AddInstanceDialogData | null {
|
||||||
|
const parsedHost = parseHost(this.instanceHost.value);
|
||||||
|
if (parsedHost === null) {
|
||||||
|
this.instanceHost.setCustomValidity("Invalid instance hostname or URL");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
this.instanceHost.setCustomValidity("");
|
||||||
return {
|
return {
|
||||||
showAddInstanceDialog,
|
host: parsedHost.host,
|
||||||
hideAddInstanceDialog
|
secure: parsedHost.secure,
|
||||||
|
autoQueryMetadata: this.autoQueryMetadata.checked
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#handleSubmit(resolve: (data: AddInstanceDialogData) => void) {
|
||||||
|
this.form.addEventListener("submit", e => {
|
||||||
|
const data = this.#getDataIfValid();
|
||||||
|
if (data === null) {
|
||||||
|
// Prevent the user from submitting the form if it's invalid and let them try again
|
||||||
|
e.preventDefault();
|
||||||
|
this.#handleSubmit(resolve);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resolve(data);
|
||||||
|
this.close();
|
||||||
|
}, ONCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override initializeDOM() {
|
||||||
|
super.initializeDOM();
|
||||||
|
|
||||||
|
this.instanceHost.addEventListener("input", e => this.#getDataIfValid());
|
||||||
|
this.closeButton.addEventListener("click", e => this.close());
|
||||||
|
}
|
||||||
|
|
||||||
|
async prompt(): Promise<AddInstanceDialogData> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.dialog.addEventListener("close", e => reject(), ONCE);
|
||||||
|
this.#handleSubmit(resolve);
|
||||||
|
this.open();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { initializeAddInstanceDialog } from "./add_an_instance.mjs";
|
import { AddInstanceDialog } from "./add_an_instance.mjs";
|
||||||
import { initializeInstanceDetailsDialog } from "./confirm_instance_details.mjs";
|
import { initializeInstanceDetailsDialog } from "./confirm_instance_details.mjs";
|
||||||
import storageManager, { Instance } from "./storage_manager.mjs";
|
import storageManager, { Instance } from "./storage_manager.mjs";
|
||||||
|
|
||||||
|
|
41
static/dialog.mts
Normal file
41
static/dialog.mts
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
export const ONCE = { once: true };
|
||||||
|
|
||||||
|
export class Dialog {
|
||||||
|
protected dialog: HTMLDialogElement;
|
||||||
|
|
||||||
|
constructor(dialog: HTMLDialogElement) {
|
||||||
|
this.dialog = dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A function that should only be called once that has permanent effects on the DOM
|
||||||
|
*/
|
||||||
|
protected initializeDOM() { }
|
||||||
|
|
||||||
|
protected open() {
|
||||||
|
this.dialog.showModal();
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.dialog.close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export class FormDialog extends Dialog {
|
||||||
|
protected form: HTMLFormElement;
|
||||||
|
|
||||||
|
constructor(dialog: HTMLDialogElement, form: HTMLFormElement) {
|
||||||
|
super(dialog);
|
||||||
|
this.form = form;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override initializeDOM() {
|
||||||
|
super.initializeDOM();
|
||||||
|
|
||||||
|
this.dialog.addEventListener("close", e => this.reset());
|
||||||
|
}
|
||||||
|
|
||||||
|
reset() {
|
||||||
|
this.form.reset();
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"checkJs": true,
|
"checkJs": true,
|
||||||
"strictNullChecks": true,
|
"strictNullChecks": true,
|
||||||
|
"noImplicitOverride": true,
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"static/**.mts",
|
"static/**.mts",
|
||||||
|
|
Loading…
Add table
Reference in a new issue