@ -1,9 +1,10 @@
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
|
||||
import { useFavorites } from '@/favorites/hooks/useFavorites';
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { formatFieldMetadataItemAsColumnDefinition } from '@/object-metadata/utils/formatFieldMetadataItemAsColumnDefinition';
|
||||
import { isObjectMetadataAvailableForRelation } from '@/object-metadata/utils/isObjectMetadataAvailableForRelation';
|
||||
import { parseFieldRelationType } from '@/object-metadata/utils/parseFieldRelationType';
|
||||
import { parseFieldType } from '@/object-metadata/utils/parseFieldType';
|
||||
import {
|
||||
@ -62,7 +63,7 @@ export const RecordShowPage = () => {
|
||||
|
||||
const { favorites, createFavorite, deleteFavorite } = useFavorites();
|
||||
|
||||
const [, setEntityFields] = useRecoilState(
|
||||
const setEntityFields = useSetRecoilState(
|
||||
entityFieldsFamilyState(objectRecordId ?? ''),
|
||||
);
|
||||
|
||||
@ -274,8 +275,21 @@ export const RecordShowPage = () => {
|
||||
)}
|
||||
</PropertyBox>
|
||||
{isRelationFieldCardEnabled &&
|
||||
relationFieldMetadataItems.map(
|
||||
(fieldMetadataItem, index) => (
|
||||
relationFieldMetadataItems
|
||||
.filter((item) => {
|
||||
const relationObjectMetadataItem =
|
||||
item.toRelationMetadata
|
||||
? item.toRelationMetadata.fromObjectMetadata
|
||||
: item.fromRelationMetadata?.toObjectMetadata;
|
||||
|
||||
if (!relationObjectMetadataItem) {
|
||||
return false;
|
||||
}
|
||||
return isObjectMetadataAvailableForRelation(
|
||||
relationObjectMetadataItem,
|
||||
);
|
||||
})
|
||||
.map((fieldMetadataItem, index) => (
|
||||
<FieldContext.Provider
|
||||
key={record.id + fieldMetadataItem.id}
|
||||
value={{
|
||||
@ -294,8 +308,7 @@ export const RecordShowPage = () => {
|
||||
>
|
||||
<RecordRelationFieldCardSection />
|
||||
</FieldContext.Provider>
|
||||
),
|
||||
)}
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</ShowPageLeftContainer>
|
||||
|
||||
@ -6,7 +6,9 @@ import { useRelationField } from '../../hooks/useRelationField';
|
||||
export const RelationFieldDisplay = () => {
|
||||
const { fieldValue, fieldDefinition } = useRelationField();
|
||||
|
||||
const { identifiersMapper } = useRelationPicker();
|
||||
const { identifiersMapper } = useRelationPicker({
|
||||
relationPickerScopeId: 'relation-picker',
|
||||
});
|
||||
|
||||
if (!fieldValue || !fieldDefinition || !identifiersMapper) {
|
||||
return <></>;
|
||||
|
||||
@ -19,7 +19,9 @@ export const useChipField = () => {
|
||||
|
||||
const record = useRecoilValue<any | null>(entityFieldsFamilyState(entityId));
|
||||
|
||||
const { identifiersMapper } = useRelationPicker();
|
||||
const { identifiersMapper } = useRelationPicker({
|
||||
relationPickerScopeId: 'relation-picker',
|
||||
});
|
||||
|
||||
return {
|
||||
basePathToShowPage,
|
||||
|
||||
@ -19,6 +19,7 @@ import { useUpsertRecordFromState } from '@/object-record/hooks/useUpsertRecordF
|
||||
import { RecordRelationFieldCardContent } from '@/object-record/record-relation-card/components/RecordRelationFieldCardContent';
|
||||
import { SingleEntitySelectMenuItemsWithSearch } from '@/object-record/relation-picker/components/SingleEntitySelectMenuItemsWithSearch';
|
||||
import { useRelationPicker } from '@/object-record/relation-picker/hooks/useRelationPicker';
|
||||
import { RelationPickerScope } from '@/object-record/relation-picker/scopes/RelationPickerScope';
|
||||
import { EntityForSelect } from '@/object-record/relation-picker/types/EntityForSelect';
|
||||
import { useFilteredSearchEntityQuery } from '@/search/hooks/useFilteredSearchEntityQuery';
|
||||
import { IconForbid, IconPlus } from '@/ui/display/icon';
|
||||
@ -153,12 +154,10 @@ export const RecordRelationFieldCardSection = () => {
|
||||
|
||||
const { closeDropdown, isDropdownOpen } = useDropdown(dropdownId);
|
||||
|
||||
const {
|
||||
identifiersMapper,
|
||||
relationPickerSearchFilter,
|
||||
searchQuery,
|
||||
setRelationPickerSearchFilter,
|
||||
} = useRelationPicker();
|
||||
const { relationPickerSearchFilter, setRelationPickerSearchFilter } =
|
||||
useRelationPicker({ relationPickerScopeId: dropdownId });
|
||||
|
||||
const { identifiersMapper, searchQuery } = useRelationPicker();
|
||||
|
||||
const entities = useFilteredSearchEntityQuery({
|
||||
filters: [
|
||||
@ -225,53 +224,55 @@ export const RecordRelationFieldCardSection = () => {
|
||||
|
||||
return (
|
||||
<Section>
|
||||
<StyledHeader isDropdownOpen={isDropdownOpen}>
|
||||
<StyledTitle>
|
||||
<StyledTitleLabel>{fieldDefinition.label}</StyledTitleLabel>
|
||||
{parseFieldRelationType(relationFieldMetadataItem) ===
|
||||
'TO_ONE_OBJECT' && (
|
||||
<StyledLink to={filterLinkHref}>
|
||||
All ({relationRecords.length})
|
||||
</StyledLink>
|
||||
)}
|
||||
</StyledTitle>
|
||||
<DropdownScope dropdownScopeId={dropdownId}>
|
||||
<StyledAddDropdown
|
||||
dropdownId={dropdownId}
|
||||
dropdownPlacement="right-start"
|
||||
onClose={handleCloseRelationPickerDropdown}
|
||||
clickableComponent={
|
||||
<LightIconButton
|
||||
className="displayOnHover"
|
||||
Icon={IconPlus}
|
||||
accent="tertiary"
|
||||
/>
|
||||
}
|
||||
dropdownComponents={
|
||||
<SingleEntitySelectMenuItemsWithSearch
|
||||
EmptyIcon={IconForbid}
|
||||
entitiesToSelect={entities.entitiesToSelect}
|
||||
loading={entities.loading}
|
||||
onEntitySelected={handleRelationPickerEntitySelected}
|
||||
/>
|
||||
}
|
||||
dropdownHotkeyScope={{
|
||||
scope: dropdownId,
|
||||
}}
|
||||
/>
|
||||
</DropdownScope>
|
||||
</StyledHeader>
|
||||
{!!relationRecords.length && (
|
||||
<Card>
|
||||
{relationRecords.slice(0, 5).map((relationRecord, index) => (
|
||||
<RecordRelationFieldCardContent
|
||||
key={`${relationRecord.id}${relationLabelIdentifierFieldMetadata?.id}`}
|
||||
divider={index < relationRecords.length - 1}
|
||||
relationRecord={relationRecord}
|
||||
<RelationPickerScope relationPickerScopeId={dropdownId}>
|
||||
<StyledHeader isDropdownOpen={isDropdownOpen}>
|
||||
<StyledTitle>
|
||||
<StyledTitleLabel>{fieldDefinition.label}</StyledTitleLabel>
|
||||
{parseFieldRelationType(relationFieldMetadataItem) ===
|
||||
'TO_ONE_OBJECT' && (
|
||||
<StyledLink to={filterLinkHref}>
|
||||
All ({relationRecords.length})
|
||||
</StyledLink>
|
||||
)}
|
||||
</StyledTitle>
|
||||
<DropdownScope dropdownScopeId={dropdownId}>
|
||||
<StyledAddDropdown
|
||||
dropdownId={dropdownId}
|
||||
dropdownPlacement="right-start"
|
||||
onClose={handleCloseRelationPickerDropdown}
|
||||
clickableComponent={
|
||||
<LightIconButton
|
||||
className="displayOnHover"
|
||||
Icon={IconPlus}
|
||||
accent="tertiary"
|
||||
/>
|
||||
}
|
||||
dropdownComponents={
|
||||
<SingleEntitySelectMenuItemsWithSearch
|
||||
EmptyIcon={IconForbid}
|
||||
entitiesToSelect={entities.entitiesToSelect}
|
||||
loading={entities.loading}
|
||||
onEntitySelected={handleRelationPickerEntitySelected}
|
||||
/>
|
||||
}
|
||||
dropdownHotkeyScope={{
|
||||
scope: dropdownId,
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</Card>
|
||||
)}
|
||||
</DropdownScope>
|
||||
</StyledHeader>
|
||||
{!!relationRecords.length && (
|
||||
<Card>
|
||||
{relationRecords.slice(0, 5).map((relationRecord, index) => (
|
||||
<RecordRelationFieldCardContent
|
||||
key={`${relationRecord.id}${relationLabelIdentifierFieldMetadata?.id}`}
|
||||
divider={index < relationRecords.length - 1}
|
||||
relationRecord={relationRecord}
|
||||
/>
|
||||
))}
|
||||
</Card>
|
||||
)}
|
||||
</RelationPickerScope>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
|
||||
@ -4,6 +4,7 @@ import { expect, userEvent, within } from '@storybook/test';
|
||||
import { IconUserCircle } from '@/ui/display/icon';
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
import { ComponentWithRecoilScopeDecorator } from '~/testing/decorators/ComponentWithRecoilScopeDecorator';
|
||||
import { RelationPickerDecorator } from '~/testing/decorators/RelationPickerDecorator';
|
||||
import { mockedPeopleData } from '~/testing/mock-data/people';
|
||||
import { sleep } from '~/testing/sleep';
|
||||
|
||||
@ -19,7 +20,11 @@ const entities = mockedPeopleData.map<EntityForSelect>((person) => ({
|
||||
const meta: Meta<typeof SingleEntitySelect> = {
|
||||
title: 'UI/Input/RelationPicker/SingleEntitySelect',
|
||||
component: SingleEntitySelect,
|
||||
decorators: [ComponentDecorator, ComponentWithRecoilScopeDecorator],
|
||||
decorators: [
|
||||
ComponentDecorator,
|
||||
ComponentWithRecoilScopeDecorator,
|
||||
RelationPickerDecorator,
|
||||
],
|
||||
argTypes: {
|
||||
selectedEntity: {
|
||||
options: entities.map(({ name }) => name),
|
||||
|
||||
@ -7,9 +7,7 @@ export const useEntitySelectSearch = () => {
|
||||
setRelationPickerPreselectedId,
|
||||
relationPickerSearchFilter,
|
||||
setRelationPickerSearchFilter,
|
||||
} = useRelationPicker({
|
||||
relationPickerScopeId: 'relation-picker',
|
||||
});
|
||||
} = useRelationPicker();
|
||||
|
||||
const debouncedSetSearchFilter = debounce(
|
||||
setRelationPickerSearchFilter,
|
||||
|
||||
Reference in New Issue
Block a user