diff --git a/web/src/lib/components/shared-components/__test__/number-range-input.spec.ts b/web/src/lib/components/shared-components/__test__/number-range-input.spec.ts new file mode 100644 index 0000000000..d95b9114fd --- /dev/null +++ b/web/src/lib/components/shared-components/__test__/number-range-input.spec.ts @@ -0,0 +1,50 @@ +import NumberRangeInput from '$lib/components/shared-components/number-range-input.svelte'; +import { act, render, type RenderResult } from '@testing-library/svelte'; +import userEvent from '@testing-library/user-event'; + +describe('NumberRangeInput component', () => { + const user = userEvent.setup(); + let sut: RenderResult; + let input: HTMLInputElement; + + beforeEach(() => { + sut = render(NumberRangeInput, { id: '', min: -90, max: 90, onInput: () => {} }); + input = sut.getByRole('spinbutton') as HTMLInputElement; + }); + + it('updates value', async () => { + expect(input.value).toBe(''); + await act(() => sut.component.$set({ value: 10 })); + expect(input.value).toBe('10'); + }); + + it('restricts minimum value', async () => { + await user.type(input, '-91'); + expect(input.value).toBe('-90'); + }); + + it('restricts maximum value', async () => { + await user.type(input, '09990'); + expect(input.value).toBe('90'); + }); + + it('allows entering negative numbers', async () => { + await user.type(input, '-10'); + expect(input.value).toBe('-10'); + }); + + it('allows entering zero', async () => { + await user.type(input, '0'); + expect(input.value).toBe('0'); + }); + + it('allows entering decimal numbers', async () => { + await user.type(input, '-0.09001'); + expect(input.value).toBe('-0.09001'); + }); + + it('ignores text input', async () => { + await user.type(input, 'test'); + expect(input.value).toBe(''); + }); +}); diff --git a/web/src/lib/components/shared-components/change-location.svelte b/web/src/lib/components/shared-components/change-location.svelte index 9feebe91ff..862ab913a2 100644 --- a/web/src/lib/components/shared-components/change-location.svelte +++ b/web/src/lib/components/shared-components/change-location.svelte @@ -12,6 +12,7 @@ import SearchBar from '../elements/search-bar.svelte'; import { listNavigation } from '$lib/actions/list-navigation'; import { t } from 'svelte-i18n'; + import CoordinatesInput from '$lib/components/shared-components/coordinates-input.svelte'; export let asset: AssetResponseDto | undefined = undefined; @@ -34,9 +35,9 @@ confirm: Point; }>(); - $: lat = asset?.exifInfo?.latitude || 0; - $: lng = asset?.exifInfo?.longitude || 0; - $: zoom = lat && lng ? 15 : 1; + $: lat = asset?.exifInfo?.latitude ?? undefined; + $: lng = asset?.exifInfo?.longitude ?? undefined; + $: zoom = lat !== undefined && lng !== undefined ? 15 : 1; $: { if (places) { @@ -148,7 +149,7 @@ {/if} - + {$t('pick_a_location')}
{#await import('../shared-components/map/map.svelte')} {#await delay(timeToLoadTheMap) then} @@ -157,10 +158,9 @@
{/await} - {:then component} - {/await} + +
+ { + point = { lat, lng }; + addClipMapMarker(lng, lat); + }} + /> +
diff --git a/web/src/lib/components/shared-components/coordinates-input.svelte b/web/src/lib/components/shared-components/coordinates-input.svelte new file mode 100644 index 0000000000..2eb9682ff6 --- /dev/null +++ b/web/src/lib/components/shared-components/coordinates-input.svelte @@ -0,0 +1,27 @@ + + +
+ + +
+ +
+ + +
diff --git a/web/src/lib/components/shared-components/number-range-input.svelte b/web/src/lib/components/shared-components/number-range-input.svelte new file mode 100644 index 0000000000..e4c780a708 --- /dev/null +++ b/web/src/lib/components/shared-components/number-range-input.svelte @@ -0,0 +1,28 @@ + + + { + if (value !== null && (value < min || value > max)) { + value = clamp(value, min, max); + } + onInput(value); + }} +/> diff --git a/web/src/lib/i18n/en.json b/web/src/lib/i18n/en.json index 2fee5000a4..99cb356d2e 100644 --- a/web/src/lib/i18n/en.json +++ b/web/src/lib/i18n/en.json @@ -740,6 +740,7 @@ "language_setting_description": "Select your preferred language", "last_seen": "Last seen", "latest_version": "Latest Version", + "latitude": "Latitude", "leave": "Leave", "let_others_respond": "Let others respond", "level": "Level", @@ -786,6 +787,7 @@ "login_has_been_disabled": "Login has been disabled.", "logout_all_device_confirmation": "Are you sure you want to log out all devices?", "logout_this_device_confirmation": "Are you sure you want to log out this device?", + "longitude": "Longitude", "look": "Look", "loop_videos": "Loop videos", "loop_videos_description": "Enable to automatically loop a video in the detail viewer.",