@@ -25,10 +25,12 @@ import FreeformSelect from '../../util/FreeformSelect';
2525
2626export type PkgOutput = Partial < WebPackage > ;
2727
28- interface Props {
28+ interface OwnProps {
2929 initial ?: Partial < WebPackage > ;
3030 onChange ?: ( usage : PkgOutput ) => void ;
31+ }
3132
33+ interface Props extends OwnProps {
3234 dispatch : ( action : any ) => any ;
3335 completions : WebPackage [ ] ;
3436 packages : PackageActions . PackageSet ;
@@ -38,7 +40,12 @@ interface Props {
3840
3941interface State {
4042 pkg : Partial < WebPackage > ;
41- selectedPackage : any ;
43+ selectedPackage : PackageOption ;
44+ }
45+
46+ interface PackageOption extends Option {
47+ name : string ;
48+ version : string ;
4249}
4350
4451interface LicenseOption extends Option {
@@ -49,7 +56,6 @@ interface LicenseOption extends Option {
4956}
5057
5158class PackageFields extends React . Component < Props , State > {
52-
5359 licenseOptions : LicenseOption [ ] = [ ] ;
5460 licenseMap : { [ name : string ] : LicenseOption } = { } ;
5561
@@ -69,20 +75,12 @@ class PackageFields extends React.Component<Props, State> {
6975 const { dispatch, licenses } = this . props ;
7076 if ( licenses . length === 0 ) {
7177 dispatch ( LicenseActions . fetchLicenses ( ) ) ;
72- } else {
73- this . initLicenses ( ) ;
74- }
75- }
76-
77- componentWillReceiveProps ( ) {
78- // no need to re-compute if the list was already built
79- if ( this . licenseOptions . length === 0 ) {
80- this . initLicenses ( ) ;
8178 }
8279 }
8380
8481 componentDidMount ( ) {
8582 this . attachBootstrap ( ) ;
83+ this . setInitialPackage ( ) ;
8684 }
8785
8886 componentDidUpdate ( ) {
@@ -92,6 +90,10 @@ class PackageFields extends React.Component<Props, State> {
9290 initLicenses ( ) {
9391 const { licenses, tags } = this . props ;
9492
93+ if ( licenses . length === 0 || this . licenseOptions . length > 0 ) {
94+ return ;
95+ }
96+
9597 for ( const license of licenses ) {
9698 // gather tag presentation data
9799 const { shortText, longText, fixedText} = license . tags
@@ -145,37 +147,67 @@ class PackageFields extends React.Component<Props, State> {
145147
146148 return [
147149 ...options ,
148- { value : filter , label : `Create package ${ filter } ` , create : true } ,
150+ { value : filter , label : filter , create : true } ,
149151 ] ;
150152 }
151153
154+ packageOptionRenderer = ( option : PackageOption ) => {
155+ if ( option . create ) {
156+ return < span className = "create-package-option" > Create package < strong > { option . value } </ strong > </ span > ;
157+ }
158+
159+ return < span className = "package-option" > { option . name } < small > { option . version } </ small > </ span > ;
160+ }
161+
152162 mapPackageCompletions = ( ) => {
153163 return this . props . completions . map ( ( item ) => {
154164 return {
155165 value : item . packageId ,
156166 label : `${ item . name } (${ item . version } )` ,
167+ name : item . name ,
168+ version : item . version ,
157169 } ;
158170 } ) ;
159171 }
160172
161- isCreating = ( ) => {
162- return this . state . pkg . packageId == null ;
173+ setInitialPackage = ( ) => {
174+ const { initial, packages } = this . props ;
175+ if ( initial == null || initial . packageId == null ) {
176+ return ;
177+ }
178+
179+ if ( this . state . selectedPackage != null ) {
180+ return ;
181+ }
182+
183+ const pkg = packages [ initial . packageId ] ;
184+ if ( pkg == null ) {
185+ return ;
186+ }
187+
188+ this . handlePackageChange ( {
189+ label : `Editing ${ pkg . name } ` ,
190+ value : initial . packageId ,
191+ name : pkg . name ,
192+ version : pkg . version ,
193+ } ) ;
163194 }
164195
165- handlePackageChange = ( selected ) => {
196+ handlePackageChange = ( selected : PackageOption ) => {
166197 // empty input? clear it all
167198 if ( selected == null || selected . value === '' ) {
168199 this . propagateState ( { pkg : { } , selectedPackage : null } ) ;
169200 return ;
170201 }
171202
172- const isCreating = selected . create === true ;
203+ const value = selected . value as number ;
173204
205+ const isCreating = selected . create === true ;
174206 if ( isCreating ) {
175207 this . propagateState ( {
176208 selectedPackage : selected ,
177209 pkg : {
178- name : selected . value ,
210+ name : selected . value as string , // value is a string when accepting custom input
179211 version : '' ,
180212 website : '' ,
181213 license : '' ,
@@ -184,7 +216,7 @@ class PackageFields extends React.Component<Props, State> {
184216 } ,
185217 } ) ;
186218 } else {
187- const pkg = this . props . packages [ selected . value ] ;
219+ const pkg = this . props . packages [ value ] ;
188220 this . propagateState ( {
189221 selectedPackage : selected ,
190222 pkg : {
@@ -202,7 +234,6 @@ class PackageFields extends React.Component<Props, State> {
202234
203235 handleChange = ( e ) => {
204236 const val = e . target . value ;
205-
206237 this . propagateState ( { pkg : {
207238 ...this . state . pkg ,
208239 [ e . target . name ] : val ,
@@ -245,13 +276,16 @@ class PackageFields extends React.Component<Props, State> {
245276 }
246277
247278 render ( ) {
279+
248280 return < div >
249281 < div className = "form-group" id = "package-container" >
250282 < label htmlFor = "package" > Package</ label >
251283 < Select
252284 name = "package"
253285 value = { this . state . selectedPackage }
254286 options = { this . mapPackageCompletions ( ) }
287+ optionRenderer = { this . packageOptionRenderer }
288+ valueRenderer = { this . packageOptionRenderer }
255289 onInputChange = { this . searchPackages }
256290 filterOptions = { this . filterPackageList }
257291 onChange = { this . handlePackageChange }
@@ -268,6 +302,8 @@ class PackageFields extends React.Component<Props, State> {
268302
269303 renderDetails ( ) {
270304 const { pkg } = this . state ;
305+ this . initLicenses ( ) ;
306+
271307 const needsFullLicense = this . needsFullLicense ( ) ;
272308 const largeCopyrightStatement = this . largeCopyrightStatement ( ) ;
273309 const license : Partial < LicenseOption > = this . licenseMap [ pkg . license ] ||
@@ -276,13 +312,11 @@ class PackageFields extends React.Component<Props, State> {
276312 return < div className = "row" >
277313
278314 < div className = "col-md-6" >
279- { this . isCreating ( ) &&
280- < div className = "form-group" >
281- < label htmlFor = "packageVersion" > Version</ label >
282- < input type = "text" name = "version" id = "packageVersion" className = "form-control"
283- value = { pkg . version } onChange = { this . handleChange } />
284- </ div >
285- }
315+ < div className = "form-group" >
316+ < label htmlFor = "packageVersion" > Version</ label >
317+ < input type = "text" name = "version" id = "packageVersion" className = "form-control"
318+ value = { pkg . version } onChange = { this . handleChange } />
319+ </ div >
286320
287321 < div className = "form-group" >
288322 < label htmlFor = "packageLicense" > License</ label >
@@ -333,9 +367,9 @@ class PackageFields extends React.Component<Props, State> {
333367
334368}
335369
336- export default connect ( ( state : any ) => ( {
370+ export default connect ( ( state : any , props : OwnProps ) => ( {
337371 completions : state . packages . completions ,
338372 packages : state . packages . set ,
339373 licenses : state . licenses . list ,
340374 tags : state . licenses . tags ,
341- } ) ) ( PackageFields as any ) as React . ComponentClass < Partial < Props > > ;
375+ } ) ) ( PackageFields ) ;
0 commit comments