Task Status Center: save progress

This commit is contained in:
2026-07-04 15:34:02 +03:00
parent 61f3e6db75
commit 047aff41d9
4 changed files with 28 additions and 13 deletions

View File

@@ -109,17 +109,22 @@
hasPermission(user, "admin:settings", "READ"),
);
let globalEnvironments = $derived(
environmentContextStore.value?.environments || [],
$environmentContextStore?.environments || [],
);
let globalSelectedEnvId = $derived(
environmentContextStore.value?.selectedEnvId || "",
$environmentContextStore?.selectedEnvId || "",
);
let globalSelectedEnv = $derived(selectedEnvironmentStore.value);
let globalSelectedEnv = $derived($selectedEnvironmentStore);
let selectedEnvironmentValue = $state("");
let isProdContext = $derived(
String(globalSelectedEnv?.stage || "").toUpperCase() === "PROD" ||
Boolean(globalSelectedEnv?.is_production),
);
$effect(() => {
selectedEnvironmentValue = globalSelectedEnvId;
});
function toggleUserMenu(event) {
event.stopPropagation();
showUserMenu = !showUserMenu;
@@ -187,7 +192,9 @@
}
function handleGlobalEnvironmentChange(event) {
setSelectedEnvironment(event.target.value);
const nextEnvId = event.currentTarget.value;
selectedEnvironmentValue = nextEnvId;
setSelectedEnvironment(nextEnvId);
if (searchQuery.trim().length >= SEARCH_MIN_LENGTH) {
triggerSearch(searchQuery.trim());
}
@@ -479,7 +486,7 @@
{isProdContext
? 'border-destructive-ring bg-destructive-light text-destructive focus:ring-destructive-ring'
: 'border-border-strong bg-surface-card text-text focus:ring-sky-200'}"
value={globalSelectedEnvId}
bind:value={selectedEnvironmentValue}
onchange={handleGlobalEnvironmentChange}
aria-label={$t.dashboard?.environment || "Environment"}
title={$t.dashboard?.environment || "Environment"}

View File

@@ -108,9 +108,9 @@ export class AgentChatModel {
_userCancelled: boolean = $state(false);
/** Populated by file_uploaded metadata — attached to user message on stream end. */
_pendingAttachment: { file_name: string; file_path: string; file_size: number } | null = $state(null);
userId: string = "";
userJwt: string = "";
envId: string = "";
userId: string = $state("");
userJwt: string = $state("");
envId: string = $state("");
// ── Private fields ─────────────────────────────────────────────
_client: GradioClient | null = null; // non-private for legacy Object.assign usage

View File

@@ -42,8 +42,8 @@
let isLoginPage = $derived(page.url.pathname === '/login');
let isExpanded = $derived(sidebarStore.value?.isExpanded ?? true);
let isProductionContext = $derived(isProductionContextStore.value);
let selectedEnvironment = $derived(selectedEnvironmentStore.value);
let isProductionContext = $derived($isProductionContextStore);
let selectedEnvironment = $derived($selectedEnvironmentStore);
</script>
<Toast />

View File

@@ -26,18 +26,22 @@
// $auth is Svelte auto-subscription syntax for stores with .subscribe()
let currentUserId = $derived($auth.user?.id ?? "");
let currentUserJwt = $derived($auth.token ?? "");
let currentEnvironmentId = $derived(
$environmentContextStore?.selectedEnvId || (browser ? localStorage.getItem("selected_env_id") || "" : ""),
);
// Guard against double initialization in dev HMR
let _initialized = false;
// Sync model with reactive values before each send
function syncModel(m: AgentChatModel): void {
function syncModel(m: AgentChatModel, envId: string = currentEnvironmentId): void {
m.userId = $auth.user?.id ?? "";
m.userJwt = $auth.token ?? "";
m.envId = environmentContextStore.value?.selectedEnvId || (browser ? localStorage.getItem("selected_env_id") || "" : "");
m.envId = envId;
}
$effect(() => {
if (model) syncModel(model);
const envId = currentEnvironmentId;
if (model) syncModel(model, envId);
});
onMount(() => {
@@ -47,6 +51,9 @@
const m = new AgentChatModel();
m.onBeforeSend = () => syncModel(m);
syncModel(m);
const unsubscribeEnvironment = environmentContextStore.subscribe((state) => {
syncModel(m, state?.selectedEnvId || (browser ? localStorage.getItem("selected_env_id") || "" : ""));
});
const desktopQuery = window.matchMedia("(min-width: 768px)");
const syncSidebarForViewport = (matches: boolean) => {
m.setConversationSidebarOpen(matches);
@@ -71,6 +78,7 @@
});
return () => {
unsubscribeEnvironment();
desktopQuery.removeEventListener("change", handleViewportChange);
_initialized = false;
};