editor data refactor - setEditorData can be called with function

This commit is contained in:
Jan Prochazka
2020-12-27 15:38:16 +01:00
parent ab0a551d67
commit 0747614e00
5 changed files with 207 additions and 121 deletions

View File

@@ -8,6 +8,13 @@ import DesignerReference from './DesignerReference';
const Wrapper = styled.div` const Wrapper = styled.div`
flex: 1; flex: 1;
background-color: ${(props) => props.theme.designer_background}; background-color: ${(props) => props.theme.designer_background};
overflow: scroll;
`;
const Canvas = styled.div`
width: 3000px;
height: 3000px;
position: relative;
`; `;
export default function Designer({ value, onChange }) { export default function Designer({ value, onChange }) {
@@ -37,72 +44,66 @@ export default function Designer({ value, onChange }) {
const changeTable = React.useCallback( const changeTable = React.useCallback(
(table) => { (table) => {
const newValue = { onChange((current) => ({
...value, ...current,
tables: (value.tables || []).map((x) => (x.designerId == table.designerId ? table : x)), tables: (current.tables || []).map((x) => (x.designerId == table.designerId ? table : x)),
}; }));
onChange(newValue);
}, },
[onChange, value] [onChange]
); );
const bringToFront = React.useCallback( const bringToFront = React.useCallback(
(table) => { (table) => {
const newValue = { onChange((current) => ({
...value, ...current,
tables: [...(value.tables || []).filter((x) => x.designerId != table.designerId), table], tables: [...(current.tables || []).filter((x) => x.designerId != table.designerId), table],
}; }));
onChange(newValue);
}, },
[onChange, value] [onChange]
); );
const removeTable = React.useCallback( const removeTable = React.useCallback(
(table) => { (table) => {
const newValue = { onChange((current) => ({
...value, ...current,
tables: (value.tables || []).filter((x) => x.designerId != table.designerId), tables: (current.tables || []).filter((x) => x.designerId != table.designerId),
}; }));
onChange(newValue);
}, },
[onChange, value] [onChange]
); );
const changeReference = React.useCallback( const changeReference = React.useCallback(
(ref) => { (ref) => {
const newValue = { onChange((current) => ({
...value, ...current,
references: (value.references || []).map((x) => (x.designerId == ref.designerId ? ref : x)), references: (current.references || []).map((x) => (x.designerId == ref.designerId ? ref : x)),
}; }));
onChange(newValue);
}, },
[onChange, value] [onChange]
); );
const removeReference = React.useCallback( const removeReference = React.useCallback(
(ref) => { (ref) => {
const newValue = { onChange((current) => ({
...value, ...current,
references: (value.references || []).filter((x) => x.designerId != ref.designerId), references: (current.references || []).filter((x) => x.designerId != ref.designerId),
}; }));
onChange(newValue);
}, },
[onChange, value] [onChange]
); );
const handleCreateReference = (source, target) => { const handleCreateReference = (source, target) => {
const existingReference = (value.references || []).find( onChange((current) => {
const existingReference = (current.references || []).find(
(x) => (x) =>
(x.sourceId == source.designerId && x.targetId == target.designerId) || (x.sourceId == source.designerId && x.targetId == target.designerId) ||
(x.sourceId == target.designerId && x.targetId == source.designerId) (x.sourceId == target.designerId && x.targetId == source.designerId)
); );
const newValue = {
...value, return {
...current,
references: existingReference references: existingReference
? value.references.map((ref) => ? current.references.map((ref) =>
ref == existingReference ref == existingReference
? { ? {
...existingReference, ...existingReference,
@@ -122,7 +123,7 @@ export default function Designer({ value, onChange }) {
: ref : ref
) )
: [ : [
...(value.references || []), ...(current.references || []),
{ {
designerId: uuidv1(), designerId: uuidv1(),
sourceId: source.designerId, sourceId: source.designerId,
@@ -136,16 +137,30 @@ export default function Designer({ value, onChange }) {
}, },
], ],
}; };
});
onChange(newValue);
}; };
const handleSelectColumn = React.useCallback(
(column) => {
onChange((current) => ({
...current,
columns: (current.columns || []).find(
(x) => x.designerId == column.designerId && x.columnName == column.columnName
)
? current.columns
: [...(current.columns || []), column],
}));
},
[onChange]
);
// React.useEffect(() => { // React.useEffect(() => {
// setTimeout(() => setChangeToken((x) => x + 1), 100); // setTimeout(() => setChangeToken((x) => x + 1), 100);
// }, [value]); // }, [value]);
return ( return (
<Wrapper onDragOver={(e) => e.preventDefault()} onDrop={handleDrop} theme={theme} ref={wrapperRef}> <Wrapper theme={theme}>
<Canvas onDragOver={(e) => e.preventDefault()} onDrop={handleDrop} ref={wrapperRef}>
{(references || []).map((ref) => ( {(references || []).map((ref) => (
<DesignerReference <DesignerReference
key={ref.designerId} key={ref.designerId}
@@ -164,6 +179,7 @@ export default function Designer({ value, onChange }) {
targetDragColumn={targetDragColumn} targetDragColumn={targetDragColumn}
setTargetDragColumn={setTargetDragColumn} setTargetDragColumn={setTargetDragColumn}
onCreateReference={handleCreateReference} onCreateReference={handleCreateReference}
onSelectColumn={handleSelectColumn}
table={table} table={table}
onChangeTable={changeTable} onChangeTable={changeTable}
onBringToFront={bringToFront} onBringToFront={bringToFront}
@@ -175,6 +191,7 @@ export default function Designer({ value, onChange }) {
}} }}
/> />
))} ))}
</Canvas>
</Wrapper> </Wrapper>
); );
} }

View File

@@ -4,7 +4,7 @@ import ColumnLabel from '../datagrid/ColumnLabel';
import { FontIcon } from '../icons'; import { FontIcon } from '../icons';
import useTheme from '../theme/useTheme'; import useTheme from '../theme/useTheme';
import DomTableRef from './DomTableRef'; import DomTableRef from './DomTableRef';
import _ from 'lodash' import _ from 'lodash';
const Wrapper = styled.div` const Wrapper = styled.div`
position: absolute; position: absolute;
@@ -85,6 +85,7 @@ export default function DesignerTable({
onBringToFront, onBringToFront,
onRemoveTable, onRemoveTable,
onCreateReference, onCreateReference,
onSelectColumn,
sourceDragColumn, sourceDragColumn,
setSourceDragColumn, setSourceDragColumn,
targetDragColumn, targetDragColumn,
@@ -241,6 +242,12 @@ export default function DesignerTable({
setTargetDragColumn(null); setTargetDragColumn(null);
setSourceDragColumn(null); setSourceDragColumn(null);
}} }}
onMouseDown={(e) =>
onSelectColumn({
...column,
designerId,
})
}
> >
<ColumnLabel {...column} forceIcon /> <ColumnLabel {...column} forceIcon />
</ColumnLine> </ColumnLine>

View File

@@ -0,0 +1,56 @@
import React from 'react';
import { CheckboxField } from '../utility/inputs';
import TableControl, { TableColumn } from '../utility/TableControl';
export default function QueryDesignColumns({ value, onChange }) {
const { columns } = value || {};
console.log('QueryDesignColumns', value);
const changeColumn = React.useCallback(
(col) => {
const newValue = {
...value,
columns: (value.columns || []).map((x) =>
x.designerId == col.designerId && x.columnName == col.columnName ? col : x
),
};
onChange(newValue);
},
[onChange, value]
);
return (
<TableControl rows={columns || []}>
<TableColumn fieldName="columnName" header="Column/Expression" />
<TableColumn fieldName="tableDisplayName" header="Table" />
<TableColumn
fieldName="isOutput"
header="Output"
formatter={(row) => (
<CheckboxField
checked={row.isOutput}
onChange={(e) => {
if (e.target.checked) changeColumn({ ...row, isOutput: true });
else changeColumn({ ...row, isOutput: false });
}}
/>
)}
/>
{/* <TableColumn fieldName="queryDesignInfo.alias" editor="textbox" header="Alias" />
<TableColumn fieldName="queryDesignInfo.isGrouped" editor="checkbox" header="Group by" />
<TableColumn
fieldName="queryDesignInfo.aggregate"
editor="combobox"
header="Aggregate"
comboValues={['---', 'MIN', 'MAX', 'COUNT', 'COUNT DISTINCT', 'SUM', 'AVG']}
/>
<TableColumn
fieldName="queryDesignInfo.sortOrder"
header="Sort order"
editor="combobox"
comboValues={sortComboValues}
/>
<TableColumn fieldName="filter" header="Filter" editor="filterbox" getFilterType={this.getFilterType} /> */}
</TableControl>
);
}

View File

@@ -22,6 +22,7 @@ import applySqlTemplate from '../utility/applySqlTemplate';
import LoadingInfo from '../widgets/LoadingInfo'; import LoadingInfo from '../widgets/LoadingInfo';
import useExtensions from '../utility/useExtensions'; import useExtensions from '../utility/useExtensions';
import QueryDesigner from '../designer/QueryDesigner'; import QueryDesigner from '../designer/QueryDesigner';
import QueryDesignColumns from '../designer/QueryDesignColumns';
export default function QueryDesignTab({ export default function QueryDesignTab({
tabid, tabid,
@@ -121,17 +122,19 @@ export default function QueryDesignTab({
return ( return (
<> <>
<VerticalSplitter> <VerticalSplitter initialValue="70%">
<QueryDesigner <QueryDesigner
value={editorData || ''} value={editorData || {}}
conid={conid} conid={conid}
database={database} database={database}
engine={connection && connection.engine} engine={connection && connection.engine}
onChange={setEditorData} onChange={setEditorData}
onKeyDown={handleKeyDown} onKeyDown={handleKeyDown}
></QueryDesigner> ></QueryDesigner>
{sessionId && (
<ResultTabs sessionId={sessionId} executeNumber={executeNumber}> <ResultTabs sessionId={sessionId} executeNumber={executeNumber}>
<TabPage label="Columns" key="columns">
<QueryDesignColumns value={editorData || {}} onChange={setEditorData} />
</TabPage>
<TabPage label="Messages" key="messages"> <TabPage label="Messages" key="messages">
<SocketMessagesView <SocketMessagesView
eventName={sessionId ? `session-info-${sessionId}` : null} eventName={sessionId ? `session-info-${sessionId}` : null}
@@ -139,7 +142,6 @@ export default function QueryDesignTab({
/> />
</TabPage> </TabPage>
</ResultTabs> </ResultTabs>
)}
</VerticalSplitter> </VerticalSplitter>
{/* {toolbarPortalRef && {/* {toolbarPortalRef &&
toolbarPortalRef.current && toolbarPortalRef.current &&

View File

@@ -94,8 +94,12 @@ export default function useEditorData({ tabid, reloadToken = 0, loadFromArgs = n
const saveToStorageDebounced = React.useMemo(() => _.debounce(saveToStorage, 5000), [saveToStorage]); const saveToStorageDebounced = React.useMemo(() => _.debounce(saveToStorage, 5000), [saveToStorage]);
const handleChange = (newValue) => { const handleChange = (newValue) => {
if (_.isFunction(newValue)) {
valueRef.current = newValue(valueRef.current);
} else {
if (newValue != null) valueRef.current = newValue; if (newValue != null) valueRef.current = newValue;
setValue(newValue); }
setValue(valueRef.current);
changeCounterRef.current += 1; changeCounterRef.current += 1;
saveToStorageDebounced(); saveToStorageDebounced();
}; };