Skip to content

Commit

Permalink
update survey form tooltips
Browse files Browse the repository at this point in the history
  • Loading branch information
mauberti-bc committed Dec 6, 2024
1 parent 211d9c1 commit 3325cbe
Show file tree
Hide file tree
Showing 12 changed files with 44 additions and 143 deletions.
12 changes: 6 additions & 6 deletions app/src/components/buttons/HelpButtonTooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const HelpButtonTooltip = ({ content, iconSx }: HelpButtonTooltipProps) => {
position: 'relative',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
justifyContent: 'center'
}}>
{/* Tooltip should always be there, but only show when hovering */}
<Tooltip
Expand All @@ -42,20 +42,20 @@ const HelpButtonTooltip = ({ content, iconSx }: HelpButtonTooltipProps) => {
py: 1.5,
px: 2,
fontSize: '0.875rem',
background: '#38598A',
background: '#38598A'
},
'& .MuiTooltip-arrow::before': {
background: '#38598A',
},
},
background: '#38598A'
}
}
}}>
{/* IconButton is always displayed */}
<IconButton
onMouseEnter={() => setRenderTooltip(true)}
onMouseLeave={() => setRenderTooltip(false)}
sx={{
color: '#38598A',
...iconSx,
...iconSx
}}>
<Icon path={mdiHelpCircleOutline} size={1} />
</IconButton>
Expand Down
17 changes: 7 additions & 10 deletions app/src/components/fields/SystemUserAutocompleteField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,20 +141,18 @@ export const SystemUserAutocompleteField = (props: ISystemUserAutocompleteFieldP
disabled={disabled}
data-testid={formikFieldName}
filterSelectedOptions
noOptionsText={inputValue.length > 2 ? 'No matching options' : 'Enter at least 3 letters'}
noOptionsText={inputValue && inputValue.length > 2 ? 'No matching options' : 'Enter at least 3 letters'}
options={options}
getOptionLabel={(option) => option.display_name}
isOptionEqualToValue={(option, value) => {
return option.system_user_id === value.system_user_id;
}}
getOptionLabel={(option) => option.display_name || ''}
value={null} // Always set value to null to prevent a selected value from showing
isOptionEqualToValue={(option, value) => option.system_user_id === value.system_user_id}
filterOptions={(options) => {
if (selectedUsers) {
return options.filter((item) => selectedUsers && !selectedUsers.includes(item.system_user_id));
return options.filter((item) => !selectedUsers.includes(item.system_user_id));
}
return options;
}}
inputValue={inputValue}
// Text field value changed
inputValue={inputValue || ''} // Control the text field value separately
onInputChange={(_, value, reason) => {
if (clearOnSelect && reason === 'reset') {
setInputValue('');
Expand Down Expand Up @@ -185,11 +183,10 @@ export const SystemUserAutocompleteField = (props: ISystemUserAutocompleteFieldP
if (!isMounted()) {
return;
}
setOptions(() => newOptions);
setOptions(newOptions);
setIsLoading(false);
});
}}
// Option selected from dropdown
onChange={(_, option) => {
if (!option) {
onClear?.();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const ProjectDetailsForm = () => {
<CustomTextField
name="project.project_name"
label="Project Name"
helpText='Use descriptive names mentioning a species or region to help organize your Projects'
helpText="Use descriptive names mentioning a species or region to help organize your Projects"
other={{
required: true
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import ProjectObjectivesForm, {

describe('ProjectObjectivesForm', () => {
it('renders correctly with default empty values', () => {
const { getByLabelText } = render(
const { getAllByLabelText } = render(
<Formik
initialValues={ProjectObjectivesFormInitialValues}
validationSchema={ProjectObjectivesFormYupSchema}
Expand All @@ -19,7 +19,7 @@ describe('ProjectObjectivesForm', () => {
</Formik>
);

expect(getByLabelText('Objectives', { exact: false })).toBeVisible();
expect(getAllByLabelText('Objectives', { exact: false })).toBeVisible();
});

it('renders correctly with existing objective/caveat values', () => {
Expand All @@ -29,7 +29,7 @@ describe('ProjectObjectivesForm', () => {
}
};

const { getByLabelText, getByText } = render(
const { getAllByLabelText, getByText } = render(
<Formik
initialValues={existingFormValues}
validationSchema={ProjectObjectivesFormYupSchema}
Expand All @@ -40,7 +40,7 @@ describe('ProjectObjectivesForm', () => {
</Formik>
);

expect(getByLabelText('Objectives', { exact: false })).toBeVisible();
expect(getAllByLabelText('Objectives', { exact: false })).toBeVisible();
expect(getByText('a project objective')).toBeVisible();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const ProjectObjectivesForm = () => {
<CustomTextField
name="objectives.objectives"
label="Objectives"
helpText='Objectives help give context to the information in this Project'
helpText="Objectives help give context to the information in this Project"
other={{ multiline: true, required: true, rows: 4 }}
/>
</Grid>
Expand Down
4 changes: 3 additions & 1 deletion app/src/features/projects/components/ProjectUserForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,12 @@ const ProjectUserForm = (props: IProjectUserFormProps) => {
<Box mt={3}>
<SystemUserAutocompleteField
formikFieldName="system_user_id"
data-testid="autocomplete-user-role-search"
label="Team Member"
placeholder="Search by user"
helpText={`People must request access before you can invite them. A member's role determines their permissions in the Project.`}
helpText={`Only active users who have requested access to the Species Inventory Management System before can be invited`}
selectedUsers={values.participants.map((participant) => participant.system_user_id)}
clearOnSelect
onSelect={(value) => {
if (value) {
handleAddUser(value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export const AnimalFormContainer = (props: IAnimalFormProps) => {
summary="Enter information to identify the animal"
component={<AnimalGeneralInformationForm isEdit={isEdit} />}
/>
<Divider/>
<Divider />
<HorizontalSplitFormComponent
title="Ecological Units"
summary="Select populations, subpopulations, or other ecological units that the animal belongs to."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import Toolbar from '@mui/material/Toolbar';
import Typography from '@mui/material/Typography';
import HelpButtonStack from 'components/buttons/HelpButtonStack';
import BaseLayerControls from 'components/map/components/BaseLayerControls';
import { SetMapBounds } from 'components/map/components/Bounds';
import DrawControls, { IDrawControlsRef } from 'components/map/components/DrawControls';
Expand Down Expand Up @@ -73,19 +72,15 @@ export const SurveyAreaMapControl = (props: ISurveyAreMapControlProps) => {
<Toolbar
disableGutters
sx={{
px: 2
px: 2,
justifyContent: 'space-between'
}}>
<HelpButtonStack helpText="Study areas are general areas of interest where you went or are extrapolating findings to.">
<Typography
data-testid="map-control-title"
component="div"
fontWeight="700">
Study Areas
<Typography component="span" color="textSecondary" sx={{ ml: 0.5, flex: '1 1 auto' }}>
({values.locations.length})
</Typography>
<Typography data-testid="map-control-title" component="div" fontWeight="700">
Study Areas
<Typography component="span" color="textSecondary" sx={{ ml: 0.5, flex: '1 1 auto' }}>
({values.locations.length})
</Typography>
</HelpButtonStack>
</Typography>
<Box display="flex">
<Button
color="primary"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ const PurposeAndMethodologyForm: React.FC<IPurposeAndMethodologyFormProps> = (pr
<MultiAutocompleteFieldVariableSize
id={'survey_details.survey_types'}
label={'Collected data'}
helpText="Data"
options={props.type}
required={true}
/>
Expand All @@ -60,7 +59,6 @@ const PurposeAndMethodologyForm: React.FC<IPurposeAndMethodologyFormProps> = (pr
<MultiAutocompleteField
id="purpose_and_methodology.intended_outcome_ids"
label="Ecological concepts of interest"
helpText="Data"
options={props.intended_outcomes}
required={true}
/>
Expand All @@ -69,7 +67,6 @@ const PurposeAndMethodologyForm: React.FC<IPurposeAndMethodologyFormProps> = (pr
<CustomTextField
name="purpose_and_methodology.additional_details"
label="Objectives"
helpText="Objectives help give context to the data in this Survey"
other={{ multiline: true, rows: 5, required: true }}
/>
</Grid>
Expand Down
112 changes: 12 additions & 100 deletions app/src/features/surveys/components/participants/SurveyUserForm.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,14 @@
import { mdiMagnify } from '@mdi/js';
import Icon from '@mdi/react';
import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete';
import Box from '@mui/material/Box';
import Collapse from '@mui/material/Collapse';
import grey from '@mui/material/colors/grey';
import InputAdornment from '@mui/material/InputAdornment';
import TextField from '@mui/material/TextField';
import Typography from '@mui/material/Typography';
import AlertBar from 'components/alert/AlertBar';
import HelpButtonTooltip from 'components/buttons/HelpButtonTooltip';
import UserCard from 'components/user/UserCard';
import { SystemUserAutocompleteField } from 'components/fields/SystemUserAutocompleteField';
import UserRoleSelector from 'components/user/UserRoleSelector';
import { useFormikContext } from 'formik';
import { useBiohubApi } from 'hooks/useBioHubApi';
import useDataLoader from 'hooks/useDataLoader';
import { ICode } from 'interfaces/useCodesApi.interface';
import { ICreateSurveyRequest, IGetSurveyParticipant } from 'interfaces/useSurveyApi.interface';
import { ISystemUser } from 'interfaces/useUserApi.interface';
import { useEffect, useState } from 'react';
import { TransitionGroup } from 'react-transition-group';
import { alphabetizeObjects } from 'utils/Utils';
import yup from 'utils/YupSchema';

export const SurveyUserJobYupSchema = yup.object().shape({
Expand All @@ -41,19 +30,6 @@ export const SurveyUserJobFormInitialValues = {

const SurveyUserForm = (props: ISurveyUserFormProps) => {
const { handleSubmit, values, setFieldValue, errors, setErrors } = useFormikContext<ICreateSurveyRequest>();
const biohubApi = useBiohubApi();

const searchUserDataLoader = useDataLoader((keyword: string) => biohubApi.user.searchSystemUser(keyword));

const [searchText, setSearchText] = useState('');

const [sortedUsers, setSortedUsers] = useState<ISystemUser[]>([]);

useEffect(() => {
if (searchUserDataLoader.data) {
setSortedUsers(alphabetizeObjects(searchUserDataLoader.data, 'display_name'));
}
}, [searchUserDataLoader.data]);

const handleAddUser = (user: ISystemUser | IGetSurveyParticipant) => {
setFieldValue(`participants[${values.participants.length}]`, {
Expand Down Expand Up @@ -121,81 +97,18 @@ const SurveyUserForm = (props: ISurveyUserFormProps) => {
<AlertBar severity="error" variant="outlined" title={alertBarText().title} text={alertBarText().text} />
</Box>
)}
<Autocomplete
id={'autocomplete-user-role-search'}
data-testid={'autocomplete-user-role-search'}
filterSelectedOptions
noOptionsText="No records found"
options={sortedUsers}
filterOptions={(options, state) => {
const searchFilter = createFilterOptions<ISystemUser>({ ignoreCase: true });
const unselectedOptions = options.filter(
(item) => !values.participants.some((existing) => existing.system_user_id === item.system_user_id)
);
return searchFilter(unselectedOptions, state);
}}
getOptionLabel={(option) => option.display_name}
inputValue={searchText}
onInputChange={(_, value, reason) => {
if (reason === 'reset') {
setSearchText('');
} else {
setSearchText(value);

if (value.length >= 3) {
// Only search if the search text is at least 3 characters long
searchUserDataLoader.refresh(value);
}
<SystemUserAutocompleteField
formikFieldName="participants"
label="Participants"
data-testid="autocomplete-user-role-search"
helpText="Only active users who have requested access to the Species Inventory Management System before can be invited"
selectedUsers={values.participants.map((participant) => participant.system_user_id)}
clearOnSelect
onSelect={(value) => {
if (value) {
handleAddUser(value);
}
}}
onChange={(_, option) => {
if (option) {
handleAddUser(option);
}
}}
renderInput={(params) => (
<TextField
{...params}
variant="outlined"
placeholder={'Find people'}
fullWidth
InputProps={{
...params.InputProps,
startAdornment: (
<Box mx={1} mt="6px">
<Icon path={mdiMagnify} size={1}></Icon>
</Box>
),
endAdornment: (
<InputAdornment position="end">
<HelpButtonTooltip content="Only active users who have gained access can be selected." />
</InputAdornment>
)
}}
/>
)}
renderOption={(renderProps, renderOption) => {
return (
<Box
component="li"
sx={{
'& + li': {
borderTop: '1px solid' + grey[300]
}
}}
{...renderProps}
key={renderOption.system_user_id}>
<Box py={0.5} width="100%">
<UserCard
name={renderOption.display_name}
email={renderOption.email}
agency={renderOption.agency}
type={renderOption.identity_source}
/>
</Box>
</Box>
);
}}
/>
<Box>
<Box
Expand All @@ -217,8 +130,7 @@ const SurveyUserForm = (props: ISurveyUserFormProps) => {
selectedRole={getSelectedRole(index)}
handleAdd={handleAddUserRole}
handleRemove={handleRemoveUser}
key={user.system_user_id}
label={'Select a Job'}
label="Select a Job"
/>
</Collapse>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@ const SamplingStrategyForm = () => {
</Box>
</Collapse>
<Box component="fieldset" mt={5}>
<HelpButtonStack helpText="Blocks are defined areas within your study area that enhance structured sampling and reduce variability. As a higher-level organizational unit, blocks contain sampling sites and help distribute sampling effort systematically across a large area, supporting randomization and reducing potential bias.">
<Typography fontWeight={700}>Add Blocks (optional)</Typography>
</HelpButtonStack>
<Typography fontWeight={700}>Add Blocks (optional)</Typography>
<Typography
sx={{
mb: 2
Expand Down
2 changes: 1 addition & 1 deletion app/src/features/surveys/edit/EditSurveyForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ const EditSurveyForm = <

<HorizontalSplitFormComponent
title="Study Area"
summary="Import, draw or select a feature from an existing layer to define the study areas for this survey"
summary="Import, draw or select a feature from an existing layer to define general areas of interest where survey findings apply."
component={<StudyAreaForm />}
/>

Expand Down

0 comments on commit 3325cbe

Please sign in to comment.