Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 120x 120x 120x 120x 120x 120x 120x 120x 120x 120x 120x 120x 120x 120x 120x 120x 120x 120x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 1x 1x | import { uniqBy } from 'lodash-es';
import { memo, useMemo } from 'react';
import { useIntl } from 'react-intl';
import { Select } from '@allshares/studio-design-system';
import { type KeysOfUserWithStringValues, type UserComputed } from '@amalia/tenants/users/types';
import { LabelVariant } from '../../types';
import { UserPrettyFormat } from '../pretty-format/UserPrettyFormat';
import { type UserOption, type UserSelectOption } from './types';
import { UserSelectorSingleValueLabel } from './UserSelectorSingleValueLabel';
export type UserSelectorProps<TProperty extends keyof UserComputed> = {
/** Users to display in the selector. */
readonly users: UserOption<TProperty>[];
/**
* Selected user's "property" value.
* For example, the selected user's `"externalId"`.
*/
readonly value: UserOption<TProperty>[TProperty] | null;
/** Callback when a user option is selected. */
readonly onChange: (value: UserOption<TProperty>[TProperty] | null) => void;
/**
* Property to use as the value.
* For example, `"externalId"`
*/
readonly property: TProperty;
/** Label to display when no user is selected. */
readonly emptyLabel?: string;
};
const UserSelectorBase = function UserSelector<TProperty extends KeysOfUserWithStringValues>({
users,
value,
onChange,
property,
emptyLabel,
}: UserSelectorProps<TProperty>) {
const { formatMessage } = useIntl();
const options = useMemo(
(): UserSelectOption<TProperty>[] =>
uniqBy(users, property)
.map((user) => {
const optionValue = user[property];
return !!optionValue && !!user.firstName && !!user.lastName
? {
user,
label: (
<UserPrettyFormat
firstName={user.firstName}
lastName={user.lastName}
pictureURL={user.pictureURL}
subLabel={optionValue}
variant={optionValue === value ? LabelVariant.ACCENTUATED : LabelVariant.DEFAULT}
/>
),
value: optionValue,
filterLabel: [user.firstName, user.lastName, user[property]].join(' '),
}
: null;
})
.filter(Boolean),
[value, users, property],
);
return (
<Select<UserSelectOption<TProperty>>
isClearable
options={options}
placeholder={emptyLabel ?? formatMessage({ defaultMessage: 'No user selected' })}
SingleValueLabelComponent={UserSelectorSingleValueLabel}
value={value}
onChange={onChange}
/>
);
};
export const UserSelector = memo(UserSelectorBase) as typeof UserSelectorBase;
|