From a77492440ea84744dcb89e8816a31c33f212640c Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sat, 25 Feb 2023 09:51:08 +0100 Subject: [PATCH] removed free table (data sheet) concept --- packages/api/src/controllers/archive.js | 40 ++--- packages/api/src/controllers/jsldata.js | 17 +- packages/api/src/utility/freeTableStorage.js | 15 -- packages/datalib/src/FreeTableGridDisplay.ts | 48 ----- packages/datalib/src/FreeTableModel.ts | 27 --- packages/datalib/src/runMacro.ts | 155 ---------------- .../src/appobj/ArchiveFileAppObject.svelte | 19 -- .../src/appobj/DatabaseObjectAppObject.svelte | 34 +--- packages/web/src/commands/stdCommands.ts | 15 -- packages/web/src/datagrid/DataGrid.svelte | 2 - packages/web/src/datagrid/DataGridCell.svelte | 16 +- packages/web/src/datagrid/DataGridCore.svelte | 36 ++-- .../freetable/FreeTableColumnEditor.svelte | 82 --------- .../src/freetable/FreeTableGridCore.svelte | 84 --------- packages/web/src/freetable/FreeTableGrider.ts | 104 ----------- packages/web/src/jsontree/JSONTree.svelte | 18 +- packages/web/src/tabs/FreeTableTab.svelte | 167 ------------------ packages/web/src/tabs/index.js | 2 - packages/web/src/utility/openJsonLinesData.ts | 17 ++ .../web/src/widgets/ArchiveFilesList.svelte | 24 ++- 20 files changed, 65 insertions(+), 857 deletions(-) delete mode 100644 packages/api/src/utility/freeTableStorage.js delete mode 100644 packages/datalib/src/FreeTableGridDisplay.ts delete mode 100644 packages/datalib/src/FreeTableModel.ts delete mode 100644 packages/web/src/freetable/FreeTableColumnEditor.svelte delete mode 100644 packages/web/src/freetable/FreeTableGridCore.svelte delete mode 100644 packages/web/src/freetable/FreeTableGrider.ts delete mode 100644 packages/web/src/tabs/FreeTableTab.svelte create mode 100644 packages/web/src/utility/openJsonLinesData.ts diff --git a/packages/api/src/controllers/archive.js b/packages/api/src/controllers/archive.js index e520871e..dcf7eee3 100644 --- a/packages/api/src/controllers/archive.js +++ b/packages/api/src/controllers/archive.js @@ -3,7 +3,6 @@ const readline = require('readline'); const path = require('path'); const { archivedir, clearArchiveLinksCache, resolveArchiveFolder } = require('../utility/directories'); const socket = require('../utility/socket'); -const { saveFreeTableData } = require('../utility/freeTableStorage'); const loadFilesRecursive = require('../utility/loadFilesRecursive'); const getJslFileName = require('../utility/getJslFileName'); const { getLogger } = require('dbgate-tools'); @@ -162,34 +161,6 @@ module.exports = { return true; }, - saveFreeTable_meta: true, - async saveFreeTable({ folder, file, data }) { - await saveFreeTableData(path.join(resolveArchiveFolder(folder), `${file}.jsonl`), data); - socket.emitChanged(`archive-files-changed`, { folder }); - return true; - }, - - loadFreeTable_meta: true, - async loadFreeTable({ folder, file }) { - return new Promise((resolve, reject) => { - const fileStream = fs.createReadStream(path.join(resolveArchiveFolder(folder), `${file}.jsonl`)); - const liner = readline.createInterface({ - input: fileStream, - }); - let structure = null; - const rows = []; - liner.on('line', line => { - const data = JSON.parse(line); - if (structure) rows.push(data); - else structure = data; - }); - liner.on('close', () => { - resolve({ structure, rows }); - fileStream.close(); - }); - }); - }, - saveText_meta: true, async saveText({ folder, file, text }) { await fs.writeFile(path.join(resolveArchiveFolder(folder), `${file}.jsonl`), text); @@ -206,6 +177,17 @@ module.exports = { return true; }, + saveRows_meta: true, + async saveRows({ folder, file, rows }) { + const fileStream = fs.createWriteStream(path.join(resolveArchiveFolder(folder), `${file}.jsonl`)); + for (const row of rows) { + await fileStream.write(JSON.stringify(row) + '\n'); + } + await fileStream.close(); + socket.emitChanged(`archive-files-changed`, { folder }); + return true; + }, + async getNewArchiveFolder({ database }) { const isLink = database.endsWith(database); const name = isLink ? database.slice(0, -5) : database; diff --git a/packages/api/src/controllers/jsldata.js b/packages/api/src/controllers/jsldata.js index d591c43d..3da64d2e 100644 --- a/packages/api/src/controllers/jsldata.js +++ b/packages/api/src/controllers/jsldata.js @@ -4,7 +4,6 @@ const lineReader = require('line-reader'); const _ = require('lodash'); const { __ } = require('lodash/fp'); const DatastoreProxy = require('../utility/DatastoreProxy'); -const { saveFreeTableData } = require('../utility/freeTableStorage'); const getJslFileName = require('../utility/getJslFileName'); const JsonLinesDatastore = require('../utility/JsonLinesDatastore'); const requirePluginFunction = require('../utility/requirePluginFunction'); @@ -189,18 +188,22 @@ module.exports = { // } }, - saveFreeTable_meta: true, - async saveFreeTable({ jslid, data }) { - saveFreeTableData(getJslFileName(jslid), data); - return true; - }, - saveText_meta: true, async saveText({ jslid, text }) { await fs.promises.writeFile(getJslFileName(jslid), text); return true; }, + saveRows_meta: true, + async saveRows({ jslid, rows }) { + const fileStream = fs.createWriteStream(getJslFileName(jslid)); + for (const row of rows) { + await fileStream.write(JSON.stringify(row) + '\n'); + } + await fileStream.close(); + return true; + }, + extractTimelineChart_meta: true, async extractTimelineChart({ jslid, timestampFunction, aggregateFunction, measures }) { const timestamp = requirePluginFunction(timestampFunction); diff --git a/packages/api/src/utility/freeTableStorage.js b/packages/api/src/utility/freeTableStorage.js deleted file mode 100644 index ceba774e..00000000 --- a/packages/api/src/utility/freeTableStorage.js +++ /dev/null @@ -1,15 +0,0 @@ -const fs = require('fs-extra'); - -async function saveFreeTableData(file, data) { - const { structure, rows } = data; - const fileStream = fs.createWriteStream(file); - await fileStream.write(JSON.stringify({ __isStreamHeader: true, ...structure }) + '\n'); - for (const row of rows) { - await fileStream.write(JSON.stringify(row) + '\n'); - } - await fileStream.close(); -} - -module.exports = { - saveFreeTableData, -}; diff --git a/packages/datalib/src/FreeTableGridDisplay.ts b/packages/datalib/src/FreeTableGridDisplay.ts deleted file mode 100644 index 607abf4e..00000000 --- a/packages/datalib/src/FreeTableGridDisplay.ts +++ /dev/null @@ -1,48 +0,0 @@ -import _ from 'lodash'; -import type { EngineDriver, ViewInfo, ColumnInfo } from 'dbgate-types'; -import { GridDisplay, ChangeCacheFunc, ChangeConfigFunc } from './GridDisplay'; -import { GridConfig, GridCache } from './GridConfig'; -import { FreeTableModel } from './FreeTableModel'; -import { analyseCollectionDisplayColumns } from '.'; - -export class FreeTableGridDisplay extends GridDisplay { - constructor( - public model: FreeTableModel, - config: GridConfig, - setConfig: ChangeConfigFunc, - cache: GridCache, - setCache: ChangeCacheFunc - ) { - super(config, setConfig, cache, setCache); - this.columns = model?.structure?.__isDynamicStructure - ? analyseCollectionDisplayColumns(model?.rows, this) - : this.getDisplayColumns(model); - this.filterable = false; - this.sortable = false; - } - - getDisplayColumns(model: FreeTableModel) { - return _.uniqBy( - model?.structure?.columns - ?.map(col => this.getDisplayColumn(col)) - ?.map(col => ({ - ...col, - isChecked: this.isColumnChecked(col), - })) || [], - col => col.uniqueName - ); - } - - getDisplayColumn(col: ColumnInfo) { - const uniquePath = [col.columnName]; - const uniqueName = uniquePath.join('.'); - return { - ...col, - pureName: 'data', - schemaName: '', - headerText: col.columnName, - uniqueName, - uniquePath, - }; - } -} diff --git a/packages/datalib/src/FreeTableModel.ts b/packages/datalib/src/FreeTableModel.ts deleted file mode 100644 index 616e0c8e..00000000 --- a/packages/datalib/src/FreeTableModel.ts +++ /dev/null @@ -1,27 +0,0 @@ -import type { TableInfo } from 'dbgate-types'; - -export interface FreeTableModel { - structure: TableInfo; - rows: any[]; -} - -export function createFreeTableModel() { - return { - structure: { - columns: [ - { - columnName: 'col1', - }, - ], - foreignKeys: [], - }, - rows: [ - { - col1: 'val1', - }, - { - col1: 'val2', - }, - ], - }; -} diff --git a/packages/datalib/src/runMacro.ts b/packages/datalib/src/runMacro.ts index bd545ef3..a85c1d7a 100644 --- a/packages/datalib/src/runMacro.ts +++ b/packages/datalib/src/runMacro.ts @@ -1,4 +1,3 @@ -import { FreeTableModel } from './FreeTableModel'; import _ from 'lodash'; import uuidv1 from 'uuid/v1'; import uuidv4 from 'uuid/v4'; @@ -27,160 +26,6 @@ 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; -// } -// }); - -// 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 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; -// } - -// 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; let func; diff --git a/packages/web/src/appobj/ArchiveFileAppObject.svelte b/packages/web/src/appobj/ArchiveFileAppObject.svelte index a0f76e1a..20457d54 100644 --- a/packages/web/src/appobj/ArchiveFileAppObject.svelte +++ b/packages/web/src/appobj/ArchiveFileAppObject.svelte @@ -111,24 +111,6 @@ const handleOpenArchive = () => { openArchive(data.fileName, data.folderName); }; - const handleOpenDataSheet = () => { - openNewTab({ - title: data.fileName, - icon: 'img free-table', - tabComponent: 'FreeTableTab', - props: { - initialArgs: { - functionName: 'archiveReader', - props: { - fileName: data.fileName, - folderName: data.folderName, - }, - }, - archiveFile: data.fileName, - archiveFolder: data.folderName, - }, - }); - }; const handleClick = () => { if (data.fileType == 'jsonl') { handleOpenArchive(); @@ -153,7 +135,6 @@ function createMenu() { return [ data.fileType == 'jsonl' && { text: 'Open', onClick: handleOpenArchive }, - data.fileType == 'jsonl' && { text: 'Open as data sheet', onClick: handleOpenDataSheet }, data.fileType == 'jsonl' && { text: 'Open in text editor', onClick: handleOpenJsonLinesText }, { text: 'Delete', onClick: handleDelete }, { text: 'Rename', onClick: handleRename }, diff --git a/packages/web/src/appobj/DatabaseObjectAppObject.svelte b/packages/web/src/appobj/DatabaseObjectAppObject.svelte index 57cbce1f..14acbd70 100644 --- a/packages/web/src/appobj/DatabaseObjectAppObject.svelte +++ b/packages/web/src/appobj/DatabaseObjectAppObject.svelte @@ -102,10 +102,6 @@ isImport: true, requiresWriteAccess: true, }, - { - label: 'Open as data sheet', - isOpenFreeTable: true, - }, { label: 'Open active chart', isActiveChart: true, @@ -176,10 +172,6 @@ isExport: true, functionName: 'tableReader', }, - { - label: 'Open as data sheet', - isOpenFreeTable: true, - }, { label: 'Open active chart', isActiveChart: true, @@ -242,10 +234,6 @@ isExport: true, functionName: 'tableReader', }, - { - label: 'Open as data sheet', - isOpenFreeTable: true, - }, { label: 'Open active chart', isActiveChart: true, @@ -409,27 +397,7 @@ return driver; }; - if (menu.isOpenFreeTable) { - const coninfo = await getConnectionInfo(data); - openNewTab({ - title: data.pureName, - icon: 'img free-table', - tabComponent: 'FreeTableTab', - props: { - initialArgs: { - functionName: 'tableReader', - props: { - connection: { - ...coninfo, - database: data.database, - }, - schemaName: data.schemaName, - pureName: data.pureName, - }, - }, - }, - }); - } else if (menu.isActiveChart) { + if (menu.isActiveChart) { const driver = await getDriver(); const dmp = driver.createDumper(); dmp.put('^select * from %f', data); diff --git a/packages/web/src/commands/stdCommands.ts b/packages/web/src/commands/stdCommands.ts index 3fef3009..46f23cb4 100644 --- a/packages/web/src/commands/stdCommands.ts +++ b/packages/web/src/commands/stdCommands.ts @@ -329,21 +329,6 @@ registerCommand({ }, }); -registerCommand({ - id: 'new.freetable', - category: 'New', - icon: 'img markdown', - name: 'Data sheet', - menuName: 'New data sheet', - onClick: () => { - openNewTab({ - title: 'Data #', - icon: 'img free-table', - tabComponent: 'FreeTableTab', - }); - }, -}); - registerCommand({ id: 'new.jsonl', category: 'New', diff --git a/packages/web/src/datagrid/DataGrid.svelte b/packages/web/src/datagrid/DataGrid.svelte index 6a1d851a..8195d766 100644 --- a/packages/web/src/datagrid/DataGrid.svelte +++ b/packages/web/src/datagrid/DataGrid.svelte @@ -63,7 +63,6 @@ import WidgetColumnBarItem from '../widgets/WidgetColumnBarItem.svelte'; import ColumnManager from './ColumnManager.svelte'; import ReferenceManager from './ReferenceManager.svelte'; - import FreeTableColumnEditor from '../freetable/FreeTableColumnEditor.svelte'; import JsonViewFilters from '../jsonview/JsonViewFilters.svelte'; import createActivator, { getActiveComponent } from '../utility/createActivator'; import _ from 'lodash'; @@ -201,7 +200,6 @@ height="40%" show={freeTableColumn && !isDynamicStructure} > - diff --git a/packages/web/src/datagrid/DataGridCell.svelte b/packages/web/src/datagrid/DataGridCell.svelte index b785de0a..f22b394c 100644 --- a/packages/web/src/datagrid/DataGridCell.svelte +++ b/packages/web/src/datagrid/DataGridCell.svelte @@ -7,6 +7,7 @@ import CellValue from './CellValue.svelte'; import { showModal } from '../modals/modalTools'; import EditCellDataModal from '../modals/EditCellDataModal.svelte'; + import { openJsonLinesData } from '../utility/openJsonLinesData'; export let rowIndex; export let col; @@ -96,20 +97,7 @@ icon="icon open-in-new" on:click={() => { if (_.every(jsonParsedValue || value, x => _.isPlainObject(x))) { - openNewTab( - { - title: 'Data #', - icon: 'img free-table', - tabComponent: 'FreeTableTab', - props: {}, - }, - { - editor: { - rows: jsonParsedValue || value, - structure: { __isDynamicStructure: true, columns: [] }, - }, - } - ); + openJsonLinesData(jsonParsedValue || value); } else { openJsonDocument(jsonParsedValue || value, undefined, true); } diff --git a/packages/web/src/datagrid/DataGridCore.svelte b/packages/web/src/datagrid/DataGridCore.svelte index bd016e30..8f611a23 100644 --- a/packages/web/src/datagrid/DataGridCore.svelte +++ b/packages/web/src/datagrid/DataGridCore.svelte @@ -161,7 +161,7 @@ registerCommand({ id: 'dataGrid.openJsonArrayInSheet', category: 'Data grid', - name: 'Open array as data sheet', + name: 'Open array as table', testEnabled: () => getCurrentDataGrid()?.openJsonArrayInSheetEnabled(), onClick: () => getCurrentDataGrid().openJsonArrayInSheet(), }); @@ -238,7 +238,7 @@ registerCommand({ id: 'dataGrid.openFreeTable', category: 'Data grid', - name: 'Edit selection as data sheet', + name: 'Edit selection as table', testEnabled: () => getCurrentDataGrid() != null, onClick: () => getCurrentDataGrid().openFreeTable(), }); @@ -398,6 +398,7 @@ import EditCellDataModal, { shouldOpenMultilineDialog } from '../modals/EditCellDataModal.svelte'; import { getDatabaseInfo, useDatabaseStatus } from '../utility/metadataLoaders'; import { showSnackbarSuccess } from '../utility/snackbar'; + import { openJsonLinesData } from '../utility/openJsonLinesData'; export let onLoadNextData = undefined; export let grider = undefined; @@ -645,15 +646,7 @@ } export function openFreeTable() { - openNewTab( - { - title: 'Data #', - icon: 'img free-table', - tabComponent: 'FreeTableTab', - props: {}, - }, - { editor: getSelectedFreeData() } - ); + openJsonLinesData(getSelectedFreeDataRows()); } export function openChartFromSelection() { @@ -784,20 +777,7 @@ } export function openJsonArrayInSheet() { - openNewTab( - { - title: 'Data #', - icon: 'img free-table', - tabComponent: 'FreeTableTab', - props: {}, - }, - { - editor: { - rows: getSelectedDataJson(true), - structure: { __isDynamicStructure: true, columns: [] }, - }, - } - ); + openJsonLinesData(getSelectedDataJson(true)); } export function editJsonEnabled() { @@ -1109,6 +1089,12 @@ }; }; + const getSelectedFreeDataRows = () => { + const columns = getSelectedColumns(); + const rows = getSelectedRowData().map(row => _.pickBy(row, (v, col) => columns.find(x => x.columnName == col))); + return rows; + }; + function getCellsPublished(cells) { const regular = cellsToRegularCells(cells); const res = regular diff --git a/packages/web/src/freetable/FreeTableColumnEditor.svelte b/packages/web/src/freetable/FreeTableColumnEditor.svelte deleted file mode 100644 index fece2312..00000000 --- a/packages/web/src/freetable/FreeTableColumnEditor.svelte +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - {#each structure?.columns || [] as column, index} - {#if index == editingColumn} - { - dispatchChangeColumns( - $$props, - cols => cols.map((col, i) => (index == i ? { columnName } : col)), - row => _.mapKeys(row, (v, k) => (k == column.columnName ? columnName : k)) - ); - }} - onBlur={() => (editingColumn = null)} - focusOnCreate - blurOnEnter - existingNames={structure?.columns.map(x => x.columnName)} - /> - {:else} - (editingColumn = index)} - onRemove={() => { - dispatchChangeColumns($$props, cols => cols.filter((c, i) => i != index)); - }} - onUp={() => { - dispatchChangeColumns($$props, cols => exchange(cols, index, index - 1)); - }} - onDown={() => { - dispatchChangeColumns($$props, cols => exchange(cols, index, index + 1)); - }} - /> - {/if} - {/each} - { - dispatchChangeColumns($$props, cols => [...cols, { columnName }]); - }} - placeholder="New column" - existingNames={(structure?.columns || []).map(x => x.columnName)} - /> - diff --git a/packages/web/src/freetable/FreeTableGridCore.svelte b/packages/web/src/freetable/FreeTableGridCore.svelte deleted file mode 100644 index c791b16f..00000000 --- a/packages/web/src/freetable/FreeTableGridCore.svelte +++ /dev/null @@ -1,84 +0,0 @@ - - - - - diff --git a/packages/web/src/freetable/FreeTableGrider.ts b/packages/web/src/freetable/FreeTableGrider.ts deleted file mode 100644 index 3d7e62b1..00000000 --- a/packages/web/src/freetable/FreeTableGrider.ts +++ /dev/null @@ -1,104 +0,0 @@ -import type { FreeTableModel } from 'dbgate-datalib'; -import Grider from '../datagrid/Grider'; - -export default class FreeTableGrider extends Grider { - public model: FreeTableModel; - private batchModel: FreeTableModel; - - constructor(public modelState, public dispatchModel) { - super(); - this.model = modelState && modelState.value; - } - getRowData(index: any) { - return this.model.rows?.[index]; - } - get rowCount() { - return this.model.rows?.length; - } - get currentModel(): FreeTableModel { - return this.batchModel || this.model; - } - set currentModel(value) { - if (this.batchModel) this.batchModel = value; - else this.dispatchModel({ type: 'set', value }); - } - setCellValue(index: number, uniqueName: string, value: any) { - const model = this.currentModel; - if (model.rows[index]) { - this.currentModel = { - ...model, - rows: model.rows.map((row, i) => (index == i ? { ...row, [uniqueName]: value } : row)), - }; - } - } - setRowData(index: number, document: any) { - const model = this.currentModel; - if (model.rows[index]) { - this.currentModel = { - ...model, - rows: model.rows.map((row, i) => (index == i ? document : row)), - }; - } - } - get editable() { - return true; - } - get canInsert() { - return true; - } - get allowSave() { - return true; - } - insertRow(): number { - const model = this.currentModel; - this.currentModel = { - ...model, - rows: [...model.rows, {}], - }; - return this.currentModel.rows.length - 1; - } - insertDocuments(documents: any[]): number { - const model = this.currentModel; - this.currentModel = { - ...model, - rows: [...model.rows, ...documents], - }; - return this.currentModel.rows.length - documents.length; - } - - deleteRow(index: number) { - const model = this.currentModel; - this.currentModel = { - ...model, - rows: model.rows.filter((row, i) => index != i), - }; - } - beginUpdate() { - this.batchModel = this.model; - } - endUpdate() { - if (this.model != this.batchModel) { - this.dispatchModel({ type: 'set', value: this.batchModel }); - this.batchModel = null; - } - } - - // static factory({ modelState, dispatchModel }): FreeTableGrider { - // return new FreeTableGrider(modelState, dispatchModel); - // } - // static factoryDeps({ modelState, dispatchModel }) { - // return [modelState, dispatchModel]; - // } - undo() { - this.dispatchModel({ type: 'undo' }); - } - redo() { - this.dispatchModel({ type: 'redo' }); - } - get canUndo() { - return this.modelState.canUndo; - } - get canRedo() { - return this.modelState.canRedo; - } -} diff --git a/packages/web/src/jsontree/JSONTree.svelte b/packages/web/src/jsontree/JSONTree.svelte index 1ffe3758..06b7a74c 100644 --- a/packages/web/src/jsontree/JSONTree.svelte +++ b/packages/web/src/jsontree/JSONTree.svelte @@ -5,6 +5,7 @@ import openNewTab from '../utility/openNewTab'; import _ from 'lodash'; import { copyTextToClipboard } from '../utility/clipboard'; + import { openJsonLinesData } from '../utility/openJsonLinesData'; setContext('json-tree-context-key', {}); @@ -49,22 +50,9 @@ if (value && _.isArray(value)) { res.push({ - text: 'Open as data sheet', + text: 'Open as table', onClick: () => { - openNewTab( - { - title: 'Data #', - icon: 'img free-table', - tabComponent: 'FreeTableTab', - props: {}, - }, - { - editor: { - rows: value, - structure: { __isDynamicStructure: true, columns: [] }, - }, - } - ); + openJsonLinesData(value); }, }); } diff --git a/packages/web/src/tabs/FreeTableTab.svelte b/packages/web/src/tabs/FreeTableTab.svelte deleted file mode 100644 index 361181ab..00000000 --- a/packages/web/src/tabs/FreeTableTab.svelte +++ /dev/null @@ -1,167 +0,0 @@ - - - - -{#if isLoading} - -{:else if errorMessage} - -{:else} - - - - - - - -{/if} diff --git a/packages/web/src/tabs/index.js b/packages/web/src/tabs/index.js index 59243e4e..fa73ab2a 100644 --- a/packages/web/src/tabs/index.js +++ b/packages/web/src/tabs/index.js @@ -5,7 +5,6 @@ import * as TableStructureTab from './TableStructureTab.svelte'; import * as QueryTab from './QueryTab.svelte'; import * as ShellTab from './ShellTab.svelte'; import * as ArchiveFileTab from './ArchiveFileTab.svelte'; -import * as FreeTableTab from './FreeTableTab.svelte'; import * as PluginTab from './PluginTab.svelte'; import * as ChartTab from './ChartTab.svelte'; import * as MarkdownEditorTab from './MarkdownEditorTab.svelte'; @@ -38,7 +37,6 @@ export default { QueryTab, ShellTab, ArchiveFileTab, - FreeTableTab, PluginTab, ChartTab, MarkdownEditorTab, diff --git a/packages/web/src/utility/openJsonLinesData.ts b/packages/web/src/utility/openJsonLinesData.ts new file mode 100644 index 00000000..a84651b7 --- /dev/null +++ b/packages/web/src/utility/openJsonLinesData.ts @@ -0,0 +1,17 @@ +import uuidv1 from 'uuid/v1'; +import { apiCall } from './api'; +import openNewTab from './openNewTab'; + +export async function openJsonLinesData(rows) { + const jslid = uuidv1(); + + await apiCall('jsldata/save-rows', { jslid, rows }); + openNewTab({ + tabComponent: 'ArchiveFileTab', + icon: 'img archive', + title: 'Data #', + props: { + jslid, + }, + }); +} diff --git a/packages/web/src/widgets/ArchiveFilesList.svelte b/packages/web/src/widgets/ArchiveFilesList.svelte index b3ed4a6b..8c39c8a2 100644 --- a/packages/web/src/widgets/ArchiveFilesList.svelte +++ b/packages/web/src/widgets/ArchiveFilesList.svelte @@ -42,30 +42,26 @@ apiCall('archive/refresh-files', { folder }); }; - function handleNewDataSheet() { + function handleNewJsonLines() { showModal(InputTextModal, { value: '', label: 'New file name', - header: 'Create new data sheet', + header: 'Create new JSON lines', onConfirm: async file => { - await apiCall('archive/save-free-table', { + await apiCall('archive/save-rows', { folder: $currentArchive, file, - data: createFreeTableModel(), + rows: [ + { id: 1, value: 'val1' }, + { id: 1, value: 'val2' }, + ], }); openNewTab({ title: file, - icon: 'img free-table', - tabComponent: 'FreeTableTab', + icon: 'img archive', + tabComponent: 'ArchiveFileTab', props: { - initialArgs: { - functionName: 'archiveReader', - props: { - fileName: file, - folderName: $currentArchive, - }, - }, archiveFile: file, archiveFolder: $currentArchive, }, @@ -75,7 +71,7 @@ } function createAddMenu() { - return [{ text: 'New data sheet', onClick: handleNewDataSheet }]; + return [{ text: 'New NDJSON file', onClick: handleNewJsonLines }]; }