Use store for routes and redirects to keep data between sidebar page changes

This commit is contained in:
Melon 2023-10-31 11:06:37 +00:00
parent 9c169e3e55
commit f9f5298a4b
Signed by: melon
GPG Key ID: 6C9D970C50D26A25
3 changed files with 31 additions and 20 deletions

6
src/stores/target.ts Normal file
View File

@ -0,0 +1,6 @@
import {writable} from "svelte/store";
import type {CSPair} from "../types/cspair";
import type {Redirect, Route} from "../types/target";
export const routesTable = writable<{[key: string]: CSPair<Route>}>({});
export const redirectsTable = writable<{[key: string]: CSPair<Redirect>}>({});

View File

@ -5,13 +5,13 @@
import type {CSPair} from "../types/cspair"; import type {CSPair} from "../types/cspair";
import {type Redirect, redirectEqual} from "../types/target"; import {type Redirect, redirectEqual} from "../types/target";
import {domainOption} from "../stores/domain-option"; import {domainOption} from "../stores/domain-option";
import {redirectsTable} from "../stores/target";
const apiViolet = import.meta.env.VITE_API_VIOLET; const apiViolet = import.meta.env.VITE_API_VIOLET;
let tableData: {[key: string]: CSPair<Redirect>} = {};
let tableKeys: string[] = []; let tableKeys: string[] = [];
$: tableKeys = Object.entries(tableData) $: tableKeys = Object.entries($redirectsTable)
.filter(x => x[1].client != null || x[1].server != null) .filter(x => x[1].client != null || x[1].server != null)
.map(x => x[0]) .map(x => x[0])
.filter(x => domainFilter(x, $domainOption)) .filter(x => domainFilter(x, $domainOption))
@ -26,9 +26,9 @@
return p.endsWith(domain); return p.endsWith(domain);
} }
let promiseForTable: Promise<void> = reloadTable(true); let promiseForTable: Promise<void> = reloadTable();
function reloadTable(firstLoad: boolean = false): Promise<void> { function reloadTable(): Promise<void> {
return new Promise<void>((res, rej) => { return new Promise<void>((res, rej) => {
fetch(apiViolet + "/redirect", {headers: {Authorization: getBearer()}}) fetch(apiViolet + "/redirect", {headers: {Authorization: getBearer()}})
.then(x => { .then(x => {
@ -38,8 +38,8 @@
.then(x => { .then(x => {
let rows = x as Redirect[]; let rows = x as Redirect[];
rows.forEach(x => { rows.forEach(x => {
tableData[x.src] = { $redirectsTable[x.src] = {
client: firstLoad || !tableData[x.src] ? JSON.parse(JSON.stringify(x)) : tableData[x.src]?.client, client: !$redirectsTable[x.src] ? JSON.parse(JSON.stringify(x)) : $redirectsTable[x.src]?.client,
server: x, server: x,
p: Promise.resolve(), p: Promise.resolve(),
}; };
@ -57,7 +57,7 @@
function saveChanges() { function saveChanges() {
let tableProm = tableKeys let tableProm = tableKeys
.map(x => tableData[x]) .map(x => $redirectsTable[x])
.filter(x => x.client != null || x.server != null) .filter(x => x.client != null || x.server != null)
.filter(x => !redirectEqual(x.client, x.server)) .filter(x => !redirectEqual(x.client, x.server))
.map((x: CSPair<Redirect>): Savable<Redirect> => { .map((x: CSPair<Redirect>): Savable<Redirect> => {
@ -109,7 +109,7 @@
<RedirectCreator <RedirectCreator
on:make={e => { on:make={e => {
const x = e.detail; const x = e.detail;
tableData[x.src] = {client: x, server: tableData[x.src]?.server, p: Promise.resolve()}; $redirectsTable[x.src] = {client: x, server: $redirectsTable[x.src]?.server, p: Promise.resolve()};
tableKeys.push(x.src); tableKeys.push(x.src);
tableKeys = tableKeys; tableKeys = tableKeys;
}} }}
@ -117,10 +117,10 @@
</thead> </thead>
<tbody> <tbody>
{#each tableKeys as src (src)} {#each tableKeys as src (src)}
{#await tableData[src].p} {#await $redirectsTable[src].p}
<tr><td colspan="5">Loading...</td></tr> <tr><td colspan="5">Loading...</td></tr>
{:then _} {:then _}
<RedirectRow bind:value={tableData[src]} /> <RedirectRow bind:value={$redirectsTable[src]} />
{:catch err} {:catch err}
<tr><td colspan="5">Error loading row for {src}: {err}</td></tr> <tr><td colspan="5">Error loading row for {src}: {err}</td></tr>
{/await} {/await}

View File

@ -5,13 +5,13 @@
import type {CSPair} from "../types/cspair"; import type {CSPair} from "../types/cspair";
import {type Route, routeEqual} from "../types/target"; import {type Route, routeEqual} from "../types/target";
import {domainOption} from "../stores/domain-option"; import {domainOption} from "../stores/domain-option";
import {routesTable} from "../stores/target";
const apiViolet = import.meta.env.VITE_API_VIOLET; const apiViolet = import.meta.env.VITE_API_VIOLET;
let tableData: {[key: string]: CSPair<Route>} = {};
let tableKeys: string[] = []; let tableKeys: string[] = [];
$: tableKeys = Object.entries(tableData) $: tableKeys = Object.entries($routesTable)
.filter(x => x[1].client != null || x[1].server != null) .filter(x => x[1].client != null || x[1].server != null)
.map(x => x[0]) .map(x => x[0])
.filter(x => domainFilter(x, $domainOption)) .filter(x => domainFilter(x, $domainOption))
@ -26,9 +26,9 @@
return p.endsWith(domain); return p.endsWith(domain);
} }
let promiseForTable: Promise<void> = reloadTable(true); let promiseForTable: Promise<void> = reloadTable();
function reloadTable(firstLoad: boolean = false): Promise<void> { function reloadTable(): Promise<void> {
return new Promise<void>((res, rej) => { return new Promise<void>((res, rej) => {
fetch(apiViolet + "/route", {headers: {Authorization: getBearer()}}) fetch(apiViolet + "/route", {headers: {Authorization: getBearer()}})
.then(x => { .then(x => {
@ -37,12 +37,17 @@
}) })
.then(x => { .then(x => {
let rows = x as Route[]; let rows = x as Route[];
let srcs = new Set(Object.keys($routesTable));
rows.forEach(x => { rows.forEach(x => {
tableData[x.src] = { $routesTable[x.src] = {
client: firstLoad || !tableData[x.src] ? JSON.parse(JSON.stringify(x)) : tableData[x.src]?.client, client: !$routesTable[x.src] ? JSON.parse(JSON.stringify(x)) : $routesTable[x.src]?.client,
server: x, server: x,
p: Promise.resolve(), p: Promise.resolve(),
}; };
srcs.delete(x.src);
});
srcs.forEach(x => {
$routesTable[x].server = null;
}); });
res(); res();
}) })
@ -57,7 +62,7 @@
function saveChanges() { function saveChanges() {
let tableProm = tableKeys let tableProm = tableKeys
.map(x => tableData[x]) .map(x => $routesTable[x])
.filter(x => x.client != null || x.server != null) .filter(x => x.client != null || x.server != null)
.filter(x => !routeEqual(x.client, x.server)) .filter(x => !routeEqual(x.client, x.server))
.map((x: CSPair<Route>): Savable<Route> => { .map((x: CSPair<Route>): Savable<Route> => {
@ -108,7 +113,7 @@
<RouteCreator <RouteCreator
on:make={e => { on:make={e => {
const x = e.detail; const x = e.detail;
tableData[x.src] = {client: x, server: tableData[x.src]?.server, p: Promise.resolve()}; $routesTable[x.src] = {client: x, server: $routesTable[x.src]?.server, p: Promise.resolve()};
tableKeys.push(x.src); tableKeys.push(x.src);
tableKeys = tableKeys; tableKeys = tableKeys;
}} }}
@ -116,10 +121,10 @@
</thead> </thead>
<tbody> <tbody>
{#each tableKeys as src (src)} {#each tableKeys as src (src)}
{#await tableData[src].p} {#await $routesTable[src].p}
<tr><td colspan="5">Loading...</td></tr> <tr><td colspan="5">Loading...</td></tr>
{:then _} {:then _}
<RouteRow bind:value={tableData[src]} /> <RouteRow bind:value={$routesTable[src]} />
{:catch err} {:catch err}
<tr><td colspan="5">Error loading row for {src}: {err}</td></tr> <tr><td colspan="5">Error loading row for {src}: {err}</td></tr>
{/await} {/await}