running row macros

This commit is contained in:
Jan Prochazka
2023-02-24 19:04:22 +01:00
parent a519c78301
commit 7c4a47c4c6
5 changed files with 280 additions and 324 deletions

View File

@@ -11,7 +11,7 @@ export interface MacroDefinition {
name: string;
group: string;
description?: string;
type: 'transformValue';
type: 'transformValue' | 'transformRow';
code: string;
args?: MacroArgument[];
}

View File

@@ -4,7 +4,7 @@ import uuidv1 from 'uuid/v1';
import uuidv4 from 'uuid/v4';
import moment from 'moment';
import { MacroDefinition, MacroSelectedCell } from './MacroDefinition';
import { ChangeSet, setChangeSetValue } from './ChangeSet';
import { ChangeSet, setChangeSetValue, setChangeSetRowData } from './ChangeSet';
import { GridDisplay } from './GridDisplay';
const getMacroFunction = {
@@ -13,13 +13,8 @@ const getMacroFunction = {
${code}
}
`,
transformRows: code => `
(rows, args, modules, selectedCells, cols, columns) => {
${code}
}
`,
transformData: code => `
(rows, args, modules, selectedCells, cols, columns) => {
transformRow: code => `
(row, args, modules, rowIndex, columns) => {
${code}
}
`,
@@ -32,159 +27,159 @@ const modules = {
moment,
};
function runTramsformValue(
func,
macroArgs: {},
data: FreeTableModel,
preview: boolean,
selectedCells: MacroSelectedCell[],
errors: string[] = []
) {
const selectedRows = _.groupBy(selectedCells, 'row');
const rows = data.rows.map((row, rowIndex) => {
const selectedRow = selectedRows[rowIndex];
if (selectedRow) {
const modifiedFields = [];
let res = null;
for (const cell of selectedRow) {
const { column } = cell;
const oldValue = row[column];
let newValue = oldValue;
try {
newValue = func(oldValue, macroArgs, modules, rowIndex, row, column);
} catch (err) {
errors.push(`Error processing column ${column} on row ${rowIndex}: ${err.message}`);
}
if (newValue != oldValue) {
if (res == null) {
res = { ...row };
}
res[column] = newValue;
if (preview) modifiedFields.push(column);
}
}
if (res) {
if (modifiedFields.length > 0) {
return {
...res,
__modifiedFields: new Set(modifiedFields),
};
}
return res;
}
return row;
} else {
return row;
}
});
// function runTramsformValue(
// func,
// macroArgs: {},
// data: FreeTableModel,
// preview: boolean,
// selectedCells: MacroSelectedCell[],
// errors: string[] = []
// ) {
// const selectedRows = _.groupBy(selectedCells, 'row');
// const rows = data.rows.map((row, rowIndex) => {
// const selectedRow = selectedRows[rowIndex];
// if (selectedRow) {
// const modifiedFields = [];
// let res = null;
// for (const cell of selectedRow) {
// const { column } = cell;
// const oldValue = row[column];
// let newValue = oldValue;
// try {
// newValue = func(oldValue, macroArgs, modules, rowIndex, row, column);
// } catch (err) {
// errors.push(`Error processing column ${column} on row ${rowIndex}: ${err.message}`);
// }
// if (newValue != oldValue) {
// if (res == null) {
// res = { ...row };
// }
// res[column] = newValue;
// if (preview) modifiedFields.push(column);
// }
// }
// if (res) {
// if (modifiedFields.length > 0) {
// return {
// ...res,
// __modifiedFields: new Set(modifiedFields),
// };
// }
// return res;
// }
// return row;
// } else {
// return row;
// }
// });
return {
structure: data.structure,
rows,
};
}
// return {
// structure: data.structure,
// rows,
// };
// }
function removePreviewRowFlags(rows) {
rows = rows.filter(row => row.__rowStatus != 'deleted');
rows = rows.map(row => {
if (row.__rowStatus || row.__modifiedFields || row.__insertedFields || row.__deletedFields)
return _.omit(row, ['__rowStatus', '__modifiedFields', '__insertedFields', '__deletedFields']);
return row;
});
return rows;
}
// function removePreviewRowFlags(rows) {
// rows = rows.filter(row => row.__rowStatus != 'deleted');
// rows = rows.map(row => {
// if (row.__rowStatus || row.__modifiedFields || row.__insertedFields || row.__deletedFields)
// return _.omit(row, ['__rowStatus', '__modifiedFields', '__insertedFields', '__deletedFields']);
// return row;
// });
// return rows;
// }
function runTramsformRows(
func,
macroArgs: {},
data: FreeTableModel,
preview: boolean,
selectedCells: MacroSelectedCell[],
errors: string[] = []
) {
let rows = data.rows;
try {
rows = func(
data.rows,
macroArgs,
modules,
selectedCells,
data.structure.columns.map(x => x.columnName),
data.structure.columns
);
if (!preview) {
rows = removePreviewRowFlags(rows);
}
} catch (err) {
errors.push(`Error processing rows: ${err.message}`);
}
return {
structure: data.structure,
rows,
};
}
// function runTramsformRows(
// func,
// macroArgs: {},
// data: FreeTableModel,
// preview: boolean,
// selectedCells: MacroSelectedCell[],
// errors: string[] = []
// ) {
// let rows = data.rows;
// try {
// rows = func(
// data.rows,
// macroArgs,
// modules,
// selectedCells,
// data.structure.columns.map(x => x.columnName),
// data.structure.columns
// );
// if (!preview) {
// rows = removePreviewRowFlags(rows);
// }
// } catch (err) {
// errors.push(`Error processing rows: ${err.message}`);
// }
// return {
// structure: data.structure,
// rows,
// };
// }
function runTramsformData(
func,
macroArgs: {},
data: FreeTableModel,
preview: boolean,
selectedCells: MacroSelectedCell[],
errors: string[] = []
) {
try {
let { rows, columns, cols } = func(
data.rows,
macroArgs,
modules,
selectedCells,
data.structure.columns.map(x => x.columnName),
data.structure.columns
);
if (cols && !columns) {
columns = cols.map(columnName => ({ columnName }));
}
columns = _.uniqBy(columns, 'columnName');
if (!preview) {
rows = removePreviewRowFlags(rows);
}
return {
structure: { columns },
rows,
};
} catch (err) {
errors.push(`Error processing data: ${err.message}`);
}
return data;
}
// function runTramsformData(
// func,
// macroArgs: {},
// data: FreeTableModel,
// preview: boolean,
// selectedCells: MacroSelectedCell[],
// errors: string[] = []
// ) {
// try {
// let { rows, columns, cols } = func(
// data.rows,
// macroArgs,
// modules,
// selectedCells,
// data.structure.columns.map(x => x.columnName),
// data.structure.columns
// );
// if (cols && !columns) {
// columns = cols.map(columnName => ({ columnName }));
// }
// columns = _.uniqBy(columns, 'columnName');
// if (!preview) {
// rows = removePreviewRowFlags(rows);
// }
// return {
// structure: { columns },
// rows,
// };
// } catch (err) {
// errors.push(`Error processing data: ${err.message}`);
// }
// return data;
// }
export function runMacro(
macro: MacroDefinition,
macroArgs: {},
data: FreeTableModel,
preview: boolean,
selectedCells: MacroSelectedCell[],
errors: string[] = []
): FreeTableModel {
let func;
try {
func = eval(getMacroFunction[macro.type](macro.code));
} catch (err) {
errors.push(`Error compiling macro ${macro.name}: ${err.message}`);
return data;
}
if (macro.type == 'transformValue') {
return runTramsformValue(func, macroArgs, data, preview, selectedCells, errors);
}
if (macro.type == 'transformRows') {
return runTramsformRows(func, macroArgs, data, preview, selectedCells, errors);
}
if (macro.type == 'transformData') {
// @ts-ignore
return runTramsformData(func, macroArgs, data, preview, selectedCells, errors);
}
return data;
}
// export function runMacro(
// macro: MacroDefinition,
// macroArgs: {},
// data: FreeTableModel,
// preview: boolean,
// selectedCells: MacroSelectedCell[],
// errors: string[] = []
// ): FreeTableModel {
// let func;
// try {
// func = eval(getMacroFunction[macro.type](macro.code));
// } catch (err) {
// errors.push(`Error compiling macro ${macro.name}: ${err.message}`);
// return data;
// }
// if (macro.type == 'transformValue') {
// return runTramsformValue(func, macroArgs, data, preview, selectedCells, errors);
// }
// if (macro.type == 'transformRows') {
// return runTramsformRows(func, macroArgs, data, preview, selectedCells, errors);
// }
// if (macro.type == 'transformData') {
// // @ts-ignore
// return runTramsformData(func, macroArgs, data, preview, selectedCells, errors);
// }
// return data;
// }
export function compileMacroFunction(macro: MacroDefinition, errors = []) {
if (!macro) return null;
@@ -198,7 +193,7 @@ export function compileMacroFunction(macro: MacroDefinition, errors = []) {
}
}
export function runMacroOnValue(compiledFunc, macroArgs, value, rowIndex, row, column, errors = []) {
export function runMacroOnValue(compiledFunc, macroArgs, value, rowIndex: number, row, column: string, errors = []) {
if (!compiledFunc) return value;
try {
const res = compiledFunc(value, macroArgs, modules, rowIndex, row, column);
@@ -209,6 +204,17 @@ export function runMacroOnValue(compiledFunc, macroArgs, value, rowIndex, row, c
}
}
export function runMacroOnRow(compiledFunc, macroArgs, rowIndex: number, row: any, columns: string[], errors = []) {
if (!compiledFunc) return row;
try {
const res = compiledFunc(row, macroArgs, modules, rowIndex, columns);
return res;
} catch (err) {
errors.push(`Error processing row ${rowIndex}: ${err.message}`);
return row;
}
}
export function runMacroOnChangeSet(
macro: MacroDefinition,
macroArgs: {},
@@ -221,26 +227,39 @@ export function runMacroOnChangeSet(
const compiledMacroFunc = compileMacroFunction(macro, errors);
if (!compiledMacroFunc) return null;
let res = changeSet;
for (const cell of selectedCells) {
const definition = display.getChangeSetField(
cell.rowData,
cell.column,
undefined,
useRowIndexInsteaOfCondition ? cell.row : undefined,
useRowIndexInsteaOfCondition
);
const macroResult = runMacroOnValue(
compiledMacroFunc,
macroArgs,
cell.value,
cell.row,
cell.rowData,
cell.column,
errors
);
res = setChangeSetValue(res, definition, macroResult);
if (macro.type == 'transformValue') {
let res = changeSet;
for (const cell of selectedCells) {
const definition = display.getChangeSetField(
cell.rowData,
cell.column,
undefined,
useRowIndexInsteaOfCondition ? cell.row : undefined,
useRowIndexInsteaOfCondition
);
const macroResult = runMacroOnValue(
compiledMacroFunc,
macroArgs,
cell.value,
cell.row,
cell.rowData,
cell.column,
errors
);
res = setChangeSetValue(res, definition, macroResult);
}
return res;
}
if (macro.type == 'transformRow') {
let res = changeSet;
const rowIndexes = _.uniq(selectedCells.map(x => x.row));
for (const index of rowIndexes) {
const rowData = selectedCells.find(x => x.row == index)?.rowData;
const columns = _.uniq(selectedCells.map(x => x.column));
const definition = display.getChangeSetRow(rowData, null, index, true);
const newRow = runMacroOnRow(compiledMacroFunc, macroArgs, index, rowData, columns);
res = setChangeSetRowData(res, definition, newRow);
}
return res;
}
return res;
}