Kanban card creation followup (#7285)

@Bonapara #7002
@FelixMalfait  #6316 
;)

Naming could be improved, do let me know!


https://github.com/user-attachments/assets/b10c9120-644d-4943-bc65-ec0d62f9986f
This commit is contained in:
nitin 2024-10-03 21:20:54 +05:30 committed by GitHub
parent 5f9435c718
commit 04579144ca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 199 additions and 282 deletions

View File

@ -141,10 +141,6 @@ const StyledRecordInlineCellPlaceholder = styled.div`
height: 24px;
`;
const StyledRecordInlineCell = styled(RecordInlineCell)`
height: 24px;
`;
export const RecordBoardCard = ({
isCreating = false,
onCreateSuccess,
@ -348,7 +344,7 @@ export const RecordBoardCard = ({
}}
>
{inView ? (
<StyledRecordInlineCell />
<RecordInlineCell />
) : (
<StyledRecordInlineCellPlaceholder />
)}

View File

@ -12,6 +12,7 @@ import { RecordBoardColumnFetchMoreLoader } from '@/object-record/record-board/r
import { RecordBoardColumnNewButton } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnNewButton';
import { RecordBoardColumnNewOpportunityButton } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnNewOpportunityButton';
import { RecordBoardColumnContext } from '@/object-record/record-board/record-board-column/contexts/RecordBoardColumnContext';
import { useIsOpportunitiesCompanyFieldDisabled } from '@/object-record/record-board/record-board-column/hooks/useIsOpportunitiesCompanyFieldDisabled';
import { getNumberOfCardsPerColumnForSkeletonLoading } from '@/object-record/record-board/record-board-column/utils/getNumberOfCardsPerColumnForSkeletonLoading';
import { isRecordIndexBoardColumnLoadingFamilyState } from '@/object-record/states/isRecordBoardColumnLoadingFamilyState';
@ -64,6 +65,8 @@ export const RecordBoardColumnCardsContainer = ({
const numberOfFields = visibleFieldDefinitions.length;
const isCompactModeActive = useRecoilValue(isCompactModeActiveState);
const { isOpportunitiesCompanyFieldDisabled } =
useIsOpportunitiesCompanyFieldDisabled();
return (
<StyledColumnCardsContainer
@ -107,8 +110,11 @@ export const RecordBoardColumnCardsContainer = ({
>
<StyledNewButtonContainer>
{objectMetadataItem.nameSingular ===
CoreObjectNameSingular.Opportunity ? (
<RecordBoardColumnNewOpportunityButton />
CoreObjectNameSingular.Opportunity &&
!isOpportunitiesCompanyFieldDisabled ? (
<RecordBoardColumnNewOpportunityButton
columnId={columnDefinition.id}
/>
) : (
<RecordBoardColumnNewButton columnId={columnDefinition.id} />
)}

View File

@ -7,8 +7,8 @@ import { RecordBoardContext } from '@/object-record/record-board/contexts/Record
import { RecordBoardCard } from '@/object-record/record-board/record-board-card/components/RecordBoardCard';
import { RecordBoardColumnDropdownMenu } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnDropdownMenu';
import { RecordBoardColumnContext } from '@/object-record/record-board/record-board-column/contexts/RecordBoardColumnContext';
import { useAddNewOpportunity } from '@/object-record/record-board/record-board-column/hooks/useAddNewOpportunity';
import { useColumnNewCardActions } from '@/object-record/record-board/record-board-column/hooks/useColumnNewCardActions';
import { useIsOpportunitiesCompanyFieldDisabled } from '@/object-record/record-board/record-board-column/hooks/useIsOpportunitiesCompanyFieldDisabled';
import { RecordBoardColumnHotkeyScope } from '@/object-record/record-board/types/BoardColumnHotkeyScope';
import { RecordBoardColumnDefinitionType } from '@/object-record/record-board/types/RecordBoardColumnDefinition';
import { SingleEntitySelect } from '@/object-record/relation-picker/components/SingleEntitySelect';
@ -90,21 +90,18 @@ export const RecordBoardColumnHeader = () => {
const boardColumnTotal = 0;
const {
isCreatingCard,
handleAddNewOpportunityClick,
handleCancel,
handleEntitySelect,
} = useAddNewOpportunity('first');
newRecord,
handleNewButtonClick,
handleCreateSuccess,
const { newRecord, handleNewButtonClick, handleCreateSuccess } =
useColumnNewCardActions(columnDefinition.id);
handleEntitySelect,
} = useColumnNewCardActions(columnDefinition.id);
const { isOpportunitiesCompanyFieldDisabled } =
useIsOpportunitiesCompanyFieldDisabled();
const isOpportunity =
objectMetadataItem.nameSingular === CoreObjectNameSingular.Opportunity;
const handleClick = isOpportunity
? handleAddNewOpportunityClick
: () => handleNewButtonClick('first');
objectMetadataItem.nameSingular === CoreObjectNameSingular.Opportunity &&
!isOpportunitiesCompanyFieldDisabled;
return (
<>
@ -152,7 +149,7 @@ export const RecordBoardColumnHeader = () => {
<LightIconButton
accent="tertiary"
Icon={IconPlus}
onClick={handleClick}
onClick={() => handleNewButtonClick('first', isOpportunity)}
/>
</StyledHeaderActions>
)}
@ -165,23 +162,26 @@ export const RecordBoardColumnHeader = () => {
stageId={columnDefinition.id}
/>
)}
{newRecord?.isCreating && newRecord.position === 'first' && (
<RecordBoardCard
isCreating={true}
onCreateSuccess={() => handleCreateSuccess('first')}
position="first"
/>
)}
{isCreatingCard && (
<SingleEntitySelect
disableBackgroundBlur
onCancel={handleCancel}
onEntitySelected={handleEntitySelect}
relationObjectNameSingular={CoreObjectNameSingular.Company}
relationPickerScopeId="relation-picker"
selectedRelationRecordIds={[]}
/>
)}
{newRecord?.isCreating &&
newRecord.position === 'first' &&
(newRecord.isOpportunity ? (
<SingleEntitySelect
disableBackgroundBlur
onCancel={() => handleCreateSuccess('first', columnDefinition.id)}
onEntitySelected={(company) =>
company && handleEntitySelect('first', company)
}
relationObjectNameSingular={CoreObjectNameSingular.Company}
relationPickerScopeId="relation-picker"
selectedRelationRecordIds={[]}
/>
) : (
<RecordBoardCard
isCreating={true}
onCreateSuccess={() => handleCreateSuccess('first')}
position="first"
/>
))}
</>
);
};

View File

@ -30,7 +30,11 @@ export const RecordBoardColumnNewButton = ({
const { newRecord, handleNewButtonClick, handleCreateSuccess } =
useColumnNewCardActions(columnId);
if (newRecord.isCreating && newRecord.position === 'last') {
if (
newRecord.isCreating &&
newRecord.position === 'last' &&
!newRecord.isOpportunity
) {
return (
<RecordBoardCard
isCreating={true}
@ -41,7 +45,7 @@ export const RecordBoardColumnNewButton = ({
}
return (
<StyledNewButton onClick={() => handleNewButtonClick('last')}>
<StyledNewButton onClick={() => handleNewButtonClick('last', false)}>
<IconPlus size={theme.icon.size.md} />
New
</StyledNewButton>

View File

@ -3,7 +3,7 @@ import styled from '@emotion/styled';
import { IconPlus } from 'twenty-ui';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useAddNewOpportunity } from '@/object-record/record-board/record-board-column/hooks/useAddNewOpportunity';
import { useColumnNewCardActions } from '@/object-record/record-board/record-board-column/hooks/useColumnNewCardActions';
import { SingleEntitySelect } from '@/object-record/relation-picker/components/SingleEntitySelect';
const StyledButton = styled.button`
@ -23,27 +23,36 @@ const StyledButton = styled.button`
}
`;
export const RecordBoardColumnNewOpportunityButton = () => {
export const RecordBoardColumnNewOpportunityButton = ({
columnId,
}: {
columnId: string;
}) => {
const theme = useTheme();
const {
isCreatingCard,
handleAddNewOpportunityClick,
handleCancel,
newRecord,
handleNewButtonClick,
handleEntitySelect,
} = useAddNewOpportunity('last');
handleCreateSuccess,
} = useColumnNewCardActions(columnId);
return (
<>
{isCreatingCard ? (
{newRecord.isCreating &&
newRecord.position === 'last' &&
newRecord.isOpportunity ? (
<SingleEntitySelect
disableBackgroundBlur
onCancel={handleCancel}
onEntitySelected={handleEntitySelect}
onCancel={() => handleCreateSuccess('last', columnId, false)}
onEntitySelected={(company) =>
company ? handleEntitySelect('last', company) : null
}
relationObjectNameSingular={CoreObjectNameSingular.Company}
relationPickerScopeId="relation-picker"
selectedRelationRecordIds={[]}
/>
) : (
<StyledButton onClick={handleAddNewOpportunityClick}>
<StyledButton onClick={() => handleNewButtonClick('last', true)}>
<IconPlus size={theme.icon.size.md} />
New
</StyledButton>

View File

@ -1,15 +1,28 @@
import { RecordBoardContext } from '@/object-record/record-board/contexts/RecordBoardContext';
import { RecordBoardColumnContext } from '@/object-record/record-board/record-board-column/contexts/RecordBoardColumnContext';
import { recordBoardNewRecordByColumnIdSelector } from '@/object-record/record-board/states/selectors/recordBoardNewRecordByColumnIdSelector';
import { EntityForSelect } from '@/object-record/relation-picker/types/EntityForSelect';
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
import { useCallback, useContext } from 'react';
import { useRecoilCallback } from 'recoil';
import { RecoilState, useRecoilCallback } from 'recoil';
import { v4 as uuidv4 } from 'uuid';
type SetFunction = <T>(
recoilVal: RecoilState<T>,
valOrUpdater: T | ((currVal: T) => T),
) => void;
export const useAddNewCard = () => {
const columnContext = useContext(RecordBoardColumnContext);
const { createOneRecord, selectFieldMetadataItem } =
useContext(RecordBoardContext);
const {
goBackToPreviousHotkeyScope,
setHotkeyScopeAndMemorizePreviousScope,
} = usePreviousHotkeyScope();
const getColumnDefinitionId = useCallback(
(columnId?: string) => {
const columnDefinitionId = columnId || columnContext?.columnDefinition.id;
@ -21,8 +34,13 @@ export const useAddNewCard = () => {
[columnContext],
);
const addNewCard = useCallback(
(set: any, columnDefinitionId: string, position: 'first' | 'last') => {
const addNewItem = useCallback(
(
set: SetFunction,
columnDefinitionId: string,
position: 'first' | 'last',
isOpportunity: boolean,
) => {
set(
recordBoardNewRecordByColumnIdSelector({
familyKey: columnDefinitionId,
@ -33,6 +51,8 @@ export const useAddNewCard = () => {
columnId: columnDefinitionId,
isCreating: true,
position,
isOpportunity,
company: null,
},
);
},
@ -44,12 +64,19 @@ export const useAddNewCard = () => {
labelIdentifier: string,
labelValue: string,
position: 'first' | 'last',
isOpportunity: boolean,
company?: EntityForSelect,
) => {
if (labelValue !== '') {
if (
(isOpportunity && company !== null) ||
(!isOpportunity && labelValue !== '')
) {
createOneRecord({
[selectFieldMetadataItem.name]: columnContext?.columnDefinition.value,
position,
[labelIdentifier.toLowerCase()]: labelValue,
...(isOpportunity
? { companyId: company?.id, name: company?.name }
: { [labelIdentifier.toLowerCase()]: labelValue }),
});
}
},
@ -62,18 +89,34 @@ export const useAddNewCard = () => {
labelIdentifier: string,
labelValue: string,
position: 'first' | 'last',
isOpportunity: boolean,
columnId?: string,
): void => {
const columnDefinitionId = getColumnDefinitionId(columnId);
addNewCard(set, columnDefinitionId, position);
createRecord(labelIdentifier, labelValue, position);
addNewItem(set, columnDefinitionId, position, isOpportunity);
if (isOpportunity) {
setHotkeyScopeAndMemorizePreviousScope(
RelationPickerHotkeyScope.RelationPicker,
);
} else {
createRecord(labelIdentifier, labelValue, position, isOpportunity);
}
},
[addNewCard, createRecord, getColumnDefinitionId],
[
addNewItem,
createRecord,
getColumnDefinitionId,
setHotkeyScopeAndMemorizePreviousScope,
],
);
const handleCreateSuccess = useRecoilCallback(
({ set }) =>
(position: 'first' | 'last', columnId?: string): void => {
(
position: 'first' | 'last',
columnId?: string,
isOpportunity = false,
): void => {
const columnDefinitionId = getColumnDefinitionId(columnId);
set(
recordBoardNewRecordByColumnIdSelector({
@ -85,10 +128,15 @@ export const useAddNewCard = () => {
columnId: columnDefinitionId,
isCreating: false,
position,
isOpportunity: Boolean(isOpportunity),
company: null,
},
);
if (isOpportunity === true) {
goBackToPreviousHotkeyScope();
}
},
[getColumnDefinitionId],
[getColumnDefinitionId, goBackToPreviousHotkeyScope],
);
const handleCreate = (
@ -98,7 +146,13 @@ export const useAddNewCard = () => {
onCreateSuccess?: () => void,
) => {
if (labelValue.trim() !== '' && position !== undefined) {
handleAddNewCardClick(labelIdentifier, labelValue.trim(), position);
handleAddNewCardClick(
labelIdentifier,
labelValue.trim(),
position,
false,
'',
);
onCreateSuccess?.();
}
};
@ -125,11 +179,25 @@ export const useAddNewCard = () => {
handleCreate(labelIdentifier, labelValue, position, onCreateSuccess);
};
const handleEntitySelect = useCallback(
(
position: 'first' | 'last',
company: EntityForSelect,
columnId?: string,
) => {
const columnDefinitionId = getColumnDefinitionId(columnId);
createRecord('', '', position, true, company);
handleCreateSuccess(position, columnDefinitionId, true);
},
[createRecord, handleCreateSuccess, getColumnDefinitionId],
);
return {
handleAddNewCardClick,
handleCreateSuccess,
handleCreate,
handleBlur,
handleInputEnter,
handleEntitySelect,
};
};

View File

@ -1,75 +0,0 @@
import { RecordBoardContext } from '@/object-record/record-board/contexts/RecordBoardContext';
import { RecordBoardColumnContext } from '@/object-record/record-board/record-board-column/contexts/RecordBoardColumnContext';
import { useIsOpportunitiesCompanyFieldDisabled } from '@/object-record/record-board/record-board-column/hooks/useIsOpportunitiesCompanyFieldDisabled';
import { useEntitySelectSearch } from '@/object-record/relation-picker/hooks/useEntitySelectSearch';
import { EntityForSelect } from '@/object-record/relation-picker/types/EntityForSelect';
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
import { useCallback, useContext, useState } from 'react';
export const useAddNewOpportunity = (position: string) => {
const [isCreatingCard, setIsCreatingCard] = useState(false);
const { columnDefinition } = useContext(RecordBoardColumnContext);
const { createOneRecord, selectFieldMetadataItem } =
useContext(RecordBoardContext);
const {
goBackToPreviousHotkeyScope,
setHotkeyScopeAndMemorizePreviousScope,
} = usePreviousHotkeyScope();
const { resetSearchFilter } = useEntitySelectSearch({
relationPickerScopeId: 'relation-picker',
});
const { isOpportunitiesCompanyFieldDisabled } =
useIsOpportunitiesCompanyFieldDisabled();
const handleEntitySelect = useCallback(
(company?: EntityForSelect) => {
setIsCreatingCard(false);
goBackToPreviousHotkeyScope();
resetSearchFilter();
createOneRecord({
name: company?.name,
companyId: company?.id,
position: position,
[selectFieldMetadataItem.name]: columnDefinition.value,
});
},
[
columnDefinition,
createOneRecord,
goBackToPreviousHotkeyScope,
resetSearchFilter,
selectFieldMetadataItem,
position,
],
);
const handleAddNewOpportunityClick = useCallback(() => {
if (isOpportunitiesCompanyFieldDisabled) {
handleEntitySelect();
} else {
setIsCreatingCard(true);
}
setHotkeyScopeAndMemorizePreviousScope(
RelationPickerHotkeyScope.RelationPicker,
);
}, [
setHotkeyScopeAndMemorizePreviousScope,
isOpportunitiesCompanyFieldDisabled,
handleEntitySelect,
]);
const handleCancel = useCallback(() => {
resetSearchFilter();
goBackToPreviousHotkeyScope();
setIsCreatingCard(false);
}, [goBackToPreviousHotkeyScope, resetSearchFilter]);
return {
isCreatingCard,
handleEntitySelect,
handleAddNewOpportunityClick,
handleCancel,
};
};

View File

@ -12,7 +12,8 @@ export const useColumnNewCardActions = (columnId: string) => {
(field) => field.isLabelIdentifier,
);
const { handleAddNewCardClick, handleCreateSuccess } = useAddNewCard();
const { handleAddNewCardClick, handleCreateSuccess, handleEntitySelect } =
useAddNewCard();
const newRecord = useRecoilValue(
recordBoardNewRecordByColumnIdSelector({
@ -21,11 +22,15 @@ export const useColumnNewCardActions = (columnId: string) => {
}),
);
const handleNewButtonClick = (position: 'first' | 'last') => {
const handleNewButtonClick = (
position: 'first' | 'last',
isOpportunity: boolean,
) => {
handleAddNewCardClick(
labelIdentifierField?.label ?? '',
'',
position,
isOpportunity,
columnId,
);
};
@ -34,5 +39,6 @@ export const useColumnNewCardActions = (columnId: string) => {
newRecord,
handleNewButtonClick,
handleCreateSuccess,
handleEntitySelect,
};
};

View File

@ -1,3 +1,4 @@
import { EntityForSelect } from '@/object-record/relation-picker/types/EntityForSelect';
import { createComponentFamilyState } from '@/ui/utilities/state/component-state/utils/createComponentFamilyState';
export type NewCard = {
@ -5,6 +6,8 @@ export type NewCard = {
columnId: string;
isCreating: boolean;
position: 'first' | 'last';
isOpportunity: boolean;
company: EntityForSelect | null;
};
export const recordBoardNewRecordByColumnIdComponentFamilyState =
@ -15,5 +18,7 @@ export const recordBoardNewRecordByColumnIdComponentFamilyState =
columnId: '',
isCreating: false,
position: 'last',
isOpportunity: false,
company: null,
},
});

View File

@ -1,24 +1,21 @@
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
import { useAddNewCard } from '@/object-record/record-board/record-board-column/hooks/useAddNewCard';
import { useIsOpportunitiesCompanyFieldDisabled } from '@/object-record/record-board/record-board-column/hooks/useIsOpportunitiesCompanyFieldDisabled';
import { RecordBoardColumnDefinition } from '@/object-record/record-board/types/RecordBoardColumnDefinition';
import { RecordIndexPageKanbanAddMenuItem } from '@/object-record/record-index/components/RecordIndexPageKanbanAddMenuItem';
import { RecordIndexRootPropsContext } from '@/object-record/record-index/contexts/RecordIndexRootPropsContext';
import { useRecordIndexPageKanbanAddButton } from '@/object-record/record-index/hooks/useRecordIndexPageKanbanAddButton';
import { SingleEntitySelect } from '@/object-record/relation-picker/components/SingleEntitySelect';
import { useEntitySelectSearch } from '@/object-record/relation-picker/hooks/useEntitySelectSearch';
import { EntityForSelect } from '@/object-record/relation-picker/types/EntityForSelect';
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
import { recordIndexKanbanFieldMetadataIdState } from '@/object-record/record-index/states/recordIndexKanbanFieldMetadataIdState';
import { IconButton } from '@/ui/input/button/components/IconButton';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
import styled from '@emotion/styled';
import { useCallback, useContext, useState } from 'react';
import { useCallback, useContext } from 'react';
import { useRecoilValue } from 'recoil';
import { IconPlus, isDefined } from 'twenty-ui';
import { IconPlus } from 'twenty-ui';
const StyledDropdownMenuItemsContainer = styled(DropdownMenuItemsContainer)`
width: 100%;
@ -30,13 +27,21 @@ const StyledDropDownMenu = styled(DropdownMenu)`
export const RecordIndexPageKanbanAddButton = () => {
const dropdownId = `record-index-page-add-button-dropdown`;
const [isSelectingCompany, setIsSelectingCompany] = useState(false);
const [selectedColumnDefinition, setSelectedColumnDefinition] =
useState<RecordBoardColumnDefinition>();
const { recordIndexId, objectNamePlural } = useContext(
const { recordIndexId, objectNameSingular } = useContext(
RecordIndexRootPropsContext,
);
const { objectMetadataItem } = useObjectMetadataItem({ objectNameSingular });
const recordIndexKanbanFieldMetadataId = useRecoilValue(
recordIndexKanbanFieldMetadataIdState,
);
const selectFieldMetadataItem = objectMetadataItem.fields.find(
(field) => field.id === recordIndexKanbanFieldMetadataId,
);
const isOpportunity =
objectMetadataItem.nameSingular === CoreObjectNameSingular.Opportunity;
const { columnIdsState, visibleFieldDefinitionsState } =
useRecordBoardStates(recordIndexId);
@ -48,73 +53,32 @@ export const RecordIndexPageKanbanAddButton = () => {
(field) => field.isLabelIdentifier,
);
const {
setHotkeyScopeAndMemorizePreviousScope,
goBackToPreviousHotkeyScope,
} = usePreviousHotkeyScope();
const { resetSearchFilter } = useEntitySelectSearch({
relationPickerScopeId: 'relation-picker',
});
const { closeDropdown } = useDropdown(dropdownId);
const { selectFieldMetadataItem, isOpportunity, createOpportunity } =
useRecordIndexPageKanbanAddButton({
objectNamePlural,
});
const { isOpportunitiesCompanyFieldDisabled } =
useIsOpportunitiesCompanyFieldDisabled();
const { handleAddNewCardClick } = useAddNewCard();
const handleItemClick = useCallback(
(columnDefinition: RecordBoardColumnDefinition) => {
if (isOpportunity) {
setIsSelectingCompany(true);
setSelectedColumnDefinition(columnDefinition);
setHotkeyScopeAndMemorizePreviousScope(
RelationPickerHotkeyScope.RelationPicker,
);
} else {
handleAddNewCardClick(
labelIdentifierField?.label ?? '',
'',
'first',
columnDefinition.id,
);
closeDropdown();
}
const isOpportunityEnabled =
isOpportunity && !isOpportunitiesCompanyFieldDisabled;
handleAddNewCardClick(
labelIdentifierField?.label ?? '',
'',
'first',
isOpportunityEnabled,
columnDefinition.id,
);
closeDropdown();
},
[
isOpportunity,
handleAddNewCardClick,
setHotkeyScopeAndMemorizePreviousScope,
closeDropdown,
labelIdentifierField,
isOpportunitiesCompanyFieldDisabled,
],
);
const handleEntitySelect = useCallback(
(company?: EntityForSelect) => {
setIsSelectingCompany(false);
goBackToPreviousHotkeyScope();
resetSearchFilter();
if (isDefined(company) && isDefined(selectedColumnDefinition)) {
createOpportunity(company, selectedColumnDefinition);
}
closeDropdown();
},
[
createOpportunity,
goBackToPreviousHotkeyScope,
resetSearchFilter,
selectedColumnDefinition,
closeDropdown,
],
);
const handleCancel = useCallback(() => {
resetSearchFilter();
goBackToPreviousHotkeyScope();
setIsSelectingCompany(false);
}, [goBackToPreviousHotkeyScope, resetSearchFilter]);
if (!selectFieldMetadataItem) {
return null;
@ -137,27 +101,16 @@ export const RecordIndexPageKanbanAddButton = () => {
dropdownId={dropdownId}
dropdownComponents={
<StyledDropDownMenu>
{isOpportunity && isSelectingCompany ? (
<SingleEntitySelect
disableBackgroundBlur
onCancel={handleCancel}
onEntitySelected={handleEntitySelect}
relationObjectNameSingular={CoreObjectNameSingular.Company}
relationPickerScopeId="relation-picker"
selectedRelationRecordIds={[]}
/>
) : (
<StyledDropdownMenuItemsContainer>
{columnIds.map((columnId) => (
<RecordIndexPageKanbanAddMenuItem
key={columnId}
columnId={columnId}
recordIndexId={recordIndexId}
onItemClick={handleItemClick}
/>
))}
</StyledDropdownMenuItemsContainer>
)}
<StyledDropdownMenuItemsContainer>
{columnIds.map((columnId) => (
<RecordIndexPageKanbanAddMenuItem
key={columnId}
columnId={columnId}
recordIndexId={recordIndexId}
onItemClick={handleItemClick}
/>
))}
</StyledDropdownMenuItemsContainer>
</StyledDropDownMenu>
}
dropdownHotkeyScope={{ scope: dropdownId }}

View File

@ -1,53 +0,0 @@
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord';
import { RecordBoardColumnDefinition } from '@/object-record/record-board/types/RecordBoardColumnDefinition';
import { recordIndexKanbanFieldMetadataIdState } from '@/object-record/record-index/states/recordIndexKanbanFieldMetadataIdState';
import { EntityForSelect } from '@/object-record/relation-picker/types/EntityForSelect';
import { useRecoilValue } from 'recoil';
import { isDefined } from 'twenty-ui';
type useRecordIndexPageKanbanAddButtonProps = {
objectNamePlural: string;
};
export const useRecordIndexPageKanbanAddButton = ({
objectNamePlural,
}: useRecordIndexPageKanbanAddButtonProps) => {
const { objectNameSingular } = useObjectNameSingularFromPlural({
objectNamePlural,
});
const { objectMetadataItem } = useObjectMetadataItem({ objectNameSingular });
const recordIndexKanbanFieldMetadataId = useRecoilValue(
recordIndexKanbanFieldMetadataIdState,
);
const { createOneRecord } = useCreateOneRecord({ objectNameSingular });
const selectFieldMetadataItem = objectMetadataItem.fields.find(
(field) => field.id === recordIndexKanbanFieldMetadataId,
);
const isOpportunity =
objectMetadataItem.nameSingular === CoreObjectNameSingular.Opportunity;
const createOpportunity = (
company: EntityForSelect,
columnDefinition: RecordBoardColumnDefinition,
) => {
if (isDefined(selectFieldMetadataItem)) {
createOneRecord({
name: company.name,
companyId: company.id,
position: 'first',
[selectFieldMetadataItem.name]: columnDefinition?.value,
});
}
};
return {
selectFieldMetadataItem,
isOpportunity,
createOpportunity,
};
};

View File

@ -4,8 +4,8 @@ import { ReactElement, useContext } from 'react';
import {
AppTooltip,
IconComponent,
TooltipDelay,
OverflowingTextWithTooltip,
TooltipDelay,
} from 'twenty-ui';
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
@ -55,11 +55,9 @@ const StyledInlineCellBaseContainer = styled.div`
box-sizing: border-box;
width: 100%;
display: flex;
height: 24px;
gap: ${({ theme }) => theme.spacing(1)};
user-select: none;
justify-content: center;
`;