mirror of
https://github.com/dbgate/dbgate
synced 2024-11-07 20:26:23 +00:00
editor data refactor - setEditorData can be called with function
This commit is contained in:
parent
ab0a551d67
commit
0747614e00
@ -8,6 +8,13 @@ import DesignerReference from './DesignerReference';
|
||||
const Wrapper = styled.div`
|
||||
flex: 1;
|
||||
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 }) {
|
||||
@ -37,144 +44,154 @@ export default function Designer({ value, onChange }) {
|
||||
|
||||
const changeTable = React.useCallback(
|
||||
(table) => {
|
||||
const newValue = {
|
||||
...value,
|
||||
tables: (value.tables || []).map((x) => (x.designerId == table.designerId ? table : x)),
|
||||
};
|
||||
onChange(newValue);
|
||||
onChange((current) => ({
|
||||
...current,
|
||||
tables: (current.tables || []).map((x) => (x.designerId == table.designerId ? table : x)),
|
||||
}));
|
||||
},
|
||||
[onChange, value]
|
||||
[onChange]
|
||||
);
|
||||
|
||||
const bringToFront = React.useCallback(
|
||||
(table) => {
|
||||
const newValue = {
|
||||
...value,
|
||||
tables: [...(value.tables || []).filter((x) => x.designerId != table.designerId), table],
|
||||
};
|
||||
|
||||
onChange(newValue);
|
||||
onChange((current) => ({
|
||||
...current,
|
||||
tables: [...(current.tables || []).filter((x) => x.designerId != table.designerId), table],
|
||||
}));
|
||||
},
|
||||
[onChange, value]
|
||||
[onChange]
|
||||
);
|
||||
|
||||
const removeTable = React.useCallback(
|
||||
(table) => {
|
||||
const newValue = {
|
||||
...value,
|
||||
tables: (value.tables || []).filter((x) => x.designerId != table.designerId),
|
||||
};
|
||||
|
||||
onChange(newValue);
|
||||
onChange((current) => ({
|
||||
...current,
|
||||
tables: (current.tables || []).filter((x) => x.designerId != table.designerId),
|
||||
}));
|
||||
},
|
||||
[onChange, value]
|
||||
[onChange]
|
||||
);
|
||||
|
||||
const changeReference = React.useCallback(
|
||||
(ref) => {
|
||||
const newValue = {
|
||||
...value,
|
||||
references: (value.references || []).map((x) => (x.designerId == ref.designerId ? ref : x)),
|
||||
};
|
||||
onChange(newValue);
|
||||
onChange((current) => ({
|
||||
...current,
|
||||
references: (current.references || []).map((x) => (x.designerId == ref.designerId ? ref : x)),
|
||||
}));
|
||||
},
|
||||
[onChange, value]
|
||||
[onChange]
|
||||
);
|
||||
|
||||
const removeReference = React.useCallback(
|
||||
(ref) => {
|
||||
const newValue = {
|
||||
...value,
|
||||
references: (value.references || []).filter((x) => x.designerId != ref.designerId),
|
||||
};
|
||||
|
||||
onChange(newValue);
|
||||
onChange((current) => ({
|
||||
...current,
|
||||
references: (current.references || []).filter((x) => x.designerId != ref.designerId),
|
||||
}));
|
||||
},
|
||||
[onChange, value]
|
||||
[onChange]
|
||||
);
|
||||
|
||||
const handleCreateReference = (source, target) => {
|
||||
const existingReference = (value.references || []).find(
|
||||
(x) =>
|
||||
(x.sourceId == source.designerId && x.targetId == target.designerId) ||
|
||||
(x.sourceId == target.designerId && x.targetId == source.designerId)
|
||||
);
|
||||
const newValue = {
|
||||
...value,
|
||||
references: existingReference
|
||||
? value.references.map((ref) =>
|
||||
ref == existingReference
|
||||
? {
|
||||
...existingReference,
|
||||
columns: [
|
||||
...existingReference.columns,
|
||||
existingReference.sourceId == source.designerId
|
||||
? {
|
||||
source: source.columnName,
|
||||
target: target.columnName,
|
||||
}
|
||||
: {
|
||||
source: target.columnName,
|
||||
target: source.columnName,
|
||||
},
|
||||
],
|
||||
}
|
||||
: ref
|
||||
)
|
||||
: [
|
||||
...(value.references || []),
|
||||
{
|
||||
designerId: uuidv1(),
|
||||
sourceId: source.designerId,
|
||||
targetId: target.designerId,
|
||||
columns: [
|
||||
{
|
||||
source: source.columnName,
|
||||
target: target.columnName,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
onChange((current) => {
|
||||
const existingReference = (current.references || []).find(
|
||||
(x) =>
|
||||
(x.sourceId == source.designerId && x.targetId == target.designerId) ||
|
||||
(x.sourceId == target.designerId && x.targetId == source.designerId)
|
||||
);
|
||||
|
||||
onChange(newValue);
|
||||
return {
|
||||
...current,
|
||||
references: existingReference
|
||||
? current.references.map((ref) =>
|
||||
ref == existingReference
|
||||
? {
|
||||
...existingReference,
|
||||
columns: [
|
||||
...existingReference.columns,
|
||||
existingReference.sourceId == source.designerId
|
||||
? {
|
||||
source: source.columnName,
|
||||
target: target.columnName,
|
||||
}
|
||||
: {
|
||||
source: target.columnName,
|
||||
target: source.columnName,
|
||||
},
|
||||
],
|
||||
}
|
||||
: ref
|
||||
)
|
||||
: [
|
||||
...(current.references || []),
|
||||
{
|
||||
designerId: uuidv1(),
|
||||
sourceId: source.designerId,
|
||||
targetId: target.designerId,
|
||||
columns: [
|
||||
{
|
||||
source: source.columnName,
|
||||
target: target.columnName,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
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(() => {
|
||||
// setTimeout(() => setChangeToken((x) => x + 1), 100);
|
||||
// }, [value]);
|
||||
|
||||
return (
|
||||
<Wrapper onDragOver={(e) => e.preventDefault()} onDrop={handleDrop} theme={theme} ref={wrapperRef}>
|
||||
{(references || []).map((ref) => (
|
||||
<DesignerReference
|
||||
key={ref.designerId}
|
||||
changeToken={changeToken}
|
||||
domTablesRef={domTablesRef}
|
||||
reference={ref}
|
||||
onChangeReference={changeReference}
|
||||
onRemoveReference={removeReference}
|
||||
/>
|
||||
))}
|
||||
{(tables || []).map((table) => (
|
||||
<DesignerTable
|
||||
key={table.designerId}
|
||||
sourceDragColumn={sourceDragColumn}
|
||||
setSourceDragColumn={setSourceDragColumn}
|
||||
targetDragColumn={targetDragColumn}
|
||||
setTargetDragColumn={setTargetDragColumn}
|
||||
onCreateReference={handleCreateReference}
|
||||
table={table}
|
||||
onChangeTable={changeTable}
|
||||
onBringToFront={bringToFront}
|
||||
onRemoveTable={removeTable}
|
||||
setChangeToken={setChangeToken}
|
||||
wrapperRef={wrapperRef}
|
||||
onChangeDomTable={(table) => {
|
||||
domTablesRef.current[table.designerId] = table;
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
<Wrapper theme={theme}>
|
||||
<Canvas onDragOver={(e) => e.preventDefault()} onDrop={handleDrop} ref={wrapperRef}>
|
||||
{(references || []).map((ref) => (
|
||||
<DesignerReference
|
||||
key={ref.designerId}
|
||||
changeToken={changeToken}
|
||||
domTablesRef={domTablesRef}
|
||||
reference={ref}
|
||||
onChangeReference={changeReference}
|
||||
onRemoveReference={removeReference}
|
||||
/>
|
||||
))}
|
||||
{(tables || []).map((table) => (
|
||||
<DesignerTable
|
||||
key={table.designerId}
|
||||
sourceDragColumn={sourceDragColumn}
|
||||
setSourceDragColumn={setSourceDragColumn}
|
||||
targetDragColumn={targetDragColumn}
|
||||
setTargetDragColumn={setTargetDragColumn}
|
||||
onCreateReference={handleCreateReference}
|
||||
onSelectColumn={handleSelectColumn}
|
||||
table={table}
|
||||
onChangeTable={changeTable}
|
||||
onBringToFront={bringToFront}
|
||||
onRemoveTable={removeTable}
|
||||
setChangeToken={setChangeToken}
|
||||
wrapperRef={wrapperRef}
|
||||
onChangeDomTable={(table) => {
|
||||
domTablesRef.current[table.designerId] = table;
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</Canvas>
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import ColumnLabel from '../datagrid/ColumnLabel';
|
||||
import { FontIcon } from '../icons';
|
||||
import useTheme from '../theme/useTheme';
|
||||
import DomTableRef from './DomTableRef';
|
||||
import _ from 'lodash'
|
||||
import _ from 'lodash';
|
||||
|
||||
const Wrapper = styled.div`
|
||||
position: absolute;
|
||||
@ -85,6 +85,7 @@ export default function DesignerTable({
|
||||
onBringToFront,
|
||||
onRemoveTable,
|
||||
onCreateReference,
|
||||
onSelectColumn,
|
||||
sourceDragColumn,
|
||||
setSourceDragColumn,
|
||||
targetDragColumn,
|
||||
@ -241,6 +242,12 @@ export default function DesignerTable({
|
||||
setTargetDragColumn(null);
|
||||
setSourceDragColumn(null);
|
||||
}}
|
||||
onMouseDown={(e) =>
|
||||
onSelectColumn({
|
||||
...column,
|
||||
designerId,
|
||||
})
|
||||
}
|
||||
>
|
||||
<ColumnLabel {...column} forceIcon />
|
||||
</ColumnLine>
|
||||
|
56
packages/web/src/designer/QueryDesignColumns.js
Normal file
56
packages/web/src/designer/QueryDesignColumns.js
Normal 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>
|
||||
);
|
||||
}
|
@ -22,6 +22,7 @@ import applySqlTemplate from '../utility/applySqlTemplate';
|
||||
import LoadingInfo from '../widgets/LoadingInfo';
|
||||
import useExtensions from '../utility/useExtensions';
|
||||
import QueryDesigner from '../designer/QueryDesigner';
|
||||
import QueryDesignColumns from '../designer/QueryDesignColumns';
|
||||
|
||||
export default function QueryDesignTab({
|
||||
tabid,
|
||||
@ -121,25 +122,26 @@ export default function QueryDesignTab({
|
||||
|
||||
return (
|
||||
<>
|
||||
<VerticalSplitter>
|
||||
<VerticalSplitter initialValue="70%">
|
||||
<QueryDesigner
|
||||
value={editorData || ''}
|
||||
value={editorData || {}}
|
||||
conid={conid}
|
||||
database={database}
|
||||
engine={connection && connection.engine}
|
||||
onChange={setEditorData}
|
||||
onKeyDown={handleKeyDown}
|
||||
></QueryDesigner>
|
||||
{sessionId && (
|
||||
<ResultTabs sessionId={sessionId} executeNumber={executeNumber}>
|
||||
<TabPage label="Messages" key="messages">
|
||||
<SocketMessagesView
|
||||
eventName={sessionId ? `session-info-${sessionId}` : null}
|
||||
executeNumber={executeNumber}
|
||||
/>
|
||||
</TabPage>
|
||||
</ResultTabs>
|
||||
)}
|
||||
<ResultTabs sessionId={sessionId} executeNumber={executeNumber}>
|
||||
<TabPage label="Columns" key="columns">
|
||||
<QueryDesignColumns value={editorData || {}} onChange={setEditorData} />
|
||||
</TabPage>
|
||||
<TabPage label="Messages" key="messages">
|
||||
<SocketMessagesView
|
||||
eventName={sessionId ? `session-info-${sessionId}` : null}
|
||||
executeNumber={executeNumber}
|
||||
/>
|
||||
</TabPage>
|
||||
</ResultTabs>
|
||||
</VerticalSplitter>
|
||||
{/* {toolbarPortalRef &&
|
||||
toolbarPortalRef.current &&
|
||||
|
@ -94,8 +94,12 @@ export default function useEditorData({ tabid, reloadToken = 0, loadFromArgs = n
|
||||
const saveToStorageDebounced = React.useMemo(() => _.debounce(saveToStorage, 5000), [saveToStorage]);
|
||||
|
||||
const handleChange = (newValue) => {
|
||||
if (newValue != null) valueRef.current = newValue;
|
||||
setValue(newValue);
|
||||
if (_.isFunction(newValue)) {
|
||||
valueRef.current = newValue(valueRef.current);
|
||||
} else {
|
||||
if (newValue != null) valueRef.current = newValue;
|
||||
}
|
||||
setValue(valueRef.current);
|
||||
changeCounterRef.current += 1;
|
||||
saveToStorageDebounced();
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user