mirror of
https://github.com/1f349/admin.1f349.com.git
synced 2024-11-09 22:32:57 +00:00
Smoother route and redirect saving changes
This commit is contained in:
parent
ca21c244fc
commit
3e22444b4f
@ -1,6 +1,6 @@
|
|||||||
export type CSPair<T> = {client: T; server: T} | CSPairNotC<T> | CSPairNotS<T>;
|
export type CSPair<T> = {client: T; server: T; p: Promise<void>} | CSPairNotC<T> | CSPairNotS<T>;
|
||||||
export type CSPairNotC<T> = {client: null; server: T};
|
export type CSPairNotC<T> = {client: null; server: T; p: Promise<void>};
|
||||||
export type CSPairNotS<T> = {client: T; server: null};
|
export type CSPairNotS<T> = {client: T; server: null; p: Promise<void>};
|
||||||
|
|
||||||
export function noCPair<T>(pair: CSPair<T>): pair is CSPairNotC<T> {
|
export function noCPair<T>(pair: CSPair<T>): pair is CSPairNotC<T> {
|
||||||
return pair.client == null;
|
return pair.client == null;
|
||||||
|
@ -8,10 +8,10 @@
|
|||||||
|
|
||||||
const apiViolet = import.meta.env.VITE_API_VIOLET;
|
const apiViolet = import.meta.env.VITE_API_VIOLET;
|
||||||
|
|
||||||
let redirectData: {[key: string]: CSPair<Redirect>} = {};
|
let tableData: {[key: string]: CSPair<Redirect>} = {};
|
||||||
let redirectSrcs: string[] = [];
|
let redirectSrcs: string[] = [];
|
||||||
|
|
||||||
$: redirectSrcs = Object.entries(redirectData)
|
$: redirectSrcs = Object.entries(tableData)
|
||||||
.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,12 +26,10 @@
|
|||||||
return p.endsWith(domain);
|
return p.endsWith(domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
let promiseForRedirects: Promise<void>;
|
let promiseForRedirects: Promise<void> = reloadRedirects(true);
|
||||||
|
|
||||||
reloadRedirects();
|
function reloadRedirects(firstLoad: boolean = false): Promise<void> {
|
||||||
|
return new Promise<void>((res, rej) => {
|
||||||
function reloadRedirects() {
|
|
||||||
promiseForRedirects = new Promise<void>((res, rej) => {
|
|
||||||
fetch(apiViolet + "/redirect", {headers: {Authorization: getBearer()}})
|
fetch(apiViolet + "/redirect", {headers: {Authorization: getBearer()}})
|
||||||
.then(x => {
|
.then(x => {
|
||||||
if (x.status != 200) throw new Error("Unexpected status code: " + x.status);
|
if (x.status != 200) throw new Error("Unexpected status code: " + x.status);
|
||||||
@ -41,9 +39,12 @@
|
|||||||
let redirects = x as Redirect[];
|
let redirects = x as Redirect[];
|
||||||
let y: {[key: string]: CSPair<Redirect>} = {};
|
let y: {[key: string]: CSPair<Redirect>} = {};
|
||||||
redirects.forEach(x => {
|
redirects.forEach(x => {
|
||||||
y[x.src] = {client: JSON.parse(JSON.stringify(x)), server: x};
|
tableData[x.src] = {
|
||||||
|
client: firstLoad || !tableData[x.src] ? JSON.parse(JSON.stringify(x)) : tableData[x.src]?.client,
|
||||||
|
server: x,
|
||||||
|
p: Promise.resolve(),
|
||||||
|
};
|
||||||
});
|
});
|
||||||
redirectData = y;
|
|
||||||
res();
|
res();
|
||||||
})
|
})
|
||||||
.catch(x => rej(x));
|
.catch(x => rej(x));
|
||||||
@ -52,32 +53,34 @@
|
|||||||
|
|
||||||
interface Savable<T> {
|
interface Savable<T> {
|
||||||
type: "del" | "ins";
|
type: "del" | "ins";
|
||||||
v: T;
|
v: CSPair<T>;
|
||||||
p?: Promise<void>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveChanges() {
|
function saveChanges() {
|
||||||
let redirectPromises = redirectSrcs
|
let redirectPromises = redirectSrcs
|
||||||
.map(x => redirectData[x])
|
.map(x => tableData[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<CSPair<Redirect>> => {
|
.map((x: CSPair<Redirect>): Savable<Redirect> => {
|
||||||
if (x.client == null && x.server != null) return {type: "del", v: x};
|
if (x.client == null && x.server != null) return {type: "del", v: x};
|
||||||
return {type: "ins", v: x};
|
return {type: "ins", v: x};
|
||||||
})
|
})
|
||||||
.sort((a, _) => (a.type === "del" ? -1 : a.type === "ins" ? 1 : 0))
|
.sort((a, _) => (a.type === "del" ? -1 : a.type === "ins" ? 1 : 0))
|
||||||
.map(x => {
|
.map(x => {
|
||||||
x.p = fetch(apiViolet + "/redirect", {
|
x.v.p = fetch(apiViolet + "/redirect", {
|
||||||
method: x.type == "del" ? "DELETE" : "POST",
|
method: x.type == "del" ? "DELETE" : "POST",
|
||||||
headers: {Authorization: getBearer()},
|
headers: {Authorization: getBearer()},
|
||||||
body: JSON.stringify(x.type == "del" ? {src: (x.v.server as Redirect).src} : x.v.client),
|
body: JSON.stringify(x.type == "del" ? {src: (x.v.server as Redirect).src} : x.v.client),
|
||||||
}).then(x => {
|
}).then(x => {
|
||||||
if (x.status !== 200) throw new Error("Unexpected status code: " + x.status);
|
if (x.status !== 200) throw new Error("Unexpected status code: " + x.status);
|
||||||
});
|
});
|
||||||
|
return x.v.p;
|
||||||
});
|
});
|
||||||
|
|
||||||
Promise.all(redirectPromises).then(_ => {
|
Promise.all(redirectPromises)
|
||||||
reloadRedirects();
|
.then(_ => reloadRedirects())
|
||||||
|
.catch(_ => {
|
||||||
|
alert("Some rows failed to save changes");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -107,7 +110,7 @@
|
|||||||
<RedirectCreator
|
<RedirectCreator
|
||||||
on:make={e => {
|
on:make={e => {
|
||||||
const x = e.detail;
|
const x = e.detail;
|
||||||
redirectData[x.src] = {client: x, server: redirectData[x.src]?.server};
|
tableData[x.src] = {client: x, server: tableData[x.src]?.server, p: Promise.resolve()};
|
||||||
redirectSrcs.push(x.src);
|
redirectSrcs.push(x.src);
|
||||||
redirectSrcs = redirectSrcs;
|
redirectSrcs = redirectSrcs;
|
||||||
}}
|
}}
|
||||||
@ -115,11 +118,13 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{#each redirectSrcs as src (src)}
|
{#each redirectSrcs as src (src)}
|
||||||
{#if redirectData[src]}
|
{#await tableData[src].p}
|
||||||
<RedirectRow bind:value={redirectData[src]} />
|
<tr><td colspan="5">Loading...</td></tr>
|
||||||
{:else}
|
{:then _}
|
||||||
<tr><td colspan="5">Error loading row for {src}</td></tr>
|
<RedirectRow bind:value={tableData[src]} />
|
||||||
{/if}
|
{:catch err}
|
||||||
|
<tr><td colspan="5">Error loading row for {src}: {err}</td></tr>
|
||||||
|
{/await}
|
||||||
{/each}
|
{/each}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@ -26,12 +26,10 @@
|
|||||||
return p.endsWith(domain);
|
return p.endsWith(domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
let promiseForRoutes: Promise<void>;
|
let promiseForRoutes: Promise<void> = reloadRoutes(true);
|
||||||
|
|
||||||
reloadRoutes();
|
function reloadRoutes(firstLoad: boolean = false): Promise<void> {
|
||||||
|
return new Promise<void>((res, rej) => {
|
||||||
function reloadRoutes() {
|
|
||||||
promiseForRoutes = new Promise<void>((res, rej) => {
|
|
||||||
fetch(apiViolet + "/route", {headers: {Authorization: getBearer()}})
|
fetch(apiViolet + "/route", {headers: {Authorization: getBearer()}})
|
||||||
.then(x => {
|
.then(x => {
|
||||||
if (x.status !== 200) throw new Error("Unexpected status code: " + x.status);
|
if (x.status !== 200) throw new Error("Unexpected status code: " + x.status);
|
||||||
@ -41,9 +39,12 @@
|
|||||||
let routes = x as Route[];
|
let routes = x as Route[];
|
||||||
let y: {[key: string]: CSPair<Route>} = {};
|
let y: {[key: string]: CSPair<Route>} = {};
|
||||||
routes.forEach(x => {
|
routes.forEach(x => {
|
||||||
y[x.src] = {client: JSON.parse(JSON.stringify(x)), server: x};
|
tableData[x.src] = {
|
||||||
|
client: firstLoad || !tableData[x.src] ? JSON.parse(JSON.stringify(x)) : tableData[x.src]?.client,
|
||||||
|
server: x,
|
||||||
|
p: Promise.resolve(),
|
||||||
|
};
|
||||||
});
|
});
|
||||||
tableData = y;
|
|
||||||
res();
|
res();
|
||||||
})
|
})
|
||||||
.catch(x => rej(x));
|
.catch(x => rej(x));
|
||||||
@ -52,8 +53,7 @@
|
|||||||
|
|
||||||
interface Savable<T> {
|
interface Savable<T> {
|
||||||
type: "del" | "ins";
|
type: "del" | "ins";
|
||||||
v: T;
|
v: CSPair<T>;
|
||||||
p?: Promise<void>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveChanges() {
|
function saveChanges() {
|
||||||
@ -61,23 +61,26 @@
|
|||||||
.map(x => tableData[x])
|
.map(x => tableData[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<CSPair<Route>> => {
|
.map((x: CSPair<Route>): Savable<Route> => {
|
||||||
if (x.client == null && x.server != null) return {type: "del", v: x};
|
if (x.client == null && x.server != null) return {type: "del", v: x};
|
||||||
return {type: "ins", v: x};
|
return {type: "ins", v: x};
|
||||||
})
|
})
|
||||||
.sort((a, _) => (a.type === "del" ? -1 : a.type === "ins" ? 1 : 0))
|
.sort((a, _) => (a.type === "del" ? -1 : a.type === "ins" ? 1 : 0))
|
||||||
.map(x => {
|
.map(x => {
|
||||||
x.p = fetch(apiViolet + "/route", {
|
x.v.p = fetch(apiViolet + "/route", {
|
||||||
method: x.type == "del" ? "DELETE" : "POST",
|
method: x.type == "del" ? "DELETE" : "POST",
|
||||||
headers: {Authorization: getBearer()},
|
headers: {Authorization: getBearer()},
|
||||||
body: JSON.stringify(x.type == "del" ? {src: (x.v.server as Route).src} : x.v.client),
|
body: JSON.stringify(x.type == "del" ? {src: (x.v.server as Route).src} : x.v.client),
|
||||||
}).then(x => {
|
}).then(x => {
|
||||||
if (x.status !== 200) throw new Error("Unexpected status code: " + x.status);
|
if (x.status !== 200) throw new Error("Unexpected status code: " + x.status);
|
||||||
});
|
});
|
||||||
|
return x.v.p;
|
||||||
});
|
});
|
||||||
|
|
||||||
Promise.all(routePromises).then(_ => {
|
Promise.all(routePromises)
|
||||||
reloadRoutes();
|
.then(_ => reloadRoutes())
|
||||||
|
.catch(_ => {
|
||||||
|
alert("Some rows failed to save changes");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -106,7 +109,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};
|
tableData[x.src] = {client: x, server: tableData[x.src]?.server, p: Promise.resolve()};
|
||||||
tableKeys.push(x.src);
|
tableKeys.push(x.src);
|
||||||
tableKeys = tableKeys;
|
tableKeys = tableKeys;
|
||||||
}}
|
}}
|
||||||
@ -114,11 +117,13 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{#each tableKeys as src (src)}
|
{#each tableKeys as src (src)}
|
||||||
{#if tableData[src]}
|
{#await tableData[src].p}
|
||||||
|
<tr><td colspan="5">Loading...</td></tr>
|
||||||
|
{:then _}
|
||||||
<RouteRow bind:value={tableData[src]} />
|
<RouteRow bind:value={tableData[src]} />
|
||||||
{:else}
|
{:catch err}
|
||||||
<tr><td colspan="5">Error loading row for {src}</td></tr>
|
<tr><td colspan="5">Error loading row for {src}: {err}</td></tr>
|
||||||
{/if}
|
{/await}
|
||||||
{/each}
|
{/each}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
Loading…
Reference in New Issue
Block a user