mirror of
https://github.com/1f349/admin.1f349.com.git
synced 2024-11-09 22:32:57 +00:00
Add created, modified and removed counts for routes and redirects
This commit is contained in:
parent
2ca7a47853
commit
91ed75f970
@ -4,3 +4,29 @@ import type {Redirect, Route} from "../types/target";
|
|||||||
|
|
||||||
export const routesTable = writable<{[key: string]: CSPair<Route>}>({});
|
export const routesTable = writable<{[key: string]: CSPair<Route>}>({});
|
||||||
export const redirectsTable = writable<{[key: string]: CSPair<Redirect>}>({});
|
export const redirectsTable = writable<{[key: string]: CSPair<Redirect>}>({});
|
||||||
|
|
||||||
|
export interface Pair<A, B> {
|
||||||
|
a: A;
|
||||||
|
b: B;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTableArray<T>(table: {[key: string]: CSPair<T>}, keys: Array<string>): Array<Pair<string, CSPair<T>>> {
|
||||||
|
return keys.map(x => ({a: x, b: table[x]}));
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CountStats {
|
||||||
|
created: number;
|
||||||
|
modified: number;
|
||||||
|
removed: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function tableCountStats<T>(table: {[key: string]: CSPair<T>}, keys: Array<string>, equality: (a: T, b: T) => boolean): CountStats {
|
||||||
|
let list = getTableArray(table, keys)
|
||||||
|
.map(x => x.b)
|
||||||
|
.filter(x => x.client != null || x.server != null);
|
||||||
|
return {
|
||||||
|
created: list.filter(x => x.server == null).length,
|
||||||
|
modified: list.filter(x => x.server != null && x.client != null && !equality(x.client, x.server)).length,
|
||||||
|
removed: list.filter(x => x.client == null).length,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
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";
|
import {redirectsTable, type CountStats, tableCountStats} from "../stores/target";
|
||||||
|
|
||||||
const apiViolet = import.meta.env.VITE_API_VIOLET;
|
const apiViolet = import.meta.env.VITE_API_VIOLET;
|
||||||
|
|
||||||
@ -17,6 +17,10 @@
|
|||||||
.filter(x => domainFilter(x, $domainOption))
|
.filter(x => domainFilter(x, $domainOption))
|
||||||
.sort((a, b) => a.localeCompare(b));
|
.sort((a, b) => a.localeCompare(b));
|
||||||
|
|
||||||
|
let rowStats: CountStats = {created: 0, modified: 0, removed: 0};
|
||||||
|
|
||||||
|
$: rowStats = tableCountStats($redirectsTable, tableKeys, redirectEqual);
|
||||||
|
|
||||||
function domainFilter(src: string, domain: string) {
|
function domainFilter(src: string, domain: string) {
|
||||||
if (domain == "*") return true;
|
if (domain == "*") return true;
|
||||||
let n = src.indexOf("/");
|
let n = src.indexOf("/");
|
||||||
@ -141,7 +145,16 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<button on:click={() => saveChanges()}>Save Changes</button>
|
<button class="btn-green" on:click={() => saveChanges()}>Save Changes</button>
|
||||||
|
{#if rowStats.created > 0}
|
||||||
|
<div class="meta-info">{rowStats.created} new redirect{rowStats.created > 1 ? "s" : ""}</div>
|
||||||
|
{/if}
|
||||||
|
{#if rowStats.modified > 0}
|
||||||
|
<div class="meta-info">{rowStats.modified} unsaved change{rowStats.modified > 1 ? "s" : ""}</div>
|
||||||
|
{/if}
|
||||||
|
{#if rowStats.removed > 0}
|
||||||
|
<div class="meta-info">{rowStats.removed} removed redirect{rowStats.removed > 1 ? "s" : ""}</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -187,19 +200,12 @@
|
|||||||
height: 50px;
|
height: 50px;
|
||||||
background-color: #2c2c2c;
|
background-color: #2c2c2c;
|
||||||
box-shadow: 0 -4px 8px #0003, 0 -6px 20px #00000030;
|
box-shadow: 0 -4px 8px #0003, 0 -6px 20px #00000030;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
button {
|
.meta-info {
|
||||||
background-color: #04aa6d;
|
line-height: 50px;
|
||||||
border: none;
|
padding-inline: 16px;
|
||||||
box-shadow: none;
|
|
||||||
box-sizing: border-box;
|
|
||||||
color: black;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: 700;
|
|
||||||
line-height: 24px;
|
|
||||||
height: 50px;
|
|
||||||
padding: 4px 16px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
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";
|
import {routesTable, type CountStats, tableCountStats} from "../stores/target";
|
||||||
|
|
||||||
const apiViolet = import.meta.env.VITE_API_VIOLET;
|
const apiViolet = import.meta.env.VITE_API_VIOLET;
|
||||||
|
|
||||||
@ -17,6 +17,10 @@
|
|||||||
.filter(x => domainFilter(x, $domainOption))
|
.filter(x => domainFilter(x, $domainOption))
|
||||||
.sort((a, b) => a.localeCompare(b));
|
.sort((a, b) => a.localeCompare(b));
|
||||||
|
|
||||||
|
let rowStats: CountStats = {created: 0, modified: 0, removed: 0};
|
||||||
|
|
||||||
|
$: rowStats = tableCountStats($routesTable, tableKeys, routeEqual);
|
||||||
|
|
||||||
function domainFilter(src: string, domain: string) {
|
function domainFilter(src: string, domain: string) {
|
||||||
if (domain == "*") return true;
|
if (domain == "*") return true;
|
||||||
let n = src.indexOf("/");
|
let n = src.indexOf("/");
|
||||||
@ -141,6 +145,15 @@
|
|||||||
|
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<button class="btn-green" on:click={() => saveChanges()}>Save Changes</button>
|
<button class="btn-green" on:click={() => saveChanges()}>Save Changes</button>
|
||||||
|
{#if rowStats.created > 0}
|
||||||
|
<div class="meta-info">{rowStats.created} new route{rowStats.created > 1 ? "s" : ""}</div>
|
||||||
|
{/if}
|
||||||
|
{#if rowStats.modified > 0}
|
||||||
|
<div class="meta-info">{rowStats.modified} unsaved change{rowStats.modified > 1 ? "s" : ""}</div>
|
||||||
|
{/if}
|
||||||
|
{#if rowStats.removed > 0}
|
||||||
|
<div class="meta-info">{rowStats.removed} removed route{rowStats.removed > 1 ? "s" : ""}</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -186,5 +199,12 @@
|
|||||||
height: 50px;
|
height: 50px;
|
||||||
background-color: #2c2c2c;
|
background-color: #2c2c2c;
|
||||||
box-shadow: 0 -4px 8px #0003, 0 -6px 20px #00000030;
|
box-shadow: 0 -4px 8px #0003, 0 -6px 20px #00000030;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
.meta-info {
|
||||||
|
line-height: 50px;
|
||||||
|
padding-inline: 16px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
Loading…
Reference in New Issue
Block a user