fix lost gpx on summit log update (#702)

* fix lost gpx on summit log update

* fix missing trail in summit log modal
This commit is contained in:
slothful-vassal
2026-01-11 22:13:39 +01:00
committed by GitHub
parent 9282f37c15
commit 6e5edf7ed7
3 changed files with 45 additions and 11 deletions

View File

@@ -4,6 +4,7 @@
import { SummitLogCreateSchema } from "$lib/models/api/summit_log_schema"; import { SummitLogCreateSchema } from "$lib/models/api/summit_log_schema";
import GPX from "$lib/models/gpx/gpx"; import GPX from "$lib/models/gpx/gpx";
import { summitLog } from "$lib/stores/summit_log_store"; import { summitLog } from "$lib/stores/summit_log_store";
import { fetchGPX } from "$lib/stores/trail_store";
import { cloneDeep } from "$lib/util/deep_util"; import { cloneDeep } from "$lib/util/deep_util";
import { validator } from "@felte/validator-zod"; import { validator } from "@felte/validator-zod";
import { createForm } from "felte"; import { createForm } from "felte";
@@ -45,10 +46,6 @@
initialValues: $summitLog, initialValues: $summitLog,
extend: validator({ schema: ClientSummitLogCreateSchema }), extend: validator({ schema: ClientSummitLogCreateSchema }),
onSubmit: async (form) => { onSubmit: async (form) => {
if (!form.expand?.gpx_data) {
form.gpx = "";
}
if ( if (
!form._photos?.length && !form._photos?.length &&
!form.photos?.length && !form.photos?.length &&
@@ -69,8 +66,6 @@
}, },
}); });
let trailData = $derived($data.expand?.gpx_data);
$effect(() => { $effect(() => {
setFields(cloneDeep($summitLog)); setFields(cloneDeep($summitLog));
}); });
@@ -81,12 +76,42 @@
} }
}); });
let gpxLoading = $state(false);
async function ensureGpxDataLoaded() {
if (gpxLoading || !$data.id || !$data.gpx || $data.expand?.gpx_data) {
return;
}
gpxLoading = true;
try {
const gpxData = await fetchGPX($data as any, fetch);
if (!gpxData) {
return;
}
if (!$data.expand) {
$data.expand = {};
}
$data.expand.gpx_data = gpxData;
} finally {
gpxLoading = false;
}
}
$effect(() => {
void ensureGpxDataLoaded();
});
async function handleTrailSelection(trailData: string | null) { async function handleTrailSelection(trailData: string | null) {
if (!trailData) { if (!trailData) {
$data.duration = undefined; $data.duration = undefined;
$data.elevation_gain = undefined; $data.elevation_gain = undefined;
$data.elevation_loss = undefined; $data.elevation_loss = undefined;
$data.distance = undefined; $data.distance = undefined;
$data.gpx = "";
if ($data.expand) {
$data.expand.gpx_data = undefined;
}
$data._gpx = null;
return; return;
} }
const gpxObject = GPX.parse(trailData); const gpxObject = GPX.parse(trailData);
@@ -141,7 +166,8 @@
{#if $data.expand} {#if $data.expand}
<TrailPicker <TrailPicker
bind:trailFile={$data._gpx} bind:trailFile={$data._gpx}
{trailData} bind:trailData={$data.expand.gpx_data}
hasTrail={Boolean($data.gpx)}
label={$_("trail", { values: { n: 1 } })} label={$_("trail", { values: { n: 1 } })}
onchange={(trail) => handleTrailSelection(trail)} onchange={(trail) => handleTrailSelection(trail)}
></TrailPicker> ></TrailPicker>

View File

@@ -7,6 +7,7 @@
interface Props { interface Props {
trailFile: File | undefined | null; trailFile: File | undefined | null;
trailData: string | undefined; trailData: string | undefined;
hasTrail?: boolean;
label?: string; label?: string;
onchange: (data: string | null) => void; onchange: (data: string | null) => void;
} }
@@ -14,6 +15,7 @@
let { let {
trailFile = $bindable(), trailFile = $bindable(),
trailData = $bindable(), trailData = $bindable(),
hasTrail = false,
label = "", label = "",
onchange onchange
}: Props = $props(); }: Props = $props();
@@ -38,8 +40,12 @@
}); });
} }
const hasTrailState = $derived(
Boolean(trailFile || trailData || hasTrail),
);
function openTrailBrowser() { function openTrailBrowser() {
if (trailData) { if (hasTrailState) {
trailFile = null; trailFile = null;
trailData = undefined; trailData = undefined;
@@ -151,7 +157,7 @@
class="h-28 aspect-square rounded-xl !bg-background border border-input-border-focus hover:!bg-secondary-hover group" class="h-28 aspect-square rounded-xl !bg-background border border-input-border-focus hover:!bg-secondary-hover group"
id="trail-picker-map" id="trail-picker-map"
> >
{#if !trailFile && !trailData} {#if !hasTrailState}
<i class="fa fa-plus text-lg"></i> <i class="fa fa-plus text-lg"></i>
{:else} {:else}
<i <i

View File

@@ -79,7 +79,7 @@ export async function summit_logs_update(oldSummitLog: SummitLog, newSummitLog:
newSummitLog.author = user.actor newSummitLog.author = user.actor
const formData = objectToFormData(newSummitLog, ["expand"]) const formData = objectToFormData(newSummitLog, ["expand", "gpx", "_gpx"])
for (const photo of newSummitLog._photos ?? []) { for (const photo of newSummitLog._photos ?? []) {
formData.append("photos", photo) formData.append("photos", photo)
@@ -93,6 +93,8 @@ export async function summit_logs_update(oldSummitLog: SummitLog, newSummitLog:
if (newSummitLog._gpx) { if (newSummitLog._gpx) {
formData.append("gpx", newSummitLog._gpx); formData.append("gpx", newSummitLog._gpx);
} else if (newSummitLog.gpx === "") {
formData.append("gpx", "");
} }
let r = await fetch('/api/v1/summit-log/form/' + newSummitLog.id + '?' + new URLSearchParams({ let r = await fetch('/api/v1/summit-log/form/' + newSummitLog.id + '?' + new URLSearchParams({
@@ -151,4 +153,4 @@ export function buildFilterText(filter: SummitLogFilter,): string {
return filterText; return filterText;
} }