mirror of
https://github.com/immich-app/immich
synced 2025-11-14 17:36:12 +00:00
refactor: user edit modal (#23169)
This commit is contained in:
parent
e196cac6f4
commit
cb7e68a287
3 changed files with 32 additions and 26 deletions
10
pnpm-lock.yaml
generated
10
pnpm-lock.yaml
generated
|
|
@ -681,8 +681,8 @@ importers:
|
||||||
specifier: file:../open-api/typescript-sdk
|
specifier: file:../open-api/typescript-sdk
|
||||||
version: link:../open-api/typescript-sdk
|
version: link:../open-api/typescript-sdk
|
||||||
'@immich/ui':
|
'@immich/ui':
|
||||||
specifier: ^0.36.0
|
specifier: ^0.37.1
|
||||||
version: 0.36.4(@internationalized/date@3.8.2)(svelte@5.40.1)
|
version: 0.37.1(@internationalized/date@3.8.2)(svelte@5.40.1)
|
||||||
'@mapbox/mapbox-gl-rtl-text':
|
'@mapbox/mapbox-gl-rtl-text':
|
||||||
specifier: 0.2.3
|
specifier: 0.2.3
|
||||||
version: 0.2.3(mapbox-gl@1.13.3)
|
version: 0.2.3(mapbox-gl@1.13.3)
|
||||||
|
|
@ -2726,8 +2726,8 @@ packages:
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
|
|
||||||
'@immich/ui@0.36.4':
|
'@immich/ui@0.37.1':
|
||||||
resolution: {integrity: sha512-urA7yD3ylKPqh6BhctvnpwZ1BZke75qaArRvnmUhjy5mV9Bud4D/yqbX5BlYq+Z3TvNP365BPLJDj7euG91gZw==}
|
resolution: {integrity: sha512-8S9KsyqyRcNgRHeBU8G3qMQ7D7fN4u9I31jjRc9c3s2tkiYucASofPJdcFdmGZnKLX5fIj+yofxiNZV9tVitOg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
svelte: ^5.0.0
|
svelte: ^5.0.0
|
||||||
|
|
||||||
|
|
@ -14182,7 +14182,7 @@ snapshots:
|
||||||
'@img/sharp-win32-x64@0.34.4':
|
'@img/sharp-win32-x64@0.34.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@immich/ui@0.36.4(@internationalized/date@3.8.2)(svelte@5.40.1)':
|
'@immich/ui@0.37.1(@internationalized/date@3.8.2)(svelte@5.40.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@mdi/js': 7.4.47
|
'@mdi/js': 7.4.47
|
||||||
bits-ui: 2.9.8(@internationalized/date@3.8.2)(svelte@5.40.1)
|
bits-ui: 2.9.8(@internationalized/date@3.8.2)(svelte@5.40.1)
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@formatjs/icu-messageformat-parser": "^2.9.8",
|
"@formatjs/icu-messageformat-parser": "^2.9.8",
|
||||||
"@immich/sdk": "file:../open-api/typescript-sdk",
|
"@immich/sdk": "file:../open-api/typescript-sdk",
|
||||||
"@immich/ui": "^0.36.0",
|
"@immich/ui": "^0.37.1",
|
||||||
"@mapbox/mapbox-gl-rtl-text": "0.2.3",
|
"@mapbox/mapbox-gl-rtl-text": "0.2.3",
|
||||||
"@mdi/js": "^7.4.47",
|
"@mdi/js": "^7.4.47",
|
||||||
"@photo-sphere-viewer/core": "^5.11.5",
|
"@photo-sphere-viewer/core": "^5.11.5",
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,19 @@
|
||||||
import { ByteUnit, convertFromBytes, convertToBytes } from '$lib/utils/byte-units';
|
import { ByteUnit, convertFromBytes, convertToBytes } from '$lib/utils/byte-units';
|
||||||
import { handleError } from '$lib/utils/handle-error';
|
import { handleError } from '$lib/utils/handle-error';
|
||||||
import { updateUserAdmin, type UserAdminResponseDto } from '@immich/sdk';
|
import { updateUserAdmin, type UserAdminResponseDto } from '@immich/sdk';
|
||||||
import { Button, Field, HStack, Input, Label, Link, Modal, ModalBody, ModalFooter, Switch, Text } from '@immich/ui';
|
import {
|
||||||
|
Button,
|
||||||
|
Field,
|
||||||
|
HStack,
|
||||||
|
Input,
|
||||||
|
Link,
|
||||||
|
Modal,
|
||||||
|
ModalBody,
|
||||||
|
ModalFooter,
|
||||||
|
NumberInput,
|
||||||
|
Switch,
|
||||||
|
Text,
|
||||||
|
} from '@immich/ui';
|
||||||
import { mdiAccountEditOutline } from '@mdi/js';
|
import { mdiAccountEditOutline } from '@mdi/js';
|
||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
|
|
||||||
|
|
@ -21,15 +33,19 @@
|
||||||
let email = $derived(user.email);
|
let email = $derived(user.email);
|
||||||
let storageLabel = $derived(user.storageLabel || '');
|
let storageLabel = $derived(user.storageLabel || '');
|
||||||
|
|
||||||
let quotaSize = $state(user.quotaSizeInBytes === null ? null : convertFromBytes(user.quotaSizeInBytes, ByteUnit.GiB));
|
|
||||||
|
|
||||||
const previousQuota = user.quotaSizeInBytes;
|
const previousQuota = user.quotaSizeInBytes;
|
||||||
|
|
||||||
|
let quotaSize = $state(
|
||||||
|
typeof user.quotaSizeInBytes === 'number' ? convertFromBytes(user.quotaSizeInBytes, ByteUnit.GiB) : undefined,
|
||||||
|
);
|
||||||
|
|
||||||
|
const quotaSizeBytes = $derived(typeof quotaSize === 'number' ? convertToBytes(quotaSize, ByteUnit.GiB) : null);
|
||||||
|
|
||||||
let quotaSizeWarning = $derived(
|
let quotaSizeWarning = $derived(
|
||||||
previousQuota !== convertToBytes(Number(quotaSize), ByteUnit.GiB) &&
|
previousQuota !== quotaSizeBytes &&
|
||||||
!!quotaSize &&
|
!!quotaSizeBytes &&
|
||||||
userInteraction.serverInfo &&
|
userInteraction.serverInfo &&
|
||||||
convertToBytes(Number(quotaSize), ByteUnit.GiB) > userInteraction.serverInfo.diskSizeRaw,
|
quotaSizeBytes > userInteraction.serverInfo.diskSizeRaw,
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleEditUser = async () => {
|
const handleEditUser = async () => {
|
||||||
|
|
@ -40,7 +56,7 @@
|
||||||
email,
|
email,
|
||||||
name,
|
name,
|
||||||
storageLabel,
|
storageLabel,
|
||||||
quotaSizeInBytes: quotaSize === null ? null : convertToBytes(Number(quotaSize), ByteUnit.GiB),
|
quotaSizeInBytes: typeof quotaSize === 'number' ? convertToBytes(quotaSize, ByteUnit.GiB) : null,
|
||||||
isAdmin,
|
isAdmin,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
@ -68,22 +84,12 @@
|
||||||
<Input bind:value={name} />
|
<Input bind:value={name} />
|
||||||
</Field>
|
</Field>
|
||||||
|
|
||||||
<div class="flex flex-col gap-1 mt-4">
|
<Field label={$t('admin.quota_size_gib')} class="mt-4">
|
||||||
<Label class="flex items-center gap-2" for="quotaSize">{$t('admin.quota_size_gib')}</Label>
|
<NumberInput bind:value={quotaSize} min="0" step="1" placeholder={$t('unlimited')} />
|
||||||
<input
|
|
||||||
class="immich-form-input"
|
|
||||||
id="quotaSize"
|
|
||||||
name="quotaSize"
|
|
||||||
placeholder={$t('unlimited')}
|
|
||||||
type="number"
|
|
||||||
step="1"
|
|
||||||
min="0"
|
|
||||||
bind:value={quotaSize}
|
|
||||||
/>
|
|
||||||
{#if quotaSizeWarning}
|
{#if quotaSizeWarning}
|
||||||
<Text size="small" color="danger">{$t('errors.quota_higher_than_disk_size')}</Text>
|
<Text size="small" color="danger">{$t('errors.quota_higher_than_disk_size')}</Text>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</Field>
|
||||||
|
|
||||||
<Field label={$t('storage_label')} class="mt-4">
|
<Field label={$t('storage_label')} class="mt-4">
|
||||||
<Input bind:value={storageLabel} />
|
<Input bind:value={storageLabel} />
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue