diff --git a/packages/datalib/src/runMacro.ts b/packages/datalib/src/runMacro.ts index 8185c4a4..4c0f17d3 100644 --- a/packages/datalib/src/runMacro.ts +++ b/packages/datalib/src/runMacro.ts @@ -27,24 +27,30 @@ export function runMacro( const rows = data.rows.map((row, rowIndex) => { const selectedRow = selectedRows[rowIndex]; if (selectedRow) { - const columnSet = new Set(selectedRow.map((item) => item.column)); const changedValues = []; - const res = _.mapValues(row, (value, key) => { - if (columnSet.has(key)) { - const newValue = func(value, macroArgs, modules, rowIndex, row, key); - if (preview && newValue != value) changedValues.push(key); - return newValue; - } else { - return value; + let res = null; + for (const cell of selectedRow) { + const { column } = cell; + const oldValue = row[column]; + const newValue = func(oldValue, macroArgs, modules, rowIndex, row, column); + if (newValue != oldValue) { + if (res == null) { + res = { ...row }; + } + res[column] = newValue; + if (preview) changedValues.push(column); } - }); - if (changedValues.length > 0) { - return { - ...res, - __changedValues: new Set(changedValues), - }; } - return res; + if (res) { + if (changedValues.length > 0) { + return { + ...res, + __changedValues: new Set(changedValues), + }; + } + return res; + } + return row; } else { return row; } diff --git a/packages/web/src/freetable/FreeTableGrid.js b/packages/web/src/freetable/FreeTableGrid.js index d9766962..5f4161c0 100644 --- a/packages/web/src/freetable/FreeTableGrid.js +++ b/packages/web/src/freetable/FreeTableGrid.js @@ -1,3 +1,4 @@ +import { runMacro } from '@dbgate/datalib'; import React from 'react'; import styled from 'styled-components'; @@ -20,9 +21,16 @@ const DataGridContainer = styled.div` `; export default function FreeTableGrid(props) { + const { modelState, dispatchModel } = props; const [managerSize, setManagerSize] = React.useState(0); const [selectedMacro, setSelectedMacro] = React.useState(null); const [macroValues, setMacroValues] = React.useState({}); + const [selectedCells, setSelectedCells] = React.useState([]); + const handleExecuteMacro = () => { + const newModel = runMacro(selectedMacro, macroValues, modelState.value, false, selectedCells); + dispatchModel({ type: 'set', value: newModel }); + setSelectedMacro(null); + }; return ( @@ -43,13 +51,19 @@ export default function FreeTableGrid(props) { - + {!!selectedMacro && ( )} diff --git a/packages/web/src/freetable/FreeTableGridCore.js b/packages/web/src/freetable/FreeTableGridCore.js index f203894c..ac96cece 100644 --- a/packages/web/src/freetable/FreeTableGridCore.js +++ b/packages/web/src/freetable/FreeTableGridCore.js @@ -5,7 +5,7 @@ import FreeTableGrider from './FreeTableGrider'; import MacroPreviewGrider from './MacroPreviewGrider'; export default function FreeTableGridCore(props) { - const { modelState, dispatchModel, config, setConfig, macroPreview, macroValues } = props; + const { modelState, dispatchModel, config, setConfig, macroPreview, macroValues, onSelectionChanged } = props; const [cache, setCache] = React.useState(createGridCache()); const [selectedCells, setSelectedCells] = React.useState([]); const grider = React.useMemo( @@ -26,12 +26,20 @@ export default function FreeTableGridCore(props) { cache, ]); + const handleSelectionChanged = React.useCallback( + (cells) => { + if (onSelectionChanged) onSelectionChanged(cells); + setSelectedCells(cells); + }, + [setSelectedCells] + ); + return ( ); } diff --git a/packages/web/src/freetable/MacroDetail.js b/packages/web/src/freetable/MacroDetail.js index 002f6e7d..806dee26 100644 --- a/packages/web/src/freetable/MacroDetail.js +++ b/packages/web/src/freetable/MacroDetail.js @@ -6,6 +6,9 @@ import { TabPage, TabControl } from '../widgets/TabControl'; import theme from '../theme'; import JavaScriptEditor from '../sqleditor/JavaScriptEditor'; import MacroParameters from './MacroParameters'; +import { WidgetTitle } from '../widgets/WidgetStyles'; +import { FormButton } from '../utility/forms'; +import FormStyledButton from '../widgets/FormStyledButton'; const Container = styled.div` display: flex; @@ -39,27 +42,70 @@ const MacroDetailContainer = styled.div` bottom: 0; `; -function MacroHeader({ selectedMacro, setSelectedMacro }) { +const MacroDetailTabWrapper = styled.div` + display: flex; +`; + +const MacroSection = styled.div` + margin: 5px; +`; + +const TextWrapper = styled.div` + margin: 5px; +`; + +const Buttons = styled.div` + display: flex; +`; + +function MacroHeader({ selectedMacro, setSelectedMacro, onExecute }) { return (
{selectedMacro.title}
- setSelectedMacro(null)} patchY={6}> - Close - + + + Execute + + setSelectedMacro(null)} patchY={6}> + Close + +
); } -export default function MacroDetail({ selectedMacro, setSelectedMacro, onChangeValues, macroValues }) { +export default function MacroDetail({ selectedMacro, setSelectedMacro, onChangeValues, macroValues, onExecute }) { return ( - + - - + + + + Execute + + + + + Parameters + {selectedMacro.args && selectedMacro.args.length > 0 ? ( + + ) : ( + This macro has no parameters + )} + + + Description + {selectedMacro.description} + + diff --git a/packages/web/src/freetable/macros.js b/packages/web/src/freetable/macros.js index 68ee5474..de7d2678 100644 --- a/packages/web/src/freetable/macros.js +++ b/packages/web/src/freetable/macros.js @@ -47,7 +47,7 @@ const macros = [ title: 'Row index', name: 'rowIndex', group: 'Tools', - description: 'index of row from 1 (autoincrement)', + description: 'Index of row from 1 (autoincrement)', type: 'transformValue', code: `return rowIndex + 1`, },