mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-24 00:16:00 +00:00
table structure tab WIP
This commit is contained in:
@@ -17,11 +17,13 @@ const IconWrap = styled.span`
|
||||
`;
|
||||
|
||||
export function AppObjectCore({ title, Icon, Menu, data, makeAppObj, onClick }) {
|
||||
const setOpenedTabs = useSetOpenedTabs();
|
||||
|
||||
const handleContextMenu = event => {
|
||||
if (!Menu) return;
|
||||
|
||||
event.preventDefault();
|
||||
showMenu(event.pageX, event.pageY, <Menu data={data} makeAppObj={makeAppObj} />);
|
||||
showMenu(event.pageX, event.pageY, <Menu data={data} makeAppObj={makeAppObj} setOpenedTabs={setOpenedTabs} />);
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
17
web/src/appobj/columnAppObject.js
Normal file
17
web/src/appobj/columnAppObject.js
Normal file
@@ -0,0 +1,17 @@
|
||||
import React from 'react';
|
||||
import { TableIcon } from '../icons';
|
||||
import { DropDownMenuItem } from '../modals/DropDownMenu';
|
||||
import showModal from '../modals/showModal';
|
||||
import ConnectionModal from '../modals/ConnectionModal';
|
||||
import axios from '../utility/axios';
|
||||
import { openNewTab } from '../utility/common';
|
||||
import { useSetOpenedTabs } from '../utility/globalState';
|
||||
|
||||
/** @param columnProps {import('@dbgate/lib').ColumnInfo} */
|
||||
export default function columnAppObject(columnProps, { setOpenedTabs }) {
|
||||
const title = columnProps.columnName;
|
||||
const key = title;
|
||||
const Icon = TableIcon;
|
||||
|
||||
return { title, key, Icon };
|
||||
}
|
||||
@@ -5,18 +5,33 @@ import showModal from '../modals/showModal';
|
||||
import ConnectionModal from '../modals/ConnectionModal';
|
||||
import axios from '../utility/axios';
|
||||
import { openNewTab } from '../utility/common';
|
||||
import { useSetOpenedTabs } from '../utility/globalState';
|
||||
|
||||
function Menu({ data, makeAppObj }) {
|
||||
const handleEdit = () => {
|
||||
showModal(modalState => <ConnectionModal modalState={modalState} connection={data} />);
|
||||
function openTableDetail(setOpenedTabs, tabComponent, { schemaName, pureName, conid, database }) {
|
||||
openNewTab(setOpenedTabs, {
|
||||
title: pureName,
|
||||
icon: 'table2.svg',
|
||||
tabComponent,
|
||||
props: {
|
||||
schemaName,
|
||||
pureName,
|
||||
conid,
|
||||
database,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function Menu({ data, makeAppObj, setOpenedTabs }) {
|
||||
const handleOpenData = () => {
|
||||
openTableDetail(setOpenedTabs, 'TableDataTab', data);
|
||||
};
|
||||
const handleDelete = () => {
|
||||
axios.post('connections/delete', data);
|
||||
const handleOpenStructure = () => {
|
||||
openTableDetail(setOpenedTabs, 'TableStructureTab', data);
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<DropDownMenuItem onClick={handleEdit}>Edit</DropDownMenuItem>
|
||||
<DropDownMenuItem onClick={handleDelete}>Delete</DropDownMenuItem>
|
||||
<DropDownMenuItem onClick={handleOpenData}>Open data</DropDownMenuItem>
|
||||
<DropDownMenuItem onClick={handleOpenStructure}>Open structure</DropDownMenuItem>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -26,16 +41,11 @@ export default function tableAppObject({ conid, database, pureName, schemaName }
|
||||
const key = title;
|
||||
const Icon = TableIcon;
|
||||
const onClick = ({ schemaName, pureName }) => {
|
||||
openNewTab(setOpenedTabs, {
|
||||
title: pureName,
|
||||
icon: 'table2.svg',
|
||||
tabComponent: 'TableDataTab',
|
||||
props: {
|
||||
schemaName,
|
||||
pureName,
|
||||
conid,
|
||||
database,
|
||||
},
|
||||
openTableDetail(setOpenedTabs, 'TableDataTab', {
|
||||
schemaName,
|
||||
pureName,
|
||||
conid,
|
||||
database,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
font-family: -apple-system,BlinkMacSystemFont,Segoe WPC,Segoe UI,HelveticaNeue-Light,Ubuntu,Droid Sans,sans-serif;
|
||||
font-size: 14px;
|
||||
/* font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
sans-serif;
|
||||
*/
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
78
web/src/tabs/TableStructureTab.js
Normal file
78
web/src/tabs/TableStructureTab.js
Normal file
@@ -0,0 +1,78 @@
|
||||
import React from 'react';
|
||||
import useFetch from '../utility/useFetch';
|
||||
import styled from 'styled-components';
|
||||
import theme from '../theme';
|
||||
import ObjectListControl from '../utility/ObjectListControl';
|
||||
import { TableColumn } from '../utility/TableControl';
|
||||
|
||||
const WhitePage = styled.div`
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: white;
|
||||
`;
|
||||
|
||||
export default function TableStructureTab({ conid, database, schemaName, pureName }) {
|
||||
/** @type {import('@dbgate/lib').TableInfo} */
|
||||
const tableInfo = useFetch({
|
||||
url: 'tables/table-info',
|
||||
params: { conid, database, schemaName, pureName },
|
||||
});
|
||||
if (!tableInfo) return null;
|
||||
return (
|
||||
<WhitePage>
|
||||
<ObjectListControl
|
||||
collection={tableInfo.columns.map((x, index) => ({ ...x, ordinal: index + 1 }))}
|
||||
title="Columns"
|
||||
>
|
||||
<TableColumn
|
||||
fieldName="notNull"
|
||||
header="Not NULL"
|
||||
sortable={true}
|
||||
formatter={row => (row.notNull ? 'YES' : 'NO')}
|
||||
/>
|
||||
<TableColumn fieldName="dataType" header="Data Type" sortable={true} />
|
||||
<TableColumn fieldName="defaultValue" header="Default value" sortable={true} />
|
||||
<TableColumn
|
||||
fieldName="isSparse"
|
||||
header="Is Sparse"
|
||||
sortable={true}
|
||||
formatter={row => (row.isSparse ? 'YES' : 'NO')}
|
||||
/>
|
||||
<TableColumn fieldName="computedExpression" header="Computed Expression" sortable={true} />
|
||||
<TableColumn
|
||||
fieldName="isPersisted"
|
||||
header="Is Persisted"
|
||||
sortable={true}
|
||||
formatter={row => (row.isPersisted ? 'YES' : 'NO')}
|
||||
/>
|
||||
{/* {_.includes(dbCaps.columnListOptionalColumns, 'referencedTableNamesFormatted') && (
|
||||
<TableColumn fieldName="referencedTableNamesFormatted" header="References" sortable={true} />
|
||||
)}
|
||||
<TableColumn
|
||||
fieldName="actions"
|
||||
header=""
|
||||
formatter={row => (
|
||||
<span>
|
||||
<Link
|
||||
linkElementId={encodeHtmlId(`button_delete_column_${row.column.name}`)}
|
||||
onClick={() => this.deleteColumn(row)}
|
||||
>
|
||||
Delete
|
||||
</Link>{' '}
|
||||
|{' '}
|
||||
<Link
|
||||
linkElementId={encodeHtmlId(`button_edit_column__${row.column.name}`)}
|
||||
onClick={() => this.editColumn(row)}
|
||||
>
|
||||
Edit
|
||||
</Link>
|
||||
</span>
|
||||
)}
|
||||
/> */}
|
||||
</ObjectListControl>
|
||||
</WhitePage>
|
||||
);
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
import TableDataTab from './TableDataTab';
|
||||
import TableStructureTab from './TableStructureTab';
|
||||
|
||||
export default {
|
||||
TableDataTab,
|
||||
TableStructureTab,
|
||||
};
|
||||
|
||||
41
web/src/utility/ObjectListControl.js
Normal file
41
web/src/utility/ObjectListControl.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import React from 'react';
|
||||
import useFetch from '../utility/useFetch';
|
||||
import styled from 'styled-components';
|
||||
import theme from '../theme';
|
||||
import TableControl from './TableControl';
|
||||
|
||||
const ObjectListWrapper = styled.div`
|
||||
margin-bottom: 20px;
|
||||
`;
|
||||
|
||||
const ObjectListHeader = styled.div`
|
||||
background-color: #ebedef;
|
||||
padding: 5px;
|
||||
`;
|
||||
|
||||
const ObjectListHeaderTitle = styled.span`
|
||||
font-weight: bold;
|
||||
margin-left: 5px;
|
||||
`;
|
||||
|
||||
const ObjectListBody = styled.div`
|
||||
margin: 20px;
|
||||
// margin-left: 20px;
|
||||
// margin-right: 20px;
|
||||
// margin-top: 3px;
|
||||
`;
|
||||
|
||||
export default function ObjectListControl({ collection = [], title, showIfEmpty = false, children }) {
|
||||
if (collection.length == 0 && !showIfEmpty) return null;
|
||||
|
||||
return (
|
||||
<ObjectListWrapper>
|
||||
<ObjectListHeader>
|
||||
<ObjectListHeaderTitle>{title}</ObjectListHeaderTitle>
|
||||
</ObjectListHeader>
|
||||
<ObjectListBody>
|
||||
<TableControl rows={collection}>{children}</TableControl>
|
||||
</ObjectListBody>
|
||||
</ObjectListWrapper>
|
||||
);
|
||||
}
|
||||
59
web/src/utility/TableControl.js
Normal file
59
web/src/utility/TableControl.js
Normal file
@@ -0,0 +1,59 @@
|
||||
import React from 'react';
|
||||
import useFetch from '../utility/useFetch';
|
||||
import styled from 'styled-components';
|
||||
import theme from '../theme';
|
||||
|
||||
const Table = styled.table`
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
`;
|
||||
const TableHead = styled.thead``;
|
||||
const TableBody = styled.tbody``;
|
||||
const TableHeaderRow = styled.tr``;
|
||||
const TableBodyRow = styled.tr``;
|
||||
const TableHeaderCell = styled.td`
|
||||
border: 1px solid #e8eef4;
|
||||
background-color: #e8eef4;
|
||||
padding: 5px;
|
||||
`;
|
||||
const TableBodyCell = styled.td`
|
||||
border: 1px solid #e8eef4;
|
||||
padding: 5px;
|
||||
`;
|
||||
|
||||
export function TableColumn({ fieldName, header, sortable, formatter = undefined }) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
function format(row, col) {
|
||||
const { formatter, fieldName } = col;
|
||||
if (formatter) return formatter(row);
|
||||
return row[fieldName];
|
||||
}
|
||||
|
||||
export default function TableControl({ rows = [], children }) {
|
||||
const columns = (children instanceof Array ? children : [children])
|
||||
.filter(child => child != null)
|
||||
.map(child => child.props);
|
||||
|
||||
return (
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableHeaderRow>
|
||||
{columns.map(x => (
|
||||
<TableHeaderCell key={x.fieldName}>{x.header}</TableHeaderCell>
|
||||
))}
|
||||
</TableHeaderRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{rows.map((row, index) => (
|
||||
<TableBodyRow key={index}>
|
||||
{columns.map(col => (
|
||||
<TableBodyCell key={col.fieldName}>{format(row, col)}</TableBodyCell>
|
||||
))}
|
||||
</TableBodyRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user