diff --git a/.forgejo/workflows/ci.yaml b/.forgejo/workflows/ci.yaml
index d2ea852..e6dfd6e 100644
--- a/.forgejo/workflows/ci.yaml
+++ b/.forgejo/workflows/ci.yaml
@@ -50,7 +50,6 @@ jobs:
id: e2etest
run: |
pnpm run build -l silent
- npx playwright install chromium
pnpm run test:e2e
- name: 💢 Upload E2E report
if: ${{ failure() && steps.e2etest.conclusion == 'failure' }}
@@ -68,7 +67,7 @@ jobs:
- name: 👁️ Checkout repository
uses: actions/checkout@v4
with:
- fetch-depth: 1 # important to fetch tag logs
+ fetch-depth: 0
- name: 📦 pnpm install
run: pnpm install
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e50f81d..bda8d0a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,22 +3,6 @@
All notable changes to this project will be documented in this file.
-## [v0.3.4](https://code.thetadev.de/HSA/Visitenbuch/compare/v0.3.3..v0.3.4) - 2024-05-16
-
-### 🚀 Features
-
-- Select table entries on doubleclick - ([c6abf63](https://code.thetadev.de/HSA/Visitenbuch/commit/c6abf633f8ae5e9b562dda36f9f7ab4d6adcb4e1))
-
-### 🐛 Bug Fixes
-
-- Escape HTML for licenses file - ([f76e7fd](https://code.thetadev.de/HSA/Visitenbuch/commit/f76e7fd97f62d9b41ecbabc3334c2c1876be253d))
-- Use btn-id class for all tables - ([d5e9a94](https://code.thetadev.de/HSA/Visitenbuch/commit/d5e9a9469f0c57939367141985a97d8404fd6fbe))
-- Avoid global state, use context for savedFilters - ([a4eebb9](https://code.thetadev.de/HSA/Visitenbuch/commit/a4eebb944f55da8e87cc899eebada0bd3fd37aa8))
-- Close autocomplete on defocus - ([4a3155c](https://code.thetadev.de/HSA/Visitenbuch/commit/4a3155c33aa354973d4e0ca3ffeab2b7fd442040))
-- Remove process.on hooks (not necessary) - ([cdb3446](https://code.thetadev.de/HSA/Visitenbuch/commit/cdb344609cde80084876faea9f80e7b26b01d0f2))
-- Autocomplete not closing on tab - ([88a5040](https://code.thetadev.de/HSA/Visitenbuch/commit/88a5040f9c4e19ae3efb5ad0894c8dc5b905a92e))
-
-
## [v0.3.3](https://code.thetadev.de/HSA/Visitenbuch/compare/v0.3.2..v0.3.3) - 2024-05-14
### 🚀 Features
diff --git a/package.json b/package.json
index 722de0f..bc6e46c 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "visitenbuch",
- "version": "0.3.4",
+ "version": "0.3.3",
"private": true,
"license": "AGPL-3.0",
"scripts": {
diff --git a/src/app.html b/src/app.html
index 50038b5..5f0dd88 100644
--- a/src/app.html
+++ b/src/app.html
@@ -1,5 +1,5 @@
-
+
diff --git a/src/hooks.server.ts b/src/hooks.server.ts
index 87c81a0..a7fddf5 100644
--- a/src/hooks.server.ts
+++ b/src/hooks.server.ts
@@ -31,3 +31,7 @@ export const handle = sequence(
authorization,
createTRPCHandle({ router, createContext }),
);
+
+// Allow server application to exit
+process.on("SIGINT", () => process.exit()); // Ctrl+C
+process.on("SIGTERM", () => process.exit()); // docker stop
diff --git a/src/lib/components/filter/Autocomplete.svelte b/src/lib/components/filter/Autocomplete.svelte
index 7a20f6d..f1a7885 100644
--- a/src/lib/components/filter/Autocomplete.svelte
+++ b/src/lib/components/filter/Autocomplete.svelte
@@ -166,14 +166,6 @@
if (opened) {
onClose(kb);
}
- // select remaining item if autoselect is enabled
- if (!selection) {
- if (!noAutoselect1 && filteredItems.length === 1) {
- selectListItem(filteredItems[0], true);
- } else {
- setInputValue("");
- }
- }
opened = false;
}
@@ -193,38 +185,43 @@
}
function onKeyDown(e: KeyboardEvent): void {
- switch (e.key) {
- case "Tab":
- close();
- break;
- case "ArrowDown":
+ let { key } = e;
+ if (key === "Tab" && e.shiftKey) key = "ShiftTab";
+ const fnmap: Record void> = {
+ Tab: () => close,
+ ShiftTab: () => close,
+ ArrowDown: () => {
open();
if (highlightIndex < filteredItems.length - 1) {
highlightIndex++;
highlight();
}
- break;
- case "ArrowUp":
+ },
+ ArrowUp: () => {
open();
if (highlightIndex > 0) {
highlightIndex--;
highlight();
}
- break;
- case "Escape":
+ },
+ Escape: () => {
e.stopPropagation();
if (opened) {
if (inputElm) inputElm.focus();
close();
}
- break;
- case "Backspace":
+ },
+ Backspace: () => {
if (inputValue().length === 0) {
onBackspace();
} else if (selection) {
clearSelection();
}
- break;
+ },
+ };
+ const fn = fnmap[key];
+ if (typeof fn === "function") {
+ fn();
}
}
@@ -237,6 +234,16 @@
}
}
+ function onBlur(): void {
+ if (!selection) {
+ if (!noAutoselect1 && filteredItems.length === 1) {
+ selectListItem(filteredItems[0], true);
+ } else {
+ setInputValue("");
+ }
+ }
+ }
+
function highlight(): void {
if (browser && opened) {
window.setTimeout(() => {
@@ -296,11 +303,12 @@
on:focus={open}
on:keydown={onKeyDown}
on:keypress={onKeyPress}
+ on:blur={onBlur}
use:floatingRef
/>
{#if opened && filteredItems.length > 0}
-
+
{#each filteredItems as item, i}
-
+
{/if}
diff --git a/src/lib/components/filter/SavedFilters.svelte b/src/lib/components/filter/SavedFilters.svelte
index 20baa2c..5854b2b 100644
--- a/src/lib/components/filter/SavedFilters.svelte
+++ b/src/lib/components/filter/SavedFilters.svelte
@@ -8,14 +8,12 @@
import { toastError, toastInfo } from "$lib/shared/util/toast";
import Icon from "$lib/components/ui/Icon.svelte";
- import { getSavedFilters } from "$lib/stores";
+ import { savedFilters } from "$lib/stores";
import Chip from "./SavedFilterChip.svelte";
export let view: string;
- const savedFilters = getSavedFilters();
-
$: filters = $savedFilters[view] ?? [];
function getQuery(): string {
diff --git a/src/lib/components/table/EntryTable.svelte b/src/lib/components/table/EntryTable.svelte
index 4af0262..42c2990 100644
--- a/src/lib/components/table/EntryTable.svelte
+++ b/src/lib/components/table/EntryTable.svelte
@@ -1,6 +1,4 @@
diff --git a/src/routes/(app)/+page.svelte b/src/routes/(app)/+page.svelte
index 1c155e1..e840d93 100644
--- a/src/routes/(app)/+page.svelte
+++ b/src/routes/(app)/+page.svelte
@@ -4,11 +4,9 @@
import { defaultFilterUrl } from "$lib/shared/util";
- import { getSavedFilters } from "$lib/stores";
+ import { savedFilters } from "$lib/stores";
export let data: PageData;
-
- const savedFilters = getSavedFilters();
diff --git a/src/routes/(app)/rooms/+page.svelte b/src/routes/(app)/rooms/+page.svelte
index 5f7d2a6..513a06f 100644
--- a/src/routes/(app)/rooms/+page.svelte
+++ b/src/routes/(app)/rooms/+page.svelte
@@ -27,7 +27,7 @@
{#each data.rooms as room (room.id)}
- {room.name} |
+ {room.name} |
{room.station.name} |
{/each}
diff --git a/src/routes/(app)/stations/+page.svelte b/src/routes/(app)/stations/+page.svelte
index e94e7bf..010080e 100644
--- a/src/routes/(app)/stations/+page.svelte
+++ b/src/routes/(app)/stations/+page.svelte
@@ -27,7 +27,7 @@
{#each data.stations as station (station.id)}
- {station.name}
+ {station.name}
|
{/each}
diff --git a/vite.config.ts b/vite.config.ts
index 195765a..9d34322 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -23,8 +23,7 @@ export default defineConfig({
createViteLicensePlugin({
additionalFiles: {
"oss-licenses.html": (packages) => {
- let res = `
-
+ let res = `
Visitenbuch - Lizenzen
@@ -32,12 +31,6 @@ export default defineConfig({
Open-Source-Lizenzen
JSON-formatted license list
`;
- const escapeHTML = (s: string | null) => s ? s.replaceAll("&", "&")
- .replaceAll("<", "<")
- .replaceAll(">", ">")
- .replaceAll('"', """)
- .replaceAll("'", "'") : "";
-
for (const _p of packages) {
type LicenseMetaExt = LicenseMeta & {
repository: string | null,
@@ -61,13 +54,13 @@ export default defineConfig({
}
res += `\n`;
- res += `
\n`;
+ res += `
\n`;
res += `
\n`;
- res += `Version: | ${escapeHTML(p.version)} |
\n`;
- if (aut) res += `Author: | ${escapeHTML(aut)} |
\n`;
- res += `License: | ${escapeHTML(p.license)} |
\n`;
- if (repoUrl) res += `Repository: | ${escapeHTML(repoUrl)} |
\n`;
- else if (rp) res += `Repository: | ${escapeHTML(rp)} |
\n`;
+ res += `Version: | ${p.version} |
\n`;
+ if (aut) res += `Author: | ${aut} |
\n`;
+ res += `License: | ${p.license} |
\n`;
+ if (repoUrl) res += `Repository: | ${repoUrl} |
\n`;
+ else if (rp) res += `Repository: | ${rp} |
\n`;
res += `
\n`;
res += "
";
}