mirror of
https://github.com/dbgate/dbgate
synced 2024-11-08 04:35:58 +00:00
formview save
This commit is contained in:
parent
90c4b44fdb
commit
ec90a8b952
@ -2,6 +2,9 @@
|
|||||||
let lastFocusedDataGrid = null;
|
let lastFocusedDataGrid = null;
|
||||||
const getCurrentDataGrid = () =>
|
const getCurrentDataGrid = () =>
|
||||||
lastFocusedDataGrid?.getTabId && lastFocusedDataGrid?.getTabId() == getActiveTabId() ? lastFocusedDataGrid : null;
|
lastFocusedDataGrid?.getTabId && lastFocusedDataGrid?.getTabId() == getActiveTabId() ? lastFocusedDataGrid : null;
|
||||||
|
export function clearLastFocusedDataGrid() {
|
||||||
|
lastFocusedDataGrid = null;
|
||||||
|
}
|
||||||
|
|
||||||
registerCommand({
|
registerCommand({
|
||||||
id: 'dataGrid.refresh',
|
id: 'dataGrid.refresh',
|
||||||
@ -205,6 +208,7 @@
|
|||||||
import { copyTextToClipboard } from '../utility/clipboard';
|
import { copyTextToClipboard } from '../utility/clipboard';
|
||||||
import invalidateCommands from '../commands/invalidateCommands';
|
import invalidateCommands from '../commands/invalidateCommands';
|
||||||
import createRef from '../utility/createRef';
|
import createRef from '../utility/createRef';
|
||||||
|
import { clearLastFocusedFormView } from '../formview/FormView.svelte';
|
||||||
|
|
||||||
export let onLoadNextData = undefined;
|
export let onLoadNextData = undefined;
|
||||||
export let grider = undefined;
|
export let grider = undefined;
|
||||||
@ -666,7 +670,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleGridKeyDown(event) {
|
function handleGridKeyDown(event) {
|
||||||
|
|
||||||
if ($inplaceEditorState.cell) return;
|
if ($inplaceEditorState.cell) return;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@ -903,6 +906,7 @@
|
|||||||
on:keydown={handleGridKeyDown}
|
on:keydown={handleGridKeyDown}
|
||||||
on:focus={() => {
|
on:focus={() => {
|
||||||
lastFocusedDataGrid = instance;
|
lastFocusedDataGrid = instance;
|
||||||
|
clearLastFocusedFormView();
|
||||||
invalidateCommands();
|
invalidateCommands();
|
||||||
}}
|
}}
|
||||||
on:paste={handlePaste}
|
on:paste={handlePaste}
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
let lastFocusedFormView = null;
|
let lastFocusedFormView = null;
|
||||||
const getCurrentDataForm = () =>
|
const getCurrentDataForm = () =>
|
||||||
lastFocusedFormView?.getTabId && lastFocusedFormView?.getTabId() == getActiveTabId() ? lastFocusedFormView : null;
|
lastFocusedFormView?.getTabId && lastFocusedFormView?.getTabId() == getActiveTabId() ? lastFocusedFormView : null;
|
||||||
|
export function clearLastFocusedFormView() {
|
||||||
|
lastFocusedFormView = null;
|
||||||
|
}
|
||||||
|
|
||||||
registerCommand({
|
registerCommand({
|
||||||
id: 'dataForm.switchToTable',
|
id: 'dataForm.switchToTable',
|
||||||
@ -12,6 +15,17 @@
|
|||||||
onClick: () => getCurrentDataForm().switchToTable(),
|
onClick: () => getCurrentDataForm().switchToTable(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
registerCommand({
|
||||||
|
id: 'dataForm.save',
|
||||||
|
group: 'save',
|
||||||
|
category: 'Data form',
|
||||||
|
name: 'Save',
|
||||||
|
toolbar: true,
|
||||||
|
icon: 'icon save',
|
||||||
|
testEnabled: () => getCurrentDataForm()?.getFormer()?.allowSave,
|
||||||
|
onClick: () => getCurrentDataForm().save(),
|
||||||
|
});
|
||||||
|
|
||||||
function isDataCell(cell) {
|
function isDataCell(cell) {
|
||||||
return cell[1] % 2 == 1;
|
return cell[1] % 2 == 1;
|
||||||
}
|
}
|
||||||
@ -27,15 +41,18 @@
|
|||||||
|
|
||||||
import registerCommand from '../commands/registerCommand';
|
import registerCommand from '../commands/registerCommand';
|
||||||
import DataGridCell from '../datagrid/DataGridCell.svelte';
|
import DataGridCell from '../datagrid/DataGridCell.svelte';
|
||||||
|
import { clearLastFocusedDataGrid } from '../datagrid/DataGridCore.svelte';
|
||||||
import InplaceEditor from '../datagrid/InplaceEditor.svelte';
|
import InplaceEditor from '../datagrid/InplaceEditor.svelte';
|
||||||
import { cellFromEvent } from '../datagrid/selection';
|
import { cellFromEvent } from '../datagrid/selection';
|
||||||
import ColumnLabel from '../elements/ColumnLabel.svelte';
|
import ColumnLabel from '../elements/ColumnLabel.svelte';
|
||||||
|
import LoadingInfo from '../elements/LoadingInfo.svelte';
|
||||||
import { plusExpandIcon } from '../icons/expandIcons';
|
import { plusExpandIcon } from '../icons/expandIcons';
|
||||||
import FontIcon from '../icons/FontIcon.svelte';
|
import FontIcon from '../icons/FontIcon.svelte';
|
||||||
|
|
||||||
import { getActiveTabId } from '../stores';
|
import { getActiveTabId } from '../stores';
|
||||||
import contextMenu from '../utility/contextMenu';
|
import contextMenu from '../utility/contextMenu';
|
||||||
import createReducer from '../utility/createReducer';
|
import createReducer from '../utility/createReducer';
|
||||||
|
import keycodes from '../utility/keycodes';
|
||||||
import resizeObserver from '../utility/resizeObserver';
|
import resizeObserver from '../utility/resizeObserver';
|
||||||
|
|
||||||
export let config;
|
export let config;
|
||||||
@ -46,6 +63,7 @@
|
|||||||
export let isLoading;
|
export let isLoading;
|
||||||
export let former;
|
export let former;
|
||||||
export let formDisplay;
|
export let formDisplay;
|
||||||
|
export let onSave;
|
||||||
|
|
||||||
let wrapperHeight = 1;
|
let wrapperHeight = 1;
|
||||||
let rowHeight = 1;
|
let rowHeight = 1;
|
||||||
@ -73,6 +91,10 @@
|
|||||||
return tabid;
|
return tabid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getFormer() {
|
||||||
|
return former;
|
||||||
|
}
|
||||||
|
|
||||||
export function switchToTable() {
|
export function switchToTable() {
|
||||||
setConfig(cfg => ({
|
setConfig(cfg => ({
|
||||||
...cfg,
|
...cfg,
|
||||||
@ -81,6 +103,15 @@
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function save() {
|
||||||
|
if ($inplaceEditorState.cell) {
|
||||||
|
// @ts-ignore
|
||||||
|
dispatchInsplaceEditor({ type: 'shouldSave' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (onSave) onSave();
|
||||||
|
}
|
||||||
|
|
||||||
const handleTableMouseDown = event => {
|
const handleTableMouseDown = event => {
|
||||||
if (event.target.closest('.buttonLike')) return;
|
if (event.target.closest('.buttonLike')) return;
|
||||||
if (event.target.closest('.resizeHandleControl')) return;
|
if (event.target.closest('.resizeHandleControl')) return;
|
||||||
@ -93,12 +124,12 @@
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const cell = cellFromEvent(event);
|
const cell = cellFromEvent(event);
|
||||||
|
|
||||||
if (isDataCell(cell) && !_.isEqual(cell, inplaceEditorState.cell) && _.isEqual(cell, currentCell)) {
|
if (isDataCell(cell) && !_.isEqual(cell, $inplaceEditorState.cell) && _.isEqual(cell, currentCell)) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
if (rowData) {
|
if (rowData) {
|
||||||
dispatchInsplaceEditor({ type: 'show', cell, selectAll: true });
|
dispatchInsplaceEditor({ type: 'show', cell, selectAll: true });
|
||||||
}
|
}
|
||||||
} else if (!_.isEqual(cell, inplaceEditorState.cell)) {
|
} else if (!_.isEqual(cell, $inplaceEditorState.cell)) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
dispatchInsplaceEditor({ type: 'close' });
|
dispatchInsplaceEditor({ type: 'close' });
|
||||||
}
|
}
|
||||||
@ -161,9 +192,78 @@
|
|||||||
return [{ command: 'dataForm.switchToTable' }];
|
return [{ command: 'dataForm.switchToTable' }];
|
||||||
}
|
}
|
||||||
|
|
||||||
$: console.log('rowHeight', rowHeight);
|
function handleKeyDown(event) {
|
||||||
|
if ($inplaceEditorState.cell) return;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!event.ctrlKey &&
|
||||||
|
!event.altKey &&
|
||||||
|
((event.keyCode >= keycodes.a && event.keyCode <= keycodes.z) ||
|
||||||
|
(event.keyCode >= keycodes.n0 && event.keyCode <= keycodes.n9) ||
|
||||||
|
event.keyCode == keycodes.dash)
|
||||||
|
) {
|
||||||
|
// @ts-ignore
|
||||||
|
event.preventDefault();
|
||||||
|
dispatchInsplaceEditor({ type: 'show', text: event.key, cell: currentCell });
|
||||||
|
// console.log('event', event.nativeEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.keyCode == keycodes.f2) {
|
||||||
|
// @ts-ignore
|
||||||
|
dispatchInsplaceEditor({ type: 'show', cell: currentCell, selectAll: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
handleCursorMove(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
const scrollIntoView = cell => {
|
||||||
|
const element = domCells[`${cell[0]},${cell[1]}`];
|
||||||
|
if (element) element.scrollIntoView();
|
||||||
|
};
|
||||||
|
|
||||||
|
const moveCurrentCell = (row, col) => {
|
||||||
|
if (row < 0) row = 0;
|
||||||
|
if (col < 0) col = 0;
|
||||||
|
if (col >= columnChunks.length * 2) col = columnChunks.length * 2 - 1;
|
||||||
|
const chunk = columnChunks[Math.floor(col / 2)];
|
||||||
|
if (chunk && row >= chunk.length) row = chunk.length - 1;
|
||||||
|
currentCell = [row, col];
|
||||||
|
scrollIntoView(currentCell);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCursorMove = event => {
|
||||||
|
if (event.ctrlKey) {
|
||||||
|
switch (event.keyCode) {
|
||||||
|
case keycodes.leftArrow:
|
||||||
|
return moveCurrentCell(currentCell[0], 0);
|
||||||
|
case keycodes.rightArrow:
|
||||||
|
return moveCurrentCell(currentCell[0], columnChunks.length * 2 - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (event.keyCode) {
|
||||||
|
case keycodes.leftArrow:
|
||||||
|
return moveCurrentCell(currentCell[0], currentCell[1] - 1);
|
||||||
|
case keycodes.rightArrow:
|
||||||
|
return moveCurrentCell(currentCell[0], currentCell[1] + 1);
|
||||||
|
case keycodes.upArrow:
|
||||||
|
return moveCurrentCell(currentCell[0] - 1, currentCell[1]);
|
||||||
|
case keycodes.downArrow:
|
||||||
|
return moveCurrentCell(currentCell[0] + 1, currentCell[1]);
|
||||||
|
case keycodes.pageUp:
|
||||||
|
return moveCurrentCell(0, currentCell[1]);
|
||||||
|
case keycodes.pageDown:
|
||||||
|
return moveCurrentCell(rowCount - 1, currentCell[1]);
|
||||||
|
case keycodes.home:
|
||||||
|
return moveCurrentCell(0, 0);
|
||||||
|
case keycodes.end:
|
||||||
|
return moveCurrentCell(rowCount - 1, columnChunks.length * 2 - 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
{#if isLoading}
|
||||||
|
<LoadingInfo wrapper message="Loading data" />
|
||||||
|
{:else}
|
||||||
<div class="outer">
|
<div class="outer">
|
||||||
<div class="wrapper" use:contextMenu={createMenu} bind:clientHeight={wrapperHeight}>
|
<div class="wrapper" use:contextMenu={createMenu} bind:clientHeight={wrapperHeight}>
|
||||||
{#each columnChunks as chunk, chunkIndex}
|
{#each columnChunks as chunk, chunkIndex}
|
||||||
@ -233,11 +333,14 @@
|
|||||||
bind:this={domFocusField}
|
bind:this={domFocusField}
|
||||||
on:focus={() => {
|
on:focus={() => {
|
||||||
lastFocusedFormView = instance;
|
lastFocusedFormView = instance;
|
||||||
|
clearLastFocusedDataGrid();
|
||||||
invalidateCommands();
|
invalidateCommands();
|
||||||
}}
|
}}
|
||||||
|
on:keydown={handleKeyDown}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
table {
|
table {
|
||||||
|
@ -20,6 +20,14 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { changeSetToSql, createChangeSet } from 'dbgate-datalib';
|
||||||
|
import { scriptToSql } from 'dbgate-sqltree';
|
||||||
|
import ConfirmSqlModal from '../modals/ConfirmSqlModal.svelte';
|
||||||
|
|
||||||
|
import ErrorMessageModal from '../modals/ErrorMessageModal.svelte';
|
||||||
|
|
||||||
|
import { showModal } from '../modals/modalTools';
|
||||||
|
|
||||||
import axiosInstance from '../utility/axiosInstance';
|
import axiosInstance from '../utility/axiosInstance';
|
||||||
import ChangeSetFormer from './ChangeSetFormer';
|
import ChangeSetFormer from './ChangeSetFormer';
|
||||||
import FormView from './FormView.svelte';
|
import FormView from './FormView.svelte';
|
||||||
@ -28,6 +36,8 @@
|
|||||||
export let changeSetState;
|
export let changeSetState;
|
||||||
export let dispatchChangeSet;
|
export let dispatchChangeSet;
|
||||||
export let masterLoadedTime;
|
export let masterLoadedTime;
|
||||||
|
export let conid;
|
||||||
|
export let database;
|
||||||
|
|
||||||
let isLoadingData = false;
|
let isLoadingData = false;
|
||||||
let isLoadedData = false;
|
let isLoadedData = false;
|
||||||
@ -117,6 +127,35 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$: former = new ChangeSetFormer(rowData, changeSetState, dispatchChangeSet, formDisplay);
|
$: former = new ChangeSetFormer(rowData, changeSetState, dispatchChangeSet, formDisplay);
|
||||||
|
|
||||||
|
async function handleConfirmSql(sql) {
|
||||||
|
const resp = await axiosInstance.request({
|
||||||
|
url: 'database-connections/query-data',
|
||||||
|
method: 'post',
|
||||||
|
params: {
|
||||||
|
conid,
|
||||||
|
database,
|
||||||
|
},
|
||||||
|
data: { sql },
|
||||||
|
});
|
||||||
|
const { errorMessage } = resp.data || {};
|
||||||
|
if (errorMessage) {
|
||||||
|
showModal(ErrorMessageModal, { title: 'Error when saving', message: errorMessage });
|
||||||
|
} else {
|
||||||
|
dispatchChangeSet({ type: 'reset', value: createChangeSet() });
|
||||||
|
formDisplay.reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSave() {
|
||||||
|
const script = changeSetToSql(changeSetState && changeSetState.value, formDisplay.dbinfo);
|
||||||
|
const sql = scriptToSql(formDisplay.driver, script);
|
||||||
|
showModal(ConfirmSqlModal, {
|
||||||
|
sql,
|
||||||
|
onConfirm: () => handleConfirmSql(sql),
|
||||||
|
engine: formDisplay.engine,
|
||||||
|
});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<FormView {...$$props} {former} isLoading={isLoadingData} {allRowCount} {rowCountBefore} />
|
<FormView {...$$props} {former} isLoading={isLoadingData} {allRowCount} {rowCountBefore} onSave={handleSave} />
|
||||||
|
Loading…
Reference in New Issue
Block a user