2024-07-16 18:14:27 +08:00
|
|
|
|
<template>
|
2025-07-23 03:52:22 +08:00
|
|
|
|
<div class="database-info-container">
|
2025-08-05 18:00:45 +08:00
|
|
|
|
<DatabaseHeader />
|
2025-06-18 19:07:29 +08:00
|
|
|
|
|
2025-07-23 03:52:22 +08:00
|
|
|
|
<!-- Maximize Graph Modal -->
|
|
|
|
|
|
<a-modal
|
2025-08-05 18:00:45 +08:00
|
|
|
|
v-model:open="isGraphMaximized"
|
2025-07-23 03:52:22 +08:00
|
|
|
|
:footer="null"
|
|
|
|
|
|
:closable="false"
|
|
|
|
|
|
width="100%"
|
|
|
|
|
|
wrap-class-name="full-modal"
|
|
|
|
|
|
:mask-closable="false"
|
|
|
|
|
|
>
|
|
|
|
|
|
<template #title>
|
|
|
|
|
|
<div class="maximized-graph-header">
|
|
|
|
|
|
<h3>知识图谱 (最大化)</h3>
|
|
|
|
|
|
<a-button type="text" @click="toggleGraphMaximize">
|
|
|
|
|
|
<CompressOutlined /> 退出最大化
|
|
|
|
|
|
</a-button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<div class="maximized-graph-content">
|
|
|
|
|
|
<div v-if="!isGraphSupported" class="graph-disabled">
|
|
|
|
|
|
<div class="disabled-content">
|
|
|
|
|
|
<h4>知识图谱不可用</h4>
|
|
|
|
|
|
<p>当前知识库类型 "{{ getKbTypeLabel(database.kb_type || 'lightrag') }}" 不支持知识图谱功能。</p>
|
|
|
|
|
|
<p>只有 LightRAG 类型的知识库支持知识图谱。</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<KnowledgeGraphViewer
|
2025-08-05 18:00:45 +08:00
|
|
|
|
v-else-if="isGraphMaximized"
|
2025-07-23 03:52:22 +08:00
|
|
|
|
:initial-database-id="databaseId"
|
|
|
|
|
|
:hide-db-selector="true"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</a-modal>
|
2025-03-23 23:10:32 +08:00
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
<FileDetailModal />
|
2025-07-21 18:18:47 +08:00
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
<FileUploadModal
|
|
|
|
|
|
v-model:visible="addFilesModalVisible"
|
|
|
|
|
|
/>
|
2025-07-21 18:18:47 +08:00
|
|
|
|
|
2025-07-23 03:52:22 +08:00
|
|
|
|
<div class="unified-layout">
|
|
|
|
|
|
<div class="left-panel" :style="{ width: leftPanelWidth + '%' }">
|
2025-08-05 18:00:45 +08:00
|
|
|
|
<FileTable
|
|
|
|
|
|
:right-panel-visible="state.rightPanelVisible"
|
|
|
|
|
|
@show-add-files-modal="showAddFilesModal"
|
|
|
|
|
|
@toggle-right-panel="toggleRightPanel"
|
|
|
|
|
|
/>
|
2025-07-23 03:52:22 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="resize-handle" ref="resizeHandle"></div>
|
|
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
<div class="right-panel" :style="{ width: (100 - leftPanelWidth) + '%', display: store.state.rightPanelVisible ? 'flex' : 'none' }">
|
|
|
|
|
|
<KnowledgeGraphSection
|
|
|
|
|
|
:visible="panels.graph.visible"
|
|
|
|
|
|
:style="computePanelStyles().graph"
|
|
|
|
|
|
@toggle-visible="togglePanel('graph')"
|
|
|
|
|
|
/>
|
2025-07-23 03:52:22 +08:00
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
<div class="resize-handle-horizontal" ref="resizeHandleHorizontal" v-show="panels.query.visible && panels.graph.visible"></div>
|
2025-07-23 03:52:22 +08:00
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
<QuerySection
|
|
|
|
|
|
:visible="panels.query.visible"
|
|
|
|
|
|
:style="computePanelStyles().query"
|
|
|
|
|
|
@toggle-visible="togglePanel('query')"
|
|
|
|
|
|
/>
|
2025-07-23 03:52:22 +08:00
|
|
|
|
</div>
|
2024-07-16 18:14:27 +08:00
|
|
|
|
</div>
|
2024-09-14 02:46:44 +08:00
|
|
|
|
</div>
|
2024-07-16 18:14:27 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup>
|
2025-08-05 18:00:45 +08:00
|
|
|
|
import { onMounted, reactive, ref, watch, onUnmounted, computed } from 'vue';
|
|
|
|
|
|
import { useRoute } from 'vue-router';
|
|
|
|
|
|
import { useDatabaseStore } from '@/stores/database';
|
|
|
|
|
|
import { getKbTypeLabel } from '@/utils/kb_utils';
|
|
|
|
|
|
import { CompressOutlined } from '@ant-design/icons-vue';
|
2025-06-30 22:29:23 +08:00
|
|
|
|
import KnowledgeGraphViewer from '@/components/KnowledgeGraphViewer.vue';
|
2025-08-05 18:00:45 +08:00
|
|
|
|
import DatabaseHeader from '@/components/DatabaseHeader.vue';
|
|
|
|
|
|
import FileTable from '@/components/FileTable.vue';
|
|
|
|
|
|
import FileDetailModal from '@/components/FileDetailModal.vue';
|
|
|
|
|
|
import FileUploadModal from '@/components/FileUploadModal.vue';
|
|
|
|
|
|
import KnowledgeGraphSection from '@/components/KnowledgeGraphSection.vue';
|
|
|
|
|
|
import QuerySection from '@/components/QuerySection.vue';
|
2024-07-16 18:14:27 +08:00
|
|
|
|
|
|
|
|
|
|
const route = useRoute();
|
2025-08-05 18:00:45 +08:00
|
|
|
|
const store = useDatabaseStore();
|
|
|
|
|
|
|
|
|
|
|
|
const databaseId = computed(() => store.databaseId);
|
|
|
|
|
|
const database = computed(() => store.database);
|
|
|
|
|
|
const state = computed(() => store.state);
|
|
|
|
|
|
const isGraphMaximized = computed({
|
|
|
|
|
|
get: () => store.state.isGraphMaximized,
|
|
|
|
|
|
set: (val) => store.state.isGraphMaximized = val
|
2025-07-23 03:52:22 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 计算属性:是否支持知识图谱
|
|
|
|
|
|
const isGraphSupported = computed(() => {
|
|
|
|
|
|
const kbType = database.value.kb_type?.toLowerCase();
|
|
|
|
|
|
return kbType === 'lightrag';
|
2025-07-21 19:25:07 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
// 面板可见性控制
|
|
|
|
|
|
const panels = reactive({
|
|
|
|
|
|
query: { visible: true },
|
|
|
|
|
|
graph: { visible: true },
|
2024-07-16 18:14:27 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
// 添加调试日志
|
|
|
|
|
|
console.log('Initial panels state:', panels);
|
2025-07-21 19:25:07 +08:00
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
const togglePanel = (panel) => {
|
|
|
|
|
|
panels[panel].visible = !panels[panel].visible;
|
2025-07-21 19:25:07 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
// 切换右侧面板显示/隐藏
|
|
|
|
|
|
const toggleRightPanel = () => {
|
|
|
|
|
|
store.state.rightPanelVisible = !store.state.rightPanelVisible;
|
2025-07-21 19:25:07 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
// 拖拽调整大小
|
2025-09-06 14:04:33 +08:00
|
|
|
|
const leftPanelWidth = ref(60);
|
2025-08-05 18:00:45 +08:00
|
|
|
|
const isDragging = ref(false);
|
|
|
|
|
|
const resizeHandle = ref(null);
|
2025-07-21 19:25:07 +08:00
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
const rightPanelHeight = reactive({ query: 50, graph: 50 });
|
|
|
|
|
|
const isDraggingVertical = ref(false);
|
|
|
|
|
|
const resizeHandleHorizontal = ref(null);
|
2025-07-21 19:25:07 +08:00
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
// 计算面板样式的方法
|
|
|
|
|
|
const computePanelStyles = () => {
|
|
|
|
|
|
const queryVisible = panels.query.visible;
|
|
|
|
|
|
const graphVisible = panels.graph.visible && isGraphSupported.value;
|
2025-07-21 19:25:07 +08:00
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
if (queryVisible && graphVisible) {
|
|
|
|
|
|
const styles = {
|
|
|
|
|
|
query: { height: rightPanelHeight.query + '%', flex: 'none' },
|
|
|
|
|
|
graph: { height: rightPanelHeight.graph + '%', flex: 'none' }
|
|
|
|
|
|
};
|
|
|
|
|
|
console.log('Computed panel styles:', styles);
|
|
|
|
|
|
return styles;
|
|
|
|
|
|
} else if (queryVisible && !graphVisible) {
|
|
|
|
|
|
return {
|
|
|
|
|
|
query: { height: '100%', flex: '1' },
|
|
|
|
|
|
graph: { height: '36px', flex: 'none' }
|
|
|
|
|
|
};
|
|
|
|
|
|
} else if (!queryVisible && graphVisible) {
|
|
|
|
|
|
return {
|
|
|
|
|
|
query: { height: '36px', flex: 'none' },
|
|
|
|
|
|
graph: { height: '100%', flex: '1' }
|
|
|
|
|
|
};
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return {
|
|
|
|
|
|
query: { height: '36px', flex: 'none' },
|
|
|
|
|
|
graph: { height: '36px', flex: 'none' }
|
|
|
|
|
|
};
|
2025-07-21 19:25:07 +08:00
|
|
|
|
}
|
|
|
|
|
|
};
|
2025-05-23 15:30:14 +08:00
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
// 添加调试日志
|
|
|
|
|
|
console.log('Panel styles computed:', computePanelStyles());
|
2025-05-26 22:50:47 +08:00
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
// 添加文件弹窗
|
|
|
|
|
|
const addFilesModalVisible = ref(false);
|
2025-05-26 22:50:47 +08:00
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
// 显示添加文件弹窗
|
|
|
|
|
|
const showAddFilesModal = () => {
|
|
|
|
|
|
addFilesModalVisible.value = true;
|
2025-05-26 22:50:47 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
// 切换图谱最大化状态
|
|
|
|
|
|
const toggleGraphMaximize = () => {
|
|
|
|
|
|
isGraphMaximized.value = !isGraphMaximized.value;
|
2025-06-27 01:55:04 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
2025-07-21 18:18:47 +08:00
|
|
|
|
watch(() => route.params.database_id, async (newId) => {
|
2025-08-05 18:00:45 +08:00
|
|
|
|
store.databaseId = newId;
|
|
|
|
|
|
store.stopAutoRefresh();
|
|
|
|
|
|
await store.getDatabaseInfo(newId);
|
|
|
|
|
|
store.startAutoRefresh();
|
|
|
|
|
|
},
|
|
|
|
|
|
{ immediate: true }
|
2024-07-16 18:14:27 +08:00
|
|
|
|
);
|
|
|
|
|
|
|
2025-07-27 02:56:13 +08:00
|
|
|
|
// 组件挂载时启动示例轮播
|
|
|
|
|
|
onMounted(() => {
|
2025-08-05 18:00:45 +08:00
|
|
|
|
store.databaseId = route.params.database_id;
|
|
|
|
|
|
store.getDatabaseInfo();
|
|
|
|
|
|
store.startAutoRefresh();
|
2025-07-27 02:56:13 +08:00
|
|
|
|
|
|
|
|
|
|
// 添加拖拽事件监听
|
|
|
|
|
|
if (resizeHandle.value) {
|
|
|
|
|
|
resizeHandle.value.addEventListener('mousedown', handleMouseDown);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (resizeHandleHorizontal.value) {
|
|
|
|
|
|
resizeHandleHorizontal.value.addEventListener('mousedown', handleMouseDownHorizontal);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
// 添加调试日志
|
|
|
|
|
|
console.log('Resize handles initialized', resizeHandle.value, resizeHandleHorizontal.value);
|
2025-07-27 02:56:13 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 组件卸载时停止示例轮播
|
|
|
|
|
|
onUnmounted(() => {
|
2025-08-05 18:00:45 +08:00
|
|
|
|
store.stopAutoRefresh();
|
2025-07-27 02:56:13 +08:00
|
|
|
|
if (resizeHandle.value) {
|
|
|
|
|
|
resizeHandle.value.removeEventListener('mousedown', handleMouseDown);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (resizeHandleHorizontal.value) {
|
|
|
|
|
|
resizeHandleHorizontal.value.removeEventListener('mousedown', handleMouseDownHorizontal);
|
|
|
|
|
|
}
|
|
|
|
|
|
document.removeEventListener('mousemove', handleMouseMove);
|
|
|
|
|
|
document.removeEventListener('mouseup', handleMouseUp);
|
|
|
|
|
|
document.removeEventListener('mousemove', handleMouseMoveHorizontal);
|
|
|
|
|
|
document.removeEventListener('mouseup', handleMouseUpHorizontal);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2025-07-23 03:52:22 +08:00
|
|
|
|
// 拖拽调整大小功能
|
|
|
|
|
|
const handleMouseDown = () => {
|
|
|
|
|
|
isDragging.value = true;
|
|
|
|
|
|
document.addEventListener('mousemove', handleMouseMove);
|
|
|
|
|
|
document.addEventListener('mouseup', handleMouseUp);
|
|
|
|
|
|
document.body.style.cursor = 'col-resize';
|
|
|
|
|
|
document.body.style.userSelect = 'none';
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const handleMouseMove = (e) => {
|
|
|
|
|
|
if (!isDragging.value) return;
|
|
|
|
|
|
|
|
|
|
|
|
const container = document.querySelector('.unified-layout');
|
|
|
|
|
|
if (!container) return;
|
|
|
|
|
|
|
|
|
|
|
|
const containerRect = container.getBoundingClientRect();
|
|
|
|
|
|
const newWidth = ((e.clientX - containerRect.left) / containerRect.width) * 100;
|
|
|
|
|
|
leftPanelWidth.value = Math.max(20, Math.min(60, newWidth));
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const handleMouseUp = () => {
|
|
|
|
|
|
isDragging.value = false;
|
|
|
|
|
|
document.removeEventListener('mousemove', handleMouseMove);
|
|
|
|
|
|
document.removeEventListener('mouseup', handleMouseUp);
|
|
|
|
|
|
document.body.style.cursor = '';
|
|
|
|
|
|
document.body.style.userSelect = '';
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const handleMouseDownHorizontal = () => {
|
2025-08-05 18:00:45 +08:00
|
|
|
|
console.log('Horizontal resize handle clicked');
|
2025-07-23 03:52:22 +08:00
|
|
|
|
isDraggingVertical.value = true;
|
2025-08-05 18:00:45 +08:00
|
|
|
|
document.addEventListener('mousemove', handleMouseMoveHorizontal);
|
|
|
|
|
|
document.addEventListener('mouseup', handleMouseUpHorizontal);
|
|
|
|
|
|
document.body.style.cursor = 'row-resize';
|
|
|
|
|
|
document.body.style.userSelect = 'none';
|
2025-06-18 19:07:29 +08:00
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
// 添加调试日志
|
|
|
|
|
|
console.log('Current panel heights:', rightPanelHeight.graph, rightPanelHeight.query);
|
|
|
|
|
|
};
|
2025-03-23 23:10:32 +08:00
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
const handleMouseMoveHorizontal = (e) => {
|
|
|
|
|
|
if (!isDraggingVertical.value) return;
|
2025-05-26 22:50:47 +08:00
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
const container = document.querySelector('.right-panel');
|
|
|
|
|
|
if (!container) return;
|
2025-05-26 22:50:47 +08:00
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
const containerRect = container.getBoundingClientRect();
|
|
|
|
|
|
const newHeight = ((e.clientY - containerRect.top) / containerRect.height) * 100;
|
2025-06-18 19:07:29 +08:00
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
// 修复计算逻辑,确保两个面板的高度总和为100%
|
|
|
|
|
|
rightPanelHeight.graph = Math.max(10, Math.min(90, newHeight));
|
|
|
|
|
|
rightPanelHeight.query = 100 - rightPanelHeight.graph;
|
2025-06-18 19:07:29 +08:00
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
// 添加调试日志
|
|
|
|
|
|
console.log('Vertical resize:', rightPanelHeight.graph, rightPanelHeight.query);
|
|
|
|
|
|
};
|
2025-06-18 19:07:29 +08:00
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
const handleMouseUpHorizontal = () => {
|
|
|
|
|
|
isDraggingVertical.value = false;
|
|
|
|
|
|
document.removeEventListener('mousemove', handleMouseMoveHorizontal);
|
|
|
|
|
|
document.removeEventListener('mouseup', handleMouseUpHorizontal);
|
|
|
|
|
|
document.body.style.cursor = '';
|
|
|
|
|
|
document.body.style.userSelect = '';
|
|
|
|
|
|
};
|
2025-06-18 19:07:29 +08:00
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
</script>
|
2025-06-18 19:07:29 +08:00
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
<style lang="less" scoped>
|
|
|
|
|
|
.db-main-container {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
width: 100%;
|
2025-03-23 23:10:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-26 22:50:47 +08:00
|
|
|
|
.ant-modal-footer {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: flex-end;
|
|
|
|
|
|
gap: 10px;
|
|
|
|
|
|
}
|
2025-06-27 01:55:04 +08:00
|
|
|
|
|
|
|
|
|
|
.auto-refresh-control {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
gap: 8px;
|
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
|
|
|
|
|
|
|
span {
|
|
|
|
|
|
color: var(--gray-700);
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.ant-switch {
|
|
|
|
|
|
&.ant-switch-checked {
|
|
|
|
|
|
background-color: var(--main-color);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-09-09 17:07:03 +08:00
|
|
|
|
|
2025-07-23 03:52:22 +08:00
|
|
|
|
/* Unified Layout Styles */
|
|
|
|
|
|
.unified-layout {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
height: calc(100vh - 54px); /* Adjust based on actual header height */
|
|
|
|
|
|
gap: 0;
|
2024-09-14 02:46:44 +08:00
|
|
|
|
|
2025-07-23 03:52:22 +08:00
|
|
|
|
.left-panel,
|
|
|
|
|
|
.right-panel {
|
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
overflow: hidden;
|
2024-09-14 02:46:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-23 03:52:22 +08:00
|
|
|
|
.left-panel {
|
|
|
|
|
|
flex-shrink: 0;
|
2025-07-26 15:19:11 +08:00
|
|
|
|
flex-grow: 1;
|
2025-09-06 14:04:33 +08:00
|
|
|
|
background-color: var(--gray-0);
|
2025-07-23 03:52:22 +08:00
|
|
|
|
padding: 8px;
|
2024-09-14 02:46:44 +08:00
|
|
|
|
}
|
2025-07-21 18:18:47 +08:00
|
|
|
|
|
2025-07-23 03:52:22 +08:00
|
|
|
|
.right-panel {
|
|
|
|
|
|
flex-grow: 1;
|
2025-08-04 18:43:06 +08:00
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
2025-07-21 18:18:47 +08:00
|
|
|
|
}
|
2024-09-09 17:07:03 +08:00
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
/* 当两个面板都可见时,确保它们正确分配空间 */
|
|
|
|
|
|
.right-panel > *:not(.resize-handle-horizontal) {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
min-height: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.resize-handle {
|
2025-09-06 14:04:33 +08:00
|
|
|
|
width: 1px;
|
2025-07-23 03:52:22 +08:00
|
|
|
|
cursor: col-resize;
|
|
|
|
|
|
background-color: var(--gray-200);
|
|
|
|
|
|
transition: background-color 0.2s ease;
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
z-index: 10;
|
2025-08-05 18:00:45 +08:00
|
|
|
|
flex-shrink: 0;
|
2024-09-14 02:46:44 +08:00
|
|
|
|
|
2025-07-23 03:52:22 +08:00
|
|
|
|
&:hover {
|
2025-07-30 11:00:50 +08:00
|
|
|
|
background-color: var(--main-40);
|
2025-07-23 03:52:22 +08:00
|
|
|
|
}
|
2024-09-14 02:46:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-23 03:52:22 +08:00
|
|
|
|
.resize-handle-horizontal {
|
2025-08-05 18:00:45 +08:00
|
|
|
|
height: 1px;
|
2025-07-23 03:52:22 +08:00
|
|
|
|
width: 100%;
|
|
|
|
|
|
cursor: row-resize;
|
|
|
|
|
|
background-color: var(--gray-200);
|
|
|
|
|
|
transition: background-color 0.2s ease;
|
|
|
|
|
|
z-index: 10;
|
2025-08-05 18:00:45 +08:00
|
|
|
|
flex-shrink: 0;
|
2025-07-21 19:25:07 +08:00
|
|
|
|
|
2025-07-23 03:52:22 +08:00
|
|
|
|
&:hover {
|
2025-07-30 11:00:50 +08:00
|
|
|
|
background-color: var(--main-40);
|
2025-07-23 03:52:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-06-30 22:29:23 +08:00
|
|
|
|
}
|
2024-09-09 17:07:03 +08:00
|
|
|
|
|
2025-07-23 03:52:22 +08:00
|
|
|
|
|
|
|
|
|
|
/* Improve the resize handle visibility */
|
|
|
|
|
|
.resize-handle,
|
|
|
|
|
|
.resize-handle-horizontal {
|
|
|
|
|
|
transition: all 0.2s ease;
|
|
|
|
|
|
opacity: 0.6;
|
|
|
|
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
|
|
opacity: 1;
|
|
|
|
|
|
background-color: var(--main-color);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
/* Responsive design for smaller screens */
|
|
|
|
|
|
@media (max-width: 768px) {
|
|
|
|
|
|
.unified-layout {
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.unified-layout .left-panel {
|
|
|
|
|
|
border-right: none;
|
|
|
|
|
|
border-bottom: 1px solid var(--gray-200);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.unified-layout .resize-handle {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 2px;
|
|
|
|
|
|
cursor: row-resize;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-23 03:52:22 +08:00
|
|
|
|
/* Table row selection styling */
|
|
|
|
|
|
:deep(.ant-table-tbody > tr.ant-table-row-selected > td) {
|
2025-07-30 11:00:50 +08:00
|
|
|
|
background-color: var(--main-5);
|
2025-07-23 03:52:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
:deep(.ant-table-tbody > tr:hover > td) {
|
2025-07-30 11:00:50 +08:00
|
|
|
|
background-color: var(--main-5);
|
2025-07-23 03:52:22 +08:00
|
|
|
|
}
|
2024-09-09 17:07:03 +08:00
|
|
|
|
</style>
|
2025-03-23 23:10:32 +08:00
|
|
|
|
|
2025-07-23 03:52:22 +08:00
|
|
|
|
<style lang="less">
|
|
|
|
|
|
:deep(.full-modal) {
|
|
|
|
|
|
.ant-modal {
|
|
|
|
|
|
max-width: 100%;
|
|
|
|
|
|
top: 0;
|
|
|
|
|
|
padding-bottom: 0;
|
|
|
|
|
|
margin: 0;
|
|
|
|
|
|
padding: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.ant-modal-content {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
height: calc(100vh - 200px);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.ant-modal-body {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.maximized-graph-header {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
|
|
|
|
h3 {
|
|
|
|
|
|
margin: 0;
|
|
|
|
|
|
color: var(--gray-800);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.maximized-graph-content {
|
|
|
|
|
|
height: calc(100vh - 300px);
|
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* 全局样式作为备用方案 */
|
|
|
|
|
|
.ant-popover .query-params-compact {
|
|
|
|
|
|
width: 220px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.ant-popover .query-params-compact .params-loading {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
min-height: 80px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.ant-popover .query-params-compact .params-grid {
|
|
|
|
|
|
display: grid;
|
|
|
|
|
|
grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
|
|
|
|
|
|
gap: 10px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.ant-popover .query-params-compact .param-item {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.ant-popover .query-params-compact .param-item label {
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
color: var(--gray-700);
|
|
|
|
|
|
margin-right: 8px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-08-05 18:00:45 +08:00
|
|
|
|
/* Improve panel transitions */
|
|
|
|
|
|
.panel-section {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
transition: all 0.3s;
|
|
|
|
|
|
min-height: 0;
|
|
|
|
|
|
|
|
|
|
|
|
&.collapsed {
|
|
|
|
|
|
height: 36px;
|
|
|
|
|
|
flex: none;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.section-header {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
padding: 8px 12px;
|
|
|
|
|
|
border-bottom: 1px solid #f0f0f0;
|
|
|
|
|
|
background-color: #fafafa;
|
|
|
|
|
|
|
|
|
|
|
|
.header-left {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
gap: 12px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.section-title {
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
color: var(--gray-700);
|
|
|
|
|
|
margin: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.panel-actions {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
gap: 0px;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.content {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
min-height: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.query-section,
|
|
|
|
|
|
.graph-section {
|
|
|
|
|
|
.panel-section();
|
|
|
|
|
|
|
|
|
|
|
|
.content {
|
|
|
|
|
|
padding: 8px;
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-07-23 03:52:22 +08:00
|
|
|
|
</style>
|