Now sorting
All checks were successful
Build & Test / build-run (push) Successful in 43s

This commit is contained in:
CenTdemeern1 2025-02-13 01:41:20 +01:00
parent bc7e388f04
commit 027faf8371
4 changed files with 138 additions and 29 deletions

View file

@ -30,7 +30,17 @@
instance.<br>
<img src="/static/down_arrow.svg" alt="" class="medium-height" />
<p id="noInstance">You currently don't have any instances. You should add one!</p>
<form id="instanceSelectForm" class="align-start wfit-content"></form>
<form id="instanceSelectForm" class="align-start wfit-content">
<ol id="preferredList" class="margin-none" hidden></ol>
<div id="forks" hidden>
<p class="align-center margin-none-bottom">Other <span id="forkOf"></span> forks</p>
<ol id="forksList" class="margin-none"></ol>
</div>
<div id="others" hidden>
<p class="align-center margin-none-bottom">Other instances</p>
<ol id="othersList" class="margin-none"></ol>
</div>
</form>
<br>
<button id="startAddInstanceFlow">Add an instance</button>
</center>

View file

@ -1,7 +1,7 @@
import { AddInstanceFlow } from "./add_instance_flow.mjs";
import { findButtonOrFail, findDialogOrFail, findFormOrFail, findInputOrFail, findParagraphOrFail, findPreOrFail, findSpanOrFail } from "./dom.mjs";
import { findButtonOrFail, findDialogOrFail, findDivOrFail, findFormOrFail, findInputOrFail, findOlOrFail, findParagraphOrFail, findPreOrFail, findSpanOrFail } from "./dom.mjs";
import knownSoftware, { getName } from "./known_software.mjs";
import storageManager from "./storage_manager.mjs";
import storageManager, { Instance } from "./storage_manager.mjs";
const RADIO_BUTTON_NAME = "instanceSelect";
@ -13,6 +13,12 @@ const addDialog = findDialogOrFail(document.body, "#addInstance");
const spinnerDialog = findDialogOrFail(document.body, "#spinner");
const detailsDialog = findDialogOrFail(document.body, "#instanceDetails");
const instanceSelectForm = findFormOrFail(document.body, "#instanceSelectForm");
const preferredList = findOlOrFail(document.body, "#preferredList");
const forksDiv = findDivOrFail(document.body, "#forks");
const forkOfSpan = findSpanOrFail(document.body, "#forkOf");
const forksList = findOlOrFail(document.body, "#forksList");
const othersDiv = findDivOrFail(document.body, "#others");
const othersList = findOlOrFail(document.body, "#othersList");
const redirectButton = findButtonOrFail(document.body, "#redirect");
const redirectAlwaysButton = findButtonOrFail(document.body, "#redirectAlways");
const noInstanceParagraph = findParagraphOrFail(document.body, "#noInstance");
@ -58,9 +64,60 @@ function updateNoInstanceHint() {
storageManager.storage.instances.length > 0;
}
function createInstanceSelectOptions() {
instanceSelectForm.replaceChildren(); // Erase all child nodes
type PreferenceGroups = {
preferred: Instance[],
forks?: {
list: Instance[],
of: string,
},
others: Instance[],
};
function sortInstancesIntoPreferenceGroups(): PreferenceGroups {
const targetID = getTargetSoftwareOrGroup();
const pGroups: PreferenceGroups = {
preferred: [],
others: [],
};
// If targetID is a group
if (knownSoftware.groups[targetID]) {
for (const instance of storageManager.storage.instances) {
const software = knownSoftware.software[instance.software];
// If the instance's software is in the target group
if (software.groups.includes(targetID)) {
pGroups.preferred.push(instance);
} else {
pGroups.others.push(instance);
}
}
} else {
const isFork = knownSoftware.software[targetID].forkOf !== undefined;
const forkOf = knownSoftware.software[targetID].forkOf ?? targetID;
const hasForks = isFork || Object.values(knownSoftware.software).some(s => s.forkOf === forkOf);
if (hasForks) {
pGroups.forks = {
list: [],
of: forkOf,
};
}
for (const instance of storageManager.storage.instances) {
if (instance.software === targetID) {
pGroups.preferred.push(instance);
continue;
}
const software = knownSoftware.software[instance.software];
// Checking pGroups.forks is the TypeScript safe way of checking hasForks
if (pGroups.forks && (instance.software === forkOf || software.forkOf === forkOf)) {
pGroups.forks.list.push(instance);
continue;
}
pGroups.others.push(instance);
}
}
return pGroups;
}
function constructOptionFromInstance(instance: Instance): HTMLDivElement {
const div = document.createElement("div");
div.setAttribute("x-option", instance.origin);
const radio = document.createElement("input");
@ -84,8 +141,35 @@ function createInstanceSelectOptions() {
label.appendChild(small);
div.appendChild(radio);
div.appendChild(label);
instanceSelectForm.appendChild(div);
return div;
}
function createInstanceSelectOptions() {
// Erase all child nodes
preferredList.replaceChildren();
forksList.replaceChildren();
othersList.replaceChildren();
const { preferred, forks, others } = sortInstancesIntoPreferenceGroups();
preferredList.hidden = preferred.length === 0;
for (const instance of preferred) {
preferredList.appendChild(constructOptionFromInstance(instance));
}
forksDiv.hidden = forks === undefined;
if (forks) {
forkOfSpan.innerText = getName(knownSoftware, forks.of) ?? forks.of;
for (const instance of forks.list) {
forksList.appendChild(constructOptionFromInstance(instance));
}
}
othersDiv.hidden = others.length === 0;
for (const instance of others) {
othersList.appendChild(constructOptionFromInstance(instance));
}
const firstInput = instanceSelectForm.querySelector("input");
if (firstInput) firstInput.checked = true;
setRedirectButtonState(firstInput !== null);

View file

@ -1,6 +1,13 @@
// I would've LOVED to use generics for this but unfortunately that's not possible.
// Type safety, but at what cost... >~< thanks TypeScript
export function findDivOrFail(on: Element, selector: string): HTMLDivElement {
const element = on.querySelector(selector);
if (!(element instanceof HTMLDivElement))
throw new Error(`${selector} isn't a div`);
return element;
}
export function findSpanOrFail(on: Element, selector: string): HTMLSpanElement {
const element = on.querySelector(selector);
if (!(element instanceof HTMLSpanElement))

View file

@ -61,6 +61,10 @@ abbr[title] {
text-align: start;
}
.align-center {
text-align: center;
}
.inline-block {
display: inline-block;
}
@ -157,6 +161,10 @@ abbr[title] {
margin-bottom: var(--large);
}
.margin-none-bottom {
margin-bottom: 0;
}
.square {
aspect-ratio: 1;
}