mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-28 10:45:59 +00:00
free table infrastructure
This commit is contained in:
45
packages/datalib/src/FreeTableGridDisplay.ts
Normal file
45
packages/datalib/src/FreeTableGridDisplay.ts
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import _ from 'lodash';
|
||||||
|
import { EngineDriver, ViewInfo, ColumnInfo } from '@dbgate/types';
|
||||||
|
import { GridDisplay, ChangeCacheFunc, ChangeConfigFunc } from './GridDisplay';
|
||||||
|
import { GridConfig, GridCache } from './GridConfig';
|
||||||
|
import { FreeTableModel } from './FreeTableModel';
|
||||||
|
|
||||||
|
export class FreeTableGridDisplay extends GridDisplay {
|
||||||
|
constructor(
|
||||||
|
public model: FreeTableModel,
|
||||||
|
config: GridConfig,
|
||||||
|
setConfig: ChangeConfigFunc,
|
||||||
|
cache: GridCache,
|
||||||
|
setCache: ChangeCacheFunc
|
||||||
|
) {
|
||||||
|
super(config, setConfig, cache, setCache);
|
||||||
|
this.columns = this.getDisplayColumns(model);
|
||||||
|
this.filterable = true;
|
||||||
|
this.sortable = true;
|
||||||
|
this.editable = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
getDisplayColumns(model: FreeTableModel) {
|
||||||
|
return (
|
||||||
|
model?.structure?.columns
|
||||||
|
?.map((col) => this.getDisplayColumn(col))
|
||||||
|
?.map((col) => ({
|
||||||
|
...col,
|
||||||
|
isChecked: this.isColumnChecked(col),
|
||||||
|
})) || []
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getDisplayColumn( col: ColumnInfo) {
|
||||||
|
const uniquePath = [col.columnName];
|
||||||
|
const uniqueName = uniquePath.join('.');
|
||||||
|
return {
|
||||||
|
...col,
|
||||||
|
pureName: 'data',
|
||||||
|
schemaName: '',
|
||||||
|
headerText: col.columnName,
|
||||||
|
uniqueName,
|
||||||
|
uniquePath,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
27
packages/datalib/src/FreeTableModel.ts
Normal file
27
packages/datalib/src/FreeTableModel.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { 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',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -5,3 +5,5 @@ export * from "./ViewGridDisplay";
|
|||||||
export * from "./JslGridDisplay";
|
export * from "./JslGridDisplay";
|
||||||
export * from "./ChangeSet";
|
export * from "./ChangeSet";
|
||||||
export * from "./filterName";
|
export * from "./filterName";
|
||||||
|
export * from "./FreeTableGridDisplay";
|
||||||
|
export * from "./FreeTableModel";
|
||||||
|
|||||||
10
packages/web/public/icons/freetable.svg
Normal file
10
packages/web/public/icons/freetable.svg
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version='1.0' encoding='iso-8859-1'?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||||
|
<g transform="translate(-326-532.36)">
|
||||||
|
<rect width="18" height="6" x="329" y="537.36" fill="#88ff88" stroke="#2d2d2d" stroke-linejoin="round" stroke-linecap="round" stroke-width=".837" rx=".646"/>
|
||||||
|
|
||||||
|
<rect width="18" height="5" x="329" y="547.86" fill="#88ff88" stroke="#2d2d2d" stroke-linejoin="round" stroke-linecap="round" stroke-width=".837" rx=".646"/>
|
||||||
|
|
||||||
|
<path d="m507.95 46.02c-1.367-16.368-14.588-30.13-31.21-30.13h-444.96c-16.622 0-29.844 13.762-31.24 30.13h-.54v414.82c0 17.544 14.239 31.782 31.782 31.782h444.95c17.544 0 31.782-14.239 31.782-31.782v-414.82h-.571m-349.04 414.82h-127.13v-95.35h127.13v95.35m0-124.49h-127.13v-97.99h127.13v97.99m0-129.77h-127.13v-95.35h127.13v95.35m158.91 254.26h-127.13v-95.35h127.13v95.35m0-124.49h-127.13v-97.99h127.13v97.99m0-129.77h-127.13v-95.35h127.13v95.35m158.91 254.26h-127.13v-95.35h127.13v95.35m0-124.49h-127.13v-97.99h127.13v97.99m0-129.77h-127.13v-95.35h127.13v95.35" transform="matrix(.03776 0 0 .03776 328.4 534.76)" fill="#2d2d2d"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -7,10 +7,6 @@ export default abstract class Grider {
|
|||||||
abstract getRowData(index): any;
|
abstract getRowData(index): any;
|
||||||
abstract get rowCount(): number;
|
abstract get rowCount(): number;
|
||||||
|
|
||||||
getRowsSample() {
|
|
||||||
return [this.getRowData(0)];
|
|
||||||
}
|
|
||||||
|
|
||||||
getRowStatus(index): GriderRowStatus {
|
getRowStatus(index): GriderRowStatus {
|
||||||
const res: GriderRowStatus = {
|
const res: GriderRowStatus = {
|
||||||
status: 'regular',
|
status: 'regular',
|
||||||
|
|||||||
@@ -17,7 +17,4 @@ export default class RowsArrayGrider extends Grider {
|
|||||||
static factoryDeps({ sourceRows }) {
|
static factoryDeps({ sourceRows }) {
|
||||||
return [sourceRows];
|
return [sourceRows];
|
||||||
}
|
}
|
||||||
getRowsSample() {
|
|
||||||
return this.rows;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
37
packages/web/src/freetable/FreeTableGrid.js
Normal file
37
packages/web/src/freetable/FreeTableGrid.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
import { ManagerMainContainer, ManagerOuterContainerFull } from '../datagrid/ManagerStyles';
|
||||||
|
import { HorizontalSplitter } from '../widgets/Splitter';
|
||||||
|
import FreeTableGridCore from './FreeTableGridCore';
|
||||||
|
|
||||||
|
const LeftContainer = styled.div`
|
||||||
|
background-color: white;
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const DataGridContainer = styled.div`
|
||||||
|
position: relative;
|
||||||
|
flex-grow: 1;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default function FreeTableGrid(props) {
|
||||||
|
const [managerSize, setManagerSize] = React.useState(0);
|
||||||
|
return (
|
||||||
|
<HorizontalSplitter initialValue="300px" size={managerSize} setSize={setManagerSize}>
|
||||||
|
<LeftContainer>
|
||||||
|
<ManagerMainContainer>
|
||||||
|
<ManagerOuterContainerFull>
|
||||||
|
COLUMNS
|
||||||
|
{/* <ColumnManager {...props} managerSize={managerSize} /> */}
|
||||||
|
</ManagerOuterContainerFull>
|
||||||
|
</ManagerMainContainer>
|
||||||
|
</LeftContainer>
|
||||||
|
|
||||||
|
<DataGridContainer>
|
||||||
|
<FreeTableGridCore {...props} />
|
||||||
|
</DataGridContainer>
|
||||||
|
</HorizontalSplitter>
|
||||||
|
);
|
||||||
|
}
|
||||||
17
packages/web/src/freetable/FreeTableGridCore.js
Normal file
17
packages/web/src/freetable/FreeTableGridCore.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { createGridCache, FreeTableGridDisplay } from '@dbgate/datalib';
|
||||||
|
import React from 'react';
|
||||||
|
import DataGridCore from '../datagrid/DataGridCore';
|
||||||
|
import FreeTableGrider from './FreeTableGrider';
|
||||||
|
|
||||||
|
export default function FreeTableGridCore(props) {
|
||||||
|
const { modelState, dispatchModel, config, setConfig } = props;
|
||||||
|
const grider = React.useMemo(() => FreeTableGrider.factory(props), FreeTableGrider.factoryDeps(props));
|
||||||
|
const [cache, setCache] = React.useState(createGridCache());
|
||||||
|
const display = React.useMemo(() => new FreeTableGridDisplay(modelState.value, config, setConfig, cache, setCache), [
|
||||||
|
modelState.value,
|
||||||
|
config,
|
||||||
|
cache,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return <DataGridCore {...props} grider={grider} display={display} />;
|
||||||
|
}
|
||||||
25
packages/web/src/freetable/FreeTableGrider.ts
Normal file
25
packages/web/src/freetable/FreeTableGrider.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { FreeTableModel } from '@dbgate/datalib';
|
||||||
|
import Grider, { GriderRowStatus } from '../datagrid/Grider';
|
||||||
|
|
||||||
|
export default class FreeTableGrider extends Grider {
|
||||||
|
public model: FreeTableModel;
|
||||||
|
public rows: any[];
|
||||||
|
constructor(public modelState, public dispatchModel) {
|
||||||
|
super();
|
||||||
|
this.model = modelState && modelState.value;
|
||||||
|
this.rows = this.model.rows;
|
||||||
|
}
|
||||||
|
getRowData(index: any) {
|
||||||
|
return this.rows[index];
|
||||||
|
}
|
||||||
|
get rowCount() {
|
||||||
|
return this.rows.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
static factory({ modelState, dispatchModel }): FreeTableGrider {
|
||||||
|
return new FreeTableGrider(modelState, dispatchModel);
|
||||||
|
}
|
||||||
|
static factoryDeps({ modelState, dispatchModel }) {
|
||||||
|
return [modelState, dispatchModel];
|
||||||
|
}
|
||||||
|
}
|
||||||
15
packages/web/src/freetable/useNewFreeTable.js
Normal file
15
packages/web/src/freetable/useNewFreeTable.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import _ from 'lodash';
|
||||||
|
import { useSetOpenedTabs, useCurrentDatabase } from '../utility/globalState';
|
||||||
|
import { openNewTab } from '../utility/common';
|
||||||
|
|
||||||
|
export default function useNewFreeTable() {
|
||||||
|
const setOpenedTabs = useSetOpenedTabs();
|
||||||
|
|
||||||
|
return ({ title = undefined, ...props } = {}) =>
|
||||||
|
openNewTab(setOpenedTabs, {
|
||||||
|
title: title || 'Table',
|
||||||
|
icon: 'freetable.svg',
|
||||||
|
tabComponent: 'FreeTableTab',
|
||||||
|
props: {},
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -57,6 +57,7 @@ export function ExpandIcon({
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const TableIcon = (props) => getIconImage('table2.svg', props);
|
export const TableIcon = (props) => getIconImage('table2.svg', props);
|
||||||
|
export const FreeTableIcon = (props) => getIconImage('freetable.svg', props);
|
||||||
export const ViewIcon = (props) => getIconImage('view2.svg', props);
|
export const ViewIcon = (props) => getIconImage('view2.svg', props);
|
||||||
export const ArchiveTableIcon = (props) => getIconImage('archtable.svg', props);
|
export const ArchiveTableIcon = (props) => getIconImage('archtable.svg', props);
|
||||||
export const DatabaseIcon = (props) => getIconImage('database.svg', props);
|
export const DatabaseIcon = (props) => getIconImage('database.svg', props);
|
||||||
|
|||||||
25
packages/web/src/tabs/FreeTableTab.js
Normal file
25
packages/web/src/tabs/FreeTableTab.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { createGridCache, createChangeSet, createGridConfig, createFreeTableModel } from '@dbgate/datalib';
|
||||||
|
import useUndoReducer from '../utility/useUndoReducer';
|
||||||
|
import usePropsCompare from '../utility/usePropsCompare';
|
||||||
|
import { useUpdateDatabaseForTab } from '../utility/globalState';
|
||||||
|
import TableDataGrid from '../datagrid/TableDataGrid';
|
||||||
|
import useGridConfig from '../utility/useGridConfig';
|
||||||
|
import FreeTableGrid from '../freetable/FreeTableGrid';
|
||||||
|
|
||||||
|
export default function FreeDataTab({ conid, database, schemaName, pureName, tabVisible, toolbarPortalRef, tabid }) {
|
||||||
|
const [config, setConfig] = useGridConfig(tabid);
|
||||||
|
const [modelState, dispatchModel] = useUndoReducer(createFreeTableModel());
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FreeTableGrid
|
||||||
|
conid={conid}
|
||||||
|
config={config}
|
||||||
|
setConfig={setConfig}
|
||||||
|
modelState={modelState}
|
||||||
|
dispatchModel={dispatchModel}
|
||||||
|
tabVisible={tabVisible}
|
||||||
|
// toolbarPortalRef={toolbarPortalRef}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ import QueryTab from './QueryTab';
|
|||||||
import ShellTab from './ShellTab';
|
import ShellTab from './ShellTab';
|
||||||
import InfoPageTab from './InfoPageTab';
|
import InfoPageTab from './InfoPageTab';
|
||||||
import ArchiveFileTab from './ArchiveFileTab';
|
import ArchiveFileTab from './ArchiveFileTab';
|
||||||
|
import FreeTableTab from './FreeTableTab';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
TableDataTab,
|
TableDataTab,
|
||||||
@@ -14,4 +15,5 @@ export default {
|
|||||||
InfoPageTab,
|
InfoPageTab,
|
||||||
ShellTab,
|
ShellTab,
|
||||||
ArchiveFileTab,
|
ArchiveFileTab,
|
||||||
|
FreeTableTab,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import useNewQuery from '../query/useNewQuery';
|
|||||||
import { useConfig } from '../utility/metadataLoaders';
|
import { useConfig } from '../utility/metadataLoaders';
|
||||||
import { useSetOpenedTabs, useOpenedTabs } from '../utility/globalState';
|
import { useSetOpenedTabs, useOpenedTabs } from '../utility/globalState';
|
||||||
import { openNewTab } from '../utility/common';
|
import { openNewTab } from '../utility/common';
|
||||||
|
import useNewFreeTable from '../freetable/useNewFreeTable';
|
||||||
|
|
||||||
const ToolbarContainer = styled.div`
|
const ToolbarContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -16,6 +17,7 @@ const ToolbarContainer = styled.div`
|
|||||||
export default function ToolBar({ toolbarPortalRef }) {
|
export default function ToolBar({ toolbarPortalRef }) {
|
||||||
const modalState = useModalState();
|
const modalState = useModalState();
|
||||||
const newQuery = useNewQuery();
|
const newQuery = useNewQuery();
|
||||||
|
const newFreeTable = useNewFreeTable();
|
||||||
const config = useConfig();
|
const config = useConfig();
|
||||||
const toolbar = config.toolbar || [];
|
const toolbar = config.toolbar || [];
|
||||||
const setOpenedTabs = useSetOpenedTabs();
|
const setOpenedTabs = useSetOpenedTabs();
|
||||||
@@ -74,6 +76,9 @@ export default function ToolBar({ toolbarPortalRef }) {
|
|||||||
<ToolbarButton onClick={newQuery} icon="fas fa-file-alt">
|
<ToolbarButton onClick={newQuery} icon="fas fa-file-alt">
|
||||||
New Query
|
New Query
|
||||||
</ToolbarButton>
|
</ToolbarButton>
|
||||||
|
<ToolbarButton onClick={newFreeTable} icon="fas fa-table">
|
||||||
|
Free table editor
|
||||||
|
</ToolbarButton>
|
||||||
<ToolbarContainer ref={toolbarPortalRef}></ToolbarContainer>
|
<ToolbarContainer ref={toolbarPortalRef}></ToolbarContainer>
|
||||||
</ToolbarContainer>
|
</ToolbarContainer>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user