Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -566,13 +566,16 @@
"customairshipextender",
"customfield",
"customise",
"darwinbox",
"dateexported",
"dayforce",
"deapex",
"dgst",
"deapexer",
"debitamount",
"deburr",
"deburred",
"decidium",
"dedupe",
"dedup",
"deeplink",
Expand Down Expand Up @@ -656,6 +659,7 @@
"foreignamount",
"formatjs",
"freetext",
"freshteam",
"frontpart",
"fullstory",
"gastos",
Expand All @@ -677,6 +681,7 @@
"gsib",
"gsst",
"gödecke",
"hailey",
"hanno",
"hanno_gödecke",
"headshot",
Expand All @@ -687,6 +692,7 @@
"hibob",
"hrefs",
"hris",
"humaans",
"hybridapp",
"iOSQRCode",
"iaco",
Expand All @@ -698,7 +704,10 @@
"inbetweenCompo",
"initialises",
"inputmethod",
"insperity",
"instancetype",
"intelli",
"intellihr",
"intenthandler",
"ionatan",
"iphonesimulator",
Expand All @@ -715,6 +724,11 @@
"jridgewell",
"jsSrcsDir",
"jsbundle",
"jumpcloud",
"justworks",
"kallidus",
"keka",
"kenjo",
"keyalg",
"keycap",
"keycommand",
Expand Down Expand Up @@ -847,13 +861,15 @@
"passplus",
"passwordless",
"pathspec",
"paycor",
"payrollcode",
"payrollid",
"pbxproj",
"pdfreport",
"pdfs",
"perdiem",
"perdiems",
"peoplehr",
"persistable",
"personaltrackcase",
"personaltrackgoal",
Expand Down Expand Up @@ -956,6 +972,7 @@
"sideproject",
"simctl",
"showcerts",
"simployer",
"skia",
"skip_codesigning",
"soloader",
Expand Down Expand Up @@ -984,6 +1001,7 @@
"subtab",
"subtabs",
"subview",
"successfactors",
"superapp",
"superpowered",
"supportal",
Expand Down Expand Up @@ -1102,6 +1120,7 @@
"yalc",
"yourcompany",
"yourname",
"zelt",
"zencdn",
"zipalign",
"zoneinfo",
Expand Down
163 changes: 159 additions & 4 deletions src/CONST/MERGE_HR_PROVIDERS.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// The provider slug keys below are dictated by Merge's API.
/* eslint-disable @typescript-eslint/naming-convention */
Comment thread
jmusial marked this conversation as resolved.
type MergeHRProviderEntry = {
/** Human-readable label used in the UI */
displayName: string;
Expand All @@ -6,19 +8,172 @@ type MergeHRProviderEntry = {
iconUrl: string;
};

// Providers commented out below are supported by Merge but not enabled on our side yet. Uncomment them as they are rolled out.
const MERGE_HR_PROVIDERS = {
workday: {
displayName: 'Workday',
iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/PlatformWorkday.png',
},
// 'adp-decidium': {
// displayName: 'ADP DECIDIUM',
// iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/ADP_Decidium_Square.png',
// },
// 'adp-run': {
// displayName: 'ADP RUN',
// iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/ADP_RUN_Square.png',
// },
// 'adp-workforce-now': {
// displayName: 'ADP Workforce Now',
// iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/ADP_Workforce_Now_Square.png',
// },
bamboohr: {
displayName: 'BambooHR',
iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/BambooHR_Square_Logo.jpg',
},
breathe: {
displayName: 'Breathe',
iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/Breathe_Square_Logo_FY9Zgjm.jpg',
},
// 'cezanne-hr': {
// displayName: 'Cezanne HR',
// iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/Cezanne-square.png',
// },
// darwinbox: {
// displayName: 'Darwinbox',
// iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/Darwinbox-square.png',
// },
dayforce: {
displayName: 'Dayforce',
iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/PlatformDayforce.png',
},
// 'folks-hr': {
// displayName: 'Folks HR',
// iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/PlatformFolks_square.png',
// },
// fourth: {
// displayName: 'Fourth',
// iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/Fourth_square.png',
// },
freshteam: {
displayName: 'Freshteam',
iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/Freshteam_Square.png',
},
// 'generic-sftp': {
// displayName: 'Generic SFTP',
// iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/generic_sftp_square_mJ3x0IU.png',
// },
// 'hailey-hr': {
// displayName: 'Hailey HR',
// iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/PlatformHailey_HR.png',
// },
hibob: {
displayName: 'HiBob',
iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/PlatformHibob.png',
},
'hr-cloud': {
displayName: 'HR Cloud',
iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/HR_Cloud_Square_Logo.jpg',
},
humaans: {
displayName: 'Humaans',
iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/Humaans_Square_Logo.jpg',
},
'insperity-premier': {
displayName: 'Insperity Premier',
iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/Platforminsperity_square.png',
},
intellihr: {
displayName: 'IntelliHR',
iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/IntelliHR_Square_Logo.jpg',
},
// 'iris-cascade': {
// displayName: 'IRIS Cascade',
// iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/IRIS_Cascade-square.png',
// },
jumpcloud: {
displayName: 'JumpCloud',
iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/Jumpcloud_square.png',
},
justworks: {
displayName: 'Justworks',
iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/Justworks_Square_Logo.jpg',
},
kallidus: {
displayName: 'Kallidus',
iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/Kallidus_square.png',
},
keka: {
displayName: 'Keka',
iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/keka_square.png',
},
// kenjo: {
// displayName: 'Kenjo',
// iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/PlatformKenjo_square.png',
// },
lucca: {
displayName: 'Lucca',
iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/Lucca.jpg',
},
namely: {
displayName: 'Namely',
iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/Namely_Square_Logo.jpg',
},
// 'oracle-cloud-human-capital-management-hcm': {
// displayName: 'Oracle Cloud Human Capital Management (HCM)',
// iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/Oracle_square.png',
// },
paychex: {
displayName: 'Paychex',
iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/Paychex_Square_Logo.png',
},
// paycom: {
// displayName: 'Paycom',
// iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/PlatformPaycom.png',
// },
paycor: {
displayName: 'Paycor',
iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/Platformpaycor_square.png',
},
paylocity: {
displayName: 'Paylocity',
iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/Paylocity_Square_Logo_LGm1Fdn.png',
},
peoplehr: {
displayName: 'PeopleHR',
iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/PeopleHR_Access_Square.png',
},
// rippling: {
// displayName: 'Rippling',
// iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/Platformrippling_rR8x3bN.png',
// },
// 'sage-hr': {
// displayName: 'Sage HR',
// iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/Sage_HR_Square_L3bw47M.png',
// },
// 'sap-successfactors': {
// displayName: 'SAP SuccessFactors',
// iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/SuccessFactors_Square_Logo_BcXogF0.jpg',
// },
simployer: {
displayName: 'Simployer',
iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/Simployer_Square.png',
},
'ukg-pro': {
displayName: 'UKG Pro',
iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/UKG_square.png',
},
'ukg-pro-workforce-management': {
displayName: 'UKG Pro Workforce Management',
iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/UKG_square_da9Q05B.png',
},
'ukg-ready': {
displayName: 'UKG Ready',
iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/UKG_square_geaH8qP.png',
},
workday: {
displayName: 'Workday',
iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/PlatformWorkday.png',
},
// zelt: {
// displayName: 'Zelt',
// iconUrl: 'https://merge-api-public.s3.amazonaws.com/media/PlatformZelt.png',
// },
} as const satisfies Record<string, MergeHRProviderEntry>;

type MergeHRProviderSlug = keyof typeof MERGE_HR_PROVIDERS;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,22 @@
import Text from '@components/Text';
import TextInput from '@components/TextInput';
import type {BaseTextInputProps, BaseTextInputRef} from '@components/TextInput/BaseTextInput/types';

import useDebouncedAccessibilityAnnouncement from '@hooks/useDebouncedAccessibilityAnnouncement';
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
import useLocalize from '@hooks/useLocalize';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeStyles from '@hooks/useThemeStyles';

import CONST from '@src/CONST';
import type IconAsset from '@src/types/utils/IconAsset';

import type {StyleProp, ViewStyle} from 'react-native';

import React from 'react';
import {View} from 'react-native';

import type {BaseTextInputRef} from './TextInput/BaseTextInput/types';

import Text from './Text';
import TextInput from './TextInput';

type SearchBarProps = {
type SharedSearchBarProps = {
/** Label describing the search input. Also used as the accessibility label. */
label: string;
icon?: IconAsset;
inputValue: string;
onChangeText?: (text: string) => void;
onSubmitEditing?: (text: string) => void;
Expand All @@ -29,11 +26,15 @@ type SearchBarProps = {
ref?: React.Ref<BaseTextInputRef>;
};

function SearchBar({ref, label, style, icon, inputValue, onChangeText, onSubmitEditing, shouldShowEmptyState, emptyStateContainerStyle}: SearchBarProps) {
type BaseSearchBarProps = SharedSearchBarProps & {
/** Variant-specific TextInput props (floating label vs placeholder, icon, size styles). */
textInputProps?: BaseTextInputProps;
};

function BaseSearchBar({ref, label, style, inputValue, onChangeText, onSubmitEditing, shouldShowEmptyState, emptyStateContainerStyle, textInputProps}: BaseSearchBarProps) {
const styles = useThemeStyles();
const {shouldUseNarrowLayout, isInLandscapeMode} = useResponsiveLayout();
const {translate} = useLocalize();
const expensifyIcons = useMemoizedLazyExpensifyIcons(['MagnifyingGlass']);
const noResultsMessage = translate('common.noResultsFoundMatching', inputValue);
const shouldAnnounceNoResults = !!shouldShowEmptyState && inputValue.length !== 0;

Expand All @@ -44,19 +45,17 @@ function SearchBar({ref, label, style, icon, inputValue, onChangeText, onSubmitE
<View style={[styles.searchBarMargin, styles.searchBarWidth(shouldUseNarrowLayout && !isInLandscapeMode), style]}>
<TextInput
ref={ref}
label={label}
accessibilityLabel={label}
role={CONST.ROLE.PRESENTATION}
value={inputValue}
onChangeText={onChangeText}
inputMode={CONST.INPUT_MODE.TEXT}
selectTextOnFocus
spellCheck={false}
icon={inputValue?.length ? undefined : (icon ?? expensifyIcons.MagnifyingGlass)}
iconContainerStyle={styles.p0}
onSubmitEditing={() => onSubmitEditing?.(inputValue)}
shouldShowClearButton
shouldHideClearButton={!inputValue?.length}
{...textInputProps}
/>
</View>
{shouldAnnounceNoResults && (
Expand All @@ -73,4 +72,5 @@ function SearchBar({ref, label, style, icon, inputValue, onChangeText, onSubmitE
);
}

export default SearchBar;
export default BaseSearchBar;
export type {SharedSearchBarProps};
Loading
Loading