diff --git a/apps/api/src/applicant/ienapplicant.util.service.ts b/apps/api/src/applicant/ienapplicant.util.service.ts
index db597970..0d3ef0b1 100755
--- a/apps/api/src/applicant/ienapplicant.util.service.ts
+++ b/apps/api/src/applicant/ienapplicant.util.service.ts
@@ -15,7 +15,7 @@ import { IENJobTitle } from './entity/ienjobtitles.entity';
import { IENJobLocation } from './entity/ienjoblocation.entity';
import { IENStatusReason } from './entity/ienstatus-reason.entity';
import { IENMasterService } from './ien-master.service';
-import { searchNames } from '../common/search-names';
+import { searchNamesAndAts1Id } from 'src/common/search-names';
@Injectable()
export class IENApplicantUtilService {
@@ -93,7 +93,7 @@ export class IENApplicantUtilService {
}
}
if (name) {
- searchNames(builder, 'applicant.name', name);
+ searchNamesAndAts1Id(builder, ['applicant.name', 'applicant.ats1_id'], name);
}
if (sortKey === 'recruiter') {
diff --git a/apps/api/src/common/search-names.ts b/apps/api/src/common/search-names.ts
index ca2b43af..02b9cce5 100644
--- a/apps/api/src/common/search-names.ts
+++ b/apps/api/src/common/search-names.ts
@@ -1,5 +1,28 @@
import { Brackets, WhereExpressionBuilder } from 'typeorm';
+const ATS1_ID_LENGTH = 6;
+export const searchNamesAndAts1Id = (
+ builder: WhereExpressionBuilder,
+ fields: [nameField: string, ats1IdField: string],
+ keyword: string,
+) => {
+ const keywords = keyword
+ .trim()
+ .split(' ')
+ .filter(item => item.length);
+
+ // Check if the keyword is a potential ATS1 ID
+ if (
+ keywords.length === 1 &&
+ keywords[0].length === ATS1_ID_LENGTH &&
+ !isNaN(Number(keywords[0]))
+ ) {
+ searchAts1Id(builder, fields[1], keyword);
+ } else {
+ searchNames(builder, fields[0], keyword);
+ }
+};
+
export const searchNames = (builder: WhereExpressionBuilder, field: string, keyword: string) => {
const keywords = keyword
.trim()
@@ -30,3 +53,18 @@ export const searchNames = (builder: WhereExpressionBuilder, field: string, keyw
builder.andWhere(`${field} ilike :name`, { name: `%${keyword.trim()}%` });
}
};
+
+export const searchAts1Id = (builder: WhereExpressionBuilder, field: string, keyword: string) => {
+ const keywords = keyword
+ .trim()
+ .split(' ')
+ .filter(item => item.length);
+
+ if (
+ keywords.length === 1 &&
+ keywords[0].length === ATS1_ID_LENGTH &&
+ !isNaN(Number(keywords[0]))
+ ) {
+ builder.andWhere(`${field} = :ats1_id`, { ats1_id: `${keyword.trim()}` });
+ }
+};
diff --git a/apps/web/src/components/Search.tsx b/apps/web/src/components/Search.tsx
index 8307ac36..bceced81 100644
--- a/apps/web/src/components/Search.tsx
+++ b/apps/web/src/components/Search.tsx
@@ -54,11 +54,18 @@ export const Search = (props: SearchProps) => {
const getResultText = (applicant: ApplicantRO) => {
if (!isHmbc(authUser) || !applicant.status) {
- return {applicant.name};
+ return (
+
+ {applicant.ats1_id} - {applicant.name}
+
+ );
}
return (
<>
- {applicant.name} found in {applicant.status.status}
+
+ {applicant.ats1_id} - {applicant.name}
+ {' '}
+ found in {applicant.status.status}
>
);
};
@@ -74,7 +81,7 @@ export const Search = (props: SearchProps) => {
onChange={handleChange}
onFocus={() => handleFocus(true)}
onKeyDown={handleEnter}
- placeholder='Search by first name or last name'
+ placeholder='Search by first name, last name or ATS1 ID'
className='flex-grow focus:outline-none placeholder-bcGray'
data-cy='search-input'
/>
diff --git a/apps/web/tests/components/form/Search.test.tsx b/apps/web/tests/components/form/Search.test.tsx
index 03870049..a7930ff8 100644
--- a/apps/web/tests/components/form/Search.test.tsx
+++ b/apps/web/tests/components/form/Search.test.tsx
@@ -5,21 +5,26 @@ describe('Search', () => {
it('renders a search box', async () => {
const mock = jest.fn();
const searchData = [
- { id: '1', name: 'Jane Doe', status: { id: 1, status: 'Recruitment' } },
- { id: '2', name: 'Mark Twain', status: { id: 5, status: 'Final Milestone' } },
+ { ats1_id: '111111', id: '1', name: 'Jane Doe', status: { id: 1, status: 'Recruitment' } },
+ {
+ ats1_id: '222222',
+ id: '2',
+ name: 'Mark Twain',
+ status: { id: 5, status: 'Final Milestone' },
+ },
];
const search = async (): Promise => searchData;
render();
- const input = screen.getByPlaceholderText('Search by first name or last name');
+ const input = screen.getByPlaceholderText('Search by first name, last name or ATS1 ID');
expect(input).toBeInTheDocument();
input.focus();
fireEvent.change(input, { target: { value: 'Mark' } });
- for (const { name } of searchData) {
+ for (const { name, ats1_id } of searchData) {
await waitFor(() => {
- expect(screen.getByText(name)).toBeInTheDocument();
+ expect(screen.getByText(`${ats1_id} - ${name}`)).toBeInTheDocument();
});
}