diff --git a/packages/web/src/datagrid/DataGridCore.svelte b/packages/web/src/datagrid/DataGridCore.svelte index dc861f08c..19d40ba4e 100644 --- a/packages/web/src/datagrid/DataGridCore.svelte +++ b/packages/web/src/datagrid/DataGridCore.svelte @@ -2,6 +2,9 @@ let lastFocusedDataGrid = null; const getCurrentDataGrid = () => lastFocusedDataGrid?.getTabId && lastFocusedDataGrid?.getTabId() == getActiveTabId() ? lastFocusedDataGrid : null; + export function clearLastFocusedDataGrid() { + lastFocusedDataGrid = null; + } registerCommand({ id: 'dataGrid.refresh', @@ -205,6 +208,7 @@ import { copyTextToClipboard } from '../utility/clipboard'; import invalidateCommands from '../commands/invalidateCommands'; import createRef from '../utility/createRef'; + import { clearLastFocusedFormView } from '../formview/FormView.svelte'; export let onLoadNextData = undefined; export let grider = undefined; @@ -666,7 +670,6 @@ } function handleGridKeyDown(event) { - if ($inplaceEditorState.cell) return; if ( @@ -903,6 +906,7 @@ on:keydown={handleGridKeyDown} on:focus={() => { lastFocusedDataGrid = instance; + clearLastFocusedFormView(); invalidateCommands(); }} on:paste={handlePaste} diff --git a/packages/web/src/formview/FormView.svelte b/packages/web/src/formview/FormView.svelte index 1abafb1ff..3362ef5ee 100644 --- a/packages/web/src/formview/FormView.svelte +++ b/packages/web/src/formview/FormView.svelte @@ -2,6 +2,9 @@ let lastFocusedFormView = null; const getCurrentDataForm = () => lastFocusedFormView?.getTabId && lastFocusedFormView?.getTabId() == getActiveTabId() ? lastFocusedFormView : null; + export function clearLastFocusedFormView() { + lastFocusedFormView = null; + } registerCommand({ id: 'dataForm.switchToTable', @@ -12,6 +15,17 @@ 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) { return cell[1] % 2 == 1; } @@ -27,15 +41,18 @@ import registerCommand from '../commands/registerCommand'; import DataGridCell from '../datagrid/DataGridCell.svelte'; + import { clearLastFocusedDataGrid } from '../datagrid/DataGridCore.svelte'; import InplaceEditor from '../datagrid/InplaceEditor.svelte'; import { cellFromEvent } from '../datagrid/selection'; import ColumnLabel from '../elements/ColumnLabel.svelte'; +import LoadingInfo from '../elements/LoadingInfo.svelte'; import { plusExpandIcon } from '../icons/expandIcons'; import FontIcon from '../icons/FontIcon.svelte'; import { getActiveTabId } from '../stores'; import contextMenu from '../utility/contextMenu'; import createReducer from '../utility/createReducer'; + import keycodes from '../utility/keycodes'; import resizeObserver from '../utility/resizeObserver'; export let config; @@ -46,6 +63,7 @@ export let isLoading; export let former; export let formDisplay; + export let onSave; let wrapperHeight = 1; let rowHeight = 1; @@ -73,6 +91,10 @@ return tabid; } + export function getFormer() { + return former; + } + export function switchToTable() { setConfig(cfg => ({ ...cfg, @@ -81,6 +103,15 @@ })); } + export function save() { + if ($inplaceEditorState.cell) { + // @ts-ignore + dispatchInsplaceEditor({ type: 'shouldSave' }); + return; + } + if (onSave) onSave(); + } + const handleTableMouseDown = event => { if (event.target.closest('.buttonLike')) return; if (event.target.closest('.resizeHandleControl')) return; @@ -93,12 +124,12 @@ event.preventDefault(); 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 if (rowData) { dispatchInsplaceEditor({ type: 'show', cell, selectAll: true }); } - } else if (!_.isEqual(cell, inplaceEditorState.cell)) { + } else if (!_.isEqual(cell, $inplaceEditorState.cell)) { // @ts-ignore dispatchInsplaceEditor({ type: 'close' }); } @@ -161,83 +192,155 @@ 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); + } + }; -
-
- {#each columnChunks as chunk, chunkIndex} - - {#each chunk as col, rowIndex} - - + {/each} +
{ - // @ts-ignore - if (rowHeight == 1) rowHeight = e.detail.height; - }} - > -
- {#if col.foreignKey} - { - e.stopPropagation(); - formDisplay.toggleExpandedColumn(col.uniqueName); +{#if isLoading} + +{:else} +
+
+ {#each columnChunks as chunk, chunkIndex} + + {#each chunk as col, rowIndex} + + + + {#if $inplaceEditorState.cell && rowIndex == $inplaceEditorState.cell[0] && chunkIndex * 2 + 1 == $inplaceEditorState.cell[1]} + { + former.setCellValue(col.uniqueName, value); }} /> - {:else} - {/if} - - - - - - {#if $inplaceEditorState.cell && rowIndex == $inplaceEditorState.cell[0] && chunkIndex * 2 + 1 == $inplaceEditorState.cell[1]} - { - former.setCellValue(col.uniqueName, value); - }} - /> - {/if} - - - {/each} -
{ + // @ts-ignore + if (rowHeight == 1) rowHeight = e.detail.height; + }} + > +
+ {#if col.foreignKey} + { + e.stopPropagation(); + formDisplay.toggleExpandedColumn(col.uniqueName); + }} + /> + {:else} + + {/if} + + +
+
- {/each} - { - lastFocusedFormView = instance; - invalidateCommands(); - }} - /> + +
+ {/each} + { + lastFocusedFormView = instance; + clearLastFocusedDataGrid(); + invalidateCommands(); + }} + on:keydown={handleKeyDown} + /> +
- +{/if}