diff --git a/packages/web/src/appobj/databaseObjectAppObject.js b/packages/web/src/appobj/databaseObjectAppObject.js index 6cba2dbd9..a010956c5 100644 --- a/packages/web/src/appobj/databaseObjectAppObject.js +++ b/packages/web/src/appobj/databaseObjectAppObject.js @@ -33,6 +33,10 @@ const menus = { label: 'Export', isExport: true, }, + { + label: 'Open in free table editor', + isOpenFreeTable: true, + }, ], views: [ { @@ -51,6 +55,10 @@ const menus = { label: 'Export', isExport: true, }, + { + label: 'Open in free table editor', + isOpenFreeTable: true, + }, { label: 'Open structure', tab: 'TableStructureTab', @@ -113,7 +121,7 @@ function Menu({ data, makeAppObj, setOpenedTabs, showModal }) { {menus[data.objectTypeField].map((menu) => ( { + onClick={async () => { if (menu.isExport) { showModal((modalState) => ( )); + } else if (menu.isOpenFreeTable) { + const coninfo = await getConnectionInfo(data); + openNewTab(setOpenedTabs, { + title: data.pureName, + icon: 'freetable.svg', + tabComponent: 'FreeTableTab', + props: { + initialData: { + functionName: 'tableReader', + props: { + connection: { + ...coninfo, + database: data.database, + }, + schemaName: data.schemaName, + pureName: data.pureName, + }, + }, + }, + }); } else { openDatabaseObjectDetail(setOpenedTabs, menu.tab, menu.sqlTemplate, data); } diff --git a/packages/web/src/datagrid/DataGridContextMenu.js b/packages/web/src/datagrid/DataGridContextMenu.js index 34acf7657..bdd89e6dd 100644 --- a/packages/web/src/datagrid/DataGridContextMenu.js +++ b/packages/web/src/datagrid/DataGridContextMenu.js @@ -11,6 +11,7 @@ export default function DataGridContextMenu({ exportGrid, filterSelectedValue, openQuery, + openFreeTable, }) { return ( <> @@ -34,11 +35,12 @@ export default function DataGridContextMenu({ Set NULL - Export + {exportGrid && Export} Filter selected value {openQuery && Open query} + Open selection in free table editor ); } diff --git a/packages/web/src/datagrid/DataGridCore.js b/packages/web/src/datagrid/DataGridCore.js index 6207b3aab..83ed11041 100644 --- a/packages/web/src/datagrid/DataGridCore.js +++ b/packages/web/src/datagrid/DataGridCore.js @@ -26,6 +26,8 @@ import { showMenu } from '../modals/DropDownMenu'; import DataGridContextMenu from './DataGridContextMenu'; import LoadingInfo from '../widgets/LoadingInfo'; import ErrorInfo from '../widgets/ErrorInfo'; +import { openNewTab } from '../utility/common'; +import { useSetOpenedTabs } from '../utility/globalState'; const GridContainer = styled.div` position: absolute; @@ -110,6 +112,7 @@ export default function DataGridCore(props) { } = props; // console.log('RENDER GRID', display.baseTable.pureName); const columns = React.useMemo(() => display.allColumns, [display]); + const setOpenedTabs = useSetOpenedTabs(); // usePropsCompare(props); @@ -294,6 +297,24 @@ export default function DataGridCore(props) { setFirstVisibleColumnScrollIndex(value); }; + const handleOpenFreeTable = () => { + const columns = getSelectedColumns(); + const rows = getSelectedRowData().map((row) => _.pickBy(row, (v, col) => columns.find((x) => x.columnName == col))); + openNewTab(setOpenedTabs, { + title: 'selection', + icon: 'freetable.svg', + tabComponent: 'FreeTableTab', + props: { + initialData: { + structure: { + columns, + }, + rows, + }, + }, + }); + }; + const handleContextMenu = (event) => { event.preventDefault(); showMenu( @@ -309,6 +330,7 @@ export default function DataGridCore(props) { exportGrid={exportGrid} filterSelectedValue={filterSelectedValue} openQuery={openQuery} + openFreeTable={handleOpenFreeTable} /> ); }; @@ -499,13 +521,27 @@ export default function DataGridCore(props) { } function getSelectedRowIndexes() { - return _.uniq((selectedCells || []).map((x) => x[0])); + if (selectedCells.find((x) => x[0] == 'header')) return _.range(0, grider.rowCount); + return _.uniq((selectedCells || []).map((x) => x[0])).filter((x) => _.isNumber(x)); + } + + function getSelectedColumnIndexes() { + if (selectedCells.find((x) => x[1] == 'header')) return _.range(0, realColumnUniqueNames.length); + return _.uniq((selectedCells || []).map((x) => x[1])).filter((x) => _.isNumber(x)); } function getSelectedRowData() { return _.compact(getSelectedRowIndexes().map((index) => grider.getRowData(index))); } + function getSelectedColumns() { + return _.compact( + getSelectedColumnIndexes().map((index) => ({ + columnName: realColumnUniqueNames[index], + })) + ); + } + function revertRowChanges() { grider.beginUpdate(); for (const index of getSelectedRowIndexes()) { diff --git a/packages/web/src/tabs/FreeTableTab.js b/packages/web/src/tabs/FreeTableTab.js index a222a3a0b..46d67f85a 100644 --- a/packages/web/src/tabs/FreeTableTab.js +++ b/packages/web/src/tabs/FreeTableTab.js @@ -44,7 +44,9 @@ export default function FreeDataTab({ archiveFolder, archiveFile, tabVisible, to // @ts-ignore dispatchModel({ type: 'reset', value }); } else if (initialData) { - handleLoadInitialData(); + if (initialData.functionName) handleLoadInitialData(); + // @ts-ignore + else dispatchModel({ type: 'reset', value: initialData }); } }, []);