mirror of
https://github.com/thiloho/archtika.git
synced 2025-11-22 02:41:35 +01:00
Merge pull request #13 from archtika/devel
Add pagination for logs and update deploy action
This commit is contained in:
3
.github/workflows/deploy.yml
vendored
3
.github/workflows/deploy.yml
vendored
@@ -31,8 +31,9 @@ jobs:
|
|||||||
- name: Deploy to demo server
|
- name: Deploy to demo server
|
||||||
run: |
|
run: |
|
||||||
nix run nixpkgs#nixos-rebuild -- switch \
|
nix run nixpkgs#nixos-rebuild -- switch \
|
||||||
--flake .#${{ github.event.workflow_run.head_branch == 'devel' && 'qs' || 'prod' }} \
|
--flake github:archtika/archtika/${{ github.event.workflow_run.head_branch }}#${{ github.event.workflow_run.head_branch == 'devel' && 'qs' || 'prod' }} \
|
||||||
--fast \
|
--fast \
|
||||||
|
--refresh \
|
||||||
--build-host ${{ env.SERVER_USER }}@${{ github.event.workflow_run.head_branch == 'devel' && env.QS_SERVER_IP || env.PROD_SERVER_IP }} \
|
--build-host ${{ env.SERVER_USER }}@${{ github.event.workflow_run.head_branch == 'devel' && env.QS_SERVER_IP || env.PROD_SERVER_IP }} \
|
||||||
--target-host ${{ env.SERVER_USER }}@${{ github.event.workflow_run.head_branch == 'devel' && env.QS_SERVER_IP || env.PROD_SERVER_IP }} \
|
--target-host ${{ env.SERVER_USER }}@${{ github.event.workflow_run.head_branch == 'devel' && env.QS_SERVER_IP || env.PROD_SERVER_IP }} \
|
||||||
--use-remote-sudo
|
--use-remote-sudo
|
||||||
|
|||||||
@@ -68,9 +68,9 @@
|
|||||||
];
|
];
|
||||||
locations = {
|
locations = {
|
||||||
"/" = {
|
"/" = {
|
||||||
root = "/var/www/archtika-websites/";
|
root = "/var/www/archtika-websites";
|
||||||
index = "index.html";
|
index = "index.html";
|
||||||
tryFiles = "$uri $uri/ $uri.html $uri/index.html index.html =404";
|
tryFiles = "$uri $uri/ $uri.html =404";
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
autoindex on;
|
autoindex on;
|
||||||
'';
|
'';
|
||||||
|
|||||||
@@ -160,14 +160,12 @@ in
|
|||||||
"/previews/" = {
|
"/previews/" = {
|
||||||
alias = "/var/www/archtika-websites/previews/";
|
alias = "/var/www/archtika-websites/previews/";
|
||||||
index = "index.html";
|
index = "index.html";
|
||||||
tryFiles = "$uri $uri/ $uri.html $uri/index.html index.html =404";
|
tryFiles = "$uri $uri/ $uri.html =404";
|
||||||
};
|
};
|
||||||
"/api/" = {
|
"/api/" = {
|
||||||
proxyPass = "http://localhost:${toString cfg.apiPort}/";
|
proxyPass = "http://localhost:${toString cfg.apiPort}/";
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
default_type application/json;
|
default_type application/json;
|
||||||
proxy_hide_header Content-Location;
|
|
||||||
add_header Content-Location /api/$upstream_http_content_location;
|
|
||||||
proxy_set_header Connection "";
|
proxy_set_header Connection "";
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
'';
|
'';
|
||||||
@@ -179,9 +177,9 @@ in
|
|||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
locations = {
|
locations = {
|
||||||
"/" = {
|
"/" = {
|
||||||
alias = "/var/www/archtika-websites/$subdomain/";
|
root = "/var/www/archtika-websites/$subdomain";
|
||||||
index = "index.html";
|
index = "index.html";
|
||||||
tryFiles = "$uri $uri/ $uri.html $uri/index.html index.html =404";
|
tryFiles = "$uri $uri/ $uri.html =404";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ export const load: PageServerLoad = async ({ parent, fetch, params, cookies, url
|
|||||||
const userFilter = url.searchParams.get("logs_filter_user");
|
const userFilter = url.searchParams.get("logs_filter_user");
|
||||||
const resourceFilter = url.searchParams.get("logs_filter_resource");
|
const resourceFilter = url.searchParams.get("logs_filter_resource");
|
||||||
const operationFilter = url.searchParams.get("logs_filter_operation");
|
const operationFilter = url.searchParams.get("logs_filter_operation");
|
||||||
|
const currentPage = Number.parseInt(url.searchParams.get("logs_results_page") ?? "1");
|
||||||
|
const resultOffset = currentPage === 1 ? 0 : currentPage * 50;
|
||||||
|
|
||||||
const searchParams = new URLSearchParams();
|
const searchParams = new URLSearchParams();
|
||||||
|
|
||||||
@@ -23,7 +25,7 @@ export const load: PageServerLoad = async ({ parent, fetch, params, cookies, url
|
|||||||
searchParams.append("operation", `eq.${operationFilter.toUpperCase()}`);
|
searchParams.append("operation", `eq.${operationFilter.toUpperCase()}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const constructedFetchUrl = `${baseFetchUrl}&${searchParams.toString()}`;
|
const constructedFetchUrl = `${baseFetchUrl}&${searchParams.toString()}&limit=50&offset=${resultOffset}`;
|
||||||
|
|
||||||
const changeLogData = await fetch(constructedFetchUrl, {
|
const changeLogData = await fetch(constructedFetchUrl, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
|
|||||||
@@ -42,6 +42,8 @@
|
|||||||
const { user, change_log, media, ...restTables } = tables;
|
const { user, change_log, media, ...restTables } = tables;
|
||||||
resources = restTables;
|
resources = restTables;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let logsSection: HTMLElement;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<WebsiteEditor
|
<WebsiteEditor
|
||||||
@@ -50,14 +52,14 @@
|
|||||||
title={data.website.title}
|
title={data.website.title}
|
||||||
previewContent={data.home.main_content}
|
previewContent={data.home.main_content}
|
||||||
>
|
>
|
||||||
<section id="logs">
|
<section id="logs" bind:this={logsSection}>
|
||||||
<hgroup>
|
<hgroup>
|
||||||
<h2>
|
<h2>
|
||||||
<a href="#logs">Logs</a>
|
<a href="#logs">Logs</a>
|
||||||
</h2>
|
</h2>
|
||||||
<p>
|
<p>
|
||||||
<strong>{data.resultChangeLogCount}</strong>
|
<strong>{data.resultChangeLogCount.toLocaleString("en", { useGrouping: true })}</strong>
|
||||||
<small>results</small>
|
<small>result(s)</small>
|
||||||
</p>
|
</p>
|
||||||
</hgroup>
|
</hgroup>
|
||||||
<details>
|
<details>
|
||||||
@@ -111,6 +113,7 @@
|
|||||||
>
|
>
|
||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
|
<input type="hidden" name="logs_results_page" value={1} />
|
||||||
<button type="submit">Submit</button>
|
<button type="submit">Submit</button>
|
||||||
</form>
|
</form>
|
||||||
</details>
|
</details>
|
||||||
@@ -155,6 +158,106 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
{#snippet commonFilterInputs()}
|
||||||
|
<input
|
||||||
|
type="hidden"
|
||||||
|
name="logs_filter_user"
|
||||||
|
value={$page.url.searchParams.get("logs_filter_user")}
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="hidden"
|
||||||
|
name="logs_filter_resource"
|
||||||
|
value={$page.url.searchParams.get("logs_filter_resource")}
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="hidden"
|
||||||
|
name="logs_filter_operation"
|
||||||
|
value={$page.url.searchParams.get("logs_filter_operation")}
|
||||||
|
/>
|
||||||
|
{/snippet}
|
||||||
|
<div class="pagination">
|
||||||
|
<p>
|
||||||
|
{$page.url.searchParams.get("logs_results_page") ?? 1} / {Math.max(
|
||||||
|
Math.floor(data.resultChangeLogCount / 50),
|
||||||
|
1
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
<form method="GET" onsubmit={() => logsSection.scrollIntoView()}>
|
||||||
|
<input type="hidden" name="logs_results_page" value={1} />
|
||||||
|
{@render commonFilterInputs()}
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
disabled={($page.url.searchParams.get("logs_results_page") ?? "1") === "1"}
|
||||||
|
>First</button
|
||||||
|
>
|
||||||
|
</form>
|
||||||
|
<form method="GET" onsubmit={() => logsSection.scrollIntoView()}>
|
||||||
|
<input
|
||||||
|
type="hidden"
|
||||||
|
name="logs_results_page"
|
||||||
|
value={Math.max(
|
||||||
|
1,
|
||||||
|
Number.parseInt($page.url.searchParams.get("logs_results_page") ?? "1") - 1
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
{@render commonFilterInputs()}
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
disabled={($page.url.searchParams.get("logs_results_page") ?? "1") === "1"}
|
||||||
|
>Previous</button
|
||||||
|
>
|
||||||
|
</form>
|
||||||
|
<form method="GET" onsubmit={() => logsSection.scrollIntoView()}>
|
||||||
|
<input
|
||||||
|
type="hidden"
|
||||||
|
name="logs_results_page"
|
||||||
|
value={Math.min(
|
||||||
|
Math.max(Math.floor(data.resultChangeLogCount / 50), 1),
|
||||||
|
Number.parseInt($page.url.searchParams.get("logs_results_page") ?? "1") + 1
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
{@render commonFilterInputs()}
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
disabled={($page.url.searchParams.get("logs_results_page") ?? "1") ===
|
||||||
|
Math.max(Math.floor(data.resultChangeLogCount / 50), 1).toString()}>Next</button
|
||||||
|
>
|
||||||
|
</form>
|
||||||
|
<form method="GET" onsubmit={() => logsSection.scrollIntoView()}>
|
||||||
|
<input
|
||||||
|
type="hidden"
|
||||||
|
name="logs_results_page"
|
||||||
|
value={Math.max(Math.floor(data.resultChangeLogCount / 50), 1)}
|
||||||
|
/>
|
||||||
|
{@render commonFilterInputs()}
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
disabled={($page.url.searchParams.get("logs_results_page") ?? "1") ===
|
||||||
|
Math.max(Math.floor(data.resultChangeLogCount / 50), 1).toString()}>Last</button
|
||||||
|
>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</WebsiteEditor>
|
</WebsiteEditor>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.pagination {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-inline: var(--space-2xs);
|
||||||
|
margin-block: var(--space-s);
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: var(--space-xs);
|
||||||
|
justify-content: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination > form:first-of-type {
|
||||||
|
margin-inline-start: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
button[disabled] {
|
||||||
|
opacity: 0.5;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -3,20 +3,11 @@
|
|||||||
import { page } from "$app/stores";
|
import { page } from "$app/stores";
|
||||||
import type { LayoutServerData } from "./$types";
|
import type { LayoutServerData } from "./$types";
|
||||||
import type { Snippet } from "svelte";
|
import type { Snippet } from "svelte";
|
||||||
import { beforeNavigate, afterNavigate } from "$app/navigation";
|
import { navigating } from "$app/stores";
|
||||||
import LoadingSpinner from "$lib/components/LoadingSpinner.svelte";
|
import LoadingSpinner from "$lib/components/LoadingSpinner.svelte";
|
||||||
|
|
||||||
const { data, children }: { data: LayoutServerData; children: Snippet } = $props();
|
const { data, children }: { data: LayoutServerData; children: Snippet } = $props();
|
||||||
|
|
||||||
let loading = $state(false);
|
|
||||||
|
|
||||||
beforeNavigate(() => {
|
|
||||||
loading = true;
|
|
||||||
});
|
|
||||||
afterNavigate(() => {
|
|
||||||
loading = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
const isProjectRoute = $derived($page.url.pathname.startsWith("/website") && !$page.error);
|
const isProjectRoute = $derived($page.url.pathname.startsWith("/website") && !$page.error);
|
||||||
const routeName = $derived(
|
const routeName = $derived(
|
||||||
$page.url.pathname === "/"
|
$page.url.pathname === "/"
|
||||||
@@ -25,7 +16,7 @@
|
|||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if loading}
|
{#if $navigating && ["link", "goto"].includes($navigating.type)}
|
||||||
<LoadingSpinner />
|
<LoadingSpinner />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user