mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
Implement chat panels
This commit is contained in:
parent
e61a8535aa
commit
e0da51be2e
|
@ -98,6 +98,9 @@ const updateGridWidth = async () => {
|
|||
</keep-alive>
|
||||
<component :is="Component" v-else />
|
||||
</router-view>
|
||||
<div :class="$style.contentFooter">
|
||||
<router-view name="footer" />
|
||||
</div>
|
||||
</div>
|
||||
<div :id="APP_MODALS_ELEMENT_ID" :class="$style.modals">
|
||||
<Modals />
|
||||
|
@ -145,11 +148,19 @@ const updateGridWidth = async () => {
|
|||
height: 100%;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
|
||||
main {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.contentFooter {
|
||||
height: auto;
|
||||
z-index: 1000000;
|
||||
background: white;
|
||||
border: 1px solid red;
|
||||
}
|
||||
}
|
||||
|
||||
.header {
|
||||
|
|
94
packages/editor-ui/src/components/CanvasChat/CanvasChat.vue
Normal file
94
packages/editor-ui/src/components/CanvasChat/CanvasChat.vue
Normal file
|
@ -0,0 +1,94 @@
|
|||
<script setup lang="ts">
|
||||
import { useAssistantStore } from '@/stores/assistant.store';
|
||||
import { useDebounce } from '@/composables/useDebounce';
|
||||
import { useUsersStore } from '@/stores/users.store';
|
||||
import { computed, ref } from 'vue';
|
||||
import SlideTransition from '@/components/transitions/SlideTransition.vue';
|
||||
import AskAssistantChat from 'n8n-design-system/components/AskAssistantChat/AskAssistantChat.vue';
|
||||
import { useTelemetry } from '@/composables/useTelemetry';
|
||||
|
||||
const assistantStore = useAssistantStore();
|
||||
const usersStore = useUsersStore();
|
||||
const telemetry = useTelemetry();
|
||||
|
||||
const height = ref(0);
|
||||
|
||||
const chatWidth = ref(0);
|
||||
const logsWidth = ref(0);
|
||||
|
||||
const rootStyles = computed(() => {
|
||||
return {
|
||||
'--chat-width': chatWidth.value + 'px',
|
||||
'--logs-width': logsWidth.value + 'px',
|
||||
'--panel-height': height.value + 'px',
|
||||
};
|
||||
});
|
||||
function onResize(data) {
|
||||
console.log('🚀 ~ onResize ~ direction:', data);
|
||||
height.value = data.height;
|
||||
// assistantStore.updateWindowWidth(data.width);
|
||||
}
|
||||
|
||||
function onResizeDebounced(data: { direction: string; x: number; width: number }) {
|
||||
void useDebounce().callDebounced(onResize, { debounceTime: 10, trailing: true }, data);
|
||||
}
|
||||
|
||||
function onResizeHorizontal(
|
||||
component: 'chat' | 'logs',
|
||||
data: { direction: string; x: number; width: number },
|
||||
) {
|
||||
if (component === 'chat') {
|
||||
chatWidth.value = data.width;
|
||||
} else {
|
||||
logsWidth.value = data.width;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<n8n-resize-wrapper
|
||||
v-show="true"
|
||||
:supported-directions="['top']"
|
||||
:class="$style.container"
|
||||
:height="height"
|
||||
data-test-id="ask-assistant-sidebar"
|
||||
@resize="onResizeDebounced"
|
||||
:style="rootStyles"
|
||||
>
|
||||
<div :class="$style.content">
|
||||
<n8n-resize-wrapper
|
||||
v-show="true"
|
||||
:supported-directions="['right']"
|
||||
:width="chatWidth"
|
||||
:class="$style.chat"
|
||||
@resize="(data) => onResizeHorizontal('chat', data)"
|
||||
>
|
||||
Chat
|
||||
</n8n-resize-wrapper>
|
||||
<div :class="$style.logs" @resize="(data) => onResizeHorizontal('logs', data)">Logs</div>
|
||||
</div>
|
||||
</n8n-resize-wrapper>
|
||||
</template>
|
||||
|
||||
<style lang="scss" module>
|
||||
.container {
|
||||
height: var(--panel-height);
|
||||
min-height: 3rem;
|
||||
flex-basis: content;
|
||||
z-index: 300;
|
||||
// transform: translateY(-18rem);
|
||||
}
|
||||
.content {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.chat {
|
||||
width: var(--chat-width);
|
||||
min-width: 5rem;
|
||||
border-right: 2px solid var(--color-foreground-base);
|
||||
}
|
||||
.logs {
|
||||
width: var(--logs-width);
|
||||
}
|
||||
</style>
|
|
@ -24,6 +24,7 @@ const ErrorView = async () => await import('./views/ErrorView.vue');
|
|||
const ForgotMyPasswordView = async () => await import('./views/ForgotMyPasswordView.vue');
|
||||
const MainHeader = async () => await import('@/components/MainHeader/MainHeader.vue');
|
||||
const MainSidebar = async () => await import('@/components/MainSidebar.vue');
|
||||
const CanvasChat = async () => await import('@/components/CanvasChat/CanvasChat.vue');
|
||||
const NodeView = async () => await import('@/views/NodeViewSwitcher.vue');
|
||||
const WorkflowExecutionsView = async () => await import('@/views/WorkflowExecutionsView.vue');
|
||||
const WorkflowExecutionsLandingPage = async () =>
|
||||
|
@ -314,6 +315,7 @@ export const routes: RouteRecordRaw[] = [
|
|||
default: NodeView,
|
||||
header: MainHeader,
|
||||
sidebar: MainSidebar,
|
||||
footer: CanvasChat,
|
||||
},
|
||||
meta: {
|
||||
nodeView: true,
|
||||
|
@ -346,6 +348,7 @@ export const routes: RouteRecordRaw[] = [
|
|||
default: NodeView,
|
||||
header: MainHeader,
|
||||
sidebar: MainSidebar,
|
||||
footer: CanvasChat,
|
||||
},
|
||||
meta: {
|
||||
nodeView: true,
|
||||
|
|
Loading…
Reference in a new issue