70 lines
3.0 KiB
Vue
70 lines
3.0 KiB
Vue
<script setup lang="ts">
|
|
import { computed, onMounted, ref, watch } from "vue";
|
|
import { useRoute, useRouter } from "vue-router";
|
|
import CommandComposer from "@/components/workbench/CommandComposer.vue";
|
|
import ConversationPanel from "@/components/workbench/ConversationPanel.vue";
|
|
import SessionRail from "@/components/workbench/SessionRail.vue";
|
|
import HwpodNodeOpsPanel from "@/components/hwpod/HwpodNodeOpsPanel.vue";
|
|
import { useAutoRefresh } from "@/composables/useAutoRefresh";
|
|
import { useWorkbenchStore } from "@/stores/workbench";
|
|
import { DEFAULT_WORKBENCH_PROJECT_ID, normalizeWorkbenchConversationId, normalizeWorkbenchProjectId } from "@/utils";
|
|
|
|
const workbench = useWorkbenchStore();
|
|
const route = useRoute();
|
|
const router = useRouter();
|
|
const routeConversationId = computed(() => normalizeWorkbenchConversationId(route.params.conversationId));
|
|
const applyingRouteConversation = ref(Boolean(routeConversationId.value));
|
|
|
|
onMounted(async () => {
|
|
applyingRouteConversation.value = Boolean(routeConversationId.value);
|
|
try {
|
|
await workbench.hydrate();
|
|
await applyRouteConversation();
|
|
} finally {
|
|
applyingRouteConversation.value = false;
|
|
}
|
|
if (!routeConversationId.value || routeConversationId.value === workbench.activeConversationId) await reflectActiveConversationInUrl(workbench.activeConversationId);
|
|
});
|
|
watch(routeConversationId, () => void applyRouteConversation());
|
|
watch(() => workbench.activeConversationId, (conversationId) => void reflectActiveConversationInUrl(conversationId));
|
|
useAutoRefresh(() => workbench.refreshLive(), 30_000);
|
|
|
|
async function applyRouteConversation(): Promise<boolean> {
|
|
const conversationId = routeConversationId.value;
|
|
if (!conversationId || workbench.activeConversationId === conversationId) return true;
|
|
applyingRouteConversation.value = true;
|
|
try {
|
|
return await workbench.selectConversationById(conversationId);
|
|
} finally {
|
|
applyingRouteConversation.value = false;
|
|
}
|
|
}
|
|
|
|
async function reflectActiveConversationInUrl(value: string | null): Promise<void> {
|
|
const conversationId = normalizeWorkbenchConversationId(value);
|
|
if (!conversationId) return;
|
|
const routeTarget = routeConversationId.value;
|
|
if (applyingRouteConversation.value && routeTarget && routeTarget !== conversationId) return;
|
|
if (routeTarget === conversationId) return;
|
|
const projectId = normalizeWorkbenchProjectId(route.query.projectId) ?? normalizeWorkbenchProjectId(workbench.workspace?.projectId) ?? normalizeWorkbenchProjectId(workbench.workspace?.workspace?.projectId);
|
|
await router.replace({
|
|
name: "CodeWorkbenchSession",
|
|
params: { conversationId },
|
|
query: projectId && projectId !== DEFAULT_WORKBENCH_PROJECT_ID ? { projectId } : {}
|
|
});
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<section id="workspace" class="workbench-route">
|
|
<div class="workbench-grid">
|
|
<SessionRail />
|
|
<main class="workbench-center">
|
|
<ConversationPanel />
|
|
<CommandComposer />
|
|
</main>
|
|
<HwpodNodeOpsPanel />
|
|
</div>
|
|
</section>
|
|
</template>
|