Skip to content

Commit 783a9e0

Browse files
committed
TAL - fetch actual data for search results
1 parent 5e7c7b8 commit 783a9e0

File tree

22 files changed

+519
-325
lines changed

22 files changed

+519
-325
lines changed

src/apps/talent-search/src/components/search-input/SearchInput.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ import { EmsiSkill, EmsiSkillSources, InputSkillSelector, Skill } from '~/libs/s
66
import styles from './SearchInput.module.scss'
77

88
interface SearchInputProps {
9+
readonly autoFocus?: boolean
910
onChange: (skills: Skill[]) => void
1011
skills: Skill[]
12+
onSearch?: () => void
1113
}
1214

1315
const SearchInput: FC<SearchInputProps> = props => {
@@ -27,12 +29,14 @@ const SearchInput: FC<SearchInputProps> = props => {
2729

2830
return (
2931
<InputSkillSelector
32+
autoFocus={props.autoFocus}
3033
placeholder='Enter skills you are searching for...'
3134
useWrapper={false}
3235
theme='clear'
3336
dropdownIcon={<IconOutline.SearchIcon className={styles.searchIcon} />}
3437
value={emsiSkills}
3538
onChange={onChange}
39+
onSubmit={props.onSearch}
3640
/>
3741
)
3842
}

src/apps/talent-search/src/components/skill-pill/SkillPill.module.scss

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
align-items: center;
1313
gap: $sp-1;
1414

15-
height: $sp-8;
16-
1715
&:hover {
1816
background-color: rgba($tc-white, 0.1);
1917
}
@@ -25,6 +23,7 @@
2523
.text {
2624
display: block;
2725
line-height: 16px;
26+
text-align: left;
2827
}
2928
}
3029

@@ -34,8 +33,9 @@
3433
color: $black-100;
3534

3635
svg {
36+
flex: 0 0 auto;
3737
color: $turq-120;
38-
@include icon-size(14);
38+
@include icon-size(16);
3939
}
4040
}
4141

src/apps/talent-search/src/components/skill-pill/SkillPill.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export interface SkillPillProps {
1010
children?: ReactNode
1111
onClick?: (skill: Skill) => void
1212
selected?: boolean
13-
skill: Skill
13+
skill: {name: string}
1414
theme?: 'dark' | 'verified' | 'light' | 'etc'
1515
verified?: boolean
1616
}
@@ -22,7 +22,7 @@ const SkillPill: FC<SkillPillProps> = props => {
2222
styles[`theme-${props.verified ? 'verified' : (props.theme ?? 'light')}`],
2323
)
2424

25-
const handleClick = useCallback(() => props.onClick?.call(undefined, props.skill), [
25+
const handleClick = useCallback(() => props.onClick?.call(undefined, props.skill as Skill), [
2626
props.onClick, props.skill,
2727
])
2828

Lines changed: 154 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -1,153 +1,154 @@
1-
/* eslint-disable react/jsx-no-bind */
2-
/* eslint-disable react/no-access-state-in-setstate */
3-
/* eslint-disable react/state-in-constructor */
4-
/* eslint-disable ordered-imports/ordered-imports */
5-
6-
import { Component } from 'react'
7-
import { LoadingCircles, Table, TableColumn } from '~/libs/ui'
8-
import { MatcherService } from '@talentSearch/lib/services/'
9-
import { Member, Skill } from '@talentSearch/lib/models'
10-
import codes, { ICountryCodeItem } from 'country-calling-code'
11-
import MemberHandleRenderer from './renderers/MemberHandleRenderer'
12-
import MemberSkillsRenderer from './renderers/MemberSkillsRenderer'
13-
14-
export const memberColumns: ReadonlyArray<TableColumn<Member>> = [
15-
{
16-
defaultSortDirection: 'desc',
17-
label: 'Wins',
18-
propertyName: 'numberOfChallengesWon',
19-
renderer: MemberHandleRenderer,
20-
type: 'numberElement',
21-
},
22-
{
23-
label: 'Skills',
24-
renderer: MemberSkillsRenderer,
25-
type: 'element',
26-
},
27-
]
28-
29-
type SkillSearchResultsProps = {
30-
skillsFilter:ReadonlyArray<Skill>
31-
}
32-
33-
type SkilLSearchResultState = {
34-
isLoading: boolean
35-
searchResults: ReadonlyArray<Member>
36-
skillsFilter: ReadonlyArray<Skill>
37-
page: number,
38-
hasMore: boolean
39-
}
40-
41-
const PER_PAGE:number = 10
42-
43-
export default class SkillSearchResult extends Component<SkillSearchResultsProps> {
44-
state: SkilLSearchResultState
45-
46-
constructor(props: SkillSearchResultsProps) {
47-
super(props)
48-
this.state = {
49-
hasMore: true,
50-
isLoading: false,
51-
page: 1,
52-
searchResults: [],
53-
skillsFilter: [],
54-
}
55-
}
56-
57-
componentDidUpdate(): void {
58-
if (this.props.skillsFilter !== this.state.skillsFilter) {
59-
this.state.searchResults = []
60-
this.state.page = 1
61-
this.retrieveMatches()
62-
this.state.skillsFilter = this.props.skillsFilter
63-
}
64-
}
65-
66-
retrieveMatches(): void {
67-
this.state.isLoading = true
68-
this.setState(this.state)
69-
MatcherService.retrieveMatchesForSkills(this.props.skillsFilter, this.state.page, PER_PAGE)
70-
.then((response: Array<Member>) => {
71-
if (response) {
72-
if (response.length === PER_PAGE) {
73-
this.state.hasMore = true
74-
} else {
75-
this.state.hasMore = false
76-
}
77-
78-
const filter:readonly Skill[] = this.props.skillsFilter
79-
response.forEach(value => {
80-
const code:ICountryCodeItem | undefined = codes.find(i => i.isoCode3
81-
=== value.competitionCountryCode)
82-
83-
if (code) {
84-
value.country = code.country
85-
}
86-
87-
// This isn't great TODO: make this cleaner
88-
value.emsiSkills.forEach(emsiSkill => {
89-
emsiSkill.isSearched = false
90-
for (let i:number = 0; i < filter.length; i++) {
91-
if (emsiSkill.skillId === filter[i].emsiId) {
92-
emsiSkill.isSearched = true
93-
}
94-
}
95-
})
96-
// Move the values that were searched to the front of the skills list for display in the UI
97-
value.emsiSkills.sort((a, b) => ((a.isSearched && b.isSearched) ? a.name.localeCompare(b.name)
98-
: (a.isSearched ? -1 : 0)))
99-
})
100-
}
101-
102-
if (this.state.page === 1) {
103-
this.state.searchResults = response
104-
} else {
105-
this.state.searchResults = this.state.searchResults.concat(response)
106-
}
107-
108-
this.state.isLoading = false
109-
this.setState(this.state)
110-
})
111-
.catch((e: Error) => {
112-
console.log(e)
113-
})
114-
}
115-
116-
async loadMore(): Promise<void> {
117-
this.state.page += 1
118-
this.setState(this.state)
119-
this.retrieveMatches()
120-
}
121-
122-
render(): JSX.Element | null {
123-
// If we searched and have no results, show "No results found", otherwise hide the results table
124-
// until a search has been made
125-
if (this.state.isLoading) {
126-
return (<LoadingCircles />)
127-
}
128-
129-
if (this.props.skillsFilter
130-
&& this.props.skillsFilter.length > 0
131-
&& (!this.state.searchResults
132-
|| this.state.searchResults.length === 0)) {
133-
// TODO - fill this in with useful no results found
134-
return (<div>No results found</div>)
135-
}
136-
137-
if (!this.props.skillsFilter
138-
|| this.props.skillsFilter.length === 0) {
139-
return (<div />)
140-
}
141-
142-
return (
143-
<div>
144-
<Table
145-
data={this.state.searchResults}
146-
columns={memberColumns}
147-
onLoadMoreClick={() => this.loadMore()}
148-
moreToLoad={this.state.hasMore}
149-
/>
150-
</div>
151-
)
152-
}
153-
}
1+
// /* eslint-disable react/jsx-no-bind */
2+
// /* eslint-disable react/no-access-state-in-setstate */
3+
// /* eslint-disable react/state-in-constructor */
4+
// /* eslint-disable ordered-imports/ordered-imports */
5+
6+
// import { Component } from 'react'
7+
// import { LoadingCircles, Table, TableColumn } from '~/libs/ui'
8+
// import { MatcherService } from '@talentSearch/lib/services/'
9+
// import { Member, Skill } from '@talentSearch/lib/models'
10+
// import codes, { ICountryCodeItem } from 'country-calling-code'
11+
// import MemberHandleRenderer from './renderers/MemberHandleRenderer'
12+
// import MemberSkillsRenderer from './renderers/MemberSkillsRenderer'
13+
14+
// export const memberColumns: ReadonlyArray<TableColumn<Member>> = [
15+
// {
16+
// defaultSortDirection: 'desc',
17+
// label: 'Wins',
18+
// propertyName: 'numberOfChallengesWon',
19+
// renderer: MemberHandleRenderer,
20+
// type: 'numberElement',
21+
// },
22+
// {
23+
// label: 'Skills',
24+
// renderer: MemberSkillsRenderer,
25+
// type: 'element',
26+
// },
27+
// ]
28+
29+
// type SkillSearchResultsProps = {
30+
// skillsFilter:ReadonlyArray<Skill>
31+
// }
32+
33+
// type SkilLSearchResultState = {
34+
// isLoading: boolean
35+
// searchResults: ReadonlyArray<Member>
36+
// skillsFilter: ReadonlyArray<Skill>
37+
// page: number,
38+
// hasMore: boolean
39+
// }
40+
41+
// const PER_PAGE:number = 10
42+
43+
// export default class SkillSearchResult extends Component<SkillSearchResultsProps> {
44+
// state: SkilLSearchResultState
45+
46+
// constructor(props: SkillSearchResultsProps) {
47+
// super(props)
48+
// this.state = {
49+
// hasMore: true,
50+
// isLoading: false,
51+
// page: 1,
52+
// searchResults: [],
53+
// skillsFilter: [],
54+
// }
55+
// }
56+
57+
// componentDidUpdate(): void {
58+
// if (this.props.skillsFilter !== this.state.skillsFilter) {
59+
// this.state.searchResults = []
60+
// this.state.page = 1
61+
// this.retrieveMatches()
62+
// this.state.skillsFilter = this.props.skillsFilter
63+
// }
64+
// }
65+
66+
// retrieveMatches(): void {
67+
// this.state.isLoading = true
68+
// this.setState(this.state)
69+
// MatcherService.retrieveMatchesForSkills(this.props.skillsFilter, this.state.page, PER_PAGE)
70+
// .then((response: Array<Member>) => {
71+
// if (response) {
72+
// if (response.length === PER_PAGE) {
73+
// this.state.hasMore = true
74+
// } else {
75+
// this.state.hasMore = false
76+
// }
77+
78+
// const filter:readonly Skill[] = this.props.skillsFilter
79+
// response.forEach(value => {
80+
// const code:ICountryCodeItem | undefined = codes.find(i => i.isoCode3
81+
// === value.competitionCountryCode)
82+
83+
// if (code) {
84+
// value.country = code.country
85+
// }
86+
87+
// // This isn't great TODO: make this cleaner
88+
// value.emsiSkills.forEach(emsiSkill => {
89+
// emsiSkill.isSearched = false
90+
// for (let i:number = 0; i < filter.length; i++) {
91+
// if (emsiSkill.skillId === filter[i].emsiId) {
92+
// emsiSkill.isSearched = true
93+
// }
94+
// }
95+
// })
96+
// // Move the values that were searched to the front of the skills list for display in the UI
97+
// value.emsiSkills.sort((a, b) => ((a.isSearched && b.isSearched) ? a.name.localeCompare(b.name)
98+
// : (a.isSearched ? -1 : 0)))
99+
// })
100+
// }
101+
102+
// if (this.state.page === 1) {
103+
// this.state.searchResults = response
104+
// } else {
105+
// this.state.searchResults = this.state.searchResults.concat(response)
106+
// }
107+
108+
// this.state.isLoading = false
109+
// this.setState(this.state)
110+
// })
111+
// .catch((e: Error) => {
112+
// console.log(e)
113+
// })
114+
// }
115+
116+
// async loadMore(): Promise<void> {
117+
// this.state.page += 1
118+
// this.setState(this.state)
119+
// this.retrieveMatches()
120+
// }
121+
122+
// render(): JSX.Element | null {
123+
// // If we searched and have no results, show "No results found", otherwise hide the results table
124+
// // until a search has been made
125+
// if (this.state.isLoading) {
126+
// return (<LoadingCircles />)
127+
// }
128+
129+
// if (this.props.skillsFilter
130+
// && this.props.skillsFilter.length > 0
131+
// && (!this.state.searchResults
132+
// || this.state.searchResults.length === 0)) {
133+
// // TODO - fill this in with useful no results found
134+
// return (<div>No results found</div>)
135+
// }
136+
137+
// if (!this.props.skillsFilter
138+
// || this.props.skillsFilter.length === 0) {
139+
// return (<div />)
140+
// }
141+
142+
// return (
143+
// <div>
144+
// <Table
145+
// data={this.state.searchResults}
146+
// columns={memberColumns}
147+
// onLoadMoreClick={() => this.loadMore()}
148+
// moreToLoad={this.state.hasMore}
149+
// />
150+
// </div>
151+
// )
152+
// }
153+
// }
154+
export {}

0 commit comments

Comments
 (0)