deduplicate/unify GalaxyAI ChatActions operations by doing them in component

Several of these operations were being emitted up parents needlessly, and therefore, now we perform most of them within the ChatActions component.
This commit is contained in:
Ahmed Awan
2026-06-01 15:50:39 -05:00
parent ae8ef8979f
commit bdd83af983
4 changed files with 54 additions and 95 deletions
+1 -28
View File
@@ -6,7 +6,6 @@ import { computed, nextTick, onMounted, ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router/composables";
import { GalaxyApi } from "@/api";
import { getGalaxyInstance } from "@/app";
import { type AgentResponse, useAgentActions } from "@/composables/agentActions";
import { useConfirmDialog } from "@/composables/confirmDialog";
import { useMarkdown } from "@/composables/markdown";
@@ -40,11 +39,6 @@ const props = withDefaults(
},
);
const emit = defineEmits<{
(e: "close"): void;
(e: "undock"): void;
}>();
const { confirm } = useConfirmDialog();
const route = useRoute();
const router = useRouter();
@@ -378,23 +372,6 @@ async function deleteCurrentChat() {
}
}
function popOutToWindowManager() {
// If opening window manager chat from center or docked mode, we want to set the center/dock
// to a new chat and then open the current chat in the window manager, so we don't have the
// same chat open in two places
if (isRouteMode.value) {
router.push("/galaxyai/new");
} else if (props.docked) {
chatStore.setActiveChatId(null);
emit("close");
}
const Galaxy = getGalaxyInstance();
const path = currentChatId.value ? `/galaxyai/${currentChatId.value}` : "/galaxyai/new";
const url = `${path}?compact=true`;
Galaxy.frame.add({ title: "GalaxyAI", url });
}
function dockTo(location: "right" | "bottom") {
chatStore.dockChat(location, currentChatId.value);
if (route.path.startsWith("/galaxyai")) {
@@ -435,12 +412,8 @@ watch(currentChatId, async (newId) => {
<ChatActions
:source="docked ? 'docked' : 'center'"
:enable-delete="Boolean(currentChatId)"
@close="emit('close')"
@delete="deleteCurrentChat"
@dock-to="dockTo"
@maximize="emit('undock')"
@pop-out="popOutToWindowManager"
@start-new="startNewChat" />
@dock-to="dockTo" />
</div>
<div v-if="(docked || panel) && effectiveContext" class="context-indicator">
+51 -22
View File
@@ -13,8 +13,11 @@ import {
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { computed } from "vue";
import { useRoute, useRouter } from "vue-router/composables";
import { getGalaxyInstance } from "@/app";
import { useActivityStore } from "@/stores/activityStore.js";
import { useChatStore } from "@/stores/chatStore";
import GButton from "../BaseComponents/GButton.vue";
@@ -25,29 +28,55 @@ const props = defineProps<{
}>();
const emit = defineEmits<{
(e: "close"): void;
(e: "delete"): void;
(e: "dock-to", location: "right" | "bottom"): void;
(e: "maximize"): void;
(e: "pop-out"): void;
(e: "start-new"): void;
(e: "update:collapsed", value: boolean): void;
}>();
const route = useRoute();
const router = useRouter();
const chatStore = useChatStore();
const activityStore = useActivityStore("default");
const showingActivityPanel = computed(() => activityStore.toggledSideBar === "galaxyai");
function onOperation(operation: "start-new" | "dock-right" | "dock-bottom") {
if (operation === "start-new") {
emit("start-new");
} else if (operation === "dock-right") {
emit("dock-to", "right");
} else if (operation === "dock-bottom") {
emit("dock-to", "bottom");
function startNew() {
if (props.source === "center") {
router.push("/galaxyai/new");
} else {
chatStore.showChat(null);
}
emit("update:collapsed", false);
}
function maximize() {
const chatId = chatStore.activeChatId;
chatStore.setLocation("center");
chatStore.hideChat();
router.push(chatId ? `/galaxyai/${chatId}` : "/galaxyai");
}
function popOut() {
// If opening window manager chat from center or docked mode, we want to set the center/dock
// to a new chat and then open the current chat in the window manager, so we don't have the
// same chat open in two places
const id = props.source === "center" ? route.params["exchangeId"] || null : chatStore.activeChatId;
const path = id ? `/galaxyai/${id}` : "/galaxyai/new";
getGalaxyInstance().frame.add({ title: "GalaxyAI", url: `${path}?compact=true` });
if (props.source === "center") {
router.push("/galaxyai/new");
} else if (props.source === "docked") {
chatStore.setActiveChatId(null);
chatStore.hideChat();
} else {
chatStore.hideChat();
}
}
function onDockTo(location: "right" | "bottom") {
emit("dock-to", location);
}
</script>
<template>
@@ -66,12 +95,7 @@ function onOperation(operation: "start-new" | "dock-right" | "dock-bottom") {
Chats
</span>
</GButton>
<GButton
data-description="new chat button"
size="small"
transparent
title="Start New Chat"
@click="onOperation('start-new')">
<GButton data-description="new chat button" size="small" transparent title="Start New Chat" @click="startNew">
<FontAwesomeIcon :icon="faPlus" fixed-width />
<span class="btn-label">New</span>
</GButton>
@@ -91,18 +115,18 @@ function onOperation(operation: "start-new" | "dock-right" | "dock-bottom") {
size="small"
transparent
title="Open in center view"
@click="emit('maximize')">
@click="maximize">
<FontAwesomeIcon :icon="faExpand" fixed-width />
</GButton>
<template v-if="props.source === 'center'">
<GButton size="small" transparent title="Dock to side panel" @click="onOperation('dock-right')">
<GButton size="small" transparent title="Dock to side panel" @click="onDockTo('right')">
<FontAwesomeIcon :icon="faColumns" fixed-width />
</GButton>
<GButton size="small" transparent title="Dock to bottom panel" @click="onOperation('dock-bottom')">
<GButton size="small" transparent title="Dock to bottom panel" @click="onDockTo('bottom')">
<FontAwesomeIcon :icon="faAngleDoubleDown" fixed-width />
</GButton>
</template>
<GButton size="small" transparent title="Open in floating window" @click="emit('pop-out')">
<GButton size="small" transparent title="Open in floating window" @click="popOut">
<FontAwesomeIcon :icon="faExternalLinkAlt" fixed-width />
</GButton>
<GButton
@@ -113,7 +137,12 @@ function onOperation(operation: "start-new" | "dock-right" | "dock-bottom") {
@click="emit('update:collapsed', !props.collapsed)">
<FontAwesomeIcon :icon="props.collapsed ? faChevronUp : faChevronDown" fixed-width />
</GButton>
<GButton v-if="props.source !== 'center'" size="small" transparent title="Close panel" @click="emit('close')">
<GButton
v-if="props.source !== 'center'"
size="small"
transparent
title="Close panel"
@click="chatStore.hideChat()">
<FontAwesomeIcon :icon="faTimes" fixed-width />
</GButton>
</div>
+1 -33
View File
@@ -1,55 +1,23 @@
<script setup lang="ts">
import { storeToRefs } from "pinia";
import { ref } from "vue";
import { useRouter } from "vue-router/composables";
import { getGalaxyInstance } from "@/app";
import { useChatStore } from "@/stores/chatStore";
import ChatActions from "./ChatActions.vue";
import GalaxyAI from "@/components/GalaxyAI.vue";
const router = useRouter();
const chatStore = useChatStore();
const { activeChatId } = storeToRefs(chatStore);
const collapsed = ref(false);
function maximize() {
const path = activeChatId.value ? `/galaxyai/${activeChatId.value}` : "/galaxyai";
chatStore.setLocation("center");
chatStore.hideChat();
router.push(path);
}
function popOut() {
const Galaxy = getGalaxyInstance();
const id = activeChatId.value;
const path = id ? `/galaxyai/${id}` : "/galaxyai/new";
Galaxy.frame.add({ title: "GalaxyAI", url: `${path}?compact=true` });
chatStore.hideChat();
}
function close() {
chatStore.hideChat();
}
function startNewChat() {
chatStore.showChat(null);
}
</script>
<template>
<div class="chat-panel" :class="collapsed ? 'collapsed' : 'expanded'">
<div class="chat-panel-header">
<span class="chat-panel-title">GalaxyAI</span>
<ChatActions
source="panel"
:collapsed.sync="collapsed"
@maximize="maximize"
@pop-out="popOut"
@close="close"
@start-new="startNewChat" />
<ChatActions source="panel" :collapsed.sync="collapsed" />
</div>
<div v-show="!collapsed" class="chat-panel-body">
<GalaxyAI :exchange-id="activeChatId || undefined" panel />
+1 -12
View File
@@ -55,13 +55,6 @@ function onLoad() {
showCenter.value = true;
}
function handleUndock() {
const chatId = activeChatId.value;
chatStore.setLocation("center");
chatStore.hideChat();
router.push(chatId ? `/galaxyai/${chatId}` : "/galaxyai");
}
// life cycle
onMounted(() => {
// Using a custom event here which, in contrast to watching $route,
@@ -106,11 +99,7 @@ onUnmounted(() => {
side="right"
:reactive-width.sync="chatPanelWidth"
@close="chatStore.hideChat()">
<GalaxyAI
:exchange-id="activeChatId || undefined"
docked
@close="chatStore.hideChat()"
@undock="handleUndock" />
<GalaxyAI :exchange-id="activeChatId || undefined" docked />
</FlexPanel>
<DragAndDropModal />
</div>