chore(web): unique ID generation (#9932)

* chore(web): automatically generate unique IDs

* fix: revert changes to Slider

* chore: add test for id store
This commit is contained in:
Ben 2024-06-01 22:58:35 +00:00 committed by GitHub
parent 4e16e2520d
commit 01f52c9021
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
52 changed files with 83 additions and 150 deletions

View file

@ -53,7 +53,7 @@
};
</script>
<FullScreenModal id="album-selection-modal" title={getTitle()} {onClose}>
<FullScreenModal title={getTitle()} {onClose}>
<div class="mb-2 flex max-h-[400px] flex-col">
{#if loading}
{#each { length: 3 } as _}

View file

@ -56,7 +56,6 @@
</script>
<ConfirmDialog
id="edit-date-time-modal"
confirmColor="primary"
title="Edit date and time"
prompt="Please select a new date:"
@ -75,13 +74,7 @@
/>
</div>
<div class="flex flex-col w-full mt-2">
<Combobox
bind:selectedOption
id="settings-timezone"
label="Timezone"
options={timezones}
placeholder="Search timezone..."
/>
<Combobox bind:selectedOption label="Timezone" options={timezones} placeholder="Search timezone..." />
</div>
</div>
</ConfirmDialog>

View file

@ -104,7 +104,6 @@
</script>
<ConfirmDialog
id="change-location-modal"
confirmColor="primary"
title="Change location"
width="wide"

View file

@ -19,17 +19,18 @@
import { clickOutside } from '$lib/actions/click-outside';
import { focusOutside } from '$lib/actions/focus-outside';
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
import { uniqueIdStore } from '$lib/stores/unique-id.store';
/**
* Unique identifier for the combobox.
*/
export let id: string;
export let label: string;
export let hideLabel = false;
export let options: ComboBoxOption[] = [];
export let selectedOption: ComboBoxOption | undefined;
export let placeholder = '';
/**
* Unique identifier for the combobox.
*/
let id: string = uniqueIdStore.generateId();
/**
* Indicates whether or not the dropdown autocomplete list should be visible.
*/

View file

@ -159,7 +159,7 @@
};
</script>
<FullScreenModal id="create-shared-link-modal" title={getTitle()} icon={mdiLink} {onClose}>
<FullScreenModal title={getTitle()} icon={mdiLink} {onClose}>
<section>
{#if shareType === SharedLinkType.Album}
{#if !editingLink}
@ -204,33 +204,25 @@
</div>
<div class="my-3">
<SettingSwitch id="require-password" bind:checked={enablePassword} title={'Require password'} />
<SettingSwitch bind:checked={enablePassword} title={'Require password'} />
</div>
<div class="my-3">
<SettingSwitch id="show-metadata" bind:checked={showMetadata} title={'Show metadata'} />
<SettingSwitch bind:checked={showMetadata} title={'Show metadata'} />
</div>
<div class="my-3">
<SettingSwitch
id="allow-public-download"
bind:checked={allowDownload}
title={'Allow public user to download'}
/>
<SettingSwitch bind:checked={allowDownload} title={'Allow public user to download'} />
</div>
<div class="my-3">
<SettingSwitch id="allow-public-upload" bind:checked={allowUpload} title={'Allow public user to upload'} />
<SettingSwitch bind:checked={allowUpload} title={'Allow public user to upload'} />
</div>
<div class="text-sm">
{#if editingLink}
<p class="immich-form-label my-2">
<SettingSwitch
id="change-expiration-time"
bind:checked={shouldChangeExpirationTime}
title={'Change expiration time'}
/>
<SettingSwitch bind:checked={shouldChangeExpirationTime} title={'Change expiration time'} />
</p>
{:else}
<p class="immich-form-label my-2">Expire after</p>

View file

@ -3,7 +3,6 @@
import Button from '../../elements/buttons/button.svelte';
import type { Color } from '$lib/components/elements/buttons/button.svelte';
export let id: string = 'confirm-dialog';
export let title = 'Confirm';
export let prompt = 'Are you sure you want to do this?';
export let confirmText = 'Confirm';
@ -24,7 +23,7 @@
};
</script>
<FullScreenModal {title} {id} onClose={onCancel} {width}>
<FullScreenModal {title} onClose={onCancel} {width}>
<div class="text-md py-5 text-center">
<slot name="prompt">
<p>{prompt}</p>

View file

@ -3,13 +3,9 @@
import { fade } from 'svelte/transition';
import FocusTrap from '$lib/components/shared-components/focus-trap.svelte';
import ModalHeader from '$lib/components/shared-components/modal-header.svelte';
import { uniqueIdStore } from '$lib/stores/unique-id.store';
export let onClose: () => void;
/**
* Unique identifier for the modal.
*/
export let id: string;
export let title: string;
/**
* If true, the logo will be displayed next to the modal title.
@ -28,6 +24,11 @@
*/
export let width: 'wide' | 'narrow' | 'auto' = 'narrow';
/**
* Unique identifier for the modal.
*/
let id: string = uniqueIdStore.generateId();
$: titleId = `${id}-title`;
$: isStickyBottom = !!$$slots['sticky-bottom'];

View file

@ -13,7 +13,7 @@
const colors: UserAvatarColor[] = Object.values(UserAvatarColor);
</script>
<FullScreenModal id="avatar-selector-modal" title="Select avatar color" width="auto" onClose={() => dispatch('close')}>
<FullScreenModal title="Select avatar color" width="auto" onClose={() => dispatch('close')}>
<div class="flex items-center justify-center mt-4">
<div class="grid grid-cols-2 md:grid-cols-5 gap-4">
{#each colors as color}

View file

@ -69,7 +69,7 @@
};
</script>
<FullScreenModal id="profile-image-cropper" title="Set profile picture" width="auto" {onClose}>
<FullScreenModal title="Set profile picture" width="auto" {onClose}>
<div class="flex place-items-center items-center justify-center">
<div
class="relative flex aspect-square w-[250px] overflow-hidden rounded-full border-4 border-immich-primary bg-immich-dark-primary dark:border-immich-dark-primary dark:bg-immich-primary"

View file

@ -41,7 +41,6 @@
<div class="grid grid-cols-[repeat(auto-fit,minmax(10rem,1fr))] gap-5 mt-1">
<div class="w-full">
<Combobox
id="camera-make"
label="Make"
on:select={({ detail }) => (filters.make = detail?.value)}
options={toComboBoxOptions(makes)}
@ -52,7 +51,6 @@
<div class="w-full">
<Combobox
id="camera-model"
label="Model"
on:select={({ detail }) => (filters.model = detail?.value)}
options={toComboBoxOptions(models)}

View file

@ -63,7 +63,6 @@
<div class="grid grid-cols-[repeat(auto-fit,minmax(10rem,1fr))] gap-5 mt-1">
<div class="w-full">
<Combobox
id="location-country"
label="Country"
on:select={({ detail }) => (filters.country = detail?.value)}
options={toComboBoxOptions(countries)}
@ -74,7 +73,6 @@
<div class="w-full">
<Combobox
id="location-state"
label="State"
on:select={({ detail }) => (filters.state = detail?.value)}
options={toComboBoxOptions(states)}
@ -85,7 +83,6 @@
<div class="w-full">
<Combobox
id="location-city"
label="City"
on:select={({ detail }) => (filters.city = detail?.value)}
options={toComboBoxOptions(cities)}

View file

@ -3,7 +3,6 @@
import { fly } from 'svelte/transition';
import Combobox, { type ComboBoxOption } from '$lib/components/shared-components/combobox.svelte';
export let id: string;
export let title: string;
export let comboboxPlaceholder: string;
export let subtitle = '';
@ -33,7 +32,6 @@
</div>
<div class="flex items-center">
<Combobox
{id}
label={title}
hideLabel={true}
{selectedOption}

View file

@ -3,14 +3,16 @@
import { fly } from 'svelte/transition';
import { createEventDispatcher } from 'svelte';
import Slider from '$lib/components/elements/slider.svelte';
import { uniqueIdStore } from '$lib/stores/unique-id.store';
export let id: string;
export let title: string;
export let subtitle = '';
export let checked = false;
export let disabled = false;
export let isEdited = false;
let id: string = uniqueIdStore.generateId();
$: sliderId = `${id}-slider`;
$: subtitleId = subtitle ? `${id}-subtitle` : undefined;

View file

@ -37,12 +37,7 @@
}>();
</script>
<FullScreenModal
id="keyboard-shortcuts-modal"
title="Keyboard shortcuts"
width="auto"
onClose={() => dispatch('close')}
>
<FullScreenModal title="Keyboard shortcuts" width="auto" onClose={() => dispatch('close')}>
<div class="grid grid-cols-1 gap-4 px-4 pb-4 md:grid-cols-2">
<div class="p-4">
<h2>General</h2>

View file

@ -33,7 +33,7 @@
</script>
{#if showModal}
<FullScreenModal id="new-version-modal" title="🎉 NEW VERSION AVAILABLE" onClose={() => (showModal = false)}>
<FullScreenModal title="🎉 NEW VERSION AVAILABLE" onClose={() => (showModal = false)}>
<div>
Hi friend, there is a new version of the application please take your time to visit the
<span class="font-medium underline"