@@ -14,7 +14,8 @@ import { Async } from '@uifabric/utilities/lib/Async';
14
14
const styles = mergeStyleSets ( {
15
15
loadingSpinnerContainer : {
16
16
width : '100%' ,
17
- textAlign : 'center'
17
+ textAlign : 'center' ,
18
+ marginTop : '8px'
18
19
} ,
19
20
searchBox : {
20
21
margin : '4px 0'
@@ -66,10 +67,11 @@ export const SitePicker: React.FunctionComponent<ISitePickerProps> = (props: Rea
66
67
onChange,
67
68
placeholder,
68
69
searchPlaceholder,
69
- deferredSearchTime
70
+ deferredSearchTime,
71
+ className
70
72
} = props ;
71
73
72
- const [ isLoading , setIsLoading ] = React . useState < boolean > ( true ) ;
74
+ const [ isLoading , setIsLoading ] = React . useState < boolean > ( ) ;
73
75
const [ selectedSites , setSelectedSites ] = React . useState < ISite [ ] > ( ) ;
74
76
const [ allSites , setAllSites ] = React . useState < ISite [ ] > ( ) ;
75
77
const [ filteredSites , setFilteredSites ] = React . useState < ISite [ ] > ( ) ;
@@ -88,9 +90,10 @@ export const SitePicker: React.FunctionComponent<ISitePickerProps> = (props: Rea
88
90
} , [ allSites ] ) ;
89
91
90
92
const onSelectionChange = React . useCallback ( ( e , item : IDropdownOption , index : number ) => {
91
- const newSelectedSites = selectedSites ? [ ... selectedSites ] : [ ] ;
93
+ let newSelectedSites : ISite [ ] = [ ] ;
92
94
93
95
if ( multiSelect !== false ) {
96
+ newSelectedSites = selectedSites ? [ ...selectedSites ] : [ ] ;
94
97
const existingIndex = findIndex ( newSelectedSites , s => s . url === item . key ) ;
95
98
96
99
if ( existingIndex >= 0 ) {
@@ -102,6 +105,11 @@ export const SitePicker: React.FunctionComponent<ISitePickerProps> = (props: Rea
102
105
} ) ;
103
106
}
104
107
}
108
+ else {
109
+ newSelectedSites = [ {
110
+ ...item . data !
111
+ } ] ;
112
+ }
105
113
106
114
if ( onChange ) {
107
115
onChange ( newSelectedSites ) ;
@@ -112,6 +120,15 @@ export const SitePicker: React.FunctionComponent<ISitePickerProps> = (props: Rea
112
120
} , [ selectedSites , multiSelect , onChange ] ) ;
113
121
114
122
const getOptions = React . useCallback ( ( ) : IDropdownOption [ ] => {
123
+
124
+ if ( ! allSites ) {
125
+ return [ {
126
+ key : 'spinner' ,
127
+ text : '' ,
128
+ itemType : SelectableOptionMenuItemType . Header
129
+ } ] ;
130
+ }
131
+
115
132
const result : IDropdownOption [ ] = [ ] ;
116
133
117
134
if ( allowSearch ) {
@@ -136,19 +153,32 @@ export const SitePicker: React.FunctionComponent<ISitePickerProps> = (props: Rea
136
153
}
137
154
138
155
return result ;
139
- } , [ allowSearch , selectedSites , filteredSites ] ) ;
156
+ } , [ allowSearch , selectedSites , filteredSites , allSites ] ) ;
140
157
141
158
const onRenderOption = ( option ?: ISelectableOption , defaultRender ?: ( props ?: ISelectableOption ) => JSX . Element | null ) : JSX . Element | null => {
142
159
if ( ! props ) {
143
160
return null ;
144
161
}
145
162
146
163
if ( option . itemType === SelectableOptionMenuItemType . Header ) {
147
- return < SearchBox
148
- placeholder = { searchPlaceholder }
149
- value = { searchQuery }
150
- onChange = { async . debounce ( onSearchChange , deferredSearchTime || 200 ) }
151
- className = { styles . searchBox } /> ;
164
+ if ( option . key === 'search' ) {
165
+ return < SearchBox
166
+ placeholder = { searchPlaceholder }
167
+ value = { searchQuery }
168
+ onChange = { async . debounce ( onSearchChange , deferredSearchTime || 200 ) }
169
+ className = { styles . searchBox } /> ;
170
+ }
171
+ else if ( option . key === 'spinner' ) {
172
+ //
173
+ // This happens when the dropdown is opened for the first time.
174
+ // That's when we want to load the sites
175
+ //
176
+ setIsLoading ( true ) ;
177
+
178
+ return < div className = { styles . loadingSpinnerContainer } >
179
+ < Spinner size = { SpinnerSize . medium } />
180
+ </ div > ;
181
+ }
152
182
}
153
183
// {multiSelect !== false && <Checkbox className={styles.siteOptionCheckbox} checked={option.selected} disabled={option.disabled} /> }
154
184
return < div className = { styles . siteOption } >
@@ -174,11 +204,10 @@ export const SitePicker: React.FunctionComponent<ISitePickerProps> = (props: Rea
174
204
} , [ initialSites ] ) ;
175
205
176
206
React . useEffect ( ( ) => {
177
- if ( ! context ) {
207
+ if ( ! context || ! isLoading ) {
178
208
return ;
179
209
}
180
210
181
- setIsLoading ( true ) ;
182
211
setSearchQuery ( '' ) ;
183
212
setFilteredSites ( [ ] ) ;
184
213
@@ -195,7 +224,8 @@ export const SitePicker: React.FunctionComponent<ISitePickerProps> = (props: Rea
195
224
setAllSites ( copy ) ;
196
225
setIsLoading ( false ) ;
197
226
} ) ;
198
- } , [ context , mode , limitToCurrentSiteCollection ] ) ;
227
+
228
+ } , [ context , isLoading , mode , limitToCurrentSiteCollection ] ) ;
199
229
200
230
React . useEffect ( ( ) => {
201
231
setAllSites ( sites => {
@@ -215,25 +245,20 @@ export const SitePicker: React.FunctionComponent<ISitePickerProps> = (props: Rea
215
245
setFilteredSites ( [ ...allSites ] ) ;
216
246
} , [ allSites ] ) ;
217
247
218
- if ( isLoading ) {
219
- return < div className = { styles . loadingSpinnerContainer } >
220
- < Spinner size = { SpinnerSize . medium } />
221
- </ div > ;
222
- }
223
-
224
248
return (
225
249
< >
226
250
< Dropdown
227
251
label = { label }
228
252
placeholder = { placeholder }
229
253
options = { getOptions ( ) }
230
254
selectedKey = { multiSelect === false && ! ! selectedSites && ! ! selectedSites [ 0 ] ? selectedSites [ 0 ] . url : undefined }
231
- selectedKeys = { multiSelect !== false && ! ! selectedSites ? selectedSites . map ( s => s . url ) : undefined }
255
+ selectedKeys = { multiSelect !== false && ! ! selectedSites ? selectedSites . map ( s => s . url ) : undefined }
232
256
disabled = { disabled }
233
257
multiSelect = { multiSelect !== false }
234
258
onRenderOption = { onRenderOption }
235
259
onChange = { onSelectionChange }
236
260
notifyOnReselect = { true }
261
+ className = { className }
237
262
/>
238
263
</ >
239
264
) ;
0 commit comments