@@ -14,11 +14,21 @@ import {
14
14
import { Popover2 } from '@blueprintjs/popover2'
15
15
16
16
import clsx from 'clsx'
17
- import { DetailedHTMLProps , FC , useState } from 'react'
17
+ import {
18
+ DetailedHTMLProps ,
19
+ Dispatch ,
20
+ FC ,
21
+ ReactNode ,
22
+ SetStateAction ,
23
+ useState ,
24
+ } from 'react'
18
25
19
26
import { OperatorAvatar } from '../../EditorOperator'
20
27
import { Group , Operator } from '../../EditorSheet'
21
- import { SheetContainerSkeleton } from '../SheetContainerSkeleton'
28
+ import {
29
+ SheetContainerSkeleton ,
30
+ SheetContainerSkeletonProps ,
31
+ } from '../SheetContainerSkeleton'
22
32
import { OperatorItem } from '../SheetOperatorItem'
23
33
import { useSheet } from '../SheetProvider'
24
34
import {
@@ -48,9 +58,8 @@ export const SheetOperatorEditor: FC<SheetOperatorEditorProp> = ({
48
58
}
49
59
50
60
type OperatorInSheetOperatorEditor = {
51
- groupName : string | undefined
52
- operatorInfo : Operator
53
- selected : boolean
61
+ groupName ?: string
62
+ operName : string
54
63
}
55
64
56
65
interface SheetOperatorEditorFormProp {
@@ -67,46 +76,138 @@ const SheetOperatorEditorForm: FC<SheetOperatorEditorFormProp> = ({
67
76
name,
68
77
opers = [ ] ,
69
78
} ) => {
70
- const { existedOperators } = useSheet ( )
79
+ const { existedOperators, existedGroups } = useSheet ( )
71
80
const [ selectedOperators , setSelectedOperators ] = useState <
72
81
OperatorInSheetOperatorEditor [ ]
73
82
> (
74
- opers . map ( ( item ) => ( {
83
+ opers . map ( ( { name : operName } ) => ( {
75
84
groupName : name ,
76
- operatorInfo : item ,
77
- selected : true ,
85
+ operName,
78
86
} ) ) ,
79
87
)
80
88
81
89
const onSubmit : FormHTMLElement [ 'onSubmit' ] = ( e ) => {
82
90
e . preventDefault ( )
83
91
}
84
92
93
+ const onReset : FormHTMLElement [ 'onReset' ] = ( e ) => {
94
+ // e.preventDefault()
95
+ console . log ( '111' )
96
+ setSelectedOperators (
97
+ opers . map ( ( { name : operName } ) => ( {
98
+ groupName : name ,
99
+ operName,
100
+ } ) ) ,
101
+ )
102
+ }
103
+
85
104
return (
86
105
< SheetContainerSkeleton title = "选择干员" icon = "select" >
87
- < form
88
- className = "flex mt-3"
89
- onSubmit = { onSubmit }
90
- onReset = { ( ) => console . log ( '222' ) }
91
- >
92
- < Button text = "确认" className = { Classes . POPOVER_DISMISS } type = "submit" />
93
- < Popover2
94
- captureDismiss
95
- content = {
96
- < div className = "flex items-center" >
97
- < p > 所有未保存的数据均会丢失,确认继续?</ p >
98
- < Button
99
- type = "reset"
100
- text = "继续"
101
- className = { clsx ( Classes . POPOVER_DISMISS , 'mx-1' ) }
106
+ < form className = "mt-3" onSubmit = { onSubmit } onReset = { onReset } >
107
+ < div className = "max-h-96 overflow-y-auto overflow-x-hidden" >
108
+ < OperatorSelectorSkeleton
109
+ icon = "person"
110
+ title = "已选择干员"
111
+ collapseDisabled = { ! opers . length }
112
+ >
113
+ { opers . map ( ( { name } ) => (
114
+ < OperatorItemInSheetOperatorEditor
115
+ setSelectedOperators = { setSelectedOperators }
116
+ selected = {
117
+ ! ! selectedOperators . find ( ( { operName } ) => operName === name )
118
+ }
119
+ operName = { name }
102
120
/>
103
- < Button text = "取消" className = { Classes . POPOVER_DISMISS } />
104
- </ div >
105
- }
106
- position = { Position . TOP }
107
- >
108
- < Button intent = { Intent . DANGER } className = "ml-1" text = "重置" />
109
- </ Popover2 >
121
+ ) ) }
122
+ </ OperatorSelectorSkeleton >
123
+ < OperatorSelectorSkeleton
124
+ icon = "person"
125
+ title = "未选择干员"
126
+ collapseDisabled = { ! existedOperators . length }
127
+ >
128
+ { existedOperators . map ( ( { name } ) => (
129
+ < OperatorItemInSheetOperatorEditor
130
+ operName = { name }
131
+ selected = {
132
+ ! ! selectedOperators . find ( ( { operName } ) => operName === name )
133
+ }
134
+ setSelectedOperators = { setSelectedOperators }
135
+ />
136
+ ) ) }
137
+ </ OperatorSelectorSkeleton >
138
+ < OperatorSelectorSkeleton
139
+ icon = "people"
140
+ title = "其他分组干员"
141
+ collapseDisabled = { ! existedOperators ?. length }
142
+ >
143
+ { existedGroups
144
+ . filter (
145
+ ( { name : existedName , opers } ) =>
146
+ existedName !== name && ! ! opers ?. length ,
147
+ )
148
+ . map ( ( { name : otherGroupName , opers } ) => (
149
+ < div key = { otherGroupName } >
150
+ < div className = "flex flex-row-reverse items-center" >
151
+ < H6 className = "p-0 m-0" > { otherGroupName } </ H6 >
152
+ < Button
153
+ minimal
154
+ icon = "arrow-top-left"
155
+ title = "全选"
156
+ onClick = { ( ) =>
157
+ opers ?. forEach ( ( { name } ) => {
158
+ if (
159
+ selectedOperators . find (
160
+ ( { operName } ) => operName === name ,
161
+ )
162
+ )
163
+ return
164
+ setSelectedOperators ( ( prev ) => [
165
+ ...prev ,
166
+ { operName : name , groupName : otherGroupName } ,
167
+ ] )
168
+ } )
169
+ }
170
+ />
171
+ </ div >
172
+ { opers ?. map ( ( { name } ) => (
173
+ < OperatorItemInSheetOperatorEditor
174
+ operName = { name }
175
+ setSelectedOperators = { setSelectedOperators }
176
+ selected = {
177
+ ! ! selectedOperators . find (
178
+ ( { operName } ) => operName === name ,
179
+ )
180
+ }
181
+ />
182
+ ) ) }
183
+ </ div >
184
+ ) ) }
185
+ </ OperatorSelectorSkeleton >
186
+ </ div >
187
+ < div className = "flex p-0.5" >
188
+ < Button
189
+ text = "确认"
190
+ className = { Classes . POPOVER_DISMISS }
191
+ type = "submit"
192
+ />
193
+ < Popover2
194
+ captureDismiss
195
+ content = {
196
+ < div className = "flex items-center" >
197
+ < p > 所有未保存的数据均会丢失,确认继续?</ p >
198
+ < Button
199
+ type = "reset"
200
+ text = "继续"
201
+ className = { clsx ( Classes . POPOVER_DISMISS , 'mx-1' ) }
202
+ />
203
+ < Button text = "取消" className = { Classes . POPOVER_DISMISS } />
204
+ </ div >
205
+ }
206
+ position = { Position . TOP }
207
+ >
208
+ < Button intent = { Intent . DANGER } className = "ml-1" text = "重置" />
209
+ </ Popover2 >
210
+ </ div >
110
211
</ form >
111
212
</ SheetContainerSkeleton >
112
213
)
@@ -115,15 +216,63 @@ const SheetOperatorEditorForm: FC<SheetOperatorEditorFormProp> = ({
115
216
const OperatorItemInSheetOperatorEditor : FC <
116
217
{
117
218
selected : boolean
118
- name : Operator [ 'name' ]
119
- } & CardProps
120
- > = ( { selected, name, ...cardProps } ) => (
121
- < Card { ...cardProps } className = { clsx ( selected && 'scale-90 bg-gray-200' ) } >
122
- < OperatorAvatar name = { name } />
123
- < p className = "font-bold leading-none text-center mt-3 truncate" > { name } </ p >
124
- </ Card >
125
- )
126
-
219
+ setSelectedOperators : Dispatch <
220
+ SetStateAction < OperatorInSheetOperatorEditor [ ] >
221
+ >
222
+ } & OperatorInSheetOperatorEditor
223
+ > = ( { selected, operName, groupName, setSelectedOperators } ) => {
224
+ const onOperatorSelect = ( ) => {
225
+ setSelectedOperators ( ( prev ) =>
226
+ selected
227
+ ? prev . filter (
228
+ ( { operName : selectedOperName } ) => selectedOperName !== operName ,
229
+ )
230
+ : [ ...prev , { groupName, operName } ] ,
231
+ )
232
+ }
233
+ return (
234
+ < Card
235
+ interactive = { ! selected }
236
+ className = { clsx (
237
+ selected && 'scale-90 bg-gray-200' ,
238
+ 'w-1/4 p-0.5 flex flex-col items-center cursor-pointer' ,
239
+ ) }
240
+ onClick = { onOperatorSelect }
241
+ >
242
+ < OperatorAvatar name = { operName } size = "large" />
243
+ < p className = "font-bold leading-none text-center mt-3 truncate" >
244
+ { operName }
245
+ </ p >
246
+ </ Card >
247
+ )
248
+ }
127
249
250
+ const OperatorSelectorSkeleton : FC < {
251
+ collapseDisabled : boolean
252
+ title : SheetContainerSkeletonProps [ 'title' ]
253
+ icon : SheetContainerSkeletonProps [ 'icon' ]
254
+ children : ReactNode
255
+ } > = ( { children, collapseDisabled, ...sheetContainerSkeletonProps } ) => {
256
+ const [ isOpen , setIsOpen ] = useState ( true )
128
257
129
- const OperatorSelectInGroupItem : FC = ( ) => { }
258
+ return (
259
+ < SheetContainerSkeleton
260
+ { ...sheetContainerSkeletonProps }
261
+ mini
262
+ className = "w-96"
263
+ rightOptions = {
264
+ < Button
265
+ onClick = { ( ) => setIsOpen ( ( prev ) => ! prev ) }
266
+ icon = { isOpen ? 'collapse-all' : 'expand-all' }
267
+ title = { `${ isOpen ? '折叠' : '展开' } 所包含干员` }
268
+ minimal
269
+ className = "cursor-pointer ml-1"
270
+ />
271
+ }
272
+ >
273
+ < Collapse isOpen = { isOpen } className = "m-0.5" >
274
+ { children }
275
+ </ Collapse >
276
+ </ SheetContainerSkeleton >
277
+ )
278
+ }
0 commit comments