diff --git a/packages/web/src/datagrid/DataGrid.svelte b/packages/web/src/datagrid/DataGrid.svelte
index 8b34add6f..1df5d3790 100644
--- a/packages/web/src/datagrid/DataGrid.svelte
+++ b/packages/web/src/datagrid/DataGrid.svelte
@@ -7,11 +7,15 @@
export let config;
export let gridCoreComponent;
+ export let formViewComponent;
+ export let formDisplay;
export let isDetailView = false;
export let showReferences = false;
let managerSize;
+
+ $: isFormView = !!(formDisplay && formDisplay.config && formDisplay.config.isFormView);
@@ -33,7 +37,15 @@
-
+ {#if isFormView}
+
+ {:else}
+
+ {/if}
diff --git a/packages/web/src/datagrid/DataGridCell.svelte b/packages/web/src/datagrid/DataGridCell.svelte
index 28334752e..222f87973 100644
--- a/packages/web/src/datagrid/DataGridCell.svelte
+++ b/packages/web/src/datagrid/DataGridCell.svelte
@@ -23,6 +23,7 @@
export let rowIndex;
export let col;
export let rowData;
+ export let colIndex = undefined;
export let hintFieldsAllowed = undefined;
export let isSelected = false;
@@ -39,7 +40,7 @@
getCurrentDataGrid().exportGrid(),
});
+ registerCommand({
+ id: 'dataGrid.switchToForm',
+ category: 'Data grid',
+ name: 'Switch to form',
+ keyText: 'F4',
+ testEnabled: () => getCurrentDataGrid()?.formViewEnabled(),
+ onClick: () => getCurrentDataGrid().switchToForm(),
+ });
+
function getRowCountInfo(selectedCells, grider, realColumnUniqueNames, selectedRowData, allRowCount) {
if (selectedCells.length > 1 && selectedCells.every(x => _.isNumber(x[0]) && _.isNumber(x[1]))) {
let sum = _.sumBy(selectedCells, cell => {
@@ -193,6 +202,7 @@
export let onSave;
export let focusOnVisible = false;
export let onExportGrid = null;
+ export let formViewAvailable = false;
export let isLoadedAll;
export let loadedTime;
@@ -329,6 +339,16 @@
}
}
+ export function formViewEnabled() {
+ return formViewAvailable && display.baseTable && display.baseTable.primaryKey;
+ }
+
+ export function switchToForm() {
+ const cell = currentCell;
+ const rowData = isRegularCell(cell) ? grider.getRowData(cell[0]) : null;
+ display.switchToFormView(rowData);
+ }
+
// export function getGeneralAllowSave() {
// return generalAllowSave;
// }
@@ -869,6 +889,7 @@
{ command: 'dataGrid.refresh' },
{ command: 'dataGrid.copyToClipboard' },
{ command: 'dataGrid.export' },
+ { command: 'dataGrid.switchToForm' },
{ divider: true },
{ command: 'dataGrid.save' },
{ command: 'dataGrid.revertRowChanges' },
diff --git a/packages/web/src/datagrid/TableDataGrid.svelte b/packages/web/src/datagrid/TableDataGrid.svelte
index 6b4db07c4..d36db7df3 100644
--- a/packages/web/src/datagrid/TableDataGrid.svelte
+++ b/packages/web/src/datagrid/TableDataGrid.svelte
@@ -13,6 +13,7 @@
import DataGrid from './DataGrid.svelte';
import ReferenceHeader from './ReferenceHeader.svelte';
import SqlDataGridCore from './SqlDataGridCore.svelte';
+ import SqlFormView from '../formview/SqlFormView.svelte';
export let conid;
export let database;
@@ -44,16 +45,19 @@
setCache,
$dbinfo
)
- : // ? new TableFormViewDisplay(
- // { schemaName, pureName },
- // findEngineDriver(connection, $extensions),
- // $config,
- // config.update,
- // $cache,
- // cache.update,
- // $dbinfo
- // )
- null;
+ : null;
+
+ $: formDisplay = connection
+ ? new TableFormViewDisplay(
+ { schemaName, pureName },
+ findEngineDriver($connection, $extensions),
+ config,
+ setConfig,
+ cache,
+ setCache,
+ $dbinfo
+ )
+ : null;
const setChildConfig = (value, reference = undefined) => {
if (_.isFunction(value)) {
@@ -111,7 +115,9 @@
{
diff --git a/packages/web/src/formview/ChangeSetFormer.ts b/packages/web/src/formview/ChangeSetFormer.ts
new file mode 100644
index 000000000..e9f645d13
--- /dev/null
+++ b/packages/web/src/formview/ChangeSetFormer.ts
@@ -0,0 +1,94 @@
+import {
+ ChangeSet,
+ changeSetContainsChanges,
+ changeSetInsertNewRow,
+ createChangeSet,
+ deleteChangeSetRows,
+ findExistingChangeSetItem,
+ getChangeSetInsertedRows,
+ TableFormViewDisplay,
+ revertChangeSetRowChanges,
+ setChangeSetValue,
+ ChangeSetRowDefinition,
+} from 'dbgate-datalib';
+import Former from './Former';
+
+export default class ChangeSetFormer extends Former {
+ public changeSet: ChangeSet;
+ public setChangeSet: Function;
+ private batchChangeSet: ChangeSet;
+ public rowDefinition: ChangeSetRowDefinition;
+ public rowStatus;
+ public rowData: {};
+
+ constructor(
+ public sourceRow: any,
+ public changeSetState,
+ public dispatchChangeSet,
+ public display: TableFormViewDisplay
+ ) {
+ super();
+ this.changeSet = changeSetState && changeSetState.value;
+ this.setChangeSet = value => dispatchChangeSet({ type: 'set', value });
+ this.batchChangeSet = null;
+ this.rowDefinition = display.getChangeSetRow(sourceRow);
+ const [matchedField, matchedChangeSetItem] = findExistingChangeSetItem(this.changeSet, this.rowDefinition);
+ this.rowData = matchedChangeSetItem ? { ...sourceRow, ...matchedChangeSetItem.fields } : sourceRow;
+ let status = 'regular';
+ if (matchedChangeSetItem && matchedField == 'updates') status = 'updated';
+ if (matchedField == 'deletes') status = 'deleted';
+ this.rowStatus = {
+ status,
+ modifiedFields:
+ matchedChangeSetItem && matchedChangeSetItem.fields ? new Set(Object.keys(matchedChangeSetItem.fields)) : null,
+ };
+ }
+
+ applyModification(changeSetReducer) {
+ if (this.batchChangeSet) {
+ this.batchChangeSet = changeSetReducer(this.batchChangeSet);
+ } else {
+ this.setChangeSet(changeSetReducer(this.changeSet));
+ }
+ }
+
+ setCellValue(uniqueName: string, value: any) {
+ const row = this.sourceRow;
+ const definition = this.display.getChangeSetField(row, uniqueName);
+ this.applyModification(chs => setChangeSetValue(chs, definition, value));
+ }
+
+ deleteRow(index: number) {
+ this.applyModification(chs => deleteChangeSetRows(chs, this.rowDefinition));
+ }
+
+ beginUpdate() {
+ this.batchChangeSet = this.changeSet;
+ }
+ endUpdate() {
+ this.setChangeSet(this.batchChangeSet);
+ this.batchChangeSet = null;
+ }
+
+ revertRowChanges() {
+ this.applyModification(chs => revertChangeSetRowChanges(chs, this.rowDefinition));
+ }
+ revertAllChanges() {
+ this.applyModification(chs => createChangeSet());
+ }
+ undo() {
+ this.dispatchChangeSet({ type: 'undo' });
+ }
+ redo() {
+ this.dispatchChangeSet({ type: 'redo' });
+ }
+ get canUndo() {
+ return this.changeSetState.canUndo;
+ }
+ get canRedo() {
+ return this.changeSetState.canRedo;
+ }
+ get containsChanges() {
+ return changeSetContainsChanges(this.changeSet);
+ }
+}
diff --git a/packages/web/src/formview/FormView.svelte b/packages/web/src/formview/FormView.svelte
new file mode 100644
index 000000000..83556dfeb
--- /dev/null
+++ b/packages/web/src/formview/FormView.svelte
@@ -0,0 +1,171 @@
+
+
+
+
+
+
+ {#each columnChunks as chunk, chunkIndex}
+
+ {#each chunk as col, rowIndex}
+
+ {#if chunkIndex == 0 && rowIndex == 0}
+
+ {:else}
+
+ {/if}
+
+
+ {/each}
+
+ {/each}
+ {
+ lastFocusedFormView = instance;
+ invalidateCommands();
+ }}
+ />
+
+
+
+
diff --git a/packages/web/src/formview/Former.ts b/packages/web/src/formview/Former.ts
new file mode 100644
index 000000000..cbd1508d2
--- /dev/null
+++ b/packages/web/src/formview/Former.ts
@@ -0,0 +1,53 @@
+// export interface GriderRowStatus {
+// status: 'regular' | 'updated' | 'deleted' | 'inserted';
+// modifiedFields?: Set;
+// insertedFields?: Set;
+// deletedFields?: Set;
+// }
+
+export default abstract class Former {
+ public rowData: any;
+
+ // getRowStatus(index): GriderRowStatus {
+ // const res: GriderRowStatus = {
+ // status: 'regular',
+ // };
+ // return res;
+ // }
+ beginUpdate() {}
+ endUpdate() {}
+ setCellValue(uniqueName: string, value: any) {}
+ revertRowChanges() {}
+ revertAllChanges() {}
+ undo() {}
+ redo() {}
+ get editable() {
+ return false;
+ }
+ get canInsert() {
+ return false;
+ }
+ get allowSave() {
+ return this.containsChanges;
+ }
+ get canUndo() {
+ return false;
+ }
+ get canRedo() {
+ return false;
+ }
+ get containsChanges() {
+ return false;
+ }
+ get disableLoadNextPage() {
+ return false;
+ }
+ get errors() {
+ return null;
+ }
+ updateRow(changeObject) {
+ for (const key of Object.keys(changeObject)) {
+ this.setCellValue(key, changeObject[key]);
+ }
+ }
+}
diff --git a/packages/web/src/formview/SqlFormView.svelte b/packages/web/src/formview/SqlFormView.svelte
new file mode 100644
index 000000000..a92df581f
--- /dev/null
+++ b/packages/web/src/formview/SqlFormView.svelte
@@ -0,0 +1,109 @@
+
+
+
+
+
diff --git a/packages/web/src/formview/openReferenceForm.ts b/packages/web/src/formview/openReferenceForm.ts
new file mode 100644
index 000000000..370ba66f5
--- /dev/null
+++ b/packages/web/src/formview/openReferenceForm.ts
@@ -0,0 +1,31 @@
+import _ from 'lodash';
+import openNewTab from '../utility/openNewTab';
+
+export default function openReferenceForm(rowData, column, conid, database) {
+ const formViewKey = _.fromPairs(
+ column.foreignKey.columns.map(({ refColumnName, columnName }) => [refColumnName, rowData[columnName]])
+ );
+ openNewTab(
+ {
+ title: column.foreignKey.refTableName,
+ icon: 'img table',
+ tabComponent: 'TableDataTab',
+ props: {
+ schemaName: column.foreignKey.refSchemaName,
+ pureName: column.foreignKey.refTableName,
+ conid,
+ database,
+ objectTypeField: 'tables',
+ },
+ },
+ {
+ grid: {
+ isFormView: true,
+ formViewKey,
+ },
+ },
+ {
+ forceNewTab: true,
+ }
+ );
+}
diff --git a/packages/web/src/tabs/MarkdownEditorTab.svelte b/packages/web/src/tabs/MarkdownEditorTab.svelte
index c2cf8e807..c33877ed4 100644
--- a/packages/web/src/tabs/MarkdownEditorTab.svelte
+++ b/packages/web/src/tabs/MarkdownEditorTab.svelte
@@ -35,8 +35,10 @@
import AceEditor from '../query/AceEditor.svelte';
import useEditorData from '../query/useEditorData';
- import { getActiveTabId } from '../stores';
+ import { getActiveTabId, openedTabs } from '../stores';
import invalidateCommands from '../commands/invalidateCommands';
+ import openNewTab from '../utility/openNewTab';
+ import { setSelectedTab } from '../utility/common';
export let tabid;
@@ -70,7 +72,25 @@
return tabid;
}
- const { editorState, editorValue, setEditorData } = useEditorData({ tabid });
+ export async function preview() {
+ await saveToStorage();
+ const existing = ($openedTabs || []).find(x => x.props && x.props.sourceTabId == tabid && x.closedTime == null);
+ if (existing) {
+ setSelectedTab(existing.tabid);
+ } else {
+ const thisTab = ($openedTabs || []).find(x => x.tabid == tabid);
+ openNewTab({
+ title: thisTab.title,
+ icon: 'img preview',
+ tabComponent: 'MarkdownPreviewTab',
+ props: {
+ sourceTabId: tabid,
+ },
+ });
+ }
+ }
+
+ const { editorState, editorValue, setEditorData, saveToStorage } = useEditorData({ tabid });
function createMenu() {
return [
diff --git a/packages/web/src/tabs/MarkdownPreviewTab.svelte b/packages/web/src/tabs/MarkdownPreviewTab.svelte
new file mode 100644
index 000000000..414ffc072
--- /dev/null
+++ b/packages/web/src/tabs/MarkdownPreviewTab.svelte
@@ -0,0 +1,41 @@
+
+
+{#if $editorState.isLoading}
+
+
+
+{:else}
+
+ {#key data}
+
+ {/key}
+
+{/if}
+
+
diff --git a/packages/web/src/tabs/index.js b/packages/web/src/tabs/index.js
index bdc1e460e..331b70860 100644
--- a/packages/web/src/tabs/index.js
+++ b/packages/web/src/tabs/index.js
@@ -9,7 +9,7 @@ import * as PluginTab from './PluginTab.svelte';
import * as ChartTab from './ChartTab.svelte';
import * as MarkdownEditorTab from './MarkdownEditorTab.svelte';
import * as MarkdownViewTab from './MarkdownViewTab.svelte';
-// import MarkdownPreviewTab from './MarkdownPreviewTab';
+import * as MarkdownPreviewTab from './MarkdownPreviewTab.svelte';
import * as FavoriteEditorTab from './FavoriteEditorTab.svelte';
import * as QueryDesignTab from './QueryDesignTab.svelte';
@@ -25,7 +25,7 @@ export default {
ChartTab,
MarkdownEditorTab,
MarkdownViewTab,
- // MarkdownPreviewTab,
+ MarkdownPreviewTab,
FavoriteEditorTab,
QueryDesignTab,
};
|