From 37cce9dd7c5679ee9a2bb4cca980284dab1fb94c Mon Sep 17 00:00:00 2001
From: zxj96 <35951769+zxj96@users.noreply.github.com>
Date: Wed, 21 Aug 2019 20:44:47 +0800
Subject: [PATCH] Update dtable UI (#4009)
* Dtable list page refactoring
* fix code
* fix bug
* fix style
* repair click range
* style
* optimization code
* style
* optimization code
* optimization code
* Variable name
* No Tables replace No tables
---
.../components/dialog/share-table-to-user.js | 2 +-
frontend/src/components/main-side-nav.js | 2 +-
frontend/src/css/dtable-page.css | 48 +++
frontend/src/pages/dtable/dtable.js | 382 +++---------------
frontend/src/pages/dtable/list-table-item.js | 151 +++++++
...ist-share-table.js => share-table-item.js} | 21 +-
frontend/src/pages/dtable/workspace.js | 122 ++++++
7 files changed, 390 insertions(+), 338 deletions(-)
create mode 100644 frontend/src/pages/dtable/list-table-item.js
rename frontend/src/pages/dtable/{list-share-table.js => share-table-item.js} (71%)
create mode 100644 frontend/src/pages/dtable/workspace.js
diff --git a/frontend/src/components/dialog/share-table-to-user.js b/frontend/src/components/dialog/share-table-to-user.js
index 19fdc8f09c..c0a46f6ba5 100644
--- a/frontend/src/components/dialog/share-table-to-user.js
+++ b/frontend/src/components/dialog/share-table-to-user.js
@@ -197,7 +197,7 @@ class ShareTableToUser extends React.Component {
diff --git a/frontend/src/components/main-side-nav.js b/frontend/src/components/main-side-nav.js
index e8210b22fe..56c59840a8 100644
--- a/frontend/src/components/main-side-nav.js
+++ b/frontend/src/components/main-side-nav.js
@@ -199,7 +199,7 @@ class MainSideNav extends React.Component {
{gettext('Database')}
-
- this.tabItemClick('dtable')}>
+ this.tabItemClick(e, 'dtable')}>
DTable
diff --git a/frontend/src/css/dtable-page.css b/frontend/src/css/dtable-page.css
index 0124ae0159..4ba634ba72 100644
--- a/frontend/src/css/dtable-page.css
+++ b/frontend/src/css/dtable-page.css
@@ -53,6 +53,8 @@
}
.workspace .table-heading {
padding: 0.25rem;
+}
+.workspace .table-heading-border {
border-bottom: 1px solid #e6e6e6;
}
.workspace .sf3-font {
@@ -61,4 +63,50 @@
}
.workspace .add-table-range:hover {
background-color: #f8f8f8;
+}
+.workspace .table-item-container {
+ display: flex;
+ justify-content: space-between;
+ flex-wrap: wrap;
+}
+.workspace .table-item-container .table-item {
+ width: 48%;
+ height: 2.5625rem;
+ padding: 0.5rem;
+ justify-content: center;
+ align-items: center;
+ display: flex;
+ border-radius: 4px
+}
+.workspace .table-item .table-icon {
+ width: 9%;
+ height: 100%;
+ display: flex;
+ align-items: center;
+}
+.workspace .table-item .table-name {
+ width: 76%;
+ height: 100%;
+}
+.workspace .table-item .table-dropdown-menu {
+ width: 15%;
+ height: 100%;
+ text-align: right;
+}
+.workspace .table-item .table-dropdown-menu .table-dropdown-menu-icon {
+ width: 24px;
+ height: 24px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+.table-item-more-operation i {
+ color: #999;
+ cursor: pointer;
+}
+.table-item-more-operation a:hover {
+ text-decoration: none;
+}
+.table-item-more-operation i:hover {
+ color: #666;
}
\ No newline at end of file
diff --git a/frontend/src/pages/dtable/dtable.js b/frontend/src/pages/dtable/dtable.js
index 0e626f0606..8a0e8e60d7 100644
--- a/frontend/src/pages/dtable/dtable.js
+++ b/frontend/src/pages/dtable/dtable.js
@@ -1,291 +1,24 @@
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import MediaQuery from 'react-responsive';
-import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem, Button } from 'reactstrap';
-import moment from 'moment';
+import { Button } from 'reactstrap';
import { seafileAPI } from '../../utils/seafile-api';
-import { gettext, siteRoot, username } from '../../utils/constants';
+import { gettext, username } from '../../utils/constants';
import CommonToolbar from '../../components/toolbar/common-toolbar';
import Loading from '../../components/loading';
import CreateTableDialog from '../../components/dialog/create-table-dialog';
-import DeleteTableDialog from '../../components/dialog/delete-table-dialog';
-import ShareTableDialog from '../../components/dialog/share-table-dialog';
-import ShareTableItem from './list-share-table';
-import Rename from '../../components/rename';
+import ShareTableItem from './share-table-item';
+import Workspace from './workspace';
import '../../css/dtable-page.css';
-moment.locale(window.app.config.lang);
-
-
-const tablePropTypes = {
- table: PropTypes.object.isRequired,
- workspaceID: PropTypes.number.isRequired,
- renameTable: PropTypes.func.isRequired,
- deleteTable: PropTypes.func.isRequired,
- onUnfreezedItem: PropTypes.func.isRequired,
- onFreezedItem: PropTypes.func.isRequired,
- isItemFreezed: PropTypes.bool.isRequired,
-};
-
-class Table extends Component {
-
- constructor(props) {
- super(props);
- this.state = {
- isTableRenaming: false,
- isTableDeleting: false,
- isTableSharing: false,
- dropdownOpen: false,
- active: false,
- };
- }
-
- onRenameTableCancel = () => {
- this.setState({isTableRenaming: !this.state.isTableRenaming});
- this.props.onUnfreezedItem();
- }
-
- onRenameTableConfirm = (newTableName) => {
- let oldTableName = this.props.table.name;
- this.props.renameTable(oldTableName, newTableName);
- this.onRenameTableCancel();
- }
-
- onDeleteTableCancel = () => {
- this.setState({isTableDeleting: !this.state.isTableDeleting});
- this.props.onUnfreezedItem();
- }
-
- onDeleteTableSubmit = () => {
- let tableName = this.props.table.name;
- this.props.deleteTable(tableName);
- this.onDeleteTableCancel();
- }
-
- onShareTableCancel = () => {
- this.setState({isTableSharing: !this.state.isTableSharing});
- this.props.onUnfreezedItem();
- }
-
- dropdownToggle = () => {
- if (this.state.dropdownOpen) {
- this.props.onUnfreezedItem();
- } else {
- this.props.onFreezedItem();
- }
- this.setState({ dropdownOpen: !this.state.dropdownOpen });
- }
-
- onMouseEnter = () => {
- if (this.props.isItemFreezed) return;
- this.setState({
- active: true
- });
- }
-
- onMouseLeave = () => {
- if (this.props.isItemFreezed) return;
- this.setState({
- active: false
- });
- }
-
- componentWillReceiveProps(nextProps) {
- if (!nextProps.isItemFreezed) {
- this.setState({ active: false });
- }
- }
-
- render() {
-
- let table = this.props.table;
- let tableHref = siteRoot + 'workspace/' + this.props.workspaceID + '/dtable/' + table.name + '/';
-
- return (
-
- |
-
- {this.state.isTableRenaming &&
-
- }
- {!this.state.isTableRenaming &&
- {table.name}
- }
- |
- {table.modifier} |
- {moment(table.updated_at).fromNow()} |
-
- {this.state.active &&
-
-
-
-
- {gettext('Rename')}
- {gettext('Delete')}
- {gettext('Share')}
-
-
- }
- {this.state.isTableDeleting &&
-
- }
- {this.state.isTableSharing &&
-
- }
- |
-
- );
- }
-}
-
-Table.propTypes = tablePropTypes;
-
-
-const workspacePropTypes = {
- workspace: PropTypes.object.isRequired,
- setCurrentWorkspace: PropTypes.func.isRequired,
- onAddDTable: PropTypes.func.isRequired,
-};
-
-class Workspace extends Component {
-
- constructor(props) {
- super(props);
- this.state = {
- tableList: this.props.workspace.table_list,
- errorMsg: '',
- isItemFreezed: false,
- };
- }
-
- onFreezedItem = () => {
- this.setState({isItemFreezed: true});
- }
-
- onUnfreezedItem = () => {
- this.setState({isItemFreezed: false});
- }
-
- renameTable = (oldTableName, newTableName) => {
- let workspaceID = this.props.workspace.id;
- seafileAPI.renameTable(workspaceID, oldTableName, newTableName).then((res) => {
- let tableList = this.state.tableList.map((table) => {
- if (table.name === oldTableName) {
- table = res.data.table;
- }
- return table;
- });
- this.setState({tableList: tableList});
- }).catch((error) => {
- if(error.response) {
- this.setState({errorMsg: gettext('Error')});
- }
- });
- }
-
- deleteTable = (tableName) => {
- let workspaceID = this.props.workspace.id;
- seafileAPI.deleteTable(workspaceID, tableName).then(() => {
- let tableList = this.state.tableList.filter(table => {
- return table.name !== tableName;
- });
- this.setState({tableList: tableList});
- }).catch((error) => {
- if(error.response) {
- this.setState({errorMsg: gettext('Error')});
- }
- });
- }
-
- addTable = (e) => {
- e.preventDefault();
- this.props.setCurrentWorkspace(this.props.workspace);
- this.props.onAddDTable();
- }
-
- componentWillReceiveProps(nextProps) {
- if (nextProps.workspace.table_list !== this.props.workspace.table_list) {
- this.setState({
- tableList: nextProps.workspace.table_list
- });
- }
- }
-
- render() {
- let workspace = this.props.workspace;
- let isPersonal = workspace.owner_type === 'Personal';
- let { tableList, isItemFreezed } = this.state;
-
- return(
-
-
{isPersonal ? gettext('My Tables') : workspace.owner_name}
- {tableList.length > 0 ?
-
- :
-
-
- {gettext('No tables')} |
-
-
- }
-
- );
- }
-}
-
-Workspace.propTypes = workspacePropTypes;
-
-
-const dtablePropTypes = {
+const propTypes = {
onShowSidePanel: PropTypes.func.isRequired,
onSearchedClick: PropTypes.func.isRequired,
};
class DTable extends Component {
+
constructor(props) {
super(props);
this.state = {
@@ -299,10 +32,26 @@ class DTable extends Component {
};
}
+ componentDidMount() {
+ this.listWorkspaces();
+ this.listSharedTables();
+ }
+
onAddDTable = () => {
this.setState({ isShowAddDTableDialog: !this.state.isShowAddDTableDialog });
}
+ newDtable = () => {
+ if (this.state.currentWorkspace) {
+ this.setState({ currentWorkspace: null });
+ }
+ this.onAddDTable();
+ }
+
+ setCurrentWorkspace = (currentWorkspace) => {
+ this.setState({ currentWorkspace: currentWorkspace });
+ }
+
createDTable = (tableName, owner) => {
seafileAPI.createTable(tableName, owner).then(() => {
this.listWorkspaces();
@@ -354,7 +103,7 @@ class DTable extends Component {
});
}
});
- };
+ }
leaveShareTable = (table) => {
let email = username;
@@ -374,56 +123,42 @@ class DTable extends Component {
});
}
});
- };
-
- setCurrentWorkspace = (currentWorkspace) => {
- this.setState({ currentWorkspace: currentWorkspace });
- }
-
- componentDidMount() {
- this.listWorkspaces();
- this.listSharedTables();
}
renderShareTablePanel = () => {
return (
{gettext('Shared with me')}
-
-
-
-
-
- {this.state.shareTableList.map((table, index) => {
- return (
-
- );
- })}
-
-
+
+ {this.state.shareTableList.map((table, index) => {
+ return (
+
+ );
+ })}
+
);
- };
-
- newDtable = () => {
- if (this.state.currentWorkspace) {
- this.setState({ currentWorkspace: null });
- }
- this.onAddDTable();
}
render() {
- let personalWorkspace = this.state.workspaceList.filter(workspace => {
+ const { workspaceList, loading } = this.state;
+
+ let personalWorkspaceList = workspaceList.filter(workspace => {
return workspace.owner_type === 'Personal';
- }).pop();
- let groupWorkspaceList = this.state.workspaceList.filter(workspace => {
+ });
+ let personalWorkspaceMessage = personalWorkspaceList[0];
+ let groupWorkspaceList = workspaceList.filter(workspace => {
return workspace.owner_type === 'Group';
});
+ if (loading) {
+ return();
+ }
+
return (
@@ -448,21 +183,18 @@ class DTable extends Component {
DTable
- {this.state.loading &&
}
- {(!this.state.loading && this.state.errorMsg) &&
+ {this.state.errorMsg &&
{this.state.errorMsg}
}
- {!this.state.loading &&
- }
{(!this.state.shareTableLoading && this.state.shareTableList.length > 0) &&
- this.renderShareTablePanel()
+ this.renderShareTablePanel()
}
- {!this.state.loading &&
+ {
groupWorkspaceList.map((workspace, index) => {
return (
-
-
+ {this.state.isShowAddDTableDialog &&
+
+
+
}
@@ -491,6 +223,6 @@ class DTable extends Component {
}
}
-DTable.propTypes = dtablePropTypes;
+DTable.propTypes = propTypes;
export default DTable;
diff --git a/frontend/src/pages/dtable/list-table-item.js b/frontend/src/pages/dtable/list-table-item.js
new file mode 100644
index 0000000000..6d2497433b
--- /dev/null
+++ b/frontend/src/pages/dtable/list-table-item.js
@@ -0,0 +1,151 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap';
+import { gettext, siteRoot } from '../../utils/constants';
+import DeleteTableDialog from '../../components/dialog/delete-table-dialog';
+import ShareTableDialog from '../../components/dialog/share-table-dialog';
+import Rename from '../../components/rename';
+
+const propTypes = {
+ table: PropTypes.object.isRequired,
+ workspaceID: PropTypes.number.isRequired,
+ renameTable: PropTypes.func.isRequired,
+ deleteTable: PropTypes.func.isRequired,
+ onUnfreezedItem: PropTypes.func.isRequired,
+ onFreezedItem: PropTypes.func.isRequired,
+ isItemFreezed: PropTypes.bool.isRequired,
+};
+
+class ListTableItem extends React.Component {
+
+ constructor(props) {
+ super(props);
+ this.state = {
+ isTableRenaming: false,
+ isTableDeleting: false,
+ isTableSharing: false,
+ dropdownOpen: false,
+ active: false,
+ };
+ }
+
+ componentWillReceiveProps(nextProps) {
+ if (!nextProps.isItemFreezed) {
+ this.setState({ active: false });
+ }
+ }
+
+ onMouseEnter = () => {
+ if (!this.props.isItemFreezed) {
+ this.setState({
+ active: true
+ });
+ }
+ }
+
+ onMouseLeave = () => {
+ if (!this.props.isItemFreezed) {
+ this.setState({
+ active: false
+ });
+ }
+ }
+
+ onRenameTableCancel = () => {
+ this.setState({isTableRenaming: !this.state.isTableRenaming});
+ this.props.onUnfreezedItem();
+ }
+
+ onRenameTableConfirm = (newTableName) => {
+ let oldTableName = this.props.table.name;
+ this.props.renameTable(oldTableName, newTableName);
+ this.onRenameTableCancel();
+ }
+
+ onDeleteTableCancel = () => {
+ this.setState({isTableDeleting: !this.state.isTableDeleting});
+ this.props.onUnfreezedItem();
+ }
+
+ onDeleteTableSubmit = () => {
+ let tableName = this.props.table.name;
+ this.props.deleteTable(tableName);
+ this.onDeleteTableCancel();
+ }
+
+ onShareTableCancel = () => {
+ this.setState({isTableSharing: !this.state.isTableSharing});
+ this.props.onUnfreezedItem();
+ }
+
+ dropdownToggle = () => {
+ if (this.state.dropdownOpen) {
+ this.props.onUnfreezedItem();
+ } else {
+ this.props.onFreezedItem();
+ }
+ this.setState({ dropdownOpen: !this.state.dropdownOpen });
+ }
+
+ render() {
+
+ let table = this.props.table;
+ let tableHref = siteRoot + 'workspace/' + this.props.workspaceID + '/dtable/' + table.name + '/';
+
+ return (
+
+
+
+ {this.state.isTableRenaming &&
+
+ }
+ {!this.state.isTableRenaming &&
+
{table.name}
+ }
+
+
+ {this.state.active &&
+
+
+
+
+ {gettext('Rename')}
+ {gettext('Delete')}
+ {gettext('Share')}
+
+
+ }
+ {this.state.isTableDeleting &&
+
+ }
+ {this.state.isTableSharing &&
+
+ }
+
+
+ );
+ }
+}
+
+ListTableItem.propTypes = propTypes;
+
+export default ListTableItem;
+
diff --git a/frontend/src/pages/dtable/list-share-table.js b/frontend/src/pages/dtable/share-table-item.js
similarity index 71%
rename from frontend/src/pages/dtable/list-share-table.js
rename to frontend/src/pages/dtable/share-table-item.js
index e4c481d4a7..8734348567 100644
--- a/frontend/src/pages/dtable/list-share-table.js
+++ b/frontend/src/pages/dtable/share-table-item.js
@@ -1,11 +1,9 @@
import React, {Component} from 'react';
import PropTypes from 'prop-types';
-import moment from 'moment';
import {gettext, siteRoot} from '../../utils/constants';
import '../../css/dtable-page.css';
-
const shareTableItemPropTypes = {
table: PropTypes.object.isRequired,
leaveShareTable: PropTypes.func.isRequired,
@@ -42,24 +40,25 @@ class ShareTableItem extends Component {
let tableHref = siteRoot + 'workspace/' + table.workspace_id + '/dtable/' + table.name + '/';
return (
-
- |
- {table.name} |
- {table.from_user_name} |
- {moment(table.updated_at).fromNow()} |
-
+
+ |
-
+
+
);
}
}
ShareTableItem.propTypes = shareTableItemPropTypes;
-export default ShareTableItem;
+export default ShareTableItem;
\ No newline at end of file
diff --git a/frontend/src/pages/dtable/workspace.js b/frontend/src/pages/dtable/workspace.js
new file mode 100644
index 0000000000..886846575f
--- /dev/null
+++ b/frontend/src/pages/dtable/workspace.js
@@ -0,0 +1,122 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { seafileAPI } from '../../utils/seafile-api';
+import { gettext } from '../../utils/constants';
+import ListTableItem from './list-table-item';
+
+const propTypes = {
+ workspace: PropTypes.object.isRequired,
+ setCurrentWorkspace: PropTypes.func.isRequired,
+ onAddDTable: PropTypes.func.isRequired,
+};
+
+class Workspace extends React.Component {
+
+ constructor(props) {
+ super(props);
+ this.state = {
+ tableList: props.workspace.table_list,
+ errorMsg: '',
+ isItemFreezed: false,
+ };
+ }
+
+ componentWillReceiveProps(nextProps) {
+ if (nextProps.workspace.table_list !== this.props.workspace.table_list) {
+ this.setState({
+ tableList: nextProps.workspace.table_list
+ });
+ }
+ }
+
+ onFreezedItem = () => {
+ this.setState({isItemFreezed: true});
+ }
+
+ onUnfreezedItem = () => {
+ this.setState({isItemFreezed: false});
+ }
+
+ renameTable = (oldTableName, newTableName) => {
+ let workspaceID = this.props.workspace.id;
+ seafileAPI.renameTable(workspaceID, oldTableName, newTableName).then((res) => {
+ let tableList = this.state.tableList.map((table) => {
+ if (table.name === oldTableName) {
+ table = res.data.table;
+ }
+ return table;
+ });
+ this.setState({tableList: tableList});
+ }).catch((error) => {
+ if(error.response) {
+ this.setState({errorMsg: gettext('Error')});
+ }
+ });
+ }
+
+ deleteTable = (tableName) => {
+ let workspaceID = this.props.workspace.id;
+ seafileAPI.deleteTable(workspaceID, tableName).then(() => {
+ let tableList = this.state.tableList.filter(table => {
+ return table.name !== tableName;
+ });
+ this.setState({tableList: tableList});
+ }).catch((error) => {
+ if(error.response) {
+ this.setState({errorMsg: gettext('Error')});
+ }
+ });
+ }
+
+ addTable = (e) => {
+ e.preventDefault();
+ this.props.setCurrentWorkspace(this.props.workspace);
+ this.props.onAddDTable();
+ }
+
+ render() {
+ let workspace = this.props.workspace;
+ let isPersonal = workspace.owner_type === 'Personal';
+ let { tableList, isItemFreezed } = this.state;
+
+ return(
+
+
0 ? '' : 'table-heading-border'}`}>{isPersonal ? gettext('My Tables') : workspace.owner_name}
+ {tableList.length > 0 ?
+
+ {tableList.map((table, index) => {
+ return (
+
+ );
+ })}
+
+
+ :
+
+
+ {gettext('No Tables')} |
+
+
+ }
+
+ );
+ }
+
+}
+
+Workspace.propTypes = propTypes;
+
+export default Workspace;
\ No newline at end of file