mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-03 19:29:32 -05:00 
			
		
		
		
	feat(web): UI/UX improvement for date time edit form (#5505)
This commit is contained in:
		
							parent
							
								
									7e8488694d
								
							
						
					
					
						commit
						84c5b08c25
					
				@ -15,8 +15,12 @@
 | 
			
		||||
  import { fly } from 'svelte/transition';
 | 
			
		||||
  import { createEventDispatcher } from 'svelte';
 | 
			
		||||
 | 
			
		||||
  let className = '';
 | 
			
		||||
  export { className as class };
 | 
			
		||||
 | 
			
		||||
  const dispatch = createEventDispatcher<{
 | 
			
		||||
    select: T;
 | 
			
		||||
    'click-outside': void;
 | 
			
		||||
  }>();
 | 
			
		||||
 | 
			
		||||
  export let options: T[];
 | 
			
		||||
@ -36,6 +40,8 @@
 | 
			
		||||
    if (!controlable) {
 | 
			
		||||
      showMenu = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    dispatch('click-outside');
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const handleSelectOption = (option: T) => {
 | 
			
		||||
@ -76,7 +82,7 @@
 | 
			
		||||
  {#if showMenu}
 | 
			
		||||
    <div
 | 
			
		||||
      transition:fly={{ y: -30, x: 30, duration: 100 }}
 | 
			
		||||
      class="text-md fixed z-50 flex min-w-[250px] max-h-[70vh] overflow-y-scroll immich-scrollbar flex-col rounded-2xl bg-gray-100 py-2 text-black shadow-lg dark:bg-gray-700 dark:text-white"
 | 
			
		||||
      class="text-md fixed z-50 flex min-w-[250px] max-h-[70vh] overflow-y-scroll immich-scrollbar flex-col rounded-2xl bg-gray-100 py-2 text-black shadow-lg dark:bg-gray-700 dark:text-white {className}"
 | 
			
		||||
    >
 | 
			
		||||
      {#each options as option (option)}
 | 
			
		||||
        {@const renderedOption = renderOption(option)}
 | 
			
		||||
 | 
			
		||||
@ -59,12 +59,27 @@
 | 
			
		||||
      dispatch('confirm', value);
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const handleKeydown = (event: KeyboardEvent) => {
 | 
			
		||||
    if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(event.key)) {
 | 
			
		||||
      event.stopPropagation();
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  let isDropdownOpen = false;
 | 
			
		||||
  let isSearching = false;
 | 
			
		||||
 | 
			
		||||
  const onSearchFocused = () => {
 | 
			
		||||
    isSearching = true;
 | 
			
		||||
 | 
			
		||||
    openDropdown();
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const onSearchBlurred = () => {
 | 
			
		||||
    isSearching = false;
 | 
			
		||||
 | 
			
		||||
    closeDropdown();
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const openDropdown = () => {
 | 
			
		||||
    isDropdownOpen = true;
 | 
			
		||||
@ -84,42 +99,46 @@
 | 
			
		||||
  <ConfirmDialogue
 | 
			
		||||
    confirmColor="primary"
 | 
			
		||||
    cancelColor="secondary"
 | 
			
		||||
    title="Change Date"
 | 
			
		||||
    title="Edit date & time"
 | 
			
		||||
    prompt="Please select a new date:"
 | 
			
		||||
    {disabled}
 | 
			
		||||
    on:confirm={handleConfirm}
 | 
			
		||||
    on:cancel={handleCancel}
 | 
			
		||||
  >
 | 
			
		||||
    <div class="flex flex-col text-md px-4 py-5 text-center gap-2" slot="prompt">
 | 
			
		||||
    <div class="flex flex-col text-md px-4 text-center gap-2" slot="prompt">
 | 
			
		||||
      <div class="mt-2" />
 | 
			
		||||
      <div class="flex flex-col">
 | 
			
		||||
        <label for="datetime">Date and Time</label>
 | 
			
		||||
        <input
 | 
			
		||||
          class="immich-form-label text-sm mt-2 w-full text-black"
 | 
			
		||||
          class="text-sm my-4 w-full bg-gray-200 p-4 rounded-lg dark:text-white dark:bg-gray-600"
 | 
			
		||||
          id="datetime"
 | 
			
		||||
          type="datetime-local"
 | 
			
		||||
          bind:value={selectedDate}
 | 
			
		||||
        />
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="flex flex-col w-full">
 | 
			
		||||
      <div class="flex flex-col w-full mt-2">
 | 
			
		||||
        <label for="timezone">Timezone</label>
 | 
			
		||||
 | 
			
		||||
        <div class="relative">
 | 
			
		||||
          <input
 | 
			
		||||
            class="immich-form-label text-sm mt-2 w-full text-black"
 | 
			
		||||
            class="text-sm my-4 w-full bg-gray-200 p-3 rounded-lg dark:text-white dark:bg-gray-600"
 | 
			
		||||
            id="timezoneSearch"
 | 
			
		||||
            type="text"
 | 
			
		||||
            placeholder="Search timezone..."
 | 
			
		||||
            bind:value={searchQuery}
 | 
			
		||||
            on:input={updateSearchQuery}
 | 
			
		||||
            on:focus={openDropdown}
 | 
			
		||||
            on:focus={onSearchFocused}
 | 
			
		||||
            on:blur={onSearchBlurred}
 | 
			
		||||
          />
 | 
			
		||||
          <Dropdown
 | 
			
		||||
            class="h-[400px]"
 | 
			
		||||
            selectedOption={initialOption}
 | 
			
		||||
            options={filteredTimezones}
 | 
			
		||||
            render={(item) => (item ? `${item.zone} (${item.offset})` : '(not selected)')}
 | 
			
		||||
            on:select={({ detail: item }) => handleSelectTz(item)}
 | 
			
		||||
            controlable={true}
 | 
			
		||||
            bind:showMenu={isDropdownOpen}
 | 
			
		||||
            on:click-outside={isSearching ? null : closeDropdown}
 | 
			
		||||
          />
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
  export let hideCancelButton = false;
 | 
			
		||||
  export let disabled = false;
 | 
			
		||||
 | 
			
		||||
  const dispatch = createEventDispatcher<{ cancel: void; confirm: void }>();
 | 
			
		||||
  const dispatch = createEventDispatcher<{ cancel: void; confirm: void; 'click-outside': void }>();
 | 
			
		||||
 | 
			
		||||
  let isConfirmButtonDisabled = false;
 | 
			
		||||
 | 
			
		||||
@ -28,9 +28,13 @@
 | 
			
		||||
    isConfirmButtonDisabled = true;
 | 
			
		||||
    dispatch('confirm');
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const handleClickOutside = () => {
 | 
			
		||||
    dispatch('click-outside');
 | 
			
		||||
  };
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<FullScreenModal on:clickOutside={handleCancel} on:escape={() => handleEscape()}>
 | 
			
		||||
<FullScreenModal on:clickOutside={handleClickOutside} on:escape={() => handleEscape()}>
 | 
			
		||||
  <div
 | 
			
		||||
    class="w-[500px] max-w-[95vw] rounded-3xl border bg-immich-bg p-4 py-8 shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg"
 | 
			
		||||
  >
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user