mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-04 03:27:09 -05:00 
			
		
		
		
	fix(web): Prevent changing asset location triggering keyboard shortcuts (#21451)
fix(web): Prevent changing asset location triggering asset keyboard shortcuts
This commit is contained in:
		
							parent
							
								
									b3372064e0
								
							
						
					
					
						commit
						225af973c1
					
				@ -1,18 +1,24 @@
 | 
			
		||||
import NumberRangeInput from '$lib/components/shared-components/number-range-input.svelte';
 | 
			
		||||
import { render, type RenderResult } from '@testing-library/svelte';
 | 
			
		||||
import userEvent from '@testing-library/user-event';
 | 
			
		||||
import type { Mock } from 'vitest';
 | 
			
		||||
 | 
			
		||||
describe('NumberRangeInput component', () => {
 | 
			
		||||
  const user = userEvent.setup();
 | 
			
		||||
  let sut: RenderResult<NumberRangeInput>;
 | 
			
		||||
  let input: HTMLInputElement;
 | 
			
		||||
  let onInput: Mock;
 | 
			
		||||
  let onKeyDown: Mock;
 | 
			
		||||
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    onInput = vi.fn();
 | 
			
		||||
    onKeyDown = vi.fn();
 | 
			
		||||
    sut = render(NumberRangeInput, {
 | 
			
		||||
      id: '',
 | 
			
		||||
      min: -90,
 | 
			
		||||
      max: 90,
 | 
			
		||||
      onInput: () => {},
 | 
			
		||||
      onInput,
 | 
			
		||||
      onKeyDown,
 | 
			
		||||
    });
 | 
			
		||||
    input = sut.getByRole('spinbutton') as HTMLInputElement;
 | 
			
		||||
  });
 | 
			
		||||
@ -21,35 +27,55 @@ describe('NumberRangeInput component', () => {
 | 
			
		||||
    expect(input.value).toBe('');
 | 
			
		||||
    await sut.rerender({ value: 10 });
 | 
			
		||||
    expect(input.value).toBe('10');
 | 
			
		||||
    expect(onInput).not.toHaveBeenCalled();
 | 
			
		||||
    expect(onKeyDown).not.toHaveBeenCalled();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('restricts minimum value', async () => {
 | 
			
		||||
    await user.type(input, '-91');
 | 
			
		||||
    expect(input.value).toBe('-90');
 | 
			
		||||
    expect(onInput).toHaveBeenCalled();
 | 
			
		||||
    expect(onKeyDown).toHaveBeenCalled();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('restricts maximum value', async () => {
 | 
			
		||||
    await user.type(input, '09990');
 | 
			
		||||
    expect(input.value).toBe('90');
 | 
			
		||||
    expect(onInput).toHaveBeenCalled();
 | 
			
		||||
    expect(onKeyDown).toHaveBeenCalled();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('allows entering negative numbers', async () => {
 | 
			
		||||
    await user.type(input, '-10');
 | 
			
		||||
    expect(input.value).toBe('-10');
 | 
			
		||||
    expect(onInput).toHaveBeenCalled();
 | 
			
		||||
    expect(onKeyDown).toHaveBeenCalled();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('allows entering zero', async () => {
 | 
			
		||||
    await user.type(input, '0');
 | 
			
		||||
    expect(input.value).toBe('0');
 | 
			
		||||
    expect(onInput).toHaveBeenCalled();
 | 
			
		||||
    expect(onKeyDown).toHaveBeenCalled();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('allows entering decimal numbers', async () => {
 | 
			
		||||
    await user.type(input, '-0.09001');
 | 
			
		||||
    expect(input.value).toBe('-0.09001');
 | 
			
		||||
    expect(onInput).toHaveBeenCalled();
 | 
			
		||||
    expect(onKeyDown).toHaveBeenCalled();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('ignores text input', async () => {
 | 
			
		||||
    await user.type(input, 'test');
 | 
			
		||||
    expect(input.value).toBe('');
 | 
			
		||||
    expect(onInput).toHaveBeenCalled();
 | 
			
		||||
    expect(onKeyDown).toHaveBeenCalled();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('test', async () => {
 | 
			
		||||
    await user.type(input, 'd');
 | 
			
		||||
    expect(onInput).not.toHaveBeenCalled();
 | 
			
		||||
    expect(onKeyDown).toHaveBeenCalled();
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
@ -20,6 +20,10 @@
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const onKeyDown = (event: KeyboardEvent) => {
 | 
			
		||||
    event.stopPropagation();
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const onPaste = (event: ClipboardEvent) => {
 | 
			
		||||
    const pastedText = event.clipboardData?.getData('text/plain');
 | 
			
		||||
    if (!pastedText) {
 | 
			
		||||
@ -42,10 +46,10 @@
 | 
			
		||||
 | 
			
		||||
<div>
 | 
			
		||||
  <label class="immich-form-label" for="latitude-input-{id}">{$t('latitude')}</label>
 | 
			
		||||
  <NumberRangeInput id="latitude-input-{id}" min={-90} max={90} {onInput} {onPaste} bind:value={lat} />
 | 
			
		||||
  <NumberRangeInput id="latitude-input-{id}" min={-90} max={90} {onKeyDown} {onInput} {onPaste} bind:value={lat} />
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<div>
 | 
			
		||||
  <label class="immich-form-label" for="longitude-input-{id}">{$t('longitude')}</label>
 | 
			
		||||
  <NumberRangeInput id="longitude-input-{id}" min={-180} max={180} {onInput} {onPaste} bind:value={lng} />
 | 
			
		||||
  <NumberRangeInput id="longitude-input-{id}" min={-180} max={180} {onKeyDown} {onInput} {onPaste} bind:value={lng} />
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
  import { clamp } from 'lodash-es';
 | 
			
		||||
  import type { ClipboardEventHandler } from 'svelte/elements';
 | 
			
		||||
  import type { ClipboardEventHandler, KeyboardEventHandler } from 'svelte/elements';
 | 
			
		||||
 | 
			
		||||
  interface Props {
 | 
			
		||||
    id: string;
 | 
			
		||||
@ -11,6 +11,7 @@
 | 
			
		||||
    value?: number;
 | 
			
		||||
    onInput: (value: number | null) => void;
 | 
			
		||||
    onPaste?: ClipboardEventHandler<HTMLInputElement>;
 | 
			
		||||
    onKeyDown?: KeyboardEventHandler<HTMLInputElement>;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  let {
 | 
			
		||||
@ -22,6 +23,7 @@
 | 
			
		||||
    value = $bindable(),
 | 
			
		||||
    onInput,
 | 
			
		||||
    onPaste = undefined,
 | 
			
		||||
    onKeyDown = undefined,
 | 
			
		||||
  }: Props = $props();
 | 
			
		||||
 | 
			
		||||
  const oninput = () => {
 | 
			
		||||
@ -48,4 +50,5 @@
 | 
			
		||||
  bind:value
 | 
			
		||||
  {oninput}
 | 
			
		||||
  onpaste={onPaste}
 | 
			
		||||
  onkeydown={onKeyDown}
 | 
			
		||||
/>
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user