mirror of
https://gitee.com/baidu/amis.git
synced 2024-12-02 03:48:13 +08:00
feat:调整列宽问题修复;新增sticky属性;列搜索;单元格支持编辑等
This commit is contained in:
parent
422376dec7
commit
34f73bf4ca
File diff suppressed because it is too large
Load Diff
@ -775,14 +775,13 @@ export const components = [
|
|||||||
import('../../docs/zh-CN/components/table.md').then(wrapDoc)
|
import('../../docs/zh-CN/components/table.md').then(wrapDoc)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
label: 'Table v2 表格',
|
// label: 'Table v2 表格',
|
||||||
path: '/zh-CN/components/table-v2',
|
// path: '/zh-CN/components/table-v2',
|
||||||
getComponent: () =>
|
// component: React.lazy(() =>
|
||||||
import('../../docs/zh-CN/components/table-v2.md').then(
|
// import('../../docs/zh-CN/components/table-v2.md').then(wrapDoc)
|
||||||
makeMarkdownRenderer
|
// )
|
||||||
)
|
// },
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: 'Table View 表格视图',
|
label: 'Table View 表格视图',
|
||||||
path: '/zh-CN/components/table-view',
|
path: '/zh-CN/components/table-view',
|
||||||
|
@ -1043,6 +1043,7 @@ body.dark {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
// overflow: hidden;
|
// overflow: hidden;
|
||||||
|
width: calc(100% - 350px);
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
@ -1309,22 +1309,43 @@
|
|||||||
--Table-searchableForm-borderRadius: #{px2rem(4px)};
|
--Table-searchableForm-borderRadius: #{px2rem(4px)};
|
||||||
|
|
||||||
--TableCell--edge-paddingX: var(--gap-md);
|
--TableCell--edge-paddingX: var(--gap-md);
|
||||||
|
--TableCell--edge-paddingX-default: var(--gap-base);
|
||||||
--TableCell-filterBtn--onActive-color: var(--primary);
|
--TableCell-filterBtn--onActive-color: var(--primary);
|
||||||
--TableCell-filterBtn-width: #{px2rem(16px)};
|
--TableCell-filterBtn-width: #{px2rem(16px)};
|
||||||
--TableCell-filterPopOver-dropDownItem-height: #{px2rem(34px)};
|
--TableCell-filterPopOver-dropDownItem-height: #{px2rem(34px)};
|
||||||
--TableCell-filterPopOver-dropDownItem-padding: 0 #{px2rem(12px)};
|
--TableCell-filterPopOver-dropDownItem-padding: 0 #{px2rem(12px)};
|
||||||
|
--TableCell-line-height-large: #{px2rem(40px)};
|
||||||
|
--TableCell-line-height-middle: #{px2rem(30px)};
|
||||||
--TableCell-height: #{px2rem(40px)};
|
--TableCell-height: #{px2rem(40px)};
|
||||||
|
--TableCell-height-default: #{px2rem(41px)};
|
||||||
|
--TableCell-height-large: #{px2rem(61px)};
|
||||||
|
--TableCell-height-small: #{px2rem(33px)};
|
||||||
--TableCell-paddingX: var(--gap-sm);
|
--TableCell-paddingX: var(--gap-sm);
|
||||||
|
--TableCell-paddingX-large: var(--gap-base);
|
||||||
|
--TableCell-paddingX-small: var(--gap-xs);
|
||||||
--TableCell-paddingY: calc(
|
--TableCell-paddingY: calc(
|
||||||
(var(--TableCell-height) - var(--Table-fontSize) * var(--Table-lineHeight)) /
|
(var(--TableCell-height) - var(--Table-fontSize) * var(--Table-lineHeight)) /
|
||||||
2
|
2
|
||||||
);
|
);
|
||||||
|
--TableCell-paddingY-default: calc(
|
||||||
|
(var(--TableCell-height-default) - var(--Table-fontSize) * var(--Table-lineHeight)) /
|
||||||
|
2
|
||||||
|
);
|
||||||
|
--TableCell-paddingY-large: calc(
|
||||||
|
(var(--TableCell-height-large) - var(--Table-fontSize) * var(--Table-lineHeight)) /
|
||||||
|
2
|
||||||
|
);
|
||||||
|
--TableCell-paddingY-small: calc(
|
||||||
|
(var(--TableCell-height-small) - var(--Table-fontSize) * var(--Table-lineHeight)) /
|
||||||
|
2
|
||||||
|
);
|
||||||
--TableCell-searchBtn--onActive-color: var(--primary);
|
--TableCell-searchBtn--onActive-color: var(--primary);
|
||||||
--TableCell-searchBtn-width: #{px2rem(16px)};
|
--TableCell-searchBtn-width: #{px2rem(16px)};
|
||||||
--TableCell-sortBtn--default-onActive-opacity: 1;
|
--TableCell-sortBtn--default-onActive-opacity: 1;
|
||||||
--TableCell-sortBtn--default-opacity: 0;
|
--TableCell-sortBtn--default-opacity: 0;
|
||||||
--TableCell-sortBtn--onActive-color: var(--primary);
|
--TableCell-sortBtn--onActive-color: var(--primary);
|
||||||
--TableCell-sortBtn-width: #{px2rem(8px)};
|
--TableCell-sortBtn-width: #{px2rem(8px)};
|
||||||
|
--TableCell-icon-gap: var(--gap-sm);
|
||||||
|
|
||||||
--Table-fixedLeftLast-boxShadow: inset 10px 0 8px -8px #00000026;
|
--Table-fixedLeftLast-boxShadow: inset 10px 0 8px -8px #00000026;
|
||||||
--Table-fixedRightFirst-boxShadow: inset -10px 0 8px -8px #00000026;
|
--Table-fixedRightFirst-boxShadow: inset -10px 0 8px -8px #00000026;
|
||||||
|
912
scss/components/_table-v2.scss
Normal file
912
scss/components/_table-v2.scss
Normal file
@ -0,0 +1,912 @@
|
|||||||
|
.#{$ns}Table-v2 {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
border-radius: var(--Table-borderRadius);
|
||||||
|
margin-bottom: var(--gap-md);
|
||||||
|
|
||||||
|
&.#{$ns}Table-bordered {
|
||||||
|
border-width: var(--Table-borderWidth) var(--Table-borderWidth) 0 var(--Table-borderWidth);
|
||||||
|
border-style: solid;
|
||||||
|
border-color: var(--Table-borderColor);
|
||||||
|
border-collapse: inherit;
|
||||||
|
|
||||||
|
.#{$ns}Table-table {
|
||||||
|
> thead > tr > th,
|
||||||
|
> tbody > tr > td,
|
||||||
|
> tfoot > tr > td {
|
||||||
|
border-right: var(--Table-borderWidth) solid var(--Table-borderColor);
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}Table-footer {
|
||||||
|
border-bottom: var(--Table-borderWidth) solid var(--Table-borderColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}Table-title {
|
||||||
|
border-bottom: var(--Table-borderWidth) solid var(--Table-borderColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.#{$ns}Table-large {
|
||||||
|
.#{$ns}Table-table {
|
||||||
|
> thead > tr {
|
||||||
|
> th {
|
||||||
|
padding: var(--TableCell-paddingY-large) var(--TableCell-paddingX-large);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> tbody > tr {
|
||||||
|
> td,
|
||||||
|
> th {
|
||||||
|
padding: var(--TableCell-paddingY-large) var(--TableCell-paddingX-large);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> tfoot > tr {
|
||||||
|
> td {
|
||||||
|
padding: var(--TableCell-paddingY-large) var(--TableCell-paddingX-large);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}TableCell-filterBtn {
|
||||||
|
right: calc(
|
||||||
|
var(--TableCell-paddingX-large) - var(--TableCell-filterBtn-width) / 2
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.#{$ns}Table-small {
|
||||||
|
.#{$ns}Table-table {
|
||||||
|
> thead > tr {
|
||||||
|
> th {
|
||||||
|
padding: var(--TableCell-paddingY-small) var(--TableCell-paddingX-small);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> tbody > tr {
|
||||||
|
> td,
|
||||||
|
> th {
|
||||||
|
padding: var(--TableCell-paddingY-small) var(--TableCell-paddingX-small);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> tfoot > tr {
|
||||||
|
> td {
|
||||||
|
padding: var(--TableCell-paddingY-small) var(--TableCell-paddingX-small);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}TableCell-filterBtn {
|
||||||
|
right: calc(
|
||||||
|
var(--TableCell-paddingX-small) - var(--TableCell-filterBtn-width) / 2
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}Table-title,
|
||||||
|
.#{$ns}Table-footer {
|
||||||
|
background: var(--Table-heading-bg);
|
||||||
|
padding: calc(
|
||||||
|
(
|
||||||
|
var(--Table-heading-height) - var(--Table-fontSize) *
|
||||||
|
var(--lineHeightBase)
|
||||||
|
) / 2
|
||||||
|
)
|
||||||
|
var(--gap-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}Table-header {
|
||||||
|
padding: var(--Table-toolbar-marginY) var(--Table-toolbar-marginX);
|
||||||
|
|
||||||
|
&.#{$ns}Table-sticky-holder {
|
||||||
|
position: sticky;
|
||||||
|
z-index: 3;
|
||||||
|
background: var(--Table-bg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}Table-toolbar {
|
||||||
|
@include clearfix();
|
||||||
|
display: flex;
|
||||||
|
margin: 0 var(--Table-toolbar-marginX) var(--Table-toolbar-marginY);
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
.#{$ns}DropDown {
|
||||||
|
&-menuItem {
|
||||||
|
height: auto;
|
||||||
|
|
||||||
|
.#{$ns}Checkbox {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}Table-header + .#{$ns}Table-toolbar {
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}Table-content {
|
||||||
|
min-height: 0.01%;
|
||||||
|
overflow-x: auto;
|
||||||
|
transform: translateZ(0);
|
||||||
|
|
||||||
|
th {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}Table-table {
|
||||||
|
width: 100%;
|
||||||
|
min-width: 100%;
|
||||||
|
margin-bottom: 0;
|
||||||
|
font-size: var(--Table-fontSize);
|
||||||
|
color: var(--Table-color);
|
||||||
|
background: var(--Table-bg);
|
||||||
|
border-spacing: 0;
|
||||||
|
border-collapse: collapse;
|
||||||
|
border: none;
|
||||||
|
|
||||||
|
& th,
|
||||||
|
& td {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
& th.text-center,
|
||||||
|
& td.text-center,
|
||||||
|
& th[colspan],
|
||||||
|
& td[colspan] {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
& th.text-right,
|
||||||
|
& td.text-right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
> thead > tr {
|
||||||
|
> th {
|
||||||
|
background: var(--Table-thead-bg);
|
||||||
|
padding: var(--TableCell-paddingY-default) var(--TableCell-paddingX);
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
padding-left: var(--TableCell--edge-paddingX-default);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.#{$ns}Table-cell-last {
|
||||||
|
padding-right: var(--TableCell--edge-paddingX-default);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(.#{$ns}Table-cell-last) {
|
||||||
|
border-right: var(--Table-thead-borderWidth) solid
|
||||||
|
var(--Table-thead-borderColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.#{$ns}Table-row-expand-icon-cell {
|
||||||
|
border-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
font-size: var(--Table-thead-fontSize);
|
||||||
|
color: var(--Table-thead-color);
|
||||||
|
font-weight: var(--fontWeightNormal);
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
.#{$ns}Remark {
|
||||||
|
margin-left: var(--gap-xs);
|
||||||
|
position: relative;
|
||||||
|
top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}Table-head-cell-wrapper {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> thead > tr:not(:last-child) {
|
||||||
|
border-bottom: var(--Table-borderWidth) solid var(--Table-borderColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
> tbody > tr {
|
||||||
|
position: relative;
|
||||||
|
border-bottom: var(--Table-borderWidth) solid var(--Table-borderColor);
|
||||||
|
|
||||||
|
&.#{$ns}Table-summary-row {
|
||||||
|
> td {
|
||||||
|
background: var(--Table-thead-bg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> th {
|
||||||
|
background: var(--Table-thead-bg);
|
||||||
|
color: var(--Table-thead-color);
|
||||||
|
font-weight: var(--fontWeightNormal);
|
||||||
|
white-space: nowrap;
|
||||||
|
border-right: var(--Table-thead-borderWidth) solid
|
||||||
|
var(--Table-thead-borderColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
> td,
|
||||||
|
> th {
|
||||||
|
padding: var(--TableCell-paddingY-default) var(--TableCell-paddingX);
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
padding-left: var(--TableCell--edge-paddingX-default);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
padding-right: var(--TableCell--edge-paddingX-default);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}Table-cell-wrapper-prefix {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.#{$ns}Table-expandBtn {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}Table-cell-height-large {
|
||||||
|
height: var(--TableCell-line-height-large);
|
||||||
|
line-height: var(--TableCell-line-height-large);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}Table-cell-height-middle {
|
||||||
|
height: var(--TableCell-line-height-middle);
|
||||||
|
line-height: var(--TableCell-line-height-middle);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
@if var(--Table-strip-bg) !=transparent {
|
||||||
|
background: transparent;
|
||||||
|
|
||||||
|
&.#{$ns}Table-tr--odd {
|
||||||
|
background: var(--Table-strip-bg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.#{$ns}Table-tr--hasItemAction:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&.is-hovered {
|
||||||
|
background: var(--Table-onHover-bg);
|
||||||
|
border-color: var(--Table-onHover-borderColor);
|
||||||
|
color: var(--Table-onHover-color);
|
||||||
|
|
||||||
|
& + tr {
|
||||||
|
border-color: var(--Table-onHover-borderColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-checked {
|
||||||
|
background: var(--Table-onChecked-bg);
|
||||||
|
border-color: var(--Table-onChecked-borderColor);
|
||||||
|
color: var(--Table-onChecked-color);
|
||||||
|
|
||||||
|
& + tr {
|
||||||
|
border-color: var(--Table-onChecked-borderColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-moved,
|
||||||
|
&.is-modified {
|
||||||
|
background: var(--Table-onModified-bg);
|
||||||
|
border-color: var(--Table-onModified-borderColor);
|
||||||
|
color: var(--Table-onModified-color);
|
||||||
|
|
||||||
|
& + tr {
|
||||||
|
border-color: var(--Table-onModified-borderColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-summary {
|
||||||
|
background: var(--Table-thead-bg);
|
||||||
|
color: var(--Table-thead-color);
|
||||||
|
font-weight: var(--fontWeightNormal);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bg-light {
|
||||||
|
@include color-variant($light, 2%, 3%, 3%, 5%);
|
||||||
|
color: $text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bg-dark {
|
||||||
|
@include color-variant($dark, 5%, 10%, 5%, 10%);
|
||||||
|
@include font-variant($dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bg-black {
|
||||||
|
@include color-variant($black, 5%, 10%, 5%, 10%);
|
||||||
|
@include font-variant($black);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bg-primary {
|
||||||
|
@include color-variant($primary, 5%, 10%, 5%, 10%);
|
||||||
|
@include font-variant($primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bg-success {
|
||||||
|
@include color-variant($success, 5%, 10%, 5%, 10%);
|
||||||
|
@include font-variant($success);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bg-info {
|
||||||
|
@include color-variant($info, 5%, 10%, 5%, 10%);
|
||||||
|
@include font-variant($info);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bg-warning {
|
||||||
|
@include color-variant($warning, 5%, 10%, 5%, 10%);
|
||||||
|
@include font-variant($warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bg-danger {
|
||||||
|
@include color-variant($danger, 5%, 10%, 5%, 10%);
|
||||||
|
@include font-variant($danger);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-dragging {
|
||||||
|
opacity: var(--Table-onDragging-opacity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@for $i from 2 through 10 {
|
||||||
|
tr.#{$ns}Table-tr--#{$i}th.is-expanded {
|
||||||
|
.#{$ns}Table-expandCell:before {
|
||||||
|
right: px2rem(7px) + px2rem(-18px) * ($i - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tr.#{$ns}Table-tr--#{$i}th {
|
||||||
|
.#{$ns}Table-expandBtn {
|
||||||
|
position: relative;
|
||||||
|
right: -(px2rem(18px)) * ($i - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}Table-expandCell + td {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: px2rem(1px);
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: px2rem(-8px) + px2rem(18px) * ($i - 2);
|
||||||
|
height: auto;
|
||||||
|
background: var(--Table-tree-borderColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
height: px2rem(1px);
|
||||||
|
top: 50%;
|
||||||
|
left: px2rem(-8px) + px2rem(18px) * ($i - 2);
|
||||||
|
width: px2rem(10px);
|
||||||
|
background: var(--Table-tree-borderColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
padding-left: px2rem(18px) * $i - px2rem(18px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tr.#{$ns}Table-tr--#{$i}th.is-expandable {
|
||||||
|
.#{$ns}Table-expandCell + td {
|
||||||
|
padding-left: px2rem(18px) * ($i - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tr.#{$ns}Table-tr--#{$i}th.is-last:not(.is-expanded) {
|
||||||
|
.#{$ns}Table-expandCell + td {
|
||||||
|
&::before {
|
||||||
|
height: 50%;
|
||||||
|
bottom: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> thead > tr > th.#{$ns}Table-checkCell,
|
||||||
|
> tbody > tr > td.#{$ns}Table-checkCell {
|
||||||
|
border-right: 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
.#{$ns}Checkbox {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> thead > tr > th.#{$ns}Table-expandCell,
|
||||||
|
> tbody > tr > td.#{$ns}Table-expandCell {
|
||||||
|
border-right: 0;
|
||||||
|
width: px2rem(1px);
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
> thead > tr > th.#{$ns}Table-dragCell,
|
||||||
|
> tbody > tr > td.#{$ns}Table-dragCell {
|
||||||
|
border-right: 0;
|
||||||
|
width: px2rem(1px);
|
||||||
|
padding-right: 0;
|
||||||
|
cursor: move;
|
||||||
|
> svg {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> tbody > tr > td.#{$ns}Table-expandCell {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
@for $i from 1 through 7 {
|
||||||
|
.#{$ns}Table-divider-#{$i} {
|
||||||
|
position: absolute;
|
||||||
|
width: px2rem(1px);
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
height: 100%;
|
||||||
|
background: var(--Table-tree-borderColor);
|
||||||
|
right: px2rem(7px) + px2rem(-18px) * ($i - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> tbody > tr.is-expanded > td.#{$ns}Table-expandCell {
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: px2rem(1px);
|
||||||
|
top: 50%;
|
||||||
|
bottom: 0;
|
||||||
|
right: px2rem(7px);
|
||||||
|
height: auto;
|
||||||
|
background: var(--Table-tree-borderColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> thead > tr > th.#{$ns}TableCell--sortable {
|
||||||
|
padding-right: calc(
|
||||||
|
var(--TableCell-paddingX) + var(--TableCell-sortBtn-width)
|
||||||
|
);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
> thead > tr > th.#{$ns}TableCell--searchable {
|
||||||
|
padding-right: calc(
|
||||||
|
var(--TableCell-paddingX) + var(--TableCell-searchBtn-width)
|
||||||
|
);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
> thead > tr > th.#{$ns}TableCell--filterable {
|
||||||
|
padding-right: calc(
|
||||||
|
var(--TableCell-paddingX) + var(--TableCell-filterBtn-width)
|
||||||
|
);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
> tbody > tr.#{$ns}Table-row-disabled {
|
||||||
|
background: var(--TableRow-onDisabled-bg);
|
||||||
|
color: var(--TableRow-onDisabled-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
> tbody > tr:not(.#{$ns}Table-row-disabled) > td.#{$ns}Table-cell-row-hover {
|
||||||
|
background: var(--Table-onHover-bg);
|
||||||
|
border-color: var(--Table-onHover-borderColor);
|
||||||
|
color: var(--Table-onHover-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
> thead > tr > th.#{$ns}Table-cell-fix-left-last,
|
||||||
|
> tbody > tr > td.#{$ns}Table-cell-fix-left-last,
|
||||||
|
> tfoot > tr > td.#{$ns}Table-cell-fix-left-last {
|
||||||
|
&:after {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: -1px;
|
||||||
|
width: 30px;
|
||||||
|
transform: translate(100%);
|
||||||
|
transition: box-shadow .3s;
|
||||||
|
content: "";
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> thead > tr > th.#{$ns}Table-cell-fix-right-first,
|
||||||
|
> tbody > tr > td.#{$ns}Table-cell-fix-right-first,
|
||||||
|
> tfoot > tr > td.#{$ns}Table-cell-fix-right-last {
|
||||||
|
&:after {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: -1px;
|
||||||
|
left: 0;
|
||||||
|
width: 30px;
|
||||||
|
transform: translate(-100%);
|
||||||
|
transition: box-shadow .3s;
|
||||||
|
content: "";
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> tbody > tr > td.#{$ns}Table-cell-expand-icon-cell {
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.#{$ns}Table-row-indent {
|
||||||
|
height: 1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> tbody > tr.#{$ns}Table-expanded-row > td {
|
||||||
|
background: var(--Table-onHover-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
> tfoot > tr {
|
||||||
|
border-bottom: var(--Table-borderWidth) solid var(--Table-borderColor);
|
||||||
|
|
||||||
|
> td {
|
||||||
|
padding: var(--TableCell-paddingY-default) var(--TableCell-paddingX);
|
||||||
|
background: var(--Table-thead-bg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}Table-container {
|
||||||
|
.#{$ns}Table-header {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.#{$ns}Table-ping-left {
|
||||||
|
.#{$ns}Table-table {
|
||||||
|
> thead > tr > th.#{$ns}Table-cell-fix-left-last,
|
||||||
|
> tbody > tr > td.#{$ns}Table-cell-fix-left-last,
|
||||||
|
> tfoot > tr > td.#{$ns}Table-cell-fix-left-last {
|
||||||
|
&:after {
|
||||||
|
box-shadow: var(--Table-fixedLeftLast-boxShadow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> tbody > tr:not(.#{$ns}Table-row-disabled) {
|
||||||
|
> td.#{$ns}Table-cell-fix-left {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
> td.#{$ns}Table-cell-fix-left:not(.#{$ns}Table-cell-row-hover) {
|
||||||
|
background: #FFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> tfoot > tr > td:not(:last-child) {
|
||||||
|
&.#{$ns}Table-cell-fix-left-last {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> thead > tr > th:not(:last-child):not(:first-child) {
|
||||||
|
&.#{$ns}Table-cell-fix-left-last {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.#{$ns}Table-ping-right {
|
||||||
|
.#{$ns}Table-table {
|
||||||
|
> thead > tr > th.#{$ns}Table-cell-fix-right-first,
|
||||||
|
> tbody > tr > td.#{$ns}Table-cell-fix-right-first,
|
||||||
|
> tfoot > tr > td.#{$ns}Table-cell-fix-right-first {
|
||||||
|
&:after {
|
||||||
|
box-shadow: var(--Table-fixedRightFirst-boxShadow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> tbody > tr:not(.#{$ns}Table-row-disabled) {
|
||||||
|
> td.#{$ns}Table-cell-fix-right {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
> td.#{$ns}Table-cell-fix-right:not(.#{$ns}Table-cell-row-hover) {
|
||||||
|
background: #FFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(.#{$ns}Table-bordered) {
|
||||||
|
.#{$ns}Table-table {
|
||||||
|
> thead > tr > th.#{$ns}Table-cell-fix-right-first-prev {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
> thead > tr > th:not(:last-child) {
|
||||||
|
&.#{$ns}Table-cell-fix-right-first {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.#{$ns}Table-resizable {
|
||||||
|
.#{$ns}Table-table {
|
||||||
|
> thead > tr > th {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.#{$ns}Table-thead-resizable {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
cursor: col-resize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}Table-loading {
|
||||||
|
padding: var(--Table-loading-padding);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}TableCell-sortBtn {
|
||||||
|
cursor: pointer;
|
||||||
|
width: var(--TableCell-sortBtn-width);
|
||||||
|
height: var(--gap-md);
|
||||||
|
position: static;
|
||||||
|
display: inline-block;
|
||||||
|
transform: none;
|
||||||
|
color: var(--icon-color);
|
||||||
|
margin-left: var(--TableCell-icon-gap);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--icon-onHover-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--up > svg,
|
||||||
|
&--down > svg,
|
||||||
|
&--default > svg {
|
||||||
|
color: inherit;
|
||||||
|
width: 13px;
|
||||||
|
height: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--up,
|
||||||
|
&--down,
|
||||||
|
&--default {
|
||||||
|
display: none;
|
||||||
|
z-index: 2;
|
||||||
|
font-style: normal;
|
||||||
|
|
||||||
|
&.is-active {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--default {
|
||||||
|
&.is-active {
|
||||||
|
color: var(--text--muted-color);
|
||||||
|
&:hover {
|
||||||
|
color: var(--text-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&--up,
|
||||||
|
&--down {
|
||||||
|
&.is-active {
|
||||||
|
color: var(--TableCell-sortBtn--onActive-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}TableCell-searchBtn {
|
||||||
|
cursor: pointer;
|
||||||
|
position: static;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
color: var(--text--muted-color);
|
||||||
|
margin-left: var(--TableCell-icon-gap);
|
||||||
|
|
||||||
|
svg.icon {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--text-color);
|
||||||
|
}
|
||||||
|
&.is-active {
|
||||||
|
color: var(--TableCell-searchBtn--onActive-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}TableCell-searchPopOver {
|
||||||
|
border: none;
|
||||||
|
min-width: px2rem(320px);
|
||||||
|
max-width: px2rem(640px);
|
||||||
|
|
||||||
|
.#{$ns}Panel {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}TableCell-filterBtn {
|
||||||
|
cursor: pointer;
|
||||||
|
width: var(--TableCell-filterBtn-width);
|
||||||
|
position: static;
|
||||||
|
display: inline-block;
|
||||||
|
transform: none;
|
||||||
|
color: var(--text--muted-color);
|
||||||
|
margin-left: var(--TableCell-icon-gap);
|
||||||
|
|
||||||
|
svg.icon {
|
||||||
|
width: 13px;
|
||||||
|
height: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-active {
|
||||||
|
color: var(--TableCell-filterBtn--onActive-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}Remark {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}TableCell-filterPopOver {
|
||||||
|
border: none;
|
||||||
|
width: px2rem(160px);
|
||||||
|
|
||||||
|
.#{$ns}DropDown-menu {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
.#{$ns}DropDown-divider {
|
||||||
|
height: var(--TableCell-filterPopOver-dropDownItem-height);
|
||||||
|
line-height: var(--TableCell-filterPopOver-dropDownItem-height);
|
||||||
|
padding: var(--TableCell-filterPopOver-dropDownItem-padding);
|
||||||
|
background: var(--white);
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: var(--light);
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-selected {
|
||||||
|
background: var(--light);
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}Checkbox {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}DropDown-multiple-menu {
|
||||||
|
text-align: center;
|
||||||
|
border-top: 1px solid var(--Table-borderColor);
|
||||||
|
|
||||||
|
.#{$ns}Button {
|
||||||
|
margin: 0 5px;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}TableCell-selectionBtn {
|
||||||
|
cursor: pointer;
|
||||||
|
margin-left: 4px;
|
||||||
|
|
||||||
|
svg.icon {
|
||||||
|
transform: rotate(270deg);
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}TableCell-selectionPopOver {
|
||||||
|
.#{$ns}DropDown-menu {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.#{$ns}Table-expandBtn {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
color: var(--Table-expandBtn-color);
|
||||||
|
display: inline-flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: px2rem(14px);
|
||||||
|
line-height: 1;
|
||||||
|
height: 16px;
|
||||||
|
|
||||||
|
> svg {
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: transform ease-in-out var(--animation-duration),
|
||||||
|
top ease-in-out var(--animation-duration);
|
||||||
|
position: relative;
|
||||||
|
transform-origin: 50% 50%;
|
||||||
|
width: px2rem(10px);
|
||||||
|
height: px2rem(10px);
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-active > svg {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}Table-table > tbody > tr:hover .#{$ns}Table-dragBtn,
|
||||||
|
.#{$ns}Table-table > tbody > tr.is-dragging .#{$ns}Table-dragBtn,
|
||||||
|
.#{$ns}Table-table > tbody > tr.is-drop-allowed .#{$ns}Table-dragBtn {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fake-hide {
|
||||||
|
visibility: hidden;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}Table-badge {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}InputTable-toolbar {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}InputTable-pager {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}OperationField {
|
||||||
|
margin: px2rem(-3px);
|
||||||
|
|
||||||
|
> .#{$ns}Button,
|
||||||
|
> .#{$ns}Button--disabled-wrap > .#{$ns}Button {
|
||||||
|
margin: px2rem(3px);
|
||||||
|
}
|
||||||
|
|
||||||
|
> .#{$ns}Button--disabled-wrap > .#{$ns}Button--link {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .#{$ns}Button--link {
|
||||||
|
padding: 0;
|
||||||
|
margin-right: px2rem(10px);
|
||||||
|
}
|
||||||
|
}
|
@ -8,34 +8,6 @@
|
|||||||
margin-bottom: var(--gap-sm);
|
margin-bottom: var(--gap-sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
&-bordered {
|
|
||||||
border: var(--Table-borderWidth) solid var(--Table-borderColor);
|
|
||||||
border-collapse: inherit;
|
|
||||||
|
|
||||||
.#{$ns}Table-container {
|
|
||||||
border-top: var(--Table-borderWidth) solid var(--Table-borderColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
.#{$ns}Table-table {
|
|
||||||
> thead > tr > th,
|
|
||||||
> tbody > tr > td,
|
|
||||||
> tfoot > tr > td {
|
|
||||||
border-right: var(--Table-borderWidth) solid var(--Table-borderColor);
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
border-right: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.#{$ns}Table-footer {
|
|
||||||
border-top: var(--Table-borderWidth) solid var(--Table-borderColor);
|
|
||||||
}
|
|
||||||
.#{$ns}Table-title {
|
|
||||||
border-bottom: var(--Table-borderWidth) solid var(--Table-borderColor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&-fixedLeft,
|
&-fixedLeft,
|
||||||
&-fixedRight {
|
&-fixedRight {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -127,9 +99,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&-heading,
|
&-heading {
|
||||||
&-title,
|
|
||||||
&-footer {
|
|
||||||
background: var(--Table-heading-bg);
|
background: var(--Table-heading-bg);
|
||||||
padding: calc(
|
padding: calc(
|
||||||
(
|
(
|
||||||
@ -261,6 +231,7 @@
|
|||||||
background: var(--Table-bg);
|
background: var(--Table-bg);
|
||||||
border-spacing: 0;
|
border-spacing: 0;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
|
border: var(--Table-borderWidth) solid var(--Table-borderColor);
|
||||||
|
|
||||||
& th,
|
& th,
|
||||||
& td {
|
& td {
|
||||||
@ -632,124 +603,6 @@
|
|||||||
);
|
);
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
> tbody > tr > td.#{$ns}Table-cell-fix-left,
|
|
||||||
> tbody > tr > td.#{$ns}Table-cell-fix-right,
|
|
||||||
> tfoot > tr > td.#{$ns}Table-cell-fix-left,
|
|
||||||
> tfoot > tr > td.#{$ns}Table-cell-fix-right {
|
|
||||||
background: #FFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
> tbody > tr > td.#{$ns}Table-cell-row-hover {
|
|
||||||
background: var(--Table-onHover-bg);
|
|
||||||
border-color: var(--Table-onHover-borderColor);
|
|
||||||
color: var(--Table-onHover-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
> thead > tr > th.#{$ns}Table-cell-fix-left-last,
|
|
||||||
> tbody > tr > td.#{$ns}Table-cell-fix-left-last,
|
|
||||||
> tfoot > tr > td.#{$ns}Table-cell-fix-left-last {
|
|
||||||
&:after {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: -1px;
|
|
||||||
width: 30px;
|
|
||||||
transform: translate(100%);
|
|
||||||
transition: box-shadow .3s;
|
|
||||||
content: "";
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> thead > tr > th.#{$ns}Table-cell-fix-right-first,
|
|
||||||
> tbody > tr > td.#{$ns}Table-cell-fix-right-first,
|
|
||||||
> tfoot > tr > td.#{$ns}Table-cell-fix-right-last {
|
|
||||||
&:after {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
bottom: -1px;
|
|
||||||
left: 0;
|
|
||||||
width: 30px;
|
|
||||||
transform: translate(-100%);
|
|
||||||
transition: box-shadow .3s;
|
|
||||||
content: "";
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> tbody > tr > td.#{$ns}Table-cell-expand-icon-cell {
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
.fa-minus-square,
|
|
||||||
.fa-plus-square {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> tbody > tr.#{$ns}Table-expanded-row > td {
|
|
||||||
background: var(--Table-onHover-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
> tfoot > tr > td {
|
|
||||||
padding: var(--TableCell-paddingY) var(--TableCell-paddingX);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&-container {
|
|
||||||
.#{$ns}Table-header {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.#{$ns}Table-ping-left {
|
|
||||||
.#{$ns}Table-table {
|
|
||||||
> thead > tr > th.#{$ns}Table-cell-fix-left-last,
|
|
||||||
> tbody > tr > td.#{$ns}Table-cell-fix-left-last,
|
|
||||||
> tfoot > tr > td.#{$ns}Table-cell-fix-left-last {
|
|
||||||
&:after {
|
|
||||||
box-shadow: var(--Table-fixedLeftLast-boxShadow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.#{$ns}Table-ping-right {
|
|
||||||
.#{$ns}Table-table {
|
|
||||||
> thead > tr > th.#{$ns}Table-cell-fix-right-first,
|
|
||||||
> tbody > tr > td.#{$ns}Table-cell-fix-right-first,
|
|
||||||
> tfoot > tr > td.#{$ns}Table-cell-fix-right-first {
|
|
||||||
&:after {
|
|
||||||
box-shadow: var(--Table-fixedRightFirst-boxShadow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> thead > tr > th.#{$ns}Table-cell-fix-right-first {
|
|
||||||
border-right: var(--Table-thead-borderWidth) solid var(--Table-thead-borderColor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.#{$ns}Table-resizable {
|
|
||||||
.#{$ns}Table-table {
|
|
||||||
> thead > tr > th {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
.#{$ns}Table-thead-resizable {
|
|
||||||
position: absolute;
|
|
||||||
width: 1px;
|
|
||||||
right: 0;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
cursor: col-resize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.#{$ns}Table-loading {
|
|
||||||
padding: var(--Table-loading-padding);
|
|
||||||
text-align: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&Cell-sortBtn {
|
&Cell-sortBtn {
|
||||||
@ -805,9 +658,6 @@
|
|||||||
color: var(--TableCell-sortBtn--onActive-color);
|
color: var(--TableCell-sortBtn--onActive-color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&:not(:last-child) {
|
|
||||||
right: calc(var(--TableCell-paddingX) - var(--TableCell-sortBtn-width) / 2 + 15px);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&Cell-searchBtn {
|
&Cell-searchBtn {
|
||||||
@ -903,20 +753,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.#{$ns}DropDown-multiple-menu {
|
|
||||||
text-align: center;
|
|
||||||
border-top: 1px solid var(--Table-borderColor);
|
|
||||||
|
|
||||||
.#{$ns}Button {
|
|
||||||
margin: 0 5px;
|
|
||||||
padding: 0 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&-itemActions-wrap {
|
&-itemActions-wrap {
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
@import '../components/wizard';
|
@import '../components/wizard';
|
||||||
@import '../components/crud';
|
@import '../components/crud';
|
||||||
@import '../components/table';
|
@import '../components/table';
|
||||||
|
@import '../components/table-v2';
|
||||||
@import '../components/column-toggler';
|
@import '../components/column-toggler';
|
||||||
@import '../components/list';
|
@import '../components/list';
|
||||||
@import '../components/cards';
|
@import '../components/cards';
|
||||||
|
@ -369,13 +369,13 @@ $L1: 0px 4px 6px 0px rgba(8, 14, 26, 0.06),
|
|||||||
--Table-color: #333;
|
--Table-color: #333;
|
||||||
--Table-thead-color: #333;
|
--Table-thead-color: #333;
|
||||||
--Table-lineHeight: 20 / 12;
|
--Table-lineHeight: 20 / 12;
|
||||||
--Table-borderColor: #f5f5f5;
|
--Table-borderColor: #{$G8};
|
||||||
--Table-tree-borderColor: #{darken(#f5f5f5, 10%)};
|
--Table-tree-borderColor: #{darken(#f5f5f5, 10%)};
|
||||||
--Table-thead-bg: #f5f5f5;
|
--Table-thead-bg: #{$G10};
|
||||||
--Table-thead-borderColor: #fff;
|
--Table-thead-borderColor: #fff;
|
||||||
--Table-thead-iconColor: #999;
|
--Table-thead-iconColor: #999;
|
||||||
--Table-strip-bg: transparent;
|
--Table-strip-bg: transparent;
|
||||||
--Table-onHover-bg: #f5f5f5;
|
--Table-onHover-bg: #{$B1};
|
||||||
--Table-onHover-bg-rgb: 245, 251, 255;
|
--Table-onHover-bg-rgb: 245, 251, 255;
|
||||||
--Table-onHover-borderColor: #eceff8;
|
--Table-onHover-borderColor: #eceff8;
|
||||||
--Table-onChecked-bg: #f0faff;
|
--Table-onChecked-bg: #f0faff;
|
||||||
@ -391,6 +391,9 @@ $L1: 0px 4px 6px 0px rgba(8, 14, 26, 0.06),
|
|||||||
--TableCell-filterPopOver-dropDownItem-height: #{px2rem(30px)};
|
--TableCell-filterPopOver-dropDownItem-height: #{px2rem(30px)};
|
||||||
--TableCell-filterPopOver-dropDownItem-padding: 0 #{px2rem(10px)};
|
--TableCell-filterPopOver-dropDownItem-padding: 0 #{px2rem(10px)};
|
||||||
|
|
||||||
|
--TableRow-onDisabled-bg: #{$G10};
|
||||||
|
--TableRow-onDisabled-color: #{$G6};
|
||||||
|
|
||||||
// listControl
|
// listControl
|
||||||
--ListControl-item-borderWidth: #{px2rem(1px)};
|
--ListControl-item-borderWidth: #{px2rem(1px)};
|
||||||
--ListControl-item-borderRadius: #{$R3};
|
--ListControl-item-borderRadius: #{$R3};
|
||||||
|
@ -118,6 +118,7 @@ import {FormControlSchema} from './renderers/Form/Control';
|
|||||||
import {TransferPickerControlSchema} from './renderers/Form/TransferPicker';
|
import {TransferPickerControlSchema} from './renderers/Form/TransferPicker';
|
||||||
import {TabsTransferPickerControlSchema} from './renderers/Form/TabsTransferPicker';
|
import {TabsTransferPickerControlSchema} from './renderers/Form/TabsTransferPicker';
|
||||||
import {JSONSchemaEditorControlSchema} from './renderers/Form/JSONSchemaEditor';
|
import {JSONSchemaEditorControlSchema} from './renderers/Form/JSONSchemaEditor';
|
||||||
|
import {TableSchemaV2} from './renderers/Table-v2';
|
||||||
|
|
||||||
// 每加个类型,这补充一下。
|
// 每加个类型,这补充一下。
|
||||||
export type SchemaType =
|
export type SchemaType =
|
||||||
@ -392,6 +393,7 @@ export type SchemaObject =
|
|||||||
| StatusSchema
|
| StatusSchema
|
||||||
| SpinnerSchema
|
| SpinnerSchema
|
||||||
| TableSchema
|
| TableSchema
|
||||||
|
| TableSchemaV2
|
||||||
| TabsSchema
|
| TabsSchema
|
||||||
| TasksSchema
|
| TasksSchema
|
||||||
| VBoxSchema
|
| VBoxSchema
|
||||||
|
@ -20,12 +20,16 @@ export interface Props extends ThemeProps, LocaleProps {
|
|||||||
children?: any;
|
children?: any;
|
||||||
tagName?: string;
|
tagName?: string;
|
||||||
style?: Object;
|
style?: Object;
|
||||||
column?: ColumnProps
|
column?: ColumnProps;
|
||||||
|
wrapperComponent: any;
|
||||||
|
groupId?: string; // 表头分组随机生成的id
|
||||||
|
depth?: number; // 表头分组
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BodyCell extends React.Component<Props> {
|
export class BodyCell extends React.Component<Props> {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
fixed: '',
|
fixed: '',
|
||||||
|
wrapperComponent: 'td',
|
||||||
rowSpan: null,
|
rowSpan: null,
|
||||||
colSpan: null
|
colSpan: null
|
||||||
};
|
};
|
||||||
@ -38,28 +42,16 @@ export class BodyCell extends React.Component<Props> {
|
|||||||
key,
|
key,
|
||||||
children,
|
children,
|
||||||
className,
|
className,
|
||||||
tagName,
|
|
||||||
style,
|
|
||||||
column,
|
column,
|
||||||
|
style,
|
||||||
|
groupId,
|
||||||
|
depth,
|
||||||
|
wrapperComponent: Component,
|
||||||
classnames: cx
|
classnames: cx
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
if (tagName === 'TH') {
|
|
||||||
return (
|
return (
|
||||||
<th
|
<Component
|
||||||
key={key || null}
|
|
||||||
rowSpan={rowSpan && rowSpan > 1 ? rowSpan : null}
|
|
||||||
colSpan={colSpan && colSpan > 1 ? colSpan : null}
|
|
||||||
className={cx('Table-cell', className, {
|
|
||||||
[cx(`Table-cell-fix-${fixed}`)] : fixed
|
|
||||||
})}
|
|
||||||
style={fixed ? {position: 'sticky', zIndex} : style}
|
|
||||||
>{children}</th>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<td
|
|
||||||
key={key || null}
|
key={key || null}
|
||||||
rowSpan={rowSpan && rowSpan > 1 ? rowSpan : null}
|
rowSpan={rowSpan && rowSpan > 1 ? rowSpan : null}
|
||||||
colSpan={colSpan && colSpan > 1 ? colSpan : null}
|
colSpan={colSpan && colSpan > 1 ? colSpan : null}
|
||||||
@ -67,8 +59,10 @@ export class BodyCell extends React.Component<Props> {
|
|||||||
[cx(`Table-cell-fix-${fixed}`)] : fixed,
|
[cx(`Table-cell-fix-${fixed}`)] : fixed,
|
||||||
[`text-${column?.align}`] : column?.align
|
[`text-${column?.align}`] : column?.align
|
||||||
})}
|
})}
|
||||||
style={fixed ? {position: 'sticky', zIndex} : {}}
|
style={fixed ? {position: 'sticky', zIndex, ...style} : {...style}}
|
||||||
>{children}</td>
|
data-group-id={groupId || null}
|
||||||
|
data-depth={depth || null}
|
||||||
|
>{children}</Component>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
115
src/components/table/HeadCellDropDown.tsx
Normal file
115
src/components/table/HeadCellDropDown.tsx
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/**
|
||||||
|
* @file table/HeadCellDropDown
|
||||||
|
* @author fex
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import {findDOMNode} from 'react-dom';
|
||||||
|
|
||||||
|
import {themeable, ThemeProps} from '../../theme';
|
||||||
|
import {LocaleProps, localeable} from '../../locale';
|
||||||
|
import Overlay from '../Overlay';
|
||||||
|
import PopOver from '../PopOver';
|
||||||
|
|
||||||
|
export interface FilterPayload {
|
||||||
|
closeDropdown?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FilterDropdownProps {
|
||||||
|
setSelectedKeys?: (keys: Array<string | number> | string) => void,
|
||||||
|
selectedKeys?: Array<string | number> | string,
|
||||||
|
confirm: (payload: FilterPayload) => void,
|
||||||
|
clearFilters?: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Props extends ThemeProps, LocaleProps {
|
||||||
|
filterIcon: Function | React.ReactNode; // 图标方法 返回ReactNode
|
||||||
|
className: string; // 图标样式
|
||||||
|
layerClassName: string; // 展开层样式
|
||||||
|
active: boolean; // 图标是否高亮
|
||||||
|
popOverContainer?: () => Element | Text | null;
|
||||||
|
filterDropdown: (payload: FilterDropdownProps) => JSX.Element | null ; // 菜单内容
|
||||||
|
selectedKeys?: Array<string | number> | string;
|
||||||
|
setSelectedKeys?: (keys: Array<string | number> | string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface State {
|
||||||
|
isOpened: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class HeadCellDropDown extends React.Component<Props, State> {
|
||||||
|
constructor(props: Props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
isOpened: false
|
||||||
|
}
|
||||||
|
|
||||||
|
this.openLayer = this.openLayer.bind(this);
|
||||||
|
this.closeLayer = this.closeLayer.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {isOpened} = this.state;
|
||||||
|
const {
|
||||||
|
popOverContainer,
|
||||||
|
active,
|
||||||
|
className,
|
||||||
|
layerClassName,
|
||||||
|
filterIcon,
|
||||||
|
filterDropdown,
|
||||||
|
classnames: cx,
|
||||||
|
classPrefix: ns
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span
|
||||||
|
className={cx(
|
||||||
|
className,
|
||||||
|
active ? 'is-active' : ''
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<span onClick={this.openLayer}>
|
||||||
|
{filterIcon && typeof filterIcon === 'function'
|
||||||
|
? filterIcon(active) : (filterIcon || null)}
|
||||||
|
</span>
|
||||||
|
{
|
||||||
|
isOpened ? (
|
||||||
|
<Overlay
|
||||||
|
container={popOverContainer || (() => findDOMNode(this))}
|
||||||
|
placement="left-bottom-left-top right-bottom-right-top"
|
||||||
|
target={
|
||||||
|
popOverContainer ? () => findDOMNode(this)!.parentNode : null
|
||||||
|
}
|
||||||
|
show
|
||||||
|
>
|
||||||
|
<PopOver
|
||||||
|
classPrefix={ns}
|
||||||
|
onHide={this.closeLayer}
|
||||||
|
className={cx(layerClassName)}
|
||||||
|
overlay
|
||||||
|
>
|
||||||
|
{filterDropdown && typeof filterDropdown === 'function'
|
||||||
|
? filterDropdown({...this.props, confirm: (payload: FilterPayload) => {
|
||||||
|
if (!(payload && payload.closeDropdown === false)) {
|
||||||
|
this.closeLayer();
|
||||||
|
}
|
||||||
|
}}) : (filterDropdown || null)}
|
||||||
|
</PopOver>
|
||||||
|
</Overlay>)
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
openLayer() {
|
||||||
|
this.setState({isOpened: true});
|
||||||
|
}
|
||||||
|
|
||||||
|
closeLayer() {
|
||||||
|
this.setState({isOpened: false});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default themeable(localeable(HeadCellDropDown));
|
@ -9,19 +9,17 @@ import isEqual from 'lodash/isEqual';
|
|||||||
|
|
||||||
import {themeable, ThemeProps} from '../../theme';
|
import {themeable, ThemeProps} from '../../theme';
|
||||||
import {LocaleProps, localeable} from '../../locale';
|
import {LocaleProps, localeable} from '../../locale';
|
||||||
import Overlay from '../Overlay';
|
import HeadCellDropDown, {FilterDropdownProps, FilterPayload} from './HeadCellDropDown';
|
||||||
import PopOver from '../PopOver';
|
|
||||||
import CheckBox from '../Checkbox';
|
import CheckBox from '../Checkbox';
|
||||||
import Button from '../Button';
|
import Button from '../Button';
|
||||||
import {Icon} from '../icons';
|
import {Icon} from '../icons';
|
||||||
|
|
||||||
export interface Props extends ThemeProps, LocaleProps {
|
export interface Props extends ThemeProps, LocaleProps {
|
||||||
column: any;
|
column: any;
|
||||||
popOverContainer?: () => Element | Text | null;
|
|
||||||
onFilter?: Function;
|
onFilter?: Function;
|
||||||
onQuery?: Function;
|
|
||||||
filteredValue?: Array<string>;
|
filteredValue?: Array<string>;
|
||||||
filterMultiple?: boolean;
|
filterMultiple?: boolean;
|
||||||
|
popOverContainer?: () => Element | Text | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OptionProps {
|
export interface OptionProps {
|
||||||
@ -33,7 +31,6 @@ export interface OptionProps {
|
|||||||
|
|
||||||
export interface State {
|
export interface State {
|
||||||
options: Array<OptionProps>;
|
options: Array<OptionProps>;
|
||||||
isOpened: boolean;
|
|
||||||
filteredValue: Array<string>;
|
filteredValue: Array<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,17 +45,11 @@ export class HeadCellFilter extends React.Component<Props, State> {
|
|||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
options: [],
|
options: [],
|
||||||
isOpened: false,
|
|
||||||
filteredValue: props.filteredValue || []
|
filteredValue: props.filteredValue || []
|
||||||
}
|
}
|
||||||
|
|
||||||
this.openLayer = this.openLayer.bind(this);
|
|
||||||
this.closeLayer = this.closeLayer.bind(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
alterOptions(options: Array<any>) {
|
alterOptions(options: Array<any>) {
|
||||||
const {column} = this.props;
|
|
||||||
|
|
||||||
options = options.map(option => ({
|
options = options.map(option => ({
|
||||||
...option,
|
...option,
|
||||||
selected: this.state.filteredValue.indexOf(option.value) > -1
|
selected: this.state.filteredValue.indexOf(option.value) > -1
|
||||||
@ -83,7 +74,7 @@ export class HeadCellFilter extends React.Component<Props, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {isOpened, options} = this.state;
|
const {options} = this.state;
|
||||||
const {
|
const {
|
||||||
column,
|
column,
|
||||||
popOverContainer,
|
popOverContainer,
|
||||||
@ -91,35 +82,10 @@ export class HeadCellFilter extends React.Component<Props, State> {
|
|||||||
classPrefix: ns
|
classPrefix: ns
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return (
|
const filterProps = {
|
||||||
<span
|
filterDropdown: (payload: FilterDropdownProps) => {
|
||||||
className={cx(
|
const {setSelectedKeys, selectedKeys, confirm, clearFilters} = payload
|
||||||
`${ns}TableCell-filterBtn`,
|
return options && options.length > 0 ? (
|
||||||
column.filtered || options && options.some((item: any) => item.selected) ? 'is-active' : ''
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<span onClick={this.openLayer}>
|
|
||||||
<Icon icon="column-filter" className="icon" />
|
|
||||||
</span>
|
|
||||||
{
|
|
||||||
isOpened ? (
|
|
||||||
<Overlay
|
|
||||||
container={popOverContainer || (() => findDOMNode(this))}
|
|
||||||
placement="left-bottom-left-top right-bottom-right-top"
|
|
||||||
target={
|
|
||||||
popOverContainer ? () => findDOMNode(this) : null
|
|
||||||
}
|
|
||||||
show
|
|
||||||
>
|
|
||||||
<PopOver
|
|
||||||
classPrefix={ns}
|
|
||||||
onHide={this.closeLayer}
|
|
||||||
className={cx(
|
|
||||||
`${ns}TableCell-filterPopOver`
|
|
||||||
)}
|
|
||||||
overlay
|
|
||||||
>
|
|
||||||
{options && options.length > 0 ? (
|
|
||||||
<ul className={cx('DropDown-menu')}>
|
<ul className={cx('DropDown-menu')}>
|
||||||
{!column.filterMultiple
|
{!column.filterMultiple
|
||||||
? options.map((option: any, index) => (
|
? options.map((option: any, index) => (
|
||||||
@ -128,7 +94,7 @@ export class HeadCellFilter extends React.Component<Props, State> {
|
|||||||
className={cx({
|
className={cx({
|
||||||
'is-active': option.selected
|
'is-active': option.selected
|
||||||
})}
|
})}
|
||||||
onClick={this.handleClick.bind(this, option.value)}
|
onClick={() => this.handleClick(confirm, setSelectedKeys, [option.value])}
|
||||||
>
|
>
|
||||||
{option.text}
|
{option.text}
|
||||||
</li>
|
</li>
|
||||||
@ -137,7 +103,9 @@ export class HeadCellFilter extends React.Component<Props, State> {
|
|||||||
<li key={index}>
|
<li key={index}>
|
||||||
<CheckBox
|
<CheckBox
|
||||||
classPrefix={ns}
|
classPrefix={ns}
|
||||||
onChange={this.handleCheck.bind(this, option.value)}
|
onChange={e =>
|
||||||
|
this.handleCheck(confirm, setSelectedKeys, e
|
||||||
|
? [option.value] : option.value)}
|
||||||
checked={option.selected}
|
checked={option.selected}
|
||||||
>
|
>
|
||||||
{option.text}
|
{option.text}
|
||||||
@ -146,65 +114,79 @@ export class HeadCellFilter extends React.Component<Props, State> {
|
|||||||
))}
|
))}
|
||||||
{column.filterMultiple ? (
|
{column.filterMultiple ? (
|
||||||
<li
|
<li
|
||||||
key="DropDown-multiple-menu"
|
key="dropDown-multiple-menu"
|
||||||
className={cx('DropDown-multiple-menu')}
|
className={cx('DropDown-multiple-menu')}
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
size={'xs'}
|
size={'xs'}
|
||||||
level={'primary'}
|
level={'primary'}
|
||||||
onClick={this.handleConfirmClick.bind(this)}
|
onClick={() => this.handleConfirmClick(confirm)}
|
||||||
>确定</Button>
|
>确定</Button>
|
||||||
<Button
|
<Button
|
||||||
size={'xs'}
|
size={'xs'}
|
||||||
onClick={this.handleCancelClick.bind(this)}
|
onClick={() => this.handleCancelClick(confirm, setSelectedKeys)}
|
||||||
>取消</Button>
|
>取消</Button>
|
||||||
</li>
|
</li>
|
||||||
) : null}
|
) : null}
|
||||||
</ul>
|
</ul>
|
||||||
) : null}
|
) : null
|
||||||
</PopOver>
|
},
|
||||||
</Overlay>)
|
setSelectedKeys: (keys: Array<string>) => this.setState({filteredValue: keys})
|
||||||
: null
|
};
|
||||||
}
|
|
||||||
</span>
|
return (
|
||||||
|
<HeadCellDropDown
|
||||||
|
className={`${ns}TableCell-filterBtn`}
|
||||||
|
layerClassName={`${ns}TableCell-filterPopOver`}
|
||||||
|
filterIcon={<Icon icon="column-filter" className="icon" />}
|
||||||
|
active={column.filtered || options && options.some((item: any) => item.selected)}
|
||||||
|
popOverContainer={popOverContainer ? popOverContainer : () => findDOMNode(this)}
|
||||||
|
selectedKeys={this.state.filteredValue}
|
||||||
|
{...filterProps}
|
||||||
|
>
|
||||||
|
</HeadCellDropDown>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
openLayer() {
|
handleClick(
|
||||||
this.setState({isOpened: true});
|
confirm: (payload?: FilterPayload) => void,
|
||||||
|
setSelectedKeys?: (keys?: (string | Array<string | number>)) => void,
|
||||||
|
selectedKeys?: Array<string>
|
||||||
|
) {
|
||||||
|
const {onFilter, column} = this.props;
|
||||||
|
|
||||||
|
setSelectedKeys && setSelectedKeys(selectedKeys);
|
||||||
|
|
||||||
|
onFilter && onFilter({[column.key] : selectedKeys});
|
||||||
|
confirm();
|
||||||
}
|
}
|
||||||
|
|
||||||
closeLayer() {
|
handleCheck(
|
||||||
this.setState({isOpened: false});
|
confirm: (payload?: FilterPayload) => void,
|
||||||
}
|
setSelectedKeys?: ((keys: (string | Array<string | number>)) => void | undefined),
|
||||||
|
selectedKeys?: Array<string>
|
||||||
handleClick(value: string) {
|
) {
|
||||||
const {onQuery, column} = this.props;
|
|
||||||
|
|
||||||
this.setState({filteredValue: [value]});
|
|
||||||
|
|
||||||
onQuery && onQuery({[column.key] : value});
|
|
||||||
this.closeLayer();
|
|
||||||
}
|
|
||||||
|
|
||||||
handleCheck(value: string) {
|
|
||||||
const filteredValue = this.state.filteredValue;
|
const filteredValue = this.state.filteredValue;
|
||||||
if (value) {
|
// 选中
|
||||||
this.setState({filteredValue: [...filteredValue, value]});
|
if (Array.isArray(selectedKeys)) {
|
||||||
} else {
|
setSelectedKeys && setSelectedKeys([...filteredValue, ...selectedKeys]);
|
||||||
this.setState({filteredValue: filteredValue.filter(v => v !== value)});
|
} else { // 取消选中
|
||||||
|
setSelectedKeys && setSelectedKeys(filteredValue.filter(v => v !== selectedKeys));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleConfirmClick() {
|
handleConfirmClick(confirm: (payload?: FilterPayload) => void) {
|
||||||
const {onQuery, column} = this.props;
|
const {onFilter, column} = this.props;
|
||||||
onQuery && onQuery({[column.key] : this.state.filteredValue});
|
onFilter && onFilter({[column.key] : this.state.filteredValue});
|
||||||
this.closeLayer();
|
confirm();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleCancelClick() {
|
handleCancelClick(
|
||||||
this.setState({filteredValue: []});
|
confirm: (payload?: FilterPayload) => void,
|
||||||
this.closeLayer();
|
setSelectedKeys?: ((keys: (string | Array<string | number>)) => void | undefined)
|
||||||
|
) {
|
||||||
|
setSelectedKeys && setSelectedKeys([]);
|
||||||
|
confirm();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
86
src/components/table/HeadCellSelect.tsx
Normal file
86
src/components/table/HeadCellSelect.tsx
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/**
|
||||||
|
* @file table/HeadCellSelect
|
||||||
|
* @author fex
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import {findDOMNode} from 'react-dom';
|
||||||
|
|
||||||
|
import {themeable, ThemeProps} from '../../theme';
|
||||||
|
import {LocaleProps, localeable} from '../../locale';
|
||||||
|
import HeadCellDropDown, {FilterPayload} from './HeadCellDropDown';
|
||||||
|
import {RowSelectionOptionProps} from './index';
|
||||||
|
import {Icon} from '../icons';
|
||||||
|
|
||||||
|
export interface Props extends ThemeProps, LocaleProps {
|
||||||
|
selections: Array<RowSelectionOptionProps>;
|
||||||
|
keys: Array<string | number> | string;
|
||||||
|
popOverContainer?: () => Element | Text | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface State {
|
||||||
|
key: Array<string | number> | string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class HeadCellSelect extends React.Component<Props, State> {
|
||||||
|
static defaultProps = {
|
||||||
|
selections: []
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor(props: Props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
key: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
selections,
|
||||||
|
keys: allKeys,
|
||||||
|
popOverContainer,
|
||||||
|
classnames: cx,
|
||||||
|
classPrefix: ns
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<HeadCellDropDown
|
||||||
|
className={`${ns}TableCell-selectionBtn`}
|
||||||
|
layerClassName={`${ns}TableCell-selectionPopOver`}
|
||||||
|
filterIcon={<Icon icon="left-arrow" className="icon" />}
|
||||||
|
active={false}
|
||||||
|
popOverContainer={popOverContainer ? popOverContainer : () => findDOMNode(this)}
|
||||||
|
filterDropdown={({setSelectedKeys, selectedKeys, confirm, clearFilters}) => {
|
||||||
|
return <ul className={cx('DropDown-menu')}>
|
||||||
|
{selections.map((item, index) => (
|
||||||
|
<li
|
||||||
|
key={index}
|
||||||
|
onClick={() => {
|
||||||
|
item.onSelect && item.onSelect(allKeys);
|
||||||
|
this.handleClick(confirm, setSelectedKeys, item.key);
|
||||||
|
}}>
|
||||||
|
{item.text}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul> ;
|
||||||
|
}}
|
||||||
|
setSelectedKeys={keys => this.setState({key: keys})}
|
||||||
|
selectedKeys={this.state.key}
|
||||||
|
>
|
||||||
|
</HeadCellDropDown>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleClick(
|
||||||
|
confirm: (payload?: FilterPayload) => void,
|
||||||
|
setSelectedKeys?: (keys?: Array<string | number> | string) => void | undefined,
|
||||||
|
selectedKeys?: Array<string> | string
|
||||||
|
) {
|
||||||
|
setSelectedKeys && setSelectedKeys(selectedKeys);
|
||||||
|
|
||||||
|
confirm();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default themeable(localeable(HeadCellSelect));
|
File diff suppressed because it is too large
Load Diff
@ -322,14 +322,11 @@ export const HocQuickEdit =
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
openQuickEdit(e) {
|
openQuickEdit() {
|
||||||
currentOpened = this;
|
currentOpened = this;
|
||||||
this.setState({
|
this.setState({
|
||||||
isOpened: true
|
isOpened: true
|
||||||
});
|
});
|
||||||
// QuickEdit在table中使用时,如果table配置了checkOnItemClick,会同时触发行选中
|
|
||||||
// 所以这里阻止冒泡一下
|
|
||||||
e.stopPropagation && e.stopPropagation();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
closeQuickEdit() {
|
closeQuickEdit() {
|
||||||
|
244
src/renderers/Table-v2/HeadCellSearchDropdown.tsx
Normal file
244
src/renderers/Table-v2/HeadCellSearchDropdown.tsx
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {findDOMNode} from 'react-dom';
|
||||||
|
|
||||||
|
import {RendererProps} from '../../factory';
|
||||||
|
import {Action} from '../../types';
|
||||||
|
import {Icon} from '../../components/icons';
|
||||||
|
import {setVariable} from '../../utils/helper';
|
||||||
|
import {ITableStore} from '../../store/table-v2';
|
||||||
|
import HeadCellDropDown from '../../components/table/HeadCellDropDown';
|
||||||
|
|
||||||
|
export interface QuickSearchConfig {
|
||||||
|
type?: string;
|
||||||
|
controls?: any;
|
||||||
|
tabs?: any;
|
||||||
|
fieldSet?: any;
|
||||||
|
[propName: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HeadCellSearchProps extends RendererProps {
|
||||||
|
name: string;
|
||||||
|
searchable: boolean | QuickSearchConfig;
|
||||||
|
classPrefix: string;
|
||||||
|
onFilter?: (values: object) => void;
|
||||||
|
onAction?: Function;
|
||||||
|
store: ITableStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class HeadCellSearchDropDown extends React.Component<
|
||||||
|
HeadCellSearchProps,
|
||||||
|
any
|
||||||
|
> {
|
||||||
|
|
||||||
|
formItems: Array<string> = [];
|
||||||
|
constructor(props: HeadCellSearchProps) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.handleSubmit = this.handleSubmit.bind(this);
|
||||||
|
this.handleAction = this.handleAction.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
buildSchema() {
|
||||||
|
const {searchable, sortable, name, label, translate: __} = this.props;
|
||||||
|
|
||||||
|
let schema: any;
|
||||||
|
|
||||||
|
if (searchable === true) {
|
||||||
|
schema = {
|
||||||
|
title: '',
|
||||||
|
controls: [
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
name,
|
||||||
|
placeholder: label,
|
||||||
|
clearable: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
} else if (searchable) {
|
||||||
|
if (searchable.controls || searchable.tabs || searchable.fieldSet) {
|
||||||
|
schema = {
|
||||||
|
title: '',
|
||||||
|
...searchable,
|
||||||
|
controls: Array.isArray(searchable.controls)
|
||||||
|
? searchable.controls.concat()
|
||||||
|
: undefined
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
schema = {
|
||||||
|
title: '',
|
||||||
|
className: searchable.formClassName,
|
||||||
|
controls: [
|
||||||
|
{
|
||||||
|
type: searchable.type || 'text',
|
||||||
|
name: searchable.name || name,
|
||||||
|
placeholder: label,
|
||||||
|
...searchable
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (schema && schema.controls && sortable) {
|
||||||
|
schema.controls.unshift(
|
||||||
|
{
|
||||||
|
type: 'hidden',
|
||||||
|
name: 'orderBy',
|
||||||
|
value: name
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'button-group',
|
||||||
|
name: 'order',
|
||||||
|
label: __('sort'),
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: __('asc'),
|
||||||
|
value: 'asc'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __('desc'),
|
||||||
|
value: 'desc'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (schema) {
|
||||||
|
const formItems: Array<string> = [];
|
||||||
|
schema.controls?.forEach(
|
||||||
|
(item: any) =>
|
||||||
|
item.name &&
|
||||||
|
item.name !== 'orderBy' &&
|
||||||
|
item.name !== 'order' &&
|
||||||
|
formItems.push(item.name)
|
||||||
|
);
|
||||||
|
this.formItems = formItems;
|
||||||
|
schema = {
|
||||||
|
...schema,
|
||||||
|
type: 'form',
|
||||||
|
wrapperComponent: 'div',
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
type: 'button',
|
||||||
|
label: __('reset'),
|
||||||
|
actionType: 'clear-and-submit'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
type: 'button',
|
||||||
|
label: __('cancel'),
|
||||||
|
actionType: 'cancel'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
label: __('search'),
|
||||||
|
type: 'submit',
|
||||||
|
primary: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return schema || 'error';
|
||||||
|
}
|
||||||
|
|
||||||
|
handleAction(e: any, action: Action, ctx: object, confirm: Function) {
|
||||||
|
const {onAction} = this.props;
|
||||||
|
|
||||||
|
if (action.actionType === 'cancel' || action.actionType === 'close') {
|
||||||
|
confirm();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action.actionType === 'reset') {
|
||||||
|
confirm();
|
||||||
|
this.handleReset();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
onAction && onAction(e, action, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleReset() {
|
||||||
|
const {onFilter, data, name, store} = this.props;
|
||||||
|
const values = {...data};
|
||||||
|
this.formItems.forEach(key => setVariable(values, key, undefined));
|
||||||
|
|
||||||
|
if (values.orderBy === name) {
|
||||||
|
values.orderBy = '';
|
||||||
|
values.order = 'asc';
|
||||||
|
}
|
||||||
|
|
||||||
|
store.updateQuery(values);
|
||||||
|
|
||||||
|
onFilter && onFilter(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSubmit(values: any, confirm: Function) {
|
||||||
|
const {onFilter, name, store} = this.props;
|
||||||
|
|
||||||
|
if (values.order) {
|
||||||
|
values = {
|
||||||
|
...values,
|
||||||
|
orderBy: name
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
store.updateQuery(values);
|
||||||
|
|
||||||
|
onFilter && onFilter(values);
|
||||||
|
|
||||||
|
confirm();
|
||||||
|
}
|
||||||
|
|
||||||
|
isActive() {
|
||||||
|
const {data, name, orderBy} = this.props;
|
||||||
|
|
||||||
|
return (orderBy && orderBy === name) || this.formItems.some(key => data?.[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
render,
|
||||||
|
name,
|
||||||
|
data,
|
||||||
|
searchable,
|
||||||
|
store,
|
||||||
|
orderBy,
|
||||||
|
popOverContainer,
|
||||||
|
classPrefix: ns,
|
||||||
|
classnames: cx
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
const formSchema = this.buildSchema();
|
||||||
|
const isActive = this.isActive();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<HeadCellDropDown
|
||||||
|
className={`${ns}TableCell-searchBtn`}
|
||||||
|
layerClassName={cx(
|
||||||
|
`${ns}TableCell-searchPopOver`,
|
||||||
|
(searchable as any).className
|
||||||
|
)}
|
||||||
|
active={isActive}
|
||||||
|
filterIcon={<Icon icon="search" className="icon" />}
|
||||||
|
popOverContainer={popOverContainer ? popOverContainer : () => findDOMNode(this)}
|
||||||
|
filterDropdown={({setSelectedKeys, selectedKeys, confirm, clearFilters}) => {
|
||||||
|
return render('quick-search-form', formSchema, {
|
||||||
|
data: {
|
||||||
|
...data,
|
||||||
|
orderBy,
|
||||||
|
order: orderBy && orderBy === name ? (store as ITableStore).order : ''
|
||||||
|
},
|
||||||
|
onSubmit: (values: object) => this.handleSubmit(values, confirm),
|
||||||
|
onAction: (e: any, action: Action, ctx: object) => {
|
||||||
|
this.handleAction(e, action, ctx, confirm);
|
||||||
|
}
|
||||||
|
}) as JSX.Element;
|
||||||
|
}}>
|
||||||
|
</HeadCellDropDown>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
19
src/renderers/Table-v2/TableCell.tsx
Normal file
19
src/renderers/Table-v2/TableCell.tsx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import {Renderer} from '../../factory';
|
||||||
|
import {TableCell} from '../Table';
|
||||||
|
import QuickEdit from '../QuickEdit';
|
||||||
|
import Copyable from '../Copyable';
|
||||||
|
import PopOverable from '../PopOver';
|
||||||
|
|
||||||
|
@Renderer({
|
||||||
|
type: 'cell-field',
|
||||||
|
name: 'cell-field'
|
||||||
|
})
|
||||||
|
@PopOverable()
|
||||||
|
@Copyable()
|
||||||
|
@QuickEdit()
|
||||||
|
export class CellFieldRenderer extends TableCell {
|
||||||
|
static defaultProps = {
|
||||||
|
...TableCell.defaultProps,
|
||||||
|
wrapperComponent: 'div'
|
||||||
|
};
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -37,7 +37,6 @@ export class HeadCellSearchDropDown extends React.Component<
|
|||||||
|
|
||||||
this.open = this.open.bind(this);
|
this.open = this.open.bind(this);
|
||||||
this.close = this.close.bind(this);
|
this.close = this.close.bind(this);
|
||||||
this.close = this.close.bind(this);
|
|
||||||
this.handleSubmit = this.handleSubmit.bind(this);
|
this.handleSubmit = this.handleSubmit.bind(this);
|
||||||
this.handleAction = this.handleAction.bind(this);
|
this.handleAction = this.handleAction.bind(this);
|
||||||
}
|
}
|
||||||
|
@ -156,16 +156,14 @@ export class TableBody extends React.Component<TableBodyProps> {
|
|||||||
classnames: cx,
|
classnames: cx,
|
||||||
rows,
|
rows,
|
||||||
prefixRowClassName,
|
prefixRowClassName,
|
||||||
affixRowClassName,
|
affixRowClassName
|
||||||
footable
|
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
if (!(Array.isArray(items) && items.length)) {
|
if (!(Array.isArray(items) && items.length)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 开启了footable,不需要考虑设置了breakpoint的列了
|
const filterColumns = columns.filter(item => item.toggable);
|
||||||
const filterColumns = columns.filter(item => item.toggable && !(footable && item.breakpoint));
|
|
||||||
const result: any[] = [];
|
const result: any[] = [];
|
||||||
|
|
||||||
for (let index = 0; index < filterColumns.length; index++) {
|
for (let index = 0; index < filterColumns.length; index++) {
|
||||||
@ -184,16 +182,14 @@ export class TableBody extends React.Component<TableBodyProps> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 缺少的单元格补齐
|
// 缺少的单元格补齐
|
||||||
// 考虑是否设置了
|
|
||||||
// 开启了footable,不需要考虑设置了breakpoint的列了
|
|
||||||
const appendLen =
|
const appendLen =
|
||||||
(footable ? columns.filter(item => !item.breakpoint).length : columns.length) - result.reduce((p, c) => p + (c.colSpan || 1), 0);
|
columns.length - result.reduce((p, c) => p + (c.colSpan || 1), 0);
|
||||||
|
|
||||||
if (appendLen) {
|
if (appendLen) {
|
||||||
const item = result.pop();
|
const item = result.pop();
|
||||||
result.push({
|
result.push({
|
||||||
...item,
|
...item,
|
||||||
colSpan: (item?.colSpan || 1) + appendLen
|
colSpan: (item.colSpan || 1) + appendLen
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const ctx = createObject(data, {
|
const ctx = createObject(data, {
|
||||||
|
@ -3,11 +3,35 @@ import {
|
|||||||
getParent,
|
getParent,
|
||||||
Instance,
|
Instance,
|
||||||
SnapshotIn,
|
SnapshotIn,
|
||||||
isAlive
|
isAlive,
|
||||||
|
IAnyModelType,
|
||||||
|
flow,
|
||||||
|
getEnv
|
||||||
} from 'mobx-state-tree';
|
} from 'mobx-state-tree';
|
||||||
|
import find from 'lodash/find';
|
||||||
|
import isEqual from 'lodash/isEqual';
|
||||||
|
|
||||||
import {isVisible, hasVisibleExpression} from '../utils/helper';
|
import {
|
||||||
import {iRendererStore} from './iRenderer';
|
isVisible,
|
||||||
|
hasVisibleExpression,
|
||||||
|
isObjectShallowModified,
|
||||||
|
qsstringify,
|
||||||
|
guid,
|
||||||
|
eachTree,
|
||||||
|
createObject,
|
||||||
|
flattenTree,
|
||||||
|
isObject,
|
||||||
|
immutableExtends,
|
||||||
|
isEmpty,
|
||||||
|
extendObject
|
||||||
|
} from '../utils/helper';
|
||||||
|
import {normalizeApiResponseData} from '../utils/api';
|
||||||
|
import {Api, Payload, fetchOptions, ApiObject} from '../types';
|
||||||
|
import {ServiceStore} from './service';
|
||||||
|
|
||||||
|
class ServerError extends Error {
|
||||||
|
type = 'ServerError';
|
||||||
|
}
|
||||||
|
|
||||||
export const Column = types
|
export const Column = types
|
||||||
.model('Column', {
|
.model('Column', {
|
||||||
@ -18,7 +42,11 @@ export const Column = types
|
|||||||
pristine: types.optional(types.frozen(), undefined),
|
pristine: types.optional(types.frozen(), undefined),
|
||||||
toggable: true,
|
toggable: true,
|
||||||
index: 0,
|
index: 0,
|
||||||
type: ''
|
type: '',
|
||||||
|
children: types.optional(
|
||||||
|
types.array(types.late((): IAnyModelType => Column)),
|
||||||
|
[]
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.actions(self => ({
|
.actions(self => ({
|
||||||
toggleToggle() {
|
toggleToggle() {
|
||||||
@ -41,29 +69,133 @@ export type SColumn = SnapshotIn<typeof Column>;
|
|||||||
|
|
||||||
export const Row = types
|
export const Row = types
|
||||||
.model('Row', {
|
.model('Row', {
|
||||||
data: types.frozen({} as any)
|
storeType: 'Row',
|
||||||
|
id: types.identifier,
|
||||||
|
key: types.string,
|
||||||
|
pristine: types.frozen({} as any), // 原始数据
|
||||||
|
data: types.frozen({} as any),
|
||||||
|
index: types.number,
|
||||||
|
newIndex: types.number,
|
||||||
|
depth: types.number, // 当前children位于第几层,便于使用getParent获取最顶层TableStore
|
||||||
|
children: types.optional(
|
||||||
|
types.array(types.late((): IAnyModelType => Row)),
|
||||||
|
[]
|
||||||
|
),
|
||||||
|
path: '' // 行数据的位置
|
||||||
|
})
|
||||||
|
.views(self => ({
|
||||||
|
get checked(): boolean {
|
||||||
|
return (getParent(self, self.depth * 2) as ITableStore).isSelected(
|
||||||
|
self as IRow
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
get modified() {
|
||||||
|
if (!self.data) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Object.keys(self.data).some(
|
||||||
|
key => !isEqual(self.data[key], self.pristine[key])
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
get locals(): any {
|
||||||
|
let children: Array<any> | null = null;
|
||||||
|
if (self.children.length) {
|
||||||
|
children = self.children.map(item => item.locals);
|
||||||
|
}
|
||||||
|
|
||||||
|
const parent = getParent(self, 2) as ITableStore;
|
||||||
|
return createObject(
|
||||||
|
extendObject((getParent(self, self.depth * 2) as ITableStore).data, {
|
||||||
|
index: self.index,
|
||||||
|
// todo 以后再支持多层,目前先一层
|
||||||
|
parent: parent.storeType === Row.name ? parent.data : undefined
|
||||||
|
}),
|
||||||
|
children
|
||||||
|
? {
|
||||||
|
...self.data,
|
||||||
|
children
|
||||||
|
}
|
||||||
|
: self.data
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.actions(self => ({
|
||||||
|
replaceWith(data: any) {
|
||||||
|
Object.keys(data).forEach(key => {
|
||||||
|
if (key !== 'id') {
|
||||||
|
(self as any)[key] = data[key];
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (Array.isArray(data.children)) {
|
||||||
|
const arr = data.children;
|
||||||
|
const pool = arr.concat();
|
||||||
|
|
||||||
|
// 把多的删了先
|
||||||
|
if (self.children.length > arr.length) {
|
||||||
|
self.children.splice(arr.length, self.children.length - arr.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
let index = 0;
|
||||||
|
const len = self.children.length;
|
||||||
|
while (pool.length) {
|
||||||
|
// 因为父级id未更新,所以需要将子级的parentId正确指向父级id
|
||||||
|
const item = {
|
||||||
|
...pool.shift(),
|
||||||
|
parentId: self.id
|
||||||
|
}!;
|
||||||
|
|
||||||
|
if (index < len) {
|
||||||
|
self.children[index].replaceWith(item);
|
||||||
|
} else {
|
||||||
|
const row = Row.create(item);
|
||||||
|
self.children.push(row);
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
change(values: object, savePristine?: boolean) {
|
||||||
|
self.data = immutableExtends(self.data, values);
|
||||||
|
savePristine && (self.pristine = self.data);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
export type IRow = Instance<typeof Row>;
|
export type IRow = Instance<typeof Row>;
|
||||||
export type SRow = SnapshotIn<typeof Row>;
|
export type SRow = SnapshotIn<typeof Row>;
|
||||||
|
|
||||||
export const TableStoreV2 = iRendererStore
|
export const TableStoreV2 = ServiceStore
|
||||||
.named('TableStoreV2')
|
.named('TableStoreV2')
|
||||||
.props({
|
.props({
|
||||||
columns: types.array(Column),
|
columns: types.array(Column),
|
||||||
rows: types.array(Row),
|
rows: types.array(Row),
|
||||||
columnsToggable: types.optional(
|
selectedRowKeys: types.array(types.frozen()),
|
||||||
|
selectedRows: types.array(types.reference(Row)),
|
||||||
|
expandedRowKeys: types.array(types.frozen()),
|
||||||
|
columnsTogglable: types.optional(
|
||||||
types.union(types.boolean, types.literal('auto')),
|
types.union(types.boolean, types.literal('auto')),
|
||||||
'auto'
|
'auto'
|
||||||
)
|
),
|
||||||
|
orderBy: '',
|
||||||
|
order: types.optional(
|
||||||
|
types.union(types.literal('asc'), types.literal('desc')),
|
||||||
|
'asc'
|
||||||
|
),
|
||||||
|
query: types.optional(types.frozen(), {}),
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
dragging: false
|
||||||
})
|
})
|
||||||
.views(self => {
|
.views(self => {
|
||||||
function getToggable() {
|
function getToggable() {
|
||||||
if (self.columnsToggable === 'auto') {
|
if (self.columnsTogglable === 'auto') {
|
||||||
return self.columns.filter.length > 10;
|
return self.columns.filter.length > 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self.columnsToggable;
|
return self.columnsTogglable;
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasColumnHidden() {
|
function hasColumnHidden() {
|
||||||
@ -80,8 +212,9 @@ export const TableStoreV2 = iRendererStore
|
|||||||
return getToggableColumns().filter(item => item.toggled);
|
return getToggableColumns().filter(item => item.toggled);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFilteredColumns() {
|
function getAllFilteredColumns(columns?: Array<SColumn>): Array<any> {
|
||||||
return self.columns.filter(
|
if (columns) {
|
||||||
|
return columns.filter(
|
||||||
item =>
|
item =>
|
||||||
item &&
|
item &&
|
||||||
isVisible(
|
isVisible(
|
||||||
@ -89,7 +222,33 @@ export const TableStoreV2 = iRendererStore
|
|||||||
hasVisibleExpression(item.pristine) ? self.data : {}
|
hasVisibleExpression(item.pristine) ? self.data : {}
|
||||||
) &&
|
) &&
|
||||||
(item.toggled || !item.toggable)
|
(item.toggled || !item.toggable)
|
||||||
).map(item => ({...item.pristine, type: item.type}));
|
).map(item => ({
|
||||||
|
...item.pristine,
|
||||||
|
type: item.type,
|
||||||
|
children: item.children ? getAllFilteredColumns(item.children) : undefined
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFilteredColumns() {
|
||||||
|
return getAllFilteredColumns(self.columns);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUnSelectedRows() {
|
||||||
|
return flattenTree<IRow>(self.rows).filter((item: IRow) => !item.checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getData(superData: any): any {
|
||||||
|
return createObject(superData, {
|
||||||
|
items: self.rows.map(item => item.data),
|
||||||
|
selectedItems: self.selectedRows.map(item => item.data),
|
||||||
|
unSelectedItems: getUnSelectedRows().map(item => item.data)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function isSelected(row: IRow): boolean {
|
||||||
|
return !!~self.selectedRows.indexOf(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -113,32 +272,63 @@ export const TableStoreV2 = iRendererStore
|
|||||||
return getActiveToggableColumns();
|
return getActiveToggableColumns();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
get dataSource() {
|
||||||
|
return self.rows.map(item => item.data);
|
||||||
|
},
|
||||||
|
|
||||||
|
get currentSelectedRowKeys() {
|
||||||
|
return self.selectedRowKeys.map(item => item);
|
||||||
|
},
|
||||||
|
|
||||||
|
get currentExpandedKeys() {
|
||||||
|
return self.expandedRowKeys.map(item => item);
|
||||||
|
},
|
||||||
|
|
||||||
// 是否隐藏了某列
|
// 是否隐藏了某列
|
||||||
hasColumnHidden() {
|
hasColumnHidden() {
|
||||||
return hasColumnHidden();
|
return hasColumnHidden();
|
||||||
}
|
},
|
||||||
|
|
||||||
|
getData,
|
||||||
|
|
||||||
|
isSelected
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.actions(self => {
|
.actions(self => {
|
||||||
function update(config: Partial<STableStore>) {
|
function updateColumns(columns: Array<SColumn>) {
|
||||||
config.columnsToggable !== void 0 &&
|
if (columns && Array.isArray(columns)) {
|
||||||
(self.columnsToggable = config.columnsToggable);
|
let cols: Array<SColumn> = columns
|
||||||
|
|
||||||
if (config.columns && Array.isArray(config.columns)) {
|
|
||||||
let columns: Array<SColumn> = config.columns
|
|
||||||
.filter(column => column)
|
.filter(column => column)
|
||||||
.concat();
|
.concat();
|
||||||
|
|
||||||
columns = columns.map((item, index) => ({
|
cols = cols.map((item, index) => ({
|
||||||
...item,
|
...item,
|
||||||
index,
|
index,
|
||||||
type: item.type || 'plain',
|
type: item.type || 'plain',
|
||||||
pristine: item,
|
pristine: item,
|
||||||
toggled: item.toggled !== false,
|
toggled: item.toggled !== false,
|
||||||
breakpoint: item.breakpoint
|
breakpoint: item.breakpoint,
|
||||||
|
children: item.children ? updateColumns(item.children) : []
|
||||||
}));
|
}));
|
||||||
|
|
||||||
self.columns.replace(columns as any);
|
return cols;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
function update(config: Partial<STableStore>) {
|
||||||
|
config.columnsTogglable !== void 0 &&
|
||||||
|
(self.columnsTogglable = config.columnsTogglable);
|
||||||
|
|
||||||
|
if (typeof config.orderBy === 'string') {
|
||||||
|
setOrderByInfo(
|
||||||
|
config.orderBy,
|
||||||
|
config.order === 'desc' ? 'desc' : 'asc'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.columns && Array.isArray(config.columns)) {
|
||||||
|
self.columns.replace(updateColumns(config.columns) as any);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,9 +343,275 @@ export const TableStoreV2 = iRendererStore
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setOrderByInfo(key: string, direction: 'asc' | 'desc') {
|
||||||
|
self.orderBy = key;
|
||||||
|
self.order = direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateQuery(
|
||||||
|
values: object,
|
||||||
|
updater?: Function,
|
||||||
|
pageNoField: string = 'pageNo',
|
||||||
|
pageSizeField: string = 'pageSize',
|
||||||
|
replace: boolean = false
|
||||||
|
) {
|
||||||
|
const originQuery = self.query;
|
||||||
|
self.query = replace
|
||||||
|
? {
|
||||||
|
...values
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
...self.query,
|
||||||
|
...values
|
||||||
|
};
|
||||||
|
|
||||||
|
if (self.query[pageNoField || 'pageNo']) {
|
||||||
|
self.pageNo = parseInt(self.query[pageNoField || 'pageNo'], 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.query[pageSizeField || 'pageSize']) {
|
||||||
|
self.pageSize = parseInt(self.query[pageSizeField || 'pageSize'], 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
updater &&
|
||||||
|
isObjectShallowModified(originQuery, self.query, false) &&
|
||||||
|
setTimeout(updater.bind(null, `?${qsstringify(self.query)}`), 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateSelectedRows(rows: Array<any>, selectedKeys: Array<any>, keyField?: string) {
|
||||||
|
eachTree(rows, item => {
|
||||||
|
if (~selectedKeys.indexOf(item.pristine[keyField || 'key'])) {
|
||||||
|
self.selectedRows.push(item.id);
|
||||||
|
self.selectedRowKeys.push(item.pristine[keyField || 'key']);
|
||||||
|
} else if (
|
||||||
|
find(
|
||||||
|
selectedKeys,
|
||||||
|
a =>
|
||||||
|
a &&
|
||||||
|
a == item.pristine[keyField || 'key']
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
self.selectedRows.push(item.id);
|
||||||
|
self.selectedRowKeys.push(item.pristine[keyField || 'key']);
|
||||||
|
} else if (item.children) {
|
||||||
|
updateSelectedRows(item.children, selectedKeys, keyField);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateSelected(selectedKeys: Array<any>, keyField?: string) {
|
||||||
|
self.selectedRows.clear();
|
||||||
|
self.selectedRowKeys.clear();
|
||||||
|
|
||||||
|
updateSelectedRows(self.rows, selectedKeys, keyField);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateExpanded(expandedRowKeys: Array<any>, keyField?: string) {
|
||||||
|
self.expandedRowKeys.clear();
|
||||||
|
|
||||||
|
eachTree(self.rows, item => {
|
||||||
|
if (~expandedRowKeys.indexOf(item.pristine[keyField || 'key'])) {
|
||||||
|
self.expandedRowKeys.push(item.pristine[keyField || 'key']);
|
||||||
|
} else if (
|
||||||
|
find(
|
||||||
|
expandedRowKeys,
|
||||||
|
a =>
|
||||||
|
a &&
|
||||||
|
a == item.pristine[keyField || 'key']
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
self.expandedRowKeys.push(item.pristine[keyField || 'key']);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尽可能的复用 row
|
||||||
|
function replaceRow(arr: Array<SRow>, reUseRow?: boolean) {
|
||||||
|
if (reUseRow === false) {
|
||||||
|
self.rows.replace(arr.map(item => Row.create(item)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pool = arr.concat();
|
||||||
|
|
||||||
|
// 把多的删了先
|
||||||
|
if (self.rows.length > arr.length) {
|
||||||
|
self.rows.splice(arr.length, self.rows.length - arr.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
let index = 0;
|
||||||
|
const len = self.rows.length;
|
||||||
|
while (pool.length) {
|
||||||
|
const item = pool.shift()!;
|
||||||
|
|
||||||
|
if (index < len) {
|
||||||
|
self.rows[index].replaceWith(item);
|
||||||
|
} else {
|
||||||
|
const row = Row.create(item);
|
||||||
|
self.rows.push(row);
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function initChildren(
|
||||||
|
children: Array<any>,
|
||||||
|
depth: number,
|
||||||
|
pindex: number,
|
||||||
|
parentId: string,
|
||||||
|
path: string = '',
|
||||||
|
keyField?: string
|
||||||
|
): any {
|
||||||
|
const key = keyField || 'children';
|
||||||
|
|
||||||
|
depth += 1;
|
||||||
|
return children.map((item, index) => {
|
||||||
|
item = isObject(item)
|
||||||
|
? item
|
||||||
|
: {
|
||||||
|
item
|
||||||
|
};
|
||||||
|
const id = guid();
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: id,
|
||||||
|
parentId,
|
||||||
|
key: String(`${pindex}-${depth}-${index}`),
|
||||||
|
path: `${path}${index}`,
|
||||||
|
depth: depth,
|
||||||
|
index: index,
|
||||||
|
newIndex: index,
|
||||||
|
pristine: item,
|
||||||
|
data: item,
|
||||||
|
rowSpans: {},
|
||||||
|
children:
|
||||||
|
item && Array.isArray(item[key])
|
||||||
|
? initChildren(
|
||||||
|
item[key],
|
||||||
|
depth,
|
||||||
|
index,
|
||||||
|
id,
|
||||||
|
`${path}${index}.`,
|
||||||
|
|
||||||
|
)
|
||||||
|
: []
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function initRows(
|
||||||
|
rows: Array<any>,
|
||||||
|
getEntryId?: (entry: any, index: number) => string,
|
||||||
|
reUseRow?: boolean,
|
||||||
|
keyField?: string
|
||||||
|
) {
|
||||||
|
self.selectedRows.clear();
|
||||||
|
|
||||||
|
const key = keyField || 'children';
|
||||||
|
|
||||||
|
let arr: Array<SRow> = rows.map((item, index) => {
|
||||||
|
let id = getEntryId ? getEntryId(item, index) : guid();
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: id,
|
||||||
|
key: String(`${index}-1-${index}`),
|
||||||
|
index: index,
|
||||||
|
newIndex: index,
|
||||||
|
pristine: item,
|
||||||
|
path: `${index}`,
|
||||||
|
data: item,
|
||||||
|
depth: 1, // 最大父节点默认为第一层,逐层叠加
|
||||||
|
children:
|
||||||
|
item && Array.isArray(item[key])
|
||||||
|
? initChildren(item[key], 1, index, id, `${index}.`, key)
|
||||||
|
: []
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
replaceRow(arr, reUseRow);
|
||||||
|
}
|
||||||
|
|
||||||
|
const saveRemote: (
|
||||||
|
api: Api,
|
||||||
|
data?: object,
|
||||||
|
options?: fetchOptions
|
||||||
|
) => Promise<any> = flow(function* saveRemote(
|
||||||
|
api: Api,
|
||||||
|
data: object,
|
||||||
|
options: fetchOptions = {}
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
options = {
|
||||||
|
method: 'post', // 默认走 post
|
||||||
|
...options
|
||||||
|
};
|
||||||
|
|
||||||
|
self.markSaving(true);
|
||||||
|
const json: Payload = yield getEnv(self).fetcher(api, data, options);
|
||||||
|
self.markSaving(false);
|
||||||
|
|
||||||
|
if (!isEmpty(json.data) || json.ok) {
|
||||||
|
self.updateData(
|
||||||
|
normalizeApiResponseData(json.data),
|
||||||
|
{
|
||||||
|
__saved: Date.now()
|
||||||
|
},
|
||||||
|
!!api && (api as ApiObject).replaceData
|
||||||
|
);
|
||||||
|
self.updatedAt = Date.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!json.ok) {
|
||||||
|
self.updateMessage(
|
||||||
|
json.msg ?? options.errorMessage ?? self.__('saveFailed'),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
getEnv(self).notify(
|
||||||
|
'error',
|
||||||
|
self.msg,
|
||||||
|
json.msgTimeout !== undefined
|
||||||
|
? {
|
||||||
|
closeButton: true,
|
||||||
|
timeout: json.msgTimeout
|
||||||
|
}
|
||||||
|
: undefined
|
||||||
|
);
|
||||||
|
throw new ServerError(self.msg);
|
||||||
|
} else {
|
||||||
|
self.updateMessage(json.msg ?? options.successMessage);
|
||||||
|
self.msg &&
|
||||||
|
getEnv(self).notify(
|
||||||
|
'success',
|
||||||
|
self.msg,
|
||||||
|
json.msgTimeout !== undefined
|
||||||
|
? {
|
||||||
|
closeButton: true,
|
||||||
|
timeout: json.msgTimeout
|
||||||
|
}
|
||||||
|
: undefined
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return json.data;
|
||||||
|
} catch (e) {
|
||||||
|
self.markSaving(false);
|
||||||
|
|
||||||
|
if (!isAlive(self) || self.disposed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
e.type !== 'ServerError' && getEnv(self).notify('error', e.message);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
update,
|
update,
|
||||||
persistSaveToggledColumns,
|
persistSaveToggledColumns,
|
||||||
|
setOrderByInfo,
|
||||||
|
updateQuery,
|
||||||
|
initRows,
|
||||||
|
updateSelected,
|
||||||
|
updateExpanded,
|
||||||
|
|
||||||
// events
|
// events
|
||||||
afterCreate() {
|
afterCreate() {
|
||||||
@ -177,6 +633,11 @@ export const TableStoreV2 = iRendererStore
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}, 200);
|
}, 200);
|
||||||
|
},
|
||||||
|
saveRemote,
|
||||||
|
|
||||||
|
getRowByIndex(rowIndex: number) {
|
||||||
|
return self.rows[rowIndex];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -639,8 +639,7 @@ export const TableStore = iRendererStore
|
|||||||
},
|
},
|
||||||
|
|
||||||
get disabledHeadCheckbox() {
|
get disabledHeadCheckbox() {
|
||||||
// 设置为multiple 默认没选择会报错
|
const selectedLength = self.data?.selectedItems.length;
|
||||||
const selectedLength = self.data?.selectedItems?.length;
|
|
||||||
const maxLength = self.maxKeepItemSelectionLength;
|
const maxLength = self.maxKeepItemSelectionLength;
|
||||||
|
|
||||||
if (!self.data || !self.keepItemSelectionOnPageChange || !maxLength) {
|
if (!self.data || !self.keepItemSelectionOnPageChange || !maxLength) {
|
||||||
|
Loading…
Reference in New Issue
Block a user