mirror of
https://github.com/immich-app/immich.git
synced 2025-04-08 03:01:32 -05:00
chore(deps): update dependency eslint-plugin-svelte to v3 (#16532)
* chore(deps): update dependency eslint-plugin-svelte to v3 * chore: linting * chore: rebase --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Daniel Dietzler <mail@ddietzler.dev> Co-authored-by: Zack Pollard <zackpollard@ymail.com>
This commit is contained in:
parent
5698f446f7
commit
3d6a6f77a8
54 changed files with 469 additions and 474 deletions
|
@ -2,6 +2,8 @@ import { FlatCompat } from '@eslint/eslintrc';
|
|||
import js from '@eslint/js';
|
||||
import typescriptEslint from '@typescript-eslint/eslint-plugin';
|
||||
import tsParser from '@typescript-eslint/parser';
|
||||
import eslintPluginSvelte from 'eslint-plugin-svelte';
|
||||
import eslintPluginUnicorn from 'eslint-plugin-unicorn';
|
||||
import globals from 'globals';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
@ -11,11 +13,12 @@ const __filename = fileURLToPath(import.meta.url);
|
|||
const __dirname = path.dirname(__filename);
|
||||
const compat = new FlatCompat({
|
||||
baseDirectory: __dirname,
|
||||
recommendedConfig: js.configs.recommended,
|
||||
allConfig: js.configs.all,
|
||||
});
|
||||
|
||||
export default [
|
||||
...eslintPluginSvelte.configs.recommended,
|
||||
eslintPluginUnicorn.configs.recommended,
|
||||
js.configs.recommended,
|
||||
{
|
||||
ignores: [
|
||||
'**/.DS_Store',
|
||||
|
@ -36,15 +39,11 @@ export default [
|
|||
'coverage',
|
||||
],
|
||||
},
|
||||
...compat.extends(
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:svelte/recommended',
|
||||
'plugin:unicorn/recommended',
|
||||
),
|
||||
...compat.extends('plugin:@typescript-eslint/recommended'),
|
||||
{
|
||||
plugins: {
|
||||
'@typescript-eslint': typescriptEslint,
|
||||
svelte: eslintPluginSvelte,
|
||||
},
|
||||
|
||||
languageOptions: {
|
||||
|
|
658
web/package-lock.json
generated
658
web/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -45,8 +45,8 @@
|
|||
"dotenv": "^16.4.7",
|
||||
"eslint": "^9.18.0",
|
||||
"eslint-config-prettier": "^10.0.0",
|
||||
"eslint-plugin-svelte": "^2.46.1",
|
||||
"eslint-plugin-unicorn": "^56.0.1",
|
||||
"eslint-plugin-svelte": "^3.0.0",
|
||||
"eslint-plugin-unicorn": "^57.0.0",
|
||||
"factory.ts": "^1.4.1",
|
||||
"globals": "^16.0.0",
|
||||
"postcss": "^8.5.0",
|
||||
|
|
|
@ -169,7 +169,7 @@
|
|||
</script>
|
||||
|
||||
<div class="flex flex-col gap-7">
|
||||
{#each jobList as [jobName, { title, subtitle, description, disabled, allText, refreshText, missingText, icon, handleCommand: handleCommandOverride }]}
|
||||
{#each jobList as [jobName, { title, subtitle, description, disabled, allText, refreshText, missingText, icon, handleCommand: handleCommandOverride }] (jobName)}
|
||||
{@const { jobCounts, queueStatus } = jobs[jobName]}
|
||||
<JobTile
|
||||
{icon}
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
<div>
|
||||
<div in:fade={{ duration: 500 }}>
|
||||
<form autocomplete="off" {onsubmit}>
|
||||
{#each jobNames as jobName}
|
||||
{#each jobNames as jobName (jobName)}
|
||||
<div class="ml-4 mt-4 flex flex-col gap-4">
|
||||
{#if isSystemConfigJobDto(jobName)}
|
||||
<SettingInputField
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
<hr />
|
||||
|
||||
<div>
|
||||
{#each config.machineLearning.urls as _, i}
|
||||
{#each config.machineLearning.urls as _, i (i)}
|
||||
{#snippet removeButton()}
|
||||
{#if config.machineLearning.urls.length > 1}
|
||||
<CircleIconButton
|
||||
|
|
|
@ -225,7 +225,7 @@
|
|||
bind:value={selectedPreset}
|
||||
onchange={handlePresetSelection}
|
||||
>
|
||||
{#each templateOptions.presetOptions as preset}
|
||||
{#each templateOptions.presetOptions as preset (preset)}
|
||||
<option value={preset}>{renderTemplate(preset)}</option>
|
||||
{/each}
|
||||
</select>
|
||||
|
@ -246,7 +246,7 @@
|
|||
<SettingInputField
|
||||
label={$t('extension')}
|
||||
inputType={SettingInputFieldType.TEXT}
|
||||
value={'.jpg'}
|
||||
value=".jpg"
|
||||
disabled
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
<h4>{$t('date_and_time').toUpperCase()}</h4>
|
||||
</div>
|
||||
|
||||
<!-- eslint-disable svelte/no-useless-mustaches -->
|
||||
<div class="mt-2 rounded-lg bg-gray-200 p-4 text-xs dark:bg-gray-700 dark:text-immich-dark-fg">
|
||||
<div class="mb-2 text-gray-600 dark:text-immich-dark-fg">
|
||||
<p>{$t('admin.storage_template_date_time_description')}</p>
|
||||
|
@ -28,7 +29,7 @@
|
|||
<div>
|
||||
<p class="font-medium text-immich-primary dark:text-immich-dark-primary">{$t('year').toUpperCase()}</p>
|
||||
<ul>
|
||||
{#each options.yearOptions as yearFormat}
|
||||
{#each options.yearOptions as yearFormat, index (index)}
|
||||
<li>{'{{'}{yearFormat}{'}}'} - {getLuxonExample(yearFormat)}</li>
|
||||
{/each}
|
||||
</ul>
|
||||
|
@ -37,7 +38,7 @@
|
|||
<div>
|
||||
<p class="font-medium text-immich-primary dark:text-immich-dark-primary">{$t('month').toUpperCase()}</p>
|
||||
<ul>
|
||||
{#each options.monthOptions as monthFormat}
|
||||
{#each options.monthOptions as monthFormat, index (index)}
|
||||
<li>{'{{'}{monthFormat}{'}}'} - {getLuxonExample(monthFormat)}</li>
|
||||
{/each}
|
||||
</ul>
|
||||
|
@ -46,7 +47,7 @@
|
|||
<div>
|
||||
<p class="font-medium text-immich-primary dark:text-immich-dark-primary">{$t('week').toUpperCase()}</p>
|
||||
<ul>
|
||||
{#each options.weekOptions as weekFormat}
|
||||
{#each options.weekOptions as weekFormat, index (index)}
|
||||
<li>{'{{'}{weekFormat}{'}}'} - {getLuxonExample(weekFormat)}</li>
|
||||
{/each}
|
||||
</ul>
|
||||
|
@ -55,7 +56,7 @@
|
|||
<div>
|
||||
<p class="font-medium text-immich-primary dark:text-immich-dark-primary">{$t('day').toUpperCase()}</p>
|
||||
<ul>
|
||||
{#each options.dayOptions as dayFormat}
|
||||
{#each options.dayOptions as dayFormat, index (index)}
|
||||
<li>{'{{'}{dayFormat}{'}}'} - {getLuxonExample(dayFormat)}</li>
|
||||
{/each}
|
||||
</ul>
|
||||
|
@ -64,7 +65,7 @@
|
|||
<div>
|
||||
<p class="font-medium text-immich-primary dark:text-immich-dark-primary">{$t('hour').toUpperCase()}</p>
|
||||
<ul>
|
||||
{#each options.hourOptions as dayFormat}
|
||||
{#each options.hourOptions as dayFormat, index (index)}
|
||||
<li>{'{{'}{dayFormat}{'}}'} - {getLuxonExample(dayFormat)}</li>
|
||||
{/each}
|
||||
</ul>
|
||||
|
@ -73,7 +74,7 @@
|
|||
<div>
|
||||
<p class="font-medium text-immich-primary dark:text-immich-dark-primary">{$t('minute').toUpperCase()}</p>
|
||||
<ul>
|
||||
{#each options.minuteOptions as dayFormat}
|
||||
{#each options.minuteOptions as dayFormat, index (index)}
|
||||
<li>{'{{'}{dayFormat}{'}}'} - {getLuxonExample(dayFormat)}</li>
|
||||
{/each}
|
||||
</ul>
|
||||
|
@ -82,7 +83,7 @@
|
|||
<div>
|
||||
<p class="font-medium text-immich-primary dark:text-immich-dark-primary">{$t('second').toUpperCase()}</p>
|
||||
<ul>
|
||||
{#each options.secondOptions as dayFormat}
|
||||
{#each options.secondOptions as dayFormat, index (index)}
|
||||
<li>{'{{'}{dayFormat}{'}}'} - {getLuxonExample(dayFormat)}</li>
|
||||
{/each}
|
||||
</ul>
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
<LoadingSpinner />
|
||||
{/if}
|
||||
|
||||
{#each templateConfigs as { label, templateKey, descriptionTags, templateName }}
|
||||
{#each templateConfigs as { label, templateKey, descriptionTags, templateName } (templateKey)}
|
||||
<SettingTextarea
|
||||
{label}
|
||||
description={$t('admin.template_email_available_tags', { values: { tags: descriptionTags } })}
|
||||
|
|
|
@ -95,7 +95,7 @@
|
|||
<p class="text-sm">{$t('owner')}</p>
|
||||
</div>
|
||||
</div>
|
||||
{#each album.albumUsers as { user, role }}
|
||||
{#each album.albumUsers as { user, role } (user.id)}
|
||||
<div
|
||||
class="flex w-full place-items-center justify-between gap-4 p-5 rounded-xl transition-colors hover:bg-gray-50 dark:hover:bg-gray-700"
|
||||
>
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
<div class="mb-2 py-2 sticky">
|
||||
<p class="text-xs font-medium">{$t('selected')}</p>
|
||||
<div class="my-2">
|
||||
{#each Object.values(selectedUsers) as { user }}
|
||||
{#each Object.values(selectedUsers) as { user } (user.id)}
|
||||
{#key user.id}
|
||||
<div class="flex place-items-center gap-4 p-4">
|
||||
<div
|
||||
|
@ -116,7 +116,7 @@
|
|||
<Text>{$t('users')}</Text>
|
||||
|
||||
<div class="my-2">
|
||||
{#each users as user}
|
||||
{#each users as user (user.id)}
|
||||
{#if !Object.keys(selectedUsers).includes(user.id)}
|
||||
<div class="flex place-items-center transition-all hover:bg-gray-200 dark:hover:bg-gray-700 rounded-xl">
|
||||
<button type="button" onclick={() => handleToggle(user)} class="flex w-full place-items-center gap-4 p-4">
|
||||
|
@ -161,7 +161,7 @@
|
|||
</div>
|
||||
|
||||
<Stack gap={4}>
|
||||
{#each sharedLinks as sharedLink}
|
||||
{#each sharedLinks as sharedLink (sharedLink.id)}
|
||||
<AlbumSharedLink {album} {sharedLink} />
|
||||
{/each}
|
||||
</Stack>
|
||||
|
|
|
@ -536,7 +536,7 @@
|
|||
{#if albums.length > 0}
|
||||
<section class="px-6 pt-6 dark:text-immich-dark-fg">
|
||||
<p class="pb-4 text-sm">{$t('appears_in').toUpperCase()}</p>
|
||||
{#each albums as album}
|
||||
{#each albums as album (album.id)}
|
||||
<a href="{AppRoute.ALBUMS}/{album.id}">
|
||||
<div class="flex gap-4 pt-2 hover:cursor-pointer items-center">
|
||||
<div>
|
||||
|
|
|
@ -137,7 +137,7 @@
|
|||
<div class="flex h-10 w-full items-center justify-between text-sm">
|
||||
<h2>{$t('editor_crop_tool_h2_aspect_ratios').toUpperCase()}</h2>
|
||||
</div>
|
||||
{#each sizesRows as sizesRow}
|
||||
{#each sizesRows as sizesRow, index (index)}
|
||||
<ul class="flex-wrap flex-row flex gap-x-6 py-2 justify-evenly">
|
||||
{#each sizesRow as size (size.name)}
|
||||
<CropPreset {size} {selectedSize} {rotateHorizontal} {selectType} />
|
||||
|
|
|
@ -325,7 +325,7 @@
|
|||
<div class="h-[250px] overflow-y-auto mt-2">
|
||||
{#if filteredCandidates.length > 0}
|
||||
<div class="mt-2 rounded-lg">
|
||||
{#each filteredCandidates as person}
|
||||
{#each filteredCandidates as person (person.id)}
|
||||
<button
|
||||
onclick={() => tagFace(person)}
|
||||
type="button"
|
||||
|
|
|
@ -225,6 +225,7 @@
|
|||
: slideshowLookCssMapping[$slideshowLook]}"
|
||||
draggable="false"
|
||||
/>
|
||||
<!-- eslint-disable-next-line svelte/require-each-key -->
|
||||
{#each getBoundingBox($boundingBoxesArray, $photoZoomState, $photoViewerImgElement) as boundingbox}
|
||||
<div
|
||||
class="absolute border-solid border-white border-[3px] rounded-lg"
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
<div class="absolute z-50 top-2 left-2 transition-transform {isFocused ? 'translate-y-0' : '-translate-y-10 sr-only'}">
|
||||
<Button
|
||||
size={'sm'}
|
||||
size="sm"
|
||||
rounded="none"
|
||||
onclick={moveFocus}
|
||||
onfocus={() => (isFocused = true)}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
class="dark:bg-immich-dark-gray flex h-full rounded-2xl bg-gray-200 ring-gray-400 has-[:focus-visible]:ring dark:ring-gray-600"
|
||||
>
|
||||
<legend class="sr-only">{label}</legend>
|
||||
{#each filters as filter, index}
|
||||
{#each filters as filter, index (`${id}-${index}`)}
|
||||
<div class="group">
|
||||
<input
|
||||
type="radio"
|
||||
|
|
|
@ -111,7 +111,7 @@
|
|||
<div></div>
|
||||
{/snippet}
|
||||
{#snippet trailing()}
|
||||
<Button size={'sm'} disabled={!hasSelection} onclick={handleMerge}>
|
||||
<Button size="sm" disabled={!hasSelection} onclick={handleMerge}>
|
||||
<Icon path={mdiMerge} size={18} />
|
||||
<span class="ml-2">{$t('merge')}</span></Button
|
||||
>
|
||||
|
|
|
@ -221,7 +221,7 @@
|
|||
<LoadingSpinner />
|
||||
</div>
|
||||
{:else}
|
||||
{#each peopleWithFaces as face, index}
|
||||
{#each peopleWithFaces as face, index (face.id)}
|
||||
{@const personName = face.person ? face.person?.name : $t('face_unassigned')}
|
||||
<div class="relative z-[20001] h-[115px] w-[95px]">
|
||||
<div
|
||||
|
|
|
@ -131,7 +131,7 @@
|
|||
<div class="flex gap-4">
|
||||
<Button
|
||||
title={$t('create_new_person_hint')}
|
||||
size={'sm'}
|
||||
size="sm"
|
||||
disabled={disableButtons || hasSelection}
|
||||
onclick={handleCreate}
|
||||
>
|
||||
|
@ -143,7 +143,7 @@
|
|||
<span class="ml-2"> {$t('create_new_person')}</span></Button
|
||||
>
|
||||
<Button
|
||||
size={'sm'}
|
||||
size="sm"
|
||||
title={$t('reassing_hint')}
|
||||
disabled={disableButtons || !hasSelection}
|
||||
onclick={handleReassign}
|
||||
|
|
|
@ -175,7 +175,7 @@
|
|||
<form {onsubmit} autocomplete="off" class="m-4 flex flex-col gap-4">
|
||||
<table class="text-left">
|
||||
<tbody class="block w-full overflow-y-auto rounded-md border dark:border-immich-dark-gray">
|
||||
{#each validatedPaths as validatedPath, listIndex}
|
||||
{#each validatedPaths as validatedPath, listIndex (validatedPath.importPath)}
|
||||
<tr
|
||||
class={`flex h-[80px] w-full place-items-center text-center dark:text-immich-dark-fg ${
|
||||
listIndex % 2 == 0
|
||||
|
|
|
@ -125,7 +125,7 @@
|
|||
<form {onsubmit} autocomplete="off" class="m-4 flex flex-col gap-4">
|
||||
<table class="w-full text-left">
|
||||
<tbody class="block w-full overflow-y-auto rounded-md border dark:border-immich-dark-gray">
|
||||
{#each exclusionPatterns as exclusionPattern, listIndex}
|
||||
{#each exclusionPatterns as exclusionPattern, listIndex (exclusionPattern)}
|
||||
<tr
|
||||
class={`flex h-[80px] w-full place-items-center text-center dark:text-immich-dark-fg ${
|
||||
listIndex % 2 == 0
|
||||
|
|
|
@ -129,6 +129,7 @@ Used for every occurrence of an HTML tag in a message
|
|||
Result: Visit <a href="">docs</a> <strong>now</strong>
|
||||
```
|
||||
-->
|
||||
<!-- eslint-disable-next-line svelte/require-each-key -->
|
||||
{#each parts as { tag, message }}
|
||||
{#if tag}
|
||||
{#if children}{@render children({ tag, message })}{:else}{message}{/if}
|
||||
|
|
|
@ -183,6 +183,7 @@
|
|||
if (!current) {
|
||||
return;
|
||||
}
|
||||
// eslint-disable-next-line no-self-assign
|
||||
current.memory.assets = current.memory.assets;
|
||||
};
|
||||
|
||||
|
@ -222,6 +223,7 @@
|
|||
|
||||
current.memory.assets = current.memory.assets.filter((asset) => asset.id !== current.asset.id);
|
||||
|
||||
// eslint-disable-next-line no-self-assign
|
||||
$memoryStore = $memoryStore;
|
||||
|
||||
await removeMemoryAssets({ id: current.memory.id, bulkIdsDto: { ids: [current.asset.id] } });
|
||||
|
@ -351,7 +353,7 @@
|
|||
class="hover:text-black"
|
||||
/>
|
||||
|
||||
{#each current.memory.assets as asset, index}
|
||||
{#each current.memory.assets as asset, index (asset.id)}
|
||||
<a class="relative w-full py-2" href={asHref(asset)}>
|
||||
<span class="absolute left-0 h-[2px] w-full bg-gray-500"></span>
|
||||
{#await resetPromise}
|
||||
|
@ -475,14 +477,10 @@
|
|||
align="bottom-right"
|
||||
class="text-white dark:text-white"
|
||||
>
|
||||
<MenuOption
|
||||
onClick={() => handleDeleteMemory(current)}
|
||||
text={'Remove memory'}
|
||||
icon={mdiCardsOutline}
|
||||
/>
|
||||
<MenuOption onClick={() => handleDeleteMemory(current)} text="Remove memory" icon={mdiCardsOutline} />
|
||||
<MenuOption
|
||||
onClick={() => handleDeleteMemoryAsset(current)}
|
||||
text={'Remove photo from this memory'}
|
||||
text="Remove photo from this memory"
|
||||
icon={mdiImageMinusOutline}
|
||||
/>
|
||||
<!-- shortcut={{ key: 'l', shift: shared }} -->
|
||||
|
|
|
@ -32,41 +32,39 @@
|
|||
|
||||
{#if config && $user}
|
||||
<AdminSettings bind:config bind:this={adminSettingsComponent}>
|
||||
{#snippet children()}
|
||||
{#if config}
|
||||
<SettingSwitch
|
||||
title={$t('admin.map_settings')}
|
||||
subtitle={$t('admin.map_implications')}
|
||||
bind:checked={config.map.enabled}
|
||||
/>
|
||||
<SettingSwitch
|
||||
title={$t('admin.version_check_settings')}
|
||||
subtitle={$t('admin.version_check_implications')}
|
||||
bind:checked={config.newVersionCheck.enabled}
|
||||
/>
|
||||
<div class="flex pt-4">
|
||||
<div class="w-full flex place-content-start">
|
||||
<Button class="flex gap-2 place-content-center" onclick={() => onPrevious()}>
|
||||
<Icon path={mdiArrowLeft} size="18" />
|
||||
<p>{$t('theme')}</p>
|
||||
</Button>
|
||||
</div>
|
||||
<div class="flex w-full place-content-end">
|
||||
<Button
|
||||
onclick={() => {
|
||||
adminSettingsComponent?.handleSave({ map: config?.map, newVersionCheck: config?.newVersionCheck });
|
||||
onDone();
|
||||
}}
|
||||
>
|
||||
<span class="flex place-content-center place-items-center gap-2">
|
||||
{$t('admin.storage_template_settings')}
|
||||
<Icon path={mdiArrowRight} size="18" />
|
||||
</span>
|
||||
</Button>
|
||||
</div>
|
||||
{#if config}
|
||||
<SettingSwitch
|
||||
title={$t('admin.map_settings')}
|
||||
subtitle={$t('admin.map_implications')}
|
||||
bind:checked={config.map.enabled}
|
||||
/>
|
||||
<SettingSwitch
|
||||
title={$t('admin.version_check_settings')}
|
||||
subtitle={$t('admin.version_check_implications')}
|
||||
bind:checked={config.newVersionCheck.enabled}
|
||||
/>
|
||||
<div class="flex pt-4">
|
||||
<div class="w-full flex place-content-start">
|
||||
<Button class="flex gap-2 place-content-center" onclick={() => onPrevious()}>
|
||||
<Icon path={mdiArrowLeft} size="18" />
|
||||
<p>{$t('theme')}</p>
|
||||
</Button>
|
||||
</div>
|
||||
{/if}
|
||||
{/snippet}
|
||||
<div class="flex w-full place-content-end">
|
||||
<Button
|
||||
onclick={() => {
|
||||
adminSettingsComponent?.handleSave({ map: config?.map, newVersionCheck: config?.newVersionCheck });
|
||||
onDone();
|
||||
}}
|
||||
>
|
||||
<span class="flex place-content-center place-items-center gap-2">
|
||||
{$t('admin.storage_template_settings')}
|
||||
<Icon path={mdiArrowRight} size="18" />
|
||||
</span>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</AdminSettings>
|
||||
{/if}
|
||||
</OnboardingCard>
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
};
|
||||
</script>
|
||||
|
||||
{#each jobs as job}
|
||||
{#each jobs as job (job)}
|
||||
{#if isAllVideos || job !== AssetJobName.TranscodeVideo}
|
||||
<MenuOption text={$getAssetJobName(job)} icon={getAssetJobIcon(job)} onClick={() => handleRunJob(job)} />
|
||||
{/if}
|
||||
|
|
|
@ -119,7 +119,7 @@
|
|||
data-date-group={dateGroup.date}
|
||||
style:height={dateGroup.height + 'px'}
|
||||
style:width={dateGroup.geometry.containerWidth + 'px'}
|
||||
style:overflow={'clip'}
|
||||
style:overflow="clip"
|
||||
>
|
||||
{#if !display}
|
||||
<Skeleton height={dateGroup.height + 'px'} title={dateGroup.groupTitle} />
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
</script>
|
||||
|
||||
<section id="measure-asset-group-by-date" class="flex flex-wrap gap-x-12" use:measure>
|
||||
{#each bucket.dateGroups as dateGroup}
|
||||
{#each bucket.dateGroups as dateGroup (dateGroup.date)}
|
||||
<div id="date-group" data-date-group={dateGroup.date}>
|
||||
<div use:resizeObserver={({ height }) => $assetStore.updateBucketDateGroup(bucket, dateGroup, { height })}>
|
||||
<div
|
||||
|
@ -83,7 +83,7 @@
|
|||
class="relative overflow-clip"
|
||||
style:height={dateGroup.geometry.containerHeight + 'px'}
|
||||
style:width={dateGroup.geometry.containerWidth + 'px'}
|
||||
style:visibility={'hidden'}
|
||||
style:visibility="hidden"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
</div>
|
||||
{/if}
|
||||
<div class="inline-block" use:resizeObserver={({ width }) => (innerWidth = width)}>
|
||||
{#each $memoryStore as memory}
|
||||
{#each $memoryStore as memory (memory.id)}
|
||||
{#if memory.assets.length > 0}
|
||||
<a
|
||||
class="memory-card relative mr-8 inline-block aspect-[3/4] md:aspect-video h-[215px] rounded-xl"
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
<div class="mt-4">
|
||||
{#if !isCollapsed}
|
||||
<div class="flex flex-row flex-wrap gap-4">
|
||||
{#each places as item}
|
||||
{#each places as item (item.id)}
|
||||
{@const city = item.exifInfo?.city}
|
||||
<a class="relative" href="{AppRoute.SEARCH}?{getMetadataSearchQuery({ city })}" draggable="false">
|
||||
<div
|
||||
|
|
|
@ -83,6 +83,7 @@
|
|||
<FullScreenModal title={shared ? $t('add_to_shared_album') : $t('add_to_album')} {onClose}>
|
||||
<div class="mb-2 flex max-h-[400px] flex-col">
|
||||
{#if loading}
|
||||
<!-- eslint-disable-next-line svelte/require-each-key -->
|
||||
{#each { length: 3 } as _}
|
||||
<div class="flex animate-pulse gap-4 px-6 py-2">
|
||||
<div class="h-12 w-12 rounded-xl bg-slate-200"></div>
|
||||
|
@ -104,6 +105,7 @@
|
|||
use:initInput
|
||||
/>
|
||||
<div class="immich-scrollbar overflow-y-auto">
|
||||
<!-- eslint-disable-next-line svelte/require-each-key -->
|
||||
{#each albumModalRows as row}
|
||||
{#if row.type === AlbumModalRowType.NEW_ALBUM}
|
||||
<NewAlbumListItem selected={row.selected || false} {onNewAlbum} searchQuery={search} />
|
||||
|
|
|
@ -139,7 +139,7 @@
|
|||
use:clickOutside={{ onOutclick: () => (hideSuggestion = true) }}
|
||||
>
|
||||
{#if !hideSuggestion}
|
||||
{#each suggestedPlaces as place, index}
|
||||
{#each suggestedPlaces as place, index (place.latitude + place.longitude)}
|
||||
<button
|
||||
type="button"
|
||||
class=" flex w-full border-t border-gray-400 dark:border-immich-dark-gray h-14 place-items-center bg-gray-200 p-2 dark:bg-gray-700 hover:bg-gray-300 hover:dark:bg-[#232932] focus:bg-gray-300 focus:dark:bg-[#232932] {index ===
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
>
|
||||
<div class="flex place-items-center sm:gap-6 justify-self-start dark:text-immich-dark-fg">
|
||||
{#if showBackButton}
|
||||
<CircleIconButton title={$t('close')} onclick={handleClose} icon={backIcon} size={'24'} class={buttonClass} />
|
||||
<CircleIconButton title={$t('close')} onclick={handleClose} icon={backIcon} size="24" class={buttonClass} />
|
||||
{/if}
|
||||
{@render leading?.()}
|
||||
</div>
|
||||
|
|
|
@ -37,5 +37,5 @@
|
|||
</h1>
|
||||
</div>
|
||||
|
||||
<CircleIconButton onclick={onClose} icon={mdiClose} size={'20'} title={$t('close')} />
|
||||
<CircleIconButton onclick={onClose} icon={mdiClose} size="20" title={$t('close')} />
|
||||
</div>
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<FullScreenModal title={$t('select_avatar_color')} width="auto" {onClose}>
|
||||
<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}
|
||||
{#each colors as color (color)}
|
||||
<button type="button" onclick={() => onChoose(color)}>
|
||||
<UserAvatar label={color} {user} {color} size="xl" showProfileImage={false} />
|
||||
</button>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
</script>
|
||||
|
||||
<Portal>
|
||||
<FullScreenModal showLogo title={''} {onClose} width="wide">
|
||||
<FullScreenModal showLogo title="" {onClose} width="wide">
|
||||
{#if showProductActivated}
|
||||
<PurchaseActivationSuccess onDone={onClose} />
|
||||
{:else}
|
||||
|
|
|
@ -278,7 +278,7 @@
|
|||
{/if}
|
||||
</div>
|
||||
<!-- Time Segment -->
|
||||
{#each segments as segment}
|
||||
{#each segments as segment (segment.date)}
|
||||
<div
|
||||
id="time-segment"
|
||||
class="relative"
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
}
|
||||
} else {
|
||||
$accordionState.delete(key);
|
||||
// eslint-disable-next-line no-self-assign
|
||||
$accordionState = $accordionState;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
</script>
|
||||
|
||||
<div class="mb-4 w-full">
|
||||
<div class={`flex h-[26px] place-items-center gap-1`}>
|
||||
<div class="flex h-[26px] place-items-center gap-1">
|
||||
<label class="font-medium text-immich-primary dark:text-immich-dark-primary text-sm" for="{name}-select">
|
||||
{label}
|
||||
</label>
|
||||
|
@ -51,7 +51,7 @@
|
|||
</p>
|
||||
{/if}
|
||||
<div class="flex flex-col gap-2">
|
||||
{#each options as option}
|
||||
{#each options as option (option.value)}
|
||||
<Checkbox
|
||||
id="{option.value}-checkbox"
|
||||
label={option.text}
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
</script>
|
||||
|
||||
<div class="mb-4 w-full">
|
||||
<div class={`flex place-items-center gap-1`}>
|
||||
<div class="flex place-items-center gap-1">
|
||||
<label class="font-medium text-immich-primary dark:text-immich-dark-primary text-sm" for={label}>{label}</label>
|
||||
{#if required}
|
||||
<div class="text-red-400">*</div>
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
</script>
|
||||
|
||||
<div class="mb-4 w-full">
|
||||
<div class={`flex h-[26px] place-items-center gap-1`}>
|
||||
<div class="flex h-[26px] place-items-center gap-1">
|
||||
<label class="font-medium text-immich-primary dark:text-immich-dark-primary text-sm" for="{name}-select"
|
||||
>{label}</label
|
||||
>
|
||||
|
@ -63,7 +63,7 @@
|
|||
<div class="grid">
|
||||
<Icon
|
||||
path={mdiChevronDown}
|
||||
size={'1.2em'}
|
||||
size="1.2em"
|
||||
ariaHidden={true}
|
||||
class="pointer-events-none right-1 relative col-start-1 row-start-1 self-center justify-self-end {disabled
|
||||
? 'text-immich-bg'
|
||||
|
@ -78,7 +78,7 @@
|
|||
bind:value
|
||||
onchange={handleChange}
|
||||
>
|
||||
{#each options as option}
|
||||
{#each options as option (option.value)}
|
||||
<option value={option.value}>{option.text}</option>
|
||||
{/each}
|
||||
</select>
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
</script>
|
||||
|
||||
<div class="mb-4 w-full">
|
||||
<div class={`flex h-[26px] place-items-center gap-1`}>
|
||||
<div class="flex h-[26px] place-items-center gap-1">
|
||||
<label class="font-medium text-immich-primary dark:text-immich-dark-primary text-sm" for={label}>{label}</label>
|
||||
{#if required}
|
||||
<div class="text-red-400">*</div>
|
||||
|
|
|
@ -50,10 +50,10 @@
|
|||
<div class="p-4">
|
||||
<h2>{$t('general')}</h2>
|
||||
<div class="text-sm">
|
||||
{#each shortcuts.general as shortcut}
|
||||
{#each shortcuts.general as shortcut (shortcut.key.join('-'))}
|
||||
<div class="grid grid-cols-[30%_70%] items-center gap-4 pt-4 text-sm">
|
||||
<div class="flex justify-self-end">
|
||||
{#each shortcut.key as key}
|
||||
{#each shortcut.key as key (key)}
|
||||
<p class="mr-1 flex items-center justify-center justify-self-end rounded-lg bg-immich-primary/25 p-2">
|
||||
{key}
|
||||
</p>
|
||||
|
@ -69,10 +69,10 @@
|
|||
<div class="p-4">
|
||||
<h2>{$t('actions')}</h2>
|
||||
<div class="text-sm">
|
||||
{#each shortcuts.actions as shortcut}
|
||||
{#each shortcuts.actions as shortcut (shortcut.key.join('-'))}
|
||||
<div class="grid grid-cols-[30%_70%] items-center gap-4 pt-4 text-sm">
|
||||
<div class="flex justify-self-end">
|
||||
{#each shortcut.key as key}
|
||||
{#each shortcut.key as key (key)}
|
||||
<p class="mr-1 flex items-center justify-center justify-self-end rounded-lg bg-immich-primary/25 p-2">
|
||||
{key}
|
||||
</p>
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
});
|
||||
</script>
|
||||
|
||||
{#each albums as album}
|
||||
{#each albums as album (album.id)}
|
||||
<a
|
||||
href={'/albums/' + album.id}
|
||||
title={album.albumName}
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
>
|
||||
<legend class="sr-only">{$t('rating')}</legend>
|
||||
<div class="flex flex-row" data-testid="star-container">
|
||||
{#each { length: count } as _, index}
|
||||
{#each { length: count } as _, index (index)}
|
||||
{@const value = index + 1}
|
||||
{@const filled = hoverRating >= value || (hoverRating === 0 && ratingSelection >= value)}
|
||||
{@const starId = `${id}-${value}`}
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
onclick={() => {}}
|
||||
/>
|
||||
</li>
|
||||
{#each pathSegments as segment, index}
|
||||
{#each pathSegments as segment, index (segment)}
|
||||
{@const isLastSegment = index === pathSegments.length - 1}
|
||||
<li
|
||||
class="flex gap-2 items-center font-mono text-sm text-nowrap text-immich-primary dark:text-immich-dark-primary"
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<div
|
||||
class="w-full grid grid-cols-2 sm:grid-cols-4 lg:grid-cols-6 2xl:grid-cols-8 gap-2 bg-gray-50 dark:bg-immich-dark-gray/50 rounded-2xl border border-gray-100 dark:border-gray-900"
|
||||
>
|
||||
{#each items as item}
|
||||
{#each items as item (item)}
|
||||
<button
|
||||
class="flex flex-col place-items-center gap-2 py-2 px-4 hover:bg-immich-primary/10 dark:hover:bg-immich-primary/40 rounded-xl"
|
||||
onclick={() => onClick(item)}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
</script>
|
||||
|
||||
<ul class="list-none ml-2">
|
||||
<!-- eslint-disable-next-line svelte/require-each-key -->
|
||||
{#each Object.entries(items).sort() as [path, tree]}
|
||||
{@const value = normalizeTreePath(`${parent}/${path}`)}
|
||||
{@const key = value + getColor(value)}
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
<h3 class="mb-2 text-xs font-medium text-immich-primary dark:text-immich-dark-primary">
|
||||
{$t('other_devices').toUpperCase()}
|
||||
</h3>
|
||||
{#each otherDevices as device, index}
|
||||
{#each otherDevices as device, index (device.id)}
|
||||
<DeviceCard {device} onDelete={() => handleDelete(device)} />
|
||||
{#if index !== otherDevices.length - 1}
|
||||
<hr class="my-3" />
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
<FullScreenModal title={$t('add_partner')} showLogo {onClose}>
|
||||
<div class="immich-scrollbar max-h-[300px] overflow-y-auto">
|
||||
{#if availableUsers.length > 0}
|
||||
{#each availableUsers as user}
|
||||
{#each availableUsers as user (user.id)}
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => selectUser(user)}
|
||||
|
|
|
@ -144,7 +144,7 @@
|
|||
<CircleIconButton
|
||||
onclick={() => handleRemovePartner(partner.user)}
|
||||
icon={mdiClose}
|
||||
size={'16'}
|
||||
size="16"
|
||||
title={$t('stop_sharing_photos_with_user')}
|
||||
/>
|
||||
{/if}
|
||||
|
|
|
@ -137,37 +137,35 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody class="block w-full overflow-y-auto rounded-md border dark:border-immich-dark-gray">
|
||||
{#each keys as key, index}
|
||||
{#key key.id}
|
||||
<tr
|
||||
class={`flex h-[80px] w-full place-items-center text-center dark:text-immich-dark-fg ${
|
||||
index % 2 == 0
|
||||
? 'bg-immich-gray dark:bg-immich-dark-gray/75'
|
||||
: 'bg-immich-bg dark:bg-immich-dark-gray/50'
|
||||
}`}
|
||||
>
|
||||
<td class="w-1/3 text-ellipsis px-4 text-sm">{key.name}</td>
|
||||
<td class="w-1/3 text-ellipsis px-4 text-sm"
|
||||
>{new Date(key.createdAt).toLocaleDateString($locale, format)}
|
||||
</td>
|
||||
<td class="flex flex-row flex-wrap justify-center gap-x-2 gap-y-1 w-1/3">
|
||||
<CircleIconButton
|
||||
color="primary"
|
||||
icon={mdiPencilOutline}
|
||||
title={$t('edit_key')}
|
||||
size="16"
|
||||
onclick={() => (editKey = key)}
|
||||
/>
|
||||
<CircleIconButton
|
||||
color="primary"
|
||||
icon={mdiTrashCanOutline}
|
||||
title={$t('delete_key')}
|
||||
size="16"
|
||||
onclick={() => handleDelete(key)}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
{/key}
|
||||
{#each keys as key, index (key.id)}
|
||||
<tr
|
||||
class={`flex h-[80px] w-full place-items-center text-center dark:text-immich-dark-fg ${
|
||||
index % 2 == 0
|
||||
? 'bg-immich-gray dark:bg-immich-dark-gray/75'
|
||||
: 'bg-immich-bg dark:bg-immich-dark-gray/50'
|
||||
}`}
|
||||
>
|
||||
<td class="w-1/3 text-ellipsis px-4 text-sm">{key.name}</td>
|
||||
<td class="w-1/3 text-ellipsis px-4 text-sm"
|
||||
>{new Date(key.createdAt).toLocaleDateString($locale, format)}
|
||||
</td>
|
||||
<td class="flex flex-row flex-wrap justify-center gap-x-2 gap-y-1 w-1/3">
|
||||
<CircleIconButton
|
||||
color="primary"
|
||||
icon={mdiPencilOutline}
|
||||
title={$t('edit_key')}
|
||||
size="16"
|
||||
onclick={() => (editKey = key)}
|
||||
/>
|
||||
<CircleIconButton
|
||||
color="primary"
|
||||
icon={mdiTrashCanOutline}
|
||||
title={$t('delete_key')}
|
||||
size="16"
|
||||
onclick={() => handleDelete(key)}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
|
@ -137,7 +137,7 @@
|
|||
await loadNextPage();
|
||||
}
|
||||
|
||||
export const loadNextPage = async () => {
|
||||
const loadNextPage = async () => {
|
||||
if (!nextPage || searchResultAssets.length >= MAX_ASSET_COUNT) {
|
||||
return;
|
||||
}
|
||||
|
@ -230,6 +230,7 @@
|
|||
return tagNames.join(', ');
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-self-assign
|
||||
const triggerAssetUpdate = () => (searchResultAssets = searchResultAssets);
|
||||
|
||||
const onAddToAlbum = (assetIds: string[]) => {
|
||||
|
|
|
@ -195,7 +195,7 @@
|
|||
</thead>
|
||||
<tbody class="block w-full overflow-y-auto rounded-md border dark:border-immich-dark-gray">
|
||||
{#if allUsers}
|
||||
{#each allUsers as immichUser, index}
|
||||
{#each allUsers as immichUser, index (immichUser.id)}
|
||||
<tr
|
||||
class="flex h-[80px] overflow-hidden w-full place-items-center text-center dark:text-immich-dark-fg {immichUser.deletedAt
|
||||
? 'bg-red-300 dark:bg-red-900'
|
||||
|
|
Loading…
Add table
Reference in a new issue