Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
submodule
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
web_component
submodule
Commits
a3356272
Commit
a3356272
authored
Dec 18, 2020
by
zhangwenshuai
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
temp
parent
8b6603d0
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
791 additions
and
35 deletions
+791
-35
Cell.less
components/apolloTable/component/Cell.less
+19
-1
Cell.tsx
components/apolloTable/component/Cell.tsx
+54
-2
Table.tsx
components/apolloTable/component/Table.tsx
+34
-14
index.less
components/apolloTable/component/index.less
+96
-0
index.tsx
components/apolloTable/component/index.tsx
+130
-12
interface.tsx
components/apolloTable/component/interface.tsx
+4
-2
index.tsx
components/apolloTable/component/operate/index.tsx
+3
-3
index.less
components/apolloTable/component/setgroup/index.less
+67
-0
index.tsx
components/apolloTable/component/setgroup/index.tsx
+330
-0
memCols.ts
components/apolloTable/utils/memCols.ts
+38
-1
utils.tsx
components/apolloTable/utils/utils.tsx
+16
-0
No files found.
components/apolloTable/component/Cell.less
View file @
a3356272
...
...
@@ -73,6 +73,19 @@
flex: 1;
overflow: hidden;
}
.groupLevel {
position: absolute;
left: 0;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: @textFontGen;
height: 40px;
line-height: 40px;
color: @textPrimaryColor;
z-index: 5;
}
}
.detailCell {
...
...
@@ -104,7 +117,6 @@
// }
//}
.content {
flex: 1;
overflow: hidden;
...
...
@@ -132,3 +144,9 @@
box-shadow: inset 0 0 0 1px @primaryColor;
}
:global(.groupLevel3) {
}
:global(.groupLevel2) {
}
:global(.groupLevel1) {
}
components/apolloTable/component/Cell.tsx
View file @
a3356272
...
...
@@ -10,6 +10,7 @@ import FormHelper from '../utils/formHelper';
import
expandIcon
from
'../assets/extend.png'
;
import
{
transferAttr
}
from
'./base/_utils/transferAttr'
;
import
{
emptyModel
}
from
'./base/_utils/setFormatter'
;
import
{
getGroupLevel
}
from
'../utils/memCols'
;
enum
EDIT_STATUS
{
'FREE'
,
// 空闲
...
...
@@ -394,7 +395,7 @@ const Cell = (props: CellProps) => {
</
div
>
);
};
const
groupLevel
=
getGroupLevel
(
record
.
classList
);
return
(
<
div
className=
{
classNames
(
...
...
@@ -403,11 +404,62 @@ const Cell = (props: CellProps) => {
`row_${rowIndex}`
,
`col_${columnIndex}`
,
cellClassName
,
...(
record
.
classList
||
[]),
)
}
style=
{
cellStyle
}
style=
{
{
...
cellStyle
,
paddingLeft
:
columnIndex
===
0
&&
position
!==
'right'
&&
record
.
groupLevel
?
`${record.groupLevel * 16}px`
:
0
,
paddingTop
:
`${groupLevel * 40}px`
,
}
}
onMouseEnter=
{
onMouseEnter
}
onMouseLeave=
{
onMouseLeave
}
>
{
record
.
classList
&&
record
.
classList
[
0
]
&&
(
<
div
className=
{
s
.
groupLevel
}
style=
{
{
top
:
0
,
paddingLeft
:
'16px'
,
background
:
groupLevel
===
3
?
'#EEEEEE'
:
groupLevel
===
2
?
'#EDEDED'
:
'#F7F9FA'
,
}
}
>
{
columnIndex
===
0
&&
position
!==
'right'
&&
record
.
groupConfig
[
0
]
&&
`${record.groupConfig[0].colChsName}:${record.groupTextArr[0]}`
}
</
div
>
)
}
{
record
.
classList
&&
record
.
classList
[
1
]
&&
(
<
div
className=
{
s
.
groupLevel
}
style=
{
{
top
:
record
.
classList
[
0
]
?
40
:
0
,
paddingLeft
:
'32px'
,
background
:
groupLevel
===
3
?
'#F5F5F5'
:
'#F7F9FA'
,
}
}
>
{
columnIndex
===
0
&&
position
!==
'right'
&&
record
.
groupConfig
[
1
]
&&
`${record.groupConfig[1].colChsName}:${record.groupTextArr[1]}`
}
</
div
>
)
}
{
record
.
classList
&&
record
.
classList
[
2
]
&&
(
<
div
className=
{
s
.
groupLevel
}
style=
{
{
top
:
groupLevel
===
3
?
80
:
groupLevel
===
2
?
40
:
0
,
paddingLeft
:
'48px'
,
background
:
'#F7F9FA'
,
}
}
>
{
columnIndex
===
0
&&
position
!==
'right'
&&
record
.
groupConfig
[
3
]
&&
`${record.groupConfig[2].colChsName}:${record.groupTextArr[2]}`
}
</
div
>
)
}
{
columnIndex
===
0
&&
position
!==
'right'
&&
renderFirst
()
}
<
div
id=
{
`cellUnit_${tableId}_${record.id}_${columnName}`
}
...
...
components/apolloTable/component/Table.tsx
View file @
a3356272
...
...
@@ -21,6 +21,8 @@ import {
getLeftWidth
,
getTotalWidth
,
getFormatColumns
,
getTotalHeight
,
getRowHeight
,
}
from
'../utils/memCols'
;
import
{
getDefaultTableConfig
}
from
'./defaultConfig'
;
import
{
Consumer
}
from
'./context'
;
...
...
@@ -56,8 +58,10 @@ export default class AirTable extends Component<TableProps, TableState> {
memoizeTotalWidth
:
Function
;
memoizeTotalHeight
:
Function
;
static
getDerivedStateFromProps
(
nextProps
:
TableProps
,
prevState
:
TableState
)
{
const
{
columns
,
dataSource
}
=
prevState
;
const
{
columns
,
dataSource
,
groupConfig
}
=
prevState
;
const
nextState
:
TableState
=
{
...
prevState
,
};
...
...
@@ -67,15 +71,19 @@ export default class AirTable extends Component<TableProps, TableState> {
if
(
JSON
.
stringify
(
columns
)
!==
JSON
.
stringify
(
nextProps
.
columns
))
{
nextState
.
columns
=
nextProps
.
columns
;
}
if
(
JSON
.
stringify
(
groupConfig
)
!==
JSON
.
stringify
(
nextProps
.
groupConfig
))
{
nextState
.
groupConfig
=
nextProps
.
groupConfig
;
}
return
nextState
;
}
constructor
(
props
:
TableProps
)
{
super
(
props
);
const
{
columns
,
dataSource
,
width
,
height
}
=
props
;
const
{
columns
,
dataSource
,
groupConfig
,
width
,
height
}
=
props
;
this
.
state
=
{
columns
,
dataSource
,
groupConfig
,
tableWidth
:
width
||
0
,
tableHeight
:
height
||
0
,
};
...
...
@@ -86,9 +94,16 @@ export default class AirTable extends Component<TableProps, TableState> {
this
.
memoizeColumns
=
memoizeOne
(
getShowColumns
);
this
.
memoizeLeftWidth
=
memoizeOne
(
getLeftWidth
);
this
.
memoizeTotalWidth
=
memoizeOne
(
getTotalWidth
);
this
.
memoizeTotalHeight
=
memoizeOne
(
getTotalHeight
);
this
.
memoizeData
=
memoizeOne
(
this
.
filterData
);
}
componentWillReceiveProps
(
prevProps
:
Readonly
<
TableProps
>
,
prevState
:
Readonly
<
TableState
>
,
snapshot
?:
any
):
void
{
if
(
JSON
.
stringify
(
prevState
.
groupConfig
)
!==
JSON
.
stringify
(
this
.
state
.
groupConfig
))
{
this
.
recomputeGridSize
();
}
}
// 获取表格显示数据
filterData
=
(
columns
:
ColumnProps
[],
dataSource
:
RowProps
[])
=>
{
if
(
columns
.
length
===
0
||
dataSource
.
length
===
0
)
{
...
...
@@ -124,6 +139,7 @@ export default class AirTable extends Component<TableProps, TableState> {
}
return
colWidth
;
};
// 重新计算单元格大小
recomputeGridSize
=
()
=>
{
if
(
this
.
grid1
&&
this
.
grid2
)
{
...
...
@@ -434,11 +450,12 @@ export default class AirTable extends Component<TableProps, TableState> {
const
rowCount
=
showData
.
length
;
const
leftWidth
=
this
.
memoizeLeftWidth
(
leftColumns
,
showColumns
,
columnWidth
,
tableWidth
);
const
rightWidth
=
this
.
memoizeLeftWidth
(
rightColumns
,
showColumns
,
columnWidth
,
tableWidth
);
const
t
otal
Height
:
number
=
tableHeight
-
headerHeight
;
const
t
ableBody
Height
:
number
=
tableHeight
-
headerHeight
;
const
{
totalWidth
}
=
this
.
memoizeTotalWidth
(
showColumns
,
columnWidth
);
const
totalHeight
=
this
.
memoizeTotalHeight
(
dataSource
,
rowHeight
);
let
realWidth
=
tableWidth
;
let
paddingRight
=
0
;
if
(
rowCount
>
0
&&
rowCount
*
rowHeight
>
total
Height
)
{
if
(
rowCount
>
0
&&
totalHeight
>
tableBody
Height
)
{
realWidth
=
tableWidth
+
scrollbarWidth
;
paddingRight
=
scrollbarWidth
;
}
...
...
@@ -460,7 +477,7 @@ export default class AirTable extends Component<TableProps, TableState> {
className=
{
styles
.
leftSideContainer
}
style=
{
{
width
:
`${leftWidth}px`
,
height
:
`${t
otal
Height - scrollbarWidth + headerHeight}px`
,
height
:
`${t
ableBody
Height - scrollbarWidth + headerHeight}px`
,
}
}
>
{
...
...
@@ -522,9 +539,9 @@ export default class AirTable extends Component<TableProps, TableState> {
}
}
columnCount=
{
leftCount
}
width=
{
leftWidth
+
scrollbarWidth
}
rowHeight=
{
rowHeight
}
rowHeight=
{
getRowHeight
.
bind
(
null
,
{
dataSource
,
rowHeight
})
}
rowCount=
{
rowCount
}
height=
{
t
otal
Height
-
scrollbarWidth
}
height=
{
t
ableBody
Height
-
scrollbarWidth
}
scrollTop=
{
scrollTop
}
/>
</
div
>
...
...
@@ -587,7 +604,7 @@ export default class AirTable extends Component<TableProps, TableState> {
// 中部内容
<
div
style=
{
{
height
:
t
otal
Height
,
height
:
t
ableBody
Height
,
width
:
tableWidth
,
}
}
>
...
...
@@ -605,14 +622,17 @@ export default class AirTable extends Component<TableProps, TableState> {
})
}
columnCount=
{
columnCount
}
width=
{
realWidth
}
rowHeight=
{
rowHeight
}
rowHeight=
{
getRowHeight
.
bind
(
null
,
{
dataSource
,
rowHeight
,
})
}
rowCount=
{
rowCount
}
onScroll=
{
(...
arg
:
Array
<
Object
>
)
=>
{
onScroll
(...
arg
);
this
.
onScroll
(
arg
[
0
]);
}
}
scrollTop=
{
scrollTop
}
height=
{
t
otal
Height
}
height=
{
t
ableBody
Height
}
cellRenderer=
{
this
.
renderBodyCell
.
bind
(
this
,
{
showColumns
,
showData
,
...
...
@@ -658,7 +678,7 @@ export default class AirTable extends Component<TableProps, TableState> {
className=
{
styles
.
rightSideContainer
}
style=
{
{
width
:
`${rightWidth}px`
,
height
:
`${t
otal
Height - scrollbarWidth + headerHeight}px`
,
height
:
`${t
ableBody
Height - scrollbarWidth + headerHeight}px`
,
right
:
paddingRight
,
}
}
>
...
...
@@ -723,9 +743,9 @@ export default class AirTable extends Component<TableProps, TableState> {
}
}
columnCount=
{
rightCount
}
width=
{
rightWidth
+
scrollbarWidth
}
rowHeight=
{
rowHeight
}
rowHeight=
{
getRowHeight
.
bind
(
null
,
{
dataSource
,
rowHeight
})
}
rowCount=
{
rowCount
}
height=
{
t
otal
Height
-
scrollbarWidth
}
height=
{
t
ableBody
Height
-
scrollbarWidth
}
scrollTop=
{
scrollTop
}
/>
</
div
>
...
...
@@ -733,7 +753,7 @@ export default class AirTable extends Component<TableProps, TableState> {
</
div
>
)
}
<
div
className=
{
styles
.
fillHandleWrapper
}
/>
<
div
className=
{
styles
.
loading
}
style=
{
{
top
:
`${t
otal
Height / 2}px`
}
}
>
<
div
className=
{
styles
.
loading
}
style=
{
{
top
:
`${t
ableBody
Height / 2}px`
}
}
>
{
loading
&&
(
loadComp
?
loadComp
:
<
Spin
/>)
}
</
div
>
<
div
className=
{
styles
.
widthHandleWrapper
}
id=
{
`dividerWrap_${tableId}`
}
>
...
...
components/apolloTable/component/index.less
View file @
a3356272
...
...
@@ -27,3 +27,99 @@
}
}
}
.groupContainer {
padding: 16px 0;
background: #EAEAEA;
min-height: 100%;
//position: absolute;
//min-width: 100%;
:global( .ant-table.ant-table-bordered .ant-table-footer) {
border-color: transparent;
}
:global(.ant-table-bordered .ant-table-body > table) {
border-color: transparent;
border-top-color: #DBDBDB;
}
:global(.ant-collapse > .ant-collapse-item > .ant-collapse-header .ant-collapse-arrow) {
left: 10px;
}
:global(.ant-collapse > .ant-collapse-item > .ant-collapse-header) {
padding: 4px 30px 10px 33px;
}
:global(.ant-collapse-content) {
background: transparent;
}
:global(.ant-collapse-content > .ant-collapse-content-box) {
padding: 0;
}
.groupFloor1 {
background: #E8E8E8;
border-radius: 4px;
border: 1px solid #CBCBCB;
margin: 0 16px 16px 16px;
.groupFloor2 {
background: #EDEDED;
border-radius: 4px;
border: 1px solid #CBCBCB;
margin: 0 16px 16px 16px;
.groupFloor3 {
background: #F7F9FA;
border-radius: 4px;
border: 1px solid #DBDBDB;
margin: 0 16px 16px 16px;
}
}
}
.floorContainer {
//padding: 4px 10px;
font-size: 12px;
font-family: PingFangSC;
font-weight: 400;
.groupName {
color: #5A6876;
margin-bottom: 4px;
}
.groupText {
display: flex;
align-items: flex-start;
color: #2C3F53;
.groupTextColor {
border-radius: 12px;
padding: 0 10px;
height: 20px;
line-height: 20px;
}
.groupTextColorNormal {
border-radius: 4px;
padding: 0 10px;
background: #E9EEF9;
height: 20px;
line-height: 20px;
}
.groupTextNormal {
}
.groupNumber {
margin-left: 12px;
color: #666666;
width: 100px;
}
}
}
}
components/apolloTable/component/index.tsx
View file @
a3356272
import
React
from
'react'
;
import
{
Pagination
}
from
'antd'
;
import
classNames
from
'classnames'
;
import
memoizeOne
from
'memoize-one'
;
import
_
from
'lodash'
;
import
styles
from
'./index.less'
;
import
{
CommonProps
,
CommonState
}
from
'./interface'
;
import
Table
from
'./Table'
;
...
...
@@ -9,9 +11,115 @@ import TableOperateConfig from './tableOperate';
import
{
defaultLocale
}
from
'../locale'
;
import
{
Provider
}
from
'./context'
;
/**
* 获取每个单元格的值用'_'相连
* @param cell
*/
const
getCellKey
=
(
cell
:
any
)
=>
{
const
arr1
:
any
=
[];
const
arr2
:
any
=
[];
if
(
Array
.
isArray
(
cell
.
cellValueList
)
&&
cell
.
cellValueList
.
length
>
0
)
{
cell
.
cellValueList
.
map
((
data
:
any
)
=>
{
arr1
.
push
(
data
.
value
);
arr2
.
push
(
data
.
text
);
});
}
else
{
return
{
key
:
'(Empty)'
,
text
:
'(空)'
,
};
}
return
{
key
:
arr1
.
join
(
'_'
),
text
:
arr2
.
join
(
'_'
),
};
};
/**
*
* @param {*} config
* @param {*} dataSource
* @params {*renderGroupText} 自定义渲染分组名称
*/
// 分组数据添加class
const
formatData
=
(
config
:
string
[],
dataSource
:
any
[])
=>
{
if
(
!
config
||
!
config
.
length
)
{
return
dataSource
;
}
const
map
:
any
=
{};
// 一级分组条件
const
group1
=
config
[
0
];
// 二级分组条件
const
group2
=
config
[
1
];
// 三级分组条件
const
group3
=
config
[
2
];
// 遍历数据默认已排序,根据分组级别给每行添加分组class
return
dataSource
.
map
((
row
:
any
)
=>
{
const
groupKeyArr
:
string
[]
=
[];
const
groupTextArr
:
string
[]
=
[];
row
.
rowData
.
map
((
cell
:
any
)
=>
{
if
(
group1
&&
cell
.
colName
===
group1
.
colName
)
{
const
group1Cell
=
getCellKey
(
cell
);
groupKeyArr
[
0
]
=
group1Cell
.
key
;
groupTextArr
[
0
]
=
group1Cell
.
text
;
}
if
(
group2
&&
cell
.
colName
===
group2
.
colName
)
{
const
group2Cell
=
getCellKey
(
cell
);
groupKeyArr
[
1
]
=
group2Cell
.
key
;
groupTextArr
[
1
]
=
group2Cell
.
text
;
}
if
(
group3
&&
cell
.
colName
===
group3
.
colName
)
{
const
group3Cell
=
getCellKey
(
cell
);
groupKeyArr
[
2
]
=
group3Cell
.
key
;
groupTextArr
[
2
]
=
group3Cell
.
text
;
}
});
if
(
groupKeyArr
[
0
])
{
const
group1Key
=
groupKeyArr
[
0
];
const
group1Text
=
groupTextArr
[
0
];
if
(
!
map
[
group1Key
])
{
map
[
group1Key
]
=
group1Text
;
if
(
row
.
classList
)
{
row
.
classList
[
0
]
=
'groupLevel1'
;
}
else
{
row
.
classList
=
[
'groupLevel1'
];
}
}
}
if
(
groupKeyArr
[
1
])
{
const
group2Key
=
`
${
groupKeyArr
[
0
]}
-
${
groupKeyArr
[
1
]}
`
;
const
group2Text
=
`
${
groupTextArr
[
0
]}
-
${
groupTextArr
[
1
]}
`
;
if
(
!
map
[
group2Key
])
{
map
[
group2Key
]
=
group2Text
;
if
(
row
.
classList
)
{
row
.
classList
[
1
]
=
'groupLevel2'
;
}
else
{
row
.
classList
=
[
''
,
'groupLevel2'
,
''
];
}
}
}
if
(
groupKeyArr
[
2
])
{
const
group3Key
=
groupKeyArr
.
join
(
'-'
);
const
group3Text
=
groupTextArr
.
join
(
'-'
);
if
(
!
map
[
group3Key
])
{
map
[
group3Key
]
=
group3Text
;
if
(
row
.
classList
)
{
row
.
classList
[
2
]
=
'groupLevel3'
;
}
else
{
row
.
classList
=
[
''
,
''
,
'groupLevel3'
];
}
}
}
row
.
groupLevel
=
groupKeyArr
.
length
;
row
.
groupKeyArr
=
groupKeyArr
;
row
.
groupTextArr
=
groupTextArr
;
row
.
groupConfig
=
config
;
return
row
;
});
};
const
memoizeData
=
memoizeOne
(
formatData
);
class
AirTable
extends
React
.
Component
<
CommonProps
,
CommonState
>
{
static
getDerivedStateFromProps
(
nextProps
:
CommonProps
,
prevState
:
CommonState
)
{
const
{
columns
,
dataSource
}
=
prevState
;
const
{
columns
,
dataSource
,
groupConfig
}
=
prevState
;
const
nextState
:
CommonState
=
{
...
prevState
,
...
...
@@ -22,6 +130,16 @@ class AirTable extends React.Component<CommonProps, CommonState> {
if
(
JSON
.
stringify
(
columns
)
!==
JSON
.
stringify
(
nextProps
.
columns
))
{
nextState
.
columns
=
nextProps
.
columns
;
}
const
operateConfig
=
nextProps
.
operateConfig
;
const
nextGroupConfig
:
any
=
operateConfig
&&
operateConfig
.
menusGroup
&&
operateConfig
.
menusGroup
.
find
((
item
:
any
)
=>
{
return
item
.
type
===
'group'
;
});
if
(
nextGroupConfig
&&
JSON
.
stringify
(
groupConfig
)
!==
JSON
.
stringify
(
nextGroupConfig
.
value
))
{
nextState
.
groupConfig
=
nextGroupConfig
.
value
;
}
return
nextState
;
}
...
...
@@ -31,6 +149,7 @@ class AirTable extends React.Component<CommonProps, CommonState> {
this
.
state
=
{
columns
,
dataSource
,
groupConfig
:
[],
};
}
...
...
@@ -55,7 +174,7 @@ class AirTable extends React.Component<CommonProps, CommonState> {
};
render
()
{
const
{
columns
,
dataSource
}
=
this
.
state
;
const
{
columns
,
dataSource
,
groupConfig
}
=
this
.
state
;
const
{
className
,
tableClassName
,
...
...
@@ -94,20 +213,18 @@ class AirTable extends React.Component<CommonProps, CommonState> {
renderFirstLeft
,
leftMargin
,
}
=
this
.
props
;
const
sortConfig
=
operateConfig
&&
operateConfig
.
menusGroup
&&
operateConfig
.
menusGroup
.
find
((
item
:
any
)
=>
{
const
sortConfig
=
operateConfig
&&
operateConfig
.
menusGroup
&&
operateConfig
.
menusGroup
.
find
((
item
:
any
)
=>
{
return
item
.
type
===
'sort'
;
});
const
memDataSource
=
memoizeData
(
groupConfig
,
dataSource
);
return
(
<
Provider
value=
{
{
locale
:
this
.
getContext
()
}
}
>
<
div
className=
{
classNames
(
styles
.
container
,
className
)
}
>
<
div
className=
{
classNames
(
styles
.
container
,
className
)
}
>
{
operateConfig
&&
<
OperateConfig
columns=
{
columns
}
operateConfig=
{
operateConfig
}
/>
}
<
div
className=
{
classNames
(
styles
.
tableContainer
,
tableClassName
)
}
>
<
div
className=
{
classNames
(
styles
.
tableContainer
,
tableClassName
)
}
>
{
tableOperateConfig
&&
(
<
div
className=
{
styles
.
tableOperateContainer
}
>
<
TableOperateConfig
operateConfig=
{
tableOperateConfig
}
/>
...
...
@@ -117,7 +234,7 @@ class AirTable extends React.Component<CommonProps, CommonState> {
<
Table
tableId=
{
tableId
}
columns=
{
columns
}
dataSource=
{
d
ataSource
}
dataSource=
{
memD
ataSource
}
rowStyle=
{
rowStyle
}
rowClassName=
{
rowClassName
}
onScroll=
{
onScroll
?
this
.
onScroll
:
undefined
}
...
...
@@ -131,6 +248,7 @@ class AirTable extends React.Component<CommonProps, CommonState> {
headerHeight=
{
headerHeight
}
columnWidth=
{
columnWidth
}
sortConfig=
{
sortConfig
}
groupConfig=
{
groupConfig
}
paginationConfig=
{
paginationConfig
}
showIndex=
{
showIndex
}
showExpand=
{
showExpand
}
...
...
components/apolloTable/component/interface.tsx
View file @
a3356272
...
...
@@ -39,7 +39,7 @@ export interface OperateConfigProps {
buttonsGroup
?:
Object
[];
// 自定义按钮组
moreGroup
?:
Object
[];
// 按钮太多时可按更多分组
renderCustomNode
?:
Function
;
// 自定义渲染节点
showCondition
?:
boolean
;
// 是否展示筛选条件
showCondition
?:
boolean
;
// 是否展示筛选条件
}
export
interface
LoadConfigProps
{
...
...
@@ -70,6 +70,7 @@ export interface TableProps extends LoadConfigProps {
cellEditable
?:
boolean
;
// 单元格是否可编辑
emitChangeCell
?:
Function
;
// 单元格修改回调
sortConfig
?:
any
;
// 表头快捷排序(正倒序)
groupConfig
?:
any
;
// 表头快捷分组
paginationConfig
?:
any
;
// 分页配置(与onScroll互斥)
noDataPlaceholder
?:
any
;
// 表格无数据时显示文案
emptyPlaceholder
?:
string
;
// 单元格数据为空时默认显示
...
...
@@ -84,12 +85,13 @@ export interface TableProps extends LoadConfigProps {
onDragResized
?:
Function
;
// 拖拽更改列伸缩回调
onEmitMsg
?:
Function
;
// 是否支持消息协同
cachedFeAttr
?:
boolean
;
// 是否启用前端缓存
renderFirstLeft
?:
Function
;
// 第一个单元格特殊渲染
renderFirstLeft
?:
Function
;
// 第一个单元格特殊渲染
leftMargin
?:
number
;
// 第一个表头左侧对齐距离
}
export
interface
TableState
{
columns
:
ColumnProps
[];
dataSource
:
RowProps
[];
groupConfig
?:
any
[];
tableHeight
?:
number
;
tableWidth
?:
number
;
}
...
...
components/apolloTable/component/operate/index.tsx
View file @
a3356272
...
...
@@ -3,7 +3,7 @@ import { Button } from 'antd';
import
Hide
from
'../hide'
;
import
Filter
from
'../filter'
;
import
Sort
from
'../sort'
;
//
import Group from '../setgroup';
import
Group
from
'../setgroup'
;
import
FilterCondition
from
'../filter-condition'
;
import
s
from
'./index.less'
;
...
...
@@ -29,8 +29,8 @@ export default class Operate extends Component<Props> {
return
<
Hide
columns=
{
columns
}
operate=
{
operate
}
/>;
case
'filter'
:
return
<
Filter
columns=
{
columns
}
operate=
{
operate
}
/>;
//
case 'group':
//
return <Group columns={columns} operate={operate} />;
case
'group'
:
return
<
Group
columns=
{
columns
}
operate=
{
operate
}
/>;
case
'sort'
:
return
<
Sort
columns=
{
columns
}
operate=
{
operate
}
/>;
default
:
...
...
components/apolloTable/component/setgroup/index.less
0 → 100644
View file @
a3356272
@import '../../common';
@import '../../media';
@import '../filter/index.less';
.optionsModal {
min-width: 325px;
.mediaMax(750px,{
min-width: 0;
});
}
.optionItem {
.optionLeft {
flex: 1;
.mediaMax(750px,{
width: auto;
});
}
.optionMid {
max-width: 112px;
.mediaMax(750px,{
max-width: 30%;
width: auto;
});
.sortBtn {
width: 54px;
padding: 0 5px;
border-color: @supportColor;
&.primary{
background: @supportColor;
color: white;
}
}
}
.optionRight {
margin-left: 20px;
}
.optionDel {
}
}
.btns {
display: flex;
align-items: center;
justify-content: flex-end;
padding: 15px;
.btn {
text-align: center;
cursor: pointer;
color: @supportColor;
margin-left: 10px;
width: 60px;
border-radius: @borderRadius;
height: 30px;
line-height: 30px;
&.reset {
background: white;
border: 1px solid @supportColor;
}
}
}
components/apolloTable/component/setgroup/index.tsx
0 → 100644
View file @
a3356272
import
React
,
{
Component
}
from
'react'
;
import
_
from
'lodash'
;
import
{
Popover
,
Button
,
Select
}
from
'antd'
;
import
classNames
from
'classnames'
;
import
s
from
'../hide/index.less'
;
import
styles
from
'./index.less'
;
import
groupIcon
from
'../../assets/group.png'
;
import
closeIcon
from
'../../assets/close.png'
;
import
{
ColumnProps
}
from
'../interface'
;
import
{
Consumer
}
from
'../context'
;
interface
Props
{
columns
:
any
;
operate
:
any
;
}
interface
State
{
visible
:
boolean
;
groupConfig
:
any
;
temp
:
any
;
}
/**
* 操作栏显隐控制
* 参数
* @configs 操作栏配置
* @columns 表头列表配置
* @onChange 显隐变化回调
*/
export
default
class
Sort
extends
Component
<
Props
,
State
>
{
constructor
(
props
:
Props
)
{
super
(
props
);
this
.
state
=
{
visible
:
false
,
groupConfig
:
[],
temp
:
{
// 临时排序数据,不上传接口
colName
:
undefined
,
colChsName
:
undefined
,
sortType
:
'ASC'
,
},
};
}
componentDidMount
()
{
const
{
operate
:
{
value
},
}
=
this
.
props
;
this
.
setState
({
groupConfig
:
value
&&
value
.
length
>
0
?
value
:
[],
});
}
UNSAFE_componentWillReceiveProps
(
nextProps
:
Props
)
{
const
oldGroupConfig
=
this
.
props
.
operate
.
value
;
const
newGroupConfig
=
nextProps
.
operate
.
value
;
if
(
JSON
.
stringify
(
oldGroupConfig
)
!==
JSON
.
stringify
(
newGroupConfig
))
{
this
.
setState
({
groupConfig
:
newGroupConfig
&&
newGroupConfig
.
length
>
0
?
newGroupConfig
:
[],
temp
:
{
colName
:
undefined
,
colChsName
:
undefined
,
sortType
:
'ASC'
,
},
});
}
}
getGroupColumns
=
(
columns
:
ColumnProps
[])
=>
{
return
columns
.
filter
((
item
)
=>
{
return
!!
item
.
groupFlag
;
});
};
toggleOption
=
()
=>
{
const
{
visible
}
=
this
.
state
;
this
.
setState
({
visible
:
!
visible
,
});
};
// 修改临时排序条件
changeColName
=
(
value
:
string
)
=>
{
const
{
temp
}
=
this
.
state
;
const
{
columns
}
=
this
.
props
;
const
groupColumnConfig
=
this
.
getGroupColumns
(
columns
);
const
group
:
any
=
groupColumnConfig
.
find
((
item
)
=>
{
return
item
.
columnName
===
value
;
});
const
newTemp
=
_
.
assign
({},
temp
,
{
colName
:
value
,
colChsName
:
group
.
columnChsName
});
this
.
addGroupItem
(
newTemp
);
};
// 修改临时排序顺序
changeNewSortType
=
(
value
:
string
)
=>
{
const
{
temp
}
=
this
.
state
;
const
newTemp
=
_
.
assign
({},
temp
,
{
sortType
:
value
});
this
.
addGroupItem
(
newTemp
);
};
// 添加一条
addGroupItem
=
async
(
data
:
any
)
=>
{
if
(
data
.
colName
&&
data
.
sortType
)
{
const
{
groupConfig
}
=
this
.
state
;
const
temp
=
_
.
cloneDeep
(
groupConfig
)
||
[];
temp
.
push
(
data
);
// 条件填齐后回调保存
this
.
onChange
(
temp
);
}
else
{
this
.
setState
({
temp
:
data
,
});
}
};
// 删除一条
delGroupItem
=
(
index
:
number
)
=>
{
const
{
groupConfig
}
=
this
.
state
;
const
temp
=
_
.
cloneDeep
(
groupConfig
);
temp
.
splice
(
index
,
1
);
this
.
onChange
(
temp
);
};
// 重置
resetGroupItem
=
()
=>
{
this
.
onChange
([]);
};
// 改变已有排序条件
changeGroupKey
=
(
index
:
number
,
value
:
any
)
=>
{
const
{
groupConfig
}
=
this
.
state
;
const
{
columns
}
=
this
.
props
;
const
groupColumnConfig
=
this
.
getGroupColumns
(
columns
);
const
temp
=
_
.
cloneDeep
(
groupConfig
);
temp
[
index
].
colName
=
value
;
const
group
:
any
=
groupColumnConfig
.
find
((
item
)
=>
{
return
item
.
columnName
===
value
;
});
temp
[
index
].
colChsName
=
group
.
columnChsName
;
this
.
onChange
(
temp
);
};
// 改变已有排序顺序
changeGroupType
=
(
index
:
number
,
value
:
any
)
=>
{
const
{
groupConfig
}
=
this
.
state
;
const
temp
=
_
.
cloneDeep
(
groupConfig
);
temp
[
index
].
sortType
=
value
;
this
.
onChange
(
temp
);
};
// 回调表格更改操作栏方法
onChange
=
(
config
:
any
[])
=>
{
const
{
operate
:
{
onChange
},
}
=
this
.
props
;
if
(
typeof
onChange
===
'function'
)
{
onChange
({
type
:
'groupConfig'
,
config
});
}
};
getFilterConfig
=
()
=>
{
const
{
groupConfig
,
temp
}
=
this
.
state
;
const
{
columns
}
=
this
.
props
;
const
groupColumnConfig
=
this
.
getGroupColumns
(
columns
);
const
tempConfig
=
_
.
cloneDeep
(
groupColumnConfig
);
return
tempConfig
.
map
((
item
:
any
)
=>
{
item
.
disabled
=
groupConfig
.
some
((
group
:
any
)
=>
{
return
group
.
colName
===
item
.
columnName
;
})
||
temp
.
colName
===
item
.
columnName
;
return
item
;
});
};
renderContent
=
(
locale
)
=>
{
const
{
groupConfig
,
temp
}
=
this
.
state
;
const
filterConfig
=
this
.
getFilterConfig
();
return
(
<
div
className=
{
styles
.
optionsModal
}
>
{
groupConfig
.
map
((
item
:
any
,
i
:
number
)
=>
{
return
(
<
div
key=
{
i
}
className=
{
styles
.
optionItem
}
>
<
div
className=
{
styles
.
optionLeft
}
>
<
Select
value=
{
item
.
colName
}
onChange=
{
this
.
changeGroupKey
.
bind
(
this
,
i
)
}
style=
{
{
width
:
'100%'
}
}
placeholder=
{
locale
.
select
}
>
{
filterConfig
.
map
((
option
)
=>
{
return
(
<
Select
.
Option
key=
{
option
.
columnName
}
disabled=
{
option
.
disabled
}
value=
{
option
.
columnName
}
>
{
option
.
columnChsName
}
</
Select
.
Option
>
);
})
}
</
Select
>
</
div
>
<
div
className=
{
styles
.
optionMid
}
>
<
Button
.
Group
>
<
Button
className=
{
item
.
sortType
===
'ASC'
?
classNames
(
styles
.
sortBtn
,
styles
.
primary
)
:
styles
.
sortBtn
}
onClick=
{
this
.
changeGroupType
.
bind
(
this
,
i
,
'ASC'
)
}
>
{
locale
.
sortASC
}
</
Button
>
<
Button
className=
{
item
.
sortType
===
'DESC'
?
classNames
(
styles
.
sortBtn
,
styles
.
primary
)
:
styles
.
sortBtn
}
onClick=
{
this
.
changeGroupType
.
bind
(
this
,
i
,
'DESC'
)
}
>
{
locale
.
sortDESC
}
</
Button
>
</
Button
.
Group
>
</
div
>
<
div
className=
{
styles
.
optionDel
}
role=
"presentation"
onClick=
{
this
.
delGroupItem
.
bind
(
this
,
i
)
}
>
<
img
alt=
""
className=
{
styles
.
delIcon
}
src=
{
closeIcon
}
/>
</
div
>
</
div
>
);
})
}
{
groupConfig
.
length
<
3
&&
(
<
div
className=
{
styles
.
optionItem
}
key=
{
groupConfig
.
length
+
3
}
>
<
div
className=
{
styles
.
optionLeft
}
>
<
Select
value=
{
temp
.
colName
}
placeholder=
{
locale
.
select
}
onChange=
{
this
.
changeColName
}
style=
{
{
width
:
'100%'
}
}
>
{
filterConfig
.
map
((
item
)
=>
{
return
(
<
Select
.
Option
key=
{
item
.
columnName
}
disabled=
{
item
.
disabled
}
value=
{
item
.
columnName
}
>
{
item
.
columnChsName
}
</
Select
.
Option
>
);
})
}
</
Select
>
</
div
>
<
div
className=
{
styles
.
optionMid
}
>
<
Button
.
Group
>
<
Button
className=
{
temp
.
sortType
===
'ASC'
?
classNames
(
styles
.
sortBtn
,
styles
.
primary
)
:
styles
.
sortBtn
}
onClick=
{
this
.
changeNewSortType
.
bind
(
this
,
'ASC'
)
}
>
{
locale
.
sortASC
}
</
Button
>
<
Button
className=
{
temp
.
sortType
===
'DESC'
?
classNames
(
styles
.
sortBtn
,
styles
.
primary
)
:
styles
.
sortBtn
}
onClick=
{
this
.
changeNewSortType
.
bind
(
this
,
'DESC'
)
}
>
{
locale
.
sortDESC
}
</
Button
>
</
Button
.
Group
>
</
div
>
</
div
>
)
}
<
div
className=
{
styles
.
btns
}
>
<
div
role=
"presentation"
className=
{
classNames
(
styles
.
btn
,
styles
.
reset
)
}
onClick=
{
this
.
resetGroupItem
}
>
{
locale
.
sortReset
}
</
div
>
</
div
>
</
div
>
);
};
render
()
{
const
{
visible
}
=
this
.
state
;
const
{
operate
:
{
value
},
}
=
this
.
props
;
const
len
=
value
&&
value
.
length
;
let
bg
=
''
;
if
(
len
>
0
)
{
bg
=
'rgba(92,153,255,0.2)'
;
}
return
(
<
Consumer
>
{
({
locale
})
=>
{
const
txt
=
locale
.
group
===
'分组'
?
`${len}条分组`
:
`Grouped by ${len} fields`
;
return
(
<
Popover
overlayClassName=
{
s
.
popover
}
placement=
"bottomLeft"
title=
{
locale
.
group
}
content=
{
this
.
renderContent
(
locale
)
}
visible=
{
visible
}
onVisibleChange=
{
this
.
toggleOption
}
trigger=
"click"
>
<
div
className=
{
s
.
operateContainer
}
style=
{
{
background
:
bg
}
}
>
<
img
alt=
""
className=
{
s
.
operateIcon
}
src=
{
groupIcon
}
/>
<
span
className=
{
s
.
operateName
}
>
{
len
>
0
?
txt
:
locale
.
group
}
</
span
>
</
div
>
</
Popover
>
);
}
}
</
Consumer
>
);
}
}
components/apolloTable/utils/memCols.ts
View file @
a3356272
import
memoizeOne
from
'memoize-one'
;
import
{
ColumnProps
}
from
'../component/interface'
;
import
{
ColumnProps
,
RowProps
}
from
'../component/interface'
;
import
{
getCache
,
saveCache
}
from
'@/submodule/components/apolloTable/utils/cache'
;
// 获取左侧固定列数量
...
...
@@ -47,6 +47,43 @@ export const getTotalWidth = (columns: ColumnProps[], columnWidth: number) => {
defaultWidthLen
,
};
};
// 获取分组级别
export
const
getGroupLevel
=
(
classList
)
=>
{
let
len
=
0
;
if
(
classList
)
{
classList
.
map
((
item
)
=>
{
if
(
item
)
{
len
++
;
}
});
}
return
len
;
};
// 获取每列的宽度
export
const
getRowHeight
=
(
{
dataSource
,
rowHeight
}:
{
dataSource
:
RowProps
[];
rowHeight
:
number
},
{
index
}:
{
index
:
number
},
)
=>
{
const
{
classList
}
=
dataSource
[
index
];
let
len
=
1
;
if
(
classList
)
{
classList
.
map
((
item
)
=>
{
if
(
item
)
{
len
++
;
}
});
}
return
rowHeight
*
len
;
};
// 获取数据总高度
export
const
getTotalHeight
=
(
dataSource
:
RowProps
[],
rowHeight
:
number
)
=>
{
let
height
=
0
;
dataSource
.
map
((
item
:
any
,
index
:
number
)
=>
{
height
+=
getRowHeight
({
dataSource
,
rowHeight
},
{
index
});
});
return
height
;
};
// 获取左侧固定列总宽度
export
const
getLeftWidth
=
(
...
...
components/apolloTable/utils/utils.tsx
View file @
a3356272
...
...
@@ -135,3 +135,19 @@ export function isNumber(data: any) {
// eslint-disable-next-line no-restricted-globals
return
!
isNaN
(
data
);
}
/**
* 按key去重
* @param data 原数组
* @param key 过滤键
* @returns {unknown[]} 键数组
*/
export
function
getKeys
(
data
,
key
)
{
const
result
=
[];
if
(
Array
.
isArray
(
data
))
{
data
.
map
((
item
)
=>
{
result
.
push
(
item
[
key
]);
});
}
const
temp
=
new
Set
(
result
);
return
Array
.
from
(
temp
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment