Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
pro-blocks
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
duanledexianxianxian
pro-blocks
Commits
27d50044
Commit
27d50044
authored
Apr 17, 2019
by
陈帅
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
SearchListArticles finish
parent
18e249b4
Changes
16
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
391 additions
and
112 deletions
+391
-112
SearchListApplications/src/_mock.ts
SearchListApplications/src/_mock.ts
+12
-6
SearchListApplications/src/components/TagSelect/index.tsx
SearchListApplications/src/components/TagSelect/index.tsx
+5
-4
SearchListApplications/src/index.tsx
SearchListApplications/src/index.tsx
+17
-29
SearchListApplications/src/service.ts
SearchListApplications/src/service.ts
+2
-2
SearchListArticles/src/_mock.ts
SearchListArticles/src/_mock.ts
+12
-6
SearchListArticles/src/components/ArticleListContent/index.tsx
...hListArticles/src/components/ArticleListContent/index.tsx
+13
-1
SearchListArticles/src/components/PageHeaderWrapper/index.js
SearchListArticles/src/components/PageHeaderWrapper/index.js
+0
-25
SearchListArticles/src/components/PageHeaderWrapper/index.less
...hListArticles/src/components/PageHeaderWrapper/index.less
+0
-11
SearchListArticles/src/components/StandardFormRow/index.tsx
SearchListArticles/src/components/StandardFormRow/index.tsx
+16
-1
SearchListArticles/src/components/TagSelect/index.less
SearchListArticles/src/components/TagSelect/index.less
+33
-0
SearchListArticles/src/components/TagSelect/index.tsx
SearchListArticles/src/components/TagSelect/index.tsx
+170
-0
SearchListArticles/src/data.d.ts
SearchListArticles/src/data.d.ts
+29
-0
SearchListArticles/src/index.tsx
SearchListArticles/src/index.tsx
+43
-24
SearchListArticles/src/model.ts
SearchListArticles/src/model.ts
+30
-2
SearchListArticles/src/service.ts
SearchListArticles/src/service.ts
+8
-0
package.json
package.json
+1
-1
No files found.
SearchListApplications/src/_mock.ts
View file @
27d50044
import
{
ListItemDataType
}
from
'
./data
'
;
const
titles
=
[
'
Alipay
'
,
'
Angular
'
,
...
...
@@ -45,7 +47,7 @@ const user = [
'
仲尼
'
,
];
function
fakeList
(
count
)
{
function
fakeList
(
count
:
number
):
ListItemDataType
[]
{
const
list
=
[];
for
(
let
i
=
0
;
i
<
count
;
i
+=
1
)
{
list
.
push
({
...
...
@@ -53,13 +55,17 @@ function fakeList(count) {
owner
:
user
[
i
%
10
],
title
:
titles
[
i
%
8
],
avatar
:
avatars
[
i
%
8
],
cover
:
parseInt
(
i
/
4
,
10
)
%
2
===
0
?
covers
[
i
%
4
]
:
covers
[
3
-
(
i
%
4
)],
status
:
[
'
active
'
,
'
exception
'
,
'
normal
'
][
i
%
3
],
cover
:
parseInt
(
i
/
4
+
''
,
10
)
%
2
===
0
?
covers
[
i
%
4
]
:
covers
[
3
-
(
i
%
4
)],
status
:
[
'
active
'
,
'
exception
'
,
'
normal
'
][
i
%
3
]
as
|
'
normal
'
|
'
exception
'
|
'
active
'
|
'
success
'
,
percent
:
Math
.
ceil
(
Math
.
random
()
*
50
)
+
50
,
logo
:
avatars
[
i
%
8
],
href
:
'
https://ant.design
'
,
updatedAt
:
new
Date
(
new
Date
().
getTime
()
-
1000
*
60
*
60
*
2
*
i
),
createdAt
:
new
Date
(
new
Date
().
getTime
()
-
1000
*
60
*
60
*
2
*
i
),
updatedAt
:
new
Date
(
new
Date
().
getTime
()
-
1000
*
60
*
60
*
2
*
i
)
.
getTime
()
,
createdAt
:
new
Date
(
new
Date
().
getTime
()
-
1000
*
60
*
60
*
2
*
i
)
.
getTime
()
,
subDescription
:
desc
[
i
%
5
],
description
:
'
在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,这些类似的组件会被抽离成一套标准规范。
'
,
...
...
@@ -93,7 +99,7 @@ function fakeList(count) {
return
list
;
}
function
getFakeList
(
req
,
res
)
{
function
getFakeList
(
req
:
{
query
:
any
},
res
:
{
json
:
(
arg0
:
any
[])
=>
void
}
)
{
const
params
=
req
.
query
;
const
count
=
params
.
count
*
1
||
20
;
...
...
SearchListApplications/src/components/TagSelect/index.tsx
View file @
27d50044
...
...
@@ -53,9 +53,9 @@ class TagSelect extends Component<TagSelectProps, TagSelectState> {
static
defaultProps
=
{
hideCheckAll
:
false
,
actionsText
:
{
expandText
:
'
Expand
'
,
collapseText
:
'
Collapse
'
,
selectAllText
:
'
All
'
,
expandText
:
'
展开
'
,
collapseText
:
'
收起
'
,
selectAllText
:
'
全部
'
,
},
};
static
Option
:
TagSelectOption
=
TagSelectOption
;
...
...
@@ -130,7 +130,7 @@ class TagSelect extends Component<TagSelectProps, TagSelectState> {
const
{
value
,
expand
}
=
this
.
state
;
const
{
children
,
hideCheckAll
,
className
,
style
,
expandable
,
actionsText
=
{}
}
=
this
.
props
;
const
checkedAll
=
this
.
getAllTags
().
length
===
value
.
length
;
const
{
expandText
=
'
Expand
'
,
collapseText
=
'
Collapse
'
,
selectAllText
=
'
All
'
}
=
actionsText
;
const
{
expandText
=
'
展开
'
,
collapseText
=
'
收起
'
,
selectAllText
=
'
全部
'
}
=
actionsText
;
const
cls
=
classNames
(
styles
.
tagSelect
,
className
,
{
[
styles
.
hasExpandTag
]:
expandable
,
...
...
@@ -145,6 +145,7 @@ class TagSelect extends Component<TagSelectProps, TagSelectState> {
</
CheckableTag
>
)
}
{
value
&&
children
&&
React
.
Children
.
map
(
children
,
(
child
:
React
.
ReactElement
<
TagSelectOption
>
)
=>
{
if
(
this
.
isTagSelectOption
(
child
))
{
return
React
.
cloneElement
(
child
,
{
...
...
SearchListApplications/src/index.tsx
View file @
27d50044
import
React
,
{
Component
}
from
'
react
'
;
import
numeral
from
'
numeral
'
;
import
{
connect
}
from
'
dva
'
;
import
{
Row
,
Col
,
Form
,
Card
,
Select
,
Icon
,
Avatar
,
List
,
Tooltip
,
Dropdown
,
Menu
,
Input
,
}
from
'
antd
'
;
import
{
Row
,
Col
,
Form
,
Card
,
Select
,
Icon
,
Avatar
,
List
,
Tooltip
,
Dropdown
,
Menu
}
from
'
antd
'
;
import
TagSelect
from
'
./components/TagSelect
'
;
import
StandardFormRow
from
'
./components/StandardFormRow
'
;
import
PageHeaderWrapper
from
'
./components/PageHeaderWrapper
'
;
import
{
formatWan
}
from
'
./utils/utils
'
;
import
styles
from
'
./style.less
'
;
import
{
IStateType
}
from
'
./model
'
;
...
...
@@ -34,18 +20,6 @@ interface PAGE_NAME_UPPER_CAMEL_CASEProps extends FormComponentProps {
loading
:
boolean
;
}
@
connect
(
({
BLOCK_NAME_CAMEL_CASE
,
loading
,
}:
{
BLOCK_NAME_CAMEL_CASE
:
IStateType
;
loading
:
{
models
:
{
[
key
:
string
]:
boolean
}
};
})
=>
({
BLOCK_NAME_CAMEL_CASE
,
loading
:
loading
.
models
.
BLOCK_NAME_CAMEL_CASE
,
})
)
class
PAGE_NAME_UPPER_CAMEL_CASE
extends
Component
<
PAGE_NAME_UPPER_CAMEL_CASEProps
>
{
componentDidMount
()
{
const
{
dispatch
}
=
this
.
props
;
...
...
@@ -115,7 +89,7 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends Component<PAGE_NAME_UPPER_CAMEL_CASEPro
<
StandardFormRow
title
=
"所属类目"
block
style
=
{
{
paddingBottom
:
11
}
}
>
<
FormItem
>
{
getFieldDecorator
(
'
category
'
)(
<
TagSelect
expandable
>
<
TagSelect
expandable
=
{
true
}
>
<
TagSelect
.
Option
value
=
"cat1"
>
类目一
</
TagSelect
.
Option
>
<
TagSelect
.
Option
value
=
"cat2"
>
类目二
</
TagSelect
.
Option
>
<
TagSelect
.
Option
value
=
"cat3"
>
类目三
</
TagSelect
.
Option
>
...
...
@@ -157,6 +131,7 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends Component<PAGE_NAME_UPPER_CAMEL_CASEPro
</
StandardFormRow
>
</
Form
>
</
Card
>
<
br
/>
<
List
<
ListItemDataType
>
rowKey="id"
grid=
{
{
gutter
:
24
,
xl
:
4
,
lg
:
3
,
md
:
3
,
sm
:
2
,
xs
:
1
}
}
...
...
@@ -198,7 +173,7 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends Component<PAGE_NAME_UPPER_CAMEL_CASEPro
}
}
export default
Form.create(
{
const WarpForm =
Form.create(
{
onValuesChange
({
dispatch
}:
PAGE_NAME_UPPER_CAMEL_CASEProps
,
changedValues
,
allValues
)
{
// 表单项变化时请求数据
// 模拟查询表单生效
...
...
@@ -210,3 +185,16 @@ export default Form.create({
});
},
}
)(PAGE_NAME_UPPER_CAMEL_CASE);
export default connect(
(
{
BLOCK_NAME_CAMEL_CASE
,
loading
,
}
:
{
BLOCK_NAME_CAMEL_CASE
:
IStateType
;
loading
:
{
models
:
{
[
key
:
string
]:
boolean
}
};
}
) => (
{
BLOCK_NAME_CAMEL_CASE
,
loading
:
loading
.
models
.
BLOCK_NAME_CAMEL_CASE
,
}
)
)(WarpForm);
SearchListApplications/src/service.ts
View file @
27d50044
import
request
from
'
umi-request
'
;
export
async
function
queryFakeList
(
params
)
{
import
{
ListItemDataType
}
from
'
./data
'
;
export
async
function
queryFakeList
(
params
:
ListItemDataType
)
{
return
request
(
`/api/BLOCK_NAME/fake_list`
,
{
params
,
});
...
...
SearchListArticles/src/_mock.
j
s
→
SearchListArticles/src/_mock.
t
s
View file @
27d50044
import
{
ListItemDataType
}
from
'
./data
'
;
const
titles
=
[
'
Alipay
'
,
'
Angular
'
,
...
...
@@ -45,7 +47,7 @@ const user = [
'
仲尼
'
,
];
function
fakeList
(
count
)
{
function
fakeList
(
count
:
number
):
ListItemDataType
[]
{
const
list
=
[];
for
(
let
i
=
0
;
i
<
count
;
i
+=
1
)
{
list
.
push
({
...
...
@@ -53,13 +55,17 @@ function fakeList(count) {
owner
:
user
[
i
%
10
],
title
:
titles
[
i
%
8
],
avatar
:
avatars
[
i
%
8
],
cover
:
parseInt
(
i
/
4
,
10
)
%
2
===
0
?
covers
[
i
%
4
]
:
covers
[
3
-
(
i
%
4
)],
status
:
[
'
active
'
,
'
exception
'
,
'
normal
'
][
i
%
3
],
cover
:
parseInt
(
i
/
4
+
''
,
10
)
%
2
===
0
?
covers
[
i
%
4
]
:
covers
[
3
-
(
i
%
4
)],
status
:
[
'
active
'
,
'
exception
'
,
'
normal
'
][
i
%
3
]
as
|
'
normal
'
|
'
exception
'
|
'
active
'
|
'
success
'
,
percent
:
Math
.
ceil
(
Math
.
random
()
*
50
)
+
50
,
logo
:
avatars
[
i
%
8
],
href
:
'
https://ant.design
'
,
updatedAt
:
new
Date
(
new
Date
().
getTime
()
-
1000
*
60
*
60
*
2
*
i
),
createdAt
:
new
Date
(
new
Date
().
getTime
()
-
1000
*
60
*
60
*
2
*
i
),
updatedAt
:
new
Date
(
new
Date
().
getTime
()
-
1000
*
60
*
60
*
2
*
i
)
.
getTime
()
,
createdAt
:
new
Date
(
new
Date
().
getTime
()
-
1000
*
60
*
60
*
2
*
i
)
.
getTime
()
,
subDescription
:
desc
[
i
%
5
],
description
:
'
在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,这些类似的组件会被抽离成一套标准规范。
'
,
...
...
@@ -93,7 +99,7 @@ function fakeList(count) {
return
list
;
}
function
getFakeList
(
req
,
res
)
{
function
getFakeList
(
req
:
{
query
:
any
},
res
:
{
json
:
(
arg0
:
any
[])
=>
void
}
)
{
const
params
=
req
.
query
;
const
count
=
params
.
count
*
1
||
20
;
...
...
SearchListArticles/src/components/ArticleListContent/index.
js
→
SearchListArticles/src/components/ArticleListContent/index.
tsx
View file @
27d50044
...
...
@@ -3,7 +3,19 @@ import moment from 'moment';
import
{
Avatar
}
from
'
antd
'
;
import
styles
from
'
./index.less
'
;
const
ArticleListContent
=
({
data
:
{
content
,
updatedAt
,
avatar
,
owner
,
href
}
})
=>
(
interface
ArticleListContentProps
{
data
:
{
content
:
React
.
ReactNode
;
updatedAt
:
number
;
avatar
:
string
;
owner
:
string
;
href
:
string
;
};
}
const
ArticleListContent
:
React
.
SFC
<
ArticleListContentProps
>
=
({
data
:
{
content
,
updatedAt
,
avatar
,
owner
,
href
},
})
=>
(
<
div
className
=
{
styles
.
listContent
}
>
<
div
className
=
{
styles
.
description
}
>
{
content
}
</
div
>
<
div
className
=
{
styles
.
extra
}
>
...
...
SearchListArticles/src/components/PageHeaderWrapper/index.js
deleted
100644 → 0
View file @
18e249b4
import
React
from
'
react
'
;
import
{
FormattedMessage
}
from
'
umi-plugin-react/locale
'
;
import
Link
from
'
umi/link
'
;
import
{
PageHeader
}
from
'
ant-design-pro
'
;
import
styles
from
'
./index.less
'
;
const
PageHeaderWrapper
=
({
children
,
wrapperClassName
,
...
restProps
})
=>
(
<
div
style
=
{{
margin
:
'
-24px -24px 0
'
}}
className
=
{
wrapperClassName
}
>
<
PageHeader
home
=
{
<
FormattedMessage
id
=
"
BLOCK_NAME.menu.home
"
defaultMessage
=
"
Home
"
/>
}
key
=
"
pageheader
"
{...
restProps
}
linkElement
=
{
Link
}
itemRender
=
{
item
=>
{
if
(
item
.
locale
)
{
return
<
FormattedMessage
id
=
{
item
.
locale
}
defaultMessage
=
{
item
.
title
}
/>
;
}
return
item
.
title
;
}}
/
>
{
children
?
<
div
className
=
{
styles
.
content
}
>
{
children
}
<
/div> : null
}
<
/div
>
);
export
default
PageHeaderWrapper
;
SearchListArticles/src/components/PageHeaderWrapper/index.less
deleted
100644 → 0
View file @
18e249b4
@import '~antd/lib/style/themes/default.less';
.content {
margin: 24px 24px 0;
}
@media screen and (max-width: @screen-sm) {
.content {
margin: 24px 0 0;
}
}
SearchListArticles/src/components/StandardFormRow/index.
js
→
SearchListArticles/src/components/StandardFormRow/index.
tsx
View file @
27d50044
...
...
@@ -2,7 +2,22 @@ import React from 'react';
import
classNames
from
'
classnames
'
;
import
styles
from
'
./index.less
'
;
const
StandardFormRow
=
({
title
,
children
,
last
,
block
,
grid
,
...
rest
})
=>
{
interface
StandardFormRowProps
{
title
?:
string
;
last
?:
boolean
;
block
?:
boolean
;
grid
?:
boolean
;
style
?:
React
.
CSSProperties
;
}
const
StandardFormRow
:
React
.
SFC
<
StandardFormRowProps
>
=
({
title
,
children
,
last
,
block
,
grid
,
...
rest
})
=>
{
const
cls
=
classNames
(
styles
.
standardFormRow
,
{
[
styles
.
standardFormRowBlock
]:
block
,
[
styles
.
standardFormRowLast
]:
last
,
...
...
SearchListArticles/src/components/TagSelect/index.less
0 → 100644
View file @
27d50044
@import '~antd/lib/style/themes/default.less';
.tagSelect {
position: relative;
max-height: 32px;
margin-left: -8px;
overflow: hidden;
line-height: 32px;
transition: all 0.3s;
user-select: none;
:global {
.ant-tag {
margin-right: 24px;
padding: 0 8px;
font-size: @font-size-base;
}
}
&.expanded {
max-height: 200px;
transition: all 0.3s;
}
.trigger {
position: absolute;
top: 0;
right: 0;
i {
font-size: 12px;
}
}
&.hasExpandTag {
padding-right: 50px;
}
}
SearchListArticles/src/components/TagSelect/index.tsx
0 → 100644
View file @
27d50044
import
React
,
{
Component
}
from
'
react
'
;
import
classNames
from
'
classnames
'
;
import
{
Tag
,
Icon
}
from
'
antd
'
;
import
styles
from
'
./index.less
'
;
const
{
CheckableTag
}
=
Tag
;
export
interface
TagSelectOptionProps
{
value
?:
string
|
number
;
style
?:
React
.
CSSProperties
;
checked
?:
boolean
;
onChange
?:
(
value
:
string
|
number
|
undefined
,
state
:
boolean
)
=>
void
;
}
export
interface
TagSelectProps
{
onChange
?:
(
value
:
(
string
|
number
)[])
=>
void
;
expandable
?:
boolean
;
value
?:
(
string
|
number
)[];
defaultValue
?:
(
string
|
number
)[];
style
?:
React
.
CSSProperties
;
hideCheckAll
?:
boolean
;
actionsText
?:
{
expandText
?:
React
.
ReactNode
;
collapseText
?:
React
.
ReactNode
;
selectAllText
?:
React
.
ReactNode
;
};
className
?:
string
;
Option
?:
TagSelectOptionProps
;
children
?:
React
.
ReactElement
<
TagSelectOption
>
|
Array
<
React
.
ReactElement
<
TagSelectOption
>>
;
}
const
TagSelectOption
:
React
.
SFC
<
TagSelectOptionProps
>
&
{
isTagSelectOption
:
boolean
;
}
=
({
children
,
checked
,
onChange
,
value
})
=>
(
<
CheckableTag
checked
=
{
!!
checked
}
key
=
{
value
}
onChange
=
{
state
=>
onChange
&&
onChange
(
value
,
state
)
}
>
{
children
}
</
CheckableTag
>
);
TagSelectOption
.
isTagSelectOption
=
true
;
interface
TagSelectState
{
expand
:
boolean
;
value
:
(
string
|
number
)[];
}
class
TagSelect
extends
Component
<
TagSelectProps
,
TagSelectState
>
{
static
defaultProps
=
{
hideCheckAll
:
false
,
actionsText
:
{
expandText
:
'
展开
'
,
collapseText
:
'
收起
'
,
selectAllText
:
'
全部
'
,
},
};
static
Option
:
TagSelectOption
=
TagSelectOption
;
constructor
(
props
:
TagSelectProps
)
{
super
(
props
);
this
.
state
=
{
expand
:
false
,
value
:
props
.
value
||
props
.
defaultValue
||
[],
};
}
static
getDerivedStateFromProps
(
nextProps
:
TagSelectProps
)
{
if
(
'
value
'
in
nextProps
)
{
return
{
value
:
nextProps
.
value
||
[]
};
}
return
null
;
}
onChange
=
(
value
:
(
string
|
number
)[])
=>
{
const
{
onChange
}
=
this
.
props
;
if
(
!
(
'
value
'
in
this
.
props
))
{
this
.
setState
({
value
});
}
if
(
onChange
)
{
onChange
(
value
);
}
};
onSelectAll
=
(
checked
:
boolean
)
=>
{
let
checkedTags
:
(
string
|
number
)[]
=
[];
if
(
checked
)
{
checkedTags
=
this
.
getAllTags
();
}
this
.
onChange
(
checkedTags
);
};
getAllTags
()
{
let
{
children
}
=
this
.
props
;
const
childrenArray
=
React
.
Children
.
toArray
(
children
)
as
React
.
ReactElement
<
TagSelectOption
>
[];
const
checkedTags
=
childrenArray
.
filter
(
child
=>
this
.
isTagSelectOption
(
child
))
.
map
(
child
=>
child
.
props
.
value
);
return
checkedTags
||
[];
}
handleTagChange
=
(
value
:
string
|
number
,
checked
:
boolean
)
=>
{
const
{
value
:
StateValue
}
=
this
.
state
;
const
checkedTags
:
(
string
|
number
)[]
=
[...
StateValue
];
const
index
=
checkedTags
.
indexOf
(
value
);
if
(
checked
&&
index
===
-
1
)
{
checkedTags
.
push
(
value
);
}
else
if
(
!
checked
&&
index
>
-
1
)
{
checkedTags
.
splice
(
index
,
1
);
}
this
.
onChange
(
checkedTags
);
};
handleExpand
=
()
=>
{
const
{
expand
}
=
this
.
state
;
this
.
setState
({
expand
:
!
expand
,
});
};
isTagSelectOption
=
(
node
:
React
.
ReactElement
<
TagSelectOption
,
TagSelectOption
>
)
=>
node
&&
node
.
type
&&
(
node
.
type
.
isTagSelectOption
||
node
.
type
.
displayName
===
'
TagSelectOption
'
);
render
()
{
const
{
value
,
expand
}
=
this
.
state
;
const
{
children
,
hideCheckAll
,
className
,
style
,
expandable
,
actionsText
=
{}
}
=
this
.
props
;
const
checkedAll
=
this
.
getAllTags
().
length
===
value
.
length
;
const
{
expandText
=
'
展开
'
,
collapseText
=
'
收起
'
,
selectAllText
=
'
全部
'
}
=
actionsText
;
const
cls
=
classNames
(
styles
.
tagSelect
,
className
,
{
[
styles
.
hasExpandTag
]:
expandable
,
[
styles
.
expanded
]:
expand
,
});
return
(
<
div
className
=
{
cls
}
style
=
{
style
}
>
{
hideCheckAll
?
null
:
(
<
CheckableTag
checked
=
{
checkedAll
}
key
=
"tag-select-__all__"
onChange
=
{
this
.
onSelectAll
}
>
{
selectAllText
}
</
CheckableTag
>
)
}
{
value
&&
children
&&
React
.
Children
.
map
(
children
,
(
child
:
React
.
ReactElement
<
TagSelectOption
>
)
=>
{
if
(
this
.
isTagSelectOption
(
child
))
{
return
React
.
cloneElement
(
child
,
{
key
:
`tag-select-
${
child
.
props
.
value
}
`
,
value
:
child
.
props
.
value
,
checked
:
value
.
indexOf
(
child
.
props
.
value
)
>
-
1
,
onChange
:
this
.
handleTagChange
,
});
}
return
child
;
})
}
{
expandable
&&
(
<
a
className
=
{
styles
.
trigger
}
onClick
=
{
this
.
handleExpand
}
>
{
expand
?
collapseText
:
expandText
}
<
Icon
type
=
{
expand
?
'
up
'
:
'
down
'
}
/>
</
a
>
)
}
</
div
>
);
}
}
export
default
TagSelect
;
SearchListArticles/src/data.d.ts
0 → 100644
View file @
27d50044
export
interface
Member
{
avatar
:
string
;
name
:
string
;
id
:
string
;
}
export
interface
ListItemDataType
{
id
:
string
;
owner
:
string
;
title
:
string
;
avatar
:
string
;
cover
:
string
;
status
:
'
normal
'
|
'
exception
'
|
'
active
'
|
'
success
'
;
percent
:
number
;
logo
:
string
;
href
:
string
;
body
?:
any
;
updatedAt
:
number
;
createdAt
:
number
;
subDescription
:
string
;
description
:
string
;
activeUser
:
number
;
newUser
:
number
;
star
:
number
;
like
:
number
;
message
:
number
;
content
:
string
;
members
:
Member
[];
}
SearchListArticles/src/index.
js
→
SearchListArticles/src/index.
tsx
View file @
27d50044
...
...
@@ -6,31 +6,23 @@ import TagSelect from './components/TagSelect';
import
StandardFormRow
from
'
./components/StandardFormRow
'
;
import
ArticleListContent
from
'
./components/ArticleListContent
'
;
import
styles
from
'
./style.less
'
;
import
{
Dispatch
}
from
'
redux
'
;
import
{
FormComponentProps
}
from
'
antd/lib/form
'
;
import
{
ListItemDataType
}
from
'
./data
'
;
import
{
IStateType
}
from
'
./model
'
;
const
{
Option
}
=
Select
;
const
FormItem
=
Form
.
Item
;
const
pageSize
=
5
;
@
connect
(({
BLOCK_NAME_CAMEL_CASE
,
loading
})
=>
({
BLOCK_NAME_CAMEL_CASE
,
loading
:
loading
.
models
.
BLOCK_NAME_CAMEL_CASE
,
}))
@
Form
.
create
({
onValuesChange
({
dispatch
},
changedValues
,
allValues
)
{
// 表单项变化时请求数据
// eslint-disable-next-line
console
.
log
(
changedValues
,
allValues
);
// 模拟查询表单生效
dispatch
({
type
:
'
BLOCK_NAME_CAMEL_CASE/fetch
'
,
payload
:
{
count
:
5
,
},
});
},
})
class
SearchList
extends
Component
{
interface
PAGE_NAME_UPPER_CAMEL_CASEProps
extends
FormComponentProps
{
dispatch
:
Dispatch
;
BLOCK_NAME_CAMEL_CASE
:
IStateType
;
loading
:
boolean
;
}
class
PAGE_NAME_UPPER_CAMEL_CASE
extends
Component
<
PAGE_NAME_UPPER_CAMEL_CASEProps
>
{
componentDidMount
()
{
const
{
dispatch
}
=
this
.
props
;
dispatch
({
...
...
@@ -89,7 +81,10 @@ class SearchList extends Component {
},
];
const
IconText
=
({
type
,
text
})
=>
(
const
IconText
:
React
.
SFC
<
{
type
:
string
;
text
:
React
.
ReactNode
;
}
>
=
({
type
,
text
})
=>
(
<
span
>
<
Icon
type
=
{
type
}
style
=
{
{
marginRight
:
8
}
}
/>
{
text
}
...
...
@@ -145,8 +140,8 @@ class SearchList extends Component {
</
StandardFormRow
>
<
StandardFormRow
title
=
"owner"
grid
>
<
Row
>
<
Col
lg
=
{
16
}
md
=
{
24
}
sm
=
{
24
}
xs
=
{
24
}
>
<
FormItem
>
<
Col
>
<
FormItem
{
...
formItemLayout
}
>
{
getFieldDecorator
(
'
owner
'
,
{
initialValue
:
[
'
wjh
'
,
'
zxx
'
],
})(
...
...
@@ -198,7 +193,7 @@ class SearchList extends Component {
bordered
=
{
false
}
bodyStyle
=
{
{
padding
:
'
8px 32px 32px 32px
'
}
}
>
<
List
<
List
<
ListItemDataType
>
size="large"
loading=
{
list
.
length
===
0
?
loading
:
false
}
rowKey="id"
...
...
@@ -239,4 +234,28 @@ class SearchList extends Component {
}
}
export
default
SearchList
;
const WarpForm = Form.create(
{
onValuesChange
({
dispatch
}:
PAGE_NAME_UPPER_CAMEL_CASEProps
,
changedValues
,
allValues
)
{
// 表单项变化时请求数据
// 模拟查询表单生效
dispatch
({
type
:
'
BLOCK_NAME_CAMEL_CASE/fetch
'
,
payload
:
{
count
:
8
,
},
});
},
}
)(PAGE_NAME_UPPER_CAMEL_CASE);
export default connect(
(
{
BLOCK_NAME_CAMEL_CASE
,
loading
,
}
:
{
BLOCK_NAME_CAMEL_CASE
:
IStateType
;
loading
:
{
models
:
{
[
key
:
string
]:
boolean
}
};
}
) => (
{
BLOCK_NAME_CAMEL_CASE
,
loading
:
loading
.
models
.
BLOCK_NAME_CAMEL_CASE
,
}
)
)(WarpForm);
SearchListArticles/src/model.
j
s
→
SearchListArticles/src/model.
t
s
View file @
27d50044
import
{
queryFakeList
}
from
'
./service
'
;
import
{
ListItemDataType
}
from
'
./data
'
;
import
{
Reducer
}
from
'
redux
'
;
import
{
EffectsCommandMap
}
from
'
dva
'
;
import
{
AnyAction
}
from
'
redux
'
;
export
default
{
export
interface
IStateType
{
list
:
ListItemDataType
[];
}
export
type
Effect
=
(
action
:
AnyAction
,
effects
:
EffectsCommandMap
&
{
select
:
<
T
>
(
func
:
(
state
:
IStateType
)
=>
T
)
=>
T
}
)
=>
void
;
export
interface
ModelType
{
namespace
:
string
;
state
:
IStateType
;
effects
:
{
fetch
:
Effect
;
appendFetch
:
Effect
;
};
reducers
:
{
queryList
:
Reducer
<
IStateType
>
;
appendList
:
Reducer
<
IStateType
>
;
};
}
const
Model
:
ModelType
=
{
namespace
:
'
BLOCK_NAME_CAMEL_CASE
'
,
state
:
{
...
...
@@ -34,8 +60,10 @@ export default {
appendList
(
state
,
action
)
{
return
{
...
state
,
list
:
state
.
list
.
concat
(
action
.
payload
),
list
:
state
!
.
list
.
concat
(
action
.
payload
),
};
},
},
};
export
default
Model
;
SearchListArticles/src/service.
j
s
→
SearchListArticles/src/service.
t
s
View file @
27d50044
import
request
from
'
umi-request
'
;
import
{
ListItemDataType
}
from
'
./data
'
;
export
async
function
queryFakeList
(
params
)
{
export
async
function
queryFakeList
(
params
:
ListItemDataType
)
{
return
request
(
`/api/BLOCK_NAME/fake_list`
,
{
params
,
});
...
...
package.json
View file @
27d50044
{
"private"
:
true
,
"scripts"
:
{
"dev"
:
"cross-env PAGES_PATH='
ResultFail
/src' umi dev"
,
"dev"
:
"cross-env PAGES_PATH='
SearchListArticles
/src' umi dev"
,
"lint:style"
:
"stylelint
\"
src/**/*.less
\"
--syntax less"
,
"lint"
:
"eslint --ext .js src mock tests && npm run lint:style"
,
"lint:fix"
:
"eslint --fix --ext .js src mock tests && npm run lint:style"
,
...
...
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