fix list fetch timeout (#701)
* fix list fetch timeout * list search modal added (replaces list select modal) * query startsWith -> includes --------- Co-authored-by: Christian Beutel <>
This commit is contained in:
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
maxSearchLength?: number;
|
maxSearchLength?: number;
|
||||||
|
timeBetweenUpdates?: number,
|
||||||
value?: string;
|
value?: string;
|
||||||
items?: SearchItem[];
|
items?: SearchItem[];
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
@@ -29,6 +30,7 @@
|
|||||||
|
|
||||||
let {
|
let {
|
||||||
maxSearchLength = 5,
|
maxSearchLength = 5,
|
||||||
|
timeBetweenUpdates = 500,
|
||||||
value = $bindable(""),
|
value = $bindable(""),
|
||||||
items = $bindable([]),
|
items = $bindable([]),
|
||||||
placeholder = "Search...",
|
placeholder = "Search...",
|
||||||
@@ -57,7 +59,7 @@
|
|||||||
}
|
}
|
||||||
typingTimer = setTimeout(() => {
|
typingTimer = setTimeout(() => {
|
||||||
update(value);
|
update(value);
|
||||||
}, 500);
|
}, timeBetweenUpdates);
|
||||||
}
|
}
|
||||||
|
|
||||||
function update(q: string) {
|
function update(q: string) {
|
||||||
|
|||||||
243
web/src/lib/components/list/list_search_modal.svelte
Normal file
243
web/src/lib/components/list/list_search_modal.svelte
Normal file
@@ -0,0 +1,243 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { type Snippet } from "svelte";
|
||||||
|
|
||||||
|
import type { List } from "$lib/models/list";
|
||||||
|
import type { Trail } from "$lib/models/trail";
|
||||||
|
import { trail } from "$lib/stores/trail_store";
|
||||||
|
import { getFileURL } from "$lib/util/file_util";
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
import Modal from "../base/modal.svelte";
|
||||||
|
import Search, { type SearchItem } from "../base/search.svelte";
|
||||||
|
import { theme } from "$lib/stores/theme_store";
|
||||||
|
import emptyStateTrailDark from "$lib/assets/svgs/empty_states/empty_state_trail_dark.svg";
|
||||||
|
import emptyStateTrailLight from "$lib/assets/svgs/empty_states/empty_state_trail_light.svg";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
lists?: List[];
|
||||||
|
trails?: Set<Trail> | undefined;
|
||||||
|
children?: Snippet<[any]>;
|
||||||
|
onchange?: (list: List) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
let { lists = [], trails, children, onchange }: Props = $props();
|
||||||
|
|
||||||
|
let modal: Modal;
|
||||||
|
let searchItems: SearchItem[] = $state([]);
|
||||||
|
let query = $state("");
|
||||||
|
let listsVersion = $state(0);
|
||||||
|
|
||||||
|
export function openModal() {
|
||||||
|
searchItems = [];
|
||||||
|
query = "";
|
||||||
|
modal.openModal();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSelect(list: List) {
|
||||||
|
const containsAll = listContainsAllTrails(list);
|
||||||
|
onchange?.(list);
|
||||||
|
|
||||||
|
if (containsAll) {
|
||||||
|
removeTrailsFromList(list);
|
||||||
|
} else {
|
||||||
|
addTrailsToList(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
listsVersion += 1;
|
||||||
|
updateLists(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleRemove(list: List) {
|
||||||
|
onchange?.(list);
|
||||||
|
|
||||||
|
removeTrailsFromList(list);
|
||||||
|
|
||||||
|
listsVersion += 1;
|
||||||
|
updateLists(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
function listContainsAllTrails(list: List): boolean {
|
||||||
|
if (trails === undefined) {
|
||||||
|
return listContainsCurrentTrail(list) ?? false;
|
||||||
|
} else if (list.trails !== undefined) {
|
||||||
|
for (const lTrail of trails) {
|
||||||
|
if (!list.trails!.includes(lTrail.id!)) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function listContainsCurrentTrail(list: List) {
|
||||||
|
return list.trails?.includes($trail.id!);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSelectedTrailIds(): string[] {
|
||||||
|
if (trails !== undefined) {
|
||||||
|
return Array.from(trails)
|
||||||
|
.map((lTrail) => lTrail.id)
|
||||||
|
.filter((id): id is string => Boolean(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $trail?.id ? [$trail.id] : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function addTrailsToList(list: List) {
|
||||||
|
const selectedTrailIds = getSelectedTrailIds();
|
||||||
|
if (!selectedTrailIds.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
list.trails ??= [];
|
||||||
|
for (const id of selectedTrailIds) {
|
||||||
|
if (!list.trails.includes(id)) {
|
||||||
|
list.trails = [...list.trails, id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeTrailsFromList(list: List) {
|
||||||
|
const selectedTrailIds = getSelectedTrailIds();
|
||||||
|
if (!selectedTrailIds.length || !list.trails?.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
list.trails = list.trails.filter(
|
||||||
|
(id) => !selectedTrailIds.includes(id),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const listsContainingTrails = $derived.by(() =>
|
||||||
|
lists.filter((list) => {
|
||||||
|
listsVersion;
|
||||||
|
return listContainsAllTrails(list);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
const showNoListHint = $derived.by(() => {
|
||||||
|
if (query.trim().length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trails !== undefined) {
|
||||||
|
return trails.size > 0 && listsContainingTrails.length === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Boolean($trail?.id) && listsContainingTrails.length === 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
function updateLists(q: string) {
|
||||||
|
query = q;
|
||||||
|
const normalizedQuery = q.trim().toLowerCase();
|
||||||
|
if (!normalizedQuery.length) {
|
||||||
|
searchItems = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
searchItems = lists
|
||||||
|
.filter((list) => {
|
||||||
|
const name = list.name?.toLowerCase() ?? "";
|
||||||
|
return (
|
||||||
|
name.includes(normalizedQuery) &&
|
||||||
|
!listContainsAllTrails(list)
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.map((list) => ({
|
||||||
|
text: list.name,
|
||||||
|
description: list.description,
|
||||||
|
value: list,
|
||||||
|
icon: list.avatar
|
||||||
|
? getFileURL(list, list.avatar)
|
||||||
|
: $theme === "light"
|
||||||
|
? emptyStateTrailLight
|
||||||
|
: emptyStateTrailDark,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
const children_render = $derived(children);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Modal
|
||||||
|
id="list-search-modal"
|
||||||
|
title={$_("select-list")}
|
||||||
|
size="md:min-w-sm"
|
||||||
|
bind:this={modal}
|
||||||
|
>
|
||||||
|
{#snippet children({ openModal })}
|
||||||
|
{@render children_render?.({ openModal })}
|
||||||
|
{/snippet}
|
||||||
|
{#snippet content()}
|
||||||
|
<div class="space-y-4 min-h-40">
|
||||||
|
<Search
|
||||||
|
onupdate={(q) => updateLists(q)}
|
||||||
|
timeBetweenUpdates={0}
|
||||||
|
onclick={(item) => handleSelect(item.value)}
|
||||||
|
placeholder={$_("search-list")}
|
||||||
|
items={searchItems}
|
||||||
|
bind:value={query}
|
||||||
|
>
|
||||||
|
{#snippet prepend({ item })}
|
||||||
|
<img
|
||||||
|
class="rounded-full w-8 aspect-square mr-2"
|
||||||
|
src={item.icon}
|
||||||
|
alt="avatar"
|
||||||
|
/>
|
||||||
|
{/snippet}
|
||||||
|
</Search>
|
||||||
|
{#if query.trim().length && searchItems.length === 0}
|
||||||
|
<p class="text-sm text-gray-500 text-center">
|
||||||
|
{$_("no-results")}
|
||||||
|
</p>
|
||||||
|
{/if}
|
||||||
|
{#if listsContainingTrails.length}
|
||||||
|
<div class="space-y-2">
|
||||||
|
<h4 class="text-sm font-semibold text-gray-500">
|
||||||
|
{$_("linked-lists")}
|
||||||
|
</h4>
|
||||||
|
{#each listsContainingTrails as list}
|
||||||
|
<div
|
||||||
|
class="w-full flex items-center gap-4 p-4 rounded-xl bg-menu-item-background"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
class="w-12 aspect-square rounded-full"
|
||||||
|
src={list.avatar
|
||||||
|
? getFileURL(list, list.avatar)
|
||||||
|
: $theme === "light"
|
||||||
|
? emptyStateTrailLight
|
||||||
|
: emptyStateTrailDark}
|
||||||
|
alt="avatar"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<h5 class="text-md font-semibold text-left">
|
||||||
|
{list.name}
|
||||||
|
</h5>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="ml-auto btn-icon text-red-500"
|
||||||
|
onclick={() => handleRemove(list)}
|
||||||
|
type="button"
|
||||||
|
aria-label={$_("unlink")}
|
||||||
|
>
|
||||||
|
<i class="fa fa-trash"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
{:else if showNoListHint}
|
||||||
|
<div class="min-h-20 flex items-center justify-center">
|
||||||
|
<p class="text-sm text-gray-500 text-center">
|
||||||
|
{$_("trail-not-in-list")}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/snippet}
|
||||||
|
{#snippet footer({ closeModal })}
|
||||||
|
<div class="flex justify-end">
|
||||||
|
<button class="btn-primary" onclick={closeModal}>
|
||||||
|
{$_("close")}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{/snippet}
|
||||||
|
</Modal>
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import { type Snippet } from "svelte";
|
|
||||||
|
|
||||||
import type { List } from "$lib/models/list";
|
|
||||||
import type { Trail } from "$lib/models/trail";
|
|
||||||
import { trail } from "$lib/stores/trail_store";
|
|
||||||
import { getFileURL } from "$lib/util/file_util";
|
|
||||||
import { _ } from "svelte-i18n";
|
|
||||||
import Modal from "../base/modal.svelte";
|
|
||||||
import { theme } from "$lib/stores/theme_store";
|
|
||||||
import emptyStateTrailDark from "$lib/assets/svgs/empty_states/empty_state_trail_dark.svg";
|
|
||||||
import emptyStateTrailLight from "$lib/assets/svgs/empty_states/empty_state_trail_light.svg";
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
lists: List[];
|
|
||||||
trails?: Set<Trail> | undefined;
|
|
||||||
children?: Snippet<[any]>;
|
|
||||||
onchange?: (list: List) => void
|
|
||||||
}
|
|
||||||
|
|
||||||
let { lists, trails, children, onchange }: Props = $props();
|
|
||||||
|
|
||||||
let modal: Modal;
|
|
||||||
|
|
||||||
export function openModal() {
|
|
||||||
modal.openModal();
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleSelect(list: List) {
|
|
||||||
onchange?.(list);
|
|
||||||
modal.closeModal!();
|
|
||||||
}
|
|
||||||
|
|
||||||
function listContainsAllTrails(list: List) : boolean {
|
|
||||||
if (trails === undefined) {
|
|
||||||
return listContainsCurrentTrail(list) ?? false;
|
|
||||||
} else if (list.trails !== undefined) {
|
|
||||||
for (const lTrail of trails) {
|
|
||||||
if (!list.trails!.includes(lTrail.id!)) return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function listContainsCurrentTrail(list: List) {
|
|
||||||
return list.trails?.includes($trail.id!);
|
|
||||||
}
|
|
||||||
|
|
||||||
const children_render = $derived(children);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<Modal
|
|
||||||
id="list-modal"
|
|
||||||
title={$_("select-list")}
|
|
||||||
size="md:min-w-sm"
|
|
||||||
bind:this={modal}
|
|
||||||
>
|
|
||||||
{#snippet children({ openModal })}
|
|
||||||
{@render children_render?.({ openModal })}
|
|
||||||
{/snippet}
|
|
||||||
{#snippet content()}
|
|
||||||
<ul>
|
|
||||||
{#each lists as list}
|
|
||||||
<li
|
|
||||||
class="flex gap-4 items-center p-4 hover:bg-menu-item-background-hover rounded-xl transition-colors cursor-pointer"
|
|
||||||
onclick={() => handleSelect(list)}
|
|
||||||
role="presentation"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
class="w-12 aspect-square rounded-full"
|
|
||||||
src={list.avatar
|
|
||||||
? getFileURL(list, list.avatar)
|
|
||||||
: $theme === "light"
|
|
||||||
? emptyStateTrailLight
|
|
||||||
: emptyStateTrailDark}
|
|
||||||
alt="avatar"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<h5 class="text-md font-semibold">{list.name}</h5>
|
|
||||||
|
|
||||||
<i
|
|
||||||
class="fa fa-{listContainsAllTrails(list)
|
|
||||||
? 'minus'
|
|
||||||
: 'plus'} rounded-full border border-input-border p-2"
|
|
||||||
></i>
|
|
||||||
</li>
|
|
||||||
{/each}
|
|
||||||
</ul>
|
|
||||||
{/snippet}
|
|
||||||
</Modal>
|
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import Dropdown, { type DropdownItem } from "../base/dropdown.svelte";
|
import Dropdown, { type DropdownItem } from "../base/dropdown.svelte";
|
||||||
import ConfirmModal from "../confirm_modal.svelte";
|
import ConfirmModal from "../confirm_modal.svelte";
|
||||||
import ListSelectModal from "../list/list_select_modal.svelte";
|
import ListSearchModal from "../list/list_search_modal.svelte";
|
||||||
import TrailExportModal from "./trail_export_modal.svelte";
|
import TrailExportModal from "./trail_export_modal.svelte";
|
||||||
import TrailShareModal from "./trail_share_modal.svelte";
|
import TrailShareModal from "./trail_share_modal.svelte";
|
||||||
import { handleFromRecordWithIRI } from "$lib/util/activitypub_util";
|
import { handleFromRecordWithIRI } from "$lib/util/activitypub_util";
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
let { trails, mode, toggle, onDelete, onShare }: Props = $props();
|
let { trails, mode, toggle, onDelete, onShare }: Props = $props();
|
||||||
|
|
||||||
let confirmModal: ConfirmModal;
|
let confirmModal: ConfirmModal;
|
||||||
let listSelectModal: ListSelectModal;
|
let listSelectModal: ListSearchModal;
|
||||||
let trailExportModal: TrailExportModal;
|
let trailExportModal: TrailExportModal;
|
||||||
let trailShareModal: TrailShareModal;
|
let trailShareModal: TrailShareModal;
|
||||||
|
|
||||||
@@ -436,12 +436,12 @@
|
|||||||
bind:this={confirmModal}
|
bind:this={confirmModal}
|
||||||
onconfirm={deleteTrails}
|
onconfirm={deleteTrails}
|
||||||
></ConfirmModal>
|
></ConfirmModal>
|
||||||
<ListSelectModal
|
<ListSearchModal
|
||||||
{lists}
|
{lists}
|
||||||
trails={getTrails()}
|
trails={getTrails()}
|
||||||
bind:this={listSelectModal}
|
bind:this={listSelectModal}
|
||||||
onchange={(list) => handleListSelection(list)}
|
onchange={(list) => handleListSelection(list)}
|
||||||
></ListSelectModal>
|
></ListSearchModal>
|
||||||
<TrailExportModal
|
<TrailExportModal
|
||||||
bind:this={trailExportModal}
|
bind:this={trailExportModal}
|
||||||
onexport={(settings) => exportTrails(settings)}
|
onexport={(settings) => exportTrails(settings)}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
"activity": "{n, plural, =1 {Aktivität} other {Aktivitäten}}",
|
"activity": "{n, plural, =1 {Aktivität} other {Aktivitäten}}",
|
||||||
"add-bio": "Bio hinzufügen",
|
"add-bio": "Bio hinzufügen",
|
||||||
"add-entry": "Eintrag hinzufügen",
|
"add-entry": "Eintrag hinzufügen",
|
||||||
"add-to-list": "Zu Liste hinzufügen",
|
"add-to-list": "Listen verwalten",
|
||||||
"add-waypoint": "Wegpunkt hinzufügen",
|
"add-waypoint": "Wegpunkt hinzufügen",
|
||||||
"added-trail-to": "Route hinzugefügt zu",
|
"added-trail-to": "Route hinzugefügt zu",
|
||||||
"added-trails-to": "Routen hinzugefügt zu",
|
"added-trails-to": "Routen hinzugefügt zu",
|
||||||
@@ -220,6 +220,7 @@
|
|||||||
"likes": "Likes",
|
"likes": "Likes",
|
||||||
"limited": "Begrenzt",
|
"limited": "Begrenzt",
|
||||||
"link-copied": "Link kopiert!",
|
"link-copied": "Link kopiert!",
|
||||||
|
"linked-lists": "Verknüpfte Listen",
|
||||||
"list": "{n, plural, =1 {Liste} other {Listen}}",
|
"list": "{n, plural, =1 {Liste} other {Listen}}",
|
||||||
"list-not-shared": "Mit niemandem geteilt",
|
"list-not-shared": "Mit niemandem geteilt",
|
||||||
"list-public-warning": "Alle Routen in dieser Liste werden veröffentlicht.",
|
"list-public-warning": "Alle Routen in dieser Liste werden veröffentlicht.",
|
||||||
@@ -403,7 +404,9 @@
|
|||||||
"tourism": "Tourismus",
|
"tourism": "Tourismus",
|
||||||
"trail": "{n, plural, =1 {Route} other {Routen}}",
|
"trail": "{n, plural, =1 {Route} other {Routen}}",
|
||||||
"trail-not-shared": "Mit niemandem geteilt",
|
"trail-not-shared": "Mit niemandem geteilt",
|
||||||
|
"trail-not-in-list": "Trail gehört zu keiner Liste.",
|
||||||
"trail-saved-successfully": "Route gespeichert",
|
"trail-saved-successfully": "Route gespeichert",
|
||||||
|
"search-list": "Liste suchen",
|
||||||
"trails-for-you": "Routen für dich",
|
"trails-for-you": "Routen für dich",
|
||||||
"tram-stop": "Tram Haltestelle",
|
"tram-stop": "Tram Haltestelle",
|
||||||
"unchanged": "unverändert",
|
"unchanged": "unverändert",
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
"activity": "{n, plural, =1 {Activity} other {Activities}}",
|
"activity": "{n, plural, =1 {Activity} other {Activities}}",
|
||||||
"add-bio": "Add Bio",
|
"add-bio": "Add Bio",
|
||||||
"add-entry": "Add Entry",
|
"add-entry": "Add Entry",
|
||||||
"add-to-list": "Add to list",
|
"add-to-list": "Manage lists",
|
||||||
"add-waypoint": "Add Waypoint",
|
"add-waypoint": "Add Waypoint",
|
||||||
"added-trail-to": "Added trail to",
|
"added-trail-to": "Added trail to",
|
||||||
"added-trails-to": "Added trails to",
|
"added-trails-to": "Added trails to",
|
||||||
@@ -220,6 +220,7 @@
|
|||||||
"likes": "Likes",
|
"likes": "Likes",
|
||||||
"limited": "Limited",
|
"limited": "Limited",
|
||||||
"link-copied": "Link copied!",
|
"link-copied": "Link copied!",
|
||||||
|
"linked-lists": "Linked lists",
|
||||||
"list": "{n, plural, =1 {List} other {Lists}}",
|
"list": "{n, plural, =1 {List} other {Lists}}",
|
||||||
"list-not-shared": "Not shared with anyone",
|
"list-not-shared": "Not shared with anyone",
|
||||||
"list-public-warning": "All trails in this list will become public.",
|
"list-public-warning": "All trails in this list will become public.",
|
||||||
@@ -403,7 +404,9 @@
|
|||||||
"tourism": "Tourism",
|
"tourism": "Tourism",
|
||||||
"trail": "{n, plural, =1 {Trail} other {Trails}}",
|
"trail": "{n, plural, =1 {Trail} other {Trails}}",
|
||||||
"trail-not-shared": "Not shared with anyone",
|
"trail-not-shared": "Not shared with anyone",
|
||||||
|
"trail-not-in-list": "Trail is not in any list",
|
||||||
"trail-saved-successfully": "Trail saved successfully",
|
"trail-saved-successfully": "Trail saved successfully",
|
||||||
|
"search-list": "Search list",
|
||||||
"trails-for-you": "Trails for you",
|
"trails-for-you": "Trails for you",
|
||||||
"tram-stop": "Tram stop",
|
"tram-stop": "Tram stop",
|
||||||
"unchanged": "unchanged",
|
"unchanged": "unchanged",
|
||||||
|
|||||||
@@ -47,11 +47,12 @@ export enum Collection {
|
|||||||
export async function list<T>(event: RequestEvent, collection: Collection) {
|
export async function list<T>(event: RequestEvent, collection: Collection) {
|
||||||
const searchParams = Object.fromEntries(event.url.searchParams);
|
const searchParams = Object.fromEntries(event.url.searchParams);
|
||||||
const safeSearchParams = RecordListOptionsSchema.parse(searchParams);
|
const safeSearchParams = RecordListOptionsSchema.parse(searchParams);
|
||||||
|
const { perPage, page, ...opts } = safeSearchParams;
|
||||||
|
|
||||||
let r: ListResult<T>;
|
let r: ListResult<T>;
|
||||||
if ((safeSearchParams.perPage ?? 0) < 0) {
|
if ((safeSearchParams.perPage ?? 0) < 0) {
|
||||||
const activities: T[] = await event.locals.pb.collection(Collection[collection])
|
const activities: T[] = await event.locals.pb.collection(Collection[collection])
|
||||||
.getFullList<T>(safeSearchParams)
|
.getFullList<T>({...opts})
|
||||||
r = {
|
r = {
|
||||||
items: activities,
|
items: activities,
|
||||||
perPage: -1,
|
perPage: -1,
|
||||||
@@ -61,7 +62,7 @@ export async function list<T>(event: RequestEvent, collection: Collection) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
r = await event.locals.pb.collection(Collection[collection])
|
r = await event.locals.pb.collection(Collection[collection])
|
||||||
.getList<T>(safeSearchParams.page, safeSearchParams.perPage, { ...safeSearchParams })
|
.getList<T>(page, perPage, opts)
|
||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
@@ -163,4 +164,4 @@ export function handleError(e: any) {
|
|||||||
} else {
|
} else {
|
||||||
return json({ message: e }, { status: 500 })
|
return json({ message: e }, { status: 500 })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
import Select from "$lib/components/base/select.svelte";
|
import Select from "$lib/components/base/select.svelte";
|
||||||
import TextField from "$lib/components/base/text_field.svelte";
|
import TextField from "$lib/components/base/text_field.svelte";
|
||||||
import Toggle from "$lib/components/base/toggle.svelte";
|
import Toggle from "$lib/components/base/toggle.svelte";
|
||||||
import ListSelectModal from "$lib/components/list/list_select_modal.svelte";
|
import ListSearchModal from "$lib/components/list/list_search_modal.svelte";
|
||||||
import SummitLogCard from "$lib/components/summit_log/summit_log_card.svelte";
|
import SummitLogCard from "$lib/components/summit_log/summit_log_card.svelte";
|
||||||
import SummitLogModal from "$lib/components/summit_log/summit_log_modal.svelte";
|
import SummitLogModal from "$lib/components/summit_log/summit_log_modal.svelte";
|
||||||
import MapWithElevationMaplibre from "$lib/components/trail/map_with_elevation_maplibre.svelte";
|
import MapWithElevationMaplibre from "$lib/components/trail/map_with_elevation_maplibre.svelte";
|
||||||
@@ -111,7 +111,7 @@
|
|||||||
|
|
||||||
let waypointModal: WaypointModal;
|
let waypointModal: WaypointModal;
|
||||||
let summitLogModal: SummitLogModal;
|
let summitLogModal: SummitLogModal;
|
||||||
let listSelectModal: ListSelectModal;
|
let listSelectModal: ListSearchModal;
|
||||||
|
|
||||||
let loading = $state(false);
|
let loading = $state(false);
|
||||||
|
|
||||||
@@ -1516,11 +1516,11 @@
|
|||||||
<WaypointModal bind:this={waypointModal} onsave={saveWaypoint}></WaypointModal>
|
<WaypointModal bind:this={waypointModal} onsave={saveWaypoint}></WaypointModal>
|
||||||
<SummitLogModal bind:this={summitLogModal} onsave={(log) => saveSummitLog(log)}
|
<SummitLogModal bind:this={summitLogModal} onsave={(log) => saveSummitLog(log)}
|
||||||
></SummitLogModal>
|
></SummitLogModal>
|
||||||
<ListSelectModal
|
<ListSearchModal
|
||||||
lists={lists.items}
|
lists={lists.items}
|
||||||
bind:this={listSelectModal}
|
bind:this={listSelectModal}
|
||||||
onchange={(e) => handleListSelection(e)}
|
onchange={(e) => handleListSelection(e)}
|
||||||
></ListSelectModal>
|
></ListSearchModal>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
#trail-map {
|
#trail-map {
|
||||||
|
|||||||
Reference in New Issue
Block a user