Add user creation button and improve data loading logic
- Introduced a button for creating users, which prompts the user to select a specific node before proceeding. - Enhanced data loading logic to handle scenarios where the URL changes without immediate data refresh, ensuring up-to-date information is displayed. - Added Russian translations for new UI elements to maintain localization consistency.
This commit is contained in:
@@ -450,6 +450,8 @@ $effect(() => {
|
|||||||
noScroll: true,
|
noScroll: true,
|
||||||
keepFocus: true
|
keepFocus: true
|
||||||
});
|
});
|
||||||
|
// Страхуемся от кейсов, когда URL уже сменился, а перезапрос не стартовал.
|
||||||
|
await load();
|
||||||
}
|
}
|
||||||
|
|
||||||
let queryKey = $derived(page.url.searchParams.toString());
|
let queryKey = $derived(page.url.searchParams.toString());
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
import FleetRefreshInput from '$lib/components/fleet/fleet-refresh-input.svelte';
|
import FleetRefreshInput from '$lib/components/fleet/fleet-refresh-input.svelte';
|
||||||
import CopyIcon from '@lucide/svelte/icons/copy';
|
import CopyIcon from '@lucide/svelte/icons/copy';
|
||||||
import RefreshCwIcon from '@lucide/svelte/icons/refresh-cw';
|
import RefreshCwIcon from '@lucide/svelte/icons/refresh-cw';
|
||||||
|
import PlusIcon from '@lucide/svelte/icons/plus';
|
||||||
import UsersIcon from '@lucide/svelte/icons/users';
|
import UsersIcon from '@lucide/svelte/icons/users';
|
||||||
import ActivityIcon from '@lucide/svelte/icons/activity';
|
import ActivityIcon from '@lucide/svelte/icons/activity';
|
||||||
import GlobeIcon from '@lucide/svelte/icons/globe';
|
import GlobeIcon from '@lucide/svelte/icons/globe';
|
||||||
@@ -128,6 +129,9 @@
|
|||||||
noScroll: true,
|
noScroll: true,
|
||||||
keepFocus: true
|
keepFocus: true
|
||||||
});
|
});
|
||||||
|
// В некоторых сценариях shallow-навигации page.url обновляется не сразу,
|
||||||
|
// поэтому дополнительно перезапрашиваем данные по текущему фильтру.
|
||||||
|
await load();
|
||||||
}
|
}
|
||||||
|
|
||||||
let queryKey = $derived(page.url.searchParams.toString());
|
let queryKey = $derived(page.url.searchParams.toString());
|
||||||
@@ -318,6 +322,14 @@ let sumActiveIps = $derived.by(() =>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openCreateUser() {
|
||||||
|
if (!aliasFilter || aliasFilter === 'all') {
|
||||||
|
toast.info('Для создания выберите конкретную ноду в фильтре "Алиас".');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
void goto(`/servers/${encodeURIComponent(aliasFilter)}/users`);
|
||||||
|
}
|
||||||
|
|
||||||
function fallbackCopy(value: string) {
|
function fallbackCopy(value: string) {
|
||||||
if (typeof document === 'undefined') return;
|
if (typeof document === 'undefined') return;
|
||||||
const ta = document.createElement('textarea');
|
const ta = document.createElement('textarea');
|
||||||
@@ -357,6 +369,10 @@ let sumActiveIps = $derived.by(() =>
|
|||||||
>Ссылки tg://proxy</Label
|
>Ссылки tg://proxy</Label
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
<Button variant="default" size="sm" onclick={openCreateUser}>
|
||||||
|
<PlusIcon class="mr-1 size-4" />
|
||||||
|
Создать
|
||||||
|
</Button>
|
||||||
<Button variant="outline" size="sm" onclick={() => void load()} disabled={loading}>
|
<Button variant="outline" size="sm" onclick={() => void load()} disabled={loading}>
|
||||||
<RefreshCwIcon class="mr-1 size-4 {loading ? 'animate-spin' : ''}" />
|
<RefreshCwIcon class="mr-1 size-4 {loading ? 'animate-spin' : ''}" />
|
||||||
Обновить
|
Обновить
|
||||||
|
|||||||
Reference in New Issue
Block a user