11import 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' ;
33import { JiraCloudResource , CloudProject } from '../../../interfaces' ;
44
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-
215interface Props {
226 resources : JiraCloudResource [ ] ;
237 selectedResource : string ;
@@ -28,30 +12,23 @@ interface Props {
2812 queryProjects : ( query : string ) => void ;
2913}
3014
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 ( ) ;
3818 }
3919
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+ }
5223
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+ }
5532
5633 render ( ) {
5734 const { resources, pickResource, selectedResource, projects, selectedProject } = this . props ;
@@ -61,51 +38,45 @@ export default class InstanceStep extends React.Component<Props, State> {
6138 < Heading > Configure</ Heading >
6239 < Paragraph > Select the Jira site and project you want to connect</ Paragraph >
6340 < 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 >
7855
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 ) ;
9063 } }
91- onBlur = { ( ) => {
92- this . setState ( { inputValue : selectedProject ? selectedProject . name : '' } ) ;
64+ selectedItem = { selectedProject || undefined }
65+ onInputValueChange = { ( inputValue ) => {
66+ this . props . queryProjects ( inputValue || '' ) ;
9367 } }
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 ;
9770 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 >
10676 ) ;
107- } ) }
108- </ div >
77+ } }
78+ className = "project-autocomplete"
79+ />
10980 </ div >
11081 </ div >
11182 </ >
0 commit comments