mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-20 21:46:00 +00:00
editing in form view
This commit is contained in:
93
packages/web/src/formview/ChangeSetFormer.ts
Normal file
93
packages/web/src/formview/ChangeSetFormer.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import _ from 'lodash';
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
@@ -48,7 +50,6 @@ const TableHeaderCell = styled.td`
|
||||
position: relative;
|
||||
|
||||
${(props) =>
|
||||
// @ts-ignore
|
||||
props.isSelected &&
|
||||
`
|
||||
background: initial;
|
||||
@@ -66,12 +67,17 @@ const TableBodyCell = styled.td`
|
||||
overflow: hidden;
|
||||
|
||||
${(props) =>
|
||||
// @ts-ignore
|
||||
props.isSelected &&
|
||||
`
|
||||
background: initial;
|
||||
background-color: ${props.theme.gridbody_selection[4]};
|
||||
color: ${props.theme.gridbody_invfont1};`}
|
||||
|
||||
${(props) =>
|
||||
!props.isSelected &&
|
||||
props.isModifiedCell &&
|
||||
`
|
||||
background-color: ${props.theme.gridbody_background_orange[1]};`}
|
||||
`;
|
||||
|
||||
const FocusField = styled.input`
|
||||
@@ -86,7 +92,7 @@ function isDataCell(cell) {
|
||||
}
|
||||
|
||||
export default function FormView(props) {
|
||||
const { rowData, toolbarPortalRef, tabVisible, config, setConfig, onNavigate } = props;
|
||||
const { toolbarPortalRef, tabVisible, config, setConfig, onNavigate, former } = props;
|
||||
/** @type {import('dbgate-datalib').FormViewDisplay} */
|
||||
const formDisplay = props.formDisplay;
|
||||
const theme = useTheme();
|
||||
@@ -100,6 +106,8 @@ export default function FormView(props) {
|
||||
const rowCount = Math.floor((wrapperHeight - 20) / rowHeight);
|
||||
const columnChunks = _.chunk(formDisplay.columns, rowCount);
|
||||
|
||||
const { rowData, rowStatus } = former;
|
||||
|
||||
const handleSwitchToTable = () => {
|
||||
setConfig((cfg) => ({
|
||||
...cfg,
|
||||
@@ -318,6 +326,7 @@ export default function FormView(props) {
|
||||
data-col={chunkIndex * 2 + 1}
|
||||
// @ts-ignore
|
||||
isSelected={currentCell[0] == rowIndex && currentCell[1] == chunkIndex * 2 + 1}
|
||||
isModifiedCell={rowStatus.modifiedFields && rowStatus.modifiedFields.has(col.uniqueName)}
|
||||
ref={(element) => setCellRef(rowIndex, chunkIndex * 2 + 1, element)}
|
||||
>
|
||||
{inplaceEditorState.cell &&
|
||||
@@ -328,7 +337,9 @@ export default function FormView(props) {
|
||||
inplaceEditorState={inplaceEditorState}
|
||||
dispatchInsplaceEditor={dispatchInsplaceEditor}
|
||||
cellValue={rowData[col.uniqueName]}
|
||||
onSetValue={(value) => {}}
|
||||
onSetValue={(value) => {
|
||||
former.setCellValue(col.uniqueName, value);
|
||||
}}
|
||||
// grider={grider}
|
||||
// rowIndex={rowIndex}
|
||||
// uniqueName={col.uniqueName}
|
||||
|
||||
53
packages/web/src/formview/Former.ts
Normal file
53
packages/web/src/formview/Former.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
// export interface GriderRowStatus {
|
||||
// status: 'regular' | 'updated' | 'deleted' | 'inserted';
|
||||
// modifiedFields?: Set<string>;
|
||||
// insertedFields?: Set<string>;
|
||||
// deletedFields?: Set<string>;
|
||||
// }
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import { useConnectionInfo, useDatabaseInfo } from '../utility/metadataLoaders';
|
||||
import useExtensions from '../utility/useExtensions';
|
||||
import FormView from './FormView';
|
||||
import axios from '../utility/axios';
|
||||
import ChangeSetFormer from './ChangeSetFormer';
|
||||
|
||||
async function loadRow(props, sql) {
|
||||
const { conid, database } = props;
|
||||
@@ -26,7 +27,7 @@ async function loadRow(props, sql) {
|
||||
}
|
||||
|
||||
export default function SqlFormView(props) {
|
||||
const { formDisplay } = props;
|
||||
const { formDisplay, changeSetState, dispatchChangeSet } = props;
|
||||
const [rowData, setRowData] = React.useState(null);
|
||||
|
||||
const handleLoadCurrentRow = async () => {
|
||||
@@ -46,7 +47,14 @@ export default function SqlFormView(props) {
|
||||
if (formDisplay && !formDisplay.isLoadedCurrentRow(rowData)) {
|
||||
handleLoadCurrentRow();
|
||||
}
|
||||
}, [formDisplay]);
|
||||
}, [formDisplay, rowData]);
|
||||
|
||||
const former = React.useMemo(() => new ChangeSetFormer(rowData, changeSetState, dispatchChangeSet, formDisplay), [
|
||||
rowData,
|
||||
changeSetState,
|
||||
dispatchChangeSet,
|
||||
formDisplay,
|
||||
]);
|
||||
|
||||
// const { config, setConfig, cache, setCache, schemaName, pureName, conid, database } = props;
|
||||
// const { formViewKey } = config;
|
||||
@@ -76,5 +84,5 @@ export default function SqlFormView(props) {
|
||||
// setDisplay(newDisplay);
|
||||
// }, [config, cache, conid, database, schemaName, pureName, dbinfo, extensions]);
|
||||
|
||||
return <FormView {...props} rowData={rowData} onNavigate={handleNavigate} />;
|
||||
return <FormView {...props} rowData={rowData} onNavigate={handleNavigate} former={former} />;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user