Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(web): add warning when setting a quota superior to the disk size #6737

Merged
merged 4 commits into from
Jan 30, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions web/src/lib/components/forms/create-user-form.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import { notificationController, NotificationType } from '../shared-components/notification/notification';
import Button from '../elements/buttons/button.svelte';
import { convertToBytes } from '$lib/utils/byte-converter';
import { serverInfo } from '$lib/stores/server-info.store';

let error: string;
let success: string;
Expand All @@ -13,9 +14,11 @@
let confirmPassowrd = '';

let canCreateUser = false;

let quotaSize: number | undefined = undefined;
let isCreatingUser = false;

$: warning = quotaSize && convertToBytes(Number(quotaSize), 'GiB') > $serverInfo.diskSizeRaw;

$: {
if (password !== confirmPassowrd && confirmPassowrd.length > 0) {
error = 'Password does not match';
Expand Down Expand Up @@ -121,8 +124,12 @@
</div>

<div class="m-4 flex flex-col gap-2">
<label class="immich-form-label" for="quotaSize">Quota Size (GiB)</label>
<input class="immich-form-input" id="quotaSize" name="quotaSize" type="number" min="0" />
<label class="flex items-center gap-2 immich-form-label" for="quotaSize"
>Quota Size (GiB) {#if warning}
<p class="text-red-400 text-sm">You set a quota superior to the disk size</p>
martabal marked this conversation as resolved.
Show resolved Hide resolved
{/if}</label
>
<input class="immich-form-input" id="quotaSize" name="quotaSize" type="number" min="0" bind:value={quotaSize} />
</div>

{#if error}
Expand Down
18 changes: 14 additions & 4 deletions web/src/lib/components/forms/edit-user-form.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,29 @@
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
import { handleError } from '$lib/utils/handle-error';
import { convertFromBytes, convertToBytes } from '$lib/utils/byte-converter';
import { serverInfo } from '$lib/stores/server-info.store';

export let user: UserResponseDto;
export let canResetPassword = true;

let error: string;
let success: string;

let isShowResetPasswordConfirmation = false;
let quotaSize = user.quotaSizeInBytes ? convertFromBytes(user.quotaSizeInBytes, 'GiB') : null;

const previousQutoa = user.quotaSizeInBytes;

$: warning =
previousQutoa !== convertToBytes(Number(quotaSize), 'GiB') &&
!!quotaSize &&
convertToBytes(Number(quotaSize), 'GiB') > $serverInfo.diskSizeRaw;

const dispatch = createEventDispatcher<{
close: void;
resetPasswordSuccess: void;
editSuccess: void;
}>();

let quotaSize = user.quotaSizeInBytes ? convertFromBytes(user.quotaSizeInBytes, 'GiB') : null;

const editUser = async () => {
try {
const { id, email, name, storageLabel, externalPath } = user;
Expand Down Expand Up @@ -102,7 +108,11 @@
</div>

<div class="m-4 flex flex-col gap-2">
<label class="immich-form-label" for="quotaSize">Quota Size (GiB)</label>
<label class="flex items-center gap-2 immich-form-label" for="quotaSize"
>Quota Size (GiB) {#if warning}
<p class="text-red-400 text-sm">You set a quota superior to the disk size</p>
{/if}</label
>
<input class="immich-form-input" id="quotaSize" name="quotaSize" type="number" min="0" bind:value={quotaSize} />
<p>Note: Enter 0 for unlimited quota</p>
</div>
Expand Down
23 changes: 6 additions & 17 deletions web/src/lib/components/shared-components/status-box.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@
import Icon from '$lib/components/elements/icon.svelte';
import { locale } from '$lib/stores/preferences.store';
import { websocketStore } from '$lib/stores/websocket';
import { api } from '@api';
import { onMount } from 'svelte';
import { asByteUnitString } from '../../utils/byte-units';
import LoadingSpinner from './loading-spinner.svelte';
import { mdiChartPie, mdiDns } from '@mdi/js';
import { serverInfoStore } from '$lib/stores/server-info.store';
import { serverInfo } from '$lib/stores/server-info.store';
import { user } from '$lib/stores/user.store';
import { requestServerInfo } from '$lib/utils/auth';

const { serverVersion, connected } = websocketStore;

let usageClasses = '';

$: version = $serverVersion ? `v${$serverVersion.major}.${$serverVersion.minor}.${$serverVersion.patch}` : null;
$: hasQuota = $user?.quotaSizeInBytes !== null;
$: availableBytes = (hasQuota ? $user?.quotaSizeInBytes : $serverInfoStore?.diskSizeRaw) || 0;
$: usedBytes = (hasQuota ? $user?.quotaUsageInBytes : $serverInfoStore?.diskUseRaw) || 0;
$: availableBytes = (hasQuota ? $user?.quotaSizeInBytes : $serverInfo?.diskSizeRaw) || 0;
$: usedBytes = (hasQuota ? $user?.quotaUsageInBytes : $serverInfo?.diskUseRaw) || 0;
$: usedPercentage = Math.round((usedBytes / availableBytes) * 100);

const onUpdate = () => {
Expand All @@ -39,19 +39,8 @@
$: $user && onUpdate();

onMount(async () => {
await refresh();
await requestServerInfo();
});

const refresh = async () => {
try {
if (!$serverInfoStore) {
const { data } = await api.serverInfoApi.getServerInfo();
$serverInfoStore = data;
}
} catch (e) {
console.log('Error [StatusBox] [onMount]');
}
};
</script>

<div class="dark:text-immich-dark-fg">
Expand All @@ -64,7 +53,7 @@
</div>
<div class="hidden group-hover:sm:block md:block">
<p class="text-sm font-medium text-immich-primary dark:text-immich-dark-primary">Storage</p>
{#if $serverInfoStore}
{#if $serverInfo}
<div class="my-2 h-[7px] w-full rounded-full bg-gray-200 dark:bg-gray-700">
<div class="h-[7px] rounded-full {usageClasses}" style="width: {usedPercentage}%" />
</div>
Expand Down
2 changes: 1 addition & 1 deletion web/src/lib/stores/server-info.store.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { writable } from 'svelte/store';
import type { ServerInfoResponseDto } from '@api';

export const serverInfoStore = writable<ServerInfoResponseDto>();
export const serverInfo = writable<ServerInfoResponseDto>();
9 changes: 8 additions & 1 deletion web/src/lib/utils/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { api } from '@api';
import { redirect } from '@sveltejs/kit';
import { AppRoute } from '../constants';
import { getSavedUser, setUser } from '$lib/stores/user.store';
import { serverInfo } from '$lib/stores/server-info.store';

export interface AuthOptions {
admin?: true;
Expand All @@ -16,7 +17,6 @@ export const getAuthUser = async () => {
}
};

// TODO: re-use already loaded user (once) instead of fetching on each page navigation
export const authenticate = async (options?: AuthOptions) => {
options = options || {};

Expand All @@ -36,6 +36,13 @@ export const authenticate = async (options?: AuthOptions) => {
}
};

export const requestServerInfo = async () => {
if (getSavedUser()) {
const { data } = await api.serverInfoApi.getServerInfo();
serverInfo.set(data);
}
};

export const isLoggedIn = async () => {
const savedUser = getSavedUser();
const user = savedUser || (await getAuthUser());
Expand Down
3 changes: 2 additions & 1 deletion web/src/routes/admin/user-management/+page.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { authenticate } from '$lib/utils/auth';
import { authenticate, requestServerInfo } from '$lib/utils/auth';
import { api } from '@api';
import type { PageLoad } from './$types';

export const load = (async () => {
await authenticate({ admin: true });
await requestServerInfo();
const { data: allUsers } = await api.userApi.getAllUsers({ isAll: false });

return {
Expand Down
Loading