diff --git a/web-react/src/assets/style/lib/list.less b/web-react/src/assets/style/lib/list.less
index f8a937f..2dbb2de 100644
--- a/web-react/src/assets/style/lib/list.less
+++ b/web-react/src/assets/style/lib/list.less
@@ -26,7 +26,7 @@
}
}
}
- >.ant-pagination {
+ .ant-pagination {
margin: @padding-md 0;
}
.ant-descriptions {
@@ -44,6 +44,14 @@
}
}
}
+ &--scroll {
+ position: relative;
+
+ overflow-x: auto;
+ }
+ .ant-list-items {
+ min-width: 1000px;
+ }
.ant-list-item {
transition: @animation-duration-slow;
transition-property: background, border-bottom-color;
@@ -52,4 +60,36 @@
background: linear-gradient(90deg, transparent 10%, @background-color-light 70%, transparent);
}
}
+ &-container {
+ position: relative;
+ &::before,
+ &::after {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ z-index: 3;
+
+ width: 30px;
+
+ content: '';
+ transition: box-shadow @animation-duration-slow;
+ pointer-events: none;
+ }
+ &::before {
+ left: 0;
+ }
+ &::after {
+ right: 0;
+ }
+ &.yo-list--ping-left {
+ &::before {
+ box-shadow: inset 10px 0 8px -8px fade(@black, 15%);
+ }
+ }
+ &.yo-list--ping-right {
+ &::after {
+ box-shadow: inset -10px 0 8px -8px fade(@black, 15%);
+ }
+ }
+ }
}
diff --git a/web-react/src/assets/style/lib/table.less b/web-react/src/assets/style/lib/table.less
index 9bde634..6ed273f 100644
--- a/web-react/src/assets/style/lib/table.less
+++ b/web-react/src/assets/style/lib/table.less
@@ -22,6 +22,14 @@
}
}
}
+.ant-table {
+ .ant-table-container {
+ &::before,
+ &::after {
+ z-index: 3;
+ }
+ }
+}
.ant-table-thead {
th.ant-table-column-has-sorters {
&:hover {
diff --git a/web-react/src/assets/style/lib/tree-layout.less b/web-react/src/assets/style/lib/tree-layout.less
index 4b1cc97..a54090a 100644
--- a/web-react/src/assets/style/lib/tree-layout.less
+++ b/web-react/src/assets/style/lib/tree-layout.less
@@ -19,6 +19,20 @@
}
}
}
+ &--collapsed {
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ z-index: 4;
+
+ transform: translateX(-100%);
+ &.open {
+ transform: translateX(0);
+
+ box-shadow: 2px 0 8px fade(@black , 20%);
+ }
+ }
&--bar {
line-height: 20px;
diff --git a/web-react/src/components/query-list/index.jsx b/web-react/src/components/query-list/index.jsx
index e623731..c052306 100644
--- a/web-react/src/components/query-list/index.jsx
+++ b/web-react/src/components/query-list/index.jsx
@@ -43,6 +43,8 @@ export default class QueryList extends Component {
state = {
loading: false,
dataSource: [],
+
+ ping: [],
}
// 查询表单实例
@@ -91,6 +93,12 @@ export default class QueryList extends Component {
if (this.autoLoad) {
this.onLoadData()
}
+
+ window.addEventListener('resize', this.onResizeScroll)
+ }
+
+ componentWillUnmount() {
+ window.removeEventListener('resize', this.onResizeScroll)
}
/**
@@ -108,9 +116,14 @@ export default class QueryList extends Component {
this.query
)
- this.setState({
- dataSource: res.rows || res.data || res.items,
- })
+ this.setState(
+ {
+ dataSource: res.rows || res.data || res.items,
+ },
+ () => {
+ this.onResizeScroll()
+ }
+ )
this.pagination.total = res.totalCount
@@ -174,7 +187,26 @@ export default class QueryList extends Component {
this.onLoadData()
}
+ onResizeScroll = () => {
+ this.onListScrollX({ target: this.refs['scroll-x'] })
+ }
+
+ onListScrollX(e) {
+ const { offsetWidth, scrollWidth, scrollLeft } = e.target
+ const ping = []
+ if (offsetWidth + scrollLeft < scrollWidth && scrollLeft > 0) {
+ ping.push(...['left', 'right'])
+ } else if (offsetWidth + scrollLeft < scrollWidth) {
+ ping.push('right')
+ } else if (offsetWidth + scrollLeft >= scrollWidth && offsetWidth < scrollWidth) {
+ ping.push('left')
+ }
+ this.setState({ ping })
+ }
+
render() {
+ const { loading, dataSource, ping } = this.state
+
const attrs = {}
Object.keys(this.props).forEach(key => {
if (!propsMap.includes(key)) {
@@ -206,9 +238,21 @@ export default class QueryList extends Component {
-
}>
-
- {!!this.state.dataSource && !!this.state.dataSource.length && (
+
}>
+
`yo-list--ping-${p}`)]
+ .filter(p => p)
+ .join(' ')}
+ >
+
this.onListScrollX(e)}
+ >
+
+
+
+ {!!dataSource && !!dataSource.length && (
-1) {
- return <>
- {title.substr(0, title.indexOf(this.state.searchValue))}
- {this.state.searchValue}
- {title.substr(title.indexOf(this.state.searchValue) + this.state.searchValue.length)}
- >
+ return (
+ <>
+ {title.substr(0, title.indexOf(this.state.searchValue))}
+ {this.state.searchValue}
+ {title.substr(
+ title.indexOf(this.state.searchValue) + this.state.searchValue.length
+ )}
+ >
+ )
}
return <>{title}>
}
function renderBreadcrumbItem() {
-
const path = ['顶级']
const findPath = (data, level) => {
@@ -91,14 +95,16 @@ function renderBreadcrumbItem() {
}
export default class QueryTreeLayout extends Component {
-
state = {
loading: false,
dataSource: [],
expandedKeys: [],
selectedKey: '',
autoExpandParent: true,
- searchValue: ''
+ searchValue: '',
+
+ collapsed: false,
+ showSider: false,
}
list = []
@@ -108,16 +114,18 @@ export default class QueryTreeLayout extends Component {
replaceFields = {
value: 'id',
title: 'title',
- children: 'children'
+ children: 'children',
}
constructor(props) {
super(props)
this.autoLoad = typeof this.props.autoLoad === 'boolean' ? this.props.autoLoad : true
- this.loadData = typeof this.props.loadData === 'function' ? this.props.loadData : async () => { }
+ this.loadData =
+ typeof this.props.loadData === 'function' ? this.props.loadData : async () => {}
- this.defaultExpanded = typeof this.props.defaultExpanded === 'boolean' ? this.props.defaultExpanded : false
+ this.defaultExpanded =
+ typeof this.props.defaultExpanded === 'boolean' ? this.props.defaultExpanded : false
if (this.props.replaceFields) {
this.replaceFields = this.props.replaceFields
@@ -131,6 +139,13 @@ export default class QueryTreeLayout extends Component {
if (this.autoLoad) {
this.onLoadData()
}
+
+ window.addEventListener('resize', this.onResizeLayout)
+ this.onResizeLayout()
+ }
+
+ componentWillUnmount() {
+ window.removeEventListener('resize', this.onResizeLayout)
}
/**
@@ -151,7 +166,7 @@ export default class QueryTreeLayout extends Component {
}
this.setState({
dataSource: data,
- expandedKeys
+ expandedKeys,
})
this.onLoaded()
}
@@ -162,8 +177,8 @@ export default class QueryTreeLayout extends Component {
onLoading = () => {
this.setState({
loading: {
- indicator:
- }
+ indicator: ,
+ },
})
}
@@ -178,28 +193,28 @@ export default class QueryTreeLayout extends Component {
this.onLoadData()
}
- onExpand = (expandedKeys) => {
+ onExpand = expandedKeys => {
this.setState({
expandedKeys,
- autoExpandParent: false
+ autoExpandParent: false,
})
}
- onSelect = (selectedKeys) => {
+ onSelect = selectedKeys => {
const selectedIds = []
selectedKeys.forEach(p => {
const data = this.list.find(m => m.key === p)
selectedIds.push(data[this.replaceFields.value])
})
this.setState({
- selectedKey: selectedIds[0]
+ selectedKey: selectedIds[0],
})
if (this.props.onSelect) {
this.props.onSelect(selectedIds[0])
}
}
- onSearch = (value) => {
+ onSearch = value => {
const expandedKeys = this.list
.map(p => {
if (p[this.replaceFields.title].indexOf(value) > -1) {
@@ -212,34 +227,49 @@ export default class QueryTreeLayout extends Component {
this.setState({
expandedKeys,
autoExpandParent: !!value,
- searchValue: value
+ searchValue: value,
+ })
+ }
+
+ onResizeLayout = () => {
+ this.setState({
+ collapsed: window.innerWidth <= SIDER_BREAK_POINT,
})
}
render() {
-
- const { dataSource, expandedKeys, autoExpandParent } = this.state
+ const { loading, dataSource, expandedKeys, autoExpandParent, collapsed, showSider } =
+ this.state
const props = {
treeData: dataSource,
expandedKeys,
- autoExpandParent
+ autoExpandParent,
}
const on = {
- onExpand: (expandedKeys) => this.onExpand(expandedKeys),
- onSelect: (selectedKeys) => this.onSelect(selectedKeys)
+ onExpand: expandedKeys => this.onExpand(expandedKeys),
+ onSelect: selectedKeys => this.onSelect(selectedKeys),
}
return (
-
+ p)
+ .join(' ')}
+ onMouseLeave={() => this.setState({ showSider: false })}
+ >
this.onSearch(value)}
+ onSearch={value => this.onSearch(value)}
/>
@@ -248,37 +278,56 @@ export default class QueryTreeLayout extends Component {
this.onReloadData()} />
- this.setState({ expandedKeys: [] })} />
+ this.setState({ expandedKeys: [] })}
+ />
-
} wrapperClassName="h-100-p">
- {
- !this.state.loading && !this.state.dataSource.length ?
-
-
- 暂无数据
-
- }
- description={false}
- />
- :
- renderTitle.call(this, nodeData)}
- />
- }
+ }
+ wrapperClassName="h-100-p"
+ >
+ {!loading && !dataSource.length ? (
+
+
+ 暂无数据
+
+ }
+ description={false}
+ />
+ ) : (
+ renderTitle.call(this, nodeData)}
+ />
+ )}
-
- {renderBreadcrumbItem.call(this)}
-
+
+ {collapsed && (
+
+ }
+ onClick={() => this.setState({ showSider: true })}
+ />
+
+ )}
+
+
+ {renderBreadcrumbItem.call(this)}
+
+
+
{this.props.children}
diff --git a/web-react/src/store/reducer/layout.js b/web-react/src/store/reducer/layout.js
index 7f2fa41..aeadbee 100644
--- a/web-react/src/store/reducer/layout.js
+++ b/web-react/src/store/reducer/layout.js
@@ -1,6 +1,21 @@
-const layout = (state = {
- siderCollapsed: false
-}, action) => {
+import { SETTING_KEY } from "common/storage"
+import { SIDER_BREAK_POINT } from "util/global"
+
+const defaultState = {
+ siderCollapsed: false,
+ allowSiderCollapsed: true
+}
+
+const localStorageState = () => {
+ return JSON.parse(window.localStorage.getItem(SETTING_KEY))
+}
+
+const mergeState = {
+ ...defaultState,
+ ...localStorageState()
+}
+
+const layout = (state = mergeState, action) => {
switch (action.type) {
// 打开窗口
case 'OPEN_WINDOW':
@@ -13,8 +28,23 @@ const layout = (state = {
return state
// 侧边收起状态
case 'TOGGLE_COLLAPSED':
- const _state = { ...state, siderCollapsed: action.siderCollapsed }
- return _state
+ {
+ if (window.innerWidth <= SIDER_BREAK_POINT) {
+ return state
+ }
+ const _state = { ...state, siderCollapsed: action.siderCollapsed }
+ window.localStorage.setItem(SETTING_KEY, JSON.stringify(_state))
+ return _state
+ }
+ case 'AUTO_TOGGLE_COLLAPSED':
+ {
+ const _state = {
+ ...state,
+ siderCollapsed: localStorageState().siderCollapsed || action.siderCollapsed,
+ allowSiderCollapsed: !action.siderCollapsed
+ }
+ return _state
+ }
default:
return state
}
diff --git a/web-react/src/util/global/index.js b/web-react/src/util/global/index.js
index 2543e20..918cb47 100644
--- a/web-react/src/util/global/index.js
+++ b/web-react/src/util/global/index.js
@@ -36,4 +36,6 @@ export const RSA_PUBLIC_KEY = '-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQU
/**
* 城市名称
*/
-export const CITY = '黄石市'
\ No newline at end of file
+export const CITY = '黄石市'
+
+export const SIDER_BREAK_POINT = 1366
\ No newline at end of file
diff --git a/web-react/src/views/main/_layout/header/index.jsx b/web-react/src/views/main/_layout/header/index.jsx
index c0e0b01..ccf9f9d 100644
--- a/web-react/src/views/main/_layout/header/index.jsx
+++ b/web-react/src/views/main/_layout/header/index.jsx
@@ -33,13 +33,20 @@ export default class index extends Component {
}
render() {
+ const { allowSiderCollapsed } = this.state
+
return (
-
this.onCollapsed()}>
-
-
+ {allowSiderCollapsed && (
+
this.onCollapsed()}
+ >
+
+
+ )}
diff --git a/web-react/src/views/main/index.jsx b/web-react/src/views/main/index.jsx
index 665c59f..1e7e7eb 100644
--- a/web-react/src/views/main/index.jsx
+++ b/web-react/src/views/main/index.jsx
@@ -1,10 +1,9 @@
import React, { Component } from 'react'
import { Spin, Layout } from 'antd'
-import { LoadingOutlined } from '@ant-design/icons'
import { api } from 'common/api'
import { cloneDeep, groupBy, findIndex, last } from 'lodash'
import store from 'store'
-import { EMPTY_ID } from 'util/global'
+import { EMPTY_ID, SIDER_BREAK_POINT } from 'util/global'
import Header from './_layout/header'
import Sider from './_layout/sider'
@@ -83,6 +82,9 @@ export default class index extends Component {
})
})
})
+
+ window.addEventListener('resize', this.onResizeSider)
+ this.onResizeSider()
}
/**
@@ -231,6 +233,13 @@ export default class index extends Component {
})
}
+ onResizeSider = () => {
+ dispatch({
+ type: 'AUTO_TOGGLE_COLLAPSED',
+ siderCollapsed: window.innerWidth <= SIDER_BREAK_POINT,
+ })
+ }
+
render() {
const { loading, panes, actived } = this.state