From a6f39bc74f768b8351082ea4127e2c31e4de9b24 Mon Sep 17 00:00:00 2001
From: Alex <alex.tran1502@gmail.com>
Date: Sun, 29 Oct 2023 13:50:43 -0500
Subject: [PATCH] fix(web): Improve UI/UX for shared link form (#4685)

* chore(web): Improve shared link form

* add verification for password

* improve ux
---
 .../shared-components/base-modal.svelte       | 13 +++++++++---
 .../create-shared-link-modal.svelte           | 21 +++++++++++++++----
 .../sharedlinks-page/shared-link-card.svelte  |  8 +++++++
 3 files changed, 35 insertions(+), 7 deletions(-)

diff --git a/web/src/lib/components/shared-components/base-modal.svelte b/web/src/lib/components/shared-components/base-modal.svelte
index 6268e9bf4..7b466a333 100644
--- a/web/src/lib/components/shared-components/base-modal.svelte
+++ b/web/src/lib/components/shared-components/base-modal.svelte
@@ -9,6 +9,7 @@
 
   const dispatch = createEventDispatcher();
   export let zIndex = 9999;
+  export let ignoreClickOutside = false;
 
   onMount(() => {
     if (browser) {
@@ -35,9 +36,9 @@
 >
   <div
     use:clickOutside
-    on:outclick={() => dispatch('close')}
+    on:outclick={() => !ignoreClickOutside && dispatch('close')}
     on:escape={() => dispatch('escape')}
-    class="max-h-[600px] min-h-[200px] w-[450px] rounded-lg bg-immich-bg shadow-md dark:bg-immich-dark-gray dark:text-immich-dark-fg"
+    class="max-h-[800px] min-h-[200px] w-[450px] overflow-y-auto rounded-lg bg-immich-bg shadow-md dark:bg-immich-dark-gray dark:text-immich-dark-fg immich-scrollbar"
   >
     <div class="flex place-items-center justify-between px-5 py-3">
       <div>
@@ -49,8 +50,14 @@
       <CircleIconButton on:click={() => dispatch('close')} icon={mdiClose} size={'20'} />
     </div>
 
-    <div class="">
+    <div>
       <slot />
     </div>
+
+    {#if $$slots['sticky-bottom']}
+      <div class="sticky bottom-0 bg-immich-bg px-5 pb-5 pt-3 dark:bg-immich-dark-gray">
+        <slot name="sticky-bottom" />
+      </div>
+    {/if}
   </div>
 </div>
diff --git a/web/src/lib/components/shared-components/create-share-link-modal/create-shared-link-modal.svelte b/web/src/lib/components/shared-components/create-share-link-modal/create-shared-link-modal.svelte
index 5baefa150..970ae6317 100644
--- a/web/src/lib/components/shared-components/create-share-link-modal/create-shared-link-modal.svelte
+++ b/web/src/lib/components/shared-components/create-share-link-modal/create-shared-link-modal.svelte
@@ -27,6 +27,8 @@
   let password = '';
   let shouldChangeExpirationTime = false;
   let canCopyImagesToClipboard = true;
+  let enablePassword = false;
+
   const dispatch = createEventDispatcher();
 
   const expiredDateOption: ImmichDropDownOption = {
@@ -50,6 +52,8 @@
 
       albumId = editingLink.album?.id;
       assetIds = editingLink.assets.map(({ id }) => id);
+
+      enablePassword = !!editingLink.password;
     }
 
     const module = await import('copy-image-clipboard');
@@ -124,7 +128,7 @@
         id: editingLink.id,
         sharedLinkEditDto: {
           description,
-          password,
+          password: enablePassword ? password : '',
           expiresAt: shouldChangeExpirationTime ? expirationDate : undefined,
           allowUpload,
           allowDownload,
@@ -184,14 +188,23 @@
     <div class="mb-2 mt-4">
       <p class="text-xs">LINK OPTIONS</p>
     </div>
-    <div class="rounded-lg bg-gray-100 p-4 dark:bg-black/40 max-h-[330px] overflow-y-scroll">
+    <div class="rounded-lg bg-gray-100 p-4 dark:bg-black/40 overflow-y-auto">
       <div class="flex flex-col">
         <div class="mb-2">
           <SettingInputField inputType={SettingInputFieldType.TEXT} label="Description" bind:value={description} />
         </div>
 
         <div class="mb-2">
-          <SettingInputField inputType={SettingInputFieldType.TEXT} label="Password" bind:value={password} />
+          <SettingInputField
+            inputType={SettingInputFieldType.TEXT}
+            label="Password"
+            bind:value={password}
+            disabled={!enablePassword}
+          />
+        </div>
+
+        <div class="my-3">
+          <SettingSwitch bind:checked={enablePassword} title={'Require password'} />
         </div>
 
         <div class="my-3">
@@ -227,7 +240,7 @@
 
   <hr />
 
-  <section class="m-6">
+  <section slot="sticky-bottom">
     {#if !sharedLink}
       {#if editingLink}
         <div class="flex justify-end">
diff --git a/web/src/lib/components/sharedlinks-page/shared-link-card.svelte b/web/src/lib/components/sharedlinks-page/shared-link-card.svelte
index 8d25972ff..621c98132 100644
--- a/web/src/lib/components/sharedlinks-page/shared-link-card.svelte
+++ b/web/src/lib/components/sharedlinks-page/shared-link-card.svelte
@@ -141,6 +141,14 @@
           EXIF
         </div>
       {/if}
+
+      {#if link.password}
+        <div
+          class="flex w-[100px] place-content-center place-items-center rounded-full bg-immich-primary px-2 py-1 text-xs text-white dark:bg-immich-dark-primary dark:text-immich-dark-gray"
+        >
+          Password
+        </div>
+      {/if}
     </div>
   </div>