feat: vertical split for process operation

This commit is contained in:
Pavel
2025-08-19 18:40:08 +02:00
parent e28e363bd0
commit 176d75768f

View File

@@ -1,6 +1,7 @@
<script lang="ts"> <script lang="ts">
import { writable } from 'svelte/store'; import { writable } from 'svelte/store';
import { DatabaseProcess } from 'dbgate-types'; import { DatabaseProcess } from 'dbgate-types';
import VerticalSplitter from '../elements/VerticalSplitter.svelte';
import TableControl from '../elements/TableControl.svelte'; import TableControl from '../elements/TableControl.svelte';
import { _t } from '../translations'; import { _t } from '../translations';
import CtaButton from '../buttons/CtaButton.svelte'; import CtaButton from '../buttons/CtaButton.svelte';
@@ -9,6 +10,7 @@
import { showSnackbarError, showSnackbarSuccess } from '../utility/snackbar'; import { showSnackbarError, showSnackbarSuccess } from '../utility/snackbar';
import { showModal } from '../modals/modalTools'; import { showModal } from '../modals/modalTools';
import ConfirmModal from '../modals/ConfirmModal.svelte'; import ConfirmModal from '../modals/ConfirmModal.svelte';
import SqlEditor from '../query/SqlEditor.svelte';
export let conid; export let conid;
export let isSummaryOpened: boolean = false; export let isSummaryOpened: boolean = false;
@@ -16,6 +18,7 @@
export let refreshInterval: number = 1000; export let refreshInterval: number = 1000;
export let tabVisible: boolean = false; export let tabVisible: boolean = false;
let selectedProcess: DatabaseProcess | null = null;
const filters = writable({}); const filters = writable({});
let internalProcesses = [...processes]; let internalProcesses = [...processes];
@@ -81,84 +84,99 @@
</script> </script>
<div class="wrapper"> <div class="wrapper">
<TableControl <VerticalSplitter initialValue="70%" isSplitter={!!selectedProcess}>
{filters} <svelte:fragment slot="1">
stickyHeader <div>
rows={internalProcesses} <TableControl
columns={[ clickable
{ on:clickrow={e => {
sortable: true, selectedProcess = e.detail;
filterable: true, }}
header: _t('summaryProcesses.processId', { defaultMessage: 'Process ID' }), {filters}
fieldName: 'processId', stickyHeader
slot: 1, rows={internalProcesses}
}, columns={[
{ {
sortable: true, sortable: true,
filterable: true, filterable: true,
header: _t('summaryProcesses.connectionId', { defaultMessage: 'Connection ID' }), header: _t('summaryProcesses.processId', { defaultMessage: 'Process ID' }),
fieldName: 'connectionId', fieldName: 'processId',
}, slot: 1,
{ },
sortable: true, {
filterable: true, sortable: true,
header: _t('summaryProcesses.client', { defaultMessage: 'Client' }), filterable: true,
fieldName: 'client', header: _t('summaryProcesses.connectionId', { defaultMessage: 'Connection ID' }),
}, fieldName: 'connectionId',
{ },
filterable: true, {
header: _t('summaryProcesses.operation', { defaultMessage: 'Operation' }), sortable: true,
fieldName: 'operation', filterable: true,
}, header: _t('summaryProcesses.client', { defaultMessage: 'Client' }),
{ fieldName: 'client',
sortable: true, },
filterable: true, {
header: _t('summaryProcesses.namespace', { defaultMessage: 'Namespace' }), filterable: true,
fieldName: 'namespace', header: _t('summaryProcesses.operation', { defaultMessage: 'Operation' }),
}, fieldName: 'operation',
{ },
sortable: true, {
header: _t('summaryProcesses.runningTime', { defaultMessage: 'Running Time' }), sortable: true,
fieldName: 'runningTime', filterable: true,
slot: 2, header: _t('summaryProcesses.namespace', { defaultMessage: 'Namespace' }),
}, fieldName: 'namespace',
{ },
sortable: true, {
filterable: true, sortable: true,
header: _t('summaryProcesses.state', { defaultMessage: 'State' }), header: _t('summaryProcesses.runningTime', { defaultMessage: 'Running Time' }),
fieldName: 'state', fieldName: 'runningTime',
}, slot: 2,
{ },
sortable: true, {
header: _t('summaryProcesses.waitingFor', { defaultMessage: 'Waiting For' }), sortable: true,
fieldName: 'waitingFor', filterable: true,
slot: 3, header: _t('summaryProcesses.state', { defaultMessage: 'State' }),
}, fieldName: 'state',
{ },
header: _t('summaryProcesses.actions', { defaultMessage: 'Actions' }), {
fieldName: 'processId', sortable: true,
slot: 0, header: _t('summaryProcesses.waitingFor', { defaultMessage: 'Waiting For' }),
}, fieldName: 'waitingFor',
]} slot: 3,
> },
<svelte:fragment slot="0" let:row> {
<CtaButton on:click={() => killProcessWithConfirm(row.processId)}> header: _t('summaryProcesses.actions', { defaultMessage: 'Actions' }),
{_t('common.kill', { defaultMessage: 'Kill' })} fieldName: 'processId',
</CtaButton> slot: 0,
</svelte:fragment> },
]}
>
<svelte:fragment slot="0" let:row>
<CtaButton on:click={() => killProcessWithConfirm(row.processId)}>
{_t('common.kill', { defaultMessage: 'Kill' })}
</CtaButton>
</svelte:fragment>
<svelte:fragment slot="1" let:row> <svelte:fragment slot="1" let:row>
<code>{row.processId}</code> <code>{row.processId}</code>
</svelte:fragment> </svelte:fragment>
<svelte:fragment slot="2" let:row> <svelte:fragment slot="2" let:row>
<span>{formatRunningTime(row.runningTime)}</span> <span>{formatRunningTime(row.runningTime)}</span>
</svelte:fragment> </svelte:fragment>
<svelte:fragment slot="3" let:row> <svelte:fragment slot="3" let:row>
<span class:waiting={row.waitingFor}>{row.waitingFor ? 'Yes' : 'No'}</span> <span class:waiting={row.waitingFor}>{row.waitingFor ? 'Yes' : 'No'}</span>
</svelte:fragment>
</TableControl>
</div>
</svelte:fragment> </svelte:fragment>
</TableControl> <svelte:fragment slot="2">
{#if !!selectedProcess}
<SqlEditor value={selectedProcess.operation} readOnly />
{/if}
</svelte:fragment>
</VerticalSplitter>
</div> </div>
<style> <style>