Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Nov 8, 2022. It is now read-only.

Commit8241845

Browse files
committed
feat(Labeler): enhance labeler
1.support multiable labeler in same page2.labeler support single/multi select3.refactor code
1 parent662d1ca commit8241845

File tree

14 files changed

+406
-60
lines changed

14 files changed

+406
-60
lines changed

‎containers/ArticleViwer/BodyFooter.js‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ const Content = ({ thread }) => {
1212
caseTHREAD.JOB:{
1313
return(
1414
<Wrapper>
15-
<Labelerlabel="城市"iconSrc={`${ICON_CMD}/city_map.svg`}/>
15+
<Labelerlabel="city"/>
1616
<Dividersrc={`${ICON_CMD}/more.svg`}/>
17-
<Labelerlabel="薪资"iconSrc={`${ICON_CMD}/money_yuan.svg`}/>
17+
<Labelerlabel="salary"/>
1818
</Wrapper>
1919
)
2020
}

‎containers/Labeler/Options.js‎

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
importReactfrom'react'
2+
importRfrom'ramda'
3+
importTagListfrom'./TagList'
4+
5+
import{ICON_CMD}from'../../config'
6+
7+
import{
8+
OptionWrapper,
9+
OptionItem,
10+
OptionCheckIcon,
11+
OptionText,
12+
}from'./styles/options'
13+
14+
importoptionMapfrom'./option_map'
15+
import{uid}from'../../utils'
16+
17+
constOptionItems=({ items, selected, onOptionSelect})=>{
18+
return(
19+
<OptionWrapper>
20+
{items.map(item=>(
21+
<OptionItemkey={uid.gen()}>
22+
<OptionCheckIcon
23+
src={`${ICON_CMD}/check.svg`}
24+
active={R.contains(item,selected)}
25+
/>
26+
<OptionTextonClick={onOptionSelect.bind(this,item)}>
27+
{item}
28+
</OptionText>
29+
</OptionItem>
30+
))}
31+
</OptionWrapper>
32+
)
33+
}
34+
35+
constrenderOptions=(label,tagsData,selected,onOptionSelect)=>{
36+
switch(label){
37+
case'default':{
38+
return<TagListdata={tagsData}/>
39+
}
40+
case'city':{
41+
return<TagListdata={tagsData}/>
42+
}
43+
default:{
44+
return(
45+
<OptionItems
46+
items={optionMap[label].data}
47+
selected={selected}
48+
onOptionSelect={onOptionSelect}
49+
/>
50+
)
51+
}
52+
}
53+
}
54+
55+
constOptions=({ label, tagsData, selected, onOptionSelect})=>(
56+
<React.Fragment>
57+
{renderOptions(label,tagsData,selected,onOptionSelect)}
58+
</React.Fragment>
59+
)
60+
61+
exportdefaultOptions

‎containers/Labeler/Selected.js‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
importReactfrom'react'
2+
importRfrom'ramda'
3+
4+
import{Maybe}from'../../components'
5+
import{Wrapper,Item,Hightlight}from'./styles/selected'
6+
7+
constrenderItems=items=>{
8+
if(items.length===1){
9+
return(
10+
<Item>
11+
(<Hightlight>{items[0]}</Hightlight>)
12+
</Item>
13+
)
14+
}
15+
// {items.map(item => <div key={uid.gen()}>{item}</div>)}
16+
return(
17+
<Item>
18+
(<Hightlight>{items[0]}, ..</Hightlight>)
19+
</Item>
20+
)
21+
}
22+
23+
constSelected=({ items})=>(
24+
<Maybetest={!R.isEmpty(items)}>
25+
<Wrapper>{renderItems(items)}</Wrapper>
26+
</Maybe>
27+
)
28+
29+
exportdefaultSelected

‎containers/Labeler/index.js‎

Lines changed: 73 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,73 +6,111 @@
66

77
importReactfrom'react'
88
importPropTypesfrom'prop-types'
9+
importRfrom'ramda'
910
import{inject,observer}from'mobx-react'
1011

11-
import{ICON_CMD}from'../../config'
12-
import{makeDebugger,storePlug}from'../../utils'
13-
1412
import{Popover}from'../../components'
15-
importTagListfrom'./TagList'
13+
importOptionsfrom'./Options'
14+
importSelectedfrom'./Selected'
1615
import{Wrapper,LabelItem,LabelIcon,Title}from'./styles'
1716

17+
importoptionMapfrom'./option_map'
18+
import{makeDebugger,storePlug,uid}from'../../utils'
1819
import*aslogicfrom'./logic'
1920
/* eslint-disable no-unused-vars */
2021
constdebug=makeDebugger('C:Labeler')
2122
/* eslint-enable no-unused-vars */
2223

24+
consttrans={
25+
default:'标签',
26+
city:'城市',
27+
salary:'月薪',
28+
exp:'经验',
29+
education:'学历',
30+
finance:'融资',
31+
scale:'规模',
32+
field:'领域',
33+
}
34+
2335
classLabelerContainerextendsReact.Component{
24-
componentWillMount(){
25-
const{ labeler}=this.props
26-
logic.init(labeler)
36+
state={
37+
uniqId:uid.gen(),
2738
}
2839

29-
state={visible:false}
40+
componentWillMount(){
41+
const{ labeler, label, multi}=this.props
42+
const{ uniqId}=this.state
43+
44+
constoptions={ label, multi}
45+
logic.init(labeler,uniqId,options)
46+
}
3047

31-
onVisibleChange(visible){
32-
if(visible){
33-
logic.loadTagsIfNeed()
34-
}
35-
this.setState({ visible})
48+
componentWillUnmount(){
49+
const{ uniqId}=this.state
50+
logic.uninit(uniqId)
3651
}
3752

3853
render(){
39-
const{ labeler, label, iconSrc}=this.props
40-
const{ tagsData}=labeler
54+
const{ uniqId}=this.state
55+
const{ labeler, label}=this.props
56+
/* const { tagsData, popVisible, bucketData, labelEntriesData } = labeler */
57+
const{ labelEntriesData}=labeler
58+
consttargetIndex=R.findIndex(R.propEq('uniqId',uniqId))(
59+
labelEntriesData
60+
)
4161

42-
const{visible}=this.state
62+
const{tags, popVisible, bucket}=labelEntriesData[targetIndex]||{}
4363

4464
return(
4565
<Wrapper>
46-
<Popover
47-
content={<TagListdata={tagsData}/>}
48-
placement="right"
49-
trigger="click"
50-
visible={visible}
51-
onVisibleChange={this.onVisibleChange.bind(this)}
52-
>
53-
<LabelItem>
54-
<LabelIconsrc={iconSrc}/>
55-
<Title>{label}</Title>
56-
</LabelItem>
57-
</Popover>
66+
{targetIndex>=0 ?(
67+
<Popover
68+
content={
69+
<Options
70+
label={label}
71+
tagsData={tags}
72+
selected={bucket}
73+
onOptionSelect={logic.onOptionSelect.bind(this,uniqId)}
74+
/>
75+
}
76+
placement="right"
77+
trigger="click"
78+
visible={popVisible}
79+
onVisibleChange={logic.onVisibleChange.bind(this,uniqId)}
80+
>
81+
<LabelItem>
82+
<LabelIconsrc={optionMap[label].iconSrc}/>
83+
<Title>
84+
{trans[label]}
85+
<Selecteditems={bucket}/>
86+
</Title>
87+
</LabelItem>
88+
</Popover>
89+
) :null}
5890
</Wrapper>
5991
)
6092
}
6193
}
6294

6395
LabelerContainer.propTypes={
64-
// https://www.npmjs.com/package/prop-types
65-
label:PropTypes.oneOf(['标签','薪资','城市','编辑']),
66-
// label: PropTypes.oneOf(['tag', 'salary', 'city']),
67-
iconSrc:PropTypes.string,
96+
label:PropTypes.oneOf([
97+
'default',
98+
'salary',
99+
'city',
100+
'exp',
101+
'education',
102+
'finance',
103+
'scale',
104+
'field',
105+
]),
68106
labeler:PropTypes.any,
107+
multi:PropTypes.bool,
69108
}
70109

71110
LabelerContainer.defaultProps={
72-
label:'标签',
73-
// label: 'tag',
74-
iconSrc:`${ICON_CMD}/extra_tag.svg`,
111+
label:'default',
75112
labeler:{},
113+
multi:false,
76114
}
77115

78116
exportdefaultinject(storePlug('labeler'))(observer(LabelerContainer))

‎containers/Labeler/logic.js‎

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
importRfrom'ramda'
22

3-
import{makeDebugger,$solver,asyncRes}from'../../utils'
3+
import{makeDebugger,$solver,makeGQClient}from'../../utils'
44
importSR71from'../../utils/network/sr71'
55

66
importSfrom'./schema'
@@ -14,35 +14,83 @@ const debug = makeDebugger('L:Labeler')
1414

1515
letstore=null
1616

17-
exportfunctionloadTags(){
17+
exportfunctionloadTags(uniqId){
1818
constcommunityId=store.curCommunity.id
1919
constthread=R.toUpper(store.curThread)
2020

2121
constargs={ communityId, thread}
22-
sr71$.query(S.partialTags,args)
22+
const{ request}=makeGQClient()
23+
24+
request(S.partialTags,args)
25+
.then(({partialTags:tags})=>store.markUniqState(uniqId,{ tags}))
26+
.catch(()=>store.toast('error',{title:'tag 加载失败',msg:'--'}))
2327
}
2428

25-
exportfunctionloadTagsIfNeed(){
26-
loadTags()
29+
exportfunctiononOptionSelect(uniqId,item){
30+
constindex=R.findIndex(R.propEq('uniqId',uniqId))(store.labelEntriesData)
31+
if(index<0)returnfalse
32+
// return false
33+
// toggle item if exsit
34+
if(R.contains(item,store.labelEntriesData[index].bucket)){
35+
returnstore.markUniqState(uniqId,{
36+
bucket:R.reject(e=>e===item,store.labelEntriesData[index].bucket),
37+
})
38+
}
39+
// replace bucket if single select mode
40+
if(!store.labelEntriesData[index].multi){
41+
returnstore.markUniqState(uniqId,{popVisible:false,bucket:[item]})
42+
}
43+
// push to bucket if multi select mode
44+
store.markUniqState(uniqId,{
45+
bucket:R.uniq(R.concat(store.labelEntriesData[index].bucket,[item])),
46+
})
47+
}
48+
49+
exportfunctiononVisibleChange(uniqId,popVisible){
50+
store.markUniqState(uniqId,{ popVisible})
51+
52+
constindex=R.findIndex(R.propEq('uniqId',uniqId))(store.labelEntriesData)
53+
if(index<0)returnfalse
54+
55+
constneedLoad=
56+
store.labelEntriesData[index].label==='default'||
57+
store.labelEntriesData[index].label==='city'
58+
59+
if(popVisible&&needLoad){
60+
// logic.loadTagsIfNeed()
61+
loadTags(uniqId)
62+
}
2763
}
2864

2965
// ###############################
3066
// Data & Error handlers
3167
// ###############################
3268

3369
constDataSolver=[
70+
/*
3471
{
3572
match: asyncRes('partialTags'),
36-
action:({partialTags:tags})=>store.markState({ tags}),
73+
action: ({ partialTags: tags }) => store.markUniqState({ tags }),
3774
},
75+
*/
3876
]
3977
constErrSolver=[]
4078

41-
exportfunctioninit(_store){
42-
if(store)returnfalse
79+
exportfunctioninit(_store,uniqId,options){
80+
if(store){
81+
returnstore.markUniqState(uniqId,options)
82+
// return store.markState({ ...options })
83+
}
4384
store=_store
4485

4586
debug(store)
4687
if(sub$)sub$.unsubscribe()
4788
sub$=sr71$.data().subscribe($solver(DataSolver,ErrSolver))
89+
90+
returnstore.markUniqState(uniqId,options)
91+
// return store.markState({ ...options })
92+
}
93+
94+
exportfunctionuninit(uniqId){
95+
store.uninit(uniqId)
4896
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp