2022-07-16 12:01:37 +02:00
|
|
|
<template>
|
|
|
|
<div
|
|
|
|
ref="wrapper"
|
|
|
|
class="query-console-wrapper"
|
|
|
|
@mouseenter="isHover = true"
|
|
|
|
@mouseleave="isHover = false"
|
|
|
|
>
|
|
|
|
<div ref="resizer" class="query-console-resizer" />
|
|
|
|
<div
|
|
|
|
id="query-console"
|
|
|
|
ref="queryConsole"
|
|
|
|
class="query-console column col-12"
|
|
|
|
:style="{height: localHeight ? localHeight+'px' : ''}"
|
|
|
|
>
|
|
|
|
<div class="query-console-header">
|
|
|
|
<div>{{ t('word.console') }}</div>
|
2022-07-17 12:36:37 +02:00
|
|
|
<button class="btn btn-clear mr-1" @click="resizeConsole(0)" />
|
2022-07-16 12:01:37 +02:00
|
|
|
</div>
|
|
|
|
<div ref="queryConsoleBody" class="query-console-body">
|
|
|
|
<div
|
|
|
|
v-for="(wLog, i) in workspaceLogs"
|
|
|
|
:key="i"
|
|
|
|
class="query-console-log"
|
2022-07-17 12:36:37 +02:00
|
|
|
tabindex="0"
|
2022-07-18 10:38:07 +02:00
|
|
|
@contextmenu.prevent="contextMenu($event, wLog)"
|
2022-07-16 12:01:37 +02:00
|
|
|
>
|
|
|
|
<span class="type-datetime">{{ moment(wLog.date).format('YYYY-MM-DD HH:mm:ss') }}</span>: <span class="type-string">{{ wLog.sql }}</span>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
2022-07-18 10:38:07 +02:00
|
|
|
<BaseContextMenu
|
|
|
|
v-if="isContext"
|
|
|
|
:context-event="contextEvent"
|
|
|
|
@close-context="isContext = false"
|
|
|
|
>
|
|
|
|
<div class="context-element" @click="copyQuery">
|
|
|
|
<span class="d-flex"><i class="mdi mdi-18px mdi-content-copy text-light pr-1" /> {{ $t('word.copy') }}</span>
|
|
|
|
</div>
|
|
|
|
</BaseContextMenu>
|
2022-07-16 12:01:37 +02:00
|
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
|
|
import { computed, nextTick, onMounted, ref, Ref, watch } from 'vue';
|
|
|
|
import { useI18n } from 'vue-i18n';
|
|
|
|
import * as moment from 'moment';
|
|
|
|
import { useConsoleStore } from '@/stores/console';
|
|
|
|
import { storeToRefs } from 'pinia';
|
2022-07-18 10:38:07 +02:00
|
|
|
import BaseContextMenu from '@/components/BaseContextMenu.vue';
|
2022-07-16 12:01:37 +02:00
|
|
|
|
|
|
|
const { t } = useI18n();
|
|
|
|
|
|
|
|
const consoleStore = useConsoleStore();
|
|
|
|
|
|
|
|
const { resizeConsole, getLogsByWorkspace } = consoleStore;
|
|
|
|
const { consoleHeight } = storeToRefs(consoleStore);
|
|
|
|
|
|
|
|
const props = defineProps({
|
|
|
|
uid: String
|
|
|
|
});
|
|
|
|
|
|
|
|
const wrapper: Ref<HTMLInputElement> = ref(null);
|
|
|
|
const queryConsole: Ref<HTMLInputElement> = ref(null);
|
|
|
|
const queryConsoleBody: Ref<HTMLInputElement> = ref(null);
|
|
|
|
const resizer: Ref<HTMLInputElement> = ref(null);
|
|
|
|
const localHeight = ref(250);
|
|
|
|
const isHover = ref(false);
|
2022-07-18 10:38:07 +02:00
|
|
|
const isContext = ref(false);
|
|
|
|
const contextQuery: Ref<string> = ref(null);
|
|
|
|
const contextEvent: Ref<MouseEvent> = ref(null);
|
2022-07-16 12:01:37 +02:00
|
|
|
|
|
|
|
const resize = (e: MouseEvent) => {
|
|
|
|
const el = queryConsole.value;
|
|
|
|
let consoleHeight = el.getBoundingClientRect().bottom - e.pageY;
|
|
|
|
if (consoleHeight > 400) consoleHeight = 400;
|
|
|
|
localHeight.value = consoleHeight;
|
|
|
|
};
|
|
|
|
|
|
|
|
const workspaceLogs = computed(() => {
|
|
|
|
return getLogsByWorkspace(props.uid);
|
|
|
|
});
|
|
|
|
|
|
|
|
const stopResize = () => {
|
|
|
|
if (localHeight.value < 0) localHeight.value = 0;
|
|
|
|
resizeConsole(localHeight.value);
|
|
|
|
window.removeEventListener('mousemove', resize);
|
|
|
|
window.removeEventListener('mouseup', stopResize);
|
|
|
|
};
|
|
|
|
|
2022-07-18 10:38:07 +02:00
|
|
|
const contextMenu = (event: MouseEvent, wLog: {date: Date; sql: string}) => {
|
|
|
|
contextEvent.value = event;
|
|
|
|
contextQuery.value = wLog.sql;
|
|
|
|
isContext.value = true;
|
|
|
|
};
|
|
|
|
|
|
|
|
const copyQuery = () => {
|
|
|
|
navigator.clipboard.writeText(contextQuery.value);
|
|
|
|
isContext.value = false;
|
|
|
|
};
|
|
|
|
|
2022-07-16 12:01:37 +02:00
|
|
|
watch(workspaceLogs, async () => {
|
|
|
|
if (!isHover.value) {
|
|
|
|
await nextTick();
|
|
|
|
queryConsoleBody.value.scrollTop = queryConsoleBody.value.scrollHeight;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
localHeight.value = consoleHeight.value;
|
|
|
|
queryConsoleBody.value.scrollTop = queryConsoleBody.value.scrollHeight;
|
|
|
|
});
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
resizer.value.addEventListener('mousedown', (e: MouseEvent) => {
|
|
|
|
e.preventDefault();
|
|
|
|
|
|
|
|
window.addEventListener('mousemove', resize);
|
|
|
|
window.addEventListener('mouseup', stopResize);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
.query-console-wrapper{
|
|
|
|
width: 100%;
|
|
|
|
z-index: 9;
|
|
|
|
margin-top: auto;
|
|
|
|
position: absolute;
|
|
|
|
bottom: 0;
|
|
|
|
|
|
|
|
.query-console-resizer{
|
|
|
|
height: 4px;
|
|
|
|
top: -1px;
|
|
|
|
width: 100%;
|
|
|
|
cursor: ns-resize;
|
|
|
|
position: absolute;
|
|
|
|
z-index: 99;
|
|
|
|
transition: background 0.2s;
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
background: rgba($primary-color, 50%);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.query-console {
|
|
|
|
padding: 0;
|
|
|
|
padding-bottom: $footer-height;
|
|
|
|
.query-console-header {
|
|
|
|
display: flex;
|
|
|
|
justify-content: space-between;
|
|
|
|
align-items: center;
|
|
|
|
padding: 4px;
|
|
|
|
font-weight: 700;
|
|
|
|
}
|
|
|
|
|
|
|
|
.query-console-body {
|
|
|
|
overflow: auto;
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
max-height: 100%;
|
|
|
|
padding: 0 6px;
|
|
|
|
|
|
|
|
.query-console-log {
|
|
|
|
padding: 1px 3px;
|
|
|
|
user-select: text;
|
|
|
|
border-radius: $border-radius;
|
2022-07-17 12:36:37 +02:00
|
|
|
&:hover,
|
|
|
|
&:focus {
|
2022-07-16 12:01:37 +02:00
|
|
|
background: $bg-color-gray;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
</style>
|