You've already forked immich
							
							
				mirror of
				https://github.com/immich-app/immich.git
				synced 2025-10-31 00:18:28 +02:00 
			
		
		
		
	refactor: library-exclusion-pattern-form modal (#18654)
Co-authored-by: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com>
This commit is contained in:
		| @@ -1,12 +1,13 @@ | ||||
| <script lang="ts"> | ||||
|   import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte'; | ||||
|   import { modalManager } from '$lib/managers/modal-manager.svelte'; | ||||
|   import LibraryExclusionPatternModal from '$lib/modals/LibraryExclusionPatternModal.svelte'; | ||||
|   import { type LibraryResponseDto } from '@immich/sdk'; | ||||
|   import { Button } from '@immich/ui'; | ||||
|   import { mdiPencilOutline } from '@mdi/js'; | ||||
|   import { onMount } from 'svelte'; | ||||
|   import { t } from 'svelte-i18n'; | ||||
|   import { handleError } from '../../utils/handle-error'; | ||||
|   import LibraryExclusionPatternForm from './library-exclusion-pattern-form.svelte'; | ||||
|  | ||||
|   interface Props { | ||||
|     library: Partial<LibraryResponseDto>; | ||||
| @@ -16,12 +17,6 @@ | ||||
|  | ||||
|   let { library = $bindable(), onCancel, onSubmit }: Props = $props(); | ||||
|  | ||||
|   let addExclusionPattern = $state(false); | ||||
|   let editExclusionPattern: number | null = $state(null); | ||||
|  | ||||
|   let exclusionPatternToAdd: string = $state(''); | ||||
|   let editedExclusionPattern: string = $state(''); | ||||
|  | ||||
|   let exclusionPatterns: string[] = $state([]); | ||||
|  | ||||
|   onMount(() => { | ||||
| @@ -32,11 +27,7 @@ | ||||
|     } | ||||
|   }); | ||||
|  | ||||
|   const handleAddExclusionPattern = () => { | ||||
|     if (!addExclusionPattern) { | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   const handleAddExclusionPattern = (exclusionPatternToAdd: string) => { | ||||
|     if (!library.exclusionPatterns) { | ||||
|       library.exclusionPatterns = []; | ||||
|     } | ||||
| @@ -49,33 +40,24 @@ | ||||
|       } | ||||
|     } catch (error) { | ||||
|       handleError(error, $t('errors.unable_to_add_exclusion_pattern')); | ||||
|     } finally { | ||||
|       exclusionPatternToAdd = ''; | ||||
|       addExclusionPattern = false; | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   const handleEditExclusionPattern = () => { | ||||
|     if (editExclusionPattern === null) { | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   const handleEditExclusionPattern = (editedExclusionPattern: string, patternIndex: number) => { | ||||
|     if (!library.exclusionPatterns) { | ||||
|       library.exclusionPatterns = []; | ||||
|     } | ||||
|  | ||||
|     try { | ||||
|       library.exclusionPatterns[editExclusionPattern] = editedExclusionPattern; | ||||
|       library.exclusionPatterns[patternIndex] = editedExclusionPattern; | ||||
|       exclusionPatterns = library.exclusionPatterns; | ||||
|     } catch (error) { | ||||
|       handleError(error, $t('errors.unable_to_edit_exclusion_pattern')); | ||||
|     } finally { | ||||
|       editExclusionPattern = null; | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   const handleDeleteExclusionPattern = () => { | ||||
|     if (editExclusionPattern === null) { | ||||
|   const handleDeleteExclusionPattern = (patternIndexToDelete?: number) => { | ||||
|     if (patternIndexToDelete === undefined) { | ||||
|       return; | ||||
|     } | ||||
|  | ||||
| @@ -84,13 +66,39 @@ | ||||
|         library.exclusionPatterns = []; | ||||
|       } | ||||
|  | ||||
|       const pathToDelete = library.exclusionPatterns[editExclusionPattern]; | ||||
|       library.exclusionPatterns = library.exclusionPatterns.filter((path) => path != pathToDelete); | ||||
|       const patternToDelete = library.exclusionPatterns[patternIndexToDelete]; | ||||
|       library.exclusionPatterns = library.exclusionPatterns.filter((path) => path != patternToDelete); | ||||
|       exclusionPatterns = library.exclusionPatterns; | ||||
|     } catch (error) { | ||||
|       handleError(error, $t('errors.unable_to_delete_exclusion_pattern')); | ||||
|     } finally { | ||||
|       editExclusionPattern = null; | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   const onEditExclusionPattern = async (patternIndexToEdit?: number) => { | ||||
|     const result = await modalManager.show(LibraryExclusionPatternModal, { | ||||
|       submitText: patternIndexToEdit === undefined ? $t('add') : $t('save'), | ||||
|       isEditing: patternIndexToEdit !== undefined, | ||||
|       exclusionPattern: patternIndexToEdit === undefined ? '' : exclusionPatterns[patternIndexToEdit], | ||||
|       exclusionPatterns, | ||||
|     }); | ||||
|  | ||||
|     if (!result) { | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     switch (result.action) { | ||||
|       case 'submit': { | ||||
|         if (patternIndexToEdit === undefined) { | ||||
|           handleAddExclusionPattern(result.exclusionPattern); | ||||
|         } else { | ||||
|           handleEditExclusionPattern(result.exclusionPattern, patternIndexToEdit); | ||||
|         } | ||||
|         break; | ||||
|       } | ||||
|       case 'delete': { | ||||
|         handleDeleteExclusionPattern(patternIndexToEdit); | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|   }; | ||||
|  | ||||
| @@ -100,28 +108,6 @@ | ||||
|   }; | ||||
| </script> | ||||
|  | ||||
| {#if addExclusionPattern} | ||||
|   <LibraryExclusionPatternForm | ||||
|     submitText={$t('add')} | ||||
|     bind:exclusionPattern={exclusionPatternToAdd} | ||||
|     {exclusionPatterns} | ||||
|     onSubmit={handleAddExclusionPattern} | ||||
|     onCancel={() => (addExclusionPattern = false)} | ||||
|   /> | ||||
| {/if} | ||||
|  | ||||
| {#if editExclusionPattern != undefined} | ||||
|   <LibraryExclusionPatternForm | ||||
|     submitText={$t('save')} | ||||
|     isEditing={true} | ||||
|     bind:exclusionPattern={editedExclusionPattern} | ||||
|     {exclusionPatterns} | ||||
|     onSubmit={handleEditExclusionPattern} | ||||
|     onDelete={handleDeleteExclusionPattern} | ||||
|     onCancel={() => (editExclusionPattern = null)} | ||||
|   /> | ||||
| {/if} | ||||
|  | ||||
| <form {onsubmit} autocomplete="off" class="m-4 flex flex-col gap-4"> | ||||
|   <table class="w-full text-start"> | ||||
|     <tbody class="block w-full overflow-y-auto rounded-md border dark:border-immich-dark-gray"> | ||||
| @@ -136,10 +122,7 @@ | ||||
|               icon={mdiPencilOutline} | ||||
|               title={$t('edit_exclusion_pattern')} | ||||
|               size="16" | ||||
|               onclick={() => { | ||||
|                 editExclusionPattern = listIndex; | ||||
|                 editedExclusionPattern = exclusionPattern; | ||||
|               }} | ||||
|               onclick={() => onEditExclusionPattern(listIndex)} | ||||
|             /> | ||||
|           </td> | ||||
|         </tr> | ||||
| @@ -153,13 +136,9 @@ | ||||
|           {/if} | ||||
|         </td> | ||||
|         <td class="w-1/4 text-ellipsis px-4 text-sm flex justify-center"> | ||||
|           <Button | ||||
|             size="small" | ||||
|             shape="round" | ||||
|             onclick={() => { | ||||
|               addExclusionPattern = true; | ||||
|             }}>{$t('add_exclusion_pattern')}</Button | ||||
|           > | ||||
|           <Button size="small" shape="round" onclick={() => onEditExclusionPattern()}> | ||||
|             {$t('add_exclusion_pattern')} | ||||
|           </Button> | ||||
|         </td> | ||||
|       </tr> | ||||
|     </tbody> | ||||
|   | ||||
| @@ -9,9 +9,7 @@ | ||||
|     exclusionPatterns?: string[]; | ||||
|     isEditing?: boolean; | ||||
|     submitText?: string; | ||||
|     onCancel: () => void; | ||||
|     onSubmit: (exclusionPattern: string) => void; | ||||
|     onDelete?: () => void; | ||||
|     onClose: (data?: { action: 'delete' } | { action: 'submit'; exclusionPattern: string }) => void; | ||||
|   } | ||||
| 
 | ||||
|   let { | ||||
| @@ -19,9 +17,7 @@ | ||||
|     exclusionPatterns = $bindable([]), | ||||
|     isEditing = false, | ||||
|     submitText = $t('submit'), | ||||
|     onCancel, | ||||
|     onSubmit, | ||||
|     onDelete, | ||||
|     onClose, | ||||
|   }: Props = $props(); | ||||
| 
 | ||||
|   onMount(() => { | ||||
| @@ -36,12 +32,12 @@ | ||||
|   const onsubmit = (event: Event) => { | ||||
|     event.preventDefault(); | ||||
|     if (canSubmit) { | ||||
|       onSubmit(exclusionPattern); | ||||
|       onClose({ action: 'submit', exclusionPattern }); | ||||
|     } | ||||
|   }; | ||||
| </script> | ||||
| 
 | ||||
| <Modal size="small" title={$t('add_exclusion_pattern')} icon={mdiFolderRemove} onClose={onCancel}> | ||||
| <Modal size="small" title={$t('add_exclusion_pattern')} icon={mdiFolderRemove} {onClose}> | ||||
|   <ModalBody> | ||||
|     <form {onsubmit} autocomplete="off" id="add-exclusion-pattern-form"> | ||||
|       <p class="py-5 text-sm"> | ||||
| @@ -68,13 +64,15 @@ | ||||
|   </ModalBody> | ||||
|   <ModalFooter> | ||||
|     <div class="flex gap-2 w-full"> | ||||
|       <Button shape="round" color="secondary" fullWidth onclick={onCancel}>{$t('cancel')}</Button> | ||||
|       <Button shape="round" color="secondary" fullWidth onclick={() => onClose()}>{$t('cancel')}</Button> | ||||
|       {#if isEditing} | ||||
|         <Button shape="round" color="danger" fullWidth onclick={onDelete}>{$t('delete')}</Button> | ||||
|         <Button shape="round" color="danger" fullWidth onclick={() => onClose({ action: 'delete' })} | ||||
|           >{$t('delete')}</Button | ||||
|         > | ||||
|       {/if} | ||||
|       <Button shape="round" type="submit" disabled={!canSubmit} fullWidth form="add-exclusion-pattern-form" | ||||
|         >{submitText}</Button | ||||
|       > | ||||
|       <Button shape="round" type="submit" disabled={!canSubmit} fullWidth form="add-exclusion-pattern-form"> | ||||
|         {submitText} | ||||
|       </Button> | ||||
|     </div> | ||||
|   </ModalFooter> | ||||
| </Modal> | ||||
		Reference in New Issue
	
	Block a user