1
1
import React from 'react' ;
2
- import { Heading , Paragraph , Select , Option , TextInput , Card } from '@contentful/f36-components' ;
2
+ import { Heading , Paragraph , Select , Option , Autocomplete } from '@contentful/f36-components' ;
3
3
import { JiraCloudResource , CloudProject } from '../../../interfaces' ;
4
4
5
- // using lodash.debouce basically breaks test with infinite timers
6
- const debounce = function ( fn : Function , timeout : number ) : Function {
7
- let timer : any ;
8
-
9
- return function ( ...args : any [ ] ) {
10
- clearTimeout ( timer ) ;
11
- timer = setTimeout ( ( ) => {
12
- fn ( ...args ) ;
13
- } , timeout ) ;
14
- } ;
15
- } ;
16
-
17
- interface State {
18
- inputValue : string ;
19
- }
20
-
21
5
interface Props {
22
6
resources : JiraCloudResource [ ] ;
23
7
selectedResource : string ;
@@ -28,30 +12,23 @@ interface Props {
28
12
queryProjects : ( query : string ) => void ;
29
13
}
30
14
31
- export default class InstanceStep extends React . Component < Props , State > {
32
- constructor ( props : Props ) {
33
- super ( props ) ;
34
-
35
- this . state = {
36
- inputValue : '' ,
37
- } ;
15
+ export default class InstanceStep extends React . Component < Props > {
16
+ componentDidMount ( ) {
17
+ this . setInputTestId ( ) ;
38
18
}
39
19
40
- handleInputChange = debounce ( ( ev : any ) => {
41
- this . setState ( {
42
- inputValue : ev . target . value ,
43
- } ) ;
44
-
45
- this . props . queryProjects ( ev . target . value ) ;
46
- } , 300 ) ;
47
-
48
- selectProject = ( project : CloudProject ) => {
49
- this . setState ( {
50
- inputValue : project . name ,
51
- } ) ;
20
+ componentDidUpdate ( ) {
21
+ this . setInputTestId ( ) ;
22
+ }
52
23
53
- this . props . pickProject ( project ) ;
54
- } ;
24
+ setInputTestId ( ) {
25
+ // Forma 36 Autocomplete renders an input inside the component
26
+ // We find it and set the data-test-id for the test
27
+ const el = document . querySelector ( '.project-autocomplete input' ) ;
28
+ if ( el ) {
29
+ el . setAttribute ( 'data-test-id' , 'cf-ui-text-input' ) ;
30
+ }
31
+ }
55
32
56
33
render ( ) {
57
34
const { resources, pickResource, selectedResource, projects, selectedProject } = this . props ;
@@ -61,51 +38,45 @@ export default class InstanceStep extends React.Component<Props, State> {
61
38
< Heading > Configure</ Heading >
62
39
< Paragraph > Select the Jira site and project you want to connect</ Paragraph >
63
40
< div className = "jira-config" data-test-id = "instance-step" >
64
- < Select
65
- testId = "instance-selector"
66
- className = " selector"
67
- // @ts -ignore: 2339
68
- onChange = { ( e ) => pickResource ( e . target . value ) }
69
- isDisabled = { resources . length === 1 }
70
- value = { selectedResource || '' } >
71
- < Option value = "" > Select a site</ Option >
72
- { resources . map ( ( r ) => (
73
- < Option key = { r . id } value = { r . id } >
74
- { r . url . replace ( 'https://' , '' ) }
75
- </ Option >
76
- ) ) }
77
- </ Select >
41
+ < div className = "jira-config-row" >
42
+ < Select
43
+ testId = "instance- selector"
44
+ className = "selector"
45
+ onChange = { ( e : React . ChangeEvent < HTMLSelectElement > ) => pickResource ( e . target . value ) }
46
+ isDisabled = { resources . length === 1 }
47
+ value = { selectedResource || '' } >
48
+ < Option value = "" > Select a site</ Option >
49
+ { resources . map ( ( r ) => (
50
+ < Option key = { r . id } value = { r . id } >
51
+ { r . url . replace ( 'https://' , '' ) }
52
+ </ Option >
53
+ ) ) }
54
+ </ Select >
78
55
79
- < div className = "search-projects" >
80
- < TextInput
81
- width = "full"
82
- placeholder = { selectedProject ? selectedProject . name : 'Search for a project' }
83
- value = { this . state . inputValue }
84
- onChange = { ( ev ) => {
85
- ev . persist ( ) ;
86
- this . handleInputChange ( ev ) ;
87
- } }
88
- onFocus = { ( ) => {
89
- this . setState ( { inputValue : '' } ) ;
56
+ < Autocomplete < CloudProject >
57
+ items = { projects }
58
+ itemToString = { ( item ) => ( item ? item . name : '' ) }
59
+ testId = "project-autocomplete"
60
+ noMatchesMessage = "No projects found"
61
+ onSelectItem = { ( item ) => {
62
+ if ( item ) this . props . pickProject ( item ) ;
90
63
} }
91
- onBlur = { ( ) => {
92
- this . setState ( { inputValue : selectedProject ? selectedProject . name : '' } ) ;
64
+ selectedItem = { selectedProject || undefined }
65
+ onInputValueChange = { ( inputValue ) => {
66
+ this . props . queryProjects ( inputValue || '' ) ;
93
67
} }
94
- />
95
- < div className = "search-projects-results" >
96
- { projects . map ( ( project ) => {
68
+ renderItem = { ( item : CloudProject , inputValue : string ) => {
69
+ const isSelected = selectedProject && selectedProject . id === item . id ;
97
70
return (
98
- < Card
99
- key = { project . id }
100
- testId = "search-result-project"
101
- onClick = { ( ) => {
102
- this . selectProject ( project ) ;
103
- } } >
104
- { project . name }
105
- </ Card >
71
+ < div
72
+ data-test-id = "search-result-project"
73
+ className = { `autocomplete-item${ isSelected ? ' selected' : '' } ` } >
74
+ { item . name }
75
+ </ div >
106
76
) ;
107
- } ) }
108
- </ div >
77
+ } }
78
+ className = "project-autocomplete"
79
+ />
109
80
</ div >
110
81
</ div >
111
82
</ >
0 commit comments